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

Stéphane Graber stgraber at ubuntu.com
Tue Jun 24 19:48:06 UTC 2014


On Wed, Jun 25, 2014 at 01:27:54AM +0800, Alexander Vladimirov wrote:
> 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>

Acked-by: Stéphane Graber <stgraber at ubuntu.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
> 
> _______________________________________________
> lxc-devel mailing list
> lxc-devel at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/lxc-devel

-- 
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20140624/04b3f490/attachment.sig>


More information about the lxc-devel mailing list