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 36d218a5 authored by Mike Hibler's avatar Mike Hibler

Merge remote branch 'central/master' into rebaseit

parents 6feda7d3 fd9b70d8
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2009 University of Utah and the Flux Group.
# Copyright (c) 2000-2010 University of Utah and the Flux Group.
# All rights reserved.
#
# Testbed Makefile
......@@ -67,12 +67,15 @@ boss-install: install-schemacheck install-sitevarscheck install-dbfillcheck \
install-setbuildinfo
@echo "Boss node installed!"
#
# Same target, with the install-schemacheck dependency omitted
#
# Same target, with the checks omitted
boss-install-force: install-subdirs install-mkdirs install-setbuildinfo
@echo "Boss node installed!"
# Skip only the schema checks, but do the other checks.
boss-install-noschemacheck: install-sitevarscheck install-dbfillcheck \
install-genischemacheck install-subdirs install-mkdirs \
install-setbuildinfo
clrhouse-install: install-subdirs install-mkdirs
@echo "CleaingHouse code installed!"
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2008 University of Utah and the Flux Group.
# Copyright (c) 2000-2010 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......@@ -149,6 +149,7 @@ my %xmlfields =
"issimnode" => ["issimnode", $SLOT_OPTIONAL],
"isgeninode" => ["isgeninode", $SLOT_OPTIONAL],
"isfednode" => ["isfednode", $SLOT_OPTIONAL],
"isswitch" => ["isswitch", $SLOT_OPTIONAL],
# Dynamic attributes with wildcards.
"attr_boolean_*" => ["attr_boolean", $SLOT_OPTIONAL],
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2008 University of Utah and the Flux Group.
# Copyright (c) 2000-2008, 2010 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......@@ -18,8 +18,9 @@ sub usage()
print("Usage: newimageid [-v] <xmlfile>\n");
exit(-1);
}
my $optlist = "dv";
my $optlist = "dvf";
my $debug = 0;
my $force = 0;
my $verify = 0; # Check data and return status only.
#
......@@ -68,6 +69,9 @@ if (! getopts($optlist, \%options)) {
if (defined($options{"d"})) {
$debug = 1;
}
if (defined($options{"f"})) {
$force = 1;
}
if (defined($options{"v"})) {
$verify = 1;
}
......@@ -266,11 +270,32 @@ foreach $key (keys(%{ $xmlparse->{'attribute'} })) {
if (! $this_user->IsAdmin());
}
# Now check that the value is legal.
if (! TBcheck_dbslot($value, "images",
$dbslot, TBDB_CHECKDBSLOT_ERROR)) {
$errors{$key} = TBFieldErrorString();
next;
#
# Special case osids so they can be in pid,osname format.
#
if (($dbslot eq "default_osid" || $dbslot =~ /^part\d/) &&
$value =~ /^.+,.+$/) {
my ($pid,$osname) = ($value =~ /^(.*),(.*)$/);
# Now check that the value is legal.
if (! TBcheck_dbslot($pid, "projects",
"pid", TBDB_CHECKDBSLOT_ERROR)) {
$errors{$key} = TBFieldErrorString();
next;
}
if (! TBcheck_dbslot($osname, "os_info",
"osname", TBDB_CHECKDBSLOT_ERROR)) {
$errors{$key} = TBFieldErrorString();
next;
}
}
else {
# Now check that the value is legal.
if (! TBcheck_dbslot($value, "images",
$dbslot, TBDB_CHECKDBSLOT_ERROR)) {
$errors{$key} = TBFieldErrorString();
next;
}
}
$newimageid_args{$key} = $value;
......@@ -460,7 +485,7 @@ foreach $key (@mtype_keys) {
}
}
UserError("Node Types: Must select at least one node type")
if ($node_types_selected == 0);
if ($node_types_selected == 0 && !$force);
#
# Check sanity of node name and that user can create an image from it.
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2008 University of Utah and the Flux Group.
# Copyright (c) 2000-2010 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......@@ -18,8 +18,9 @@ sub usage()
print("Usage: newimageid [-v] <xmlfile>\n");
exit(-1);
}
my $optlist = "dv";
my $optlist = "dvf";
my $debug = 0;
my $force = 0;
my $verify = 0; # Check data and return status only.
#
......@@ -68,6 +69,9 @@ if (! getopts($optlist, \%options)) {
if (defined($options{"d"})) {
$debug = 1;
}
if (defined($options{"f"})) {
$force = 1;
}
if (defined($options{"v"})) {
$verify = 1;
}
......@@ -487,7 +491,7 @@ foreach $key (@mtype_keys) {
}
}
UserError("Node Types: Must select at least one node type")
if ($node_types_selected == 0);
if ($node_types_selected == 0 && !$force);
#
# We perform a further check for non-admins. When a node to snapshot
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2007 University of Utah and the Flux Group.
# Copyright (c) 2000-2010 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......@@ -132,13 +132,14 @@ my %xmlfields =
# XML Field Name DB slot name Flags Default
("description" => ["description", $SLOT_REQUIRED],
"osname" => ["osname" , $SLOT_REQUIRED],
"project" => ["pid_idx", $SLOT_REQUIRED],
"pid" => ["pid", $SLOT_REQUIRED],
"OS" => ["OS", $SLOT_REQUIRED],
"version" => ["version", $SLOT_OPTIONAL, ""],
"path" => ["path", $SLOT_OPTIONAL, "NULL"],
"magic", => ["magic", $SLOT_OPTIONAL, ""],
"op_mode", => ["op_mode", $SLOT_REQUIRED],
"features", => ["osfeatures", $SLOT_OPTIONAL, ""],
"mfs", => ["mfs", $SLOT_ADMINONLY, 0],
"shared", => ["shared", $SLOT_ADMINONLY, 0],
"mustclean", => ["mustclean", $SLOT_ADMINONLY, 1],
"nextosid", => ["nextosid", $SLOT_ADMINONLY],
......@@ -257,12 +258,32 @@ foreach $key (keys(%{ $xmlparse->{'attribute'} })) {
$errors{$key} = "Administrators only"
if (! $this_user->IsAdmin());
}
#
# Special case nextosid so it can be in pid,osname format.
#
if ($dbslot eq "nextosid" && $value =~ /^.+,.+$/) {
my ($pid,$osname) = ($value =~ /^(.*),(.*)$/);
# Now check that the value is legal.
if (! TBcheck_dbslot($value, "os_info",
$dbslot, TBDB_CHECKDBSLOT_ERROR)) {
$errors{$key} = TBFieldErrorString();
next;
# Now check that the value is legal.
if (! TBcheck_dbslot($pid, "projects",
"pid", TBDB_CHECKDBSLOT_ERROR)) {
$errors{$key} = TBFieldErrorString();
next;
}
if (! TBcheck_dbslot($osname, "os_info",
"osname", TBDB_CHECKDBSLOT_ERROR)) {
$errors{$key} = TBFieldErrorString();
next;
}
}
else {
# Now check that the value is legal.
if (! TBcheck_dbslot($value, "os_info",
$dbslot, TBDB_CHECKDBSLOT_ERROR)) {
$errors{$key} = TBFieldErrorString();
next;
}
}
$newosid_args{$key} = $value;
......@@ -273,9 +294,9 @@ UserError()
#
# Now do special checks.
#
my $project = Project->Lookup($newosid_args{"project"});
my $project = Project->Lookup($newosid_args{"pid"});
if (!defined($project)) {
UserError("Project: No such project ($project)");
UserError("Project: No such project");
}
if (!$project->AccessCheck($this_user, TB_PROJECT_MAKEOSID())) {
UserError("Project: Not enough permission");
......@@ -297,6 +318,8 @@ if (exists($newosid_args{"nextosid"})) {
if (!defined($nextos)) {
UserError("Nextosid: Does not exist");
}
# Might be in pid,osname format.
$newosid_args{"nextosid"} = $nextos->osid();
}
# Mere users have to supply a version, but admin people do not.
......
......@@ -8,7 +8,7 @@ package Experiment;
use strict;
use Exporter;
use vars qw(@ISA @EXPORT);
use vars qw(@ISA @EXPORT $AUTOLOAD);
@ISA = "Exporter";
@EXPORT = qw ( );
......@@ -275,78 +275,38 @@ sub Lookup($$;$)
return $self;
}
# accessors
sub field($$) { return ((! ref($_[0])) ? -1 : $_[0]->{'EXPT'}->{$_[1]}); }
sub stats($$) { return ((! ref($_[0])) ? -1 : $_[0]->{'STATS'}->{$_[1]});}
sub resources($$) { return ((! ref($_[0])) ? -1 : $_[0]->{'RSRC'}->{$_[1]}); }
# To avoid writting out all the methods.
sub AUTOLOAD {
my $self = shift;
my $type = ref($self) or die("$self is not an object\n");
my $name = $AUTOLOAD;
$name =~ s/.*://; # strip fully-qualified portion
if (exists($self->{'EXPT'}->{$name})) {
return $self->{'EXPT'}->{$name};
}
elsif (exists($self->{'STATS'}->{$name})) {
return $self->{'STATS'}->{$name};
}
elsif (exists($self->{'RSRC'}->{$name})) {
return $self->{'RSRC'}->{$name};
}
print STDERR "$self: tried to access unknown slot $name\n";
return undef;
}
sub dbrow($$) { return $_[0]->{'EXPT'}; }
sub pid($) { return field($_[0], 'pid'); }
sub gid($) { return field($_[0], 'gid'); }
sub pid_idx($) { return field($_[0], 'pid_idx'); }
sub gid_idx($) { return field($_[0], 'gid_idx'); }
sub eid($) { return field($_[0], 'eid'); }
sub idx($) { return field($_[0], 'idx'); }
sub uuid($) { return field($_[0], 'eid_uuid'); }
sub eid_uuid($) { return field($_[0], 'eid_uuid'); }
sub description($) { return field($_[0], 'expt_name'); }
sub path($) { return field($_[0], 'path'); }
sub state($) { return field($_[0], 'state'); }
sub batchstate($) { return field($_[0], 'batchstate'); }
sub batchmode($) { return field($_[0], 'batchmode'); }
sub rsrcidx($) { return stats($_[0], 'rsrcidx'); }
sub lastrsrc($) { return stats($_[0], 'lastrsrc'); }
sub creator($) { return field($_[0], 'expt_head_uid');}
sub locked($) { return field($_[0], 'expt_locked'); }
sub elabinelab($) { return field($_[0], 'elab_in_elab');}
sub elabinelab_eid($) { return field($_[0], 'elabinelab_eid');}
sub elabinelab_exptidx($){return field($_[0], 'elabinelab_exptidx');}
sub elabinelab_nosetup($){return field($_[0], 'elabinelab_nosetup');}
sub elabinelab_singlenet($){return field($_[0], 'elabinelab_singlenet');}
sub elabinelab_cvstag($){return field($_[0], 'elabinelab_cvstag');}
sub lockdown($) { return field($_[0], 'lockdown'); }
sub geniflags($) { return field($_[0], 'geniflags'); }
sub created($) { return field($_[0], 'expt_created'); }
sub swapper($) { return field($_[0], 'expt_swap_uid');}
sub swappable($) { return field($_[0], 'swappable');}
sub idleswap($) { return field($_[0], 'idleswap');}
sub autoswap($) { return field($_[0], 'autoswap');}
sub noswap_reason($) { return field($_[0], 'noswap_reason');}
sub noidleswap_reason($){ return field($_[0], 'noidleswap_reason');}
sub idleswap_timeout($) { return field($_[0], 'idleswap_timeout');}
sub autoswap_timeout($) { return field($_[0], 'autoswap_timeout');}
sub prerender_pid($) { return field($_[0], 'prerender_pid');}
sub dpdb($) { return field($_[0], 'dpdb');}
sub dpdbname($) { return field($_[0], 'dpdbname');}
sub dpdbpassword($) { return field($_[0], 'dpdbpassword');}
sub instance_idx($) { return field($_[0], 'instance_idx'); }
sub creator_idx($) { return field($_[0], 'creator_idx');}
sub swapper_idx($) { return field($_[0], 'swapper_idx');}
sub use_ipassign($) { return field($_[0], 'use_ipassign');}
sub ipassign_args($) { return field($_[0], 'ipassign_args');}
sub security_level($) { return field($_[0], 'security_level');}
sub linktest_pid($) { return field($_[0], 'linktest_pid');}
sub linktest_level($) { return field($_[0], 'linktest_level');}
sub logfile($) { return field($_[0], 'logfile');}
sub eventkey($) { return field($_[0], 'eventkey');}
sub keyhash($) { return field($_[0], 'keyhash');}
sub paniced($) { return field($_[0], 'paniced');}
sub cpu_usage($) { return field($_[0], 'cpu_usage');}
sub encap_style($) { return field($_[0], 'encap_style');}
sub minimum_nodes($) { return field($_[0], 'minimum_nodes');}
sub maximum_nodes($) { return field($_[0], 'maximum_nodes');}
sub multiplex_factor($) { return field($_[0], 'multiplex_factor');}
sub delay_capacity($) { return field($_[0], 'delay_capacity');}
sub virtnode_count($) { return field($_[0], 'virtnode_count');}
sub archive_idx($) { return stats($_[0], 'archive_idx'); }
sub swapin_count($) { return stats($_[0], 'swapin_count'); }
sub destroyed($) { return stats($_[0], 'destroyed'); }
sub archive_tag($) { return resources($_[0], 'archive_tag'); }
sub thumbnail($) { return resources($_[0], 'thumbnail'); }
sub swapin_time($) { return resources($_[0], 'swapin_time'); }
sub swapout_time($) { return resources($_[0], 'swapout_time'); }
sub lastidx($) { return resources($_[0], 'lastidx'); }
sub input_data_idx($) { return resources($_[0], 'input_data_idx'); }
# Break circular reference someplace to avoid exit errors.
sub DESTROY {
my $self = shift;
$self->{"EXPT"} = undef;
$self->{"STATS"} = undef;
$self->{"RSRC"} = undef;
$self->{'VIRTEXPT'} = undef;
}
#
# For canceled, goto to the DB.
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2007, 2008 University of Utah and the Flux Group.
# Copyright (c) 2007-2010 University of Utah and the Flux Group.
# All rights reserved.
#
package Image;
......@@ -139,6 +139,7 @@ sub ezid($) { return field($_[0], "ezid"); }
sub shared($) { return field($_[0], "shared"); }
sub global($) { return field($_[0], "global"); }
sub updated($) { return field($_[0], "updated"); }
sub mbr_version($) { return field($_[0], "mbr_version"); }
sub access_key($) { return field($_[0], "access_key"); }
#
......
......@@ -1191,6 +1191,7 @@ sub issimnode($) { return NodeTypeInfo($_[0])->issimnode(); }
sub isgeninode($) { return NodeTypeInfo($_[0])->isgeninode(); }
sub isfednode($) { return NodeTypeInfo($_[0])->isfednode(); }
sub isdedicatedremote($) { return NodeTypeInfo($_[0])->isdedicatedremote(); }
sub isswitch($) { return NodeTypeInfo($_[0])->isswitch(); }
#
# And these are the less common attributes, but still common enough to
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2005-2009 University of Utah and the Flux Group.
# Copyright (c) 2005-2010 University of Utah and the Flux Group.
# All rights reserved.
#
package NodeType;
......@@ -82,6 +82,7 @@ sub isplabphysnode($) { return field($_[0], 'isplabphysnode'); }
sub issimnode($) { return field($_[0], 'issimnode'); }
sub isgeninode($) { return field($_[0], 'isgeninode'); }
sub isfednode($) { return field($_[0], 'isfednode'); }
sub isswitch($) { return field($_[0], 'isswitch'); }
#
# Force a reload of the data.
......
......@@ -71,6 +71,10 @@ my %WAITTIMES = ("Linux" => 120,
# OP modes. Mirrored in the web interface. The value is a user-okay flag.
my %OPMODES = ("NORMALv2" => 1,
"NORMALv1" => 0,
"PXEFBSD" => 0,
"RELOAD" => 0,
"OPSNODEBSD" => 0,
"PCVM" => 0,
"MINIMAL" => 1,
"NORMAL" => 1,
"ALWAYSUP" => 1 );
......@@ -573,6 +577,16 @@ sub ResolveNextOSID($;$)
return OSinfo->Lookup($osid);
}
#
# Set the nextosid.
#
sub SetNextOS($$)
{
my ($self, $nextosinfo) = @_;
return $self->Update({"nextosid" => $nextosinfo->osid()});
}
#
# Check if a particular feature is supported.
#
......
......@@ -41,7 +41,7 @@ delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
# Turn off line buffering on output
$| = 1;
use lib "@prefix@/lib";
use lib "/usr/testbed/lib";
use libdb;
use libtestbed;
use NodeType;
......@@ -50,6 +50,9 @@ my $CRTLTAG = TBDB_IFACEROLE_CONTROL();
my $DHCPD_CONF = "/usr/local/etc/dhcpd.conf";
my $DHCPD_TEMPLATE = "/usr/local/etc/dhcpd.conf.template";
my %servernodes = ();
my %dhcp_subbosses = ();
my %tftp_subbosses = ();
my %bootinfo_subbosses = ();
my %singlectlnet = ();
my $template = $DHCPD_TEMPLATE;
my $outfile = "/tmp/dhcpd_makeconf.$$";
......@@ -155,6 +158,28 @@ while (my %row = $query_result->fetchhash()) {
}
}
# Slurp in all of the subboss data to know A) if we should serve the DHCP
# lease to a given node, or if the next-server field should be something
# other than the IP for boss.
$query_result =
DBQueryWarn("select s.node_id, s.service, s.subboss_id, i.IP ".
"from subbosses as s left join interfaces as i on ".
"s.subboss_id=i.node_id where i.role='$CRTLTAG'");
if (! $query_result) {
fatal("Could not dhcpd data from DB!");
}
while (my %row = $query_result->fetchhash()) {
my $node_id = $row{"node_id"};
if ($row{"service"} eq 'tftp') {
$tftp_subbosses{$node_id} = $row{"IP"};
} elsif ($row{"service"} eq 'dhcp') {
$dhcp_subbosses{$node_id} = $row{"IP"};
} elsif ($row{"service"} eq 'bootinfo') {
$bootinfo_subbosses{$node_id} = $row{"IP"};
}
}
open(IF,"<$template") or
fatal("Unable to open $template for reading");
while (<IF>) {
......@@ -239,47 +264,25 @@ while (<IF>) {
}
}
}
elsif (defined $dhcp_subbosses{$node_id}) {
$hostname =
"${spaces}\toption host-name \"$node_id\";\n";
$booting = "${spaces}\tignore booting;\n";
}
else {
$hostname =
"${spaces}\toption host-name \"$node_id\";\n";
my $query_result =
DBQueryWarn( "(select attrvalue from " .
"node_attributes where node_id = '$node_id' " .
" and attrkey = 'tftp_server' ) union " .
"(select attrvalue from " .
"node_type_attributes where type = " .
"'$nodetype' " .
" and attrkey = 'tftp_server') limit 1" );
if (! $query_result) {
fatal("Could not get tftp_server data from DB!");
}
if (my %row = $query_result->fetchhash()) {
my $tftp_server = $row{'attrvalue'};
$next_server = "${spaces}\tnext-server " .
$tftp_server . ";\n";
}
if (defined $tftp_subbosses{$node_id}) {
$next_server = "${spaces}\tnext-server " .
$tftp_subbosses{$node_id} . ";\n";
}
$query_result =
DBQueryWarn( "(select attrvalue from " .
"node_attributes where node_id = '$node_id' " .
" and attrkey = 'bootinfo_server' ) union " .
"(select attrvalue from " .
"node_type_attributes where type = " .
"'$nodetype' " .
" and attrkey = 'bootinfo_server') limit 1" );
if (! $query_result) {
fatal("Could not get bootinfo_server data from DB!");
}
if (defined $bootinfo_subbosses{$node_id}) {
$bootinfo_server = "${spaces}\toption PXE.emulab-bootinfo " .
$bootinfo_subbosses{$node_id} . ";\n";
}
if (my %row = $query_result->fetchhash()) {
$bootinfo_server = "${spaces}\toption " .
"PXE.emulab-bootinfo " .
$row{'attrvalue'} . ";\n";
}
}
#
......
......@@ -1307,26 +1307,6 @@ sub TBOSMaxConcurrent ($)
return $osinfo->max_concurrent();
}
#
# Returns the reboot waittime.
#
# usage: TBOSIDRebootWaittime(char *osid)
# returns >= 1 if there is a waittime
# returns undef if there is no waittime
# returns 0 if not valid.
#
sub TBOSIDRebootWaittime ($)
{
my ($osid) = @_;
require OSinfo;
my $osinfo = OSinfo->Lookup($osid);
return 0
if (!defined($osinfo));
return $osinfo->reboot_waittime();
}
#
# Returns the number of nodes that are supposedly booting an OS. A list of
# nodes that should be excluded from this count can be given.
......
<descriptors>
<osid>
<attribute name="mfs">
<value>1</value>
</attribute>
<attribute name="features">
<value>ping,ssh,ipod,isup</value>
</attribute>
<attribute name="version">
<value>6.2</value>
</attribute>
<attribute name="path">
<value>boss:/tftpboot/frisbee</value>
</attribute>
<attribute name="reboot_waittime">
<value>150</value>
</attribute>
<attribute name="description">
<value>Frisbee (FreeBSD) in an MFS</value>
</attribute>
<attribute name="mustclean">
<value>0</value>
</attribute>
<attribute name="shared">
<value>1</value>
</attribute>
<attribute name="op_mode">
<value>RELOAD</value>
</attribute>
<attribute name="pid">
<value>emulab-ops</value>
</attribute>
<attribute name="osname">
<value>FRISBEE-MFS</value>
</attribute>
<attribute name="OS">
<value>FreeBSD</value>
</attribute>
</osid>
<osid>
<attribute name="mfs">
<value>1</value>
</attribute>
<attribute name="features">
<value>ping,ssh,ipod,isup</value>
</attribute>
<attribute name="version">
<value>4.X</value>
</attribute>
<attribute name="reboot_waittime">
<value>150</value>
</attribute>
<attribute name="description">
<value>FreeBSD on the Operations Node</value>
</attribute>
<attribute name="mustclean">
<value>0</value>
</attribute>
<attribute name="op_mode">
<value>OPSNODEBSD</value>
</attribute>