Commit 713e0919 authored by Leigh Stoller's avatar Leigh Stoller

Clientside changes to handle creating a snapshot of the an OpenVZ

container.

* Change reboot_prepare to take a -noreboot argument since in general
  we want to control the reboot externally. Just want to run prepare. 

* New openvz variant of create-image that installed on openvz hosts,
  which is called from the server side to reboot/prepare the contaner,
  take the snapshot using tar/imagezip/frisupload, and then restart
  the container.
parent 0054f55e
......@@ -6,5 +6,15 @@
. /etc/emulab/paths.sh
echo "$ETCDIR/prepare.sh" > /bootcmd
shutdown now "Rebooting with Prepare"
reboot=1
if [ $# -eq 1 ]; then
if [ "$1" = "-noreboot" ]; then
reboot=0
fi
fi
if [ $reboot -eq 1 ]; then
shutdown now "Rebooting with Prepare"
fi
exit 0
......@@ -33,6 +33,7 @@ ETCDIR ?= $(DESTDIR)$(CLIENT_ETCDIR)
BINDIR ?= $(DESTDIR)$(CLIENT_BINDIR)
VARDIR ?= $(DESTDIR)$(CLIENT_VARDIR)
VSDIR ?= $(BINDIR)/vserver
LBINDIR ?= $(DESTDIR)/usr/local/bin
RCDIR ?= $(SYSETCDIR)/rc.d
INSTALL ?= /usr/bin/install -c
COMMON ?= $(SRCDIR)/../common
......@@ -272,6 +273,7 @@ openvz-install: dir-install
$(INSTALL) -m 755 $(SRCDIR)/openvz/vznetinit-elab.sh $(BINDIR)/
$(INSTALL) -m 755 $(SRCDIR)/xen/xenbridge-setup $(BINDIR)/
$(INSTALL) -m 755 $(SRCDIR)/vnodectl $(BINDIR)/
$(INSTALL) -m 755 $(SRCDIR)/openvz/create-image $(LBINDIR)/
echo "openvz" > $(ETCDIR)/genvmtype
$(INSTALL) -m 755 $(SRCDIR)/openvz/vzmount-elab.sh $(BINDIR)/
# No destdir in this symlink!
......
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2012 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
use Getopt::Std;
use strict;
# Drag in path stuff so we can find emulab stuff.
BEGIN { require "/etc/emulab/paths.pm"; import emulabpaths; }
my $VNODESETUP = "$BINDIR/vnodesetup";
my $VZCTL = "/usr/sbin/vzctl";
my $VZLIST = "/usr/sbin/vzlist";
my $TAR = "/bin/tar";
#
# Client-side to create a disk image. Caller must have sudo permission!
# This is the OpenVZ specific version.
#
sub usage()
{
print STDOUT "Usage: create-image [-S image-server] [-F imageid] ".
"<vnodeid> <filename>\n";
exit(-1);
}
my $optlist = "F:S:";
#
# Turn off line buffering on output
#
$| = 1;
#
# No configure vars.
#
my $sudo;
my $zipper = "/usr/local/bin/imagezip";
my $uploader = "/usr/local/etc/emulab/frisupload";
my $vnodeid;
my $filename;
my $error = 0;
for my $path (qw#/usr/local/bin /usr/bin#) {
if (-e "$path/sudo") {
$sudo = "$path/sudo";
last;
}
}
# Frisbee master server params
my $iserver = "boss"; # XXX
my $imageid;
#
# 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 (@ARGV != 2) {
usage();
}
if (defined($options{"S"})) {
$iserver = $options{"S"};
if ($iserver =~ /^([-\w\.]+)$/) {
$iserver = $1;
} else {
die("Bad -S hostname: '$iserver'");
}
}
if (defined($options{"F"})) {
$imageid = $options{"F"};
if ($imageid =~ /^(\S+)$/) {
$imageid = $1;
} else {
die("Bad -F imageid: '$imageid'");
}
}
$vnodeid = $ARGV[0];
if (defined($imageid)) {
$filename = "-";
} else {
$filename = $ARGV[1];
}
#
# Untaint the arguments.
#
# Note different taint check (allow /).
if ($filename =~ /^([-\w.\/\+]+)$/) {
$filename = $1;
}
else {
die("Tainted output filename: $filename");
}
# This directory must exist to create the snapshot. See the openvz library.
if (0 && ! -e "/mnt/snapshot/.created") {
die("snapshot directory does not exist\n");
}
# Only LVM is supported right now.
if (! -e "/mnt/$vnodeid/private") {
die("container file system does not exist\n");
}
#
# Check contaner status. If it is running, we need to stop it,
# but first set it up to run "prepare" on the way down.
#
my $ctid;
my $status;
my $stuff = `$sudo $VZLIST -n $vnodeid -H -o ctid,status`;
if ($?) {
die("Could not container status for $vnodeid\n");
}
if ($stuff =~ /(\d*)\s+([-\w]*)$/) {
$ctid = $1;
$status = $2;
}
else {
chomp($stuff);
die("Could not parse container status: '$stuff'\n");
}
#
# If the container is running, run the reboot_prepare command
# inside and then halt it.
#
if ($status eq "running") {
system("$sudo $VZCTL exec2 $ctid $BINDIR/reboot_prepare -noreboot");
if ($?) {
die("Could not setup prepare to run in $vnodeid\n");
}
system("$sudo $VNODESETUP -jh $vnodeid");
if ($?) {
die("Could not halt container $ctid");
}
for (my $i = 5; $i >= 0; $i--) {
my $stuff = `$sudo $VZLIST -n $vnodeid -H -o status`;
if ($?) {
die("Could not get container status for $vnodeid\n");
}
if ($stuff =~ /([-\w]*)$/) {
$status = $1;
last
if ($status eq "stopped");
}
else {
chomp($stuff);
die("Could not parse container status: '$stuff'\n");
}
}
if ($status ne "stopped") {
die("Container $ctid would not stop!\n");
}
}
elsif ($status ne "stopped") {
die("Container is not in a good state: $status\n");
}
#
# Too bad that imagezip will not allow a raw file to be piped into it.
# Instead, we have to create the tar file first.
#
if (0) {
chdir("/mnt/snapshot") or
die("Could not chdir to the snapshot directory\n");
system("$sudo $TAR zcf snapshot.tar.gz -C /mnt/$vnodeid/private .");
if ($?) {
die("Could not create tar file of container private area\n");
}
}
#
# If imageid is defined, we use the frisbee uploader.
#
my $cmd = "$TAR zcf - -C /mnt/$vnodeid/private . | $zipper -f - $filename";
if (defined($imageid)) {
$cmd .= " | $uploader -S $iserver -F $imageid -";
}
#
# Run the command using sudo, since by definition only testbed users
# with proper trust should be able to zip up a disk. sudo will fail
# if the user is not in the proper group.
#
if (system("$sudo $cmd")) {
print STDERR "*** Failed to create image!\n";
print STDERR " command: '$sudo $cmd'\n";
$error = 1;
}
#
# Reboot the vnode.
#
system("$sudo $VNODESETUP -jbVt $vnodeid");
if ($?) {
die("Could not restart container $ctid");
}
exit($error);
......@@ -17,7 +17,13 @@ if [ -x /bin/systemd ]; then
systemctl start tbprepare.service
fi
# Reboot!
/sbin/reboot
reboot=1
if [ $# -eq 1 ]; then
if [ "$1" = "-noreboot" ]; then
reboot=0
fi
fi
if [ $reboot -eq 1 ]; then
/sbin/reboot
fi
exit 0
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment