lxc-gentoo.in revision 35e68b0447feb185db41395c70bdf16da6bbad94
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes# LXC template for gentoo
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes# Author: Guillaume Zitta <lxc@zitta.fr>
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes# Widely inspired from lxc-gentoo script at https://github.com/globalcitizen/lxc-gentoo
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes# this version is reworked with :
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes# - out of the lxc-create compat
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes# - vanilla gentoo config
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes# - ready to use cache
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes# Detect use under userns (unsupported)
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes echo "This template can't be used for unprivileged containers." 1>&2
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes echo "You may want to try the \"download\" template instead." 1>&2
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes# Make sure the usual locations are in PATH
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes# Ensure strict root's umask doesen't render the VM unusable
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes################################################################################
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes# Various helper functions
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes################################################################################
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes# param: $1: the name of the lock
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes# param: $2: the timeout for the lock
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes# The rest contain the command to execute and its parameters
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes printf "Attempting to obtain an exclusive lock (timeout: %s sec) named \"%s\"...\n" "${timeout}" "$lock_name"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes if [[ $? -ne 0 ]]; then
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes } 50> "@LOCALSTATEDIR@/lock/subsys/lxc-gentoo-${lock_name}"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes# a die function is always a good idea
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes printf "\n[the last exit code leading to this death was: %s ]\n" "$?"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes# gentoo arch/variant detection
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes printf "### set_default_arch: default arch/variant autodetect...\n"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes if [[ $arch =~ i.86 ]]; then
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes elif [[ $arch =~ arm.* ]]; then
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes printf " => warn: unexpected arch:${arch} let me knows if it works :)\n"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes printf " => Got: arch=%s variant=%s\n" "${arch}" "${variant}"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes################################################################################
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes# CACHE Preparation
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes################################################################################
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes# during setup cachedir is $cacheroot/partial-$arch-$variant
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes# at the end, it will be $cacheroot/rootfs-$arch-$variant
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes partialfs="${cacheroot}/partial-${arch}-${variant}"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes [[ -d "${cachefs}" && -z "${flush_cache}" ]] && return 0
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes printf "###### cache_setup(): doing cache preparation\n"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes printf "###### cache_setup: Cache should be ready\n"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes printf "### cache_precheck(): doing some pre-start checks ...\n"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes || die 8 "\$cacheroot (%s) IS EMPTY OR MADE OF ONLY DIRECTORY SEPARATORS, THIS IS *VERY* BAD!\n" "${cacheroot}"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes#get latest stage3 tarball
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes printf "### cache_stage3(): stage3 cache deployment...\n"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes local stage3_baseurl="${mirror}/releases/${arch}/autobuilds"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes local stage3_pointer="${stage3_baseurl}/latest-stage3-${variant}.txt"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes printf "Determining path to latest Gentoo %s (%s) stage3 archive...\n" "${arch}" "${variant}"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes printf " => downloading and processing %s\n" "${stage3_pointer}"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes local stage3_latest_tarball=$(wget -q -O - "${stage3_pointer}" | tail -n1 | cut -d' ' -f1) \
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes printf "Downloading/untarring the actual stage3 tarball...\n"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes wget -O - "${stage3_baseurl}/${stage3_latest_tarball}" \
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes tar -xpf "${tarball}" --numeric-owner -C "${partialfs}" \
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes || die 6 "unable to untar ${tarball} to ${partialfs}"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes chroot ${partialfs} /bin/true || die 1 "Error: chroot %s /bin/true, failed" "${partialfs}"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes printf " => stage3 cache extracted in : %s\n" "${partialfs}"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes printf "### cache_portage: caching portage tree tarball...\n"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes [[ -z "${flush_cache}" && -f "${portage_cache}" ]] && return 0
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes printf "Downloading Gentoo portage (software build database) snapshot...\n"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes execute_exclusively portage 60 wget -O "${portage_cache}" "${mirror}/snapshots/portage-latest.tar.bz2" \
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes# custom inittab
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes [[ -w "$INITTAB" ]] || die 1 "Error: $INITTAB is not writeable"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes echo "1:12345:respawn:/sbin/agetty -a root --noclear 115200 console linux" >> "$INITTAB"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes # finally we add a pf line to enable clean shutdown on SIGPWR (issue 60)
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes echo "# clean container shutdown on SIGPWR" >> "$INITTAB"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes echo "pf:12345:powerwait:/sbin/halt" >> "$INITTAB"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes # we also blank out /etc/issue here in order to prevent delays spawning login
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes # caused by attempts to determine domainname on disconnected containers
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes printf "### cache_net: doing some useful net tuning...\n"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes grep -i 'search ' /etc/resolv.conf > "${partialfs}/etc/resolv.conf"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes grep -i 'nameserver ' /etc/resolv.conf >> "${partialfs}/etc/resolv.conf"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes # fix boot-time interface config wipe under aggressive cap drop
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes # (openrc 0.9.8.4 ~sep 2012 - https://bugs.gentoo.org/show_bug.cgi?id=436266)
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes # initial warkaround was: sed -i -e 's/^#rc_nostop=""/rc_nostop="net.eth0 net.lo"/' "${partialfs}/etc/rc.conf"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes # but this one does not depends on interfaces names
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes echo 'rc_keyword="-stop"' >> "${partialfs}/etc/conf.d/net"
3c937b528ca923d5b51e63def9f888af4a77bb40bnicholes #Wait for https://bugs.gentoo.org/show_bug.cgi?id=496054
#If backingstore was specified, lxc.rootfs should be present or --rootfs did the rootfs var creation
container_precheck && \
container_rootfs && \
container_consoles && \
container_tz && \
container_portage && \
container_net && \
container_hostname && \
container_auth && \
container_sshd && \
if [ $? -ne 0 ]; then
|| die 8 "\$name (%s) IS EMPTY OR MADE OF ONLY DIRECTORY SEPARATORS, THIS IS *VERY* BAD!\n" "${name}"
|| die 8 "\$rootfs (%s) IS EMPTY OR MADE OF ONLY DIRECTORY SEPARATORS, THIS IS *VERY* BAD!\n" "${rootfs}"
|| die 8 "\$cachefs (%s) IS EMPTY OR MADE OF ONLY DIRECTORY SEPARATORS, THIS IS *VERY* BAD!\n" "${cachefs}"
if [[ ${tty} < 6 ]]; then
die 1 "specified portage_dir (%s) does not contains profiles, is it a portage tree ?\n" "${portage_dir}"
lxc.mount.entry=${portage_dir} ${portage_container/\//} none ro,bind 0 0
lxc.mount.entry=${portage_distfiles_dir} ${portage_container/\//}/distfiles none rw,bind 0 0
store_user_message "container has a shared portage from host's ${portage_dir} to ${portage_container/\//}"
# enable and *tune* this kind of entry to slot binaries, specialy if you use multiples archs and variants
printf "# untaring private portage to %s from %s ... \n" "${rootfs}/${portage_container}" "${portage_cache}"
local file=${1}
if [[ ${nic_count} == 0 ]]; then
If it is for Lxc, use it next time by adding this to your default.conf :
lxc.network.type = veth
lxc.network.link = ${bridge}
lxc.network.flags = up
lxc.network.hwaddr = fe:xx:xx:xx:xx:xx"
for nic in ${nic_managed}
let sys_nic_index=sys_nic_index+1
and man lxc.conf"
chroot "${rootfs}" useradd --create-home -s /bin/bash "${user}" || die 1 "failed to create user ${user}"
grep -q "^lxc.network.hwaddr" ${conf_file} || sed -i -e "/^lxc\.network\.type[ \t]*=[ \t]*veth/a lxc.network.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')" ${conf_file}
cat <<EOF
$1 -h|--help [-a|--arch <arch>] [-v|--variant <variant>] [-P|--private-portage] [--portage-dir <protagedir>] [-t|--tarball <stage3file>]
[-F|--flush-cache] [-c|--cache-only] [-u|--user <username>] [-w|--password <password>] [--autologin] [-S|--auth-key <keyfile>]
private-portage: by default, /usr/portage is mount-binded with host one if exists (currently: '${private_portage}')
options=$(getopt -o hp:n:a:FcPv:t:S:u:w:s:m: -l help,rootfs:,path:,name:,arch:,flush-cache,cache-only,private-portage,variant:,portage-dir:,tarball:,auth_key:,user:,autologin,password:,settings:,mirror:,tty: -- "$@")
eval set -- "$options"