* /usr/lib/lxc/templates of lxc 0.8.0~rc1-4ubuntu37 on Ubuntu 12.10 (beta)
[lab.git] / lxc / 0.8.0~rc1-4ubuntu37 / templates / lxc-opensuse
1 #!/bin/bash
2
3 #
4 # template script for generating suse container for LXC
5 #
6
7 #
8 # lxc: linux Container library
9
10 # Authors:
11 # Daniel Lezcano <daniel.lezcano@free.fr>
12 # Frederic Crozat <fcrozat@suse.com>
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
26 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27
28 DISTRO=12.1
29
30 configure_opensuse()
31 {
32     rootfs=$1
33     hostname=$2
34
35    # set network as static, but everything is done by LXC outside the container
36    cat <<EOF > $rootfs/etc/sysconfig/network/ifcfg-eth0
37 STARTMODE='auto'
38 BOOTPROTO='static'
39 EOF
40
41    # set default route
42    IP=$(/sbin/ip route | awk '/default/ { print $3 }')
43    echo "default $IP - -" > $rootfs/etc/sysconfig/network/routes
44
45    # create empty fstab
46    touch $rootfs/etc/fstab
47
48     # create minimal /dev
49     mknod -m 666 $rootfs/dev/random c 1 8
50     mknod -m 666 $rootfs/dev/urandom c 1 9
51     mkdir -m 755 $rootfs/dev/pts
52     mkdir -m 1777 $rootfs/dev/shm
53     mknod -m 666 $rootfs/dev/tty c 5 0
54     mknod -m 600 $rootfs/dev/console c 5 1
55     mknod -m 666 $rootfs/dev/tty0 c 4 0
56     mknod -m 666 $rootfs/dev/tty1 c 4 1
57     mknod -m 666 $rootfs/dev/tty2 c 4 2
58     mknod -m 666 $rootfs/dev/tty3 c 4 3
59     mknod -m 666 $rootfs/dev/tty4 c 4 4
60     ln -s null $rootfs/dev/tty10
61     mknod -m 666 $rootfs/dev/full c 1 7
62     mknod -m 666 $rootfs/dev/ptmx c 5 2
63     ln -s /proc/self/fd $rootfs/dev/fd
64     ln -s /proc/kcore $rootfs/dev/core
65     mkdir -m 755 $rootfs/dev/mapper
66     mknod -m 600 $rootfs/dev/mapper/control c 10 60
67     mkdir -m 755 $rootfs/dev/net
68     mknod -m 666 $rootfs/dev/net/tun c 10 200
69
70     # set the hostname
71     cat <<EOF > $rootfs/etc/HOSTNAME
72 $hostname
73 EOF
74
75     # do not use hostname from HOSTNAME variable
76     cat <<EOF >> $rootfs/etc/sysconfig/cron
77 unset HOSTNAME
78 EOF
79
80     # set minimal hosts
81     cat <<EOF > $rootfs/etc/hosts
82 127.0.0.1 localhost $hostname
83 EOF
84
85     # disable various services
86     # disable yast->bootloader in container
87     cat <<EOF > $rootfs/etc/sysconfig/bootloader
88 LOADER_TYPE=none
89 LOADER_LOCATION=none
90 EOF
91
92     # cut down inittab
93     cat <<EOF > $rootfs/etc/inittab
94 id:3:initdefault:
95 si::bootwait:/etc/init.d/boot
96 l0:0:wait:/etc/init.d/rc 0
97 l1:1:wait:/etc/init.d/rc 1
98 l2:2:wait:/etc/init.d/rc 2
99 l3:3:wait:/etc/init.d/rc 3
100 l6:6:wait:/etc/init.d/rc 6
101 ls:S:wait:/etc/init.d/rc S
102 ~~:S:respawn:/sbin/sulogin
103 p6::ctrlaltdel:/sbin/init 6
104 p0::powerfail:/sbin/init 0
105 cons:2345:respawn:/sbin/mingetty --noclear console screen
106 c1:2345:respawn:/sbin/mingetty --noclear tty1 screen
107 EOF
108
109     # set /dev/console as securetty
110     cat << EOF >> $rootfs/etc/securetty
111 console
112 EOF
113
114     cat <<EOF >> $rootfs/etc/sysconfig/boot
115 # disable root fsck
116 ROOTFS_FSCK="0"
117 ROOTFS_BLKDEV="/dev/null"
118 EOF
119
120
121     # remove pointless services in a container
122     chroot $rootfs /sbin/insserv -r -f boot.udev boot.loadmodules boot.device-mapper boot.clock boot.swap boot.klog kbd
123
124     echo "Please change root-password !"
125     echo "root:root" | chroot $rootfs chpasswd
126
127     return 0
128 }
129
130 download_opensuse()
131 {
132     cache=$1
133     arch=$2
134
135     if [ ! -x /usr/bin/build ]; then
136        echo "Could not create openSUSE template :"
137        echo "you need to install \"build\" package"
138        return 1
139     fi
140
141     # check the mini opensuse was not already downloaded
142     mkdir -p "$cache/partial-$arch"
143
144     if [ $? -ne 0 ]; then
145         echo "Failed to create '$cache/partial-$arch' directory"
146         return 1
147     fi
148
149     # download a mini opensuse into a cache
150     echo "Downloading opensuse minimal ..."
151     mkdir -p "$cache/partial-$arch-packages"
152     zypper --quiet --root $cache/partial-$arch-packages --non-interactive ar http://download.opensuse.org/distribution/$DISTRO/repo/oss/ repo-oss
153     zypper --quiet --root $cache/partial-$arch-packages --non-interactive ar http://download.opensuse.org/update/$DISTRO/ update
154     zypper --quiet --root $cache/partial-$arch-packages --non-interactive --gpg-auto-import-keys update
155     zypper --root $cache/partial-$arch-packages --non-interactive in --auto-agree-with-licenses --download-only zypper lxc patterns-openSUSE-base sysvinit-init
156     cat > $cache/partial-$arch-packages/opensuse.conf << EOF
157 Preinstall: aaa_base bash coreutils diffutils
158 Preinstall: filesystem fillup glibc grep insserv libacl1 libattr1
159 Preinstall: libbz2-1 libgcc46 libxcrypt libncurses5 pam
160 Preinstall: permissions libreadline6 rpm sed tar zlib libselinux1
161 Preinstall: liblzma5 libcap2 libpcre0
162 Preinstall: libpopt0 libelf1 liblua5_1
163
164 RunScripts: aaa_base
165
166 Support: zypper
167 Support: patterns-openSUSE-base
168 Support: lxc
169 Prefer: sysvinit-init
170
171 Ignore: patterns-openSUSE-base:patterns-openSUSE-yast2_install_wf
172 EOF
173
174     CLEAN_BUILD=1 BUILD_ROOT="$cache/partial-$arch" BUILD_DIST="$cache/partial-$arch-packages/opensuse.conf" /usr/lib/build/init_buildsystem  --clean --cachedir $cache/partial-$arch-cache --repository $cache/partial-$arch-packages/var/cache/zypp/packages/repo-oss/suse/$arch --repository $cache/partial-$arch-packages/var/cache/zypp/packages/repo-oss/suse/noarch
175     chroot $cache/partial-$arch /usr/bin/zypper --quiet --non-interactive ar http://download.opensuse.org/distribution/$DISTRO/repo/oss repo-oss
176     chroot $cache/partial-$arch /usr/bin/zypper --quiet --non-interactive ar http://download.opensuse.org/update/$DISTRO/ update
177     chroot $cache/partial-$arch rpm -e patterns-openSUSE-base
178     umount $cache/partial-$arch/proc
179 #   really clean the image
180     rm -fr $cache/partial-$arch/{.build,.guessed_dist,.srcfiles*,installed-pkg}
181     rm -fr $cache/partial-$arch/dev
182 #    make sure we have a minimal /dev
183     mkdir -p "$cache/partial-$arch/dev"
184     mknod -m 666 $cache/partial-$arch/dev/null c 1 3
185     mknod -m 666 $cache/partial-$arch/dev/zero c 1 5
186 #   create mtab symlink
187     rm -f $cache/partial-$arch/etc/mtab
188     ln -sf /proc/self/mounts $cache/partial-$arch/etc/mtab
189     if [ $? -ne 0 ]; then
190         echo "Failed to download the rootfs, aborting."
191         return 1
192     fi
193
194     rm -fr "$cache/partial-$arch-packages"
195     mv "$1/partial-$arch" "$1/rootfs-$arch"
196     echo "Download complete."
197
198     return 0
199 }
200
201 copy_opensuse()
202 {
203     cache=$1
204     arch=$2
205     rootfs=$3
206
207     # make a local copy of the mini opensuse
208     echo -n "Copying rootfs to $rootfs ..."
209     mkdir -p $rootfs
210     rsync -a $cache/rootfs-$arch/ $rootfs/ || return 1
211     return 0
212 }
213
214 install_opensuse()
215 {
216     cache="/var/cache/lxc/opensuse"
217     rootfs=$1
218     mkdir -p /var/lock/subsys/
219     (
220         flock -x 200
221         if [ $? -ne 0 ]; then
222             echo "Cache repository is busy."
223             return 1
224         fi
225
226         arch=$(arch)
227
228         echo "Checking cache download in $cache/rootfs-$arch ... "
229         if [ ! -e "$cache/rootfs-$arch" ]; then
230             download_opensuse $cache $arch
231             if [ $? -ne 0 ]; then
232                 echo "Failed to download 'opensuse base'"
233                 return 1
234             fi
235         fi
236
237         echo "Copy $cache/rootfs-$arch to $rootfs ... "
238         copy_opensuse $cache $arch $rootfs
239         if [ $? -ne 0 ]; then
240             echo "Failed to copy rootfs"
241             return 1
242         fi
243
244         return 0
245
246         ) 200>/var/lock/subsys/lxc
247
248     return $?
249 }
250
251 copy_configuration()
252 {
253     path=$1
254     rootfs=$2
255     name=$3
256
257     grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config
258     cat <<EOF >> $path/config
259 lxc.utsname = $name
260
261 lxc.tty = 4
262 lxc.pts = 1024
263 lxc.mount  = $path/fstab
264 # uncomment the next line to run the container unconfined:
265 #lxc.aa_profile = unconfined
266
267 lxc.cgroup.devices.deny = a
268 # /dev/null and zero
269 lxc.cgroup.devices.allow = c 1:3 rwm
270 lxc.cgroup.devices.allow = c 1:5 rwm
271 # consoles
272 lxc.cgroup.devices.allow = c 5:1 rwm
273 lxc.cgroup.devices.allow = c 5:0 rwm
274 lxc.cgroup.devices.allow = c 4:0 rwm
275 lxc.cgroup.devices.allow = c 4:1 rwm
276 # /dev/{,u}random
277 lxc.cgroup.devices.allow = c 1:9 rwm
278 lxc.cgroup.devices.allow = c 1:8 rwm
279 lxc.cgroup.devices.allow = c 136:* rwm
280 lxc.cgroup.devices.allow = c 5:2 rwm
281 # rtc
282 lxc.cgroup.devices.allow = c 254:0 rwm
283 EOF
284
285     cat <<EOF > $path/fstab
286 proc            proc         proc       nodev,noexec,nosuid 0 0
287 sysfs           sys          sysfs      defaults  0 0
288 EOF
289
290     if [ $? -ne 0 ]; then
291         echo "Failed to add configuration"
292         return 1
293     fi
294
295     return 0
296 }
297
298 clean()
299 {
300     cache="/var/cache/lxc/opensuse"
301
302     if [ ! -e $cache ]; then
303         exit 0
304     fi
305
306     # lock, so we won't purge while someone is creating a repository
307     (
308         flock -x 200
309         if [ $? != 0 ]; then
310             echo "Cache repository is busy."
311             exit 1
312         fi
313
314         echo -n "Purging the download cache..."
315         rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1
316         exit 0
317
318     ) 200>/var/lock/subsys/lxc
319 }
320
321 usage()
322 {
323     cat <<EOF
324 $1 -h|--help -p|--path=<path> --clean
325 EOF
326     return 0
327 }
328
329 options=$(getopt -o hp:n:c -l help,path:,name:,clean -- "$@")
330 if [ $? -ne 0 ]; then
331     usage $(basename $0)
332     exit 1
333 fi
334 eval set -- "$options"
335
336 while true
337 do
338     case "$1" in
339         -h|--help)      usage $0 && exit 0;;
340         -p|--path)      path=$2; shift 2;;
341         -n|--name)      name=$2; shift 2;;
342         -c|--clean)     clean=$2; shift 2;;
343         --)             shift 1; break ;;
344         *)              break ;;
345     esac
346 done
347
348 if [ ! -z "$clean" -a -z "$path" ]; then
349     clean || exit 1
350     exit 0
351 fi
352
353 type zypper > /dev/null
354 if [ $? -ne 0 ]; then
355     echo "'zypper' command is missing"
356     exit 1
357 fi
358
359 if [ -z "$path" ]; then
360     echo "'path' parameter is required"
361     exit 1
362 fi
363
364 if [ "$(id -u)" != "0" ]; then
365     echo "This script should be run as 'root'"
366     exit 1
367 fi
368
369 # detect rootfs
370 config="$path/config"
371 if grep -q '^lxc.rootfs' $config 2>/dev/null ; then
372     rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'`
373 else
374     rootfs=$path/rootfs
375 fi
376
377 install_opensuse $rootfs
378 if [ $? -ne 0 ]; then
379     echo "failed to install opensuse"
380     exit 1
381 fi
382
383 configure_opensuse $rootfs $name
384 if [ $? -ne 0 ]; then
385     echo "failed to configure opensuse for a container"
386     exit 1
387 fi
388
389 copy_configuration $path $rootfs $name
390 if [ $? -ne 0 ]; then
391     echo "failed write configuration file"
392     exit 1
393 fi
394
395 if [ ! -z $clean ]; then
396     clean || exit 1
397     exit 0
398 fi