I've replaced most of my previous use of kvm and cloud instances for bug
investigations with lxc instances.  To emulate my older workflows, I've
created lxc-clone.  My diff against the current natty lxc package is
attached.  I've written up how I use this at s3hh.wordpress.com.  Briefly,
I have a single pristine container, with LVM rootfs, for each of lucid,
maverick, and natty.  When I want a container, I

        lxc-clone -o natty -n n1 -s
        lxc-start -n n1

which takes about 5 seconds altogether.  Ruin n1 however I like, and

        lxc-destroy -l -n n1

when done.

It needs fleshing out, but it's at the point where it does exactly what
I need.  The next thing I'm likely to add will be btrfs snapshotting,
not sure when.

Daniel, is this something you'd consider adding?  I assume that if so,
then there are changes you'd like to make to the interface :)

thanks,
-serge

=== modified file 'configure'
--- configure   2011-03-10 07:25:34 +0000
+++ configure   2011-03-30 15:36:58 +0000
@@ -5057,7 +5057,7 @@
   CFLAGS="$CFLAGS -Wall"
 fi
 
-ac_config_files="$ac_config_files Makefile lxc.pc lxc.spec config/Makefile 
doc/Makefile doc/lxc-create.sgml doc/lxc-destroy.sgml doc/lxc-execute.sgml 
doc/lxc-start.sgml doc/lxc-checkpoint.sgml doc/lxc-restart.sgml 
doc/lxc-stop.sgml doc/lxc-console.sgml doc/lxc-freeze.sgml 
doc/lxc-unfreeze.sgml doc/lxc-monitor.sgml doc/lxc-wait.sgml doc/lxc-ls.sgml 
doc/lxc-ps.sgml doc/lxc-cgroup.sgml doc/lxc-kill.sgml doc/lxc.conf.sgml 
doc/lxc.sgml doc/common_options.sgml doc/see_also.sgml doc/rootfs/Makefile 
doc/examples/Makefile doc/examples/lxc-macvlan.conf doc/examples/lxc-vlan.conf 
doc/examples/lxc-no-netns.conf doc/examples/lxc-empty-netns.conf 
doc/examples/lxc-phys.conf doc/examples/lxc-veth.conf 
doc/examples/lxc-complex.conf templates/Makefile templates/lxc-lenny 
templates/lxc-debian templates/lxc-lucid templates/lxc-maverick 
templates/lxc-natty templates/lxc-busybox templates/lxc-fedora 
templates/lxc-sshd src/Makefile src/lxc/Makefile src/lxc/lxc-ps src/lxc/lxc-ls 
src/lxc/lxc-netstat src/lxc/lxc-checkconfig src/lxc/lxc-setcap 
src/lxc/lxc-setuid src/lxc/lxc-version src/lxc/lxc-create src/lxc/lxc-destroy"
+ac_config_files="$ac_config_files Makefile lxc.pc lxc.spec config/Makefile 
doc/Makefile doc/lxc-create.sgml doc/lxc-destroy.sgml doc/lxc-execute.sgml 
doc/lxc-start.sgml doc/lxc-checkpoint.sgml doc/lxc-restart.sgml 
doc/lxc-stop.sgml doc/lxc-console.sgml doc/lxc-freeze.sgml 
doc/lxc-unfreeze.sgml doc/lxc-monitor.sgml doc/lxc-wait.sgml doc/lxc-ls.sgml 
doc/lxc-ps.sgml doc/lxc-cgroup.sgml doc/lxc-kill.sgml doc/lxc.conf.sgml 
doc/lxc.sgml doc/common_options.sgml doc/see_also.sgml doc/rootfs/Makefile 
doc/examples/Makefile doc/examples/lxc-macvlan.conf doc/examples/lxc-vlan.conf 
doc/examples/lxc-no-netns.conf doc/examples/lxc-empty-netns.conf 
doc/examples/lxc-phys.conf doc/examples/lxc-veth.conf 
doc/examples/lxc-complex.conf templates/Makefile templates/lxc-lenny 
templates/lxc-debian templates/lxc-lucid templates/lxc-maverick 
templates/lxc-natty templates/lxc-busybox templates/lxc-fedora 
templates/lxc-sshd src/Makefile src/lxc/Makefile src/lxc/lxc-ps src/lxc/lxc-ls 
src/lxc/lxc-netstat src/lxc/lxc-checkconfig src/lxc/lxc-setcap 
src/lxc/lxc-setuid src/lxc/lxc-version src/lxc/lxc-create src/lxc/lxc-clone 
src/lxc/lxc-destroy"
 
 ac_config_commands="$ac_config_commands default"
 
@@ -5842,6 +5842,7 @@
     "src/lxc/lxc-setuid") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-setuid" ;;
     "src/lxc/lxc-version") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-version" ;;
     "src/lxc/lxc-create") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-create" ;;
+    "src/lxc/lxc-clone") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-clone" ;;
     "src/lxc/lxc-destroy") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-destroy" ;;
     "default") CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;;
 

=== modified file 'configure.ac'
--- configure.ac        2011-03-10 07:25:34 +0000
+++ configure.ac        2011-03-30 15:36:58 +0000
@@ -156,6 +156,7 @@
        src/lxc/lxc-setuid
        src/lxc/lxc-version
        src/lxc/lxc-create
+       src/lxc/lxc-clone
        src/lxc/lxc-destroy
 
 ])

=== modified file 'lxc.spec'
--- lxc.spec    2011-03-10 07:25:34 +0000
+++ lxc.spec    2011-03-30 15:36:58 +0000
@@ -78,6 +78,7 @@
 %{_bindir}/*
 %attr(4111,root,root) %{_bindir}/lxc-attach
 %attr(4111,root,root) %{_bindir}/lxc-create
+%attr(4111,root,root) %{_bindir}/lxc-clone
 %attr(4111,root,root) %{_bindir}/lxc-start
 %attr(4111,root,root) %{_bindir}/lxc-netstat
 %attr(4111,root,root) %{_bindir}/lxc-unshare

=== modified file 'src/lxc/Makefile.am'
--- src/lxc/Makefile.am 2011-03-10 07:25:34 +0000
+++ src/lxc/Makefile.am 2011-03-30 15:36:58 +0000
@@ -72,6 +72,7 @@
        lxc-setuid \
        lxc-version \
        lxc-create \
+       lxc-clone \
        lxc-destroy
 
 bin_PROGRAMS = \

=== modified file 'src/lxc/Makefile.in'
--- src/lxc/Makefile.in 2011-03-10 07:25:34 +0000
+++ src/lxc/Makefile.in 2011-03-30 15:36:58 +0000
@@ -49,7 +49,8 @@
        $(srcdir)/lxc-create.in $(srcdir)/lxc-destroy.in \
        $(srcdir)/lxc-ls.in $(srcdir)/lxc-netstat.in \
        $(srcdir)/lxc-ps.in $(srcdir)/lxc-setcap.in \
-       $(srcdir)/lxc-setuid.in $(srcdir)/lxc-version.in
+       $(srcdir)/lxc-setuid.in $(srcdir)/lxc-version.in \
+       $(srcdir)/lxc-clone.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/config/acinclude.m4 \
        $(top_srcdir)/config/linux.m4 $(top_srcdir)/configure.ac
@@ -58,7 +59,8 @@
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/src/config.h
 CONFIG_CLEAN_FILES = lxc-ps lxc-ls lxc-netstat lxc-checkconfig \
-       lxc-setcap lxc-setuid lxc-version lxc-create lxc-destroy
+       lxc-setcap lxc-setuid lxc-version lxc-create lxc-destroy \
+       lxc-clone
 CONFIG_CLEAN_VPATH_FILES =
 am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkglibdir)" \
        "$(DESTDIR)$(sodir)" "$(DESTDIR)$(bindir)" \
@@ -376,6 +378,7 @@
        lxc-setcap \
        lxc-setuid \
        lxc-version \
+       lxc-clone \
        lxc-create \
        lxc-destroy
 
@@ -445,6 +448,8 @@
        cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 lxc-version: $(top_builddir)/config.status $(srcdir)/lxc-version.in
        cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+lxc-clone: $(top_builddir)/config.status $(srcdir)/lxc-clone.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 lxc-create: $(top_builddir)/config.status $(srcdir)/lxc-create.in
        cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 lxc-destroy: $(top_builddir)/config.status $(srcdir)/lxc-destroy.in

=== added file 'src/lxc/lxc-clone.in'
--- src/lxc/lxc-clone.in        1970-01-01 00:00:00 +0000
+++ src/lxc/lxc-clone.in        2011-03-30 15:36:58 +0000
@@ -0,0 +1,206 @@
+#!/bin/bash
+
+#
+# lxc: linux Container library
+
+# Authors:
+# Serge Hallyn <[email protected]>
+# Daniel Lezcano <[email protected]>
+
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# This library 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
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+usage() {
+    echo "usage: lxc-clone -o <orig> -n <new> [-s] [-h] [-L fssize] [-v 
vgname]"
+}
+
+help() {
+    usage
+    echo
+    echo "creates a lxc system object."
+    echo
+    echo "Options:"
+    echo "orig        : name of the original container"
+    echo "new         : name of the new container"
+    echo "-s          : make the new rootfs a snapshot of the original"
+    echo "fssize      : size if creating a new fs.  By default, 2G"
+    echo "vgname      : lvm volume group name, lxc by default"
+}
+
+shortoptions='ho:n:sL:v:'
+longoptions='help,orig:,name:,snapshot,fssize,vgname'
+lxc_path=/var/lib/lxc
+bindir=/usr/bin
+snapshot=no
+lxc_size=2G
+lxc_vg=lxc
+
+getopt=$(getopt -o $shortoptions --longoptions  $longoptions -- "$@")
+if [ $? != 0 ]; then
+    usage
+    exit 1;
+fi
+
+eval set -- "$getopt"
+
+while true; do
+        case "$1" in
+           -h|--help)
+               help
+               exit 1
+               ;;
+           -s|--snapshot)
+               shift
+               snapshot=yes
+               ;;
+           -o|--orig)
+               shift
+               lxc_orig=$1
+               shift
+               ;;
+           -L|--fssize)
+               shift
+               lxc_size=$1
+               shift
+               ;;
+           -v|--vgname)
+               shift
+               lxc_vg=$1
+               shift
+               ;;
+           -n|--new)
+               shift
+               lxc_new=$1
+               shift
+               ;;
+            --)
+               shift
+               break;;
+            *)
+               echo $1
+               usage
+               exit 1
+               ;;
+        esac
+done
+
+if [ -z "$lxc_path" ]; then
+    echo "no configuration path defined !"
+    exit 1
+fi
+
+if [ ! -r $lxc_path ]; then
+    echo "configuration path '$lxc_path' not found"
+    exit 1
+fi
+
+if [ -z "$lxc_orig" ]; then
+    echo "no original container name specified"
+    usage
+    exit 1
+fi
+
+if [ -z "$lxc_new" ]; then
+    echo "no new container name specified"
+    usage
+    exit 1
+fi
+
+if [ "$(id -u)" != "0" ]; then
+   echo "This command has to be run as root"
+   exit 1
+fi
+
+if [ ! -r $lxc_path ]; then
+    echo "no configuration path defined !"
+    exit 1
+fi
+
+if [ ! -d "$lxc_path/$lxc_orig" ]; then
+    echo "'$lxc_orig' does not exist"
+    exit 1
+fi
+
+if [ -d "$lxc_path/$lxc_new" ]; then
+    echo "'$lxc_new' already exists"
+    exit 1
+fi
+
+trap "${bindir}/lxc-destroy -n $lxc_new; echo aborted; exit 1" SIGHUP SIGINT 
SIGTERM
+
+mkdir -p $lxc_path/$lxc_new
+
+echo "Tweaking configuration"
+cp $lxc_path/$lxc_orig/config $lxc_path/$lxc_new/config
+sed -i '/lxc.utsname/d' $lxc_path/$lxc_new/config
+echo "lxc.utsname = $hostname" >> $lxc_path/$lxc_new/config
+
+sed -i '/lxc.mount/d' $lxc_path/$lxc_new/config
+echo "lxc.mount = $lxc_path/$lxc_new/fstab" >> $lxc_path/$lxc_new/config
+
+cp $lxc_path/$lxc_orig/fstab $lxc_path/$lxc_new/fstab
+sed -i "s@$lxc_path/$lxc_orig@$lxc_path/$lxc_new@" $lxc_path/$lxc_new/fstab
+
+echo "Copying rootfs..."
+rootfs=$lxc_path/$lxc_new/rootfs
+# First figure out if the old is a device.  For now we only support
+# lvm devices.
+mounted=0
+sed -i '/lxc.rootfs/d' $lxc_path/$lxc_new/config
+oldroot=`grep lxc.rootfs $lxc_path/$lxc_orig/config | awk -F= '{ print $2 '}`
+if [ -b $oldroot ]; then
+       # this is a device.  If we don't want to snapshot, then mkfs, mount
+       # and rsync.  Trivial but not yet implemented
+       if [ $snapshot == "no" ]; then
+               echo "non-snapshot and non-lvm clone of block device not yet 
implemented"
+               exit 1
+       fi
+       lvdisplay $oldroot > /dev/null 2>&1
+       if [ $? -ne 0 ]; then
+               echo "non-snapshot and non-lvm clone of block device not yet 
implemented"
+               exit 1
+       fi
+       # ok, create a snapshot of the lvm device
+       lvcreate -s -L $lxc_size -n $lxc_new /dev/$lxc_vg/$lxc_orig || exit 1
+       echo "lxc.rootfs = /dev/$lxc_vg/$lxc_new" >> $lxc_path/$lxc_new/config
+       # and mount it so we can tweak it
+       mkdir -p $lxc_path/$lxc_new/rootfs
+       mount /dev/$lxc_vg/$lxc_new $rootfs || { echo "failed to mount new 
rootfs"; exit 1; }
+       mounted=1
+else
+       cp -a $lxc_path/$lxc_orig/rootfs $lxc_path/$lxc_new/rootfs || return 1
+       echo "lxc.rootfs = $rootfs" >> $lxc_path/$lxc_new/config
+fi
+
+echo "Updating rootfs..."
+hostname=$lxc_new
+
+# so you can 'ssh $hostname.' or 'ssh $hostname.local'
+sed -i "s/send host-name.*$/send host-name $hostname/" 
$rootfs/etc/dhcp/dhclient.conf
+
+# set the hostname
+cat <<EOF > $rootfs/etc/hostname
+$hostname
+EOF
+# set minimal hosts
+cat <<EOF > $rootfs/etc/hosts
+127.0.0.1 localhost $hostname
+EOF
+
+# if this was a block device, then umount it now
+if [ $mounted -eq 1 ]; then
+       umount $rootfs
+fi
+
+echo "'$lxc_new' created"

=== modified file 'src/lxc/lxc-destroy.in'
--- src/lxc/lxc-destroy.in      2010-01-10 10:40:21 +0000
+++ src/lxc/lxc-destroy.in      2011-03-29 23:00:34 +0000
@@ -26,7 +26,8 @@
 #
 
 usage() {
-    echo "usage: $0 -n <name>"
+    echo "usage: $0 -n <name> [-l]"
+    echo "       if -l is specified, attempt to lvremove the rootfs device"
 }
 
 if [ "$(id -u)" != "0" ]; then
@@ -34,9 +35,9 @@
    exit 1
 fi
 
-shortoptions='n:'
-longoptions='name:'
-lxc_path=@LXCPATH@
+shortoptions='n:l'
+longoptions='name:,lvm'
+lxc_path=/var/lib/lxc
 
 getopt=$(getopt -o $shortoptions --longoptions  $longoptions -- "$@")
 if [ $? != 0 ]; then
@@ -46,6 +47,8 @@
 
 eval set -- "$getopt"
 
+lvremove=0
+
 while true; do
         case "$1" in
            -n|--name)
@@ -53,6 +56,10 @@
                lxc_name=$1
                shift
                ;;
+           -l|--lvm)
+               shift
+               lvremove=1
+               ;;
             --)
                shift
                break;;
@@ -75,5 +82,13 @@
     exit 1
 fi
 
+if [ $lvremove -eq 1 ]; then
+    rootdev=`grep lxc.rootfs $lxc_path/$lxc_name/config | awk -F= '{ print $2 
'}`
+    # only makes sense if it is a blockdev or a symlink to one
+    if [ -b $rootdev -o -h $rootdev ]; then
+           lvremove $rootdev
+    fi
+fi
+
 # recursively remove the container to remove old container configuration
 rm -rf --preserve-root $lxc_path/$lxc_name

Attachment: signature.asc
Description: Digital signature

------------------------------------------------------------------------------
Create and publish websites with WebMatrix
Use the most popular FREE web apps or write code yourself; 
WebMatrix provides all the features you need to develop and 
publish your website. http://p.sf.net/sfu/ms-webmatrix-sf
_______________________________________________
Lxc-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/lxc-users

Reply via email to