mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-08-06 05:17:59 +00:00
remove lxc-clone-sh
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
This commit is contained in:
parent
ec471210d9
commit
b164a17f9b
1
.gitignore
vendored
1
.gitignore
vendored
@ -42,7 +42,6 @@ src/lxc/lxc-cgroup
|
||||
src/lxc/lxc-checkconfig
|
||||
src/lxc/lxc-checkpoint
|
||||
src/lxc/lxc-clone
|
||||
src/lxc/lxc-clone-sh
|
||||
src/lxc/lxc-console
|
||||
src/lxc/lxc-config
|
||||
src/lxc/lxc-create
|
||||
|
@ -382,7 +382,6 @@ AC_CONFIG_FILES([
|
||||
src/lxc/lxc-checkconfig
|
||||
src/lxc/lxc-version
|
||||
src/lxc/lxc-create
|
||||
src/lxc/lxc-clone-sh
|
||||
src/lxc/lxc-shutdown
|
||||
src/lxc/lxc-start-ephemeral
|
||||
src/lxc/lxc-destroy
|
||||
|
@ -124,7 +124,6 @@ bin_SCRIPTS = \
|
||||
lxc-checkconfig \
|
||||
lxc-version \
|
||||
lxc-create \
|
||||
lxc-clone-sh \
|
||||
lxc-shutdown \
|
||||
lxc-destroy
|
||||
|
||||
|
@ -1,324 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# lxc: linux Container library
|
||||
|
||||
# Authors:
|
||||
# Serge Hallyn <serge.hallyn@ubuntu.com>
|
||||
# Daniel Lezcano <daniel.lezcano@free.fr>
|
||||
|
||||
# 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
|
||||
|
||||
set -e
|
||||
|
||||
usage() {
|
||||
echo "usage: $(basename $0) -o ORIG_NAME -n NEW_NAME [-s] [-h] [-L FS_SIZE]" >&2
|
||||
echo " [-v VG_NAME] [-p LV_PREFIX] [-t FS_TYPE]" >&2
|
||||
}
|
||||
|
||||
help() {
|
||||
usage
|
||||
echo >&2
|
||||
echo "Clone an existing container on the system." >&2
|
||||
echo >&2
|
||||
echo "Options:" >&2
|
||||
echo " -o ORIG_NAME specify the name of the original container" >&2
|
||||
echo " -n NEW_NAME specify the name of the new container" >&2
|
||||
echo " -s make the new rootfs a snapshot of the original" >&2
|
||||
echo " -L FS_SIZE specify the new filesystem size (default: same as original)" >&2
|
||||
echo " -v VG_NAME specify the new LVM volume group name (default: lxc)" >&2
|
||||
echo " -p LV_PREFIX add a prefix to new LVM logical volume names" >&2
|
||||
echo " -t FS_TYPE specify the new filesystem type (default: ext3;" >&2
|
||||
echo " only works for non-snapshot LVM)" >&2
|
||||
}
|
||||
|
||||
usage_err() {
|
||||
[ -n "$1" ] && echo "$1" >&2
|
||||
usage
|
||||
exit 1
|
||||
}
|
||||
|
||||
optarg_check() {
|
||||
[ -n "$2" ] || usage_err "option $1 requires an argument"
|
||||
}
|
||||
|
||||
. @DATADIR@/lxc/lxc.functions
|
||||
snapshot=no
|
||||
lxc_size=_unset
|
||||
lxc_vg=lxc
|
||||
lxc_lv_prefix=""
|
||||
fstype=ext3
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
opt="$1"
|
||||
shift
|
||||
case "$opt" in
|
||||
-h|--help)
|
||||
help
|
||||
exit 1
|
||||
;;
|
||||
-s|--snapshot)
|
||||
snapshot=yes
|
||||
snapshot_opt="-s"
|
||||
;;
|
||||
-o|--orig)
|
||||
optarg_check $opt $1
|
||||
lxc_orig=$1
|
||||
shift
|
||||
;;
|
||||
-L|--fssize)
|
||||
optarg_check $opt $1
|
||||
lxc_size=$1
|
||||
shift
|
||||
;;
|
||||
-t|--fstype)
|
||||
optarg_check $opt $1
|
||||
fstype=$1
|
||||
shift
|
||||
;;
|
||||
-v|--vgname)
|
||||
optarg_check $opt $1
|
||||
lxc_vg=$1
|
||||
shift
|
||||
;;
|
||||
-n|--name)
|
||||
optarg_check $opt $1
|
||||
lxc_new=$1
|
||||
shift
|
||||
;;
|
||||
-p|--lvprefix)
|
||||
optarg_check $opt $1
|
||||
lxc_lv_prefix=$1
|
||||
shift
|
||||
;;
|
||||
--)
|
||||
break
|
||||
;;
|
||||
-?)
|
||||
usage_err "Unknown option: '$opt'"
|
||||
;;
|
||||
-*)
|
||||
# split opts -abc into -a -b -c
|
||||
set -- $(echo "${opt#-}" | sed 's/\(.\)/ -\1/g') "$@"
|
||||
;;
|
||||
*)
|
||||
usage_err
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$lxc_path" ]; then
|
||||
echo "$(basename $0): no configuration path defined" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -r $lxc_path ]; then
|
||||
echo "$(basename $0): configuration path '$lxc_path' not found" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$lxc_orig" ]; then
|
||||
echo "$(basename $0): no original container name specified" >&2
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$lxc_new" ]; then
|
||||
echo "$(basename $0): no new container name specified" >&2
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$(id -u)" != "0" ]; then
|
||||
echo "$(basename $0): must be run as root" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "$lxc_path/$lxc_orig" ]; then
|
||||
echo "$(basename $0): '$lxc_orig' does not exist" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -d "$lxc_path/$lxc_new" ]; then
|
||||
echo "$(basename $0): '$lxc_new' already exists" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mounted=0
|
||||
frozen=0
|
||||
oldroot=`grep lxc.rootfs $lxc_path/$lxc_orig/config | awk -F= '{ print $2 '}`
|
||||
|
||||
cleanup() {
|
||||
if [ -b $oldroot ]; then
|
||||
if [ $mounted -eq 1 ]; then
|
||||
umount $rootfs || true
|
||||
fi
|
||||
lvremove -f $rootdev || true
|
||||
fi
|
||||
${bindir}/lxc-destroy -n $lxc_new || true
|
||||
if [ $frozen -eq 1 ]; then
|
||||
lxc-unfreeze -n $lxc_orig
|
||||
fi
|
||||
echo "$(basename $0): aborted" >&2
|
||||
exit 1
|
||||
}
|
||||
trap cleanup HUP INT TERM
|
||||
|
||||
mkdir -p $lxc_path/$lxc_new
|
||||
hostname=$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
|
||||
|
||||
grep "lxc.mount[ \t]" $lxc_path/$lxc_new/config >/dev/null 2>&1 && { sed -i '/lxc.mount[ \t]/d' $lxc_path/$lxc_new/config; echo "lxc.mount = $lxc_path/$lxc_new/fstab" >> $lxc_path/$lxc_new/config; }
|
||||
|
||||
if [ -e $lxc_path/$lxc_orig/fstab ];then
|
||||
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
|
||||
fi
|
||||
|
||||
echo "Copying rootfs..."
|
||||
oldroot=`grep lxc.rootfs $lxc_path/$lxc_orig/config | awk -F'[= \t]+' '{ print $2 }'`
|
||||
rootfs=`echo $oldroot |sed "s/$lxc_orig/$lxc_new/"`
|
||||
|
||||
container_running=True
|
||||
lxc-info -n $lxc_orig --state-is RUNNING || container_running=False
|
||||
|
||||
sed -i '/lxc.rootfs/d' $lxc_path/$lxc_new/config
|
||||
if [ -b $oldroot ]; then
|
||||
which vgscan >/dev/null 2>&1 || { echo "$(basename $0): lvm is not installed" >&2; false; }
|
||||
lvdisplay $oldroot > /dev/null 2>&1 || { echo "$(basename $0): non-lvm blockdev cloning is not supported" >&2; false; }
|
||||
lvm=TRUE
|
||||
# ok, create a snapshot of the lvm device
|
||||
if [ $container_running = "True" ]; then
|
||||
lxc-freeze -n $lxc_orig
|
||||
frozen=1
|
||||
fi
|
||||
if [ $lxc_size = "_unset" ]; then
|
||||
lxc_size=`lvdisplay $oldroot | grep Size | awk '{ print $3 $4 }'`
|
||||
fi
|
||||
newlv="${lxc_lv_prefix}${lxc_new}_snapshot"
|
||||
lvcreate -s -L $lxc_size -n $newlv $oldroot
|
||||
which xfs_admin > /dev/null 2>&1 && {
|
||||
# change filesystem UUID if it is an xfs filesystem
|
||||
xfs_admin -u /dev/$lxc_vg/$newlv && xfs_admin -U generate /dev/$lxc_vg/$newlv
|
||||
}
|
||||
|
||||
if [ $container_running = "True" ]; then
|
||||
lxc-unfreeze -n $lxc_orig
|
||||
frozen=0
|
||||
fi
|
||||
if [ $snapshot = "no" ]; then
|
||||
#mount snapshot
|
||||
mkdir -p ${rootfs}_snapshot
|
||||
mount /dev/$lxc_vg/${lxc_lv_prefix}${lxc_new}_snapshot ${rootfs}_snapshot || { echo "$(basename $0): failed to mount new rootfs_snapshot" >&2; false; }
|
||||
#create a new lv
|
||||
lvcreate -L $lxc_size $lxc_vg -n ${lxc_lv_prefix}$lxc_new
|
||||
echo "lxc.rootfs = /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new" >> $lxc_path/$lxc_new/config
|
||||
# and mount it so we can tweak it
|
||||
mkdir -p $rootfs
|
||||
mkfs -t $fstype /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new
|
||||
mount /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new $rootfs || { echo "$(basename $0): failed to mount new rootfs" >&2; false; }
|
||||
mounted=1
|
||||
rsync -Hax ${rootfs}_snapshot/ ${rootfs}/ || { echo "$(basename $0): copying data to new lv failed" >&2; false; }
|
||||
umount ${rootfs}_snapshot
|
||||
rmdir ${rootfs}_snapshot
|
||||
lvremove -f $lxc_vg/${lxc_lv_prefix}${lxc_new}_snapshot
|
||||
else
|
||||
lvrename $lxc_vg/${lxc_lv_prefix}${lxc_new}_snapshot $lxc_vg/${lxc_lv_prefix}$lxc_new
|
||||
echo "lxc.rootfs = /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new" >> $lxc_path/$lxc_new/config
|
||||
# and mount it so we can tweak it
|
||||
mkdir -p $rootfs
|
||||
mount /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new $rootfs || { echo "$(basename $0): failed to mount new rootfs" >&2; false; }
|
||||
mounted=1
|
||||
fi
|
||||
|
||||
elif which btrfs >/dev/null 2>&1 && btrfs subvolume list $oldroot >/dev/null 2>&1; then
|
||||
# if oldroot is a btrfs subvolume, assume they want a snapshot
|
||||
btrfs subvolume snapshot "$oldroot" "$rootfs" 2>&1 || { echo "$(basename $0): btrfs snapshot failed" >&2; false; }
|
||||
echo "lxc.rootfs = $rootfs" >> "$lxc_path/$lxc_new/config"
|
||||
elif [ -d $lxc_path/$lxc_orig/delta0 ]; then # this is a quasi-ephemeral container
|
||||
if [ $container_running = "True" ]; then
|
||||
echo "$(basename $0): container $lxc_orig is running." >&2
|
||||
cleanup
|
||||
fi
|
||||
rsync -Hax $lxc_path/$lxc_orig/delta0 $lxc_path/$lxc_new/
|
||||
touch $lxc_path/$lxc_new/configured
|
||||
cp -f $lxc_path/$lxc_orig/pre-mount $lxc_path/$lxc_new/
|
||||
sed -i "s@$lxc_path/$lxc_orig@$lxc_path/$lxc_new@g" $lxc_path/$lxc_new/config
|
||||
sed -i "s@$lxc_path/$lxc_orig@$lxc_path/$lxc_new@g" $lxc_path/$lxc_new/pre-mount
|
||||
sed -i "s@LXC_NAME=\"$lxc_orig@LXC_NAME=\"$lxc_new@" $lxc_path/$lxc_new/pre-mount
|
||||
# lxc-start-ephemeral will have updated /etc/hostname and such under the
|
||||
# delta0, so just mounting the delta should suffice.
|
||||
mkdir -p $rootfs
|
||||
mount --bind $lxc_path/$lxc_new/delta0 $rootfs
|
||||
mounted=1
|
||||
echo "lxc.rootfs = $rootfs" >> "$lxc_path/$lxc_new/config"
|
||||
else
|
||||
if [ $snapshot = "yes" ]; then
|
||||
echo "$(basename $0): cannot snapshot a directory" >&2
|
||||
cleanup
|
||||
fi
|
||||
if [ $container_running = "True" ]; then
|
||||
lxc-freeze -n $lxc_orig
|
||||
frozen=1
|
||||
fi
|
||||
mkdir -p $rootfs/
|
||||
rsync -Hax $oldroot/ $rootfs/
|
||||
echo "lxc.rootfs = $rootfs" >> $lxc_path/$lxc_new/config
|
||||
if [ $container_running = "True" ]; then
|
||||
lxc-unfreeze -n $lxc_orig
|
||||
frozen=0
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Updating rootfs..."
|
||||
|
||||
# so you can 'ssh $hostname.' or 'ssh $hostname.local'
|
||||
if [ -f $rootfs/etc/dhcp/dhclient.conf ] && ! grep -q "^send host-name.*hostname" $rootfs/etc/dhcp/dhclient.conf; then
|
||||
sed -i "s/send host-name.*$/send host-name \"$hostname\";/" $rootfs/etc/dhcp/dhclient.conf
|
||||
fi
|
||||
|
||||
c=$lxc_path/$lxc_new/config
|
||||
# change hwaddrs
|
||||
mv ${c} ${c}.old
|
||||
(
|
||||
while read line; do
|
||||
if echo $line | grep -q -w '^lxc.network.hwaddr'; then
|
||||
echo "lxc.network.hwaddr= 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')"
|
||||
else
|
||||
echo "$line"
|
||||
fi
|
||||
done
|
||||
) < ${c}.old > ${c}
|
||||
rm -f ${c}.old
|
||||
|
||||
# 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"
|
Loading…
Reference in New Issue
Block a user