]> git.proxmox.com Git - mirror_lxc.git/blame - templates/lxc-altlinux.in
Merge pull request #1658 from 0x0916/2017-06-30/new-configuration-keys
[mirror_lxc.git] / templates / lxc-altlinux.in
CommitLineData
262f4e48
AS
1#!/bin/bash
2
3#
4# template script for generating altlinux container for LXC
5#
6
7#
8# lxc: linux Container library
9
10# Authors:
11# Alexey Shabalin <shaba@altlinux.org>
12
13# This library is free software; you can redistribute it and/or
14# modify it under the terms of the GNU Lesser General Public
15# License as published by the Free Software Foundation; either
16# version 2.1 of the License, or (at your option) any later version.
17
18# This library is distributed in the hope that it will be useful,
19# but WITHOUT ANY WARRANTY; without even the implied warranty of
14d9c0f0 20# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
262f4e48
AS
21# Lesser General Public License for more details.
22
23# You should have received a copy of the GNU Lesser General Public
24# License along with this library; if not, write to the Free Software
250b1eec 25# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
262f4e48 26
8ec981fc 27# Detect use under userns (unsupported)
c63c04fc 28for arg in "$@"; do
96283b54
SG
29 [ "$arg" = "--" ] && break
30 if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
8ec981fc
SG
31 echo "This template can't be used for unprivileged containers." 1>&2
32 echo "You may want to try the \"download\" template instead." 1>&2
33 exit 1
34 fi
35done
36
207bf0e4
SG
37# Make sure the usual locations are in PATH
38export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
39
262f4e48 40#Configurations
ed4616b1 41arch=$(uname -m)
e29bf450 42cache_base=@LOCALSTATEDIR@/cache/lxc/altlinux/$arch
b031f0d2 43default_path=@LXCPATH@
262f4e48
AS
44default_profile=default
45profile_dir=/etc/lxc/profiles
262f4e48
AS
46lxc_network_type=veth
47lxc_network_link=virbr0
48
49# is this altlinux?
50[ -f /etc/altlinux-release ] && is_altlinux=true
51
52configure_altlinux()
53{
54
55 # disable selinux in altlinux
56 mkdir -p $rootfs_path/selinux
57 echo 0 > $rootfs_path/selinux/enforce
58
5c60f990
DP
59 mkdir -p ${rootfs_path}/etc/net/ifaces/eth0
60 cat <<EOF > ${rootfs_path}/etc/net/ifaces/eth0/options
b031f0d2 61BOOTPROTO=${BOOTPROTO}
262f4e48 62ONBOOT=yes
5c60f990 63NM_CONTROLLED=yes
262f4e48
AS
64TYPE=eth
65EOF
66
b031f0d2
AS
67if [ ${BOOTPROTO} != "dhcp" ]; then
68 # ip address
5c60f990 69 cat <<EOF > ${rootfs_path}/etc/net/ifaces/eth0/ipv4address
b031f0d2
AS
70${ipv4}
71EOF
72
5c60f990 73 cat <<EOF > ${rootfs_path}/etc/net/ifaces/eth0/ipv4route
b031f0d2
AS
74${gw}
75EOF
76
5c60f990 77 cat <<EOF > ${rootfs_path}/etc/net/ifaces/eth0/resolv.conf
b031f0d2
AS
78nameserver ${dns}
79EOF
80
5c60f990 81 cat <<EOF > ${rootfs_path}/etc/net/ifaces/eth0/ipv6address
b031f0d2
AS
82${ipv6}
83EOF
84
5c60f990 85 cat <<EOF > ${rootfs_path}/etc/net/ifaces/eth0/ipv6route
b031f0d2
AS
86${gw6}
87EOF
88
89fi
90
262f4e48
AS
91 # set the hostname
92 cat <<EOF > ${rootfs_path}/etc/sysconfig/network
93NETWORKING=yes
94CONFMETHOD=etcnet
95HOSTNAME=${UTSNAME}
96RESOLV_MODS=yes
97EOF
98
99 # set minimal hosts
100 cat <<EOF > $rootfs_path/etc/hosts
101127.0.0.1 localhost.localdomain localhost $name
102EOF
103 # Allow to login at virsh console. loginuid.so doen't work in the absence of auditd.
b031f0d2 104# sed -i 's/^.*loginuid.so.*$/\#&/' ${rootfs_path}/etc/pam.d/common-login
262f4e48
AS
105
106 # Allow root to login at virsh console
107 echo "pts/0" >> ${rootfs_path}/etc/securetty
b031f0d2 108 echo "console" >> ${rootfs_path}/etc/securetty
262f4e48 109
05e61b82 110 # Enable services
5c60f990 111 for service in network syslogd random NetworkManager
05e61b82
DP
112 do
113 chroot ${rootfs_path} chkconfig $service --list &>/dev/null && chroot ${rootfs_path} chkconfig $service on || true
5c60f990
DP
114 # For systemd
115 chroot ${rootfs_path} systemctl -q enable $service &>/dev/null|| true
05e61b82
DP
116 done
117 # Disable services
118 for service in rawdevices fbsetfont
119 do
120 chroot ${rootfs_path} chkconfig $service --list &>/dev/null && chroot ${rootfs_path} chkconfig $service off || true
5c60f990 121 chroot ${rootfs_path} systemctl -q disable $service &>/dev/null || true
05e61b82 122 done
262f4e48 123
b031f0d2
AS
124 subst 's/^\([3-9]\+:[0-9]\+:respawn:\/sbin\/mingetty.*\)/#\1/' ${rootfs_path}/etc/inittab
125 echo "c1:2345:respawn:/sbin/mingetty --noclear console" >> ${rootfs_path}/etc/inittab
05e61b82
DP
126
127 [ -f "${rootfs_path}/etc/syslog.conf" ] && \
128 subst 's,\/dev\/tty12,/var/log/syslog/console,' ${rootfs_path}/etc/syslog.conf
262f4e48
AS
129
130 dev_path="${rootfs_path}/dev"
b031f0d2
AS
131 rm -rf ${dev_path}
132 mkdir -p ${dev_path}
262f4e48
AS
133 mknod -m 666 ${dev_path}/null c 1 3
134 mknod -m 666 ${dev_path}/zero c 1 5
135 mknod -m 644 ${dev_path}/random c 1 8
136 mknod -m 644 ${dev_path}/urandom c 1 9
137 mkdir -m 755 ${dev_path}/pts
138 mkdir -m 1777 ${dev_path}/shm
139 mknod -m 666 ${dev_path}/tty c 5 0
b031f0d2
AS
140 chown root:tty ${dev_path}/tty
141 mknod -m 600 ${dev_path}/tty0 c 4 0
142 mknod -m 600 ${dev_path}/tty1 c 4 1
143 mknod -m 600 ${dev_path}/tty2 c 4 2
144 mknod -m 600 ${dev_path}/tty3 c 4 3
145 mknod -m 600 ${dev_path}/tty4 c 4 4
262f4e48
AS
146 mknod -m 600 ${dev_path}/console c 5 1
147 mknod -m 666 ${dev_path}/full c 1 7
148 mknod -m 600 ${dev_path}/initctl p
149 mknod -m 666 ${dev_path}/ptmx c 5 2
b031f0d2
AS
150 chown root:tty ${dev_path}/ptmx
151 ln -s /proc/self/fd ${dev_path}/fd
152 ln -s /proc/kcore ${dev_path}/core
153 mkdir -m 755 ${dev_path}/mapper
154 mknod -m 600 ${dev_path}/mapper/control c 10 236
155 mkdir -m 755 ${dev_path}/net
156 mknod -m 666 ${dev_path}/net/tun c 10 200
262f4e48 157
436ab4be
EG
158 if [ -n "${root_password}" ]; then
159 echo "setting root passwd to $root_password"
160 echo "root:$root_password" | chroot $rootfs_path chpasswd
161 fi
262f4e48
AS
162
163 return 0
164}
165
166download_altlinux()
167{
168
169 # check the mini altlinux was not already downloaded
170 INSTALL_ROOT=$cache/partial
171 mkdir -p $INSTALL_ROOT
172 if [ $? -ne 0 ]; then
14d9c0f0
SG
173 echo "Failed to create '$INSTALL_ROOT' directory"
174 return 1
262f4e48
AS
175 fi
176
177 # download a mini altlinux into a cache
178 echo "Downloading altlinux minimal ..."
179 APT_GET="apt-get -o RPM::RootDir=$INSTALL_ROOT -y"
180 PKG_LIST="$(grep -hs '^[^#]' "$profile_dir/$profile")"
a9ae28a0 181 # if no configuration file $profile -- fall back to default list of packages
0b7c005e 182 [ -z "$PKG_LIST" ] && PKG_LIST="interactivesystem apt apt-conf etcnet-full openssh-server systemd-sysvinit systemd-units systemd NetworkManager-daemon"
262f4e48
AS
183
184 mkdir -p $INSTALL_ROOT/var/lib/rpm
185 rpm --root $INSTALL_ROOT --initdb
a9ae28a0
DP
186
187 # some scripts want to have /dev/null at least
188 dev_path="$INSTALL_ROOT/dev"
189 if [ ! -c "${dev_path}/null" ]; then
190 mkdir -p "${dev_path}"
191 mknod -m 666 "${dev_path}/null" c 1 3
192 fi
193
262f4e48
AS
194 $APT_GET install $PKG_LIST
195
196 if [ $? -ne 0 ]; then
14d9c0f0
SG
197 echo "Failed to download the rootfs, aborting."
198 return 1
262f4e48
AS
199 fi
200
201 mv "$INSTALL_ROOT" "$cache/rootfs"
202 echo "Download complete."
203
204 return 0
205}
206
207copy_altlinux()
208{
209
210 # make a local copy of the minialtlinux
211 echo -n "Copying rootfs to $rootfs_path ..."
212 #cp -a $cache/rootfs-$arch $rootfs_path || return 1
213 # i prefer rsync (no reason really)
214 mkdir -p $rootfs_path
44d39789 215 rsync -Ha $cache/rootfs/ $rootfs_path/
262f4e48
AS
216 return 0
217}
218
219update_altlinux()
220{
221 chroot $cache/rootfs apt-get update
222 chroot $cache/rootfs apt-get -y dist-upgrade
223}
224
225install_altlinux()
226{
e29bf450 227 mkdir -p @LOCALSTATEDIR@/lock/subsys/
262f4e48 228 (
17abf278 229 flock -x 9
14d9c0f0
SG
230 if [ $? -ne 0 ]; then
231 echo "Cache repository is busy."
232 return 1
233 fi
234
235 echo "Checking cache download in $cache/rootfs ... "
236 if [ ! -e "$cache/rootfs" ]; then
237 download_altlinux
238 if [ $? -ne 0 ]; then
239 echo "Failed to download 'altlinux base'"
240 return 1
241 fi
262f4e48 242 else
14d9c0f0 243 echo "Cache found. Updating..."
262f4e48 244 update_altlinux
14d9c0f0
SG
245 if [ $? -ne 0 ]; then
246 echo "Failed to update 'altlinux base', continuing with last known good cache"
262f4e48
AS
247 else
248 echo "Update finished"
14d9c0f0
SG
249 fi
250 fi
251
252 echo "Copy $cache/rootfs to $rootfs_path ... "
253 copy_altlinux
254 if [ $? -ne 0 ]; then
255 echo "Failed to copy rootfs"
256 return 1
257 fi
258 return 0
17abf278 259 ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-altlinux
262f4e48
AS
260
261 return $?
262}
263
264copy_configuration()
265{
266
267 mkdir -p $config_path
1881820a 268 grep -q "^lxc.rootfs" $config_path/config 2>/dev/null || echo "lxc.rootfs = $rootfs_path" >> $config_path/config
262f4e48 269 cat <<EOF >> $config_path/config
b67771bc 270lxc.uts.name = $name
262f4e48
AS
271lxc.tty = 4
272lxc.pts = 1024
eee3ba81 273lxc.cap.drop = sys_module mac_admin mac_override sys_time
f02ce27d
SG
274
275# When using LXC with apparmor, uncomment the next line to run unconfined:
276#lxc.aa_profile = unconfined
277
262f4e48 278#networking
7fa3f2e9 279#lxc.net.0.type = $lxc_network_type
280#lxc.net.0.flags = up
281#lxc.net.0.link = $lxc_network_link
282#lxc.net.0.name = veth0
283#lxc.net.0.mtu = 1500
b031f0d2
AS
284EOF
285if [ ! -z ${ipv4} ]; then
286 cat <<EOF >> $config_path/config
7fa3f2e9 287lxc.net.0.ipv4 = $ipv4
b031f0d2
AS
288EOF
289fi
290if [ ! -z ${gw} ]; then
291 cat <<EOF >> $config_path/config
7fa3f2e9 292lxc.net.0.ipv4.gateway = $gw
b031f0d2
AS
293EOF
294fi
295if [ ! -z ${ipv6} ]; then
296 cat <<EOF >> $config_path/config
7fa3f2e9 297lxc.net.0.ipv6 = $ipv6
b031f0d2
AS
298EOF
299fi
300if [ ! -z ${gw6} ]; then
301 cat <<EOF >> $config_path/config
7fa3f2e9 302lxc.net.0.ipv6.gateway = $gw6
b031f0d2
AS
303EOF
304fi
305 cat <<EOF >> $config_path/config
262f4e48
AS
306#cgroups
307lxc.cgroup.devices.deny = a
308# /dev/null and zero
309lxc.cgroup.devices.allow = c 1:3 rwm
310lxc.cgroup.devices.allow = c 1:5 rwm
311# consoles
312lxc.cgroup.devices.allow = c 5:1 rwm
313lxc.cgroup.devices.allow = c 5:0 rwm
314lxc.cgroup.devices.allow = c 4:0 rwm
315lxc.cgroup.devices.allow = c 4:1 rwm
316# /dev/{,u}random
317lxc.cgroup.devices.allow = c 1:9 rwm
318lxc.cgroup.devices.allow = c 1:8 rwm
319lxc.cgroup.devices.allow = c 136:* rwm
320lxc.cgroup.devices.allow = c 5:2 rwm
321# rtc
b031f0d2 322lxc.cgroup.devices.allow = c 10:135 rwm
262f4e48 323
f24a52d5 324lxc.mount.auto = cgroup:mixed proc:mixed sys:mixed
262f4e48
AS
325EOF
326
327 if [ $? -ne 0 ]; then
14d9c0f0
SG
328 echo "Failed to add configuration"
329 return 1
262f4e48
AS
330 fi
331
332 return 0
333}
334
335clean()
336{
337
338 if [ ! -e $cache ]; then
14d9c0f0 339 exit 0
262f4e48
AS
340 fi
341
342 # lock, so we won't purge while someone is creating a repository
343 (
17abf278 344 flock -x 9
14d9c0f0
SG
345 if [ $? != 0 ]; then
346 echo "Cache repository is busy."
347 exit 1
348 fi
349
350 echo -n "Purging the download cache for ALTLinux-$release..."
351 rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1
352 exit 0
17abf278 353 ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-altlinux
262f4e48
AS
354}
355
356usage()
357{
358 cat <<EOF
359usage:
360 $1 -n|--name=<container_name>
361 [-p|--path=<path>] [-c|--clean] [-R|--release=<ALTLinux_release>]
b031f0d2
AS
362 [-4|--ipv4=<ipv4 address>] [-6|--ipv6=<ipv6 address>]
363 [-g|--gw=<gw address>] [-d|--dns=<dns address>]
1897e3bc 364 [-P|--profile=<name of the profile>] [--rootfs=<path>]
262f4e48
AS
365 [-A|--arch=<arch of the container>]
366 [-h|--help]
367Mandatory args:
368 -n,--name container name, used to as an identifier for that container from now on
369Optional args:
e29bf450 370 -p,--path path to where the container rootfs will be created, defaults to @LXCPATH@. The container config will go under @LXCPATH@ in that case
262f4e48
AS
371 -c,--clean clean the cache
372 -R,--release ALTLinux release for the new container. if the host is ALTLinux, then it will defaultto the host's release.
b031f0d2
AS
373 -4,--ipv4 specify the ipv4 address to assign to the virtualized interface, eg. 192.168.1.123/24
374 -6,--ipv6 specify the ipv6 address to assign to the virtualized interface, eg. 2003:db8:1:0:214:1234:fe0b:3596/64
375 -g,--gw specify the default gw, eg. 192.168.1.1
376 -G,--gw6 specify the default gw, eg. 2003:db8:1:0:214:1234:fe0b:3596
377 -d,--dns specify the DNS server, eg. 192.168.1.2
262f4e48
AS
378 -P,--profile Profile name is the file name in /etc/lxc/profiles contained packages name for install to cache.
379 -A,--arch NOT USED YET. Define what arch the container will be [i686,x86_64]
1897e3bc 380 ---rootfs rootfs path
262f4e48
AS
381 -h,--help print this help
382EOF
383 return 0
384}
385
a9ae28a0 386options=$(getopt -o hp:n:P:cR:4:6:g:d: -l help,rootfs:,path:,name:,profile:,clean,release:,ipv4:,ipv6:,gw:,dns: -- "$@")
262f4e48
AS
387if [ $? -ne 0 ]; then
388 usage $(basename $0)
389 exit 1
390fi
391eval set -- "$options"
392
393while true
394do
395 case "$1" in
14d9c0f0
SG
396 -h|--help) usage $0 && exit 0;;
397 -p|--path) path=$2; shift 2;;
1897e3bc 398 --rootfs) rootfs_path=$2; shift 2;;
14d9c0f0
SG
399 -n|--name) name=$2; shift 2;;
400 -P|--profile) profile=$2; shift 2;;
217535de 401 -c|--clean) clean=1; shift 1;;
14d9c0f0
SG
402 -R|--release) release=$2; shift 2;;
403 -4|--ipv4) ipv4=$2; shift 2;;
404 -6|--ipv6) ipv6=$2; shift 2;;
405 -g|--gw) gw=$2; shift 2;;
406 -d|--dns) dns=$2; shift 2;;
407 --) shift 1; break ;;
262f4e48
AS
408 *) break ;;
409 esac
410done
411
412if [ ! -z "$clean" -a -z "$path" ]; then
413 clean || exit 1
414 exit 0
415fi
416
417type apt-get >/dev/null 2>&1
418if [ $? -ne 0 ]; then
419 echo "'apt-get' command is missing"
420 exit 1
421fi
422
423if [ -z "$path" ]; then
424 path=$default_path
425fi
426
427if [ -z "$profile" ]; then
428 profile=$default_profile
429fi
430
431if [ -z "$release" ]; then
432 if [ "$is_altlinux" ]; then
433 release=$(cat /etc/altlinux-release |awk '/^ALT/ {print $3}')
434 else
435 echo "This is not a ALTLinux host and release missing, use -R|--release to specify release"
436 exit 1
437 fi
438fi
439
b031f0d2
AS
440if [ -z "$ipv4" -a -z "$ipv6" ]; then
441 BOOTPROTO="dhcp"
442else
443 BOOTPROTO="static"
444fi
445
262f4e48
AS
446if [ "$(id -u)" != "0" ]; then
447 echo "This script should be run as 'root'"
448 exit 1
449fi
450
1897e3bc
SH
451# check for 'lxc.rootfs' passed in through default config by lxc-create
452if [ -z "$rootfs_path" ]; then
453 if grep -q '^lxc.rootfs' $path/config 2>/dev/null ; then
853d58fd 454 rootfs_path=$(awk -F= '/^lxc.rootfs =/{ print $2 }' $path/config)
1897e3bc 455 else
44b430e2 456 rootfs_path=$path/rootfs
1897e3bc
SH
457 fi
458fi
459
262f4e48
AS
460config_path=$default_path/$name
461cache=$cache_base/$release/$profile
462
262f4e48
AS
463install_altlinux
464if [ $? -ne 0 ]; then
465 echo "failed to install altlinux"
466 exit 1
467fi
468
469configure_altlinux
470if [ $? -ne 0 ]; then
471 echo "failed to configure altlinux for a container"
472 exit 1
473fi
474
475copy_configuration
476if [ $? -ne 0 ]; then
477 echo "failed write configuration file"
478 exit 1
479fi
480
4986f1c4 481if [ ! -z "$clean" ]; then
262f4e48
AS
482 clean || exit 1
483 exit 0
484fi
485echo "container rootfs and config created"
eba7df9e 486echo "network configured as $lxc_network_type in the $lxc_network_link"