elabinelab_bossinit.in 5.84 KB
Newer Older
1
#!/usr/bin/perl -wT
2
3
#
# EMULAB-COPYRIGHT
4
# Copyright (c) 2000-2010 University of Utah and the Flux Group.
5
6
7
8
9
10
11
12
13
# All rights reserved.
#
use English;
use Getopt::Std;

#
# ElabInElab: This is run on the inner boss to construct a bunch stuff
# from the db (groups, projects, users, etc).
#
14
15
16
17
18
19
# We also use this opportunity to munge node-related bootstrap state.
# Right now we only load the standard BSD-based pxeboot and MFSes into
# an elabinelab, but many of our node types now use the Linux-based tools
# instead.  So for the moment, we tweak the DB to rewrite everything to use
# the BSD tools.
#
20
21
22
23
24
25
26
sub usage()
{
    print STDERR "Usage: $0 [-d] <pid>\n";
    exit(1);
}
my $optlist = "d";
my $debug   = 0;
27
sub mysystem($);
28
29
30
31
32
33
34

#
# Configure variables
#
my $TB		= "@prefix@";
my $TBOPS       = "@TBOPSEMAIL@";
my $ELABINELAB  = @ELABINELAB@;
35
my $SAVEUID     = $UID;
36
37
38
39
40
41
42
43
44
45
46
47

# un-taint path
$ENV{'PATH'} = '/bin:/usr/bin:/usr/sbin:/usr/local/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

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

use lib "@prefix@/lib";
use libdb;
use libtestbed;

Leigh B. Stoller's avatar
Leigh B. Stoller committed
48
49
50
# Defined in libdb ...
my $TBOPSPID    = TBOPSPID();

51
52
53
54
55
56
57
58
59
if (!$ELABINELAB) {
    die("*** $0:\n".
	"    This script can only run on an inner Emulab!\n");
}
# Only admin types!
if (!TBAdmin($UID)) {
    die("*** $0:\n".
	"    Only TB administrators can run this script!\n");
}
60
61
62
63
64
65
66
#
# We don't want to run this script unless its the real version.
#
if ($EUID != 0) {
    die("*** $0:\n".
	"    Must be root! Maybe its a development version?\n");
}
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

#
# Parse command arguments. Once we return from getopts, all that should
# left are the required arguments.
#
%options = ();
if (! getopts($optlist, \%options)) {
    usage();
}
if (defined($options{"d"})) {
    $debug = 1;
}

usage()
    if (scalar(@ARGV) != 1);
my $pid = shift();

#
85
# Untaint the arguments.
86
#
87
88
89
90
91
92
if ($pid =~ /^([-\w]+)$/) {
    $pid = $1;
}
else {
    die("Tainted argument $pid!\n");
}
93

94
# Temporary ... See utils/firstuser ... 
95
96
97
DBQueryFatal("update group_membership set pid_idx=1,gid_idx=1 ".
	     "where pid='$TBOPSPID' and pid=gid");

98
99
100
101
# Do not want to share the UUIDs with outer Emulab.
DBQueryFatal("update users set uid_uuid=UUID()");
DBQueryFatal("update nodes set uuid=UUID()");

102
#
103
# Shift to real user for these scripts.
104
#
105
106
107
108
109
$EUID = $UID;

#
# Build the project.
#
110
mysystem("$TB/sbin/mkproj -s $pid");
111
112
113

#
# Get the list of users and admin status. Admin users get a real shell
114
115
# on boss. Create the users, and not that we have to do this before the
# groups are created (tbacct add does not do a setgroups).
116
#
117
my $users_result =
118
119
120
121
    DBQueryFatal("select distinct u.uid,u.admin,u.status ".
		 "   from group_membership as m ".
		 "left join users as u on u.uid_idx=m.uid_idx ");
while (my ($uid,$admin,$status) = $users_result->fetchrow_array()) {
122
123
124
    next
	if ($uid eq "elabman");
    
125
126
    if ($admin) {
	# Add admin users to group wheel for convenience.
127
	DBQueryFatal("replace into unixgroup_membership ".
128
		     "values ('$uid','wheel')");
129
    }
130
131
132
133
134
    next
	if ($status ne USERSTATUS_ACTIVE());
    
    mysystem("$TB/sbin/tbacct -b add $uid");
    
135
    if ($admin) {
136
137
	# Flip back to root for pw command.
	$EUID = 0;
138
	mysystem("pw usermod -n $uid -s /bin/tcsh");
139
	$EUID = $UID;
140
141
142
    }
}

143
144
145
146
#
# Get the list of subgroups in the project and create those groups.
#
my $query_result =
147
148
    DBQueryFatal("select gid_idx from groups where pid='$pid' and pid!=gid");
while (my ($gid_idx) = $query_result->fetchrow_array()) {
149
    mysystem("$TB/sbin/mkgroup -s $gid_idx");
150
151
152
153
154
155
}

#
# Now do a setgroups.
#
$users_result->dataseek(0);
Mike Hibler's avatar
Doh!    
Mike Hibler committed
156
while (my ($uid,$admin,$status) = $users_result->fetchrow_array()) {
157
158
    next
	if ($uid eq "elabman");
159
160
    next
	if ($status ne USERSTATUS_ACTIVE());
161
162
163
164
    
    mysystem("$TB/sbin/setgroups $uid");
}

165
166
167
168
169
170
171
#
# Do the exports setup and the genelists all at once now that all the above
# stuff happened.
#
mysystem("$TB/sbin/genelists -a");
mysystem("$TB/sbin/exports_setup");

172
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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#
# Fixup pxeboot and MFS info.
#
# Right now we only load the standard BSD-based pxeboot and MFSes into
# an elabinelab, but many of our node types use the Linux-based tools instead.
# So for the moment, we tweak the DB to rewrite everything to use the BSD
# tools.
#
# XXX this should go away if we once again settle on a single set of tools.
#
if (1) {
    # first find the OSIDs for the "standard" MFSes
    my $qr = DBQueryFatal("select osname,osid from os_info where osname in ".
			  "  ('FREEBSD-MFS','FRISBEE-MFS','NEWNODE-MFS') ".
			  " and pid='$TBOPSPID'");
    my ($amfs,$dmfs,$nmfs,$nmfspath);
    while (my ($name, $osid) = $qr->fetchrow_array()) {
	if ($name eq "FREEBSD-MFS") {
	    $amfs = $osid;
	} elsif ($name eq "FRISBEE-MFS") {
	    $dmfs = $osid;
	} else {
	    $nmfs = $osid;
	    $nmfspath = "/tftpboot/freebsd.newnode"; # XXX hardwired
	}
    }

    # make sure newnode MFS points to the correct place
    DBQueryFatal("update os_info set path='$nmfspath' where osid=$nmfs");

    # and find all the node types and update their attributes.
    $qr = DBQueryFatal("select type from node_types where class='pc'");
    while (my ($ntype) = $qr->fetchrow_array()) {
	# XXX assumes that BSD version is the default in dhcpd.conf.template
	DBQueryFatal("delete from node_type_attributes ".
		     "  where attrkey='pxe_boot_path' and type='$ntype'");
	DBQueryFatal("update node_type_attributes set attrvalue='$amfs' ".
		     "  where attrkey='adminmfs_osid' and type='$ntype'");
	DBQueryFatal("update node_type_attributes set attrvalue='$dmfs' ".
		     "  where attrkey='diskloadmfs_osid' and type='$ntype'");
    }

    #
    # Remake the dhcpd.conf file to reflect any pxeboot change.
216
    # XXX dhcpd is not running yet so don't need this.
217
    #
218
    #mysystem("$TB/sbin/dhcpd_makeconf -ir");
219
220
}

221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
#
# Run a command string.
#
sub mysystem($)
{
    my ($command) = @_;

    if ($debug) {
	print "Command: '$command\'\n";
    }

    system($command);
    if ($?) {
	die("*** $0:\n".
	    "    Command failed: $? - $command\n");
    }
}