<div dir="ltr">I saw this on the blog. Very useful and time saver. Exactly what alot of pople were looking for.<br><br>
<div class="gmail_quote">On Wed, Mar 30, 2011 at 7:29 PM, Serge E. Hallyn <span dir="ltr"><<a href="mailto:serge.hallyn@ubuntu.com">serge.hallyn@ubuntu.com</a>></span> wrote:<br>
<blockquote style="BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex; PADDING-LEFT: 1ex" class="gmail_quote">I've replaced most of my previous use of kvm and cloud instances for bug<br>investigations with lxc instances. To emulate my older workflows, I've<br>
created lxc-clone. My diff against the current natty lxc package is<br>attached. I've written up how I use this at <a href="http://s3hh.wordpress.com/" target="_blank">s3hh.wordpress.com</a>. Briefly,<br>I have a single pristine container, with LVM rootfs, for each of lucid,<br>
maverick, and natty. When I want a container, I<br><br> lxc-clone -o natty -n n1 -s<br> lxc-start -n n1<br><br>which takes about 5 seconds altogether. Ruin n1 however I like, and<br><br> lxc-destroy -l -n n1<br>
<br>when done.<br><br>It needs fleshing out, but it's at the point where it does exactly what<br>I need. The next thing I'm likely to add will be btrfs snapshotting,<br>not sure when.<br><br>Daniel, is this something you'd consider adding? I assume that if so,<br>
then there are changes you'd like to make to the interface :)<br><br>thanks,<br>-serge<br><br>=== modified file 'configure'<br>--- configure 2011-03-10 07:25:34 +0000<br>+++ configure 2011-03-30 15:36:58 +0000<br>
@@ -5057,7 +5057,7 @@<br> CFLAGS="$CFLAGS -Wall"<br> fi<br><br>-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"<br>
+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"<br>
<br> ac_config_commands="$ac_config_commands default"<br><br>@@ -5842,6 +5842,7 @@<br> "src/lxc/lxc-setuid") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-setuid" ;;<br> "src/lxc/lxc-version") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-version" ;;<br>
"src/lxc/lxc-create") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-create" ;;<br>+ "src/lxc/lxc-clone") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-clone" ;;<br> "src/lxc/lxc-destroy") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-destroy" ;;<br>
"default") CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;;<br><br><br>=== modified file '<a href="http://configure.ac/" target="_blank">configure.ac</a>'<br>--- <a href="http://configure.ac/" target="_blank">configure.ac</a> 2011-03-10 07:25:34 +0000<br>
+++ <a href="http://configure.ac/" target="_blank">configure.ac</a> 2011-03-30 15:36:58 +0000<br>@@ -156,6 +156,7 @@<br> src/lxc/lxc-setuid<br> src/lxc/lxc-version<br> src/lxc/lxc-create<br>+ src/lxc/lxc-clone<br>
src/lxc/lxc-destroy<br><br> ])<br><br>=== modified file 'lxc.spec'<br>--- lxc.spec 2011-03-10 07:25:34 +0000<br>+++ lxc.spec 2011-03-30 15:36:58 +0000<br>@@ -78,6 +78,7 @@<br> %{_bindir}/*<br> %attr(4111,root,root) %{_bindir}/lxc-attach<br>
%attr(4111,root,root) %{_bindir}/lxc-create<br>+%attr(4111,root,root) %{_bindir}/lxc-clone<br> %attr(4111,root,root) %{_bindir}/lxc-start<br> %attr(4111,root,root) %{_bindir}/lxc-netstat<br> %attr(4111,root,root) %{_bindir}/lxc-unshare<br>
<br>=== modified file 'src/lxc/Makefile.am'<br>--- src/lxc/Makefile.am 2011-03-10 07:25:34 +0000<br>+++ src/lxc/Makefile.am 2011-03-30 15:36:58 +0000<br>@@ -72,6 +72,7 @@<br> lxc-setuid \<br> lxc-version \<br>
lxc-create \<br>+ lxc-clone \<br> lxc-destroy<br><br> bin_PROGRAMS = \<br><br>=== modified file 'src/lxc/Makefile.in'<br>--- src/lxc/Makefile.in 2011-03-10 07:25:34 +0000<br>+++ src/lxc/Makefile.in 2011-03-30 15:36:58 +0000<br>
@@ -49,7 +49,8 @@<br> $(srcdir)/<a href="http://lxc-create.in/" target="_blank">lxc-create.in</a> $(srcdir)/<a href="http://lxc-destroy.in/" target="_blank">lxc-destroy.in</a> \<br> $(srcdir)/<a href="http://lxc-ls.in/" target="_blank">lxc-ls.in</a> $(srcdir)/<a href="http://lxc-netstat.in/" target="_blank">lxc-netstat.in</a> \<br>
$(srcdir)/<a href="http://lxc-ps.in/" target="_blank">lxc-ps.in</a> $(srcdir)/<a href="http://lxc-setcap.in/" target="_blank">lxc-setcap.in</a> \<br>- $(srcdir)/<a href="http://lxc-setuid.in/" target="_blank">lxc-setuid.in</a> $(srcdir)/<a href="http://lxc-version.in/" target="_blank">lxc-version.in</a><br>
+ $(srcdir)/<a href="http://lxc-setuid.in/" target="_blank">lxc-setuid.in</a> $(srcdir)/<a href="http://lxc-version.in/" target="_blank">lxc-version.in</a> \<br>+ $(srcdir)/<a href="http://lxc-clone.in/" target="_blank">lxc-clone.in</a><br>
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4<br> am__aclocal_m4_deps = $(top_srcdir)/config/acinclude.m4 \<br> $(top_srcdir)/config/linux.m4 $(top_srcdir)/<a href="http://configure.ac/" target="_blank">configure.ac</a><br>
@@ -58,7 +59,8 @@<br> mkinstalldirs = $(install_sh) -d<br> CONFIG_HEADER = $(top_builddir)/src/config.h<br> CONFIG_CLEAN_FILES = lxc-ps lxc-ls lxc-netstat lxc-checkconfig \<br>- lxc-setcap lxc-setuid lxc-version lxc-create lxc-destroy<br>
+ lxc-setcap lxc-setuid lxc-version lxc-create lxc-destroy \<br>+ lxc-clone<br> CONFIG_CLEAN_VPATH_FILES =<br> am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkglibdir)" \<br> "$(DESTDIR)$(sodir)" "$(DESTDIR)$(bindir)" \<br>
@@ -376,6 +378,7 @@<br> lxc-setcap \<br> lxc-setuid \<br> lxc-version \<br>+ lxc-clone \<br> lxc-create \<br> lxc-destroy<br><br>@@ -445,6 +448,8 @@<br> cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@<br>
lxc-version: $(top_builddir)/config.status $(srcdir)/<a href="http://lxc-version.in/" target="_blank">lxc-version.in</a><br> cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@<br>+lxc-clone: $(top_builddir)/config.status $(srcdir)/<a href="http://lxc-clone.in/" target="_blank">lxc-clone.in</a><br>
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@<br> lxc-create: $(top_builddir)/config.status $(srcdir)/<a href="http://lxc-create.in/" target="_blank">lxc-create.in</a><br> cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@<br>
lxc-destroy: $(top_builddir)/config.status $(srcdir)/<a href="http://lxc-destroy.in/" target="_blank">lxc-destroy.in</a><br><br>=== added file 'src/lxc/<a href="http://lxc-clone.in/" target="_blank">lxc-clone.in</a>'<br>
--- src/lxc/<a href="http://lxc-clone.in/" target="_blank">lxc-clone.in</a> 1970-01-01 00:00:00 +0000<br>+++ src/lxc/<a href="http://lxc-clone.in/" target="_blank">lxc-clone.in</a> 2011-03-30 15:36:58 +0000<br>
@@ -0,0 +1,206 @@<br>+#!/bin/bash<br>+<br>+#<br>+# lxc: linux Container library<br>+<br>+# Authors:<br>+# Serge Hallyn <<a href="mailto:serge.hallyn@ubuntu.com">serge.hallyn@ubuntu.com</a>><br>+# Daniel Lezcano <<a href="mailto:daniel.lezcano@free.fr">daniel.lezcano@free.fr</a>><br>
+<br>+# This library is free software; you can redistribute it and/or<br>+# modify it under the terms of the GNU Lesser General Public<br>+# License as published by the Free Software Foundation; either<br>+# version 2.1 of the License, or (at your option) any later version.<br>
+<br>+# This library is distributed in the hope that it will be useful,<br>+# but WITHOUT ANY WARRANTY; without even the implied warranty of<br>+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU<br>+# Lesser General Public License for more details.<br>
+<br>+# You should have received a copy of the GNU Lesser General Public<br>+# License along with this library; if not, write to the Free Software<br>+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<br>
+<br>+usage() {<br>+ echo "usage: lxc-clone -o <orig> -n <new> [-s] [-h] [-L fssize] [-v vgname]"<br>+}<br>+<br>+help() {<br>+ usage<br>+ echo<br>+ echo "creates a lxc system object."<br>
+ echo<br>+ echo "Options:"<br>+ echo "orig : name of the original container"<br>+ echo "new : name of the new container"<br>+ echo "-s : make the new rootfs a snapshot of the original"<br>
+ echo "fssize : size if creating a new fs. By default, 2G"<br>+ echo "vgname : lvm volume group name, lxc by default"<br>+}<br>+<br>+shortoptions='ho:n:sL:v:'<br>+longoptions='help,orig:,name:,snapshot,fssize,vgname'<br>
+lxc_path=/var/lib/lxc<br>+bindir=/usr/bin<br>+snapshot=no<br>+lxc_size=2G<br>+lxc_vg=lxc<br>+<br>+getopt=$(getopt -o $shortoptions --longoptions $longoptions -- "$@")<br>+if [ $? != 0 ]; then<br>+ usage<br>
+ exit 1;<br>+fi<br>+<br>+eval set -- "$getopt"<br>+<br>+while true; do<br>+ case "$1" in<br>+ -h|--help)<br>+ help<br>+ exit 1<br>+ ;;<br>
+ -s|--snapshot)<br>+ shift<br>+ snapshot=yes<br>+ ;;<br>+ -o|--orig)<br>+ shift<br>+ lxc_orig=$1<br>+ shift<br>+ ;;<br>
+ -L|--fssize)<br>+ shift<br>+ lxc_size=$1<br>+ shift<br>+ ;;<br>+ -v|--vgname)<br>+ shift<br>+ lxc_vg=$1<br>+ shift<br>
+ ;;<br>+ -n|--new)<br>+ shift<br>+ lxc_new=$1<br>+ shift<br>+ ;;<br>+ --)<br>+ shift<br>+ break;;<br>
+ *)<br>+ echo $1<br>+ usage<br>+ exit 1<br>+ ;;<br>+ esac<br>+done<br>+<br>+if [ -z "$lxc_path" ]; then<br>+ echo "no configuration path defined !"<br>
+ exit 1<br>+fi<br>+<br>+if [ ! -r $lxc_path ]; then<br>+ echo "configuration path '$lxc_path' not found"<br>+ exit 1<br>+fi<br>+<br>+if [ -z "$lxc_orig" ]; then<br>+ echo "no original container name specified"<br>
+ usage<br>+ exit 1<br>+fi<br>+<br>+if [ -z "$lxc_new" ]; then<br>+ echo "no new container name specified"<br>+ usage<br>+ exit 1<br>+fi<br>+<br>+if [ "$(id -u)" != "0" ]; then<br>
+ echo "This command has to be run as root"<br>+ exit 1<br>+fi<br>+<br>+if [ ! -r $lxc_path ]; then<br>+ echo "no configuration path defined !"<br>+ exit 1<br>+fi<br>+<br>+if [ ! -d "$lxc_path/$lxc_orig" ]; then<br>
+ echo "'$lxc_orig' does not exist"<br>+ exit 1<br>+fi<br>+<br>+if [ -d "$lxc_path/$lxc_new" ]; then<br>+ echo "'$lxc_new' already exists"<br>+ exit 1<br>+fi<br>+<br>
+trap "${bindir}/lxc-destroy -n $lxc_new; echo aborted; exit 1" SIGHUP SIGINT SIGTERM<br>+<br>+mkdir -p $lxc_path/$lxc_new<br>+<br>+echo "Tweaking configuration"<br>+cp $lxc_path/$lxc_orig/config $lxc_path/$lxc_new/config<br>
+sed -i '/lxc.utsname/d' $lxc_path/$lxc_new/config<br>+echo "lxc.utsname = $hostname" >> $lxc_path/$lxc_new/config<br>+<br>+sed -i '/lxc.mount/d' $lxc_path/$lxc_new/config<br>+echo "lxc.mount = $lxc_path/$lxc_new/fstab" >> $lxc_path/$lxc_new/config<br>
+<br>+cp $lxc_path/$lxc_orig/fstab $lxc_path/$lxc_new/fstab<br>+sed -i "s@$lxc_path/$lxc_orig@$lxc_path/$lxc_new@" $lxc_path/$lxc_new/fstab<br>+<br>+echo "Copying rootfs..."<br>+rootfs=$lxc_path/$lxc_new/rootfs<br>
+# First figure out if the old is a device. For now we only support<br>+# lvm devices.<br>+mounted=0<br>+sed -i '/lxc.rootfs/d' $lxc_path/$lxc_new/config<br>+oldroot=`grep lxc.rootfs $lxc_path/$lxc_orig/config | awk -F= '{ print $2 '}`<br>
+if [ -b $oldroot ]; then<br>+ # this is a device. If we don't want to snapshot, then mkfs, mount<br>+ # and rsync. Trivial but not yet implemented<br>+ if [ $snapshot == "no" ]; then<br>
+ echo "non-snapshot and non-lvm clone of block device not yet implemented"<br>+ exit 1<br>+ fi<br>+ lvdisplay $oldroot > /dev/null 2>&1<br>+ if [ $? -ne 0 ]; then<br>
+ echo "non-snapshot and non-lvm clone of block device not yet implemented"<br>+ exit 1<br>+ fi<br>+ # ok, create a snapshot of the lvm device<br>+ lvcreate -s -L $lxc_size -n $lxc_new /dev/$lxc_vg/$lxc_orig || exit 1<br>
+ echo "lxc.rootfs = /dev/$lxc_vg/$lxc_new" >> $lxc_path/$lxc_new/config<br>+ # and mount it so we can tweak it<br>+ mkdir -p $lxc_path/$lxc_new/rootfs<br>+ mount /dev/$lxc_vg/$lxc_new $rootfs || { echo "failed to mount new rootfs"; exit 1; }<br>
+ mounted=1<br>+else<br>+ cp -a $lxc_path/$lxc_orig/rootfs $lxc_path/$lxc_new/rootfs || return 1<br>+ echo "lxc.rootfs = $rootfs" >> $lxc_path/$lxc_new/config<br>+fi<br>+<br>+echo "Updating rootfs..."<br>
+hostname=$lxc_new<br>+<br>+# so you can 'ssh $hostname.' or 'ssh $hostname.local'<br>+sed -i "s/send host-name.*$/send host-name $hostname/" $rootfs/etc/dhcp/dhclient.conf<br>+<br>+# set the hostname<br>
+cat <<EOF > $rootfs/etc/hostname<br>+$hostname<br>+EOF<br>+# set minimal hosts<br>+cat <<EOF > $rootfs/etc/hosts<br>+127.0.0.1 localhost $hostname<br>+EOF<br>+<br>+# if this was a block device, then umount it now<br>
+if [ $mounted -eq 1 ]; then<br>+ umount $rootfs<br>+fi<br>+<br>+echo "'$lxc_new' created"<br><br>=== modified file 'src/lxc/<a href="http://lxc-destroy.in/" target="_blank">lxc-destroy.in</a>'<br>
--- src/lxc/<a href="http://lxc-destroy.in/" target="_blank">lxc-destroy.in</a> 2010-01-10 10:40:21 +0000<br>+++ src/lxc/<a href="http://lxc-destroy.in/" target="_blank">lxc-destroy.in</a> 2011-03-29 23:00:34 +0000<br>
@@ -26,7 +26,8 @@<br> #<br><br> usage() {<br>- echo "usage: $0 -n <name>"<br>+ echo "usage: $0 -n <name> [-l]"<br>+ echo " if -l is specified, attempt to lvremove the rootfs device"<br>
}<br><br> if [ "$(id -u)" != "0" ]; then<br>@@ -34,9 +35,9 @@<br> exit 1<br> fi<br><br>-shortoptions='n:'<br>-longoptions='name:'<br>-lxc_path=@LXCPATH@<br>+shortoptions='n:l'<br>
+longoptions='name:,lvm'<br>+lxc_path=/var/lib/lxc<br><br> getopt=$(getopt -o $shortoptions --longoptions $longoptions -- "$@")<br> if [ $? != 0 ]; then<br>@@ -46,6 +47,8 @@<br><br> eval set -- "$getopt"<br>
<br>+lvremove=0<br>+<br> while true; do<br> case "$1" in<br> -n|--name)<br>@@ -53,6 +56,10 @@<br> lxc_name=$1<br> shift<br> ;;<br>+ -l|--lvm)<br>
+ shift<br>+ lvremove=1<br>+ ;;<br> --)<br> shift<br> break;;<br>@@ -75,5 +82,13 @@<br> exit 1<br> fi<br><br>+if [ $lvremove -eq 1 ]; then<br>
+ rootdev=`grep lxc.rootfs $lxc_path/$lxc_name/config | awk -F= '{ print $2 '}`<br>+ # only makes sense if it is a blockdev or a symlink to one<br>+ if [ -b $rootdev -o -h $rootdev ]; then<br>+ lvremove $rootdev<br>
+ fi<br>+fi<br>+<br> # recursively remove the container to remove old container configuration<br> rm -rf --preserve-root $lxc_path/$lxc_name<br><br><br>-----BEGIN PGP SIGNATURE-----<br>Version: GnuPG v1.4.10 (GNU/Linux)<br>
<br>iQEcBAEBAgAGBQJNk1pzAAoJEHmllQITXQdF7G4H/0xMrCVEzaFnmZAdo8jppR6E<br>tvo5fP1MtHlvu/SH+TbNEYv/Pd3TsqFllRomnBgKWPXbRVPmCY3gomoh+ec2wQOd<br>OYX8GMVCusqk2JTOTz/KD9YhBhYUEYrv2JRdXdYAav1yOdEhbtaJWWyO5L3qAV6M<br>lgoHrRqtuM0ueNVY5+0OIrhd5sHbxc/G1BXHERTkcPKWR7GwsyUjWOmjIL8bGQG/<br>
t0GKlyYAJPIbXDATW6Izp/R9q6+5tu8k9A+c2di2afFsS8l7ZhpUU+HhMTvqxYTJ<br>ajoRjfwzfhqbzGh1dnWRyLnRXL9Lfokkkhii0RPbVpIdTLRaYCuJ1Uh2v1im5i4=<br>=/Kxf<br>-----END PGP SIGNATURE-----<br><br>------------------------------------------------------------------------------<br>
Create and publish websites with WebMatrix<br>Use the most popular FREE web apps or write code yourself;<br>WebMatrix provides all the features you need to develop and<br>publish your website. <a href="http://p.sf.net/sfu/ms-webmatrix-sf" target="_blank">http://p.sf.net/sfu/ms-webmatrix-sf</a><br>
<br>_______________________________________________<br>Lxc-users mailing list<br><a href="mailto:Lxc-users@lists.sourceforge.net">Lxc-users@lists.sourceforge.net</a><br><a href="https://lists.sourceforge.net/lists/listinfo/lxc-users" target="_blank">https://lists.sourceforge.net/lists/listinfo/lxc-users</a><br>
<br></blockquote></div><br><br clear="all"><br>-- <br>God Bless<br></div>