All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

Commit 5ba4b9d3 authored by Cody Cutler's avatar Cody Cutler

Merge branch 'master' of...

Merge branch 'master' of ccutler@git-public.flux.utah.edu:/flux/git/users/mike/emulab-devel into tpm-tmcd
parents 6e14662f 1b7ca63a
......@@ -2717,7 +2717,7 @@ sub CleanLogFiles($)
if ($file =~ /^.*\.ns$/);
push(@delete, "${workdir}/$1")
if ($file =~ /^(.*\.(log|ptop|top|assign|soln|xml))$/);
if ($file =~ /^(.*\.(log|ptop|top|assign|soln|xml|limits))$/);
push(@delete, "${workdir}/$1")
if ($file =~ /^((swap|start|cancel|newrun).*\..*)$/);
......
......@@ -133,6 +133,16 @@ if (!$experiment->AccessCheck($this_user, TB_EXPT_MODIFY)) {
" You do not have permission to allocate nodes in $pid/$eid\n");
}
#
# Need an RPC context for this to work.
#
my $certificate = GeniCertificate->LoadFromFile("$TB/etc/genisa.pem");
fatal("Could not load SA certificate")
if (!defined($certificate));
Genixmlrpc->SetContext(Genixmlrpc->Context($certificate));
$ENV{'MYUUID'} = $certificate->uuid();
$ENV{'MYURN'} = $certificate->urn();
my $foo = "urn:publicid:IDN+emulab.net+authority+cm";
my $fee = "urn:publicid:IDN+emulab.net+node+pc172";
......
......@@ -143,11 +143,13 @@ my @INCDIRS = ("-I${objdir}", "-I${objdir}/../tbsetup",
);
# Chicken or Egg.
DBQueryFatal("INSERT INTO sitevariables VALUES ".
# XXX only set specific fields as the ns_include field may not be there yet.
DBQueryFatal("INSERT INTO sitevariables (name,value,defaultvalue,description)".
" VALUES ".
" ('general/testbed_shutdown',NULL,'0', ".
" 'Non-zero value indicates that the testbed is shutdown ".
"and scripts should not do anything when they run. ".
"DO NOT SET THIS BY HAND!', 0)")
"DO NOT SET THIS BY HAND!')")
if (!SiteVarExists("general/testbed_shutdown"));
#
......
#
# Switch power to use syslog.
#
use strict;
use libinstall;
my $SYSLOG_CONF = "/etc/syslog.conf";
my $POWERLOG = "$TBROOT/log/power.log";
my $CHMOD = "/bin/chmod";
my $CHGRP = "/usr/bin/chgrp";
sub InstallUpdate($$)
{
my ($version, $phase) = @_;
#
# If something should run in the pre-install phase.
#
if ($phase eq "pre") {
Phase "power", "Updating power logging", sub {
Phase "syslog.conf", "Updating $SYSLOG_CONF", sub {
DoneIfEdited($SYSLOG_CONF);
BackUpFileFatal($SYSLOG_CONF);
AppendToFileFatal($SYSLOG_CONF,
"!power", "*.*\t\t\t\t\t\t$LOGDIR/power.log");
};
Phase "logfile", "Creating $POWERLOG", sub {
DoneIfExists($POWERLOG);
CreateFileFatal($POWERLOG);
ExecQuietFatal("$CHGRP tbadmin $POWERLOG");
ExecQuietFatal("$CHMOD 640 $POWERLOG");
};
Phase "syslogd", "Restarting syslogd", sub {
HUPDaemon("syslog");
};
};
}
#
# If something should run in the post-install phase.
#
if ($phase eq "post") {
}
return 0;
}
1;
......@@ -20,14 +20,14 @@ sub InstallUpdate($$)
Phase "p5-Crypt-X509", "Checking for port p5-Crypt-X509", sub {
DoneIfPackageInstalled("p5-Crypt-X509");
ExecQuietFatal("cd $PORTSDIR/security/p5-Crypt-X509; ".
"make -DBATCH install");
"make MASTER_SITE_FREEBSD=1 -DBATCH install");
};
Phase "p5-Crypt-OpenSSL-X509",
"Checking for port p5-Crypt-OpenSSL-X509", sub {
DoneIfPackageInstalled("p5-Crypt-OpenSSL-X509");
ExecQuietFatal("cd $PORTSDIR/security/p5-Crypt-OpenSSL-X509; ".
"make -DBATCH install");
"make MASTER_SITE_FREEBSD=1 -DBATCH install");
};
}
......
......@@ -20,7 +20,7 @@ sub InstallUpdate($$)
DoneIfPackageInstalled("xerces");
ExecQuietFatal("cd $PORTSDIR/textproc/xerces-c2; ".
"make clean; make rmconfig; ".
"make -DBATCH WITH_DEBUG=on install");
"make MASTER_SITE_FREEBSD=1 -DBATCH WITH_DEBUG=on install");
};
Phase "reconfig", "Checking to see if reconfigure needed", sub {
PhaseSkip("No reconfig needed")
......
......@@ -29,7 +29,6 @@ use GeniComponent;
use GeniHRN;
use GeniXML;
use emutil;
use Lan;
use Data::Dumper;
use English;
use overload ('""' => 'Stringify');
......@@ -730,6 +729,8 @@ sub ProcessManifest($$)
sub Start($$$)
{
my ($self, $version, $restart) = @_;
require Lan;
require OSinfo;
return -1
if (! ref($self));
......
......@@ -95,6 +95,8 @@ sub Lookup($$)
my $self = {};
$self->{'AUTHORITY'} = $query_result->fetchrow_hashref();
$self->{'version'} = undef;
$self->{'apilevel'} = undef;
$self->{'api'} = undef;
bless($self, $class);
#
......@@ -178,7 +180,9 @@ sub url($) { return field($_[0], "url"); }
sub hrn($) { return field($_[0], "hrn"); }
sub type($) { return field($_[0], "type"); }
sub disabled($) { return field($_[0], "disabled"); }
sub version($) { return field($_[0], "version"); }
sub version($) { return $_[0]->{"version"}; }
sub apilevel($) { return $_[0]->{"apilevel"}; }
sub api($) { return $_[0]->{"api"}; }
sub cert($) { return $_[0]->{'CERT'}->cert(); }
sub GetCertificate($) { return $_[0]->{'CERT'}; }
......@@ -329,13 +333,53 @@ sub Version($)
return undef;
}
if (ref($response->value())) {
$self->{'version'} = $response->value()->{'api'};
# Look for the AM interface.
if (exists($response->value()->{'geni_api'})) {
$self->{'version'} = $response->value()->{'geni_api'};
# This was wrong; it should be 2.0 not 1.0
$self->{'version'} = 2.0 if ($self->{'version'} == 1.0);
$self->{'apilevel'} = 0;
$self->{'api'} = "AM";
}
else {
$self->{'version'} = $response->value()->{'api'};
$self->{'apilevel'} = $response->value()->{'level'};
$self->{'apilevel'} = 0;
$self->{'api'} = "CM";
}
}
else {
$self->{'version'} = $response->value();
$self->{'version'} = $response->value();
$self->{'apilevel'} = 1;
$self->{'api'} = "CM";
}
return $self->{'version'};
}
# Ditto for the API level
sub ApiLevel($)
{
my ($self) = @_;
return $self->apilevel()
if (defined($self->apilevel()));
return undef
if (!defined($self->Version()));
return $self->apilevel();
}
sub Api($)
{
my ($self) = @_;
return $self->api()
if (defined($self->api()));
return undef
if (!defined($self->Version()));
return $self->api();
}
#
# Check that the authority is the issuer of the given certificate.
......
This diff is collapsed.
......@@ -20,34 +20,24 @@ use vars qw(@ISA @EXPORT);
# Must come after package declaration!
use lib '@prefix@/lib';
use GeniDB;
use Genixmlrpc;
use GeniResponse;
use GeniTicket;
use GeniCredential;
use GeniCertificate;
use GeniSlice;
use GeniAggregate;
use GeniAuthority;
use GeniSliver;
use GeniUser;
use GeniRegistry;
use GeniUtil;
use GeniCM;
use GeniHRN;
use GeniXML;
use libtestbed qw(SENDMAIL);
use emutil;
# Hate to import all this crap; need a utility library.
use libdb qw(TBGetSiteVar EXPTSTATE_SWAPPED EXPTSTATE_ACTIVE TBOPSPID
TBDB_NODESTATE_TBFAILED);
use Node;
use English;
use Data::Dumper;
use XML::Simple;
use Date::Parse;
use POSIX qw(strftime tmpnam);
use Time::Local;
use Experiment;
use Compress::Zlib;
use MIME::Base64;
......@@ -79,8 +69,7 @@ my $PRERENDER = "$TB/libexec/vis/prerender";
my $EMULAB_PEMFILE = "@prefix@/etc/genicm.pem";
# Just one of these, at Utah.
my $GENICH_PEMFILE = "@prefix@/etc/genich.pem";
my $API_VERSION = 2;
my $API_VERSION = 2;
#
# Tell the client what API revision we support. The correspondence
......@@ -97,7 +86,7 @@ sub GetVersion()
"output_rspec" => "0.1"
};
return GeniResponse->Create( GENIRESPONSE_SUCCESS, $blob );
return GeniResponse->Create( GENIRESPONSE_SUCCESS, $blob);
}
#
......@@ -268,6 +257,8 @@ sub CreateSliver($)
my $credentials = $argref->{'credentials'};
my $keys = $argref->{'keys'};
my $impotent = $argref->{'impotent'} || 0;
require Node;
require Experiment;
# For now, I am not worrying about the slice_urn argument.
if (! (defined($credentials) &&
......@@ -699,24 +690,21 @@ sub SliverAction($$$$$)
my $PerformAction = sub {
my ($object, $action) = @_;
my $exitval = 0;
if ($action eq "start") {
if ($object->Start($API_VERSION, 0) != 0) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not start sliver");
}
$exitval = $object->Start($API_VERSION, 0);
}
elsif ($action eq "stop") {
if ($object->Stop($API_VERSION) != 0) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not stop sliver");
}
$exitval = $object->Stop($API_VERSION);
}
elsif ($action eq "restart") {
if ($object->Start($API_VERSION, 1) != 0) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not restart sliver");
}
$exitval = $object->Start($API_VERSION, 1);
}
return GeniResponse->Create(GENIRESPONSE_ERROR,
"Could not $action sliver")
if ($exitval);
return 0;
};
......@@ -887,6 +875,7 @@ sub Shutdown($)
my $slice_urn = $argref->{'slice_urn'};
my $clear = $argref->{'clear'} || 0;
my $credentials = $argref->{'credentials'};
require libtestbed;
if (! (defined($credentials) && defined($slice_urn))) {
return GeniResponse->MalformedArgsResponse("Missing arguments");
......@@ -946,8 +935,8 @@ sub Shutdown($)
return GeniResponse->BusyResponse();
}
if (GeniCM::CleanupDeadSlice($slice, 0) != 0) {
SENDMAIL($TBOPS, "Emergency Shutdown failed",
"Emergency shutdown failed on $slice\n");
libtestbed::SENDMAIL($TBOPS, "Emergency Shutdown failed",
"Emergency shutdown failed on $slice\n");
print STDERR "Could not shutdown $slice!\n";
# Lets call this a non-error since the local admin person
# is going to have to deal with it anyway.
......@@ -1365,7 +1354,7 @@ sub ReleaseTicket($)
my ($slice, $aggregate) = Credential2SliceAggregate($credential);
if (! (defined($slice))) {
return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
return GeniResponse->Create(GENIRESPONSE_SEARCHFAILED, undef,
"No slice here");
}
if ($slice_urn ne $slice->urn()) {
......
......@@ -62,8 +62,19 @@ sub RegisterExperiment($$)
my ($experiment, $user) = @_;
my $slice = GeniSlice->LookupByExperiment($experiment);
return 0
if (defined($slice));
#
# If we have a slice for it, check to see if its expired. We just
# go ahead and renew it.
#
if (defined($slice)) {
if ($slice->IsExpired() &&
$slice->SetExpiration(time() + (24 * 3600 * 30))) {
print STDERR "Could not reset slice expiration\n";
return -1;
}
return 0;
}
#
# Load the SA cert to act as caller context.
......
......@@ -909,14 +909,31 @@ sub GetCredential($;$$)
{
my ($class, $context, $certfile) = @_;
$context = Genixmlrpc->GetContext()
if (!defined($context));
#
# If there is no UUID in the environment, then try to figure it
# out from the context.
#
my $myuuid = (exists($ENV{'MYUUID'}) ? $ENV{'MYUUID'} : undef);
if (!defined($myuuid) && defined($context)) {
$myuuid = $context->certificate()->uuid();
}
if (!defined($myuuid)) {
print STDERR "*** GeniRegistry::ClearingHouse::GetCredential: ".
"No context or MYUUID for RPC\n";
return undef;
}
my $clearinghousecert = GeniRegistry::ClearingHouse->GetCertificate();
if (!defined($clearinghousecert)) {
return undef;
}
my $clearinghousecred =
GeniCredential->Lookup($clearinghousecert->uuid(), $ENV{'MYUUID'});
GeniCredential->Lookup($clearinghousecert->uuid(), $myuuid);
#print "$clearinghousecred\n";
#print "$clearinghousecred\n" if (defined($clearinghousecred));
if (defined($clearinghousecred) &&
defined($clearinghousecred->expires())) {
......@@ -931,9 +948,6 @@ sub GetCredential($;$$)
}
#print STDERR "Getting new clearinghouse credential\n";
$context = Genixmlrpc->GetContext()
if (!defined($context));
my $url = $clearinghousecert->URL();
if (!defined($url)) {
print STDERR "No URI extension in $clearinghousecert\n";
......@@ -957,8 +971,11 @@ sub GetCredential($;$$)
print STDERR "Could not parse credential from clearinghouse\n";
return undef;
}
$clearinghousecred->Store();
if ($clearinghousecred->Store()) {
print STDERR "*** GeniRegistry::ClearingHouse::GetCredential: ".
"Could not store credential for clearinghouse\n";
return undef;
}
return $clearinghousecred;
}
......
......@@ -24,7 +24,6 @@ use GeniUsage;
use GeniHRN;
use GeniXML;
use emutil;
use OSinfo;
use Node;
use English;
use XML::Simple;
......@@ -605,7 +604,7 @@ sub component_urn($)
sub Create($$$$$$)
{
# $rspec is a LibXML element representing a single node.
my ($class, $slice, $user, $resource_uuid, $rspec) = @_;
my ($class, $slice, $user, $node, $rspec) = @_;
my $virtualization_type = GeniXML::GetVirtualizationType($rspec);
if (!defined($virtualization_type)) {
print STDERR "Node does not contain a virtualization_type\n";
......@@ -618,17 +617,6 @@ sub Create($$$$$$)
return undef;
}
#
# the node is already allocated to the sliver, but still need to enter
# a virt_nodes entry, and possibly more virt table entries, so that the
# node will boot properly, and is otherwise controllable.
#
my $node = Node->Lookup($resource_uuid);
if (!defined($node)) {
print STDERR "Could not map node $resource_uuid to its object\n";
return undef;
}
#
# An artifact of Emulab is that for shared/remote nodes, the physical
# node is already allocated, but not to the current experiment.
......@@ -651,32 +639,16 @@ sub Create($$$$$$)
print STDERR "Node does not contain a virtual_id\n";
return undef;
}
my $hrn;
my $sshdport = 22;
my $hostname;
my $phostname;
my $resource_id;
my $resource_uuid = $node->uuid();
my $resource_id = $node->node_id();
my $hrn = "${PGENIDOMAIN}." . $node->node_id();
my $sshdport = 22;
my $hostname = GeniUtil::FindHostname($node->node_id());
my $phostname = $hostname;
#
# The resource UUID refers to the physical node, but the virtualization
# type might require a vnode.
#
if ($virtualization_type eq "emulab-vnode") {
my $vnode = $experiment->VnameToNode($nickname);
if (!defined($vnode)) {
print STDERR "Could not lookup node $nickname in $experiment\n";
return undef;
}
$hrn = "${PGENIDOMAIN}." . $vnode->node_id();
$resource_id = $vnode->node_id();
$hostname = GeniUtil::FindHostname($vnode->node_id());
$phostname = GeniUtil::FindHostname($vnode->phys_nodeid());
$sshdport = $vnode->sshdport();
}
else {
$hrn = "${PGENIDOMAIN}." . $node->node_id();
$resource_id = $node->node_id();
$phostname = $hostname = GeniUtil::FindHostname($node->node_id());
if ($node->isvirtnode()) {
$sshdport = $node->sshdport();
$phostname = GeniUtil::FindHostname($node->phys_nodeid());
}
#
......@@ -796,7 +768,7 @@ sub UnProvision($;$)
my $experiment = $self->GetExperiment();
if (!defined($experiment)) {
print STDERR "Could not map $self to its experiment\n";
return -1;
return 0;
}
my $node_id = $self->resource_id();
return 0
......
......@@ -777,6 +777,7 @@ sub Release($$)
my $eid = $experiment->eid();
my @nodeids = ();
my @nodes = ();
my @vhosts = ();
foreach my $ref (GeniXML::FindNodes("n:node",
$self->rspec())->get_nodelist()) {
......@@ -795,7 +796,6 @@ sub Release($$)
return -1;
}
# Virtual nodes not created until ticket redeemed.
my $node = GeniUtil::LookupNode($resource_id);
next
if (!defined($node));
......@@ -804,10 +804,6 @@ sub Release($$)
next
if (!defined($reservation));
# Watch for duplicates, as in multiple vnodes on a pnode.
next
if (grep {$_ eq $node->node_id()} @nodeids);
#
# If the node is still in the experiment and not incorporated,
# release it. genisliver_idx is not defined until ticket redeemed.
......@@ -819,6 +815,13 @@ sub Release($$)
$restable->{'genisliver_idx'} == 0)) {
push(@nodeids, $node->node_id());
push(@nodes, $node);
# So we can tell if we need to deallocate a physical
# host once all the VMs on it are gone.
if ($node->isvirtnode() && !$node->sharing_mode()) {
push(@vhosts, $node->phys_nodeid())
if (! grep {$_ eq $node->phys_nodeid()} @vhosts);
}
}
}
}
......@@ -828,10 +831,50 @@ sub Release($$)
#
#system("export NORELOAD=1; $NFREE -x -q $pid $eid @nodeids");
system("$NFREE -x -q $pid $eid @nodeids");
return -1
if ($?);
}
foreach my $node (@nodes) {
$node->Refresh();
}
@nodes = @nodeids = ();
#
# Now go through the vhosts that belong to us, and see if we can
# free them cause there are no longer VMs on them.
#
foreach my $pnode_id (@vhosts) {
my $pnode = Node->Lookup($pnode_id);
if (!defined($pnode)) {
print STDERR "ReleaseTicket: *** No such pnode $pnode_id\n";
next;
}
my $reservation = $pnode->Reservation();
next
if (!defined($reservation) ||
!$reservation->SameExperiment($experiment));
my @vnodes = ();
if ($pnode->VirtualNodes(\@vnodes) != 0) {
print STDERR
"ReleaseTicket: *** Could not get vnode list for $pnode_id\n";
return -1;
}
if (!@vnodes) {
push(@nodeids, $pnode->node_id());
push(@nodes, $pnode);
}
}
if (@nodeids) {
system("$NFREE -x -q $pid $eid @nodeids");
return -1
if ($?);
}
foreach my $node (@nodes) {
$node->Refresh();
}
$self->Delete($flag);
return 0;
}
......
......@@ -44,8 +44,11 @@ sub GENI_PURGEFLAG() { return 1; }
# there is an emulab user context, or many of the scripts we invoke
# will complain and croak.
#
sub FlipToGeniUser()
sub FlipToGeniUser(;$)
{
my ($default_gid) = @_;
my $glist;
my $unix_uid = getpwnam("$user") or
die("*** $0:\n".
" No such user $user\n");
......@@ -53,14 +56,29 @@ sub FlipToGeniUser()
die("*** $0:\n".
" No such group $group\n");
$GID = $unix_gid;
$EGID = "$unix_gid $unix_gid";
if (defined($default_gid) && $default_gid != $unix_gid) {
$glist = "$default_gid $default_gid $unix_gid";
}
else {
$default_gid = $unix_gid;
$glist = "$unix_gid $unix_gid";
}
$GID = $default_gid;
$EGID = $glist;
$EUID = $UID = $unix_uid;
$ENV{'USER'} = $user;
$ENV{'LOGNAME'} = $user;
return 0;
}
sub ResetGroups($)
{
my ($default_gid) = @_;
$EUID = 0;
return FlipToGeniUser($default_gid);
}
#
# Store up the list of caches to flush
#
......@@ -104,6 +122,7 @@ sub NewUUID()
sub LookupNode($)
{
my ($nodeid) = @_;
require Node;
if( GeniHRN::IsValid( $nodeid ) ) {
# Looks like a URN.
......@@ -138,5 +157,24 @@ sub FindHostname($)
return $nodeid . "." . $prefix;
}