mkexpdir.in 4.67 KB
Newer Older
1
#!/usr/bin/perl -wT
Leigh Stoller's avatar
Leigh Stoller committed
2 3 4

#
# EMULAB-COPYRIGHT
5
# Copyright (c) 2000-2012 University of Utah and the Flux Group.
Leigh Stoller's avatar
Leigh Stoller committed
6 7
# All rights reserved.
#
8
use English;
Leigh Stoller's avatar
Leigh Stoller committed
9
use Getopt::Std;
10
use strict;
11

12 13
#
# This gets invoked from the Web interface. CD into the proper directory
14 15
# and do the tb stuff. This script cannot do any damage since it can
# only create directories where the caller has the permission to do so.
16
#
Leigh Stoller's avatar
Leigh Stoller committed
17 18
sub usage()
{
19
    print STDOUT "Usage: mkexpdir <eid>\n";
Leigh Stoller's avatar
Leigh Stoller committed
20 21
    exit(-1);
}
22

23
sub fatal($;$);
24
sub chowner($$$);
Leigh Stoller's avatar
Leigh Stoller committed
25

26
#
Leigh Stoller's avatar
Leigh Stoller committed
27 28
# Configure variables
#
29 30 31
my $TB		= "@prefix@";
my $TBOPS	= "@TBOPSEMAIL@";
my $LINUX_FSNODE= @LINUX_FSNODE@;
32

Leigh Stoller's avatar
Leigh Stoller committed
33 34 35 36 37
#
# Turn off line buffering on output
#
$| = 1;

38 39 40 41 42 43
#
# Untaint the path
# 
$ENV{'PATH'} = '/bin:/usr/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
#
# Testbed Support libraries
#
use lib "@prefix@/lib";
use libdb;
use libtestbed;
use libtblog;
use Experiment;

# Locals
my $projroot = PROJROOT();
my $grouproot= GROUPROOT();
my $tbdata   = "tbdata";
my @dirlist  = ($tbdata, "bin", "tmp", "logs", "archive", "datastore",
		"tftpboot", "swapinfo");
my $exitval;

61 62 63
#
# Check args.
# 
64
if (@ARGV != 1) {
Leigh Stoller's avatar
Leigh Stoller committed
65
    usage();
66
}
67 68 69
my $experiment = Experiment->Lookup($ARGV[0]);
if (!defined($experiment)) {
    tbdie("Could not lookup experiment object for $ARGV[0]!")
Leigh Stoller's avatar
Leigh Stoller committed
70
}
71 72 73
my $pid       = $experiment->pid();
my $eid       = $experiment->eid();
my $gid       = $experiment->gid();
74 75 76 77 78
my $piddir    = (($pid eq $gid) ? "$projroot/$pid" : "$grouproot/$pid/$gid");
my $expdir    = "$piddir/exp";
my $eiddir    = "$expdir/$eid";
my $eidlink   = "$projroot/$pid/exp/$eid";
my $workdir   = TBExptWorkDir($pid, $eid);
79
my $INFODIR   = "$TB/expinfo";
80

Leigh Stoller's avatar
Leigh Stoller committed
81 82 83
#
# Unix info for the group
#
84 85 86
my $group = $experiment->GetGroup();
if (!defined($group)) {
    tbdie("Could not lookup group object for $experiment!")
Leigh Stoller's avatar
Leigh Stoller committed
87
}
88 89
my $unix_gid  = $group->unix_gid();
my $unix_name = $group->unix_name();
Leigh Stoller's avatar
Leigh Stoller committed
90

91 92 93 94
#
# We create a directory structure for the experiment in the project directory.
#
if (! chdir($expdir)) {
95
    print "Could not chdir to $expdir: $!\n";
96 97 98 99
    exit(-1);
}

if (! mkdir($eid, 0770)) {
100
    $exitval = $ERRNO;
101
    print "Could not mkdir $eid in $expdir: $!\n";
102
    exit($exitval);
103 104 105
}

if (! chmod(0770, "$eid")) {
106
    $exitval = $ERRNO;
107
    print "Could not chmod $eid to 0770 in $expdir: $!\n";
108
    rmdir($eid);
109
    exit($exitval);
110 111
}

112
if (! chowner($UID, $unix_gid, "$eid")) {
113
    $exitval = $ERRNO;
114
    print "Could not chown $eid to $UID/$unix_gid in $expdir: $!\n";
Leigh Stoller's avatar
Leigh Stoller committed
115
    rmdir($eid);
116
    exit($exitval);
Leigh Stoller's avatar
Leigh Stoller committed
117 118
}

119
if (! chdir($eid)) {
120
    $exitval = $ERRNO;
121
    print "Could not chdir to $eid in $expdir: $!\n";
122
    rmdir($eid);
123
    exit($exitval);
124 125 126 127 128
}

#
# Create the experiment directory list in the new directory.
#
129
foreach my $dir (@dirlist) {
130
    if (! mkdir($dir, 0770)) {
131
	fatal("Could not mkdir $dir in $eiddir: $!");
132 133 134
    }

    if (! chmod(0770, "$dir")) {
135
	fatal("Could not chmod $dir to 0770 in $eiddir: $!");
136 137 138
    }
}

Leigh Stoller's avatar
Leigh Stoller committed
139 140 141 142
#
# Update the DB. This leaves the decision about where the directory
# is created, in this script. 
#
143 144
$experiment->Update({"path" => "$eiddir"}) == 0 or
    fatal("Could not update path for $experiment");
Leigh Stoller's avatar
Leigh Stoller committed
145

146 147 148
#
# Create the working directory.
#
149 150 151 152
if (! -e $workdir) {
    if (! mkdir($workdir, 0775)) {
	fatal("Could not create $workdir: $!");
    }
153
    if (! chowner($UID, $unix_gid, "$workdir")) {
154 155
	fatal("Could not chown $workdir to $UID/$unix_gid: $!");
    }
156 157
}

158 159 160 161 162 163 164 165 166
#
# Create the expinfo directory.
#
my $expinfo = "$INFODIR/$pid/$eid";

if (! -e $expinfo) {
    if (! mkdir($expinfo, 0777)) {
	fatal("Could not create $expinfo: $!");
    }
167
    if (! chowner($UID, $unix_gid, "$expinfo")) {
168 169 170 171
	fatal("Could not chown $expinfo to $UID/$unix_gid: $!");
    }
}

172 173
#
# If a group experiment, leave behind a symlink from the project experiment
174 175
# directory to the group experiment directory. This is convenient so that
# there is a common path for all experiments. 
176
#
177
if ($pid ne $gid) {
178 179
    # XXX Bad. This link should be removed when the experiment is removed.
    unlink($eidlink)
180
	if (-l $eidlink);
181 182 183
    symlink($eiddir, $eidlink) or
	fatal("Could not symlink($eiddir, $eidlink): $!");
}
184

185 186
exit(0);

187
sub fatal($;$)
188
{
189 190 191 192
    my ($msg, $exitval) = @_;

    $exitval = $ERRNO
	if (!defined($exitval));
193 194 195

    system("/bin/rm -rf $eiddir");
    system("/bin/rm -rf $workdir");
196 197
    unlink($eidlink)
	if ($pid ne $gid && -l $eidlink);
198

199
    tberror($msg);
200
    exit($exitval);
201 202
}

203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
sub chowner($$$)
{
    my ($uid, $gid, $file) = @_;

    if (0 && $LINUX_FSNODE) {
	#
	# use chgrp because linux NFS does not allow to chown !!
	# set chgrp suid root -- only on boss !!!
	#
	# XXX I do not think this is the case for linux in general, so
	# change the if expression above if you must.
	#
	system("/usr/bin/chgrp", $gid, $file);
	return ($? ? 0 : 1);
    }
    else {
	return chown($uid, $gid, $file);
    }
}