Commit 075175c0 authored by Leigh B Stoller's avatar Leigh B Stoller
Browse files

Merge branch 'imagealiases'

parents 82d50e46 a5ee67dc
......@@ -235,6 +235,8 @@ endif
subboss:
@$(MAKE) -C clientside subboss
@$(MAKE) -C tbsetup subboss
@$(MAKE) -C db subboss
@$(MAKE) -C os subboss
ifneq ($(SYSTEM),CYGWIN_NT-5.1)
@$(MAKE) -C tip client
......@@ -243,6 +245,7 @@ endif
subboss-install: subboss
@$(MAKE) -C clientside subboss-install
@$(MAKE) -C tbsetup subboss-install
@$(MAKE) -C os subboss-install
ifneq ($(SYSTEM),CYGWIN_NT-5.1)
@$(MAKE) -C tip client-install
......
......@@ -111,7 +111,7 @@ default-clean:
# This is to avoid warnings about duplicate targets.
default-install-notusing:
ifeq ($(ISMAINSITE),1)
ifeq ($(TBROOT),/usr/testbed/devel/stoller)
ifeq ($(TBROOT),/usr/testbed)
(cd $(SRCDIR) ; \
git status --porcelain -s -b | head -1 | grep -q -s current)
else
......
......@@ -118,7 +118,7 @@ use Experiment;
use User;
use Project;
use Group;
use OSinfo;
use Image;
use emutil;
use libEmulab;
use GeniDB;
......
#!/usr/bin/perl -wT
#
# Copyright (c) 2000-2014 University of Utah and the Flux Group.
# Copyright (c) 2000-2016 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -67,7 +67,7 @@ use libdb;
use libtestbed;
use User;
use Project;
use Image;
use OSImage;
# Protos
sub fatal($);
......@@ -161,6 +161,7 @@ my %xmlfields =
"mtype_*" => ["mtype", $SLOT_OPTIONAL],
"hash", => ["hash", $SLOT_ADMINONLY],
"notes", => ["notes", $SLOT_ADMINONLY],
"architecture" => ["architecture", $SLOT_OPTIONAL],
);
#
# Need a list of node types. We join this over the nodes table so that
......@@ -319,8 +320,8 @@ UserError()
# Now do special checks.
#
my $image = Image->Lookup($editimageid_args{"imageid"},
$editimageid_args{"version"});
my $image = OSImage->Lookup($editimageid_args{"imageid"},
$editimageid_args{"version"});
if (!defined($image)) {
UserError("Image: No such image");
}
......@@ -369,6 +370,16 @@ if (!$isadmin && exists($editimageid_args{"path"})) {
}
}
if ($image->architecture() ||
(exists($editimageid_args{"architecture"}) &&
$editimageid_args{"architecture"} ne "")) {
foreach my $arch (split(",", $editimageid_args{"architecture"})) {
if (!exists($OSImage::IMAGE_ARCHITECTURES{$arch})) {
UserError("Architecture: Not a valid Architecture: $arch");
}
}
}
else {
#
# See what node types this image will work on. Must be at least one!
#
......@@ -446,7 +457,7 @@ if (defined($osidclause)) {
" and make the necessary changes!\n $msg");
}
}
}
exit(0)
if ($verify);
......@@ -459,8 +470,8 @@ exit(0)
delete($editimageid_args{"imageid"});
my $usrerr;
my $editimageid_val = Image->EditImageid($image,
\%editimageid_args, \$usrerr);
my $editimageid_val = OSImage->EditImageid($image,
\%editimageid_args, \$usrerr);
UserError($usrerr)
if (defined($usrerr));
fatal("Could not create new Image!")
......
#!/usr/bin/perl -wT
#
# Copyright (c) 2000-2014 University of Utah and the Flux Group.
# Copyright (c) 2000-2016 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -68,7 +68,6 @@ use libdb;
use libtestbed;
use User;
use Project;
use OSinfo;
# Protos
sub fatal($);
......@@ -161,6 +160,8 @@ my %xmlfields =
# Class may only be changed while making a new class.
"class" => ["class", $SLOT_OPTIONAL],
"architecture" => ["architecture", $SLOT_OPTIONAL],
# Fixed attributes.
"isvirtnode" => ["isvirtnode", $SLOT_OPTIONAL],
......@@ -374,6 +375,12 @@ if (exists($editnodetype_args{"class"})) {
}
}
if (exists($editnodetype_args{"architecture"})) {
my $architecture = $editnodetype_args{"architecture"};
push(@nodetype_data, "architecture='$architecture'");
}
# The rest of them all have names starting with "is" at present.
my @fixed_args = grep(/^is/, keys(%editnodetype_args));
foreach my $name (@fixed_args) {
......
#!/usr/bin/perl -w
#
# Copyright (c) 2000-2015 University of Utah and the Flux Group.
# Copyright (c) 2000-2016 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -77,6 +77,7 @@ use libdb;
use libtestbed;
use User;
use Project;
use OSImage;
use Image;
use OSinfo;
use Node;
......@@ -223,6 +224,7 @@ my %xmlfields =
"lba_low", => ["lba_low", $SLOT_OPTIONAL],
"lba_high", => ["lba_high", $SLOT_OPTIONAL],
"lba_size", => ["lba_size", $SLOT_OPTIONAL],
"architecture", => ["architecture", $SLOT_OPTIONAL],
);
#
......@@ -420,7 +422,8 @@ if ($allpc) {
}
}
else {
$types_querystring = "select distinct n.type,nt.class from nodes as n ".
$types_querystring =
"select distinct n.type,nt.class,nt.architecture from nodes as n ".
"left join node_types as nt on n.type=nt.type ".
"left join node_type_attributes as a on a.type=n.type ".
"where a.attrkey='imageable' and ".
......@@ -433,9 +436,11 @@ my $types_result = DBQueryFatal($types_querystring);
# Save the valid types in a new array for later.
my %mtypes_array;
my %mtypes_arch;
if ($types_result->numrows) {
while (my ($type,$class) = $types_result->fetchrow_array()) {
while (my ($type,$class,$arch) = $types_result->fetchrow_array()) {
$mtypes_arch{$type} = $arch if (defined($arch));
$mtypes_array{$type} = $class;
$xmlfields{"mtype_$type"} = ["mtype", $SLOT_OPTIONAL];
}
......@@ -642,81 +647,67 @@ if (!$isdataset &&
#
# See what node types this image will work on. Must be at least one!
#
UserError("Node Types: Must have at least one node type")
UserError("Node Types: Must have at least one node type defined")
if (!$isdataset && !keys(%mtypes_array));
my $node_types_selected = 0;
# Check validity of mtype_* args, since the keys are dynamically generated.
my @mtype_keys = grep(/^mtype_/, keys(%newimageid_args));
foreach $key (@mtype_keys) {
my $value = $newimageid_args{$key};
print STDERR "mtype: '$key' -> '$value'\n"
if ($debug);
my $node_types_selected = 0;
my $type = $key;
$type =~ s/^mtype_//;
# Treat pcvm special for now.
if ($type eq "pcvm" ||
grep(/^${type}$/, keys(%mtypes_array))) {
$node_types_selected++
if ($value eq "1");
}
else {
$errors{$key} = "Illegal node type."
}
}
#
# When -a specified, add mappings for all pc types, does not matter if
# there are nodes of that type. Skip the stub pc/pc entry though.
# If we have architectures defined in the node_types table, and we got
# an architecture in the xml file for the image, we use those. Otherwise
# fall back to the old method.
#
if ($allpc) {
foreach my $type (keys(%mtypes_array)) {
my $class = $mtypes_array{$type};
next
if ($class ne "pc" || $type eq $class);
if (keys(%mtypes_arch) &&
(exists($newimageid_args{"architecture"}) &&
$newimageid_args{"architecture"} ne "")) {
$newimageid_args{"mtype_${type}"} = "1";
$node_types_selected++;
foreach my $arch (split(",", $newimageid_args{"architecture"})) {
if (!exists($OSImage::IMAGE_ARCHITECTURES{$arch})) {
UserError("Architecture: Not a valid Architecture: $arch");
}
}
}
else {
# Clear this since not using Architectures
delete($newimageid_args{"architecture"})
if (exists($newimageid_args{"architecture"}));
# Check validity of mtype_* args, since the keys are dynamically generated.
my @mtype_keys = grep(/^mtype_/, keys(%newimageid_args));
foreach $key (@mtype_keys) {
my $value = $newimageid_args{$key};
print STDERR "mtype: '$key' -> '$value'\n"
if ($debug);
my $type = $key;
$type =~ s/^mtype_//;
# Treat pcvm special for now.
if ($type eq "pcvm" ||
grep(/^${type}$/, keys(%mtypes_array))) {
$node_types_selected++
if ($value eq "1");
}
else {
$errors{$key} = "Illegal node type."
}
}
#
# When -a specified, add mappings for all pc types, does not matter if
# there are nodes of that type. Skip the stub pc/pc entry though.
#
if ($allpc) {
foreach my $type (keys(%mtypes_array)) {
my $class = $mtypes_array{$type};
next
if ($class ne "pc" || $type eq $class);
UserError("Node Types: Must select at least one node type")
if ($node_types_selected == 0 && !($force || $isdataset));
#
# We perform a further check for non-admins. When a node to snapshot
# has been specified, we check the OSID of the appropriate partition
# and see which node types it is appropriate for, and further restrict
# the list as necessary. This prevents creation of custom images based on
# old OSes from being checked as runnable on newer HW where they do not
# stand a chance.
#
if (!($isadmin || $isdataset) && defined($node) && !$node->isvirtnode()) {
my $query_result =
DBQueryFatal("select oi.type from osidtoimageid as oi ".
"left join partitions as p on oi.osid=p.osid ".
"where p.node_id='$node_id' and p.partition=$loadpart");
if ($query_result->numrows != 0) {
my %otypes;
while (my ($ntype) = $query_result->fetchrow_array()) {
$otypes{$ntype} = 1;
$newimageid_args{"mtype_${type}"} = "1";
$node_types_selected++;
}
my @invalid_node_types;
foreach my $ntype (@mtype_keys) {
$ntype =~ s/^mtype_//;
if (!exists($otypes{$ntype})) {
push @invalid_node_types, $ntype;
}
}
if (@invalid_node_types) {
UserError("Node Types: Current image on $node_id".
" cannot run on the following node types: ".
join(' ', @invalid_node_types));
}
} else {
UserError("Partition: No image originally loaded in partition $loadpart on $node_id; this is probably not the partition you meant to save");
}
UserError("Node Types: Must select at least one node type")
if ($node_types_selected == 0 && !($force || $isdataset));
}
# XXX Allowable OS types, OS features, and OpModes need to be
......@@ -787,13 +778,6 @@ if (!$isdataset) {
fatal("Could not create new OSID!")
if (!defined($new_osinfo));
#
# Insert a submap entry.
#
if (defined($parentos)) {
$new_osinfo->SetRunsOnParent($parentos);
}
$newimageid_args{"path"} = $ipath;
$osid = $new_osinfo->osid();
......
#!/usr/bin/perl -wT
#
# Copyright (c) 2011-2013 University of Utah and the Flux Group.
# Copyright (c) 2011-2016 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -72,7 +72,6 @@ use libdb;
use libtestbed;
use User;
use Project;
use OSinfo;
use EmulabFeatures;
# Protos
......
#
# Copyright (c) 2000-2014 University of Utah and the Flux Group.
# Copyright (c) 2000-2016 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -43,7 +43,7 @@ control-install: control-install-subdirs
fs-install: fs-install-subdirs
client-install: client-install-subdirs
subboss: client
subboss-install: client-install
subboss-install: subboss-install-subdirs
clean: clean-subdirs
distclean: distclean-subdirs
mfs frisbee-mfs newnode-mfs:
......
#
# Copyright (c) 2000-2015 University of Utah and the Flux Group.
# Copyright (c) 2000-2016 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -179,6 +179,7 @@ fs-install:
client: $(LIBS)
client-install: client # client-libinstall
client-libinstall: client-pylibinstall client-pllibinstall
subboss-install: client client-libinstall
#
# XXX Fix the python install location.
......
#
# Copyright (c) 2000-2012 University of Utah and the Flux Group.
# Copyright (c) 2000-2012, 2016 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -32,6 +32,7 @@ all: libtb.a
client: libtb-nodb.a
cmp -s libtb-nodb.a libtb.a || cp -pf libtb-nodb.a libtb.a
client-install: client
subboss-install: client
# The point of this is to make sure a nodb version of the library is
# built during the ops-install target when installing a new emulab.
......
#!/usr/bin/perl -wT
#
# Copyright (c) 2000-2015 University of Utah and the Flux Group.
# Copyright (c) 2000-2016 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -37,6 +37,7 @@ use Exporter;
TBSCRIPTLOCK_WOULDBLOCK TBSCRIPTLOCK_INTERRUPTED
TBSCRIPTLOCK_INTERRUPTIBLE
TBTimeStamp TBTimeStampWithDate TBBackGround ReOpenLog
CheckDaemonRunning MarkDaemonRunning MarkDaemonStopped);
);
# Must come after package declaration!
......@@ -465,5 +466,54 @@ sub TBScriptUnlock(;$)
}
}
#
# Check for the existence of a pid file and see if that file is
# running. Mostly cause of devel tree versions.
#
sub CheckDaemonRunning($)
{
my ($name) = @_;
my $pidfile = "/var/run/${name}.pid";
if (-e $pidfile) {
my $opid = `cat $pidfile`;
if ($opid =~ /^(\d*)$/) {
$opid = $1;
}
else {
print STDERR "$pidfile exists, but $opid is malformed\n";
return 1;
}
if (kill(0, $opid)) {
print STDERR "$pidfile exists, and process $opid is running\n";
return 1;
}
unlink($pidfile);
}
return 0;
}
#
# Mark a daemon as running.
#
sub MarkDaemonRunning($)
{
my ($name) = @_;
my $pidfile = "/var/run/${name}.pid";
if (system("echo '$PID' > $pidfile")) {
print STDERR "Could not create $pidfile\n";
return -1;
}
return 0;
}
sub MarkDaemonStopped($)
{
my ($name) = @_;
my $pidfile = "/var/run/${name}.pid";
unlink($pidfile);
return 0;
}
1;
......@@ -64,6 +64,8 @@ mfs:*frisbee)
;;
*)
echo "rebooting..."
$BINDIR/tmcc state SHUTDOWN
sleep 1
reboot
;;
esac
......
......@@ -643,14 +643,14 @@ sub LoadEstimate($)
{
my ($blockstore) = @_;
my $bsname = $blockstore->vname();
require Image;
require OSImage;
if (!exists($blockstore->{'attributes'}->{"dataset"})) {
print STDERR "No dataset attribute for $bsname\n";
return -1;
}
my $dataset = $blockstore->{'attributes'}->{"dataset"};
my $image = Image->Lookup($dataset);
my $image = OSImage->Lookup($dataset);
if (!defined($image)) {
print STDERR "No image for dataset $dataset for $bsname\n";
return -1;
......
#
# Copyright (c) 2000-2014 University of Utah and the Flux Group.
# Copyright (c) 2000-2016 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -51,7 +50,7 @@ LIB_SCRIPTS = libdb.pm Node.pm libdb.py libadminctrl.pm Experiment.pm \
EmulabFeatures.pm Port.pm BlockstoreType.pm Blockstore.pm \
IPBuddyAlloc.pm IPBuddyWrapper.pm Lease.pm Quota.pm \
libTaintStates.pm WebSession.pm WebTask.pm Brand.pm \
Reservation.pm
Reservation.pm OSImage.pm
# Stuff installed on plastic.
USERSBINS = genelists.proxy dumperrorlog.proxy backup
......@@ -80,6 +79,8 @@ endif
#
all: $(TARGETS)
subboss: $(SUBBOSS_SBIN_SCRIPTS)
$(SUBBOSS_SBIN_SCRIPTS):
include $(TESTBED_SRCDIR)/GNUmakerules
......
......@@ -321,6 +321,20 @@ sub field($$) {
}
return undef;
}
sub fieldExists($$) {
my ($self, $name) = @_;
return 1
if (exists($self->{'IMAGE'}->{$name}));
return 0;
}
sub fieldSet($$$) {
my ($self, $name, $value) = @_;
$self->{'IMAGE'}->{$name} = $value;
return $value;
}
sub isImageAlias($) { return 0; }
# Break circular reference someplace to avoid exit errors.
sub DESTROY {
......@@ -484,33 +498,6 @@ sub LookupByAuthorityURN($$)
return Image->Lookup($imageid);
}
#
# Get a list of all running frisbee images.
# XXX if this is actually used, it will have to be fixed; DB no longer
# tracks running frisbee daemons.
#
sub ActiveImages($)
{
my ($class) = @_;
my @result = ();
my $query_result =
DBQueryWarn("select imageid,imageid_version from frisbee_blobs ".
"where frisbee_pid!=0");
return undef
if (!defined($query_result));
while (my ($imageid,$version) = $query_result->fetchrow_array()) {
my $image = Image->Lookup($imageid, $version);
if (!defined($image)) {
print STDERR "*** Could not find DB object for image $imageid\n";
return undef;
}
push(@result, $image);
}
return \@result;
}
#
# Return a list of all images of the given format for the given pid.
# If format is NULL, return all formats. If pid is NULL, return for all pids.
......@@ -620,6 +607,8 @@ sub Create($$$$$$$$)
my $isadmin = $creator->IsAdmin();
my $isdataset = (exists($argref->{"isdataset"}) ?
$argref->{"isdataset"} : 0);
my $architecture = $argref->{'architecture'}
if (defined($argref->{'architecture'}));
# We may ignore particular partN_osid's by deleting them.
my @arg_slots = grep(/^part[1-4]_osid$/, keys(%{$argref}));
......@@ -720,9 +709,13 @@ sub Create($$$$$$$$)
$bquery .= ",pid='$pid',pid_idx='$pid_idx'";
$bquery .= ",gid='$gid',gid_idx='$gid_idx'";
# image_versions include all the images stuff.
my $query = "insert into image_versions set $bquery, ".
join(",", map("$_='" . $argref->{$_} . "'", @arg_slots));
# except for this.
$bquery .= ",architecture='$architecture'"
if (defined($architecture));
$query .= ",creator='$uid',creator_idx='$uid_idx'";
$query .= ",uuid='$version_uuid'";
$query .= ",created=now()";
......@@ -766,7 +759,8 @@ sub Create($$$$$$$$)
# Create the osidtoimageid mapping. Admins have an option to do it or not.
my $makedefault = exists($argref->{"makedefault"}) &&
$argref->{"makedefault"} eq "1";
if (!$isdataset && (!$isadmin || $makedefault)) {
if (!$isdataset && !defined($architecture) && (!$isadmin || $makedefault)){
#
# Dig out the mtypes we want to turn on. The caller has already
# sanity checked them to make sure the types actually exist, and
......@@ -825,12 +819,22 @@ sub NewVersion($$$$)
my $ostablename = "os_info_versions" . $tableid;
my $imtablename = "image_versions" . $tableid;
#
# Grab the current type list. Do this before table locking.
#
if (!$isdataset) {
my @typelist = $self->TypeList();
$typelist = join(",", @typelist)
if (@typelist);
}
#
# The pid/imageid has to be unique, so lock the table for the check/insert.
#
DBQueryWarn("lock tables images write, image_versions write, ".
" os_info write, os_info_versions write, ".
" emulab_indicies write, osidtoimageid read")
" emulab_indicies write, osidtoimageid read, ".
" node_types read")
or return undef;
my $query_result =
......@@ -848,22 +852,6 @@ sub NewVersion($$$$)<