mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-07-27 12:37:35 +00:00
lxc-debian: allow to specify a binfmt interpreter
If you specify an interpreter path with "-I" or "--interpreter-path", the architecture of the debian container can differ from the one of the host. Before creating the container, binfmt must be configured on the host: the script checks the name of the interpreter in /proc/sys/fs/binfmt_misc/ to know where to install it in the container. To create a MIPS container on an x86_64 host: $ cat /proc/sys/fs/binfmt_misc/qemu-mips enabled interpreter //qemu-mips flags: OC offset 0 magic 7f454c4601020100000000000000000000020008 mask ffffffffffffff00fffffffffffffffffffeffff $ sudo lxc-create -n virtmips-stretch -t debian -- \ --arch=mips \ --interpreter-path=./mips-linux-user/qemu-mips \ --mirror=http://ftp.debian.org/debian \ --release=stretch Signed-off-by: Laurent Vivier <laurent@vivier.eu>
This commit is contained in:
parent
56c80e0d4d
commit
d50cebd697
@ -41,6 +41,29 @@ LXC_TEMPLATE_CONFIG="@LXCTEMPLATECONFIG@"
|
||||
# Allows the lxc-cache directory to be set by environment variable
|
||||
LXC_CACHE_PATH=${LXC_CACHE_PATH:-"$LOCALSTATEDIR/cache/lxc"}
|
||||
|
||||
find_interpreter()
|
||||
{
|
||||
given_interpreter=$(basename "$1")
|
||||
|
||||
if [ ! -d /proc/sys/fs/binfmt_misc/ ] ; then
|
||||
return 1
|
||||
fi
|
||||
for file in /proc/sys/fs/binfmt_misc/* ; do
|
||||
if [ "$file" = "/proc/sys/fs/binfmt_misc/register" -o \
|
||||
"$file" = "/proc/sys/fs/binfmt_misc/status" ] ; then
|
||||
continue
|
||||
fi
|
||||
interpreter_path=$(sed -n "/^interpreter/s/interpreter \([^[:space:]]*\)/\1/p" "$file")
|
||||
interpreter=$(basename $interpreter_path)
|
||||
|
||||
if [ "$given_interpreter" = "$interpreter" ] ; then
|
||||
echo "$interpreter_path"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
configure_debian()
|
||||
{
|
||||
rootfs=$1
|
||||
@ -252,6 +275,8 @@ openssh-server
|
||||
cache=$1
|
||||
arch=$2
|
||||
release=$3
|
||||
interpreter="$4"
|
||||
interpreter_path="$5"
|
||||
|
||||
trap cleanup EXIT SIGHUP SIGINT SIGTERM
|
||||
|
||||
@ -285,6 +310,7 @@ openssh-server
|
||||
|
||||
# download a mini debian into a cache
|
||||
echo "Downloading debian minimal ..."
|
||||
if [ "$interpreter" = "" ] ; then
|
||||
debootstrap --verbose --variant=minbase --arch=$arch \
|
||||
--include=$packages --keyring=${releasekeyring} \
|
||||
"$release" "$cache/partial-$release-$arch" $MIRROR
|
||||
@ -292,6 +318,26 @@ openssh-server
|
||||
echo "Failed to download the rootfs, aborting."
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
debootstrap --foreign --verbose --variant=minbase --arch=$arch \
|
||||
--include=$packages --keyring=${releasekeyring} \
|
||||
"$release" "$cache/partial-$release-$arch" $MIRROR
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to download the rootfs, aborting."
|
||||
return 1
|
||||
fi
|
||||
mkdir -p $(basename "$cache/partial-$release-$arch/$interpreter_path")
|
||||
cp "$interpreter" "$cache/partial-$release-$arch/$interpreter_path"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "failed to copy $interpreter to $cache/partial-$release-$arch/$interpreter_path"
|
||||
return 1
|
||||
fi
|
||||
chroot "$cache/partial-$release-$arch" debootstrap/debootstrap --second-stage
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "failed to update the rootfs, aborting"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
mv "$1/partial-$release-$arch" "$1/rootfs-$release-$arch"
|
||||
echo "Download complete."
|
||||
@ -323,6 +369,8 @@ install_debian()
|
||||
release=$2
|
||||
arch=$3
|
||||
cache="$4/debian"
|
||||
interpreter="$5"
|
||||
interpreter_path="$6"
|
||||
mkdir -p $LOCALSTATEDIR/lock/subsys/
|
||||
(
|
||||
flock -x 9
|
||||
@ -333,7 +381,7 @@ install_debian()
|
||||
|
||||
echo "Checking cache download in $cache/rootfs-$release-$arch ... "
|
||||
if [ ! -e "$cache/rootfs-$release-$arch" ]; then
|
||||
download_debian $cache $arch $release
|
||||
download_debian $cache $arch $release "$interpreter" "$interpreter_path"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to download 'debian base'"
|
||||
return 1
|
||||
@ -388,6 +436,7 @@ copy_configuration()
|
||||
lxc.tty = $num_tty
|
||||
lxc.utsname = $hostname
|
||||
lxc.arch = $arch
|
||||
lxc.pts=1023
|
||||
EOF
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
@ -404,6 +453,7 @@ post_process()
|
||||
local release="$1"; shift
|
||||
local arch="$1"; shift
|
||||
local hostarch="$1"; shift
|
||||
local interpreter="$1"; shift
|
||||
local packages="$*"
|
||||
|
||||
# Disable service startup
|
||||
@ -414,7 +464,7 @@ EOF
|
||||
chmod +x ${rootfs}/usr/sbin/policy-rc.d
|
||||
|
||||
# If the container isn't running a native architecture, setup multiarch
|
||||
if [ "${arch}" != "${hostarch}" ]; then
|
||||
if [ "$interpreter" = "" -a "${arch}" != "${hostarch}" ]; then
|
||||
# Test if dpkg supports multiarch
|
||||
if ! chroot $rootfs dpkg --print-foreign-architecture 2>&1; then
|
||||
chroot $rootfs dpkg --add-architecture ${hostarch}
|
||||
@ -423,7 +473,7 @@ EOF
|
||||
|
||||
# Write a new sources.list containing both native and multiarch entries
|
||||
> ${rootfs}/etc/apt/sources.list
|
||||
if [ "${arch}" = "${hostarch}" ]; then
|
||||
if [ "$interpreter" != "" -a "${arch}" = "${hostarch}" ]; then
|
||||
write_sourceslist ${rootfs} ${release} ${arch}
|
||||
else
|
||||
write_sourceslist ${rootfs} ${release}
|
||||
@ -492,6 +542,7 @@ Template specific options can be passed to lxc-create after a '--' like this:
|
||||
Usage: $1 -h|--help -p|--path=<path> [-c|--clean] [-a|--arch=<arch>] [-r|--release=<release>]
|
||||
[--mirror=<mirror>] [--security-mirror=<security mirror>]
|
||||
[--package=<package_name1,package_name2,...>]
|
||||
[-I|--interpreter-path=<interpreter path>]
|
||||
|
||||
Options :
|
||||
|
||||
@ -510,6 +561,8 @@ Options :
|
||||
List of additional packages to install. Comma separated, without space.
|
||||
-c, --clean only clean up the cache and terminate
|
||||
--enable-non-free include also Debian's contrib and non-free repositories.
|
||||
-I|--interpreter-path=INTERPRETER-PATH
|
||||
Path of the binfmt interpreter to copy to the rootfs
|
||||
|
||||
Environment variables:
|
||||
|
||||
@ -522,7 +575,7 @@ EOF
|
||||
return 0
|
||||
}
|
||||
|
||||
options=$(getopt -o hp:n:a:r:c -l arch:,clean,help,enable-non-free,mirror:,name:,packages:,path:,release:,rootfs:,security-mirror: -- "$@")
|
||||
options=$(getopt -o hp:n:a:r:cI: -l arch:,clean,help,enable-non-free,mirror:,name:,packages:,path:,release:,rootfs:,security-mirror:,interpreter-path: -- "$@")
|
||||
if [ $? -ne 0 ]; then
|
||||
usage $(basename $0)
|
||||
exit 1
|
||||
@ -547,6 +600,8 @@ do
|
||||
--) shift 1; break ;;
|
||||
|
||||
-a|--arch) arch=$2; shift 2;;
|
||||
-I|--interpreter-path)
|
||||
interpreter="$2"; shift 2;;
|
||||
-c|--clean) clean=1; shift 1;;
|
||||
--enable-non-free) mainonly=0; shift 1;;
|
||||
--mirror) MIRROR=$2; shift 2;;
|
||||
@ -573,6 +628,7 @@ if [ "$arch" = "x86_64" ]; then
|
||||
arch=amd64
|
||||
fi
|
||||
|
||||
if [ "$interpreter" = "" ] ; then
|
||||
if [ $hostarch = "i386" -a $arch = "amd64" ]; then
|
||||
echo "can't create $arch container on $hostarch"
|
||||
exit 1
|
||||
@ -588,6 +644,17 @@ if [ $hostarch = "powerpc" -a $arch != "powerpc" ]; then
|
||||
echo "can't create $arch container on $hostarch"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
if ! file -b "${interpreter}" |grep -q "statically linked" ; then
|
||||
echo "'${interpreter}' must be statically linked" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
interpreter_path=$(find_interpreter "$interpreter")
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "no binfmt interpreter using $(basename $interpreter)" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
type debootstrap
|
||||
if [ $? -ne 0 ]; then
|
||||
@ -630,7 +697,7 @@ else
|
||||
num_tty=4
|
||||
fi
|
||||
|
||||
install_debian $rootfs $release $arch $LXC_CACHE_PATH
|
||||
install_debian $rootfs $release $arch $LXC_CACHE_PATH "$interpreter" "$interpreter_path"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "failed to install debian"
|
||||
exit 1
|
||||
@ -650,7 +717,7 @@ fi
|
||||
|
||||
configure_debian_systemd $path $rootfs $config $num_tty
|
||||
|
||||
post_process ${rootfs} ${release} ${arch} ${hostarch} ${packages}
|
||||
post_process ${rootfs} ${release} ${arch} ${hostarch} "${interpreter}" ${packages}
|
||||
|
||||
if [ ! -z "$clean" ]; then
|
||||
clean || exit 1
|
||||
|
Loading…
Reference in New Issue
Block a user