I saw this on the blog. Very useful and time saver. Exactly what alot of pople were looking for.
On Wed, Mar 30, 2011 at 7:29 PM, Serge E. Hallyn <[email protected]>wrote: > 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 > > > -----BEGIN PGP SIGNATURE----- > Version: GnuPG v1.4.10 (GNU/Linux) > > iQEcBAEBAgAGBQJNk1pzAAoJEHmllQITXQdF7G4H/0xMrCVEzaFnmZAdo8jppR6E > tvo5fP1MtHlvu/SH+TbNEYv/Pd3TsqFllRomnBgKWPXbRVPmCY3gomoh+ec2wQOd > OYX8GMVCusqk2JTOTz/KD9YhBhYUEYrv2JRdXdYAav1yOdEhbtaJWWyO5L3qAV6M > lgoHrRqtuM0ueNVY5+0OIrhd5sHbxc/G1BXHERTkcPKWR7GwsyUjWOmjIL8bGQG/ > t0GKlyYAJPIbXDATW6Izp/R9q6+5tu8k9A+c2di2afFsS8l7ZhpUU+HhMTvqxYTJ > ajoRjfwzfhqbzGh1dnWRyLnRXL9Lfokkkhii0RPbVpIdTLRaYCuJ1Uh2v1im5i4= > =/Kxf > -----END PGP 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 > > -- God Bless
------------------------------------------------------------------------------ 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
