ec2import-image.pl.in 6.66 KB
Newer Older
1
#!/usr/bin/perl
Srikanth Raju's avatar
Srikanth Raju committed
2
#
Leigh Stoller's avatar
Leigh Stoller committed
3
# Copyright (c) 2013-2015 University of Utah and the Flux Group.
4
#
Srikanth Raju's avatar
Srikanth Raju committed
5
# {{{EMULAB-LICENSE
6
#
Srikanth Raju's avatar
Srikanth Raju committed
7
# This file is part of the Emulab network testbed software.
8
#
Srikanth Raju's avatar
Srikanth Raju committed
9 10 11 12
# 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.
13
#
Srikanth Raju's avatar
Srikanth Raju committed
14 15 16 17
# 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.
18
#
Srikanth Raju's avatar
Srikanth Raju committed
19 20
# 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/>.
21
#
Srikanth Raju's avatar
Srikanth Raju committed
22 23 24 25 26
# }}}
#
use English;
use Getopt::Std;
use strict;
27
use POSIX;
Srikanth Raju's avatar
Srikanth Raju committed
28 29 30 31 32 33 34 35 36 37 38 39

# Drag in path stuff so we can find emulab stuff.
BEGIN { require "/etc/emulab/paths.pm"; import emulabpaths; }

#
# Take a raw image and make a proper emulab image based off of it
#
sub usage()
{
    print STDOUT "Usage: ec2import-image remote-user remote-addr project user osid";
    exit(-1);
}
40 41
my $optlist = "d";
my $debug   = 1;
Srikanth Raju's avatar
Srikanth Raju committed
42 43 44 45 46 47 48 49 50

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

# Need this for predicates.
use libsetup;

51 52 53 54
#
# Configure variables
#
my $TB          = "@prefix@";
55
my $TBPROJ_DIR	= "@PROJROOT_DIR@";
56
my $IMPORT_BASE = "@IMPORT_TMPDIR@";
Srikanth Raju's avatar
Srikanth Raju committed
57 58 59 60 61 62

#
# No configure vars.
#
my $TAR      = "tar";
my $sudo;
Leigh Stoller's avatar
Leigh Stoller committed
63
my $zipper   = "/usr/testbed/bin/imagezip";
Srikanth Raju's avatar
Srikanth Raju committed
64
my $uploader = "/usr/local/etc/emulab/frisupload";
Srikanth Raju's avatar
Srikanth Raju committed
65
my $error    = 0;
Srikanth Raju's avatar
Srikanth Raju committed
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81

for my $path (qw#/usr/local/bin /usr/bin#) {
    if (-e "$path/sudo") {
        $sudo = "$path/sudo";
        last;
    }
}

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

Srikanth Raju's avatar
Srikanth Raju committed
83 84 85 86
if (@ARGV != 5) {
    usage();
}

87 88 89 90 91
my $remote = $ARGV[0];
my $project = $ARGV[1];
my $user = $ARGV[2];
my $osid = $ARGV[3];
my $outfile = $ARGV[4];
Srikanth Raju's avatar
Srikanth Raju committed
92

93 94 95 96 97 98 99 100
my $infile  = "$TBPROJ_DIR/$project/images/${osid}.tar.gz";
my $workdir = "$TBPROJ_DIR/$project/ec2import/$user/${osid}-tmp";
if (!-e $workdir) {
    system("/bin/mkdir -p $workdir");
    if ($?) {
	die("Could not create $workdir\n");
    }
}
Srikanth Raju's avatar
Srikanth Raju committed
101 102

# Man, this really needs some exception handling
103 104 105

# Check if we can connect to the machine using publickey only
if(system("ssh -o PasswordAuthentication=no -o KbdInteractiveAuthentication=no" .
Srikanth Raju's avatar
Srikanth Raju committed
106
        " -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" .
107 108 109
        " -o ChallengeResponseAuthentication=no $remote 'exit'")){
    print STDERR "*** Couldn't connect to $remote\n";
    print STDERR "    Ensure that Emulabs public key is in the authorized_hosts\n";
Srikanth Raju's avatar
Srikanth Raju committed
110 111 112
    print STDERR "    command: ssh -o PasswordAuthentication=no" .
        " -o KbdInteractiveAuthentication=no" .
        " -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" .
113 114 115 116 117
        " -o ChallengeResponseAuthentication=no $remote 'exit'";
    $error = 1;
    goto cleanup;
}

Srikanth Raju's avatar
Srikanth Raju committed
118 119
if(system("echo \"mkdir -p ~/.emulab\" | ssh -o UserKnownHostsFile=/dev/null ".
        "-o StrictHostKeyChecking=no $remote bash")){
120
    print STDERR "*** Couldn't mkdir ~/.emulab\n";
121 122
    $error = 1;
    goto cleanup;
Srikanth Raju's avatar
Srikanth Raju committed
123 124
}

125 126 127
# Check if Ruby and unzip exist
if(system("ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ".
        "$remote 'which ruby unzip'")){
128
    print STDERR "*** Could not find either ruby or unzip on remote machine!\n";
129 130 131 132 133
    $error = 1;
    goto cleanup;
}

# scp export scripts
Srikanth Raju's avatar
Srikanth Raju committed
134 135
if(system("scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ".
        "$TB/sbin/export-template-remote.rb $remote:~/.emulab/export.rb")){
136
    print STDERR "*** Couldn't scp exporter script into $remote\n";
Srikanth Raju's avatar
Srikanth Raju committed
137
    $error = 1;
Srikanth Raju's avatar
Srikanth Raju committed
138 139 140
    goto cleanup;
}

141 142 143
if(system("scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ".
        "$TB/sbin/GrubConf.rb $remote:~/.emulab/GrubConf.rb")){
    print STDERR "*** Couldn't scp exporter-grubconf script into $remote\n";
144 145 146
    $error = 1;
    goto cleanup;
}
147

148
# Run it!
Srikanth Raju's avatar
Srikanth Raju committed
149 150
if(system("ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ".
        "-t -t $remote 'sudo ruby -C ~/.emulab < ~/.emulab/export.rb'")){
151
    print STDERR "*** Remote image creation failed\n";
Srikanth Raju's avatar
Srikanth Raju committed
152
    $error = 1;
Srikanth Raju's avatar
Srikanth Raju committed
153 154 155 156 157
    goto cleanup;
}

# SCP back the generated image file
# TODO Saner name for tar and .emulab?
Srikanth Raju's avatar
Srikanth Raju committed
158 159
if(system("scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ".
        "$remote:~/.emulab/emulab.tar.gz $infile")){
160
    print STDERR "*** Couldn't scp image back into ops\n";
Srikanth Raju's avatar
Srikanth Raju committed
161
    $error = 1;
Srikanth Raju's avatar
Srikanth Raju committed
162 163 164 165 166 167
    goto cleanup;
}

# Process the tar blah image
if (! -e $infile){
    print STDERR "*** Input tar image not found.\n";
168
    print STDERR "    Looking for:" . $infile . "\n";
Srikanth Raju's avatar
Srikanth Raju committed
169
    $error = 1;
Srikanth Raju's avatar
Srikanth Raju committed
170 171
    goto cleanup;
}
172

Srikanth Raju's avatar
Srikanth Raju committed
173 174
# Unzip into the working dir
if (system("mkdir -p $workdir")){
175
    print STDERR "*** Couldn't mkdir $workdir \n";
Srikanth Raju's avatar
Srikanth Raju committed
176
    $error = 1;
Srikanth Raju's avatar
Srikanth Raju committed
177 178 179 180
    goto cleanup;
}

if (system("tar -xvzf $infile -C $workdir")){
181
    print STDERR "*** Failed to extract $infile \n";
Srikanth Raju's avatar
Srikanth Raju committed
182
    $error = 1;
Srikanth Raju's avatar
Srikanth Raju committed
183 184
    goto cleanup;
}
185
unlink($infile);
Srikanth Raju's avatar
Srikanth Raju committed
186

187
my $filesize = ceil((-s "$workdir/emulab-image")/(1024*1024*1024));
Srikanth Raju's avatar
Srikanth Raju committed
188 189
$filesize = $filesize + 4;

190 191
my $console = 'hvc0';
if (-e "$workdir/bootopts") {
192
    if(open(my $bo, "<", "$workdir/bootopts")) {
193 194
        my $bootopts = join('', <$bo>);
        if ($bootopts =~ /xvc0/){
195
            $console =~ s/hvc0/xvc0/g;
196 197 198 199
        }
    }
}
    
Srikanth Raju's avatar
Srikanth Raju committed
200 201 202 203 204 205 206 207 208
# Create the "special" xm.conf
my $heredoc = <<XMCONF;
disksizes = 'xvda2:2.00g,xvda1:$filesize.00g'
memory = '256'
disk = ['phy:/dev/xen-vg/pcvm666-1,xvda1,w','phy:/dev/xen-vg/pcvm666.swap,xvda2,w']
kernel = 'kernel'
ramdisk = 'initrd'
vif = ['mac=02:bf:bb:b9:ae:9c, ip=172.19.140.1, bridge=xenbr0']
name = 'pcvm666-1'
209
extra = 'root=/dev/xvda1 boot_verbose=1 xencons=tty console=$console selinux=0'
Srikanth Raju's avatar
Srikanth Raju committed
210 211 212 213 214 215 216 217 218
XMCONF

open(FH, '>', "$workdir/xm.conf") or goto cleanup;

print FH $heredoc;

close(FH);

# Image zip the raw image
219
if (system("$zipper -o -l $workdir/emulab-image $workdir/xvda1")) {
Srikanth Raju's avatar
Srikanth Raju committed
220
    print STDERR "*** Failed to greate image!\n";
221
    print STDERR "    command: $zipper -o -l $workdir/emulab-image $workdir/xvda1\n";
Srikanth Raju's avatar
Srikanth Raju committed
222 223
    $error = 1;
    goto cleanup;
Srikanth Raju's avatar
Srikanth Raju committed
224 225 226 227
}


# Tar everything up and then imagezip
228 229
my $cmd = "$TAR zcf - -C $workdir xvda1 xm.conf kernel initrd | ".
    "$zipper -o -f - $outfile";
Srikanth Raju's avatar
Srikanth Raju committed
230 231 232
if (system("$cmd")) {
    print STDERR "*** Failed to create image!\n";
    print STDERR "    command: '$cmd'\n";
233
    $error = 1;
Srikanth Raju's avatar
Srikanth Raju committed
234 235 236 237 238
    goto cleanup;
}

cleanup:
# Clean up the directory.
239
if ($debug <= 1) {
240 241 242 243 244
	print STDOUT "Performing cleanup...\n";
	system("$sudo /bin/rm -rf $workdir 2>/dev/null");
	system("echo 'rm -Rf ~/.emulab' | ssh -o UserKnownHostsFile=/dev/null ".
	       "-o StrictHostKeyChecking=no $remote bash");
}
Srikanth Raju's avatar
Srikanth Raju committed
245

246
exit($error);