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://deb.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 # just in case systemd is not installed
242 mkdir
-p "${rootfs}/lib/systemd/system"
243 mkdir
-p "${rootfs}/etc/systemd/system/getty.target.wants"
245 # Fix getty-static-service as debootstrap does not install dbus
246 if [ -e "$rootfs//lib/systemd/system/getty-static.service" ] ; then
248 tty_services
=$
(for i
in $
(seq 2 "$num_tty"); do echo -n "getty@tty${i}.service "; done; )
249 sed 's/ getty@tty.*/'" $tty_services "'/g' \
250 "$rootfs/lib/systemd/system/getty-static.service" | \
251 sed 's/\(tty2-tty\)[5-9]/\1'"${num_tty}"'/g' > "$rootfs/etc/systemd/system/getty-static.service"
254 # This function has been copied and adapted from lxc-fedora
255 rm -f "${rootfs}/etc/systemd/system/default.target"
256 chroot
"${rootfs}" ln -s /dev
/null
/etc
/systemd
/system
/udev.service
257 chroot
"${rootfs}" ln -s /dev
/null
/etc
/systemd
/system
/systemd-udevd.service
258 chroot
"${rootfs}" ln -s /lib
/systemd
/system
/multi-user.target
/etc
/systemd
/system
/default.target
259 # Setup getty service on the ttys we are going to allow in the
260 # default config. Number should match lxc.tty.max
261 ( cd "${rootfs}/etc/systemd/system/getty.target.wants"
262 for i
in $
(seq 1 "$num_tty") ; do ln -sf ..
/getty\@.service getty@tty
"${i}".service
; done )
264 # Since we use static-getty.target; we need to mask container-getty@.service generated by
265 # container-getty-generator, so we don't get multiple instances of agetty running.
266 # See https://github.com/lxc/lxc/issues/520 and https://github.com/lxc/lxc/issues/484
267 ( cd "${rootfs}/etc/systemd/system/getty.target.wants"
268 for i
in $
(seq 0 "$num_tty"); do ln -sf /dev
/null container-getty\@
"${i}".service
; done )
273 # Check if given path is in a btrfs partition
276 [ -e "$1" -a "$(stat -f -c '%T' "$1")" = "btrfs" ]
279 # Check if given path is the root of a btrfs subvolume
282 [ -d "$1" -a "$(stat -f -c '%T' "$1")" = "btrfs" -a "$(stat -c '%i' "$1")" -eq 256 ]
288 [ -d "$path" ] && return 0
289 mkdir
-p "$(dirname "$path")"
290 if which btrfs
>/dev
/null
2>&1 && is_btrfs
"$(dirname "$path")"; then
291 btrfs subvolume create
"$path"
300 [ -d "$path" ] ||
return 0
301 if which btrfs
>/dev
/null
2>&1 && is_btrfs_subvolume
"$path"; then
302 btrfs subvolume delete
"$path"
310 try_rmsubvolume
"$cache/partial-$release-$arch"
311 try_rmsubvolume
"$cache/rootfs-$release-$arch"
339 interpreter_path
="$5"
341 trap cleanup EXIT SIGHUP SIGINT SIGTERM
346 # If debian-archive-keyring isn't installed, fetch GPG keys directly
347 releasekeyring
=/usr
/share
/keyrings
/debian-archive-keyring.gpg
348 if [ ! -f $releasekeyring ]; then
349 releasekeyring
="$cache/archive-key.gpg"
352 gpgkeyname
="archive-key-7.0"
355 gpgkeyname
="archive-key-8"
358 wget https
://ftp-master.debian.org
/keys
/${gpgkeyname}.asc
-O - --quiet \
359 | gpg
--import --no-default-keyring --keyring="${releasekeyring}"
361 # check the mini debian was not already downloaded
362 try_mksubvolume
"$cache/partial-$release-$arch"
363 if [ $?
-ne 0 ]; then
364 echo "Failed to create '$cache/partial-$release-$arch' directory"
368 # download a mini debian into a cache
369 echo "Downloading debian minimal ..."
370 if [ "$interpreter" = "" ] ; then
371 debootstrap
--verbose --variant=minbase
--arch="$arch" \
372 --include=$packages --keyring="${releasekeyring}" \
373 "$release" "$cache/partial-$release-$arch" "$MIRROR"
374 if [ $?
-ne 0 ]; then
375 echo "Failed to download the rootfs, aborting."
379 debootstrap
--foreign --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."
386 mkdir
-p "$(basename "$cache/partial-
$release-$arch/$interpreter_path")"
387 cp "$interpreter" "$cache/partial-$release-$arch/$interpreter_path"
388 if [ $?
-ne 0 ]; then
389 echo "failed to copy $interpreter to $cache/partial-$release-$arch/$interpreter_path"
392 chroot
"$cache/partial-$release-$arch" debootstrap
/debootstrap
--second-stage
393 if [ $?
-ne 0 ]; then
394 echo "failed to update the rootfs, aborting"
399 mv "$1/partial-$release-$arch" "$1/rootfs-$release-$arch"
400 echo "Download complete."
416 # make a local copy of the minidebian
417 echo -n "Copying rootfs to $rootfs..."
418 try_mksubvolume
"$rootfs"
419 if which btrfs
>/dev
/null
2>&1 && \
420 is_btrfs_subvolume
"$cache/rootfs-$release-$arch" && \
421 is_btrfs_subvolume
"$rootfs"; then
422 realrootfs
="$(dirname "$config")"/rootfs
423 [ "$rootfs" = "$realrootfs" ] || umount
"$rootfs" ||
return 1
424 btrfs subvolume delete
"$realrootfs" ||
return 1
425 btrfs subvolume snapshot
"$cache/rootfs-$release-$arch" "$realrootfs" ||
return 1
426 [ "$rootfs" = "$realrootfs" ] || mount
--bind "$realrootfs" "$rootfs" ||
return 1
428 rsync
-SHaAX "$cache/rootfs-$release-$arch"/ $rootfs/ ||
return 1
440 interpreter_path
="$6"
442 mkdir
-p $LOCALSTATEDIR/lock
/subsys
/
445 if [ $?
-ne 0 ]; then
446 echo "Cache repository is busy."
450 if [ "$flushcache" -eq 1 ]; then
451 echo "Flushing cache..."
455 echo "Checking cache download in $cache/rootfs-$release-$arch ... "
456 if [ ! -e "$cache/rootfs-$release-$arch" ]; then
457 download_debian
"$cache" "$arch" "$release" "$interpreter" "$interpreter_path"
458 if [ $?
-ne 0 ]; then
459 echo "Failed to download 'debian base'"
464 copy_debian
"$cache" "$arch" "$rootfs" "$release"
465 if [ $?
-ne 0 ]; then
466 echo "Failed to copy rootfs"
472 ) 9>$LOCALSTATEDIR/lock
/subsys
/lxc-debian
485 # Generate the configuration file
486 # if there is exactly one veth network entry, make sure it has an
488 nics
=$
(grep -ce '^lxc\.net\.0\.type[ \t]*=[ \t]*veth' "$path/config")
489 if [ "$nics" -eq 1 ]; then
490 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"
493 ## Add all the includes
494 echo "" >> "$path/config"
495 echo "# Common configuration" >> "$path/config"
496 if [ -e "${LXC_TEMPLATE_CONFIG}/debian.common.conf" ]; then
497 echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/debian.common.conf" >> "$path/config"
499 if [ -e "${LXC_TEMPLATE_CONFIG}/debian.${release}.conf" ]; then
500 echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/debian.${release}.conf" >> "$path/config"
503 ## Add the container-specific config
504 echo "" >> "$path/config"
505 echo "# Container specific configuration" >> "$path/config"
506 grep -q "^lxc.rootfs.path" "$path/config" 2> /dev
/null ||
echo "lxc.rootfs.path = $rootfs" >> "$path/config"
508 cat <<EOF >> $path/config
509 lxc.tty.max = $num_tty
510 lxc.uts.name = $hostname
515 if [ $?
-ne 0 ]; then
516 echo "Failed to add configuration"
525 local rootfs
="$1"; shift
526 local release
="$1"; shift
527 local arch
="$1"; shift
528 local hostarch
="$1"; shift
529 local interpreter
="$1"; shift
532 # Disable service startup
533 cat > "${rootfs}/usr/sbin/policy-rc.d" << EOF
537 chmod +x
"${rootfs}/usr/sbin/policy-rc.d"
539 # If the container isn't running a native architecture, setup multiarch
540 if [ "$interpreter" = "" -a "${arch}" != "${hostarch}" ]; then
541 # Test if dpkg supports multiarch
542 if ! chroot
"$rootfs" dpkg
--print-foreign-architectures 2>&1; then
543 chroot
"$rootfs" dpkg
--add-architecture "${hostarch}"
547 # Write a new sources.list containing both native and multiarch entries
548 > "${rootfs}/etc/apt/sources.list"
549 if [ "$interpreter" != "" -a "${arch}" = "${hostarch}" ]; then
550 write_sourceslist
"${rootfs}" "${release}" "${arch}"
552 write_sourceslist
"${rootfs}" "${release}"
555 # Install Packages in container
556 if [ -n "${packages}" ]; then
558 pack_list
="${packages//,/ }"
559 echo "Installing packages: ${pack_list}"
560 install_packages
"${rootfs}" "${pack_list}"
563 # Re-enable service startup
564 rm "${rootfs}/usr/sbin/policy-rc.d"
571 cache
=${LXC_CACHE_PATH:-"$LOCALSTATEDIR/cache/lxc/debian"}
573 if [ ! -e "$cache" ]; then
577 # lock, so we won't purge while someone is creating a repository
581 echo "Cache repository is busy."
585 echo -n "Purging the download cache..."
586 rm --preserve-root --one-file-system -rf "$cache" && echo "Done." ||
exit 1
589 ) 9>$LOCALSTATEDIR/lock
/subsys
/lxc-debian
595 Template specific options can be passed to lxc-create after a '--' like this:
597 lxc-create --name=NAME [-lxc-create-options] -- [-template-options]
599 Usage: $1 -h|--help -p|--path=<path> [-c|--clean] [-a|--arch=<arch>] [-r|--release=<release>]
600 [--mirror=<mirror>] [--security-mirror=<security mirror>]
601 [--package=<package_name1,package_name2,...>]
602 [-I|--interpreter-path=<interpreter path>]
603 [-F | --flush-cache] [-S|--auth-key=<keyfile>]
607 -h, --help print this help text
608 -p, --path=PATH directory where config and rootfs of this VM will be kept
609 -S, --auth-key=KEYFILE SSH public key to inject into the container as the root user.
610 -a, --arch=ARCH The container architecture. Can be one of: i686, x86_64,
611 amd64, armhf, armel, powerpc. Defaults to host arch.
612 -r, --release=RELEASE Debian release. Can be one of: wheezy, jessie, stretch, buster, sid.
613 Defaults to current stable.
614 --mirror=MIRROR Debian mirror to use during installation. Overrides the MIRROR
615 environment variable (see below).
616 --security-mirror=SECURITY_MIRROR
617 Debian mirror to use for security updates. Overrides the
618 SECURITY_MIRROR environment variable (see below).
619 --packages=PACKAGE_NAME1,PACKAGE_NAME2,...
620 List of additional packages to install. Comma separated, without space.
621 -c, --clean only clean up the cache and terminate
622 --enable-non-free include also Debian's contrib and non-free repositories.
623 -I|--interpreter-path=INTERPRETER-PATH
624 Path of the binfmt interpreter to copy to the rootfs
625 -F | --flush-cache Flush the debian release cache
627 Environment variables:
629 MIRROR The Debian package mirror to use. See also the --mirror switch above.
630 Defaults to '$MIRROR'
631 SECURITY_MIRROR The Debian package security mirror to use. See also the --security-mirror switch above.
632 Defaults to '$SECURITY_MIRROR'
638 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
-- "$@")
639 if [ $?
-ne 0 ]; then
640 usage
"$(basename "$0")"
643 eval set -- "$options"
645 littleendian
=$
(lscpu |
grep '^Byte Order' |
grep -q Little
&& echo yes)
648 if [ "$arch" = "i686" ]; then
650 elif [ "$arch" = "x86_64" ]; then
652 elif [ "$arch" = "armv7l" ]; then
654 elif [ "$arch" = "aarch64" ]; then
656 elif [ "$arch" = "ppc" ]; then
658 elif [ "$arch" = "ppc64le" ]; then
660 elif [ "$arch" = "mips" -a "$littleendian" = "yes" ]; then
662 elif [ "$arch" = "mips64" -a "$littleendian" = "yes" ]; then
672 -h|
--help) usage
"$0" && exit 1;;
673 --) shift 1; break ;;
675 -a|
--arch) arch
=$2; shift 2;;
676 -S|
--auth-key) authkey
=$2; shift 2;;
677 -I|
--interpreter-path)
678 interpreter
="$2"; shift 2;;
679 -c|
--clean) clean
=1; shift 1;;
680 --enable-non-free) mainonly
=0; shift 1;;
681 --mirror) MIRROR
=$2; shift 2;;
682 -n|
--name) name
=$2; shift 2;;
683 --packages) packages
=$2; shift 2;;
684 -p|
--path) path
=$2; shift 2;;
685 -r|
--release) release
=$2; shift 2;;
686 --rootfs) rootfs
=$2; shift 2;;
687 --security-mirror) SECURITY_MIRROR
=$2; shift 2;;
688 -F|
--flush-cache) flushcache
=1; shift 1;;
693 if [ ! -z "$clean" -a -z "$path" ]; then
698 if [ "$arch" = "i686" ]; then
702 if [ "$arch" = "x86_64" ]; then
706 if [ "$interpreter" = "" ] ; then
707 if [ $hostarch = "i386" -a $arch = "amd64" ]; then
708 echo "can't create $arch container on $hostarch"
712 if [ $hostarch = "armhf" -o $hostarch = "armel" ] && \
713 [ $arch != "armhf" -a $arch != "armel" ]; then
714 echo "can't create $arch container on $hostarch"
718 if [ $hostarch = "powerpc" -a $arch != "powerpc" ]; then
719 echo "can't create $arch container on $hostarch"
723 if [ $hostarch = "mips" -a $arch != "mips" ] || \
724 [ $hostarch = "mipsel" -a $arch != "mipsel" ] || \
725 [ $hostarch = "mips64" -a $arch != "mips" -a $arch != "mips64" ] || \
726 [ $hostarch = "mips64el" -a $arch != "mipsel" -a $arch != "mips64el" ]; then
727 echo "can't create $arch container on $hostarch"
731 if ! file -b "${interpreter}" |
grep -q "statically linked" ; then
732 echo "'${interpreter}' must be statically linked" 1>&2
735 interpreter_path
=$
(find_interpreter
"$interpreter")
736 if [ $?
-ne 0 ] ; then
737 echo "no binfmt interpreter using $(basename "$interpreter")" 1>&2
743 if [ $?
-ne 0 ]; then
744 echo "'debootstrap' command is missing"
748 if [ -z "$path" ]; then
749 echo "'path' parameter is required"
753 if [ "$(id -u)" != "0" ]; then
754 echo "This script should be run as 'root'"
758 if [ -n "$authkey" ]; then
759 if [ ! -f "$authkey" ]; then
760 echo "SSH keyfile '$authkey' not found"
763 # This is mostly to prevent accidental uage of the private key instead
765 if [ "${authkey: -4}" != ".pub" ]; then
766 echo "SSH keyfile '$authkey' does not end with '.pub'"
771 current_release
=$
(wget
"${MIRROR}/dists/stable/Release" -O - 2> /dev
/null |
head |
awk '/^Codename: (.*)$/ { print $2; }')
772 release
=${release:-${current_release}}
773 valid_releases
=('wheezy' 'jessie' 'stretch' 'buster' 'sid')
774 if [[ ! "${valid_releases[*]}" =~
(^|
[^
[:alpha
:]])$release([^
[:alpha
:]]|$
) ]]; then
775 echo "Invalid release ${release}, valid ones are: ${valid_releases[*]}"
780 config
="$path/config"
781 if [ -z "$rootfs" ]; then
782 if grep -q '^lxc.rootfs.path' "$config" 2> /dev
/null
; then
783 rootfs
=$
(awk -F= '/^lxc.rootfs.path[ \t]+=/{ print $2 }' "$config")
789 # determine the number of ttys - default is 4
790 if grep -q '^lxc.tty.max' "$config" 2> /dev
/null
; then
791 num_tty
=$
(awk -F= '/^lxc.tty.max[ \t]+=/{ print $2 }' "$config")
796 install_debian
"$rootfs" "$release" "$arch" "$LXC_CACHE_PATH" "$interpreter" "$interpreter_path" "$flushcache"
797 if [ $?
-ne 0 ]; then
798 echo "failed to install debian"
802 configure_debian
"$rootfs" "$name" $num_tty
803 if [ $?
-ne 0 ]; then
804 echo "failed to configure debian for a container"
808 copy_configuration
"$path" "$rootfs" "$name" $arch $num_tty
809 if [ $?
-ne 0 ]; then
810 echo "failed write configuration file"
814 configure_debian_systemd
"$path" "$rootfs" "$config" $num_tty
816 post_process
"${rootfs}" "${release}" ${arch} ${hostarch} "${interpreter}" "${packages}"
818 if [ ! -z "$clean" ]; then