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