Commit 8054f5f8 authored by Kevin Atkinson's avatar Kevin Atkinson

Implemt FS#187 -- Show admin history of projects:

  When a project is initially created a new mailing list is created,
  PROJ-admin@emulab.net.

  testbed-approval is subscribed to the list

  Several emails that originally went to testbed-approval now go to the
  mailing list instead.  The From, To, fields are basically the same
  with testbed-approval becoming PROJ-admin.  This means some mail
  is sent with a From PROJ-admin and Bcc the mailing list.  Note that
  some mail still goes to testbed-approval directly, in particular
  ones where there is no clear project involved, and when a project is
  denied.

  In addition notifications of approval status of new members is also
  sent to the list.  These emails use to only go to testbed-audit@.

  Currently All mail sent to PROJ-admin is also sent to testbed-audit
  (via a Bcc).  This means that some mail that didn't use to go to
  testbed-audit now does.

  The mailing list is deleted when a project is deleted with out first
  being approved.  Becuase of this notified that a project is denied
  is sent to testbed-approval instead of PROJ-admin.

  Admins can access the mailing list from the Project Profile page.

  The mailing list is open in order to allow users to reply to the
  mailing list, in addition the check that PROJ-admin is in the To or
  CC field is disabled.  There is currently no spam control on the
  mailing lists.  However, since the mailing list address is not posted
  anywhere it should't pick up to much spam.  If it does we can deal
  with it then.

  Finally, a new script is created to create the per-project admin
  mailing list.  See doc/UPDATING.

Also add DBQuerySingleFatal to libdb, which is like DBQueryFatal but
also fails if the query didn't return any results.  Basically
identical to he version in libtblog.  Eventually libtblog should be
modified to use this version.
parent 48d5feb4
...@@ -28,7 +28,6 @@ my $resend; ...@@ -28,7 +28,6 @@ my $resend;
# #
my $TB = "@prefix@"; my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@"; my $TBOPS = "@TBOPSEMAIL@";
my $TBAPPROVAL = "@TBAPPROVALEMAIL@";
my $TBAUDIT = "@TBAUDITEMAIL@"; my $TBAUDIT = "@TBAUDITEMAIL@";
my $TBBASE = "@TBBASE@"; my $TBBASE = "@TBBASE@";
my $TBWWW = "@TBWWW@"; my $TBWWW = "@TBWWW@";
......
...@@ -13,7 +13,7 @@ include $(OBJDIR)/Makeconf ...@@ -13,7 +13,7 @@ include $(OBJDIR)/Makeconf
SBIN_SCRIPTS = addmmlist delmmlist setmmlistmembers mmsetup \ SBIN_SCRIPTS = addmmlist delmmlist setmmlistmembers mmsetup \
setmmpasswd mmlistmembership mmmodifymember \ setmmpasswd mmlistmembership mmmodifymember \
addmmuser delmmuser addmmuser delmmuser addprojadminlist
LIBEXEC_SCRIPTS = webaddmmlist webdelmmlist websetmmpasswd mmxlogin \ LIBEXEC_SCRIPTS = webaddmmlist webdelmmlist websetmmpasswd mmxlogin \
webmmlistmembership webmmlistmembership
CTRL_LIBEXEC_SCRIPTS = genaliases CTRL_LIBEXEC_SCRIPTS = genaliases
...@@ -24,7 +24,7 @@ CTRL_SBIN_SCRIPTS = mailmanproxy ...@@ -24,7 +24,7 @@ CTRL_SBIN_SCRIPTS = mailmanproxy
SETUID_BIN_SCRIPTS = SETUID_BIN_SCRIPTS =
SETUID_SBIN_SCRIPTS = addmmuser delmmuser addmmlist delmmlist \ SETUID_SBIN_SCRIPTS = addmmuser delmmuser addmmlist delmmlist \
setmmlistmembers setmmpasswd mmlistmembership \ setmmlistmembers setmmpasswd mmlistmembership \
mmmodifymember mmmodifymember addprojadminlist
SETUID_LIBX_SCRIPTS = mmxlogin SETUID_LIBX_SCRIPTS = mmxlogin
# #
...@@ -63,6 +63,8 @@ post-install: ...@@ -63,6 +63,8 @@ post-install:
chmod u+s $(INSTALL_LIBEXECDIR)/mmxlogin chmod u+s $(INSTALL_LIBEXECDIR)/mmxlogin
chown root $(INSTALL_SBINDIR)/mmmodifymember chown root $(INSTALL_SBINDIR)/mmmodifymember
chmod u+s $(INSTALL_SBINDIR)/mmmodifymember chmod u+s $(INSTALL_SBINDIR)/mmmodifymember
chown root $(INSTALL_SBINDIR)/mmmodifymember
chmod u+s $(INSTALL_SBINDIR)/addprojadminlist
# #
# Control node installation (okay, plastic) # Control node installation (okay, plastic)
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2005, 2006, 2007 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
use Getopt::Std;
use Errno qw(EEXIST);
#
# Add a mailman list, say for a project or other reason. If for a project
# the admin password comes from the groups table. Otherwise it comes from
# the sitevars table cause its assumed to be an admins list of some kind.
#
sub usage()
{
print STDOUT "Usage: addprojadminlist <proj>\n";
exit(-1);
}
my $optlist = "";
my $debug = 0;
#
# Configure variables
#
my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@";
my $TBAUDIT = "@TBAUDITEMAIL@";
my $TBAPPROVAL = "@TBAPPROVALEMAIL@";
my $CONTROL = "@USERNODE@";
my $BOSSNODE = "@BOSSNODE@";
my $OURDOMAIN = "@OURDOMAIN@";
my $MAILMANSUPPORT= @MAILMANSUPPORT@;
my $SSH = "$TB/bin/sshtb";
my $MMPROXY = "$TB/sbin/mailmanproxy";
my $ADDMMLIST = "$TB/sbin/addmmlist";
my $MAILMANDIR = "/usr/local/mailman";
my $MMBINDIR = "$MAILMANDIR/bin";
my $MMLISTDIR = "$MAILMANDIR/lists";
# Protos
sub fatal($);
#
# Untaint the path
#
$ENV{'PATH'} = "/bin:/usr/bin";
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
#
# Turn off line buffering on output
#
$| = 1;
#
# Load the Testbed support stuff.
#
use lib "@prefix@/lib";
use libdb;
use libtestbed;
use User;
#
# We don't want to run this script unless its the real version.
#
if ($EUID != 0) {
die("*** $0:\n".
" Must be setuid! Maybe its a development version?\n");
}
#
# This script is setuid, so please do not run it as root. Hard to track
# what has happened.
#
if ($UID == 0) {
die("*** $0:\n".
" Please do not run this as root! Its already setuid!\n");
}
#
# If no mailman support, just exit.
#
if (! $MAILMANSUPPORT) {
print "MailMan support is not enabled. Exit ...\n";
exit(0);
}
#
# Verify user and get his DB uid and other info for later.
#
#my $this_user = User->ThisUser();
#if (! defined($this_user)) {
# die("You ($UID) do not exist!");
#}
#my $user_uid = $this_user->uid();
#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
%options = ();
if (! getopts($optlist, \%options)) {
usage();
}
usage()
if (@ARGV == 0);
my $proj = $ARGV[0];
#
# Untaint args.
#
if ($proj =~ /^([\w-]+)$/) {
$proj = $1;
}
else {
die("Bad data in proj: $proj");
}
my $listname = "$proj-admin";
my $listtype = "projadmin";
# An admins list of some kind.
$listowner_email = $TBOPS;
if (! TBGetSiteVar("general/mailman/password", \$listpasswd)) {
fatal("Could not get mailman admin password from sitevars!");
}
if (!defined($listpasswd) || $listpasswd eq "") {
fatal("mailman admin password sitevar is not set!");
}
#
# Note that since we are sending cleartext passwords over, pipe the info
# into its STDIN so that the passwords are not visible in a ps listing.
#
# For ssh.
#
$UID = $EUID;
if ($CONTROL ne $BOSSNODE) {
# Must serialize some of the mailman stuff. Be sure to use the same token!
TBScriptLock("mailman_update") == 0 or
fatal("Could not get the lock!");
# my $optarg = ($debug ? "-d" : "");
my $optarg = "";
my $verb = "Adding";
my $cmd = "addlist";
print "$verb mailman list $listname ($listtype) on $CONTROL.\n";
system("echo '$listowner_email $listpasswd' | ".
"$SSH -host $CONTROL $MMPROXY $cmd $listname $listtype");
if ($?) {
if ($? >> 8 == EEXIST()) {
# Not an error.
exit(0);
}
fatal("$MMPROXY failed on $CONTROL!");
}
system("echo $TBAPPROVAL | ".
"$SSH -host $CONTROL $MMBINDIR/add_members -r - $proj-admin");
my $status = $?;
TBScriptUnlock();
$? = $status;
}
exit(0);
sub fatal($)
{
my($mesg) = $_[0];
die("*** $0:\n".
" $mesg\n");
}
...@@ -11,8 +11,7 @@ use Errno qw(EEXIST); ...@@ -11,8 +11,7 @@ use Errno qw(EEXIST);
# #
# A wrapper for messing with Mailman from boss. # A wrapper for messing with Mailman from boss.
# #
sub usage() sub usage() {
{
print "Usage: mailmanproxy addlist <listname> <listtype> or\n"; print "Usage: mailmanproxy addlist <listname> <listtype> or\n";
print " mailmanproxy setlistmembers <listname> or\n"; print " mailmanproxy setlistmembers <listname> or\n";
print " mailmanproxy modifymember <uid> <email> or\n"; print " mailmanproxy modifymember <uid> <email> or\n";
...@@ -375,7 +374,7 @@ sub AddList(@) ...@@ -375,7 +374,7 @@ sub AddList(@)
# a carriage return! # a carriage return!
# #
if (! -d "$MMLISTDIR/" . lc($name)) { if (! -d "$MMLISTDIR/" . lc($name)) {
my $optarg = ($listtype eq "admin" ? "-q" : ""); my $optarg = ($listtype =~ /admin$/ ? "-q" : "");
if ($reconfig) { if ($reconfig) {
print "List '$name' does not exist; exiting ...\n"; print "List '$name' does not exist; exiting ...\n";
...@@ -409,7 +408,7 @@ sub AddList(@) ...@@ -409,7 +408,7 @@ sub AddList(@)
print CONFIG "send_reminders = False\n"; print CONFIG "send_reminders = False\n";
print CONFIG "send_welcome_msg = False\n"; print CONFIG "send_welcome_msg = False\n";
print CONFIG "send_goodbye_msg = False\n"; print CONFIG "send_goodbye_msg = False\n";
if ($listtype eq "admin") { if ($listtype =~ /admin$/) {
# No need for tbops to see any of this. # No need for tbops to see any of this.
print CONFIG "admin_notify_mchanges = 0\n"; print CONFIG "admin_notify_mchanges = 0\n";
# Users may not unsubscribe from our lists. Only their own. # Users may not unsubscribe from our lists. Only their own.
...@@ -427,10 +426,17 @@ sub AddList(@) ...@@ -427,10 +426,17 @@ sub AddList(@)
print CONFIG "archive = True\n"; print CONFIG "archive = True\n";
print CONFIG "archive_private = 1\n"; print CONFIG "archive_private = 1\n";
print CONFIG "digestable = 0\n"; print CONFIG "digestable = 0\n";
# Be default, lists are closed unless the mail originates in the domain. if ($listtype eq "projadmin") {
# The point is to allow admin people to post to the lists, but this will # projadmin lists are open by default ...
# do for now, since we do not expect spammers from within ... print CONFIG "generic_nonmember_action = 0\n";
print CONFIG "generic_nonmember_action = 2\n"; print CONFIG "require_explicit_destination = 0\n";
print CONFIG "subject_prefix = ''\n";
} else {
# Be default, lists are closed unless the mail originates in the domain.
# The point is to allow admin people to post to the lists, but this will
# do for now, since we do not expect spammers from within ...
print CONFIG "generic_nonmember_action = 2\n";
}
print CONFIG "accept_these_nonmembers = ['^.*\@.*${OURDOMAIN}\$', ". print CONFIG "accept_these_nonmembers = ['^.*\@.*${OURDOMAIN}\$', ".
"'^.*\@.*utah.edu\$']\n"; "'^.*\@.*utah.edu\$']\n";
close(CONFIG); close(CONFIG);
......
...@@ -30,7 +30,6 @@ my $TB = "@prefix@"; ...@@ -30,7 +30,6 @@ my $TB = "@prefix@";
my $BOSSNODE = "@BOSSNODE@"; my $BOSSNODE = "@BOSSNODE@";
my $CONTROL = "@USERNODE@"; my $CONTROL = "@USERNODE@";
my $TBOPS = "@TBOPSEMAIL@"; my $TBOPS = "@TBOPSEMAIL@";
my $TBAPPROVAL = "@TBAPPROVALEMAIL@";
my $TBAUDIT = "@TBAUDITEMAIL@"; my $TBAUDIT = "@TBAUDITEMAIL@";
my $TBBASE = "@TBBASE@"; my $TBBASE = "@TBBASE@";
my $TBWWW = "@TBWWW@"; my $TBWWW = "@TBWWW@";
...@@ -893,35 +892,34 @@ sub SendJoinEmail($$) ...@@ -893,35 +892,34 @@ sub SendJoinEmail($$)
$usr_URL = "" $usr_URL = ""
if (!defined($usr_URL)); if (!defined($usr_URL));
SENDMAIL("$leader_name '$leader_uid' <$leader_email>", SendProjAdminMail
"$uid $pid Project Join Request", ($pid, "ADMIN", "$leader_name '$leader_uid' <$leader_email>",
"$usr_name is trying to join your group $gid in project $pid.". "$uid $pid Project Join Request",
"\n". "$usr_name is trying to join your group $gid in project $pid.".
"\n". "\n".
"Contact Info:\n". "\n".
"Name: $usr_name\n". "Contact Info:\n".
"Emulab ID: $uid\n". "Name: $usr_name\n".
"Email: $usr_email\n". "Emulab ID: $uid\n".
"User URL: $usr_URL\n". "Email: $usr_email\n".
"Job Title: $usr_title\n". "User URL: $usr_URL\n".
"Affiliation: $usr_affil\n". "Job Title: $usr_title\n".
"Address 1: $usr_addr\n". "Affiliation: $usr_affil\n".
"Address 2: $usr_addr2\n". "Address 1: $usr_addr\n".
"City: $usr_city\n". "Address 2: $usr_addr2\n".
"State: $usr_state\n". "City: $usr_city\n".
"ZIP/Postal Code: $usr_zip\n". "State: $usr_state\n".
"Country: $usr_country\n". "ZIP/Postal Code: $usr_zip\n".
"Phone: $usr_phone\n". "Country: $usr_country\n".
"\n". "Phone: $usr_phone\n".
"Please return to $TBWWW,\n". "\n".
"log in, select the 'New User Approval' page, and enter your\n". "Please return to $TBWWW,\n".
"log in, select the 'New User Approval' page, and enter your\n".
"decision regarding $usr_name's membership in your project.\n". "decision regarding $usr_name's membership in your project.\n".
"\n". "\n".
"Thanks,\n". "Thanks,\n".
"Testbed Operations\n", "Testbed Operations\n",
"$TBAPPROVAL", "CC: $allleaders");
"CC: $allleaders\n".
"Bcc: $TBAUDIT");
return 0; return 0;
} }
...@@ -952,7 +950,9 @@ sub SendApprovalEmail($$$) ...@@ -952,7 +950,9 @@ sub SendApprovalEmail($$$)
my $trust = $membership->trust(); my $trust = $membership->trust();
SENDMAIL("$usr_name '$usr_uid' <$usr_email>", SendProjAdminMail($pid,
"$this_name <$this_email>",
"$usr_name '$usr_uid' <$usr_email>",
"Membership Approved in '$pid/$gid' ", "Membership Approved in '$pid/$gid' ",
"\n". "\n".
"This message is to notify you that you have been approved as\n". "This message is to notify you that you have been approved as\n".
...@@ -960,9 +960,7 @@ sub SendApprovalEmail($$$) ...@@ -960,9 +960,7 @@ sub SendApprovalEmail($$$)
"\n\n". "\n\n".
"Thanks,\n". "Thanks,\n".
"Testbed Operations\n", "Testbed Operations\n",
"$this_name <$this_email>", "CC: $allleaders");
"CC: $allleaders\n".
"Bcc: $TBAUDIT");
return 0; return 0;
} }
......
...@@ -30,7 +30,6 @@ my $TB = "@prefix@"; ...@@ -30,7 +30,6 @@ my $TB = "@prefix@";
my $BOSSNODE = "@BOSSNODE@"; my $BOSSNODE = "@BOSSNODE@";
my $CONTROL = "@USERNODE@"; my $CONTROL = "@USERNODE@";
my $TBOPS = "@TBOPSEMAIL@"; my $TBOPS = "@TBOPSEMAIL@";
my $TBAPPROVAL = "@TBAPPROVALEMAIL@";
my $TBAUDIT = "@TBAUDITEMAIL@"; my $TBAUDIT = "@TBAUDITEMAIL@";
my $TBBASE = "@TBBASE@"; my $TBBASE = "@TBBASE@";
my $TBWWW = "@TBWWW@"; my $TBWWW = "@TBWWW@";
......
...@@ -28,7 +28,6 @@ my $TB = "@prefix@"; ...@@ -28,7 +28,6 @@ my $TB = "@prefix@";
my $BOSSNODE = "@BOSSNODE@"; my $BOSSNODE = "@BOSSNODE@";
my $CONTROL = "@USERNODE@"; my $CONTROL = "@USERNODE@";
my $TBOPS = "@TBOPSEMAIL@"; my $TBOPS = "@TBOPSEMAIL@";
my $TBAPPROVAL = "@TBAPPROVALEMAIL@";
my $TBAUDIT = "@TBAUDITEMAIL@"; my $TBAUDIT = "@TBAUDITEMAIL@";
my $TBBASE = "@TBBASE@"; my $TBBASE = "@TBBASE@";
my $TBWWW = "@TBWWW@"; my $TBWWW = "@TBWWW@";
......
...@@ -34,6 +34,8 @@ my $TBAUDIT = "@TBAUDITEMAIL@"; ...@@ -34,6 +34,8 @@ my $TBAUDIT = "@TBAUDITEMAIL@";
my $TBBASE = "@TBBASE@"; my $TBBASE = "@TBBASE@";
my $TBWWW = "@TBWWW@"; my $TBWWW = "@TBWWW@";
my $WIKISUPPORT = @WIKISUPPORT@; my $WIKISUPPORT = @WIKISUPPORT@;
my $MAILMANSUPPORT = @MAILMANSUPPORT@;
my $ADDPROJADMINLIST = "$TB/sbin/addprojadminlist";
# Cache of instances to avoid regenerating them. # Cache of instances to avoid regenerating them.
my %projects = (); my %projects = ();
...@@ -260,6 +262,15 @@ sub Create($$$$) ...@@ -260,6 +262,15 @@ sub Create($$$$)
DBQueryWarn("delete from projects where pid_idx=$pid_idx"); DBQueryWarn("delete from projects where pid_idx=$pid_idx");
return undef; return undef;
} }
#
# Now create the per-project Admin List
#
if ($MAILMANSUPPORT) {
system("$ADDPROJADMINLIST $pid") == 0 or
die("$ADDPROJADMINLIST $pid failed!");
}
return $newproject; return $newproject;
} }
...@@ -373,60 +384,56 @@ sub SendNewProjectEmail($;$) ...@@ -373,60 +384,56 @@ sub SendNewProjectEmail($;$)
if (!defined($proj_whynotpublic)); if (!defined($proj_whynotpublic));
if ($returning || $firstproject) { if ($returning || $firstproject) {
SENDMAIL($TBAPPROVAL, SendProjAdminMail
"New Project '$pid' ($usr_uid)", ($pid, "$usr_name '$usr_uid' <$usr_email>", "ADMIN",
"'$usr_name' wants to start project '$pid'.\n". "New Project '$pid' ($usr_uid)",
"\n". "'$usr_name' wants to start project '$pid'.\n".
"Name: $usr_name ($usr_uid/$usr_idx)\n". "\n".
"Project IDX: $pid_idx\n". "Name: $usr_name ($usr_uid/$usr_idx)\n".
"Returning User?: $usr_returning\n". "Project IDX: $pid_idx\n".
"Email: $usr_email\n". "Returning User?: $usr_returning\n".
"User URL: $usr_URL\n". "Email: $usr_email\n".
"Description: $proj_desc\n". "User URL: $usr_URL\n".
"Project URL: $proj_URL\n". "Description: $proj_desc\n".
"Public URL: $proj_public\n". "Project URL: $proj_URL\n".
"Why Not Public: $proj_whynotpublic\n". "Public URL: $proj_public\n".
"Link to Us?: $proj_linked\n". "Why Not Public: $proj_whynotpublic\n".
"Funders: $proj_funders\n". "Link to Us?: $proj_linked\n".
"Job Title: $usr_title\n". "Funders: $proj_funders\n".
"Affiliation: $usr_affil\n". "Job Title: $usr_title\n".
"Address 1: $usr_addr\n". "Affiliation: $usr_affil\n".
"Address 2: $usr_addr2\n". "Address 1: $usr_addr\n".
"City: $usr_city\n". "Address 2: $usr_addr2\n".
"State: $usr_state\n". "City: $usr_city\n".
"ZIP/Postal Code: $usr_zip\n". "State: $usr_state\n".
"Country: $usr_country\n". "ZIP/Postal Code: $usr_zip\n".
"Phone: $usr_phone\n". "Country: $usr_country\n".
"Members: $proj_members\n". "Phone: $usr_phone\n".
"PCs: $proj_pcs\n". "Members: $proj_members\n".
"Planetlab PCs: $proj_plabpcs\n". "PCs: $proj_pcs\n".
"RON PCs: $proj_ronpcs\n". "Planetlab PCs: $proj_plabpcs\n".
"Unix GID: $unix_name ($unix_gid)\n". "RON PCs: $proj_ronpcs\n".
"Reasons:\n$proj_why\n\n". "Unix GID: $unix_name ($unix_gid)\n".
"Please review the application and when you have made a \n". "Reasons:\n$proj_why\n\n".
"decision, go to $TBWWW and\n". "Please review the application and when you have made a \n".
"select the 'Project Approval' page.", "decision, go to $TBWWW and\n".
"$usr_name '$usr_uid' <$usr_email>", "select the 'Project Approval' page.");
"Reply-To: $TBAPPROVAL\n".
"Bcc: $TBAUDIT");
} }
else { else {
SENDMAIL($TBAPPROVAL, SendProjAdminMail
"New Project '$pid' ($usr_uid)", ($pid, "$usr_name '$usr_uid' <$usr_email>", "ADMIN",
"'$usr_name' wants to start project '$pid'.\n". "New Project '$pid' ($usr_uid)",
"\n". "'$usr_name' wants to start project '$pid'.\n".
"Name: $usr_name ($usr_uid/$usr_idx)\n". "\n".
"Project IDX: $pid_idx\n". "Name: $usr_name ($usr_uid/$usr_idx)\n".
"Email: $usr_email\n". "Project IDX: $pid_idx\n".
"Returning User?: No\n". "Email: $usr_email\n".
"\n". "Returning User?: No\n".
"No action is necessary until the user has verified the ". "\n".
"account.\n", "No action is necessary until the user has verified the ".
"$usr_name '$usr_uid' <$usr_email>", "account.\n");
"Reply-To: $TBAPPROVAL\n".
"Bcc: $TBAUDIT");
} }
return 0; return 0;
} }
......
...@@ -313,6 +313,20 @@ sub DBQueryFatalN($$) ...@@ -313,6 +313,20 @@ sub DBQueryFatalN($$)
} }
sub DBQueryFatal($) {return DBQueryFatalN(0,$_[0]);} sub DBQueryFatal($) {return DBQueryFatalN(0,$_[0]);}
#
# Like DBQueryFatal but also fail if the query didn't return any results
#
sub DBQuerySingleFatalN($$)
{
my ($dbnum, $query) = @_;
my $query_result = DBQueryFatalN($dbnum, $query);
DBFatal("DB Query \"$query\" didn't return any results")
unless $query_result->numrows > 0;
my @row = $query_result->fetchrow_array();
return $row[0];
}
sub DBQuerySingleFatal($) {return DBQuerySingleFatalN(0,$_[0]);}
# #
# Same as above, but just send email on error. This info is useful # Same as above, but just send email on error. This info is useful
# to the TB system, but the caller has to retain control. # to the TB system, but the caller has to retain control.
......
...@@ -162,6 +162,7 @@ use vars qw(@ISA @EXPORT); ...@@ -162,6 +162,7 @@ use vars qw(@ISA @EXPORT);
SetNodeBootStatus OSFeatureSupported NodeidToExp SetNodeBootStatus OSFeatureSupported NodeidToExp
DBQuery DBQueryFatal DBQueryWarn DBWarn DBFatal DBErr DBQuery DBQueryFatal DBQueryWarn DBWarn DBFatal DBErr
NewTBDBHandle DBQueryN DBQueryFatalN DBQueryWarnN DBErrN NewTBDBHandle DBQueryN DBQueryFatalN DBQueryWarnN DBErrN
DBQuerySingleFatal DBQuerySingleFatalN
DBQuoteSpecial ExpState DBQuoteSpecial ExpState
ExpNodes ExpNodeVnames ExpNodesOldReserved ExpNodes ExpNodeVnames ExpNodesOldReserved
DBDateTime DefaultImageID DBDateTime DefaultImageID
...@@ -298,6 +299,8 @@ sub DBQueryN($$) { return emdbi::DBQueryN($_[0], $_[1]); } ...@@ -298,6 +299,8 @@ sub DBQueryN($$) { return emdbi::DBQueryN($_[0], $_[1]); }
sub DBQuery($) { return emdbi::DBQuery($_[0]); } sub DBQuery($) { return emdbi::DBQuery($_[0]); }
sub DBQueryFatalN($$) { return emdbi::DBQueryFatalN($_[0], $_[1]); } sub DBQueryFatalN($$) { return emdbi::DBQueryFatalN($_[0], $_[1]); }
sub DBQueryFatal($) { return emdbi::DBQueryFatal($_[0]);} sub DBQueryFatal($) { return emdbi::DBQueryFatal($_[0]);}
sub DBQuerySingleFatalN($$) { return emdbi::DBQuerySingleFatalN($_[0], $_[1]);}
sub DBQuerySingleFatal($) { return emdbi::DBQuerySingleFatal($_[0]);}
sub DBQueryWarnN($$) { return emdbi::DBQueryWarnN($_[0], $_[1]); } sub DBQueryWarnN($$) { return emdbi::DBQueryWarnN($_[0], $_[1]); }
sub DBQueryWarn($) { return emdbi::DBQueryWarn($_[0]);} sub DBQueryWarn($) { return emdbi::DBQueryWarn($_[0]);}
sub DBQuoteSpecial($) { return emdbi::DBQuoteSpecial($_[0]); } sub DBQuoteSpecial($) { return emdbi::DBQuoteSpecial($_[0]); }
......
...@@ -18,6 +18,13 @@ Note that some instructions may have steps that need to occur at a few ...@@ -18,6 +18,13 @@ Note that some instructions may have steps that need to occur at a few
different points in the install process - these are marked with the different points in the install process - these are marked with the
earliest time one of the steps needs to occur. earliest time one of the steps needs to occur.
20080401: Before install.
Create per project admin mailing lists if you enabled
mailman support (MAILMANSUPPORT set to 1 in defs file).
sql/create-projadminlists.pl
20080219: After install: 20080219: After install:
The newnode MFS ssh keys have been updated from protocol 1 The newnode MFS ssh keys have been updated from protocol 1
...@@ -260,7 +267,6 @@ earliest time one of the steps needs to occur. ...@@ -260,7 +267,6 @@ earliest time one of the steps needs to occur.
Where SESSION is the session number where the values where first Where SESSION is the session number where the values where first
swapped, 9359824, for emulab.net. swapped, 9359824, for emulab.net.
20060322: Before installing tbsetup/ns2ir/sim.tcl.in rev 1.109 (3/22/06). 20060322: Before installing tbsetup/ns2ir/sim.tcl.in rev 1.109 (3/22/06).
This revision introduces a new features/desire pair called This revision introduces a new features/desire pair called
......
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2004 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
use lib "/usr/testbed/lib";
use libdb;
use libtestbed;
my $ADDPROJADMINLIST = "/usr/testbed/sbin/addprojadminlist";
#
# Turn off line buffering on output
#
$| = 1;
my $gentopofile = "/usr/testbed/libexec/gentopofile";
#
# Untaint the path
#
$ENV{'PATH'} = '/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
$query_result =
DBQueryFatal("select pid from projects");