Magellan Linux

Annotation of /trunk/lxc/lxc-magellan.sh

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1057 - (hide annotations) (download) (as text)
Tue Jul 13 14:47:25 2010 UTC (13 years, 10 months ago) by niro
File MIME type: application/x-sh
File size: 9102 byte(s)
lxc template script

1 niro 1057 #!/bin/bash
2    
3     #
4     # lxc: linux Container library
5    
6     # Authors:
7     # Niels Rogalla <niro@magellan-linux.de>
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     die() { echo "ERROR: $@"; exit 1; }
24    
25     configure_magellan()
26     {
27     local rootfs="$1"
28     local hostname="$2"
29    
30     echo "Setting up rootfs..."
31    
32     # fix locales first
33     if [[ -z ${LANG} ]] && [[ -z ${LC_ALL} ]]
34     then
35     sed -i "s:^#\(en_US..*\):\1:g" ${rootfs}/etc/locale.gen
36     LC_ALL=C chroot ${rootfs} /usr/sbin/locale-gen
37     elif [[ ! -z ${LANG} ]]
38     then
39     sed -i "s:^#\(${LANG}\):\1:g" ${rootfs}/etc/locale.gen
40     echo "LANG=${LANG}" > ${rootfs}/etc/env.d/01locale
41     LC_ALL=C chroot ${rootfs} /usr/sbin/locale-gen
42     LC_ALL=C chroot ${rootfs} /sbin/env-rebuild
43     elif [[ ! -z ${LC_ALL} ]]
44     then
45     sed -i "s:^#\(${LC_ALL}\):\1:g" ${rootfs}/etc/locale.gen
46     echo "LC_ALL=${LC_ALL}" > ${rootfs}/etc/env.d/01locale
47     LC_ALL=C chroot ${rootfs} /usr/sbin/locale-gen
48     LC_ALL=C chroot ${rootfs} /sbin/env-rebuild
49     fi
50    
51     # configure the inittab
52     cat <<EOF > ${rootfs}/etc/inittab
53     id:3:initdefault:
54     si::sysinit:/etc/rc.d/init.d/rc sysinit
55     l0:0:wait:/etc/rc.d/init.d/rc 0
56     l1:S1:wait:/etc/rc.d/init.d/rc 1
57     l2:2:wait:/etc/rc.d/init.d/rc 2
58     l3:3:wait:/etc/rc.d/init.d/rc 3
59     l4:4:wait:/etc/rc.d/init.d/rc 4
60     l5:5:wait:/etc/rc.d/init.d/rc 5
61     l6:6:wait:/etc/rc.d/init.d/rc 6
62     su:S016:once:/sbin/sulogin
63     1:2345:respawn:/sbin/agetty console 38400
64     2:2345:respawn:/sbin/agetty tty2 38400 linux
65     3:2345:respawn:/sbin/agetty tty3 38400 linux
66     4:2345:respawn:/sbin/agetty tty4 38400 linux
67     5:2345:respawn:/sbin/agetty tty5 38400 linux
68     6:2345:respawn:/sbin/agetty tty6 38400 linux
69     x:a:once:/etc/X11/startxdm
70     EOF
71    
72     # configure the network using dhcp
73     cat <<EOF > ${rootfs}/etc/conf.d/net.eth0
74     ONBOOT="yes"
75     NETWORKING="dhcp"
76     EOF
77    
78     # set the hostname
79     cat <<EOF > ${rootfs}/etc/hostname
80     ${hostname}
81     EOF
82    
83     # remove /, /boot, swap from fstab (\s = space)
84     sed -i -e '/\s\/\s/d' -e '/\s\/boot\s/d' -e '/\sswap\s/d' ${rootfs}/etc/fstab
85    
86     # remove pointless services in a container
87     chroot ${rootfs} /sbin/rc-config del checkfs
88     chroot ${rootfs} /sbin/rc-config del setclock
89    
90     #echo "root:foobar" | chroot ${rootfs} chpasswd
91     chroot ${rootfs} usermod -p $(openssl passwd -1 foobar) root
92     echo "Root password is 'foobar', please change!"
93    
94     # create missing device nodes
95     [[ ! -e ${rootfs}/dev/null ]] && mknod -m 666 ${rootfs}/dev/null c 1 3
96     [[ ! -e ${rootfs}/dev/zero ]] && mknod -m 666 ${rootfs}/dev/zero c 1 5
97     [[ ! -e ${rootfs}/dev/random ]] && mknod -m 666 ${rootfs}/dev/random c 1 8
98     [[ ! -e ${rootfs}/dev/urandom ]] && mknod -m 666 ${rootfs}/dev/urandom c 1 9
99     [[ ! -e ${rootfs}/dev/pts ]] && mkdir -m 755 ${rootfs}/dev/pts
100     [[ ! -e ${rootfs}/dev/shm ]] && mkdir -m 1777 ${rootfs}/dev/shm
101     [[ ! -e ${rootfs}/dev/tty ]] && mknod -m 666 ${rootfs}/dev/tty c 5 0
102     [[ ! -e ${rootfs}/dev/console ]] && mknod -m 600 ${rootfs}/dev/console c 5 1
103     [[ ! -e ${rootfs}/dev/tty0 ]] && mknod -m 666 ${rootfs}/dev/tty0 c 4 0
104     [[ ! -e ${rootfs}/dev/tty1 ]] && mknod -m 666 ${rootfs}/dev/tty1 c 4 1
105     [[ ! -e ${rootfs}/dev/tty2 ]] && mknod -m 666 ${rootfs}/dev/tty2 c 4 2
106     [[ ! -e ${rootfs}/dev/tty3 ]] && mknod -m 666 ${rootfs}/dev/tty3 c 4 3
107     [[ ! -e ${rootfs}/dev/tty4 ]] && mknod -m 666 ${rootfs}/dev/tty4 c 4 4
108     [[ ! -e ${rootfs}/dev/tty5 ]] && mknod -m 666 ${rootfs}/dev/tty5 c 4 5
109     [[ ! -e ${rootfs}/dev/tty6 ]] && mknod -m 666 ${rootfs}/dev/tty6 c 4 6
110     [[ ! -e ${rootfs}/dev/full ]] && mknod -m 666 ${rootfs}/dev/full c 1 7
111     [[ ! -e ${rootfs}/dev/initctl ]] && mknod -m 600 ${rootfs}/dev/initctl p
112     [[ ! -e ${rootfs}/dev/ptmx ]] && mknod -m 666 ${rootfs}/dev/ptmx c 5 2
113    
114     return 0
115     }
116    
117     download_magellan()
118     {
119     local cache="$1"
120     local arch="$2"
121     local distribution="unstable"
122     local mageprofile="$(basename $(readlink /etc/mage-profile))"
123     local extrapackages="dialog iproute2 openssh"
124    
125     # check the mini magellan was not already downloaded
126     mkdir -p "${cache}/partial-${arch}"
127     if [ $? -ne 0 ]
128     then
129     echo "Failed to create '${cache}/partial-${arch}' directory"
130     return 1
131     fi
132    
133     # setup magerc
134     cat <<EOF > ${cache}/partial-${arch}/mage.rc.bootstrap
135     ARCH="${arch}"
136     MAGE_DISTRIBUTION="${distribution}"
137    
138     MAGEDIR="/usr/mage"
139     PKGDIR="/var/cache/mage/packages"
140     BUILDDIR="/var/tmp/magebuild"
141     INSTALLDB="/var/db/mage"
142     VIRTUALDB_DEFAULTS="/etc/mage-profile/virtuals.defaults"
143     VIRTUALDB_FILE="\${INSTALLDB}/virtuals"
144    
145     VERBOSE="off"
146     MAGEDEBUG="off"
147    
148     MIRRORS="http://magellan-linux.de/magellan/magellan-dev/svn/\${MAGE_DISTRIBUTION}"
149     RSYNC="rsync://magellan-linux.de/mage-svn"
150    
151     PACKAGES_SERVER_PATH="packages/\${ARCH}"
152     MAGE_UNINSTALL_TIMEOUT=0
153     EOF
154    
155     # download a mini magellan into a cache
156     echo "Downloading magellan minimal ..."
157     mage-bootstrap --profile ${mageprofile} --root ${cache}/partial-${arch} --magerc ${cache}/partial-${arch}/mage.rc.bootstrap --update-tarball
158     if [ $? -ne 0 ]
159     then
160     echo "Failed to download the rootfs, aborting."
161     return 1
162     fi
163    
164     # install extra packages
165     for pkg in ${extrapackages}
166     do
167     MROOT=${cache}/partial-${arch} mage install ${pkg}
168     if [ $? -ne 0 ]
169     then
170     echo "Failed to install package ${pkg}, aborting."
171     return 1
172     fi
173     done
174    
175     mv "${cache}/partial-${arch}" "${cache}/rootfs-${arch}"
176     echo "Download complete."
177    
178     return 0
179     }
180    
181     copy_magellan()
182     {
183     local cache="$1"
184     local arch="$2"
185     local rootfs="$3"
186    
187     # make a local copy of the minimagellan
188     echo "Copying rootfs to ${rootfs}..."
189     cp -a ${cache}/rootfs-${arch} ${rootfs} || return 1
190     return 0
191     }
192    
193     install_magellan()
194     {
195     local cache="/var/cache/lxc/magellan"
196     local rootfs="$1"
197    
198     mkdir -p /var/lock/subsys/
199     (
200     flock -n -x 200
201     if [ $? -ne 0 ]
202     then
203     echo "Cache repository is busy."
204     return 1
205     fi
206    
207     arch=$(uname -m)
208     echo "Checking cache download in ${cache}/rootfs-${arch} ... "
209     if [ ! -e "${cache}/rootfs-${arch}" ]
210     then
211     download_magellan "${cache}" "${arch}"
212     if [ $? -ne 0 ]
213     then
214     echo "Failed to download 'magellan base'"
215     return 1
216     fi
217     fi
218    
219     install -d $(dirname ${rootfs})
220     copy_magellan "${cache}" "${arch}" "${rootfs}"
221     if [ $? -ne 0 ]; then
222     echo "Failed to copy rootfs"
223     return 1
224     fi
225    
226     return 0
227    
228     ) 200>/var/lock/subsys/lxc
229    
230     return $?
231     }
232    
233     copy_configuration()
234     {
235     local path="$1"
236     local rootfs="$2"
237     local name="$3"
238    
239     cat <<EOF >> ${path}/config
240     lxc.tty = 4
241     lxc.pts = 1024
242     lxc.rootfs = ${rootfs}
243     lxc.cgroup.devices.deny = a
244     # /dev/null and zero
245     lxc.cgroup.devices.allow = c 1:3 rwm
246     lxc.cgroup.devices.allow = c 1:5 rwm
247     # consoles
248     lxc.cgroup.devices.allow = c 5:1 rwm
249     lxc.cgroup.devices.allow = c 5:0 rwm
250     lxc.cgroup.devices.allow = c 4:0 rwm
251     lxc.cgroup.devices.allow = c 4:1 rwm
252     # /dev/{,u}random
253     lxc.cgroup.devices.allow = c 1:9 rwm
254     lxc.cgroup.devices.allow = c 1:8 rwm
255     lxc.cgroup.devices.allow = c 136:* rwm
256     lxc.cgroup.devices.allow = c 5:2 rwm
257     # rtc
258     lxc.cgroup.devices.allow = c 254:0 rwm
259    
260     # mounts point
261     lxc.mount.entry=proc ${rootfs}/proc proc nodev,noexec,nosuid 0 0
262     lxc.mount.entry=devpts ${rootfs}/dev/pts devpts defaults 0 0
263     lxc.mount.entry=sysfs ${rootfs}/sys sysfs defaults 0 0
264     EOF
265    
266     if [ $? -ne 0 ]
267     then
268     echo "Failed to add configuration"
269     return 1
270     fi
271    
272     return 0
273     }
274    
275     clean()
276     {
277     local cache="/var/cache/lxc/magellan"
278    
279     if [ ! -e ${cache} ]
280     then
281     exit 0
282     fi
283    
284     # lock, so we won't purge while someone is creating a repository
285     (
286     flock -n -x 200
287     if [ $? != 0 ]; then
288     echo "Cache repository is busy."
289     exit 1
290     fi
291    
292     echo -n "Purging the download cache..."
293     rm --preserve-root --one-file-system -rf ${cache} && echo "Done." || exit 1
294     exit 0
295     ) 200>/var/lock/subsys/lxc
296     }
297    
298     usage()
299     {
300     cat <<EOF
301     $1 -h|--help -p|--path=<path> --clean
302     EOF
303     return 0
304     }
305    
306     options=$(getopt -o hp:n:c -l help,path:,name:,clean -- "$@")
307     if [ $? -ne 0 ]
308     then
309     usage $(basename $0)
310     exit 1
311     fi
312     eval set -- "${options}"
313    
314     while true
315     do
316     case "$1" in
317     -h|--help) usage $0 && exit 0;;
318     -p|--path) path=$2; shift 2;;
319     -n|--name) name=$2; shift 2;;
320     -c|--clean) clean=$2; shift 2;;
321     --) shift 1; break ;;
322     *) break ;;
323     esac
324     done
325    
326     if [ ! -z "${clean}" -a -z "${path}" ]
327     then
328     clean || exit 1
329     exit 0
330     fi
331    
332     # sanity checks
333     [ "$(id -u)" != "0" ] && die "This script should be run as 'root'"
334     type mage-bootstrap || die "'mage-bootstrap' command is missing"
335     [ -z "${path}" ] && die "'path' parameter is required"
336    
337     rootfs=${path}/rootfs
338    
339     install_magellan ${rootfs} || die "failed to install magellan"
340     configure_magellan ${rootfs} ${name} || die "failed to configure debian for a container"
341     copy_configuration ${path} ${rootfs} || die "failed write configuration file"
342    
343     if [ ! -z ${clean} ]
344     then
345     clean || exit 1
346     exit 0
347     fi