Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1057 - (show 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 #!/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