load-descriptors.in 6.97 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2007 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
use Getopt::Std;
use strict;

#
# 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()
{
    print STDOUT "Usage: load-descriptors filename\n";
    exit(-1);
}

#
# These are the OSIDs that are used to populate the osidtoimageid table
# using their nextosid entries.
#
25
my @standard_osnames  = ('RHL-STD', 'FBSD-STD');
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

#
# Configure variables
#
my $TB		= "@prefix@";
my $TBOPS       = "@TBOPSEMAIL@";
my $TBLOGS      = "@TBLOGSEMAIL@";
my $BOSSNODE	= "@BOSSNODE@";
my $TFTPDIR     = "/tftpboot";

#
# Testbed Support libraries
#
use lib "@prefix@/lib";
use libdb;
use libtestbed;
use User;
use Project;

#$libdb::DBQUERY_DEBUG = 1;

# Local
48
49
50
my %osidtoimageid  = ();
my %local_osids    = ();
my %local_imageids = ();
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88

#
# 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($);

usage()
    if (@ARGV != 1);
my $filename = $ARGV[0];

#
# We need to know various indicies, for the protouser (elabman) and the
# TBOPSPID (emulab-ops) project.
#
my $protouser = User->Lookup("elabman");
if (!defined($protouser)) {
    fatal("Could not look up object for protouser (elabman)");
}
my $user_uid = $protouser->uid();
my $user_idx = $protouser->uid_idx();

my $protoproj = Project->Lookup(TBOPSPID());
if (!defined($protoproj)) {
    fatal("Could not look up object for protoproj");
}
my $pid     = $protoproj->pid();
my $pid_idx = $protoproj->pid_idx();
my $gid     = $protoproj->gid();
my $gid_idx = $protoproj->gid_idx();
89
my $douuids = 0;
90
91

# Temp tables to hold new rows.
92
93
94
DBQueryFatal("create table temp_images like images");
DBQueryFatal("create table temp_os_info like os_info");
DBQueryFatal("create table temp_o2i like osidtoimageid");
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

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

while (<OUTPUT>) {
    DBQueryFatal($_);
}
close(OUTPUT);

#
# See if the local images table has the new indicies. 
#
my $describe_result = DBQueryFatal("describe images");

while (my $rowref = $describe_result->fetchrow_hashref()) {
    my $slot  = $rowref->{"Field"};

    if ($slot eq "pid_idx") {
	DBQueryFatal("update temp_images set pid_idx='$pid_idx'");
    }
    elsif ($slot eq "gid_idx") {
	DBQueryFatal("update temp_images set gid_idx='$gid_idx'");
    }
    elsif ($slot eq "creator_idx") {
	DBQueryFatal("update temp_images set creator_idx='$user_idx'");
    }
124
125
126
    elsif ($slot eq "uuid") {
	douuids++;
    }
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
}

#
# Ditto for os_info table
#
$describe_result = DBQueryFatal("describe os_info");

while (my $rowref = $describe_result->fetchrow_hashref()) {
    my $slot  = $rowref->{"Field"};

    if ($slot eq "pid_idx") {
	DBQueryFatal("update temp_os_info set pid_idx='$pid_idx'");
    }
    elsif ($slot eq "creator_idx") {
	DBQueryFatal("update temp_os_info set creator_idx='$user_idx'");
    }
}

145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#
# Go through the new set of os_info entries and assign local IDs to them.
# Remember them since we need to change the new images table too.
#
my $query_result = DBQueryFatal("select osid from temp_os_info");

while (my ($osid) = $query_result->fetchrow_array()) {
    $local_osids{$osid} = TBGetUniqueIndex("next_osid", 1000);
}

#
# Update temp_os_info with locally derived osids. nextosid as well.
#
$query_result->dataseek(0);

while (my ($osid) = $query_result->fetchrow_array()) {
    my $newosid = $local_osids{$osid};

    DBQueryFatal("update temp_os_info set osid='$newosid' ".
		 "where osid='$osid'");
    DBQueryFatal("update temp_os_info set nextosid='$newosid' ".
		 "where nextosid='$osid'");
167
168
169
170
171
172
    if ($uuids) {
	my $uuid = NewUUID();
	
	DBQueryFatal("update temp_os_info set uuid='$uuid' ".
		     "where nextosid='$osid'");
    }
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
}

#
# Go through new set of images entries, but watch for ezid images since they
# have the same ID as its corresponding os_info entry.
#
$query_result = DBQueryFatal("select imageid,ezid from temp_images");

while (my ($imageid,$ezid) = $query_result->fetchrow_array()) {
    if ($ezid) {
	$local_imageids{$imageid} = $local_osids{$imageid};
    }
    else {
	$local_imageids{$imageid} = TBGetUniqueIndex("next_osid", 1000);
    }
}

#
# Update temp_images with locally derived imageids.
#
$query_result->dataseek(0);

while (my ($imageid) = $query_result->fetchrow_array()) {
    my $newimageid = $local_imageids{$imageid};

    DBQueryFatal("update temp_images set imageid='$newimageid' ".
		 "where imageid='$imageid'");
200
201
202
203
204
205
206

    if ($uuids) {
	my $uuid = NewUUID();
	
	DBQueryFatal("update temp_images set uuid='$uuid' ".
		     "where imageid='$imageid'");
    }
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
}

#
# And then update osids inside temp_images with locally derived imageids.
#
foreach my $osid (keys(%local_osids)) {
    my $newosid = $local_osids{$osid};

    DBQueryFatal("update temp_images set part1_osid='$newosid' ".
		 "where part1_osid='$osid'");
    DBQueryFatal("update temp_images set part2_osid='$newosid' ".
		 "where part2_osid='$osid'");
    DBQueryFatal("update temp_images set part3_osid='$newosid' ".
		 "where part3_osid='$osid'");
    DBQueryFatal("update temp_images set part4_osid='$newosid' ".
		 "where part4_osid='$osid'");
    DBQueryFatal("update temp_images set default_osid='$newosid' ".
		 "where default_osid='$osid'");
}

227
228
229
230
#
# Use the nextosid slot of the -STD osids to figure out what the default
# images are.
#
231
$query_result =
232
233
    DBQueryFatal("select nextosid from temp_os_info ".
		 "where nextosid is not null and (".
234
		 join(" or ", map("osname='$_'", @standard_osnames)) . ")");
235
236
237

while (my ($nextosid) = $query_result->fetchrow_array()) {
    my $subquery_result =
238
239
	DBQueryFatal("select imageid from temp_images ".
		     "where loadlength=1 and (".
240
241
		     join(" or ", map("$_='$nextosid'",
				      ("part1_osid", "part2_osid",
242
				       "part3_osid", "part4_osid"))) . ")");
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263

    if (!$subquery_result->numrows) {
	print "*** WARNING: No osidtoimageid mapping for $nextosid\n";
	next;
    }
    my ($imageid) = $subquery_result->fetchrow_array();
    
    $osidtoimageid{$nextosid} = $imageid;
}

#
# Make up osidtoimageid entries for all local PCs. This is a shotgun
# approach, but for a new testbed is probably the right thing.
#
$query_result =
    DBQueryFatal("select type from node_types where class='pc'");

while (my ($type) = $query_result->fetchrow_array()) {
    foreach my $osid (keys(%osidtoimageid)) {
	my $imageid = $osidtoimageid{$osid};

264
	DBQueryFatal("replace into temp_o2i values ".
265
266
267
268
		     "('$osid', '$type', '$imageid')");
    }
}

269
270
271
272
273
274
275
276
#
# Ready to populate the tables. Move the entries from temp_images and
# temp_os_info across to the real tables.
#
DBQueryFatal("replace into images select * from temp_images");
DBQueryFatal("replace into os_info select * from temp_os_info");
DBQueryFatal("replace into osidtoimageid select * from temp_o2i");

277
278
279
280
281
282
283
284
285
286
287
exit(0);

sub fatal($)
{
    my ($mesg) = $_[0];

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