[lxc-devel] [PATCH] Update Arch Linux template and add common configuration files

Alexander Vladimirov alexander.idkfa.vladimirov at gmail.com
Tue Jun 24 17:27:54 UTC 2014


Move common container configuration entries into template config.
Remove unnecessary service symlinking and configuration entries, as well as
guest configs and other redundant configuration, fix minor script bugs.
Clean up template command line, add -d option to allow disabling services.
Also enable getty's on all configured ttys to allow logins via lxc-console,
set lxc.tty value corresponding to default Arch /etc/securetty configuration.

This patch simplifies Arch Linux template a bit, while fixing some
longstanding issues. It also provides common configuration based on
files provided for Fedora templates.

Signed-off-by: Alexander Vladimirov <alexander.idkfa.vladimirov at gmail.com>
---
 config/templates/Makefile.am              |   2 +
 config/templates/archlinux.common.conf.in |  50 ++++++++++
 config/templates/archlinux.userns.conf.in |  20 ++++
 configure.ac                              |   2 +
 templates/lxc-archlinux.in                | 156 ++++++++++++------------------
 5 files changed, 138 insertions(+), 92 deletions(-)
 create mode 100644 config/templates/archlinux.common.conf.in
 create mode 100644 config/templates/archlinux.userns.conf.in
 mode change 100755 => 100644 templates/lxc-archlinux.in

diff --git a/config/templates/Makefile.am b/config/templates/Makefile.am
index 0b265df..3db2269 100644
--- a/config/templates/Makefile.am
+++ b/config/templates/Makefile.am
@@ -3,6 +3,8 @@ templatesconfigdir=@LXCTEMPLATECONFIG@
 EXTRA_DIST = ubuntu.priv.seccomp
 
 templatesconfig_DATA = \
+	archlinux.common.conf \
+	archlinux.userns.conf \
 	centos.common.conf \
 	centos.userns.conf \
 	debian.common.conf \
diff --git a/config/templates/archlinux.common.conf.in b/config/templates/archlinux.common.conf.in
new file mode 100644
index 0000000..2c49299
--- /dev/null
+++ b/config/templates/archlinux.common.conf.in
@@ -0,0 +1,50 @@
+# Based on fedora.common.conf.in
+# Console settings
+
+lxc.autodev = 1
+lxc.tty = 6
+lxc.pts = 1024
+lxc.kmsg = 0
+
+lxc.haltsignal=SIGRTMIN+4
+lxc.stopsignal=SIGRTMIN+14
+
+# Mount entries
+lxc.mount.auto = proc:mixed sys:ro
+
+# Capabilities
+# Uncomment these if you don't run anything that needs the capability, and
+# would like the container to run with less privilege.
+#
+# Dropping sys_admin disables container root from doing a lot of things
+# that could be bad like re-mounting lxc fstab entries rw for example,
+# but also disables some useful things like being able to nfs mount, and
+# things that are already namespaced with ns_capable() kernel checks, like
+# hostname(1).
+# lxc.cap.drop = sys_admin
+# lxc.cap.drop = net_raw          # breaks dhcp/ping
+# lxc.cap.drop = setgid           # breaks login (initgroups/setgroups)
+# lxc.cap.drop = dac_read_search  # breaks login (pam unix_chkpwd)
+# lxc.cap.drop = setuid           # breaks sshd,nfs statd
+# lxc.cap.drop = audit_control    # breaks sshd (set_loginuid failed)
+# lxc.cap.drop = audit_write
+# lxc.cap.drop = setpcap          # big big login delays in Fedora 20 systemd
+#
+lxc.cap.drop = mac_admin mac_override
+lxc.cap.drop = setfcap
+lxc.cap.drop = sys_module sys_nice sys_pacct
+lxc.cap.drop = sys_rawio sys_time
+
+# Control Group devices: all denied except those whitelisted
+lxc.cgroup.devices.deny = a
+# Allow any mknod (but not reading/writing the node)
+lxc.cgroup.devices.allow = c *:* m
+lxc.cgroup.devices.allow = b *:* m
+lxc.cgroup.devices.allow = c 1:3 rwm	# /dev/null
+lxc.cgroup.devices.allow = c 1:5 rwm	# /dev/zero
+lxc.cgroup.devices.allow = c 1:7 rwm	# /dev/full
+lxc.cgroup.devices.allow = c 5:0 rwm	# /dev/tty
+lxc.cgroup.devices.allow = c 1:8 rwm	# /dev/random
+lxc.cgroup.devices.allow = c 1:9 rwm	# /dev/urandom
+lxc.cgroup.devices.allow = c 136:* rwm	# /dev/tty[1-6] ptys and lxc console
+lxc.cgroup.devices.allow = c 5:2 rwm	# /dev/ptmx pty master
diff --git a/config/templates/archlinux.userns.conf.in b/config/templates/archlinux.userns.conf.in
new file mode 100644
index 0000000..28b03fa
--- /dev/null
+++ b/config/templates/archlinux.userns.conf.in
@@ -0,0 +1,20 @@
+# Based on fedora.userns.conf.in
+# CAP_SYS_ADMIN in init-user-ns is required for cgroup.devices
+lxc.cgroup.devices.deny =
+lxc.cgroup.devices.allow =
+
+# We can't move bind-mounts, so don't use /dev/lxc/
+lxc.devttydir =
+
+# Extra bind-mounts for userns
+lxc.mount.entry = /dev/console dev/console none bind,create=file 0 0
+lxc.mount.entry = /dev/full dev/full none bind,create=file 0 0
+lxc.mount.entry = /dev/null dev/null none bind,create=file 0 0
+lxc.mount.entry = /dev/random dev/random none bind,create=file 0 0
+lxc.mount.entry = /dev/tty dev/tty none bind,create=file 0 0
+lxc.mount.entry = /dev/urandom dev/urandom none bind,create=file 0 0
+lxc.mount.entry = /dev/zero dev/zero none bind,create=file 0 0
+
+# Extra fstab entries as mountall can't mount those by itself
+# lxc.mount.entry = /sys/firmware/efi/efivars sys/firmware/efi/efivars none bind,optional 0 0
+lxc.mount.entry = /proc/sys/fs/binfmt_misc proc/sys/fs/binfmt_misc none bind,optional 0 0
diff --git a/configure.ac b/configure.ac
index 6ee9aaa..1a27e1f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -594,6 +594,8 @@ AC_CONFIG_FILES([
 	config/init/upstart/Makefile
 	config/etc/Makefile
 	config/templates/Makefile
+	config/templates/archlinux.common.conf
+	config/templates/archlinux.userns.conf
 	config/templates/centos.common.conf
 	config/templates/centos.userns.conf
 	config/templates/debian.common.conf
diff --git a/templates/lxc-archlinux.in b/templates/lxc-archlinux.in
old mode 100755
new mode 100644
index ec14a9a..6f3ce2e
--- a/templates/lxc-archlinux.in
+++ b/templates/lxc-archlinux.in
@@ -1,14 +1,14 @@
 #!/bin/bash
 
 #
-# template script for generating Arch linux container for LXC
+# template script for generating Arch Linux container for LXC
 #
 
 #
 # lxc: linux Container library
 
 # Authors:
-# Alexander Vladimirov <idkfa at vlan1.ru>
+# Alexander Vladimirov <alexander.idkfa.vladimirov at gmail.com>
 # John Lane <lxc at jelmail.com>
 
 # This library is free software; you can redistribute it and/or
@@ -40,12 +40,11 @@ export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
 
 # defaults
 arch=$(uname -m)
-lxc_network_type="veth"
-lxc_network_link="br0"
 default_path="@LXCPATH@"
 default_locale="en-US.UTF-8"
 default_timezone="UTC"
 pacman_config="/etc/pacman.conf"
+shared_config="@LXCTEMPLATECONFIG@/archlinux.common.conf"
 
 # by default, install 'base' except the kernel
 pkg_blacklist="linux"
@@ -73,20 +72,14 @@ split_string() {
 configure_arch() {
     # on ArchLinux, read defaults from host systemd configuration
     if [ "${is_arch}" ]; then
-        cp -p /etc/vconsole.conf /etc/locale.conf /etc/locale.gen \
-		"${rootfs_path}/etc/"
+        cp -p /etc/locale.conf /etc/locale.gen "${rootfs_path}/etc/"
     else
         echo "LANG=${default_lang}" > "${rootfs_path}/etc/locale.conf"
-        echo "KEYMAP=us" > "${rootfs_path}/etc/vconsole.conf"
-        cat > "${rootfs_path}/etc/adjtime" << EOF
-0.0 0.0 0.0
-0
-LOCAL
-EOF
         if [ -e "${rootfs_path}/etc/locale.gen" ]; then
             sed -i 's@^#\(en_US\.UTF-8\)@\1@' "${rootfs_path}/etc/locale.gen"
             if [ ! "${default_locale}" = "en_US.UTF-8" ]; then
-                echo "${default_locale} ${default_locale##*.}" >> "${rootfs_path}/etc/locale.gen"
+                echo "${default_locale} ${default_locale##*.}" >> \
+                "${rootfs_path}/etc/locale.gen"
             fi
         fi
     fi
@@ -102,65 +95,41 @@ EOF
 mkdir /run/lock
 locale-gen
 ln -s /usr/share/zoneinfo/${default_timezone} /etc/localtime
-# disable services unavailable for container
-for i in systemd-udevd.service \
-	systemd-udevd-control.socket \
-	systemd-udevd-kernel.socket \
-	proc-sys-fs-binfmt_misc.automount; do
-   ln -s /dev/null /etc/systemd/system/\$i
-done
-# set default systemd target
+# set default boot target
 ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target
-# enable sigpwr signal handling in systemd as otherwise lxc-stop won't work
-ln -s /usr/lib/systemd/system/poweroff.target /etc/systemd/system/sigpwr.target
-# initialize pacman keyring
-pacman-key --init
-pacman-key --populate archlinux
+# override getty at .service for container ttys
+sed -e 's/^ConditionPathExists=/# ConditionPathExists=/' \
+    -e 's/After=dev-%i.device/After=/' \
+    < /lib/systemd/system/getty\@.service \
+    > /etc/systemd/system/getty\@.service
 EOF
+    # enable getty on active ttys
+    nttys=$(grep lxc.tty ${config_path}/config | cut -d= -f 2 | tr -d "[:blank:]")
+    if [ ${nttys:-0} -gt 1 ]; then
+      ( cd ${rootfs_path}/etc/systemd/system/getty.target.wants
+        for i in $(seq 1 $nttys); do ln -sf ../getty\@.service getty at tty${i}.service; done )
+    fi
+    [ ${nttys:-0} -gt 6 ] && echo \
+      "You may want to modify container's /etc/securetty \
+      file to allow root logins on tty7 and higher"
     return 0
 }
 
 # write container configuration files
 copy_configuration() {
     mkdir -p "${config_path}"
-    cat > "${config_path}/config" << EOF
-lxc.utsname=${name}
-lxc.autodev=1
-lxc.tty=1
-lxc.pts=1024
-lxc.mount=${config_path}/fstab
-lxc.cap.drop=sys_module mac_admin mac_override sys_time
-lxc.kmsg=0
-lxc.stopsignal=SIGRTMIN+4
-#networking
-lxc.network.type=${lxc_network_type}
-lxc.network.link=${lxc_network_link}
-lxc.network.flags=up
-lxc.network.name=eth0
-lxc.network.mtu=1500
-#cgroups
-lxc.cgroup.devices.deny = a
-lxc.cgroup.devices.allow = c *:* m
-lxc.cgroup.devices.allow = b *:* m
-lxc.cgroup.devices.allow = c 1:3 rwm
-lxc.cgroup.devices.allow = c 1:5 rwm
-lxc.cgroup.devices.allow = c 1:7 rwm
-lxc.cgroup.devices.allow = c 1:8 rwm
-lxc.cgroup.devices.allow = c 1:9 rwm
-lxc.cgroup.devices.allow = c 4:1 rwm
-lxc.cgroup.devices.allow = c 5:0 rwm
-lxc.cgroup.devices.allow = c 5:1 rwm
-lxc.cgroup.devices.allow = c 5:2 rwm
-lxc.cgroup.devices.allow = c 136:* rwm
-EOF
-
-    grep -q "^lxc.rootfs" ${config_path}/config 2>/dev/null || echo "lxc.rootfs = ${path}/rootfs" >> ${config_path}/config
-
-    cat > "${config_path}/fstab" << EOF
-sysfs sys sysfs defaults 0 0
-proc proc proc nodev,noexec,nosuid 0 0
-EOF
-
+    local config="${config_path}/config"
+    echo "lxc.utsname = ${name}" >> "${config}"
+    grep -q "^lxc.arch" "${config}" 2>/dev/null \
+        || echo "lxc.arch = ${arch}" >> "${config}"
+    grep -q "^lxc.rootfs" "${config}" 2>/dev/null \
+        || echo "lxc.rootfs = ${rootfs_path}" >> "${config}"
+    [ -e "${shared_config}" ] \
+        && echo "lxc.include = ${shared_config}" >> "${config}"
+    if [ $? -ne 0 ]; then
+        echo "Failed to configure container"
+        return 1
+    fi
     return 0
 }
 
@@ -181,7 +150,7 @@ install_arch() {
     fi
 
     if ! pacstrap -dcGC "${pacman_config}" "${rootfs_path}" \
-	    ${base_packages[@]}; then
+            ${base_packages[@]}; then
         echo "Failed to install container packages"
         return 1
     fi
@@ -200,25 +169,26 @@ install_arch() {
 usage() {
     cat <<EOF
 usage:
-    ${1} -n|--name=<container_name>
-        [-P|--packages=<pkg1,pkg2,...>] [-p|--path=<path>] [-t|--network_type=<type>] [-l|--network_link=<link>] [-h|--help]
+    ${1} -n|--name=<container_name> [-p|--path=<path>] [-a|--arch=<arch of the container>] [-r|--root_password=<root password>]
+        [-P|--packages=<pkg1,pkg2,...>] [-e|--enable_units=unit1,unit2...] [-c|--config=<pacman config path>] [-h|--help]
+
 Mandatory args:
-  -n,--name         container name, used to as an identifier for that container from now on
+  -n,--name           container name, used to as an identifier for that container from now on
 Optional args:
-  -p,--path         path to where the container rootfs will be created, defaults to ${default_path}/rootfs. The container config will go under ${default_path} in that case
-  -P,--packages     preinstall additional packages, comma-separated list
-  -e,--enable_units Enable additional systemd units, comma-separated list
-  -c,--config       use specified pacman config when installing container packages
-  -a,--arch         use specified architecture instead of host's architecture
-  -t,--network_type set container network interface type (${lxc_network_type})
-  -l,--network_link set network link device (${lxc_network_link})
-  -r,--root_passwd  set container root password
-  -h,--help         print this help
+  -p,--path           path to where the container rootfs will be created (${default_path})
+  --rootfs            path for actual container rootfs, (${default_path/rootfs)
+  -P,--packages       preinstall additional packages, comma-separated list
+  -e,--enable_units   enable systemd services, comma-separated list
+  -d,--disable_units  disable systemd services, comma-separated list
+  -c,--config         use specified pacman config when installing container packages
+  -a,--arch           use specified architecture instead of host's architecture
+  -r,--root_password  set container root password
+  -h,--help           print this help
 EOF
     return 0
 }
 
-options=$(getopt -o hp:P:e:n:c:a:l:t:r: -l help,rootfs:,path:,packages:,enable_units:,name:,config:,arch:,network_type:,network_link:,root_passwd: -- "${@}")
+options=$(getopt -o hp:P:e:d:n:c:a:r: -l help,rootfs:,path:,packages:,enable_units:,disable_units:,name:,config:,arch:,root_password: -- "${@}")
 if [ ${?} -ne 0 ]; then
     usage $(basename ${0})
     exit 1
@@ -234,11 +204,10 @@ do
     --rootfs)           rootfs_path=${2}; shift 2;;
     -P|--packages)      additional_packages=${2}; shift 2;;
     -e|--enable_units)  enable_units=${2}; shift 2;;
+    -d|--disable_units) disable_units=${2}; shift 2;;
     -c|--config)        pacman_config=${2}; shift 2;;
     -a|--arch)          arch=${2}; shift 2;;
-    -t|--network_type)  lxc_network_type=${2}; shift 2;;
-    -l|--network_link)  lxc_network_link=${2}; shift 2;;
-    -r|--root_passwd)   root_passwd=${2}; shift 2;;
+    -r|--root_password) root_passwd=${2}; shift 2;;
     --)             shift 1; break ;;
     *)              break ;;
     esac
@@ -249,11 +218,6 @@ if [ -z "${name}" ]; then
     exit 1
 fi
 
-if [ ! -e /sys/class/net/${lxc_network_link} ]; then
-    echo "network link interface, ${lxc_network_link}, does not exist"
-    exit 1
-fi
-
 type pacman >/dev/null 2>&1
 if [ ${?} -ne 0 ]; then
     echo "'pacman' command is missing, refer to wiki.archlinux.org for information about installing pacman"
@@ -272,7 +236,7 @@ fi
 if [ -z "$rootfs_path" ]; then
     rootfs_path="${path}/rootfs"
 fi
-config_path="${default_path}/${name}"
+config_path="${path}"
 
 revert() {
     echo "Interrupted, cleaning up"
@@ -314,9 +278,17 @@ fi
 if [ ${#enable_units[@]} -gt 0 ]; then
     split_string ${enable_units}
     for unit in ${result[@]}; do
-        [ "${unit}" = *'.'* ] || unit="${unit}.service"
-        ln -s /usr/lib/systemd/system/"${unit}" \
-            "${rootfs_path}"/etc/systemd/system/multi-user.target.wants
+        [ "${unit##*.}" = "service" ] || unit="${unit}.service"
+        ln -s "/usr/lib/systemd/system/${unit}" \
+            "${rootfs_path}/etc/systemd/system/multi-user.target.wants/"
+    done
+fi
+
+if [ ${#disable_units[@]} -gt 0 ]; then
+    split_string ${disable_units}
+    for unit in ${result[@]}; do
+        [ "${unit##*.}" = "service" ] || unit="${unit}.service"
+        ln -s /dev/null "${rootfs_path}/etc/systemd/system/${unit}"
     done
 fi
 
@@ -325,7 +297,7 @@ if [ -n "${root_passwd}" ]; then
 fi
 
 cat << EOF
-ArchLinux container ${name} is successfully created! The configuration is
+Arch Linux container ${name} is successfully created! The configuration is
 stored in ${config_path}/config. Please refer to https://wiki.archlinux.org for
-information about configuring ArchLinux.
+information about configuring Arch Linux.
 EOF
-- 
2.0.0



More information about the lxc-devel mailing list