~serge-hallyn/ubuntu/quantal/lxc/lxc-fixapi

« back to all changes in this revision

Viewing changes to templates/lxc-ubuntu.in

  • Committer: Package Import Robot
  • Author(s): Daniel Baumann
  • Date: 2012-03-09 13:05:03 UTC
  • mto: (3.1.38 sid)
  • mto: This revision was merged to the branch mainline in revision 94.
  • Revision ID: package-import@ubuntu.com-20120309130503-j0prgw9tsp967bbv
Tags: upstream-0.8.0~rc1
Import upstream version 0.8.0~rc1

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
# This script consolidates and extends the existing lxc ubuntu scripts
7
7
#
8
8
 
9
 
# XXX todo: add -lvm option
10
 
 
11
9
# Copyright � 2011 Serge Hallyn <serge.hallyn@canonical.com>
12
10
# Copyright � 2010 Wilhelm Meier
13
11
# Author: Wilhelm Meier <wilhelm.meier@fh-kl.de>
34
32
{
35
33
    rootfs=$1
36
34
    hostname=$2
 
35
    release=$3
37
36
 
38
37
   # configure the network using the dhcp
39
38
    cat <<EOF > $rootfs/etc/network/interfaces
44
43
iface eth0 inet dhcp
45
44
EOF
46
45
 
47
 
    # so you can 'ssh $hostname.' or 'ssh $hostname.local'
48
 
    if [ -f $rootfs/etc/dhcp/dhclient.conf ]; then
49
 
        sed -i "s/<hostname>/$hostname/" $rootfs/etc/dhcp/dhclient.conf
50
 
    elif [ -f $rootfs/etc/dhcp3/dhclient.conf ]; then
51
 
        sed -i "s/<hostname>/$hostname/" $rootfs/etc/dhcp3/dhclient.conf
52
 
    fi
53
 
 
54
46
    # set the hostname
55
47
    cat <<EOF > $rootfs/etc/hostname
56
48
$hostname
60
52
127.0.0.1 localhost $hostname
61
53
EOF
62
54
 
63
 
    # suppress log level output for udev
64
 
    sed -i "s/=\"err\"/=0/" $rootfs/etc/udev/udev.conf
65
 
 
66
 
    # remove jobs for consoles 5 and 6 since we only create 4 consoles in
67
 
    # this template
68
 
    rm -f $rootfs/etc/init/tty{5,6}.conf
69
 
 
70
 
    echo "Please change root-password !"
71
 
    echo "root:root" | chroot $rootfs chpasswd
72
 
 
 
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
73
80
    return 0
74
81
}
75
82
 
 
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
 
76
126
download_ubuntu()
77
127
{
78
128
    cache=$1
86
136
    elif [ $release = "natty" ]; then
87
137
        packages=dialog,apt,apt-utils,resolvconf,iproute,inetutils-ping,vim,isc-dhcp-client,isc-dhcp-common,ssh,lsb-release,gnupg,netbase
88
138
    else
89
 
        packages=dialog,apt,apt-utils,resolvconf,iproute,inetutils-ping,vim,isc-dhcp-client,isc-dhcp-common,ssh,lsb-release,gnupg,netbase,ubuntu-keyring
 
139
        packages=dialog,apt,apt-utils,iproute,inetutils-ping,vim,isc-dhcp-client,isc-dhcp-common,ssh,lsb-release,gnupg,netbase,ubuntu-keyring
90
140
    fi
91
141
    echo "installing packages: $packages"
92
142
 
99
149
 
100
150
    # download a mini ubuntu into a cache
101
151
    echo "Downloading ubuntu $release minimal ..."
102
 
    debootstrap --verbose --variant=minbase --components=main,universe --arch=$arch --include=$packages $release $cache/partial-$arch $MIRROR
 
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
 
103
158
    if [ $? -ne 0 ]; then
104
159
        echo "Failed to download the rootfs, aborting."
105
160
            return 1
106
161
    fi
107
162
 
 
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
 
108
217
    mv "$1/partial-$arch" "$1/rootfs-$arch"
109
 
    echo "Download complete."
110
 
 
 
218
    echo "Download complete"
111
219
    return 0
112
220
}
113
221
 
118
226
    rootfs=$3
119
227
 
120
228
    # make a local copy of the miniubuntu
121
 
    echo -n "Copying rootfs to $rootfs ..."
122
 
    cp -a $cache/rootfs-$arch $rootfs || return 1
 
229
    echo "Copying rootfs to $rootfs ..."
 
230
    mkdir -p $rootfs
 
231
    rsync -a $cache/rootfs-$arch/ $rootfs/ || return 1
123
232
    return 0
124
233
}
125
234
 
127
236
{
128
237
    rootfs=$1
129
238
    release=$2
 
239
    flushcache=$3
130
240
    cache="/var/cache/lxc/$release"
131
241
    mkdir -p /var/lock/subsys/
132
242
    (
137
247
        fi
138
248
 
139
249
 
 
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
 
140
256
        echo "Checking cache download in $cache/rootfs-$arch ... "
141
257
        if [ ! -e "$cache/rootfs-$arch" ]; then
142
258
            download_ubuntu $cache $arch $release
166
282
    rootfs=$2
167
283
    name=$3
168
284
    arch=$4
 
285
    release=$5
169
286
 
170
287
    if [ $arch = "i386" ]; then
171
288
        arch="i686"
172
289
    fi
173
290
 
 
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
 
174
305
    cat <<EOF >> $path/config
175
306
lxc.utsname = $name
176
307
 
 
308
lxc.devttydir = $ttydir
177
309
lxc.tty = 4
178
310
lxc.pts = 1024
179
311
lxc.rootfs = $rootfs
180
312
lxc.mount  = $path/fstab
181
313
lxc.arch = $arch
 
314
lxc.cap.drop = sys_module mac_admin mac_override
182
315
 
183
316
lxc.cgroup.devices.deny = a
 
317
# Allow any mknod (but not using the node)
 
318
lxc.cgroup.devices.allow = c *:* m
 
319
lxc.cgroup.devices.allow = b *:* m
184
320
# /dev/null and zero
185
321
lxc.cgroup.devices.allow = c 1:3 rwm
186
322
lxc.cgroup.devices.allow = c 1:5 rwm
198
334
lxc.cgroup.devices.allow = c 254:0 rwm
199
335
#fuse
200
336
lxc.cgroup.devices.allow = c 10:229 rwm
 
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
201
345
EOF
202
346
 
203
347
    cat <<EOF > $path/fstab
314
458
 
315
459
    if [ $trim_container -eq 1 ]; then
316
460
        trim $rootfs $release
317
 
    else
 
461
    elif [ $release = "lucid" -o $release = "maverick" -o $release = "natty" \
 
462
               -o $release = "oneiric" ]; then
318
463
        # for lucid and maverick, if not trimming, then add the ubuntu-virt
319
464
        # ppa and install lxcguest
320
465
        if [ $release = "lucid" -o $release = "maverick" ]; then
321
466
            chroot $rootfs apt-get install --force-yes -y python-software-properties
322
467
            chroot $rootfs add-apt-repository ppa:ubuntu-virt/ppa
323
 
            chroot $rootfs apt-get update
324
468
        fi
 
469
        cp /etc/resolv.conf "${rootfs}/etc"
 
470
        chroot $rootfs apt-get update
325
471
        chroot $rootfs apt-get install --force-yes -y lxcguest
326
472
    fi
 
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
327
495
}
328
496
 
329
497
do_bindhome()
331
499
    rootfs=$1
332
500
    user=$2
333
501
 
334
 
    # bind-mount the user's path into the container's /home
335
 
    h=`getent passwd $user | cut -d: -f 6`
336
 
    mkdir -p $rootfs/$h
337
 
    echo "$h $rootfs/$h none bind 0 0" >> $path/fstab
338
 
 
339
502
    # copy /etc/passwd, /etc/shadow, and /etc/group entries into container
340
503
    pwd=`getent passwd $user`
341
504
    if [ $? -ne 0 ]; then
342
505
        echo 'Warning: failed to copy password entry for $user'
 
506
        return
343
507
    else
344
508
        echo $pwd >> $rootfs/etc/passwd
345
509
    fi
346
510
    shad=`getent shadow $user`
347
511
    echo $shad >> $rootfs/etc/shadow
348
 
}
349
 
 
350
 
clean()
351
 
{
352
 
    release=$1
353
 
    cache="/var/cache/lxc/$release"
354
 
 
355
 
    if [ ! -e $cache ]; then
356
 
        exit 0
357
 
    fi
358
 
 
359
 
    # lock, so we won't purge while someone is creating a repository
360
 
    (
361
 
        flock -n -x 200
362
 
        if [ $? != 0 ]; then
363
 
            echo "Cache repository is busy."
364
 
            exit 1
365
 
        fi
366
 
 
367
 
        echo -n "Purging the download cache..."
368
 
        rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1
369
 
        exit 0
370
 
 
371
 
    ) 200>/var/lock/subsys/lxc
 
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
372
517
}
373
518
 
374
519
usage()
375
520
{
376
521
    cat <<EOF
377
 
$1 -h|--help -p|--path=<path> --clean [-a|--arch] [-b|--bindhome <user>] [--trim] [-r|--release]
378
 
release: lucid | maverick | natty | oneiric
 
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
379
525
trim: make a minimal (faster, but not upgrade-safe) container
380
526
bindhome: bind <user>'s home into the container
381
527
arch: amd64 or i386: defaults to host arch
 
528
auth_key: SSH Public key file to inject into container
382
529
EOF
383
530
    return 0
384
531
}
385
532
 
386
 
options=$(getopt -o a:b:hp:r:xn:c -l arch:,bindhome:,help,path:,release:,trim,name:,clean -- "$@")
 
533
options=$(getopt -o a:b:hp:r:xn:FS: -l arch:,bindhome:,help,path:,release:,trim,name:,flush-cache,auth-key: -- "$@")
387
534
if [ $? -ne 0 ]; then
388
535
    usage $(basename $0)
389
536
    exit 1
394
541
if [ -f /etc/lsb-release ]; then
395
542
    . /etc/lsb-release
396
543
    case "$DISTRIB_CODENAME" in
397
 
        lucid|maverick|natty|oneiric)
 
544
        lucid|maverick|natty|oneiric|precise)
398
545
            release=$DISTRIB_CODENAME
399
546
        ;;
400
547
    esac
421
568
 
422
569
trim_container=0
423
570
hostarch=$arch
 
571
flushcache=0
424
572
while true
425
573
do
426
574
    case "$1" in
427
575
    -h|--help)      usage $0 && exit 0;;
428
576
    -p|--path)      path=$2; shift 2;;
429
577
    -n|--name)      name=$2; shift 2;;
430
 
    -c|--clean)     clean=$2; shift 2;;
 
578
    -F|--flush-cache) flushcache=1; shift 1;;
431
579
    -r|--release)   release=$2; shift 2;;
432
580
    -b|--bindhome)  bindhome=$2; shift 2;;
433
581
    -a|--arch)      arch=$2; shift 2;;
434
582
    -x|--trim)      trim_container=1; shift 1;;
 
583
    -S|--auth_key)  auth_key=$2; shift 2;;
435
584
    --)             shift 1; break ;;
436
585
        *)              break ;;
437
586
    esac
438
587
done
439
588
 
 
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
 
440
596
if [ "$arch" == "i686" ]; then
441
597
    arch=i386
442
598
fi
443
599
 
444
 
if [ ! -z "$clean" -a -z "$path" ]; then
445
 
    clean || exit 1
446
 
    exit 0
447
 
fi
448
 
 
449
600
if [ $hostarch = "i386" -a $arch = "amd64" ]; then
450
601
    echo "can't create amd64 container on i386"
451
602
    exit 1
469
620
 
470
621
rootfs=$path/rootfs
471
622
 
472
 
install_ubuntu $rootfs $release
 
623
install_ubuntu $rootfs $release $flushcache
473
624
if [ $? -ne 0 ]; then
474
625
    echo "failed to install ubuntu $release"
475
626
    exit 1
476
627
fi
477
628
 
478
 
configure_ubuntu $rootfs $name
 
629
configure_ubuntu $rootfs $name $release
479
630
if [ $? -ne 0 ]; then
480
631
    echo "failed to configure ubuntu $release for a container"
481
632
    exit 1
482
633
fi
483
634
 
484
 
copy_configuration $path $rootfs $name $arch
 
635
copy_configuration $path $rootfs $name $arch $release
485
636
if [ $? -ne 0 ]; then
486
637
    echo "failed write configuration file"
487
638
    exit 1
492
643
        do_bindhome $rootfs $bindhome
493
644
fi
494
645
 
495
 
if [ ! -z $clean ]; then
496
 
    clean $release || exit 1
497
 
    exit 0
498
 
fi
 
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 ""