Hi, Attached is a cvs diff of what I currently did to externalize the local Savannah changes from Savane itself. Those are the parts I could not separate from Savane, or added because they can be useful outside of Savannah. The next step for me is to write some separate cron-jobs to perform the remaining Savannah-specific tasks.
Overview: - Done: * added a prefix to authorized keys: new configuration variable: $sys_authorized_keys_prefix, changes in User.pm (GetUserSSHRealKey, UserAddSSHKey) and sv_users (the way to compare ssh keys in the system and in the database regarding newlines). * added MySQL option for Perl: new configuration variable: $sys_dbparams, change in DB.pm * added MakeCvsAttic-like procedures to create the per-projects CVS repositories roots and the gatekeeper directories; added 2 possible values in the "group types" parameters for download/cvs/webcvs in the frontend. Remaiming in Savane: * add documentation for the new variables once/if they are approved And incidentally, Remaining not in Savane (should be doable in separate cron jobs, unless I'm mistaken): * (1) create a chroot'd /etc/passwd and /etc/group -> separate cron job. Copy /etc/group and /etc/passwd in each cvs root, provided /etc/ is more recent that in an arbitrary cvs root. * (2) Is group 'www' properly supported? -> Yes, old hardcoding.. Could be added in (1) before the copy if not working * (3) sv_gatekpr -> separate cron_job, recreates all keyrings, provided /etc/group is more recent that the current keyring. Any comments? How should we proceed for the commit, given the current work on the CERN branch? -- Sylvain
Index: backend/accounts/sv_groups.pl =================================================================== RCS file: /cvs/savane/savane/backend/accounts/sv_groups.pl,v retrieving revision 1.10 diff -u -r1.10 sv_groups.pl --- backend/accounts/sv_groups.pl 16 Oct 2004 10:24:09 -0000 1.10 +++ backend/accounts/sv_groups.pl 5 Nov 2004 21:42:37 -0000 @@ -328,6 +328,8 @@ $madesomething .= DownloadMakeArea($name,$dir_cvs,$is_public); } elsif ($dir_type_cvs eq "cvsattic") { $madesomething .= CvsMakeAreaAttic($name,$dir_cvs,$is_public); + } elsif ($dir_type_cvs eq "savannah-gnu" or $dir_type_cvs eq "savannah-nongnu") { + $madesomething .= CvsMakeAreaSavannah($name,$dir_cvs,$is_public); } } @@ -341,7 +343,11 @@ $madesomething .= DownloadMakeArea($name,$dir_homepage,$is_public); } elsif ($dir_type_homepage eq "cvsattic") { $madesomething .= CvsMakeAreaAttic($name,$dir_homepage,$is_public); - } + } elsif ($dir_type_homepage eq "savannah-gnu") { + $madesomething .= WebCvsMakeAreaSavannahGNU($name,$dir_homepage,$is_public); + } elsif ($dir_type_homepage eq "savannah-nongnu") { + $madesomething .= WebCvsMakeAreaSavannahNonGNU($name,$dir_homepage,$is_public); + } } # Create the download area, by relying on the library, that should @@ -354,6 +360,8 @@ $madesomething .= DownloadMakeArea($name,$dir_download,$is_public); } elsif ($dir_type_download eq "cvsattic") { $madesomething .= CvsMakeAreaAttic($name,$dir_download,$is_public); + } elsif ($dir_type_download eq "savannah-gnu" or $dir_type_download eq "savannah-nongnu") { + $madesomething .= DownloadMakeAreaSavannah($name,$dir_download,$is_public); } } Index: backend/accounts/sv_users.pl =================================================================== RCS file: /cvs/savane/savane/backend/accounts/sv_users.pl,v retrieving revision 1.44 diff -u -r1.44 sv_users.pl --- backend/accounts/sv_users.pl 19 Oct 2004 12:30:00 -0000 1.44 +++ backend/accounts/sv_users.pl 5 Nov 2004 21:42:40 -0000 @@ -547,8 +547,13 @@ # key by bash login, not by web interface. my $ssh_keys_count = 0; if ($etc_password{$user}->[8] eq $sys_shell) { - print "DBG update: $user ssh key managed by sv\n" if $debug; - if ($authorized_keys ne GetUserSSHKeyReal($user)) { + print "DBG update: $user ssh key managed by sv\n" if $debug; + # Compare: strip the last newline + my $authorized_keys_system = GetUserSSHKeyReal($user); + my $authorized_keys_database = $authorized_keys; + $authorized_keys_system =~ s/###$//; + $authorized_keys_database =~ s/###$//; + if ($authorized_keys_system ne $authorized_keys_database) { unless ($debug) { $ssh_keys_count = UserAddSSHKey($user, $authorized_keys); } Index: frontend/php/include/html.php =================================================================== RCS file: /cvs/savane/savane/frontend/php/include/html.php,v retrieving revision 1.52 diff -u -r1.52 html.php --- frontend/php/include/html.php 22 Sep 2004 08:11:51 -0000 1.52 +++ frontend/php/include/html.php 5 Nov 2004 21:42:54 -0000 @@ -594,6 +594,8 @@ <option value="basiccvs"'.(($current_value == "basiccvs")?" selected=\"selected\"":"").'>'._("Basic Cvs Directory").'</option> <option value="basicdirectory"'.(($current_value == "basicdirectory")?" selected":"").'>'._("Basic Directory").'</option> <option value="cvsattic"'.(($current_value == "cvsattic")?" selected=\"selected\"":"").'>'._("Cvs Attic").'</option> + <option value="savannah-gnu"'.(($current_value == "savannah-gnu")?" selected=\"selected\"":"").'>'._("Savannah GNU").'</option> + <option value="savannah-nongnu"'.(($current_value == "savannah-nongnu")?" selected=\"selected\"":"").'>'._("Savannah non-GNU").'</option> </select> [BACKEND SPECIFIC] '; Index: lib/Savannah/Cvs.pm =================================================================== RCS file: /cvs/savane/savane/lib/Savannah/Cvs.pm,v retrieving revision 1.8 diff -u -r1.8 Cvs.pm --- lib/Savannah/Cvs.pm 14 May 2004 09:54:08 -0000 1.8 +++ lib/Savannah/Cvs.pm 5 Nov 2004 21:42:55 -0000 @@ -175,3 +175,92 @@ return; } + +## Make a cvs area at Savannah +## This is temporary +sub CvsMakeAreaSavannah { + my ($name,$dir_cvs,$is_public,$group_name) = @_; + + $group_name = (defined($group_name)) ? $group_name : "$name"; + + my $replace_tag = "%PROJECT"; + + $dir_cvs =~ /((.*$replace_tag).*$replace_tag.*)/; + my ($fullpath, $root) = ($1, $2); + + if (!defined($root) or !defined($fullpath)) { + return 1; + } + + $root =~ s/$replace_tag/$name/; + $fullpath =~ s/$replace_tag/$name/g; + + unless (-e "$root") { + # print LOG strftime "[$script] %c ---- created cvsroot $name\n", localtime; + + mkdir ("$root"); + mkdir ("$root/bin"); + + # hardcoded + system (('/bin/cp', '/savannah/cvs-seed/cvs', + "$root/bin")); + + mkdir ("$root/cvs-locks"); + chmod (02777, "$root/cvs-locks"); + + mkdir ("$root/dev"); + system (('/bin/mknod', + "$root/dev/null", 'c', '1', '3')); + + mkdir ("$root/etc"); + mkdir ("$root/tmp"); + chmod (01777, "$root/tmp"); + } + + unless (-e $fullpath) { + system (('/bin/mkdir', '-p', '-m', ($is_public ? '00755' : '00751'), $fullpath)); + + chmod (01777, $fullpath) if ($is_public); + chmod (00751, $fullpath) unless ($is_public); + + chdir ($fullpath); + # hardcoded + system (('/bin/tar', 'xfzp', '/savannah/cvs-seed/CVSROOT.tar.gz')); + chdir ('/'); + system (('/bin/chgrp', $group_name, + "$fullpath/CVSROOT/history")); + system (('/bin/chgrp', $group_name, + "$fullpath/CVSROOT/val-tags")); + + mkdir ("$fullpath/$name"); + chmod (02775, "$fullpath/$name"); + system (('/bin/chgrp', $group_name, + "$fullpath/$name")); + } +} + + +## Make a webcvs area at Savannah +## This is temporary +sub WebCvsMakeAreaSavannahGNU { + my ($name,$dir_cvs,$is_public) = @_; + + CvsMakeAreaSavannah(@_, "web$name"); + + # perform an initial checkout so that updates happen: + system (('/usr/bin/curl', 'http://www.gnu.org/new-savannah-project/new.py', + '-F', "type=gnu", '-F', "project=$name")); +} + + +## Make a webcvs area at Savannah +## This is temporary +sub WebCvsMakeAreaSavannahNonGNU { + my ($name,$dir_cvs,$is_public) = @_; + + CvsMakeAreaSavannah(@_, "web$name"); + + # perform an initial checkout so that updates happen: + system (('/usr/bin/curl', 'http://www.gnu.org/new-savannah-project/new.py', + '-F', "type=non-gnu", '-F', "project=$name")); +} Index: lib/Savannah/DB.pm =================================================================== RCS file: /cvs/savane/savane/lib/Savannah/DB.pm,v retrieving revision 1.13 diff -u -r1.13 DB.pm --- lib/Savannah/DB.pm 22 Sep 2004 08:11:52 -0000 1.13 +++ lib/Savannah/DB.pm 5 Nov 2004 21:42:55 -0000 @@ -39,12 +39,14 @@ our $sys_dbhost; our $sys_dbuser; our $sys_dbpasswd; +our $sys_dbparams; # Init -our $dbd = DBI->connect('DBI:mysql:'.$sys_dbname.':'.$sys_dbhost, - $sys_dbuser, $sys_dbpasswd, - { RaiseError => 1, AutoCommit => 1}); - +our $dbd =DBI->connect('DBI:mysql:database='.$sys_dbname + .':host='.$sys_dbhost + .':'.$sys_dbparams, + $sys_dbuser, $sys_dbpasswd, + { RaiseError => 1, AutoCommit => 1}); ## Returns all settings for a group, user (a row).. # arg0 : table Index: lib/Savannah/Download.pm =================================================================== RCS file: /cvs/savane/savane/lib/Savannah/Download.pm,v retrieving revision 1.5 diff -u -r1.5 Download.pm --- lib/Savannah/Download.pm 31 Jan 2004 01:07:22 -0000 1.5 +++ lib/Savannah/Download.pm 5 Nov 2004 21:42:55 -0000 @@ -58,3 +58,46 @@ return; } + +## Make a gatekeeper download area at Savannah +## This is temporary +sub DownloadMakeAreaSavannah { + my ($name,$dir_download,$is_public) = @_; + + if (-e "/savannah/download/$name" || !$is_public) { + return 1; + } + + # print LOG strftime "[$script] %c ---- created download $name\n", localtime; + + mkdir ("/savannah/download/$name"); + chmod (00755, "/savannah/download/$name"); + system (('/bin/chown', "gatekpr.gatekpr", "/savannah/download/$name")); + + mkdir ("/home/upload/incoming/savannah/$name"); + chmod (00770, "/home/upload/incoming/savannah/$name"); + system (('/bin/chown', 'upload.gatekpr', "/home/upload/incoming/savannah/$name")); + + # print LOG strftime "[$script] %c ---- created upload $name\n", localtime; + + # create the incoming ftp dir + mkdir ("/home/upload/incoming/savannah/$name"); + chmod (00770, "/home/upload/incoming/savannah/$name"); + system (('/bin/chown', 'upload.gatekpr', "/home/upload/incoming/savannah/$name")); + + # print LOG strftime "[$script] %c ---- created ftp-in $name\n", localtime; + + # ..and the ftp-in tmp dir + mkdir ("/var/tmp/ftp-in/$name"); + chmod (00770, "/var/tmp/ftp-in/$name"); + system (('/bin/chown', 'gatekpr.gatekpr', "/var/tmp/ftp-in/$name")); + + # print LOG strftime "[$script] %c ---- created ftp-out $name\n", localtime; + + # ..and the ftp-out tmp dir + mkdir ("/var/tmp/ftp-out/$name"); + chmod (00770, "/var/tmp/ftp-out/$name"); + system (('/bin/chown', 'gatekpr.gatekpr', "/var/tmp/ftp-out/$name")); + + return; +} Index: lib/Savannah/User.pm =================================================================== RCS file: /cvs/savane/savane/lib/Savannah/User.pm,v retrieving revision 1.30 diff -u -r1.30 User.pm --- lib/Savannah/User.pm 22 Sep 2004 08:11:52 -0000 1.30 +++ lib/Savannah/User.pm 5 Nov 2004 21:42:55 -0000 @@ -39,6 +39,7 @@ our $qqch; our $sys_homedir; our $sys_homedir_subdirs; +our $sys_authorized_keys_prefix; ####################################################################### @@ -154,14 +155,17 @@ my $file = GetUserHome($_[0])."/.ssh/authorized_keys"; my $ret; if (-e $file) { - open(SSH_KEY, "< $file"); - while (<SSH_KEY>) { - s/\n/###/g; #' - $ret .= $_; - } - close(SSH_KEY); - return $ret; - } + open(SSH_KEY, "< $file"); + while (<SSH_KEY>) { + if (index($_, $sys_authorized_keys_prefix) == 0) { + $_ = substr($_, length($sys_authorized_keys_prefix) + 1); + } + s/\n/###/g; #' + $ret .= $_; + } + close(SSH_KEY); + return $ret; + } } @@ -219,17 +223,18 @@ open(SSH_KEY, "> $home/.ssh/authorized_keys"); # In the database, linebreak are ### - $authorized_keys =~ s/###/\n/g; #' - print SSH_KEY $authorized_keys; - close(SSH_KEY); - - open(SSH_KEY, "< $home/.ssh/authorized_keys"); - while (<SSH_KEY>) { - next if m/^\#/; - $ssh_keys_registered++; + my (@lines) = split('###',$authorized_keys); + foreach my $key (@lines) { + my ($key_type) = split(' ',$key); + if ($key_type eq 'ssh-dss' || + $key_type eq 'ssh-rsa') { + $ssh_keys_registered++; + print SSH_KEY "$sys_authorized_keys_prefix $key\n"; + } } close(SSH_KEY); - + + # Is this really needed? The frontend does not use it. SetUserSettings($user, "authorized_keys_count", $ssh_keys_registered); return $ssh_keys_registered;