]> git.proxmox.com Git - mirror_lxc.git/blame - templates/lxc-archlinux.in
doc: Update Japanese lxc.container.conf(5) for lxc.cap.keep = none
[mirror_lxc.git] / templates / lxc-archlinux.in
CommitLineData
f6267d90
AV
1#!/bin/bash
2
3#
4# template script for generating Arch linux container for LXC
5#
6
7#
8# lxc: linux Container library
9
10# Authors:
11# Alexander Vladimirov <idkfa@vlan1.ru>
d0800999 12# John Lane <lxc@jelmail.com>
f6267d90
AV
13
14# This library is free software; you can redistribute it and/or
15# modify it under the terms of the GNU Lesser General Public
16# License as published by the Free Software Foundation; either
17# version 2.1 of the License, or (at your option) any later version.
18
19# This library is distributed in the hope that it will be useful,
20# but WITHOUT ANY WARRANTY; without even the implied warranty of
21# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22# Lesser General Public License for more details.
23
24# You should have received a copy of the GNU Lesser General Public
25# License along with this library; if not, write to the Free Software
250b1eec 26# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
f6267d90 27
8ec981fc 28# Detect use under userns (unsupported)
c63c04fc 29for arg in "$@"; do
96283b54
SG
30 [ "$arg" = "--" ] && break
31 if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
8ec981fc
SG
32 echo "This template can't be used for unprivileged containers." 1>&2
33 echo "You may want to try the \"download\" template instead." 1>&2
34 exit 1
35 fi
36done
37
207bf0e4
SG
38# Make sure the usual locations are in PATH
39export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
40
f6267d90 41# defaults
f3849d01 42arch=$(uname -m)
f6267d90
AV
43lxc_network_type="veth"
44lxc_network_link="br0"
f3849d01
AV
45default_path="@LXCPATH@"
46default_locale="en-US.UTF-8"
47default_timezone="UTC"
14831534 48pacman_config="/etc/pacman.conf"
f6267d90 49
b7b7d388
LI
50# by default, install 'base' except the kernel
51pkg_blacklist="linux"
52base_packages=()
53for pkg in $(pacman -Sqg base); do
54 [ "${pkg_blacklist#*$pkg}" = "$pkg_blacklist" ] && base_packages+=($pkg)
55done
f6267d90
AV
56declare -a additional_packages
57
f6267d90
AV
58# split comma-separated string into an array
59# ${1} - string to split
60# ${2} - separator (default is ",")
61# ${result} - result value on success
17abf278 62split_string() {
f6267d90
AV
63 local ifs=${IFS}
64 IFS="${2:-,}"
65 read -a result < <(echo "${1}")
66 IFS=${ifs}
67 return 0
68}
69
f3849d01
AV
70[ -f /etc/arch-release ] && is_arch=true
71
f6267d90 72# Arch-specific preconfiguration for container
17abf278 73configure_arch() {
21ca73b9 74 # on ArchLinux, read defaults from host systemd configuration
f6267d90 75 if [ "${is_arch}" ]; then
21ca73b9
LI
76 cp -p /etc/vconsole.conf /etc/locale.conf /etc/locale.gen \
77 "${rootfs_path}/etc/"
f6267d90 78 else
f3849d01
AV
79 echo "LANG=${default_lang}" > "${rootfs_path}/etc/locale.conf"
80 echo "KEYMAP=us" > "${rootfs_path}/etc/vconsole.conf"
81 cat > "${rootfs_path}/etc/adjtime" << EOF
820.0 0.0 0.0
830
84LOCAL
f6267d90 85EOF
f3849d01
AV
86 if [ -e "${rootfs_path}/etc/locale.gen" ]; then
87 sed -i 's@^#\(en_US\.UTF-8\)@\1@' "${rootfs_path}/etc/locale.gen"
88 if [ ! "${default_locale}" = "en_US.UTF-8" ]; then
89 echo "${default_locale} ${default_locale##*.}" >> "${rootfs_path}/etc/locale.gen"
90 fi
f6267d90 91 fi
f6267d90 92 fi
21ca73b9
LI
93
94 # hostname and nameservers
f3849d01 95 echo "${name}" > "${rootfs_path}/etc/hostname"
21ca73b9
LI
96 while read r; do
97 [ "${r#nameserver}" = "$r" ] || echo "$r"
98 done < /etc/resolv.conf > "${rootfs_path}/etc/resolv.conf"
f6267d90 99
21ca73b9 100 # chroot and configure system
f3849d01
AV
101 arch-chroot "${rootfs_path}" /bin/bash -s << EOF
102mkdir /run/lock
103locale-gen
104ln -s /usr/share/zoneinfo/${default_timezone} /etc/localtime
105# disable services unavailable for container
21ca73b9
LI
106for i in systemd-udevd.service \
107 systemd-udevd-control.socket \
108 systemd-udevd-kernel.socket \
109 proc-sys-fs-binfmt_misc.automount; do
110 ln -s /dev/null /etc/systemd/system/\$i
111done
14831534 112# set default systemd target
f3849d01 113ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target
31efc34c
EK
114# enable sigpwr signal handling in systemd as otherwise lxc-stop won't work
115ln -s /usr/lib/systemd/system/poweroff.target /etc/systemd/system/sigpwr.target
44b03630
LI
116# initialize pacman keyring
117pacman-key --init
118pacman-key --populate archlinux
f3849d01 119EOF
f6267d90
AV
120 return 0
121}
122
123# write container configuration files
17abf278 124copy_configuration() {
f6267d90
AV
125 mkdir -p "${config_path}"
126 cat > "${config_path}/config" << EOF
f3849d01
AV
127lxc.utsname=${name}
128lxc.autodev=1
129lxc.tty=1
130lxc.pts=1024
f3849d01 131lxc.mount=${config_path}/fstab
d8c77af0 132lxc.cap.drop=sys_module mac_admin mac_override sys_time
6139e7e5
AV
133lxc.kmsg=0
134lxc.stopsignal=SIGRTMIN+4
f6267d90 135#networking
f3849d01
AV
136lxc.network.type=${lxc_network_type}
137lxc.network.link=${lxc_network_link}
138lxc.network.flags=up
139lxc.network.name=eth0
140lxc.network.mtu=1500
f6267d90
AV
141#cgroups
142lxc.cgroup.devices.deny = a
f3849d01
AV
143lxc.cgroup.devices.allow = c *:* m
144lxc.cgroup.devices.allow = b *:* m
f6267d90
AV
145lxc.cgroup.devices.allow = c 1:3 rwm
146lxc.cgroup.devices.allow = c 1:5 rwm
f3849d01 147lxc.cgroup.devices.allow = c 1:7 rwm
f6267d90 148lxc.cgroup.devices.allow = c 1:8 rwm
f3849d01 149lxc.cgroup.devices.allow = c 1:9 rwm
f3849d01
AV
150lxc.cgroup.devices.allow = c 4:1 rwm
151lxc.cgroup.devices.allow = c 5:0 rwm
152lxc.cgroup.devices.allow = c 5:1 rwm
f6267d90 153lxc.cgroup.devices.allow = c 5:2 rwm
f3849d01 154lxc.cgroup.devices.allow = c 136:* rwm
f6267d90
AV
155EOF
156
44464003 157 grep -q "^lxc.rootfs" ${config_path}/config 2>/dev/null || echo "lxc.rootfs = ${path}/rootfs" >> ${config_path}/config
1897e3bc 158
f6267d90 159 cat > "${config_path}/fstab" << EOF
b335cf8d 160sysfs sys sysfs defaults 0 0
f3849d01 161proc proc proc nodev,noexec,nosuid 0 0
f6267d90
AV
162EOF
163
f6267d90
AV
164 return 0
165}
166
f6267d90 167# install packages within container chroot
17abf278 168install_arch() {
734d0bed
JL
169 [ "${arch}" != "$(uname -m)" ] && different_arch=true
170
171 if [ "${different_arch}" = "true" ]; then
172 container_pacman_config=$(mktemp)
173 container_mirrorlist=$(mktemp)
174 sed -e "s:Architecture =.*:Architecture = ${arch}:g" \
175 -e "s:/etc/pacman.d/mirrorlist:${container_mirrorlist}:g" \
176 "${pacman_config}" > "${container_pacman_config}"
177 sed -e "s:\(x86_64\|\$arch\):${arch}:g" \
178 /etc/pacman.d/mirrorlist > "${container_mirrorlist}"
179
180 pacman_config="${container_pacman_config}"
181 fi
182
44b03630
LI
183 if ! pacstrap -dcGC "${pacman_config}" "${rootfs_path}" \
184 ${base_packages[@]}; then
f6267d90
AV
185 echo "Failed to install container packages"
186 return 1
187 fi
734d0bed
JL
188
189 if [ "${different_arch}" = "true" ]; then
190 sed -i -e "s:Architecture =.*:Architecture = ${arch}:g" \
191 "${rootfs_path}"/etc/pacman.conf
192 cp "${container_mirrorlist}" "${rootfs_path}"/etc/pacman.d/mirrorlist
193 rm "${container_pacman_config}" "${container_mirrorlist}"
194 fi
195
f6267d90 196 [ -d "${rootfs_path}/lib/modules" ] && ldconfig -r "${rootfs_path}"
f6267d90
AV
197 return 0
198}
199
f3849d01 200usage() {
f6267d90
AV
201 cat <<EOF
202usage:
203 ${1} -n|--name=<container_name>
f3849d01 204 [-P|--packages=<pkg1,pkg2,...>] [-p|--path=<path>] [-t|--network_type=<type>] [-l|--network_link=<link>] [-h|--help]
f6267d90
AV
205Mandatory args:
206 -n,--name container name, used to as an identifier for that container from now on
207Optional args:
f3849d01 208 -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
f6267d90 209 -P,--packages preinstall additional packages, comma-separated list
012f591a 210 -e,--enable_units Enable additional systemd units, comma-separated list
14831534 211 -c,--config use specified pacman config when installing container packages
b408e70d 212 -a,--arch use specified architecture instead of host's architecture
f3849d01
AV
213 -t,--network_type set container network interface type (${lxc_network_type})
214 -l,--network_link set network link device (${lxc_network_link})
d0800999 215 -r,--root_passwd set container root password
f6267d90
AV
216 -h,--help print this help
217EOF
218 return 0
219}
220
d0800999 221options=$(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: -- "${@}")
f6267d90
AV
222if [ ${?} -ne 0 ]; then
223 usage $(basename ${0})
224 exit 1
225fi
226eval set -- "${options}"
227
228while true
229do
230 case "${1}" in
f3849d01
AV
231 -h|--help) usage ${0} && exit 0;;
232 -p|--path) path=${2}; shift 2;;
233 -n|--name) name=${2}; shift 2;;
1897e3bc 234 --rootfs) rootfs_path=${2}; shift 2;;
f3849d01 235 -P|--packages) additional_packages=${2}; shift 2;;
012f591a 236 -e|--enable_units) enable_units=${2}; shift 2;;
14831534 237 -c|--config) pacman_config=${2}; shift 2;;
734d0bed 238 -a|--arch) arch=${2}; shift 2;;
f3849d01
AV
239 -t|--network_type) lxc_network_type=${2}; shift 2;;
240 -l|--network_link) lxc_network_link=${2}; shift 2;;
d0800999 241 -r|--root_passwd) root_passwd=${2}; shift 2;;
f6267d90
AV
242 --) shift 1; break ;;
243 *) break ;;
244 esac
245done
246
247if [ -z "${name}" ]; then
248 echo "missing required 'name' parameter"
249 exit 1
250fi
251
f3849d01 252if [ ! -e /sys/class/net/${lxc_network_link} ]; then
8dac6e74 253 echo "network link interface, ${lxc_network_link}, does not exist"
f3849d01
AV
254 exit 1
255fi
256
f6267d90
AV
257type pacman >/dev/null 2>&1
258if [ ${?} -ne 0 ]; then
259 echo "'pacman' command is missing, refer to wiki.archlinux.org for information about installing pacman"
260 exit 1
261fi
262
263if [ -z "${path}" ]; then
264 path="${default_path}/${name}"
265fi
266
267if [ "${EUID}" != "0" ]; then
268 echo "This script should be run as 'root'"
269 exit 1
270fi
271
1897e3bc
SH
272if [ -z "$rootfs_path" ]; then
273 rootfs_path="${path}/rootfs"
274fi
f6267d90
AV
275config_path="${default_path}/${name}"
276
f3849d01
AV
277revert() {
278 echo "Interrupted, cleaning up"
f6267d90 279 lxc-destroy -n "${name}"
f6267d90
AV
280 rm -rf "${path}/${name}"
281 rm -rf "${default_path}/${name}"
282 exit 1
283}
284
285trap revert SIGHUP SIGINT SIGTERM
286
287copy_configuration
288if [ ${?} -ne 0 ]; then
f3849d01 289 echo "failed to write configuration file"
f6267d90
AV
290 rm -rf "${config_path}"
291 exit 1
292fi
293
294if [ ${#additional_packages[@]} -gt 0 ]; then
295 split_string ${additional_packages}
296 base_packages+=(${result[@]})
297fi
298
f3849d01 299mkdir -p "${rootfs_path}"
f6267d90
AV
300install_arch
301if [ ${?} -ne 0 ]; then
f3849d01 302 echo "failed to install Arch Linux"
f6267d90
AV
303 rm -rf "${config_path}" "${path}"
304 exit 1
305fi
306
307configure_arch
308if [ ${?} -ne 0 ]; then
f3849d01 309 echo "failed to configure Arch Linux for a container"
f6267d90
AV
310 rm -rf "${config_path}" "${path}"
311 exit 1
312fi
313
012f591a
JL
314if [ ${#enable_units[@]} -gt 0 ]; then
315 split_string ${enable_units}
316 for unit in ${result[@]}; do
317 [ "${unit}" = *'.'* ] || unit="${unit}.service"
318 ln -s /usr/lib/systemd/system/"${unit}" \
319 "${rootfs_path}"/etc/systemd/system/multi-user.target.wants
320 done
321fi
322
d0800999
JL
323if [ -n "${root_passwd}" ]; then
324 echo "root:${root_passwd}" | chroot "${rootfs_path}" chpasswd
325fi
326
21ca73b9
LI
327cat << EOF
328ArchLinux container ${name} is successfully created! The configuration is
329stored in ${config_path}/config. Please refer to https://wiki.archlinux.org for
330information about configuring ArchLinux.
331EOF