1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
1 |
#!/bin/bash
|
2 |
||
3 |
#
|
|
4 |
# template script for generating ubuntu container for LXC
|
|
5 |
#
|
|
6 |
# This script consolidates and extends the existing lxc ubuntu scripts
|
|
7 |
#
|
|
8 |
||
9 |
# Copyright © 2011 Serge Hallyn <serge.hallyn@canonical.com>
|
|
10 |
# Copyright © 2010 Wilhelm Meier
|
|
11 |
# Author: Wilhelm Meier <wilhelm.meier@fh-kl.de>
|
|
12 |
#
|
|
13 |
# This program is free software; you can redistribute it and/or modify
|
|
14 |
# it under the terms of the GNU General Public License version 2, as
|
|
15 |
# published by the Free Software Foundation.
|
|
16 |
||
17 |
# This program is distributed in the hope that it will be useful,
|
|
18 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
19 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
20 |
# GNU General Public License for more details.
|
|
21 |
||
22 |
# You should have received a copy of the GNU General Public License along
|
|
23 |
# with this program; if not, write to the Free Software Foundation, Inc.,
|
|
24 |
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
25 |
#
|
|
26 |
||
27 |
if [ -r /etc/default/lxc ]; then |
|
28 |
. /etc/default/lxc |
|
29 |
fi
|
|
30 |
||
31 |
configure_ubuntu()
|
|
32 |
{
|
|
33 |
rootfs=$1 |
|
34 |
hostname=$2 |
|
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
35 |
release=$3 |
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
36 |
|
37 |
# configure the network using the dhcp
|
|
38 |
cat <<EOF > $rootfs/etc/network/interfaces
|
|
39 |
auto lo
|
|
40 |
iface lo inet loopback
|
|
41 |
||
42 |
auto eth0
|
|
43 |
iface eth0 inet dhcp
|
|
44 |
EOF
|
|
45 |
||
46 |
# set the hostname
|
|
47 |
cat <<EOF > $rootfs/etc/hostname
|
|
48 |
$hostname
|
|
49 |
EOF
|
|
50 |
# set minimal hosts
|
|
51 |
cat <<EOF > $rootfs/etc/hosts
|
|
52 |
127.0.0.1 localhost $hostname
|
|
53 |
EOF
|
|
54 |
||
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
55 |
if [ "$release" = "precise" ]; then |
56 |
group="sudo" |
|
57 |
else
|
|
58 |
group="admin" |
|
59 |
||
60 |
# suppress log level output for udev
|
|
61 |
sed -i "s/=\"err\"/=0/" $rootfs/etc/udev/udev.conf |
|
62 |
||
63 |
# remove jobs for consoles 5 and 6 since we only create 4 consoles in
|
|
64 |
# this template
|
|
65 |
rm -f $rootfs/etc/init/tty{5,6}.conf |
|
66 |
fi
|
|
67 |
||
68 |
chroot $rootfs groupadd --system $group >/dev/null 2>&1 || true |
|
69 |
chroot $rootfs useradd --create-home -s /bin/bash -G $group ubuntu |
|
70 |
echo "ubuntu:ubuntu" | chroot $rootfs chpasswd |
|
71 |
if [ -n "$auth_key" -a -f "$auth_key" ]; then |
|
72 |
u_path="/home/ubuntu/.ssh" |
|
73 |
root_u_path="$rootfs/$u_path" |
|
74 |
mkdir -p $root_u_path
|
|
75 |
cp $auth_key "$root_u_path/authorized_keys" |
|
76 |
chroot $rootfs chown -R ubuntu: "$u_path" |
|
77 |
||
78 |
echo "Inserted SSH public key from $auth_key into /home/ubuntu/.ssh/authorized_keys" |
|
79 |
fi
|
|
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
80 |
return 0 |
81 |
}
|
|
82 |
||
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
83 |
write_sourceslist()
|
84 |
{
|
|
85 |
# $1 => path to the rootfs
|
|
86 |
# $2 => architecture we want to add
|
|
87 |
# $3 => whether to use the multi-arch syntax or not
|
|
88 |
||
89 |
case $2 in |
|
90 |
amd64|i386) |
|
91 |
MIRROR=${MIRROR:-http://archive.ubuntu.com/ubuntu} |
|
92 |
SECURITY_MIRROR=${SECURITY_MIRROR:-http://security.ubuntu.com/ubuntu} |
|
93 |
;;
|
|
94 |
sparc)
|
|
95 |
case $SUITE in |
|
96 |
gutsy)
|
|
97 |
MIRROR=${MIRROR:-http://archive.ubuntu.com/ubuntu} |
|
98 |
SECURITY_MIRROR=${SECURITY_MIRRORMIRROR:-http://security.ubuntu.com/ubuntu} |
|
99 |
;;
|
|
100 |
*)
|
|
101 |
MIRROR=${MIRROR:-http://ports.ubuntu.com/ubuntu-ports} |
|
102 |
SECURITY_MIRROR=${SECURITY_MIRROR:-http://ports.ubuntu.com/ubuntu-ports} |
|
103 |
;;
|
|
104 |
esac
|
|
105 |
;;
|
|
106 |
*)
|
|
107 |
MIRROR=${MIRROR:-http://ports.ubuntu.com/ubuntu-ports} |
|
108 |
SECURITY_MIRROR=${SECURITY_MIRROR:-http://ports.ubuntu.com/ubuntu-ports} |
|
109 |
;;
|
|
110 |
esac
|
|
111 |
if [ -n "$3" ]; then |
|
112 |
cat >> "$1/etc/apt/sources.list" << EOF |
|
113 |
deb [arch=$2] $MIRROR ${release} main restricted universe multiverse
|
|
114 |
deb [arch=$2] $MIRROR ${release}-updates main restricted universe multiverse
|
|
115 |
deb [arch=$2] $SECURITY_MIRROR ${release}-security main restricted universe multiverse
|
|
116 |
EOF
|
|
117 |
else
|
|
118 |
cat >> "$1/etc/apt/sources.list" << EOF |
|
119 |
deb $MIRROR ${release} main restricted universe multiverse
|
|
120 |
deb $MIRROR ${release}-updates main restricted universe multiverse
|
|
121 |
deb $SECURITY_MIRROR ${release}-security main restricted universe multiverse
|
|
122 |
EOF
|
|
123 |
fi
|
|
124 |
}
|
|
125 |
||
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
126 |
download_ubuntu()
|
127 |
{
|
|
128 |
cache=$1 |
|
129 |
arch=$2 |
|
130 |
release=$3 |
|
131 |
||
132 |
if [ $release = "lucid" ]; then |
|
133 |
packages=dialog,apt,apt-utils,resolvconf,iproute,inetutils-ping,vim,dhcp3-client,ssh,lsb-release,gnupg |
|
134 |
elif [ $release = "maverick" ]; then |
|
135 |
packages=dialog,apt,apt-utils,resolvconf,iproute,inetutils-ping,vim,dhcp3-client,ssh,lsb-release,gnupg,netbase |
|
136 |
elif [ $release = "natty" ]; then |
|
137 |
packages=dialog,apt,apt-utils,resolvconf,iproute,inetutils-ping,vim,isc-dhcp-client,isc-dhcp-common,ssh,lsb-release,gnupg,netbase |
|
138 |
else
|
|
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
139 |
packages=dialog,apt,apt-utils,iproute,inetutils-ping,vim,isc-dhcp-client,isc-dhcp-common,ssh,lsb-release,gnupg,netbase,ubuntu-keyring |
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
140 |
fi
|
141 |
echo "installing packages: $packages" |
|
142 |
||
143 |
# check the mini ubuntu was not already downloaded
|
|
144 |
mkdir -p "$cache/partial-$arch" |
|
145 |
if [ $? -ne 0 ]; then |
|
146 |
echo "Failed to create '$cache/partial-$arch' directory" |
|
147 |
return 1 |
|
148 |
fi
|
|
149 |
||
150 |
# download a mini ubuntu into a cache
|
|
151 |
echo "Downloading ubuntu $release minimal ..." |
|
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
152 |
if [ -n "$(which qemu-debootstrap)" ]; then |
153 |
qemu-debootstrap --verbose --components=main,universe --arch=$arch --include=$packages $release $cache/partial-$arch $MIRROR |
|
154 |
else
|
|
155 |
debootstrap --verbose --components=main,universe --arch=$arch --include=$packages $release $cache/partial-$arch $MIRROR |
|
156 |
fi
|
|
157 |
||
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
158 |
if [ $? -ne 0 ]; then |
159 |
echo "Failed to download the rootfs, aborting." |
|
160 |
return 1 |
|
161 |
fi
|
|
162 |
||
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
163 |
echo "Installing updates" |
164 |
if [ -z "$MIRROR" ]; then |
|
165 |
MIRROR="http://archive.ubuntu.com/ubuntu" |
|
166 |
fi
|
|
167 |
cat >> "$1/partial-${arch}/etc/apt/sources.list" << EOF |
|
168 |
deb $MIRROR ${release}-updates main universe
|
|
169 |
deb http://security.ubuntu.com/ubuntu ${release}-security main universe
|
|
170 |
EOF
|
|
171 |
chroot "$1/partial-${arch}" apt-get update |
|
172 |
if [ $? -ne 0 ]; then |
|
173 |
echo "Failed to update the apt cache" |
|
174 |
return 1 |
|
175 |
fi
|
|
176 |
cat > "$1/partial-${arch}"/usr/sbin/policy-rc.d << EOF |
|
177 |
#!/bin/sh
|
|
178 |
exit 101
|
|
179 |
EOF
|
|
180 |
chmod +x "$1/partial-${arch}"/usr/sbin/policy-rc.d |
|
181 |
||
182 |
chroot "$1/partial-${arch}" apt-get dist-upgrade -y |
|
183 |
ret=$? |
|
184 |
||
185 |
rm -f "$1/partial-${arch}"/usr/sbin/policy-rc.d |
|
186 |
if [ $ret -ne 0 ]; then |
|
187 |
echo "Failed to upgrade the cache" |
|
188 |
return 1 |
|
189 |
fi
|
|
190 |
||
191 |
# Serge isn't sure whether we should avoid doing this when
|
|
192 |
# $release == `distro-info -d`
|
|
193 |
echo "Installing updates" |
|
194 |
> $cache/partial-$arch/etc/apt/sources.list |
|
195 |
write_sourceslist $cache/partial-$arch/ $arch |
|
196 |
||
197 |
chroot "$1/partial-${arch}" apt-get update |
|
198 |
if [ $? -ne 0 ]; then |
|
199 |
echo "Failed to update the apt cache" |
|
200 |
return 1 |
|
201 |
fi
|
|
202 |
cat > "$1/partial-${arch}"/usr/sbin/policy-rc.d << EOF |
|
203 |
#!/bin/sh
|
|
204 |
exit 101
|
|
205 |
EOF
|
|
206 |
chmod +x "$1/partial-${arch}"/usr/sbin/policy-rc.d |
|
207 |
||
208 |
lxc-unshare -s MOUNT -- chroot "$1/partial-${arch}" apt-get dist-upgrade -y |
|
209 |
ret=$? |
|
210 |
rm -f "$1/partial-${arch}"/usr/sbin/policy-rc.d |
|
211 |
||
212 |
if [ $ret -ne 0 ]; then |
|
213 |
echo "Failed to upgrade the cache" |
|
214 |
return 1 |
|
215 |
fi
|
|
216 |
||
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
217 |
mv "$1/partial-$arch" "$1/rootfs-$arch" |
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
218 |
echo "Download complete" |
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
219 |
return 0 |
220 |
}
|
|
221 |
||
222 |
copy_ubuntu()
|
|
223 |
{
|
|
224 |
cache=$1 |
|
225 |
arch=$2 |
|
226 |
rootfs=$3 |
|
227 |
||
228 |
# make a local copy of the miniubuntu
|
|
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
229 |
echo "Copying rootfs to $rootfs ..." |
230 |
mkdir -p $rootfs
|
|
231 |
rsync -a $cache/rootfs-$arch/ $rootfs/ || return 1 |
|
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
232 |
return 0 |
233 |
}
|
|
234 |
||
235 |
install_ubuntu()
|
|
236 |
{
|
|
237 |
rootfs=$1 |
|
238 |
release=$2 |
|
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
239 |
flushcache=$3 |
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
240 |
cache="/var/cache/lxc/$release" |
241 |
mkdir -p /var/lock/subsys/ |
|
242 |
(
|
|
243 |
flock -n -x 200
|
|
244 |
if [ $? -ne 0 ]; then |
|
245 |
echo "Cache repository is busy." |
|
246 |
return 1 |
|
247 |
fi
|
|
248 |
||
249 |
||
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
250 |
if [ $flushcache -eq 1 ]; then |
251 |
echo "Flushing cache..." |
|
252 |
rm -rf "$cache/partial-$arch" |
|
253 |
rm -rf "$cache/rootfs-$arch" |
|
254 |
fi
|
|
255 |
||
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
256 |
echo "Checking cache download in $cache/rootfs-$arch ... " |
257 |
if [ ! -e "$cache/rootfs-$arch" ]; then |
|
258 |
download_ubuntu $cache $arch $release |
|
259 |
if [ $? -ne 0 ]; then |
|
260 |
echo "Failed to download 'ubuntu $release base'" |
|
261 |
return 1 |
|
262 |
fi
|
|
263 |
fi
|
|
264 |
||
265 |
echo "Copy $cache/rootfs-$arch to $rootfs ... " |
|
266 |
copy_ubuntu $cache $arch $rootfs |
|
267 |
if [ $? -ne 0 ]; then |
|
268 |
echo "Failed to copy rootfs" |
|
269 |
return 1 |
|
270 |
fi
|
|
271 |
||
272 |
return 0 |
|
273 |
||
274 |
) 200>/var/lock/subsys/lxc |
|
275 |
||
276 |
return $? |
|
277 |
}
|
|
278 |
||
279 |
copy_configuration()
|
|
280 |
{
|
|
281 |
path=$1 |
|
282 |
rootfs=$2 |
|
283 |
name=$3 |
|
284 |
arch=$4 |
|
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
285 |
release=$5 |
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
286 |
|
287 |
if [ $arch = "i386" ]; then |
|
288 |
arch="i686" |
|
289 |
fi
|
|
290 |
||
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
291 |
ttydir="" |
292 |
if [ $release = "precise" ]; then |
|
293 |
ttydir=" lxc" |
|
294 |
fi
|
|
295 |
||
296 |
# if there is exactly one veth network entry, make sure it has an
|
|
297 |
# associated hwaddr.
|
|
298 |
nics=`grep -e '^lxc\.network\.type[ \t]*=[ \t]*veth' $path/config | wc -l` |
|
299 |
if [ $nics -eq 1 ]; then |
|
300 |
grep -q "^lxc.network.hwaddr" $path/config || cat <<EOF >> $path/config |
|
301 |
lxc.network.hwaddr= 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')
|
|
302 |
EOF
|
|
303 |
fi
|
|
304 |
||
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
305 |
cat <<EOF >> $path/config
|
306 |
lxc.utsname = $name
|
|
307 |
||
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
308 |
lxc.devttydir = $ttydir
|
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
309 |
lxc.tty = 4
|
310 |
lxc.pts = 1024
|
|
311 |
lxc.rootfs = $rootfs
|
|
312 |
lxc.mount = $path/fstab
|
|
313 |
lxc.arch = $arch
|
|
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
314 |
lxc.cap.drop = sys_module mac_admin mac_override
|
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
315 |
|
316 |
lxc.cgroup.devices.deny = a
|
|
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
317 |
# Allow any mknod (but not using the node)
|
318 |
lxc.cgroup.devices.allow = c *:* m
|
|
319 |
lxc.cgroup.devices.allow = b *:* m
|
|
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
320 |
# /dev/null and zero
|
321 |
lxc.cgroup.devices.allow = c 1:3 rwm
|
|
322 |
lxc.cgroup.devices.allow = c 1:5 rwm
|
|
323 |
# consoles
|
|
324 |
lxc.cgroup.devices.allow = c 5:1 rwm
|
|
325 |
lxc.cgroup.devices.allow = c 5:0 rwm
|
|
326 |
#lxc.cgroup.devices.allow = c 4:0 rwm
|
|
327 |
#lxc.cgroup.devices.allow = c 4:1 rwm
|
|
328 |
# /dev/{,u}random
|
|
329 |
lxc.cgroup.devices.allow = c 1:9 rwm
|
|
330 |
lxc.cgroup.devices.allow = c 1:8 rwm
|
|
331 |
lxc.cgroup.devices.allow = c 136:* rwm
|
|
332 |
lxc.cgroup.devices.allow = c 5:2 rwm
|
|
333 |
# rtc
|
|
334 |
lxc.cgroup.devices.allow = c 254:0 rwm
|
|
335 |
#fuse
|
|
336 |
lxc.cgroup.devices.allow = c 10:229 rwm
|
|
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
337 |
#tun
|
338 |
lxc.cgroup.devices.allow = c 10:200 rwm
|
|
339 |
#full
|
|
340 |
lxc.cgroup.devices.allow = c 1:7 rwm
|
|
341 |
#hpet
|
|
342 |
lxc.cgroup.devices.allow = c 10:228 rwm
|
|
343 |
#kvm
|
|
344 |
lxc.cgroup.devices.allow = c 10:232 rwm
|
|
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
345 |
EOF
|
346 |
||
347 |
cat <<EOF > $path/fstab
|
|
348 |
proc $rootfs/proc proc nodev,noexec,nosuid 0 0
|
|
349 |
sysfs $rootfs/sys sysfs defaults 0 0
|
|
350 |
EOF
|
|
351 |
||
352 |
if [ $? -ne 0 ]; then |
|
353 |
echo "Failed to add configuration" |
|
354 |
return 1 |
|
355 |
fi
|
|
356 |
||
357 |
return 0 |
|
358 |
}
|
|
359 |
||
360 |
trim()
|
|
361 |
{
|
|
362 |
rootfs=$1 |
|
363 |
release=$2 |
|
364 |
||
365 |
# provide the lxc service
|
|
366 |
cat <<EOF > $rootfs/etc/init/lxc.conf
|
|
367 |
# fake some events needed for correct startup other services
|
|
368 |
||
369 |
description "Container Upstart"
|
|
370 |
||
371 |
start on startup
|
|
372 |
||
373 |
script
|
|
374 |
rm -rf /var/run/*.pid
|
|
375 |
rm -rf /var/run/network/*
|
|
376 |
/sbin/initctl emit stopped JOB=udevtrigger --no-wait
|
|
377 |
/sbin/initctl emit started JOB=udev --no-wait
|
|
378 |
end script
|
|
379 |
EOF
|
|
380 |
||
381 |
# fix buggus runlevel with sshd
|
|
382 |
cat <<EOF > $rootfs/etc/init/ssh.conf
|
|
383 |
# ssh - OpenBSD Secure Shell server
|
|
384 |
#
|
|
385 |
# The OpenSSH server provides secure shell access to the system.
|
|
386 |
||
387 |
description "OpenSSH server"
|
|
388 |
||
389 |
start on filesystem
|
|
390 |
stop on runlevel [!2345]
|
|
391 |
||
392 |
expect fork
|
|
393 |
respawn
|
|
394 |
respawn limit 10 5
|
|
395 |
umask 022
|
|
396 |
# replaces SSHD_OOM_ADJUST in /etc/default/ssh
|
|
397 |
oom never
|
|
398 |
||
399 |
pre-start script
|
|
400 |
test -x /usr/sbin/sshd || { stop; exit 0; }
|
|
401 |
test -e /etc/ssh/sshd_not_to_be_run && { stop; exit 0; }
|
|
402 |
test -c /dev/null || { stop; exit 0; }
|
|
403 |
||
404 |
mkdir -p -m0755 /var/run/sshd
|
|
405 |
end script
|
|
406 |
||
407 |
# if you used to set SSHD_OPTS in /etc/default/ssh, you can change the
|
|
408 |
# 'exec' line here instead
|
|
409 |
exec /usr/sbin/sshd
|
|
410 |
EOF
|
|
411 |
||
412 |
cat <<EOF > $rootfs/etc/init/console.conf
|
|
413 |
# console - getty
|
|
414 |
#
|
|
415 |
# This service maintains a console on tty1 from the point the system is
|
|
416 |
# started until it is shut down again.
|
|
417 |
||
418 |
start on stopped rc RUNLEVEL=[2345]
|
|
419 |
stop on runlevel [!2345]
|
|
420 |
||
421 |
respawn
|
|
422 |
exec /sbin/getty -8 38400 /dev/console
|
|
423 |
EOF
|
|
424 |
||
425 |
cat <<EOF > $rootfs/lib/init/fstab
|
|
426 |
# /lib/init/fstab: cleared out for bare-bones lxc
|
|
427 |
EOF
|
|
428 |
||
429 |
# reconfigure some services
|
|
430 |
if [ -z "$LANG" ]; then |
|
431 |
chroot $rootfs locale-gen en_US.UTF-8
|
|
432 |
chroot $rootfs update-locale LANG=en_US.UTF-8 |
|
433 |
else
|
|
434 |
chroot $rootfs locale-gen $LANG |
|
435 |
chroot $rootfs update-locale LANG=$LANG |
|
436 |
fi
|
|
437 |
||
438 |
# remove pointless services in a container
|
|
439 |
chroot $rootfs /usr/sbin/update-rc.d -f ondemand remove
|
|
440 |
||
441 |
chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls u*.conf); do mv $f $f.orig; done' |
|
442 |
chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls tty[2-9].conf); do mv $f $f.orig; done' |
|
443 |
chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls plymouth*.conf); do mv $f $f.orig; done' |
|
444 |
chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls hwclock*.conf); do mv $f $f.orig; done' |
|
445 |
chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls module*.conf); do mv $f $f.orig; done' |
|
446 |
||
447 |
# if this isn't lucid, then we need to twiddle the network upstart bits :(
|
|
448 |
if [ $release != "lucid" ]; then |
|
449 |
sed -i 's/^.*emission handled.*$/echo Emitting lo/' $rootfs/etc/network/if-up.d/upstart |
|
450 |
fi
|
|
451 |
}
|
|
452 |
||
453 |
post_process()
|
|
454 |
{
|
|
455 |
rootfs=$1 |
|
456 |
release=$2 |
|
457 |
trim_container=$3 |
|
458 |
||
459 |
if [ $trim_container -eq 1 ]; then |
|
460 |
trim $rootfs $release |
|
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
461 |
elif [ $release = "lucid" -o $release = "maverick" -o $release = "natty" \ |
462 |
-o $release = "oneiric" ]; then |
|
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
463 |
# for lucid and maverick, if not trimming, then add the ubuntu-virt
|
464 |
# ppa and install lxcguest
|
|
465 |
if [ $release = "lucid" -o $release = "maverick" ]; then |
|
466 |
chroot $rootfs apt-get install --force-yes -y python-software-properties
|
|
467 |
chroot $rootfs add-apt-repository ppa:ubuntu-virt/ppa
|
|
468 |
fi
|
|
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
469 |
cp /etc/resolv.conf "${rootfs}/etc" |
470 |
chroot $rootfs apt-get update
|
|
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
471 |
chroot $rootfs apt-get install --force-yes -y lxcguest
|
472 |
fi
|
|
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
473 |
|
474 |
# If the container isn't running a native architecture, setup multiarch
|
|
475 |
if [ -x "$(ls -1 ${rootfs}/usr/bin/qemu-*-static 2>/dev/null)" ]; then |
|
476 |
mkdir -p ${rootfs}/etc/dpkg/dpkg.cfg.d |
|
477 |
echo "foreign-architecture ${hostarch}" > ${rootfs}/etc/dpkg/dpkg.cfg.d/lxc-multiarch |
|
478 |
||
479 |
# Save existing value of MIRROR and SECURITY_MIRROR
|
|
480 |
DEFAULT_MIRROR=$MIRROR |
|
481 |
DEFAULT_SECURITY_MIRROR=$SECURITY_MIRROR |
|
482 |
||
483 |
# Write a new sources.list containing both native and multiarch entries
|
|
484 |
> ${rootfs}/etc/apt/sources.list |
|
485 |
write_sourceslist $rootfs $arch "native" |
|
486 |
||
487 |
MIRROR=$DEFAULT_MIRROR |
|
488 |
SECURITY_MIRROR=$DEFAULT_SECURITY_MIRROR |
|
489 |
write_sourceslist $rootfs $hostarch "multiarch" |
|
490 |
||
491 |
# Finally update the lists and install upstart using the host architecture
|
|
492 |
chroot $rootfs apt-get update
|
|
493 |
chroot $rootfs apt-get install --force-yes -y --no-install-recommends upstart:${hostarch} mountall:amd64 iproute:amd64 isc-dhcp-client:amd64 |
|
494 |
fi
|
|
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
495 |
}
|
496 |
||
497 |
do_bindhome()
|
|
498 |
{
|
|
499 |
rootfs=$1 |
|
500 |
user=$2 |
|
501 |
||
502 |
# copy /etc/passwd, /etc/shadow, and /etc/group entries into container
|
|
503 |
pwd=`getent passwd $user` |
|
504 |
if [ $? -ne 0 ]; then |
|
505 |
echo 'Warning: failed to copy password entry for $user' |
|
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
506 |
return
|
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
507 |
else
|
508 |
echo $pwd >> $rootfs/etc/passwd |
|
509 |
fi
|
|
510 |
shad=`getent shadow $user` |
|
511 |
echo $shad >> $rootfs/etc/shadow |
|
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
512 |
|
513 |
# bind-mount the user's path into the container's /home
|
|
514 |
h=`getent passwd $user | cut -d: -f 6` |
|
515 |
mkdir -p $rootfs/$h |
|
516 |
echo "$h $rootfs/$h none bind 0 0" >> $path/fstab |
|
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
517 |
}
|
518 |
||
519 |
usage()
|
|
520 |
{
|
|
521 |
cat <<EOF
|
|
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
522 |
$1 -h|--help [-a|--arch] [-b|--bindhome <user>] [--trim]
|
523 |
[-F | --flush-cache] [-r|--release <release>] [ -S | --auth_key <keyfile>]
|
|
524 |
release: lucid | maverick | natty | oneiric | precise
|
|
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
525 |
trim: make a minimal (faster, but not upgrade-safe) container
|
526 |
bindhome: bind <user>'s home into the container
|
|
527 |
arch: amd64 or i386: defaults to host arch
|
|
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
528 |
auth_key: SSH Public key file to inject into container
|
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
529 |
EOF
|
530 |
return 0 |
|
531 |
}
|
|
532 |
||
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
533 |
options=$(getopt -o a:b:hp:r:xn:FS: -l arch:,bindhome:,help,path:,release:,trim,name:,flush-cache,auth-key: -- "$@") |
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
534 |
if [ $? -ne 0 ]; then |
535 |
usage $(basename $0) |
|
536 |
exit 1 |
|
537 |
fi
|
|
538 |
eval set -- "$options" |
|
539 |
||
540 |
release=lucid |
|
541 |
if [ -f /etc/lsb-release ]; then |
|
542 |
. /etc/lsb-release |
|
543 |
case "$DISTRIB_CODENAME" in |
|
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
544 |
lucid|maverick|natty|oneiric|precise) |
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
545 |
release=$DISTRIB_CODENAME |
546 |
;;
|
|
547 |
esac
|
|
548 |
fi
|
|
549 |
||
550 |
bindhome= |
|
551 |
arch=$(arch) |
|
552 |
||
553 |
# Code taken from debootstrap
|
|
554 |
if [ -x /usr/bin/dpkg ] && /usr/bin/dpkg --print-architecture >/dev/null 2>&1; then |
|
555 |
arch=`/usr/bin/dpkg --print-architecture` |
|
556 |
elif type udpkg >/dev/null 2>&1 && udpkg --print-architecture >/dev/null 2>&1; then |
|
557 |
arch=`/usr/bin/udpkg --print-architecture` |
|
558 |
else
|
|
559 |
arch=$(arch) |
|
560 |
if [ "$arch" = "i686" ]; then |
|
561 |
arch="i386" |
|
562 |
elif [ "$arch" = "x86_64" ]; then |
|
563 |
arch="amd64" |
|
564 |
elif [ "$arch" = "armv7l" ]; then |
|
565 |
arch="armel" |
|
566 |
fi
|
|
567 |
fi
|
|
568 |
||
569 |
trim_container=0 |
|
570 |
hostarch=$arch |
|
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
571 |
flushcache=0 |
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
572 |
while true |
573 |
do
|
|
574 |
case "$1" in |
|
575 |
-h|--help) usage $0 && exit 0;; |
|
576 |
-p|--path) path=$2; shift 2;; |
|
577 |
-n|--name) name=$2; shift 2;; |
|
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
578 |
-F|--flush-cache) flushcache=1; shift 1;; |
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
579 |
-r|--release) release=$2; shift 2;; |
580 |
-b|--bindhome) bindhome=$2; shift 2;; |
|
581 |
-a|--arch) arch=$2; shift 2;; |
|
582 |
-x|--trim) trim_container=1; shift 1;; |
|
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
583 |
-S|--auth_key) auth_key=$2; shift 2;; |
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
584 |
--) shift 1; break ;; |
585 |
*) break ;; |
|
586 |
esac
|
|
587 |
done
|
|
588 |
||
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
589 |
pwd=`getent passwd $bindhome` |
590 |
if [ $? -ne 0 ]; then |
|
591 |
echo "Error: no password entry found for $bindhome" |
|
592 |
exit 1 |
|
593 |
fi
|
|
594 |
||
595 |
||
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
596 |
if [ "$arch" == "i686" ]; then |
597 |
arch=i386 |
|
598 |
fi
|
|
599 |
||
600 |
if [ $hostarch = "i386" -a $arch = "amd64" ]; then |
|
601 |
echo "can't create amd64 container on i386" |
|
602 |
exit 1 |
|
603 |
fi
|
|
604 |
||
605 |
type debootstrap
|
|
606 |
if [ $? -ne 0 ]; then |
|
607 |
echo "'debootstrap' command is missing" |
|
608 |
exit 1 |
|
609 |
fi
|
|
610 |
||
611 |
if [ -z "$path" ]; then |
|
612 |
echo "'path' parameter is required" |
|
613 |
exit 1 |
|
614 |
fi
|
|
615 |
||
616 |
if [ "$(id -u)" != "0" ]; then |
|
617 |
echo "This script should be run as 'root'" |
|
618 |
exit 1 |
|
619 |
fi
|
|
620 |
||
621 |
rootfs=$path/rootfs |
|
622 |
||
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
623 |
install_ubuntu $rootfs $release $flushcache |
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
624 |
if [ $? -ne 0 ]; then |
625 |
echo "failed to install ubuntu $release" |
|
626 |
exit 1 |
|
627 |
fi
|
|
628 |
||
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
629 |
configure_ubuntu $rootfs $name $release |
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
630 |
if [ $? -ne 0 ]; then |
631 |
echo "failed to configure ubuntu $release for a container" |
|
632 |
exit 1 |
|
633 |
fi
|
|
634 |
||
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
635 |
copy_configuration $path $rootfs $name $arch $release |
1.1.10
by Stéphane Graber
Import upstream version 0.7.5 |
636 |
if [ $? -ne 0 ]; then |
637 |
echo "failed write configuration file" |
|
638 |
exit 1 |
|
639 |
fi
|
|
640 |
||
641 |
post_process $rootfs $release $trim_container |
|
642 |
if [ ! -z $bindhome ]; then |
|
643 |
do_bindhome $rootfs $bindhome |
|
644 |
fi
|
|
645 |
||
1.1.11
by Daniel Baumann
Import upstream version 0.8.0~rc1 |
646 |
echo "" |
647 |
echo "##" |
|
648 |
echo "# The default user is 'ubuntu' with password 'ubuntu'!" |
|
649 |
echo "# Use the 'sudo' command to run tasks as root in the container." |
|
650 |
echo "##" |
|
651 |
echo "" |