* /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-debian
1 #!/bin/bash
2
3 #
4 # lxc: linux Container library
5
6 # Authors:
7 # Daniel Lezcano <daniel.lezcano@free.fr>
8
9 # This library is free software; you can redistribute it and/or
10 # modify it under the terms of the GNU Lesser General Public
11 # License as published by the Free Software Foundation; either
12 # version 2.1 of the License, or (at your option) any later version.
13
14 # This library is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 # Lesser General Public License for more details.
18
19 # You should have received a copy of the GNU Lesser General Public
20 # License along with this library; if not, write to the Free Software
21 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
23 SUITE=${SUITE:-squeeze}
24 MIRROR=${MIRROR:-http://cdn.debian.net/debian}
25
26 configure_debian()
27 {
28     rootfs=$1
29     hostname=$2
30
31     # squeeze only has /dev/tty and /dev/tty0 by default,
32     # therefore creating missing device nodes for tty1-4.
33     for tty in $(seq 1 4); do
34         if [ ! -e $rootfs/dev/tty$tty ]; then
35             mknod $rootfs/dev/tty$tty c 4 $tty
36         fi
37     done
38
39     # configure the inittab
40     cat <<EOF > $rootfs/etc/inittab
41 id:3:initdefault:
42 si::sysinit:/etc/init.d/rcS
43 l0:0:wait:/etc/init.d/rc 0
44 l1:1:wait:/etc/init.d/rc 1
45 l2:2:wait:/etc/init.d/rc 2
46 l3:3:wait:/etc/init.d/rc 3
47 l4:4:wait:/etc/init.d/rc 4
48 l5:5:wait:/etc/init.d/rc 5
49 l6:6:wait:/etc/init.d/rc 6
50 # Normally not reached, but fallthrough in case of emergency.
51 z6:6:respawn:/sbin/sulogin
52 1:2345:respawn:/sbin/getty 38400 console
53 c1:12345:respawn:/sbin/getty 38400 tty1 linux
54 c2:12345:respawn:/sbin/getty 38400 tty2 linux
55 c3:12345:respawn:/sbin/getty 38400 tty3 linux
56 c4:12345:respawn:/sbin/getty 38400 tty4 linux
57 p6::ctrlaltdel:/sbin/init 6 
58 p0::powerfail:/sbin/init 0
59 EOF
60
61     # disable selinux in debian
62     mkdir -p $rootfs/selinux
63     echo 0 > $rootfs/selinux/enforce
64
65     # configure the network using the dhcp
66     cat <<EOF > $rootfs/etc/network/interfaces
67 auto lo
68 iface lo inet loopback
69
70 auto eth0
71 iface eth0 inet dhcp
72 EOF
73
74     # set the hostname
75     cat <<EOF > $rootfs/etc/hostname
76 $hostname
77 EOF
78
79     # reconfigure some services
80     if [ -z "$LANG" ]; then
81         chroot $rootfs locale-gen en_US.UTF-8 UTF-8
82         chroot $rootfs update-locale LANG=en_US.UTF-8
83     else
84         chroot $rootfs locale-gen $LANG $(echo $LANG | cut -d. -f2)
85         chroot $rootfs update-locale LANG=$LANG
86     fi
87
88     # remove pointless services in a container
89     chroot $rootfs /usr/sbin/update-rc.d -f checkroot.sh remove
90     chroot $rootfs /usr/sbin/update-rc.d -f umountfs remove
91     chroot $rootfs /usr/sbin/update-rc.d -f hwclock.sh remove
92     chroot $rootfs /usr/sbin/update-rc.d -f hwclockfirst.sh remove
93
94     echo "root:root" | chroot $rootfs chpasswd
95     echo "Root password is 'root', please change !"
96
97     return 0
98 }
99
100 cleanup()
101 {
102     rm -rf $cache/partial-$SUITE-$arch
103     rm -rf $cache/rootfs-$SUITE-$arch
104 }
105
106 download_debian()
107 {
108     packages=\
109 ifupdown,\
110 locales,\
111 libui-dialog-perl,\
112 dialog,\
113 isc-dhcp-client,\
114 netbase,\
115 net-tools,\
116 iproute,\
117 openssh-server
118
119     cache=$1
120     arch=$2
121
122     trap cleanup EXIT SIGHUP SIGINT SIGTERM
123     # check the mini debian was not already downloaded
124     mkdir -p "$cache/partial-$SUITE-$arch"
125     if [ $? -ne 0 ]; then
126         echo "Failed to create '$cache/partial-$SUITE-$arch' directory"
127         return 1
128     fi
129
130     # download a mini debian into a cache
131     echo "Downloading debian minimal ..."
132     debootstrap --verbose --variant=minbase --arch=$arch \
133         --include=$packages \
134         "$SUITE" "$cache/partial-$SUITE-$arch" $MIRROR
135     if [ $? -ne 0 ]; then
136         echo "Failed to download the rootfs, aborting."
137         return 1
138     fi
139
140     mv "$1/partial-$SUITE-$arch" "$1/rootfs-$SUITE-$arch"
141     echo "Download complete."
142     trap EXIT
143     trap SIGINT
144     trap SIGTERM
145     trap SIGHUP
146
147     return 0
148 }
149
150 copy_debian()
151 {
152     cache=$1
153     arch=$2
154     rootfs=$3
155
156     # make a local copy of the minidebian
157     echo -n "Copying rootfs to $rootfs..."
158     mkdir -p $rootfs
159     rsync -a "$cache/rootfs-$SUITE-$arch"/ $rootfs/ || return 1
160     return 0
161 }
162
163 install_debian()
164 {
165     cache="/var/cache/lxc/debian"
166     rootfs=$1
167     mkdir -p /var/lock/subsys/
168     (
169         flock -x 200
170         if [ $? -ne 0 ]; then
171             echo "Cache repository is busy."
172             return 1
173         fi
174
175         arch=$(dpkg --print-architecture)
176
177         echo "Checking cache download in $cache/rootfs-$SUITE-$arch ... "
178         if [ ! -e "$cache/rootfs-$SUITE-$arch" ]; then
179             download_debian $cache $arch
180             if [ $? -ne 0 ]; then
181                 echo "Failed to download 'debian base'"
182                 return 1
183             fi
184         fi
185
186         copy_debian $cache $arch $rootfs
187         if [ $? -ne 0 ]; then
188             echo "Failed to copy rootfs"
189             return 1
190         fi
191
192         return 0
193
194         ) 200>/var/lock/subsys/lxc
195
196     return $?
197 }
198
199 copy_configuration()
200 {
201     path=$1
202     rootfs=$2
203     hostname=$3
204
205     grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config
206     cat <<EOF >> $path/config
207 lxc.tty = 4
208 lxc.pts = 1024
209 lxc.utsname = $hostname
210 # uncomment the next line to run the container unconfined:
211 #lxc.aa_profile = unconfined
212 lxc.cgroup.devices.deny = a
213 # /dev/null and zero
214 lxc.cgroup.devices.allow = c 1:3 rwm
215 lxc.cgroup.devices.allow = c 1:5 rwm
216 # consoles
217 lxc.cgroup.devices.allow = c 5:1 rwm
218 lxc.cgroup.devices.allow = c 5:0 rwm
219 lxc.cgroup.devices.allow = c 4:0 rwm
220 lxc.cgroup.devices.allow = c 4:1 rwm
221 # /dev/{,u}random
222 lxc.cgroup.devices.allow = c 1:9 rwm
223 lxc.cgroup.devices.allow = c 1:8 rwm
224 lxc.cgroup.devices.allow = c 136:* rwm
225 lxc.cgroup.devices.allow = c 5:2 rwm
226 # rtc
227 lxc.cgroup.devices.allow = c 254:0 rwm
228
229 # mounts point
230 lxc.mount.entry=proc proc proc nodev,noexec,nosuid 0 0
231 lxc.mount.entry=sysfs sys sysfs defaults  0 0
232 EOF
233
234     if [ $? -ne 0 ]; then
235         echo "Failed to add configuration"
236         return 1
237     fi
238
239     return 0
240 }
241
242 clean()
243 {
244     cache="/var/cache/lxc/debian"
245
246     if [ ! -e $cache ]; then
247         exit 0
248     fi
249
250     # lock, so we won't purge while someone is creating a repository
251     (
252         flock -n -x 200
253         if [ $? != 0 ]; then
254             echo "Cache repository is busy."
255             exit 1
256         fi
257
258         echo -n "Purging the download cache..."
259         rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1
260         exit 0
261
262     ) 200>/var/lock/subsys/lxc
263 }
264
265 usage()
266 {
267     cat <<EOF
268 $1 -h|--help -p|--path=<path> --clean
269 EOF
270     return 0
271 }
272
273 options=$(getopt -o hp:n:c -l help,path:,name:,clean -- "$@")
274 if [ $? -ne 0 ]; then
275         usage $(basename $0)
276         exit 1
277 fi
278 eval set -- "$options"
279
280 while true
281 do
282     case "$1" in
283         -h|--help)      usage $0 && exit 0;;
284         -p|--path)      path=$2; shift 2;;
285         -n|--name)      name=$2; shift 2;;
286         -c|--clean)     clean=$2; shift 2;;
287         --)             shift 1; break ;;
288         *)              break ;;
289     esac
290 done
291
292 if [ ! -z "$clean" -a -z "$path" ]; then
293     clean || exit 1
294     exit 0
295 fi
296
297 type debootstrap
298 if [ $? -ne 0 ]; then
299     echo "'debootstrap' command is missing"
300     exit 1
301 fi
302
303 if [ -z "$path" ]; then
304     echo "'path' parameter is required"
305     exit 1
306 fi
307
308 if [ "$(id -u)" != "0" ]; then
309     echo "This script should be run as 'root'"
310     exit 1
311 fi
312
313 # detect rootfs
314 config="$path/config"
315 if grep -q '^lxc.rootfs' $config 2>/dev/null ; then
316     rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'`
317 else
318     rootfs=$path/rootfs
319 fi
320
321
322 install_debian $rootfs
323 if [ $? -ne 0 ]; then
324     echo "failed to install debian"
325     exit 1
326 fi
327
328 configure_debian $rootfs $name
329 if [ $? -ne 0 ]; then
330     echo "failed to configure debian for a container"
331     exit 1
332 fi
333
334 copy_configuration $path $rootfs $name
335 if [ $? -ne 0 ]; then
336     echo "failed write configuration file"
337     exit 1
338 fi
339
340 if [ ! -z $clean ]; then
341     clean || exit 1
342     exit 0
343 fi