load-descriptors.in 7.4 KB
Newer Older
1 2
#!/usr/bin/perl -w
#
3
# Copyright (c) 2007-2012 University of Utah and the Flux Group.
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
# 
# {{{EMULAB-LICENSE
# 
# This file is part of the Emulab network testbed software.
# 
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
# 
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
# License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this file.  If not, see <http://www.gnu.org/licenses/>.
# 
# }}}
23 24 25 26
#
use English;
use Getopt::Std;
use strict;
27 28
use XML::Simple;
use Data::Dumper;
29 30 31 32 33 34 35

#
# Load in descriptors for images and osids. The input to this script is
# a file created with the dump-descriptors script in this directory,
#
sub usage()
{
36
    print STDOUT "Usage: load-descriptors [-f] [-a] filename\n";
37 38
    exit(-1);
}
39
my $optlist = "dfa";
40 41
my $force   = 0;
my $debug   = 0;
42
my $alltypes= 0;
43 44 45 46 47

#
# These are the OSIDs that are used to populate the osidtoimageid table
# using their nextosid entries.
#
48
my @standard_osnames  = ('RHL-STD', 'FBSD-STD');
49 50 51 52 53 54 55 56

#
# Configure variables
#
my $TB		= "@prefix@";
my $TBOPS       = "@TBOPSEMAIL@";
my $TBLOGS      = "@TBLOGSEMAIL@";
my $BOSSNODE	= "@BOSSNODE@";
57 58 59
my $NEWOSID     = "$TB/bin/newosid";
my $NEWIMAGE    = "$TB/bin/newimageid";
my $NEWIMAGE_EZ = "$TB/bin/newimageid_ez";
60 61 62 63 64 65 66 67 68

#
# Testbed Support libraries
#
use lib "@prefix@/lib";
use libdb;
use libtestbed;
use User;
use Project;
69 70
use OSinfo;
use Image;
71 72 73 74

#$libdb::DBQUERY_DEBUG = 1;

# Local
75 76 77
my %osidtoimageid  = ();
my %local_osids    = ();
my %local_imageids = ();
78 79 80 81 82 83 84 85 86 87 88 89 90 91

#
# Turn off line buffering on output
#
$| = 1;

#
# Untaint the path
# 
$ENV{'PATH'} = "/bin:/sbin:/usr/bin:";
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

# Protos
sub fatal($);
92
sub ParseIt($);
93

94 95 96 97 98 99 100 101 102 103 104
#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
my %options = ();
if (! getopts($optlist, \%options)) {
    usage();
}
if (defined($options{"d"})) {
    $debug = 1;
}
105 106 107
if (defined($options{"a"})) {
    $alltypes = 1;
}
108 109 110
if (defined($options{"f"})) {
    $force = 1;
}
111 112 113 114 115
usage()
    if (@ARGV != 1);
my $filename = $ARGV[0];

#
116
#
117 118 119 120 121
#
my $protouser = User->Lookup("elabman");
if (!defined($protouser)) {
    fatal("Could not look up object for protouser (elabman)");
}
122 123 124 125
my $PROTOPROJ = TBOPSPID();
my %mappings  = ();
my %images    = ();
my %osinfos   = ();
126 127 128 129 130 131 132

#
# Open tempfile.
#
open(OUTPUT, "$filename") or
    die("Could not open $filename for reading!\n");

133 134
my $which = "";
my $tmp   = "";
135

136 137 138 139 140 141
while (<OUTPUT>) {
    next
	if ($_ =~ /descriptors\>/);
	
    if ($_ =~ /\<mapping/) {
	$which = "mapping";
142
    }
143 144
    elsif ($_ =~ /\<osid\>/) {
	$which = "osid";
145
    }
146 147
    elsif ($_ =~ /\<image\>/) {
	$which = "image";
148
    }
149 150 151 152 153
    if ($_ =~ /\<\/mapping\>/) {
	my $mapping = ParseIt($tmp . $_);
	$mappings{$mapping->{'name'}} = $mapping->{'value'};
	$tmp = "";
	next;
154
    }
155 156 157 158 159 160
    elsif ($_ =~ /\<\/osid\>/) {
	my $osinfo = ParseIt($tmp . $_);
	$osinfos{$osinfo->{'attribute'}->{"osname"}->{'value'}} =
	    [$osinfo, $tmp . $_];
	$tmp = "";
	next;
161
    }
162 163 164 165 166 167
    elsif ($_ =~ /\<\/image\>/) {
	my $image = ParseIt($tmp . $_);
	$images{$image->{'attribute'}->{"imagename"}->{'value'}} =
	    [$image, $tmp . $_];
	$tmp = "";
	next;
168
    }
169
    $tmp .= $_;
170
}
171
close(OUTPUT);
172

173
#
174 175 176 177
# Must create the OSids first since the images reference them. But must
# do this in two passes since there are nextosid references. But, the EZ
# imageIDs also create OSids that can be referenced by nextosid, so must
# do those after the first OSid pass but before the second one.
178
#
179 180
foreach my $osname (keys(%osinfos)) {
    my ($xmlparse, $string) = @{ $osinfos{$osname} };
181
    my $nextosid  = exists($xmlparse->{'attribute'}->{"nextosid"});
182

183 184
    next
	if ($nextosid);
185

186 187 188 189
    my $osinfo = OSinfo->Lookup("$PROTOPROJ,$osname");
    if (defined($osinfo) && !$force) {
	print STDERR "OS $osname already exists. Skipping; use -f option\n";
	next;
190
    }
191 192 193 194 195 196
    open(NEW, "| $NEWOSID -")
	or fatal("Cannot start $NEWOSID");
    print NEW $string;
    if (!close(NEW)) {
	print STDERR "$string\n";
	fatal("$osname could not be created");
197 198 199
    }
}
#
200
# Do the EZ images
201
#
202 203 204
foreach my $imagename (keys(%images)) {
    my ($xmlparse, $string) = @{ $images{$imagename} };
    my $ezid  = exists($xmlparse->{'attribute'}->{"OS"});
205
    my $which = ($ezid ? "$NEWIMAGE_EZ -a " : $NEWIMAGE);
206

207 208
    next
	if (! $ezid);
209

210 211 212 213 214 215 216 217 218 219 220 221
    my $image = Image->Lookup("$PROTOPROJ,$imagename");
    if (defined($image) && !$force) {
	print STDERR
	    "Image $imagename already exists. Skipping; use -f option\n";
	next;
    }
    open(NEW, "| $which -f -")
	or fatal("Cannot start $which");
    print NEW $string;
    if (!close(NEW)) {
	print STDERR "$string\n";
	fatal("Image $imagename could not be created");
222
    }
223
}
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
#
# Now the rest of the OSids.
#
foreach my $osname (keys(%osinfos)) {
    my ($xmlparse, $string) = @{ $osinfos{$osname} };
    my $nextosid  = exists($xmlparse->{'attribute'}->{"nextosid"});

    next
	if (!$nextosid);

    my $osinfo = OSinfo->Lookup("$PROTOPROJ,$osname");
    if (defined($osinfo) && !$force) {
	print STDERR "OS $osname already exists. Skipping; use -f option\n";
	next;
    }
    open(NEW, "| $NEWOSID -")
	or fatal("Cannot start $NEWOSID");
    print NEW $string;
    if (!close(NEW)) {
	print STDERR "$string\n";
	fatal("$osname could not be created");
    }
}
#
# And the rest of the images.
#
250 251 252 253 254 255 256 257 258 259 260 261
foreach my $imagename (keys(%images)) {
    my ($xmlparse, $string) = @{ $images{$imagename} };
    my $ezid  = exists($xmlparse->{'attribute'}->{"OS"});
    my $which = ($ezid ? $NEWIMAGE_EZ : $NEWIMAGE);

    next
	if ($ezid);

    my $image = Image->Lookup("$PROTOPROJ,$imagename");
    if (defined($image) && !$force) {
	print STDERR
	    "Image $imagename already exists. Skipping; use -f option\n";
262 263
	next;
    }
264 265 266 267 268 269 270
    open(NEW, "| $which -f -")
	or fatal("Cannot start $which");
    print NEW $string;
    if (!close(NEW)) {
	print STDERR "$string\n";
	fatal("Image $imagename could not be created");
    }
271 272
}
#
273
# Now do the nextosid mappings.
274
#
275 276 277 278
foreach my $osid (keys(%mappings)) {
    my $nextosid   = $mappings{$osid};
    my $osinfo     = OSinfo->Lookup("$PROTOPROJ,$osid");
    my $nextosinfo = OSinfo->Lookup("$PROTOPROJ,$nextosid");
279

280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
    if (!defined($osinfo)) {
	fatal("Could not find osid $osid");
    }
    if (!defined($nextosinfo)) {
	fatal("Could not find nextosid $nextosid");
    }
    if (defined($osinfo->nextosid()) &&
	$osinfo->nextosid() != $nextosinfo->osid()) {
	my $current;

	if ($osinfo->nextosid()) {
	    $current = OSinfo->Lookup($osinfo->nextosid());
	}
	else {
	    # So bogus.
	    $current = "osid_map";
	}
	print STDERR "nextosid for $osinfo wants to be $nextosinfo, ".
	    "but its already set to $current. Skipping ...\n";
	next;
    }
    print "Setting nextosid for $osinfo to $nextosinfo\n";
    if ($osinfo->SetNextOS($nextosinfo)) {
	fatal("Could not set nextosid for $osinfo to $nextosinfo");
304 305 306 307 308
    }
}

exit(0);

309 310 311 312 313 314 315 316 317 318 319 320 321 322
sub ParseIt($)
{
    my ($string) = @_;

    my $xmlparse = eval { XMLin($string,
				VarAttr => 'name',
				ContentKey => '-content',
				SuppressEmpty => undef); };
    fatal($@)
	if ($@);
    
    return $xmlparse;
}

323 324 325 326 327 328 329 330 331
sub fatal($)
{
    my ($mesg) = $_[0];

    die("*** $0:\n".
	"    $mesg\n");
}