# - ready to use cache
#
+# Detect use under userns (unsupported)
+for arg in "$@"; do
+ [ "$arg" = "--" ] && break
+ if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
+ echo "This template can't be used for unprivileged containers." 1>&2
+ echo "You may want to try the \"download\" template instead." 1>&2
+ exit 1
+ fi
+done
+
+# Make sure the usual locations are in PATH
+export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
+
# Ensure strict root's umask doesen't render the VM unusable
umask 022
set_default_arch()
{
printf "### set_default_arch: default arch/variant autodetect...\n"
- arch=$(arch)
+ arch=$(uname -m)
if [[ $arch =~ i.86 ]]; then
arch="x86"
variant="x86"
cache_net && \
cache_dev && \
cache_openrc && \
+ cache_locale && \
rm -rf "${cachefs}" && \
mv "${partialfs}" "${cachefs}" && \
printf "###### cache_setup: Cache should be ready\n"
printf "### cache_precheck(): doing some pre-start checks ...\n"
# never hurts to have a fail-safe.
[[ -n "${cacheroot//\/}" ]] \
- || die 8 "\$cacheroot (%s) IS EMPTY OR MADE OF ONLY DIRECTORY SEPERATORS, THIS IS *VERY* BAD!\n" "${cacheroot}"
+ || die 8 "\$cacheroot (%s) IS EMPTY OR MADE OF ONLY DIRECTORY SEPARATORS, THIS IS *VERY* BAD!\n" "${cacheroot}"
}
#get latest stage3 tarball
printf "Determining path to latest Gentoo %s (%s) stage3 archive...\n" "${arch}" "${variant}"
printf " => downloading and processing %s\n" "${stage3_pointer}"
- local stage3_latest_tarball=$(wget -q -O - "${stage3_pointer}" | tail -n1 ) \
+ local stage3_latest_tarball=$(wget -q -O - "${stage3_pointer}" | tail -n1 | cut -d' ' -f1) \
|| die 6 "Error: unable to fetch\n"
printf " => Got: %s\n" "${stage3_latest_tarball}"
printf "Downloading/untarring the actual stage3 tarball...\n"
- wget -O - "${stage3_baseurl}/${stage3_latest_tarball}" | tar -xjpf - -C "${partialfs}" \
+ wget -O - "${stage3_baseurl}/${stage3_latest_tarball}" \
+ | tar -xjpf - --numeric-owner -C "${partialfs}" \
|| die 6 "Error: unable to fetch or untar\n"
printf " => extracted to: %s\n" "${partialfs}"
else
printf "Extracting the stage3 tarball...\n"
- tar -xpf "${tarball}" -C "${partialfs}" || die 6 "unable to untar ${tarball} to ${partialfs}"
+ tar -xpf "${tarball}" --numeric-owner -C "${partialfs}" \
+ || die 6 "unable to untar ${tarball} to ${partialfs}"
fi
#check if it chroots
mkdir "${partialfs}/dev/shm"
mkdir "${partialfs}/dev/mqueue"
- mkdir -m 755 "${partialfs}/net"
- mknod -m 666 "${partialfs}/net/tun" c 10 200
+ mkdir -m 755 "${partialfs}/dev/net"
+ mknod -m 666 "${partialfs}/dev/net/tun" c 10 200
return 0
}
return 0
}
+cache_locale()
+{
+ printf "### cache_locale(): initiating minimale locale en_US.UTF-8 \n"
+
+ echo "en_US.UTF-8 UTF-8" >> "${partialfs}/etc/locale.gen"
+ chroot "${partialfs}" locale-gen
+
+ return 0
+}
+
################################################################################
# CONTAINER Preparation
################################################################################
echo '### lxc-gentoo template stuff starts here' >> "$path/config"
#Determine rootfs
- #If backingstore was specified, lxc.rootfs should be present or --rootfs did the rootfs var creation
+ #If backingstore was specified, lxc.rootfs.path should be present or --rootfs did the rootfs var creation
if [ -z "${rootfs}" ]; then
- rootfs=`awk -F= '$1 ~ /^lxc.rootfs/ { print $2 }' "$path/config" 2>/dev/null`
+ rootfs=`awk -F= '$1 ~ /^lxc.rootfs.path/ { print $2 }' "$path/config" 2>/dev/null`
if [ -z "${rootfs}" ]; then
#OK it's default
rootfs="${path}/rootfs"
container_net && \
container_hostname && \
container_auth && \
+ container_sshd && \
container_conf
if [ $? -ne 0 ]; then
die 1 "container_setup(): one step didn't complete, sorry\n"
printf "### container_precheck(): doing some pre-start checks ...\n"
# never hurts to have a fail-safe.
[[ -n "${name//\/}" ]] \
- || die 8 "\$name (%s) IS EMPTY OR MADE OF ONLY DIRECTORY SEPERATORS, THIS IS *VERY* BAD!\n" "${name}"
+ || die 8 "\$name (%s) IS EMPTY OR MADE OF ONLY DIRECTORY SEPARATORS, THIS IS *VERY* BAD!\n" "${name}"
[[ -n "${rootfs//\/}" ]] \
- || die 8 "\$rootfs (%s) IS EMPTY OR MADE OF ONLY DIRECTORY SEPERATORS, THIS IS *VERY* BAD!\n" "${rootfs}"
+ || die 8 "\$rootfs (%s) IS EMPTY OR MADE OF ONLY DIRECTORY SEPARATORS, THIS IS *VERY* BAD!\n" "${rootfs}"
[[ -n "${cachefs//\/}" ]] \
- || die 8 "\$cachefs (%s) IS EMPTY OR MADE OF ONLY DIRECTORY SEPERATORS, THIS IS *VERY* BAD!\n" "${cachefs}"
+ || die 8 "\$cachefs (%s) IS EMPTY OR MADE OF ONLY DIRECTORY SEPARATORS, THIS IS *VERY* BAD!\n" "${cachefs}"
# check if the rootfs already exists
[[ -d "${rootfs}/etc" ]] && die 18 "Error: \$rootfs (%s) already exists!" "${rootfs}"
container_rootfs()
{
printf "#### container_rootfs(): copying rootfs %s from cache %s ...\n" "${rootfs}" "${cachefs}"
- tar -c -f - -C "${cachefs}" . | tar -x -p -f - -C "${rootfs}" || die 1 "Error: cache copy to rootfs failed"
+ tar -c -f - --numeric-owner -C "${cachefs}" . \
+ | tar -x -p -f - --numeric-owner -C "${rootfs}" \
+ || die 1 "Error: cache copy to rootfs failed"
printf "chroot test..."
chroot "${rootfs}" /bin/true || die 1 "Error: 'chroot %s /bin/true' failed"
fi
fi
+ printf "trying to guess portage distfiles dir from host ...\n"
+ portage_distfiles_dir="$(portageq distdir 2>/dev/null)"
+ if [ ! -d "${portage_distfiles_dir}" ]; then
+ portage_distfiles_dir="${portage_dir}/distfiles"
+ fi
+
# if we are here, we have shared portage_dir
#ensure dir exists
chroot "${rootfs}" mkdir ${portage_container}
portage_mount="#container set with shared portage
- lxc.mount.entry=${portage_dir} ${portage_container/\//} none ro,bind 0 0"
+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
+#If you use eix, you should uncomment this
+#lxc.mount.entry=/var/cache/eix var/cache/eix none ro,bind 0 0"
store_user_message "container has a shared portage from host's ${portage_dir} to ${portage_container/\//}"
#Let's propose binary packages
cat <<- EOF >> "${rootfs}/etc/portage/make.conf"
- # enable this to store built binary packages
- #FEATURES="\$FEATURES buildpkg"
+# enable this to store built binary packages
+#FEATURES="\$FEATURES buildpkg"
- # enable this to use built binary packages
- #EMERGE_DEFAULT_OPTS="\${EMERGE_DEFAULT_OPTS} --usepkg"
+# enable this to use built binary packages
+#EMERGE_DEFAULT_OPTS="\${EMERGE_DEFAULT_OPTS} --usepkg"
- # enable and *tune* this kind of entry to slot binaries, specialy if you use multiples archs and variants
- #PKGDIR="\${PKGDIR}/amd64
- #or PKGDIR="\${PKGDIR}/hardened"
+# enable and *tune* this kind of entry to slot binaries, specialy if you use multiples archs and variants
+#PKGDIR="\${PKGDIR}/amd64
+#or PKGDIR="\${PKGDIR}/hardened"
EOF
- printf " => portage stuff done, see /etc/portage/make.conf for additionnal tricks\n"
+ printf " => portage stuff done, see /etc/portage/make.conf for additional tricks\n"
}
#called from container_portage() do not call directly from container_setup
printf "# untaring private portage to %s from %s ... \n" "${rootfs}/${portage_container}" "${portage_cache}"
mkdir -p "${rootfs}/${portage_container}"
- execute_exclusively portage 60 tar -xp --strip-components 1 -C "${rootfs}/${portage_container}" -f "${portage_cache}" \
+ execute_exclusively portage 60 \
+ tar -xp --strip-components 1 -C "${rootfs}/${portage_container}" \
+ -f "${portage_cache}" --numeric-owner \
|| die 2 "Error: unable to extract the portage tree.\n"
store_user_message "container has its own portage tree at ${portage_container}"
printf "=> done\n"
value=$(echo "${line}" | sed 's/^.*_real_ugly_sep_42_//')
#new nic !
- if [[ "${key}" == "lxc.network.type" ]]; then
+ if [[ "${key}" == "lxc.net.0.type" ]]; then
#we don't know what to do with it.
[[ "${value}" == "empty" ]] && continue
nic_type="${value}"
fi
- if [[ "${key}" == "lxc.network.hwaddr" ]]; then
+ if [[ "${key}" == "lxc.net.0.hwaddr" ]]; then
nic_hwaddr=1
fi
- if [[ "${key}" =~ ^lxc.network.ipv(4|6) ]]; then
+ if [[ "${key}" =~ ^lxc.net.0.ipv(4|6) ]]; then
#tell openrc to not manage this NIC as LXC set there address
nic_conf="null"
fi
- if [[ "${key}" =~ ^lxc.network.name ]]; then
+ if [[ "${key}" =~ ^lxc.net.0.name ]]; then
nic_name="${value}"
let nic_named=nic_named+1
fi
#Analyse network configuration in config
container_conf_net "$path/config" >> "${rootfs}/etc/conf.d/net"
- # found how much nic finaly have
+ # found how much nic finally have
nic_count=$(( ${nic_last} + 1 ))
# unless openrc manage a nic, we now have to force openrc to automatic
store_user_message "No network interface for this container
It's a pitty, you have bridge, ${bridge}.
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"
+lxc.net.0.type = veth
+lxc.net.0.link = ${bridge}
+lxc.net.0.flags = up
+lxc.net.0.hwaddr = fe:xx:xx:xx:xx:xx"
return 0
else
store_user_message "No network interface for this container"
container_hostname()
{
printf "#### container_hostname(): setting hostname... \n"
- printf "hostnale=%s\n" "${name}" > "${rootfs}/etc/conf.d/hostname"
+ printf "hostname=\"%s\"\n" "${name}" > "${rootfs}/etc/conf.d/hostname"
printf " => done.\n"
}
if [[ -r "${auth_key}" ]]; then
printf " deploying auth_key %s for user %s ...\n" "${auth_key}" "${user}"
mkdir -p "${rootfs}/${auth_home}/.ssh"
- cat >> "${rootfs}/${auth_home}/.ssh/authorized_keys"
+ cat "${auth_key}" >> "${rootfs}/${auth_home}/.ssh/authorized_keys"
chroot "${rootfs}" chown "${user}:" "${auth_home}/.ssh/authorized_keys"
printf " => inserted public key in %s/.ssh/authorized_keys\n" "${auth_home}"
[[ -z "${forced_password}" ]] && unset password
- store_user_message "${user} has the ssh key you gived us"
+ store_user_message "${user} has the ssh key you gave us"
fi
if [[ -n "${password}" ]]; then
printf " => done. if you didn't specify , default is 'toor'\n"
if [[ -n "${forced_password}" ]]; then
store_user_message "${user} has the password you give for him"
- else
- store_user_message "${user} has the default password 'toor', please change it ASAP"
fi
fi
printf " => done.\n"
}
+container_sshd() {
+ printf "#### container_sshd(): enabling sshd... \n"
+
+ chroot "${rootfs}" rc-update add sshd || die 1 "failed to enable sshd\n"
+
+ printf " => done.\n"
+}
+
################################################################################
# lxc configuration files
################################################################################
#at this point if there
conf_file="${path}/config"
- if grep -q "^lxc.rootfs" "${conf_file}" ; then
+ # if there is exactly one veth network entry, make sure it has an
+ # associated hwaddr.
+ nics=`grep -e '^lxc\.net\.0\.type[ \t]*=[ \t]*veth' ${conf_file} | wc -l`
+ if [ $nics -eq 1 ]; then
+ grep -q "^lxc.net.0.hwaddr" ${conf_file} || sed -i -e "/^lxc\.net\.0\.type[ \t]*=[ \t]*veth/a lxc.net.0.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')" ${conf_file}
+ fi
+
+ if grep -q "^lxc.rootfs.path" "${conf_file}" ; then
#lxc-create already provided one
conf_rootfs_line=""
else
- conf_rootfs_line="lxc.rootfs = $(readlink -f "${rootfs}")"
+ conf_rootfs_line="lxc.rootfs.path = $(readlink -f "${rootfs}")"
fi
if [[ "${arch}" == "x86" || "${arch}" == "amd64" ]]; then
local conf_arch_line="lxc.arch = ${arch}"
${conf_arch_line}
# set the hostname
-lxc.utsname = ${name}
+lxc.uts.name = ${name}
lxc.tty = ${tty}
${conf_rootfs_line}
mirror="http://distfiles.gentoo.org"
user="root"
-password="toor"
-tty=0
+tty=1
settings="common"
-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: -- "$@")
+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"
-n|--name) name=$2; shift 2;;
-a|--arch) arch=$2; shift 2;;
-F|--flush-cache) flush_cache=1; shift 1;;
- -c|--cache-only) cache_only=1; shitf 1;;
+ -c|--cache-only) cache_only=1; shift 1;;
-P|--private-portage) private_portage=1; shift 1;;
-v|--variant) variant=$2; shift 2;;
--portage-dir) portage_dir=$2; shift 2;;
-w|--password) forced_password=1; password=$2; shift 2;;
-s|--settings) settings=$2; shift 2;;
-m|--mirror) mirror=$2; shift 2;;
+ --container-cache) containercache=$2; shift 2;;
--tty) [[ $2 -lt 6 ]] && tty=$2; shift 2;;
--autologin) autologin=1; shift 1;;
--) shift 1; break ;;
esac
done
-cacheroot="@LOCALSTATEDIR@/cache/lxc/gentoo"
+# Allow the cache path to be set by environment variable
+cacheroot="${LXC_CACHE_PATH:-"@LOCALSTATEDIR@/cache/lxc"}/gentoo"
portage_cache="${cacheroot}/portage.tbz"
cachefs="${cacheroot}/rootfs-${arch}-${variant}"