File build-vm-lxc of Package build
#
# LXC specific functions
#
################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
lxc_get_id() {
LXCID="obsbuild:${BUILD_ROOT##*/}"
if which lxc-config >/dev/null 2>&1; then
LXC_TYPE=standalone
elif which virsh >/dev/null 2>&1; then
LXC_TYPE=libvirt
else
LXC_TYPE=unknown
fi
}
vm_verify_options_lxc() {
VM_ROOT=
VM_SWAP=
}
lxcsh() {
virsh -c lxc:/// "$@"
}
vm_startup_lxc() {
lxc_get_id
LXCCONF="$BUILD_ROOT/.build.lxc.conf"
buildroot_rm .build.lxc.conf
vm_startup_lxc_$LXC_TYPE "$@"
BUILDSTATUS="$?"
test "$BUILDSTATUS" != 255 || BUILDSTATUS=3
cleanup_and_exit "$BUILDSTATUS"
}
vm_startup_lxc_standalone() {
LXCDIR="`lxc-config lxc.lxcpath`/$LXCID"
LXCROOTFS="$LXCDIR/rootfs"
LXCHOOK="$LXCDIR/pre-mount.hook"
LXCVERSION="$(lxc-create --version)"
cat $BUILD_DIR/lxc.conf > "$LXCCONF"
cat >> "$LXCCONF" <<-EOF
lxc.rootfs = $LXCROOTFS
lxc.hook.pre-mount = $LXCHOOK
EOF
case "$LXCVERSION" in
[34].*)
sed -i \
-e 's/lxc\.aa_profile = /lxc.apparmor.profile = /' \
-e 's/lxc\.console = /lxc.console.path = /' \
-e 's/lxc\.rootfs = /lxc.rootfs.path = dir:/' \
"$LXCCONF"
;;
esac
# XXX: do this always instead of leaking the hosts' one?
buildroot_rm /etc/mtab
echo "rootfs / rootfs rw 0 0" > "$BUILD_ROOT/etc/mtab"
lxc-destroy -n "$LXCID" >/dev/null 2>&1 || true
mkdir -p "$LXCROOTFS"
cat > "$LXCHOOK" <<-EOF
#!/bin/sh
mount --bind "$BUILD_ROOT" "$LXCROOTFS"
EOF
chmod a+x "$LXCHOOK"
case "$LXCVERSION" in
1.0.8|1.1.*|[234].*)
lxc-create -n "$LXCID" -f "$LXCCONF" -t none || cleanup_and_exit 1
lxc-start -n "$LXCID" -F "$@" "$vm_init_script"
;;
1.0.*)
lxc-create -n "$LXCID" -f "$LXCCONF" || cleanup_and_exit 1
lxc-start -n "$LXCID" "$@" "$vm_init_script"
;;
*)
echo "Unsupported lxc version $LXCVERSION!" >&2
cleanup_and_exit 1
;;
esac
if ! [ -r "$BUILD_ROOT/.build/_exitcode" -a ! -L "$BUILD_ROOT/.build/_exitcode" ]; then
echo "'$BUILD_ROOT/.build/_exitcode' not found or symlink"
return 3
fi
exitcode=$(cat $BUILD_ROOT/.build/_exitcode)
return "$exitcode"
}
vm_startup_lxc_libvirt() {
local lxc_arch
# x86 i686 x86_64 amd64
case $BUILD_ARCH in
i586:*) lxc_arch=i686 ;;
x86_64:*) lxc_arch=x86_64 ;;
*) lxc_arch=${BUILD_ARCH/:*} ;;
esac
lxcsh destroy "$LXCID" >/dev/null 2>&1 || true
cat <<-EOF > "$LXCCONF"
<domain type='lxc'>
<name>$LXCID</name>
<memory unit='MiB'>${VM_MEMSIZE:-512}</memory>
<os>
<type arch='$lxc_arch'>exe</type>
<init>$vm_init_script</init>
</os>
<vcpu>1</vcpu>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/lib64/libvirt/libvirt_lxc</emulator>
<filesystem type='mount'>
<source dir='$BUILD_ROOT'/>
<target dir='/'/>
</filesystem>
<!-- SLES11 and OpenSUSE 13.1 fails if cannot change /sys owner -->
<!-- BTW, ro mode can be overlapped with mount -o remount,rw -->
<filesystem type='mount'>
<source dir='/sys'/>
<target dir='/sys'/>
</filesystem>
<console type='pty'/>
</devices>
<features>
<privnet/>
<!-- SLES11 fails if cannot create nodes (mknode) -->
<capabilities policy='default'>
<mknod state='on'/>
</capabilities>
</features>
</domain>
EOF
# XXX: do this always instead of leaking the hosts' one?
buildroot_rm /etc/mtab
echo "rootfs / rootfs rw 0 0" > $BUILD_ROOT/etc/mtab
# could LOGFILE be used instead?
lxcsh create --console "$@" $LXCCONF | sed -ure 's/\x0d//g;:redo /.\x08/{s/.\x08//; b redo}'
exitcode="${PIPESTATUS[0]}"
if [ "$exitcode" -gt 0 ]; then
return $exitcode # libvirt errors
fi
if ! [ -r "$BUILD_ROOT/.build/_exitcode" -a ! -L "$BUILD_ROOT/.build/_exitcode" ]; then
echo "'$BUILD_ROOT/.build/_exitcode' not found or symlink"
return 3
fi
exitcode=$(cat $BUILD_ROOT/.build/_exitcode)
return "$exitcode"
}
vm_kill_lxc() {
lxc_get_id
vm_kill_lxc_$LXC_TYPE
}
vm_kill_lxc_standalone() {
lxc-stop -n "$LXCID" || true
}
vm_kill_lxc_libvirt() {
lxcsh destroy "$LXCID" || true
}
vm_fixup_lxc() {
:
}
vm_attach_root_lxc() {
:
}
vm_attach_swap_lxc() {
:
}
vm_detach_root_lxc() {
:
}
vm_detach_swap_lxc() {
:
}
vm_sysrq_lxc() {
:
}
vm_wipe_lxc() {
:
}
vm_cleanup_lxc() {
if test $$ -ne 1 && test $$ -ne 2 ; then
lxc_get_id
vm_cleanup_lxc_$LXC_TYPE
fi
}
vm_cleanup_lxc_standalone() {
lxc-destroy -n "$LXCID"
}
vm_cleanup_lxc_libvirt() {
lxcsh destroy "$LXCID" >/dev/null 2>&1 || true
}