]> git.proxmox.com Git - mirror_lxc.git/blame - templates/lxc-archlinux.in
lxc-ubuntu-cloud: Fix cache and lock location
[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
AV
27
28# defaults
f3849d01 29arch=$(uname -m)
f6267d90
AV
30lxc_network_type="veth"
31lxc_network_link="br0"
f3849d01
AV
32default_path="@LXCPATH@"
33default_locale="en-US.UTF-8"
34default_timezone="UTC"
14831534 35pacman_config="/etc/pacman.conf"
f6267d90
AV
36
37# sort of minimal package set
38base_packages=(
f3849d01
AV
39 "systemd"
40 "systemd-sysvcompat"
f6267d90 41 "filesystem"
f6267d90 42 "coreutils"
4852d800 43 "kmod"
f6267d90
AV
44 "procps"
45 "psmisc"
46 "pacman"
47 "bash"
f6267d90
AV
48 "cronie"
49 "iproute2"
50 "iputils"
51 "inetutils"
52 "dhcpcd"
53 "dnsutils"
54 "nano"
55 "grep"
56 "less"
57 "gawk"
58 "sed"
59 "tar"
f6267d90
AV
60 "gzip"
61 "which"
62)
63declare -a additional_packages
64
f6267d90
AV
65# split comma-separated string into an array
66# ${1} - string to split
67# ${2} - separator (default is ",")
68# ${result} - result value on success
17abf278 69split_string() {
f6267d90
AV
70 local ifs=${IFS}
71 IFS="${2:-,}"
72 read -a result < <(echo "${1}")
73 IFS=${ifs}
74 return 0
75}
76
f3849d01
AV
77[ -f /etc/arch-release ] && is_arch=true
78
f6267d90 79# Arch-specific preconfiguration for container
17abf278 80configure_arch() {
f6267d90
AV
81 # read locale and timezone defaults from system rc.conf if running on Arch
82 if [ "${is_arch}" ]; then
f3849d01 83 cp -p /etc/vconsole.conf /etc/locale.conf /etc/locale.gen "${rootfs_path}/etc/"
f6267d90 84 else
f3849d01
AV
85 echo "LANG=${default_lang}" > "${rootfs_path}/etc/locale.conf"
86 echo "KEYMAP=us" > "${rootfs_path}/etc/vconsole.conf"
87 cat > "${rootfs_path}/etc/adjtime" << EOF
880.0 0.0 0.0
890
90LOCAL
f6267d90 91EOF
f3849d01
AV
92 if [ -e "${rootfs_path}/etc/locale.gen" ]; then
93 sed -i 's@^#\(en_US\.UTF-8\)@\1@' "${rootfs_path}/etc/locale.gen"
94 if [ ! "${default_locale}" = "en_US.UTF-8" ]; then
95 echo "${default_locale} ${default_locale##*.}" >> "${rootfs_path}/etc/locale.gen"
96 fi
f6267d90 97 fi
f6267d90 98 fi
f3849d01 99 echo "${name}" > "${rootfs_path}/etc/hostname"
f6267d90
AV
100 cat > "${rootfs_path}/etc/hosts" << EOF
101127.0.0.1 localhost.localdomain localhost ${name}
102::1 localhost.localdomain localhost
103EOF
f6267d90
AV
104 grep nameserver /etc/resolv.conf > "${rootfs_path}/etc/resolv.conf"
105
f3849d01
AV
106 arch-chroot "${rootfs_path}" /bin/bash -s << EOF
107mkdir /run/lock
108locale-gen
109ln -s /usr/share/zoneinfo/${default_timezone} /etc/localtime
110# disable services unavailable for container
111ln -s /dev/null /etc/systemd/system/systemd-udevd.service
112ln -s /dev/null /etc/systemd/system/systemd-udevd-control.socket
113ln -s /dev/null /etc/systemd/system/systemd-udevd-kernel.socket
114ln -s /dev/null /etc/systemd/system/proc-sys-fs-binfmt_misc.automount
14831534 115# set default systemd target
f3849d01 116ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target
f3849d01 117EOF
f6267d90
AV
118 return 0
119}
120
121# write container configuration files
17abf278 122copy_configuration() {
f6267d90
AV
123 mkdir -p "${config_path}"
124 cat > "${config_path}/config" << EOF
f3849d01
AV
125lxc.utsname=${name}
126lxc.autodev=1
127lxc.tty=1
128lxc.pts=1024
f3849d01 129lxc.mount=${config_path}/fstab
d8c77af0 130lxc.cap.drop=sys_module mac_admin mac_override sys_time
6139e7e5
AV
131lxc.kmsg=0
132lxc.stopsignal=SIGRTMIN+4
f6267d90 133#networking
f3849d01
AV
134lxc.network.type=${lxc_network_type}
135lxc.network.link=${lxc_network_link}
136lxc.network.flags=up
137lxc.network.name=eth0
138lxc.network.mtu=1500
f6267d90
AV
139#cgroups
140lxc.cgroup.devices.deny = a
f3849d01
AV
141lxc.cgroup.devices.allow = c *:* m
142lxc.cgroup.devices.allow = b *:* m
f6267d90
AV
143lxc.cgroup.devices.allow = c 1:3 rwm
144lxc.cgroup.devices.allow = c 1:5 rwm
f3849d01 145lxc.cgroup.devices.allow = c 1:7 rwm
f6267d90 146lxc.cgroup.devices.allow = c 1:8 rwm
f3849d01
AV
147lxc.cgroup.devices.allow = c 1:9 rwm
148lxc.cgroup.devices.allow = c 1:9 rwm
149lxc.cgroup.devices.allow = c 4:1 rwm
150lxc.cgroup.devices.allow = c 5:0 rwm
151lxc.cgroup.devices.allow = c 5:1 rwm
f6267d90 152lxc.cgroup.devices.allow = c 5:2 rwm
f3849d01 153lxc.cgroup.devices.allow = c 136:* rwm
f6267d90
AV
154EOF
155
1897e3bc
SH
156 grep -q "^lxc.rootfs" ${config_path}/config 2>/dev/null || echo "lxc.rootfs = ${rootfs_path}" >> ${config_path}/config
157
f6267d90 158 cat > "${config_path}/fstab" << EOF
b335cf8d 159sysfs sys sysfs defaults 0 0
f3849d01 160proc proc proc nodev,noexec,nosuid 0 0
f6267d90
AV
161EOF
162
f6267d90
AV
163 return 0
164}
165
f6267d90 166# install packages within container chroot
17abf278 167install_arch() {
734d0bed
JL
168 [ "${arch}" != "$(uname -m)" ] && different_arch=true
169
170 if [ "${different_arch}" = "true" ]; then
171 container_pacman_config=$(mktemp)
172 container_mirrorlist=$(mktemp)
173 sed -e "s:Architecture =.*:Architecture = ${arch}:g" \
174 -e "s:/etc/pacman.d/mirrorlist:${container_mirrorlist}:g" \
175 "${pacman_config}" > "${container_pacman_config}"
176 sed -e "s:\(x86_64\|\$arch\):${arch}:g" \
177 /etc/pacman.d/mirrorlist > "${container_mirrorlist}"
178
179 pacman_config="${container_pacman_config}"
180 fi
181
14831534 182 if ! pacstrap -dcC "${pacman_config}" "${rootfs_path}" ${base_packages[@]}; then
f6267d90
AV
183 echo "Failed to install container packages"
184 return 1
185 fi
734d0bed
JL
186
187 if [ "${different_arch}" = "true" ]; then
188 sed -i -e "s:Architecture =.*:Architecture = ${arch}:g" \
189 "${rootfs_path}"/etc/pacman.conf
190 cp "${container_mirrorlist}" "${rootfs_path}"/etc/pacman.d/mirrorlist
191 rm "${container_pacman_config}" "${container_mirrorlist}"
192 fi
193
f6267d90 194 [ -d "${rootfs_path}/lib/modules" ] && ldconfig -r "${rootfs_path}"
f6267d90
AV
195 return 0
196}
197
f3849d01 198usage() {
f6267d90
AV
199 cat <<EOF
200usage:
201 ${1} -n|--name=<container_name>
f3849d01 202 [-P|--packages=<pkg1,pkg2,...>] [-p|--path=<path>] [-t|--network_type=<type>] [-l|--network_link=<link>] [-h|--help]
f6267d90
AV
203Mandatory args:
204 -n,--name container name, used to as an identifier for that container from now on
205Optional args:
f3849d01 206 -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 207 -P,--packages preinstall additional packages, comma-separated list
012f591a 208 -e,--enable_units Enable additional systemd units, comma-separated list
14831534 209 -c,--config use specified pacman config when installing container packages
b408e70d 210 -a,--arch use specified architecture instead of host's architecture
f3849d01
AV
211 -t,--network_type set container network interface type (${lxc_network_type})
212 -l,--network_link set network link device (${lxc_network_link})
d0800999 213 -r,--root_passwd set container root password
f6267d90
AV
214 -h,--help print this help
215EOF
216 return 0
217}
218
d0800999 219options=$(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
220if [ ${?} -ne 0 ]; then
221 usage $(basename ${0})
222 exit 1
223fi
224eval set -- "${options}"
225
226while true
227do
228 case "${1}" in
f3849d01
AV
229 -h|--help) usage ${0} && exit 0;;
230 -p|--path) path=${2}; shift 2;;
231 -n|--name) name=${2}; shift 2;;
1897e3bc 232 --rootfs) rootfs_path=${2}; shift 2;;
f3849d01 233 -P|--packages) additional_packages=${2}; shift 2;;
012f591a 234 -e|--enable_units) enable_units=${2}; shift 2;;
14831534 235 -c|--config) pacman_config=${2}; shift 2;;
734d0bed 236 -a|--arch) arch=${2}; shift 2;;
f3849d01
AV
237 -t|--network_type) lxc_network_type=${2}; shift 2;;
238 -l|--network_link) lxc_network_link=${2}; shift 2;;
d0800999 239 -r|--root_passwd) root_passwd=${2}; shift 2;;
f6267d90
AV
240 --) shift 1; break ;;
241 *) break ;;
242 esac
243done
244
245if [ -z "${name}" ]; then
246 echo "missing required 'name' parameter"
247 exit 1
248fi
249
f3849d01
AV
250if [ ! -e /sys/class/net/${lxc_network_link} ]; then
251 echo "network link interface does not exist"
252 exit 1
253fi
254
f6267d90
AV
255type pacman >/dev/null 2>&1
256if [ ${?} -ne 0 ]; then
257 echo "'pacman' command is missing, refer to wiki.archlinux.org for information about installing pacman"
258 exit 1
259fi
260
261if [ -z "${path}" ]; then
262 path="${default_path}/${name}"
263fi
264
265if [ "${EUID}" != "0" ]; then
266 echo "This script should be run as 'root'"
267 exit 1
268fi
269
1897e3bc
SH
270if [ -z "$rootfs_path" ]; then
271 rootfs_path="${path}/rootfs"
272fi
f6267d90
AV
273config_path="${default_path}/${name}"
274
f3849d01
AV
275revert() {
276 echo "Interrupted, cleaning up"
f6267d90 277 lxc-destroy -n "${name}"
f6267d90
AV
278 rm -rf "${path}/${name}"
279 rm -rf "${default_path}/${name}"
280 exit 1
281}
282
283trap revert SIGHUP SIGINT SIGTERM
284
285copy_configuration
286if [ ${?} -ne 0 ]; then
f3849d01 287 echo "failed to write configuration file"
f6267d90
AV
288 rm -rf "${config_path}"
289 exit 1
290fi
291
292if [ ${#additional_packages[@]} -gt 0 ]; then
293 split_string ${additional_packages}
294 base_packages+=(${result[@]})
295fi
296
f3849d01 297mkdir -p "${rootfs_path}"
f6267d90
AV
298install_arch
299if [ ${?} -ne 0 ]; then
f3849d01 300 echo "failed to install Arch Linux"
f6267d90
AV
301 rm -rf "${config_path}" "${path}"
302 exit 1
303fi
304
305configure_arch
306if [ ${?} -ne 0 ]; then
f3849d01 307 echo "failed to configure Arch Linux for a container"
f6267d90
AV
308 rm -rf "${config_path}" "${path}"
309 exit 1
310fi
311
012f591a
JL
312if [ ${#enable_units[@]} -gt 0 ]; then
313 split_string ${enable_units}
314 for unit in ${result[@]}; do
315 [ "${unit}" = *'.'* ] || unit="${unit}.service"
316 ln -s /usr/lib/systemd/system/"${unit}" \
317 "${rootfs_path}"/etc/systemd/system/multi-user.target.wants
318 done
319fi
320
d0800999
JL
321if [ -n "${root_passwd}" ]; then
322 echo "root:${root_passwd}" | chroot "${rootfs_path}" chpasswd
323fi
324
f3849d01 325echo "container config is ${config_path}/config"