4 # lxc: linux Container library
7 # Daniel Lezcano <daniel.lezcano@free.fr>
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 # Detect use under userns (unsupported)
25 [ "$arg" = "--" ] && break
26 if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
27 echo "This template can't be used for unprivileged containers." 1>&2
28 echo "You may want to try the \"download\" template instead." 1>&2
33 # Make sure the usual locations are in PATH
34 export PATH
=$PATH:/usr
/sbin
:/usr
/bin
:/sbin
:/bin
35 export GREP_OPTIONS
=""
37 MIRROR
=${MIRROR:-http://httpredir.debian.org/debian}
38 SECURITY_MIRROR
=${SECURITY_MIRROR:-http://security.debian.org/}
39 LOCALSTATEDIR
="@LOCALSTATEDIR@"
40 LXC_TEMPLATE_CONFIG
="@LXCTEMPLATECONFIG@"
41 # Allows the lxc-cache directory to be set by environment variable
42 LXC_CACHE_PATH
=${LXC_CACHE_PATH:-"$LOCALSTATEDIR/cache/lxc"}
46 given_interpreter
=$
(basename "$1")
48 if [ ! -d /proc
/sys
/fs
/binfmt_misc
/ ] ; then
51 for file in /proc
/sys
/fs
/binfmt_misc
/* ; do
52 if [ "$file" = "/proc/sys/fs/binfmt_misc/register" -o \
53 "$file" = "/proc/sys/fs/binfmt_misc/status" ] ; then
56 interpreter_path
=$
(sed -n "/^interpreter/s/interpreter \([^[:space:]]*\)/\1/p" "$file")
57 interpreter
=$
(basename "$interpreter_path")
59 if [ "$given_interpreter" = "$interpreter" ] ; then
60 echo "$interpreter_path"
73 # squeeze only has /dev/tty and /dev/tty0 by default,
74 # therefore creating missing device nodes for tty1-4.
75 for tty
in $
(seq 1 "$num_tty"); do
76 if [ ! -e "$rootfs/dev/tty$tty" ]; then
77 mknod
"$rootfs/dev/tty$tty" c
4 "$tty"
81 # configure the inittab
82 cat <<EOF > $rootfs/etc/inittab
84 si::sysinit:/etc/init.d/rcS
85 l0:0:wait:/etc/init.d/rc 0
86 l1:1:wait:/etc/init.d/rc 1
87 l2:2:wait:/etc/init.d/rc 2
88 l3:3:wait:/etc/init.d/rc 3
89 l4:4:wait:/etc/init.d/rc 4
90 l5:5:wait:/etc/init.d/rc 5
91 l6:6:wait:/etc/init.d/rc 6
92 # Normally not reached, but fallthrough in case of emergency.
93 z6:6:respawn:/sbin/sulogin
94 1:2345:respawn:/sbin/getty 38400 console
95 $(for tty in $(seq 1 "$num_tty"); do echo "c${tty}:12345:respawn:/sbin/getty 38400 tty${tty} linux" ; done;)
96 p6::ctrlaltdel:/sbin/init 6
97 p0::powerfail:/sbin/init 0
101 [ -e "$rootfs/etc/mtab" ] && rm "$rootfs/etc/mtab"
102 ln -s /proc
/self
/mounts
"$rootfs/etc/mtab"
104 # disable selinux in debian
105 mkdir
-p "$rootfs/selinux"
106 echo 0 > "$rootfs/selinux/enforce"
108 # configure the network using the dhcp
109 cat <<EOF > $rootfs/etc/network/interfaces
111 iface lo inet loopback
118 cat <<EOF > $rootfs/etc/hostname
122 # reconfigure some services
124 # but first reconfigure locales - so we get no noisy perl-warnings
125 if [ -z "$LANG" ]; then
126 cat >> "$rootfs/etc/locale.gen" << EOF
129 chroot
"$rootfs" locale-gen en_US.UTF-8 UTF-8
130 chroot
"$rootfs" update-locale LANG
=en_US.UTF-8
132 encoding
=$
(echo "$LANG" | cut
-d.
-f2)
133 chroot
"$rootfs" sed -e "s/^# \(${LANG} ${encoding}\)/\1/" \
134 -i /etc
/locale.gen
2> /dev
/null
135 cat >> "$rootfs/etc/locale.gen" << EOF
138 chroot
"$rootfs" locale-gen
"$LANG" "$encoding"
139 chroot
"$rootfs" update-locale LANG
="$LANG"
142 # remove pointless services in a container
143 chroot
"$rootfs" /usr
/sbin
/update-rc.d
-f checkroot.sh disable
144 chroot
"$rootfs" /usr
/sbin
/update-rc.d
-f umountfs disable
145 chroot
"$rootfs" /usr
/sbin
/update-rc.d
-f hwclock.sh disable
146 chroot
"$rootfs" /usr
/sbin
/update-rc.d
-f hwclockfirst.sh disable
148 # generate new SSH keys
149 if [ -x "$rootfs/var/lib/dpkg/info/openssh-server.postinst" ]; then
150 cat > "$rootfs/usr/sbin/policy-rc.d" << EOF
154 chmod +x
"$rootfs/usr/sbin/policy-rc.d"
156 if [ -f "$rootfs/etc/init/ssh.conf" ]; then
157 mv "$rootfs/etc/init/ssh.conf" "$rootfs/etc/init/ssh.conf.disabled"
160 rm -f "$rootfs/etc/ssh/"ssh_host_
*key
*
162 DPKG_MAINTSCRIPT_PACKAGE
=openssh DPKG_MAINTSCRIPT_NAME
=postinst chroot
"$rootfs" /var
/lib
/dpkg
/info
/openssh-server.postinst configure
163 sed -i "s/root@$(hostname)/root@$hostname/g" "$rootfs/etc/ssh/"ssh_host_
*.pub
165 if [ -f "$rootfs/etc/init/ssh.conf.disabled" ]; then
166 mv "$rootfs/etc/init/ssh.conf.disabled" "$rootfs/etc/init/ssh.conf"
169 rm -f "$rootfs/usr/sbin/policy-rc.d"
172 # set initial timezone as on host
173 if [ -f /etc
/timezone
]; then
174 cat /etc
/timezone
> "$rootfs/etc/timezone"
175 chroot
"$rootfs" dpkg-reconfigure
-f noninteractive tzdata
176 elif [ -f /etc
/sysconfig
/clock ]; then
177 .
/etc
/sysconfig
/clock
178 echo "$ZONE" > "$rootfs/etc/timezone"
179 chroot
"$rootfs" dpkg-reconfigure
-f noninteractive tzdata
181 echo "Timezone in container is not configured. Adjust it manually."
184 if [ -n "$authkey" ]; then
185 local ssh_dir_path
="${rootfs}/root/.ssh"
186 mkdir
-p "$ssh_dir_path"
187 cp "$authkey" "${ssh_dir_path}/authorized_keys"
188 chmod 700 "$ssh_dir_path"
189 echo "Inserted SSH public key from '$authkey' into /root/.ssh/authorized_keys"
197 local rootfs
="$1"; shift
198 local release
="$1"; shift
199 local arch
="$1"; shift
202 if [ -n "${arch}" ]; then
203 prefix
="deb [arch=${arch}]"
206 if [ "$mainonly" = 1 ]; then
209 non_main
=' contrib non-free'
212 cat >> "${rootfs}/etc/apt/sources.list" << EOF
213 ${prefix} $MIRROR ${release} main${non_main}
216 if [ "$release" != "unstable" -a "$release" != "sid" ]; then
217 cat >> "${rootfs}/etc/apt/sources.list" << EOF
218 ${prefix} $SECURITY_MIRROR ${release}/updates main${non_main}
225 local rootfs
="$1"; shift
228 chroot
"${rootfs}" apt-get update
229 if [ -n "${packages}" ]; then
230 chroot
"${rootfs}" apt-get
install --force-yes -y --no-install-recommends ${packages}
234 configure_debian_systemd
()
241 # this only works if we have getty@.service to manipulate
242 if [ -f "${rootfs}/lib/systemd/system/getty@.service" ]; then
243 sed -e 's/^ConditionPathExists=/# ConditionPathExists=/' \
244 -e 's/After=dev-%i.device/After=/' \
245 < "${rootfs}/lib/systemd/system/getty@.service" \
246 > "${rootfs}/etc/systemd/system/getty@.service"
249 # just in case systemd is not installed
250 mkdir
-p "${rootfs}/lib/systemd/system"
251 mkdir
-p "${rootfs}/etc/systemd/system/getty.target.wants"
253 # Fix getty-static-service as debootstrap does not install dbus
254 if [ -e "$rootfs//lib/systemd/system/getty-static.service" ] ; then
256 tty_services
=$
(for i
in $
(seq 2 "$num_tty"); do echo -n "getty@tty${i}.service "; done; )
257 sed 's/ getty@tty.*/'" $tty_services "'/g' \
258 "$rootfs/lib/systemd/system/getty-static.service" | \
259 sed 's/\(tty2-tty\)[5-9]/\1'"${num_tty}"'/g' > "$rootfs/etc/systemd/system/getty-static.service"
262 # This function has been copied and adapted from lxc-fedora
263 rm -f "${rootfs}/etc/systemd/system/default.target"
264 chroot
"${rootfs}" ln -s /dev
/null
/etc
/systemd
/system
/udev.service
265 chroot
"${rootfs}" ln -s /dev
/null
/etc
/systemd
/system
/systemd-udevd.service
266 chroot
"${rootfs}" ln -s /lib
/systemd
/system
/multi-user.target
/etc
/systemd
/system
/default.target
267 # Setup getty service on the ttys we are going to allow in the
268 # default config. Number should match lxc.tty.max
269 ( cd "${rootfs}/etc/systemd/system/getty.target.wants"
270 for i
in $
(seq 1 "$num_tty") ; do ln -sf ..
/getty\@.service getty@tty
"${i}".service
; done )
272 # Since we use static-getty.target; we need to mask container-getty@.service generated by
273 # container-getty-generator, so we don't get multiple instances of agetty running.
274 # See https://github.com/lxc/lxc/issues/520 and https://github.com/lxc/lxc/issues/484
275 ( cd "${rootfs}/etc/systemd/system/getty.target.wants"
276 for i
in $
(seq 0 "$num_tty"); do ln -sf /dev
/null container-getty\@
"${i}".service
; done )
281 # Check if given path is in a btrfs partition
284 [ -e "$1" -a "$(stat -f -c '%T' "$1")" = "btrfs" ]
287 # Check if given path is the root of a btrfs subvolume
290 [ -d "$1" -a "$(stat -f -c '%T' "$1")" = "btrfs" -a "$(stat -c '%i' "$1")" -eq 256 ]
296 [ -d "$path" ] && return 0
297 mkdir
-p "$(dirname "$path")"
298 if which btrfs
>/dev
/null
2>&1 && is_btrfs
"$(dirname "$path")"; then
299 btrfs subvolume create
"$path"
308 [ -d "$path" ] ||
return 0
309 if which btrfs
>/dev
/null
2>&1 && is_btrfs_subvolume
"$path"; then
310 btrfs subvolume delete
"$path"
318 try_rmsubvolume
"$cache/partial-$release-$arch"
319 try_rmsubvolume
"$cache/rootfs-$release-$arch"
347 interpreter_path
="$5"
349 trap cleanup EXIT SIGHUP SIGINT SIGTERM
354 # If debian-archive-keyring isn't installed, fetch GPG keys directly
355 releasekeyring
=/usr
/share
/keyrings
/debian-archive-keyring.gpg
356 if [ ! -f $releasekeyring ]; then
357 releasekeyring
="$cache/archive-key.gpg"
360 gpgkeyname
="archive-key-7.0"
363 gpgkeyname
="archive-key-8"
366 wget https
://ftp-master.debian.org
/keys
/${gpgkeyname}.asc
-O - --quiet \
367 | gpg
--import --no-default-keyring --keyring="${releasekeyring}"
369 # check the mini debian was not already downloaded
370 try_mksubvolume
"$cache/partial-$release-$arch"
371 if [ $?
-ne 0 ]; then
372 echo "Failed to create '$cache/partial-$release-$arch' directory"
376 # download a mini debian into a cache
377 echo "Downloading debian minimal ..."
378 if [ "$interpreter" = "" ] ; then
379 debootstrap
--verbose --variant=minbase
--arch="$arch" \
380 --include=$packages --keyring="${releasekeyring}" \
381 "$release" "$cache/partial-$release-$arch" "$MIRROR"
382 if [ $?
-ne 0 ]; then
383 echo "Failed to download the rootfs, aborting."
387 debootstrap
--foreign --verbose --variant=minbase
--arch="$arch" \
388 --include=$packages --keyring="${releasekeyring}" \
389 "$release" "$cache/partial-$release-$arch" "$MIRROR"
390 if [ $?
-ne 0 ]; then
391 echo "Failed to download the rootfs, aborting."
394 mkdir
-p "$(basename "$cache/partial-
$release-$arch/$interpreter_path")"
395 cp "$interpreter" "$cache/partial-$release-$arch/$interpreter_path"
396 if [ $?
-ne 0 ]; then
397 echo "failed to copy $interpreter to $cache/partial-$release-$arch/$interpreter_path"
400 chroot
"$cache/partial-$release-$arch" debootstrap
/debootstrap
--second-stage
401 if [ $?
-ne 0 ]; then
402 echo "failed to update the rootfs, aborting"
407 mv "$1/partial-$release-$arch" "$1/rootfs-$release-$arch"
408 echo "Download complete."
424 # make a local copy of the minidebian
425 echo -n "Copying rootfs to $rootfs..."
426 try_mksubvolume
"$rootfs"
427 if which btrfs
>/dev
/null
2>&1 && \
428 is_btrfs_subvolume
"$cache/rootfs-$release-$arch" && \
429 is_btrfs_subvolume
"$rootfs"; then
430 realrootfs
="$(dirname "$config")"/rootfs
431 [ "$rootfs" = "$realrootfs" ] || umount
"$rootfs" ||
return 1
432 btrfs subvolume delete
"$realrootfs" ||
return 1
433 btrfs subvolume snapshot
"$cache/rootfs-$release-$arch" "$realrootfs" ||
return 1
434 [ "$rootfs" = "$realrootfs" ] || mount
--bind "$realrootfs" "$rootfs" ||
return 1
436 rsync
-Ha "$cache/rootfs-$release-$arch"/ "$rootfs"/ ||
return 1
448 interpreter_path
="$6"
450 mkdir
-p $LOCALSTATEDIR/lock
/subsys
/
453 if [ $?
-ne 0 ]; then
454 echo "Cache repository is busy."
458 if [ "$flushcache" -eq 1 ]; then
459 echo "Flushing cache..."
463 echo "Checking cache download in $cache/rootfs-$release-$arch ... "
464 if [ ! -e "$cache/rootfs-$release-$arch" ]; then
465 download_debian
"$cache" "$arch" "$release" "$interpreter" "$interpreter_path"
466 if [ $?
-ne 0 ]; then
467 echo "Failed to download 'debian base'"
472 copy_debian
"$cache" "$arch" "$rootfs" "$release"
473 if [ $?
-ne 0 ]; then
474 echo "Failed to copy rootfs"
480 ) 9>$LOCALSTATEDIR/lock
/subsys
/lxc-debian
493 # Generate the configuration file
494 # if there is exactly one veth network entry, make sure it has an
496 nics
=$
(grep -ce '^lxc\.net\.0\.type[ \t]*=[ \t]*veth' "$path/config")
497 if [ "$nics" -eq 1 ]; then
498 grep -q "^lxc.net.0.hwaddr" "$path/config" ||
sed -i -e "/^lxc\.net\.0\.type[ \t]*=[ \t]*veth/a lxc.net.0.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')" "$path/config"
501 ## Add all the includes
502 echo "" >> "$path/config"
503 echo "# Common configuration" >> "$path/config"
504 if [ -e "${LXC_TEMPLATE_CONFIG}/debian.common.conf" ]; then
505 echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/debian.common.conf" >> "$path/config"
507 if [ -e "${LXC_TEMPLATE_CONFIG}/debian.${release}.conf" ]; then
508 echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/debian.${release}.conf" >> "$path/config"
511 ## Add the container-specific config
512 echo "" >> "$path/config"
513 echo "# Container specific configuration" >> "$path/config"
514 grep -q "^lxc.rootfs.path" "$path/config" 2> /dev
/null ||
echo "lxc.rootfs.path = $rootfs" >> "$path/config"
516 cat <<EOF >> $path/config
517 lxc.tty.max = $num_tty
518 lxc.uts.name = $hostname
523 if [ $?
-ne 0 ]; then
524 echo "Failed to add configuration"
533 local rootfs
="$1"; shift
534 local release
="$1"; shift
535 local arch
="$1"; shift
536 local hostarch
="$1"; shift
537 local interpreter
="$1"; shift
540 # Disable service startup
541 cat > "${rootfs}/usr/sbin/policy-rc.d" << EOF
545 chmod +x
"${rootfs}/usr/sbin/policy-rc.d"
547 # If the container isn't running a native architecture, setup multiarch
548 if [ "$interpreter" = "" -a "${arch}" != "${hostarch}" ]; then
549 # Test if dpkg supports multiarch
550 if ! chroot
"$rootfs" dpkg
--print-foreign-architectures 2>&1; then
551 chroot
"$rootfs" dpkg
--add-architecture "${hostarch}"
555 # Write a new sources.list containing both native and multiarch entries
556 > "${rootfs}/etc/apt/sources.list"
557 if [ "$interpreter" != "" -a "${arch}" = "${hostarch}" ]; then
558 write_sourceslist
"${rootfs}" "${release}" "${arch}"
560 write_sourceslist
"${rootfs}" "${release}"
563 # Install Packages in container
564 if [ -n "${packages}" ]; then
566 pack_list
="${packages//,/ }"
567 echo "Installing packages: ${pack_list}"
568 install_packages
"${rootfs}" "${pack_list}"
571 # Re-enable service startup
572 rm "${rootfs}/usr/sbin/policy-rc.d"
579 cache
=${LXC_CACHE_PATH:-"$LOCALSTATEDIR/cache/lxc/debian"}
581 if [ ! -e "$cache" ]; then
585 # lock, so we won't purge while someone is creating a repository
589 echo "Cache repository is busy."
593 echo -n "Purging the download cache..."
594 rm --preserve-root --one-file-system -rf "$cache" && echo "Done." ||
exit 1
597 ) 9>$LOCALSTATEDIR/lock
/subsys
/lxc-debian
603 Template specific options can be passed to lxc-create after a '--' like this:
605 lxc-create --name=NAME [-lxc-create-options] -- [-template-options]
607 Usage: $1 -h|--help -p|--path=<path> [-c|--clean] [-a|--arch=<arch>] [-r|--release=<release>]
608 [--mirror=<mirror>] [--security-mirror=<security mirror>]
609 [--package=<package_name1,package_name2,...>]
610 [-I|--interpreter-path=<interpreter path>]
611 [-F | --flush-cache] [-S|--auth-key=<keyfile>]
615 -h, --help print this help text
616 -p, --path=PATH directory where config and rootfs of this VM will be kept
617 -S, --auth-key=KEYFILE SSH public key to inject into the container as the root user.
618 -a, --arch=ARCH The container architecture. Can be one of: i686, x86_64,
619 amd64, armhf, armel, powerpc. Defaults to host arch.
620 -r, --release=RELEASE Debian release. Can be one of: wheezy, jessie, stretch, sid.
621 Defaults to current stable.
622 --mirror=MIRROR Debian mirror to use during installation. Overrides the MIRROR
623 environment variable (see below).
624 --security-mirror=SECURITY_MIRROR
625 Debian mirror to use for security updates. Overrides the
626 SECURITY_MIRROR environment variable (see below).
627 --packages=PACKAGE_NAME1,PACKAGE_NAME2,...
628 List of additional packages to install. Comma separated, without space.
629 -c, --clean only clean up the cache and terminate
630 --enable-non-free include also Debian's contrib and non-free repositories.
631 -I|--interpreter-path=INTERPRETER-PATH
632 Path of the binfmt interpreter to copy to the rootfs
633 -F | --flush-cache Flush the debian release cache
635 Environment variables:
637 MIRROR The Debian package mirror to use. See also the --mirror switch above.
638 Defaults to '$MIRROR'
639 SECURITY_MIRROR The Debian package security mirror to use. See also the --security-mirror switch above.
640 Defaults to '$SECURITY_MIRROR'
646 options
=$
(getopt
-o hp
:n
:a
:r
:cI
:FS
: -l arch
:,auth-key
:,clean
,help,enable-non-free
,mirror
:,name
:,packages
:,path
:,release
:,rootfs
:,security-mirror
:,interpreter-path
:,flush-cache
-- "$@")
647 if [ $?
-ne 0 ]; then
648 usage
"$(basename "$0")"
651 eval set -- "$options"
653 littleendian
=$
(lscpu |
grep '^Byte Order' |
grep -q Little
&& echo yes)
656 if [ "$arch" = "i686" ]; then
658 elif [ "$arch" = "x86_64" ]; then
660 elif [ "$arch" = "armv7l" ]; then
662 elif [ "$arch" = "aarch64" ]; then
664 elif [ "$arch" = "ppc" ]; then
666 elif [ "$arch" = "ppc64le" ]; then
668 elif [ "$arch" = "mips" -a "$littleendian" = "yes" ]; then
670 elif [ "$arch" = "mips64" -a "$littleendian" = "yes" ]; then
680 -h|
--help) usage
"$0" && exit 1;;
681 --) shift 1; break ;;
683 -a|
--arch) arch
=$2; shift 2;;
684 -S|
--auth-key) authkey
=$2; shift 2;;
685 -I|
--interpreter-path)
686 interpreter
="$2"; shift 2;;
687 -c|
--clean) clean
=1; shift 1;;
688 --enable-non-free) mainonly
=0; shift 1;;
689 --mirror) MIRROR
=$2; shift 2;;
690 -n|
--name) name
=$2; shift 2;;
691 --packages) packages
=$2; shift 2;;
692 -p|
--path) path
=$2; shift 2;;
693 -r|
--release) release
=$2; shift 2;;
694 --rootfs) rootfs
=$2; shift 2;;
695 --security-mirror) SECURITY_MIRROR
=$2; shift 2;;
696 -F|
--flush-cache) flushcache
=1; shift 1;;
701 if [ ! -z "$clean" -a -z "$path" ]; then
706 if [ "$arch" = "i686" ]; then
710 if [ "$arch" = "x86_64" ]; then
714 if [ "$interpreter" = "" ] ; then
715 if [ $hostarch = "i386" -a $arch = "amd64" ]; then
716 echo "can't create $arch container on $hostarch"
720 if [ $hostarch = "armhf" -o $hostarch = "armel" ] && \
721 [ $arch != "armhf" -a $arch != "armel" ]; then
722 echo "can't create $arch container on $hostarch"
726 if [ $hostarch = "powerpc" -a $arch != "powerpc" ]; then
727 echo "can't create $arch container on $hostarch"
731 if [ $hostarch = "mips" -a $arch != "mips" ] || \
732 [ $hostarch = "mipsel" -a $arch != "mipsel" ] || \
733 [ $hostarch = "mips64" -a $arch != "mips" -a $arch != "mips64" ] || \
734 [ $hostarch = "mips64el" -a $arch != "mipsel" -a $arch != "mips64el" ]; then
735 echo "can't create $arch container on $hostarch"
739 if ! file -b "${interpreter}" |
grep -q "statically linked" ; then
740 echo "'${interpreter}' must be statically linked" 1>&2
743 interpreter_path
=$
(find_interpreter
"$interpreter")
744 if [ $?
-ne 0 ] ; then
745 echo "no binfmt interpreter using $(basename "$interpreter")" 1>&2
751 if [ $?
-ne 0 ]; then
752 echo "'debootstrap' command is missing"
756 if [ -z "$path" ]; then
757 echo "'path' parameter is required"
761 if [ "$(id -u)" != "0" ]; then
762 echo "This script should be run as 'root'"
766 if [ -n "$authkey" ]; then
767 if [ ! -f "$authkey" ]; then
768 echo "SSH keyfile '$authkey' not found"
771 # This is mostly to prevent accidental uage of the private key instead
773 if [ "${authkey: -4}" != ".pub" ]; then
774 echo "SSH keyfile '$authkey' does not end with '.pub'"
779 current_release
=$
(wget
"${MIRROR}/dists/stable/Release" -O - 2> /dev
/null |
head |
awk '/^Codename: (.*)$/ { print $2; }')
780 release
=${release:-${current_release}}
781 valid_releases
=('wheezy' 'jessie' 'stretch' 'sid')
782 if [[ ! "${valid_releases[*]}" =~
(^|
[^
[:alpha
:]])$release([^
[:alpha
:]]|$
) ]]; then
783 echo "Invalid release ${release}, valid ones are: ${valid_releases[*]}"
788 config
="$path/config"
789 if [ -z "$rootfs" ]; then
790 if grep -q '^lxc.rootfs.path' "$config" 2> /dev
/null
; then
791 rootfs
=$
(awk -F= '/^lxc.rootfs.path[ \t]+=/{ print $2 }' "$config")
797 # determine the number of ttys - default is 4
798 if grep -q '^lxc.tty.max' "$config" 2> /dev
/null
; then
799 num_tty
=$
(awk -F= '/^lxc.tty.max[ \t]+=/{ print $2 }' "$config")
804 install_debian
"$rootfs" "$release" "$arch" "$LXC_CACHE_PATH" "$interpreter" "$interpreter_path" "$flushcache"
805 if [ $?
-ne 0 ]; then
806 echo "failed to install debian"
810 configure_debian
"$rootfs" "$name" $num_tty
811 if [ $?
-ne 0 ]; then
812 echo "failed to configure debian for a container"
816 copy_configuration
"$path" "$rootfs" "$name" $arch $num_tty
817 if [ $?
-ne 0 ]; then
818 echo "failed write configuration file"
822 configure_debian_systemd
"$path" "$rootfs" "$config" $num_tty
824 post_process
"${rootfs}" "${release}" ${arch} ${hostarch} "${interpreter}" "${packages}"
826 if [ ! -z "$clean" ]; then