]>
Commit | Line | Data |
---|---|---|
bad69158 | 1 | #!/bin/bash |
7afc269d | 2 | |
fb7460fe DL |
3 | # |
4 | # lxc: linux Container library | |
06388011 | 5 | |
fb7460fe DL |
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 | |
f1fa1a08 | 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
fb7460fe | 17 | # Lesser General Public License for more details. |
06388011 | 18 | |
fb7460fe DL |
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 | |
06388011 | 22 | |
9116540b | 23 | SUITE=${SUITE:-squeeze} |
49a630b8 | 24 | MIRROR=${MIRROR:-http://cdn.debian.net/debian} |
2a7c16dc | 25 | |
fb7460fe DL |
26 | configure_debian() |
27 | { | |
28 | rootfs=$1 | |
29 | hostname=$2 | |
30 | ||
4e0eb765 DB |
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 | ||
fb7460fe DL |
39 | # configure the inittab |
40 | cat <<EOF > $rootfs/etc/inittab | |
06388011 | 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 | |
b0a33c1e | 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 | |
6bf8daf9 SG |
57 | p6::ctrlaltdel:/sbin/init 6 |
58 | p0::powerfail:/sbin/init 0 | |
06388011 | 59 | EOF |
06388011 | 60 | |
fb7460fe DL |
61 | # disable selinux in debian |
62 | mkdir -p $rootfs/selinux | |
63 | echo 0 > $rootfs/selinux/enforce | |
06388011 | 64 | |
fb7460fe DL |
65 | # configure the network using the dhcp |
66 | cat <<EOF > $rootfs/etc/network/interfaces | |
67 | auto lo | |
68 | iface lo inet loopback | |
06388011 | 69 | |
fb7460fe DL |
70 | auto eth0 |
71 | iface eth0 inet dhcp | |
06388011 | 72 | EOF |
1846e71a | 73 | |
fb7460fe DL |
74 | # set the hostname |
75 | cat <<EOF > $rootfs/etc/hostname | |
76 | $hostname | |
77 | EOF | |
06388011 | 78 | |
fb7460fe | 79 | # reconfigure some services |
f1fa1a08 | 80 | if [ -z "$LANG" ]; then |
57f61aa7 | 81 | chroot $rootfs locale-gen en_US.UTF-8 UTF-8 |
f1fa1a08 DL |
82 | chroot $rootfs update-locale LANG=en_US.UTF-8 |
83 | else | |
57f61aa7 | 84 | chroot $rootfs locale-gen $LANG $(echo $LANG | cut -d. -f2) |
f1fa1a08 DL |
85 | chroot $rootfs update-locale LANG=$LANG |
86 | fi | |
06388011 | 87 | |
fb7460fe | 88 | # remove pointless services in a container |
7593bdfb | 89 | chroot $rootfs /usr/sbin/update-rc.d -f checkroot.sh remove |
fb7460fe DL |
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 | |
19d618b1 DL |
93 | |
94 | echo "root:root" | chroot $rootfs chpasswd | |
95 | echo "Root password is 'root', please change !" | |
96 | ||
97 | return 0 | |
06388011 | 98 | } |
99 | ||
f1ccde27 SH |
100 | cleanup() |
101 | { | |
102 | rm -rf $cache/partial-$SUITE-$arch | |
103 | rm -rf $cache/rootfs-$SUITE-$arch | |
104 | } | |
105 | ||
fb7460fe DL |
106 | download_debian() |
107 | { | |
108 | packages=\ | |
109 | ifupdown,\ | |
110 | locales,\ | |
111 | libui-dialog-perl,\ | |
112 | dialog,\ | |
3f16e26c | 113 | isc-dhcp-server,\ |
fb7460fe DL |
114 | netbase,\ |
115 | net-tools,\ | |
116 | iproute,\ | |
117 | openssh-server | |
118 | ||
119 | cache=$1 | |
120 | arch=$2 | |
121 | ||
f1ccde27 | 122 | trap cleanup EXIT SIGHUP SIGINT SIGTERM |
fb7460fe | 123 | # check the mini debian was not already downloaded |
2a7c16dc | 124 | mkdir -p "$cache/partial-$SUITE-$arch" |
fb7460fe | 125 | if [ $? -ne 0 ]; then |
2a7c16dc | 126 | echo "Failed to create '$cache/partial-$SUITE-$arch' directory" |
fb7460fe | 127 | return 1 |
81f6a40a RT |
128 | fi |
129 | ||
fb7460fe DL |
130 | # download a mini debian into a cache |
131 | echo "Downloading debian minimal ..." | |
132 | debootstrap --verbose --variant=minbase --arch=$arch \ | |
346645ef | 133 | --include=$packages \ |
49a630b8 | 134 | "$SUITE" "$cache/partial-$SUITE-$arch" $MIRROR |
fb7460fe DL |
135 | if [ $? -ne 0 ]; then |
136 | echo "Failed to download the rootfs, aborting." | |
137 | return 1 | |
c952d1b9 | 138 | fi |
cd830f33 | 139 | |
2a7c16dc | 140 | mv "$1/partial-$SUITE-$arch" "$1/rootfs-$SUITE-$arch" |
fb7460fe | 141 | echo "Download complete." |
f1ccde27 SH |
142 | trap EXIT |
143 | trap SIGINT | |
144 | trap SIGTERM | |
145 | trap SIGHUP | |
cd830f33 | 146 | |
fb7460fe | 147 | return 0 |
c952d1b9 | 148 | } |
bad69158 | 149 | |
fb7460fe | 150 | copy_debian() |
c952d1b9 | 151 | { |
fb7460fe DL |
152 | cache=$1 |
153 | arch=$2 | |
154 | rootfs=$3 | |
bad69158 | 155 | |
fb7460fe DL |
156 | # make a local copy of the minidebian |
157 | echo -n "Copying rootfs to $rootfs..." | |
6d8ac56b SH |
158 | mkdir -p $rootfs |
159 | rsync -a "$cache/rootfs-$SUITE-$arch"/ $rootfs/ || return 1 | |
fb7460fe | 160 | return 0 |
c952d1b9 | 161 | } |
162 | ||
fb7460fe DL |
163 | install_debian() |
164 | { | |
165 | cache="@LOCALSTATEDIR@/cache/lxc/debian" | |
166 | rootfs=$1 | |
167 | mkdir -p @LOCALSTATEDIR@/lock/subsys/ | |
168 | ( | |
add1d118 | 169 | flock -x 200 |
fb7460fe DL |
170 | if [ $? -ne 0 ]; then |
171 | echo "Cache repository is busy." | |
172 | return 1 | |
173 | fi | |
7afc269d | 174 | |
3930b745 | 175 | arch=$(dpkg --print-architecture) |
bad69158 | 176 | |
2a7c16dc DL |
177 | echo "Checking cache download in $cache/rootfs-$SUITE-$arch ... " |
178 | if [ ! -e "$cache/rootfs-$SUITE-$arch" ]; then | |
fb7460fe DL |
179 | download_debian $cache $arch |
180 | if [ $? -ne 0 ]; then | |
181 | echo "Failed to download 'debian base'" | |
182 | return 1 | |
b75afd90 | 183 | fi |
fb7460fe | 184 | fi |
c952d1b9 | 185 | |
fb7460fe DL |
186 | copy_debian $cache $arch $rootfs |
187 | if [ $? -ne 0 ]; then | |
188 | echo "Failed to copy rootfs" | |
189 | return 1 | |
190 | fi | |
c952d1b9 | 191 | |
fb7460fe | 192 | return 0 |
c952d1b9 | 193 | |
fb7460fe | 194 | ) 200>@LOCALSTATEDIR@/lock/subsys/lxc |
85cbaa06 | 195 | |
fb7460fe | 196 | return $? |
bad69158 | 197 | } |
198 | ||
fb7460fe DL |
199 | copy_configuration() |
200 | { | |
201 | path=$1 | |
202 | rootfs=$2 | |
16501521 | 203 | hostname=$3 |
bad69158 | 204 | |
fb7460fe DL |
205 | cat <<EOF >> $path/config |
206 | lxc.tty = 4 | |
207 | lxc.pts = 1024 | |
208 | lxc.rootfs = $rootfs | |
16501521 | 209 | lxc.utsname = $hostname |
f02ce27d SG |
210 | |
211 | # When using LXC with apparmor, uncomment the next line to run unconfined: | |
212 | #lxc.aa_profile = unconfined | |
213 | ||
fb7460fe DL |
214 | lxc.cgroup.devices.deny = a |
215 | # /dev/null and zero | |
216 | lxc.cgroup.devices.allow = c 1:3 rwm | |
217 | lxc.cgroup.devices.allow = c 1:5 rwm | |
218 | # consoles | |
219 | lxc.cgroup.devices.allow = c 5:1 rwm | |
220 | lxc.cgroup.devices.allow = c 5:0 rwm | |
221 | lxc.cgroup.devices.allow = c 4:0 rwm | |
222 | lxc.cgroup.devices.allow = c 4:1 rwm | |
223 | # /dev/{,u}random | |
224 | lxc.cgroup.devices.allow = c 1:9 rwm | |
225 | lxc.cgroup.devices.allow = c 1:8 rwm | |
226 | lxc.cgroup.devices.allow = c 136:* rwm | |
227 | lxc.cgroup.devices.allow = c 5:2 rwm | |
228 | # rtc | |
229 | lxc.cgroup.devices.allow = c 254:0 rwm | |
a7dff834 DL |
230 | |
231 | # mounts point | |
80a881b2 SH |
232 | lxc.mount.entry=proc proc proc nodev,noexec,nosuid 0 0 |
233 | lxc.mount.entry=sysfs sys sysfs defaults 0 0 | |
fb7460fe | 234 | EOF |
bad69158 | 235 | |
fb7460fe DL |
236 | if [ $? -ne 0 ]; then |
237 | echo "Failed to add configuration" | |
238 | return 1 | |
bad69158 | 239 | fi |
240 | ||
241 | return 0 | |
242 | } | |
243 | ||
fb7460fe DL |
244 | clean() |
245 | { | |
246 | cache="@LOCALSTATEDIR@/cache/lxc/debian" | |
bad69158 | 247 | |
fb7460fe | 248 | if [ ! -e $cache ]; then |
bad69158 | 249 | exit 0 |
250 | fi | |
251 | ||
252 | # lock, so we won't purge while someone is creating a repository | |
253 | ( | |
add1d118 | 254 | flock -x 200 |
fb7460fe | 255 | if [ $? != 0 ]; then |
bad69158 | 256 | echo "Cache repository is busy." |
257 | exit 1 | |
258 | fi | |
259 | ||
260 | echo -n "Purging the download cache..." | |
fb7460fe | 261 | rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1 |
bad69158 | 262 | exit 0 |
263 | ||
fb7460fe | 264 | ) 200>@LOCALSTATEDIR@/lock/subsys/lxc |
bad69158 | 265 | } |
266 | ||
fb7460fe DL |
267 | usage() |
268 | { | |
269 | cat <<EOF | |
270 | $1 -h|--help -p|--path=<path> --clean | |
271 | EOF | |
272 | return 0 | |
273 | } | |
274 | ||
275 | options=$(getopt -o hp:n:c -l help,path:,name:,clean -- "$@") | |
276 | if [ $? -ne 0 ]; then | |
277 | usage $(basename $0) | |
bad69158 | 278 | exit 1 |
fb7460fe DL |
279 | fi |
280 | eval set -- "$options" | |
281 | ||
282 | while true | |
283 | do | |
284 | case "$1" in | |
285 | -h|--help) usage $0 && exit 0;; | |
286 | -p|--path) path=$2; shift 2;; | |
287 | -n|--name) name=$2; shift 2;; | |
288 | -c|--clean) clean=$2; shift 2;; | |
289 | --) shift 1; break ;; | |
290 | *) break ;; | |
291 | esac | |
292 | done | |
293 | ||
294 | if [ ! -z "$clean" -a -z "$path" ]; then | |
295 | clean || exit 1 | |
296 | exit 0 | |
297 | fi | |
298 | ||
299 | type debootstrap | |
300 | if [ $? -ne 0 ]; then | |
301 | echo "'debootstrap' command is missing" | |
302 | exit 1 | |
303 | fi | |
304 | ||
305 | if [ -z "$path" ]; then | |
306 | echo "'path' parameter is required" | |
307 | exit 1 | |
308 | fi | |
309 | ||
310 | if [ "$(id -u)" != "0" ]; then | |
311 | echo "This script should be run as 'root'" | |
312 | exit 1 | |
c01d62f2 | 313 | fi |
bad69158 | 314 | |
fb7460fe DL |
315 | rootfs=$path/rootfs |
316 | ||
317 | install_debian $rootfs | |
318 | if [ $? -ne 0 ]; then | |
319 | echo "failed to install debian" | |
320 | exit 1 | |
321 | fi | |
322 | ||
323 | configure_debian $rootfs $name | |
324 | if [ $? -ne 0 ]; then | |
325 | echo "failed to configure debian for a container" | |
326 | exit 1 | |
327 | fi | |
328 | ||
16501521 | 329 | copy_configuration $path $rootfs $name |
fb7460fe DL |
330 | if [ $? -ne 0 ]; then |
331 | echo "failed write configuration file" | |
332 | exit 1 | |
333 | fi | |
334 | ||
335 | if [ ! -z $clean ]; then | |
336 | clean || exit 1 | |
337 | exit 0 | |
338 | fi |