4 # template script for generating fedora container for LXC
8 # lxc: linux Container library
11 # Daniel Lezcano <daniel.lezcano@free.fr>
12 # Ramez Hanna <rhanna@informatiq.org>
13 # Michael H. Warfield <mhw@WittsEnd.com>
15 # This library is free software; you can redistribute it and/or
16 # modify it under the terms of the GNU Lesser General Public
17 # License as published by the Free Software Foundation; either
18 # version 2.1 of the License, or (at your option) any later version.
20 # This library is distributed in the hope that it will be useful,
21 # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 # Lesser General Public License for more details.
25 # You should have received a copy of the GNU Lesser General Public
26 # License along with this library; if not, write to the Free Software
27 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 default_path
=@LXCPATH@
32 # Some combinations of the tuning knobs below do not exactly make sense.
35 # If the "root_password" is non-blank, use it, else set a default.
36 # This can be passed to the script as an environment variable and is
37 # set by a shell conditional assignment. Looks weird but it is what it is.
39 # If the root password contains a ding ($) then try to expand it.
40 # That will pick up things like ${name} and ${RANDOM}.
41 # If the root password contains more than 3 consecutive X's, pass it as
42 # a template to mktemp and take the result.
44 # If root_display_password = yes, display the temporary root password at exit.
45 # If root_store_password = yes, store it in the configuration directory
46 # If root_prompt_password = yes, invoke "passwd" to force the user to change
47 # the root password after the container is created.
48 # If root_expire_password = yes, you will be prompted to change the root
49 # password at the first login.
51 # These are conditional assignments... The can be overridden from the
52 # preexisting environment variables...
54 # Make sure this is in single quotes to defer expansion to later!
55 # :{root_password='Root-${name}-${RANDOM}'}
56 : ${root_password='Root-${name}-XXXXXX'}
58 # Now, it doesn't make much sense to display, store, and force change
59 # together. But, we gotta test, right???
60 : ${root_display_password='no'}
61 : ${root_store_password='yes'}
62 # Prompting for something interactive has potential for mayhem
63 # with users running under the API... Don't default to "yes"
64 : ${root_prompt_password='no'}
66 # Expire root password? Default to yes, but can be overridden from
67 # the environment variable
68 : ${root_expire_password='yes'}
70 # These are only going into comments in the resulting config...
72 lxc_network_link
=lxcbr0
75 # Alow for weird remixes like the Raspberry Pi
77 # Use the Mitre standard CPE identifier for the release ID if possible...
78 # This may be in /etc/os-release or /etc/system-release-cpe. We
79 # should be able to use EITHER. Give preference to /etc/os-release for now.
81 # Detect use under userns (unsupported)
83 [ "$arg" = "--" ] && break
84 if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
85 echo "This template can't be used for unprivileged containers." 1>&2
86 echo "You may want to try the \"download\" template instead." 1>&2
91 # Make sure the usual locations are in PATH
92 export PATH
=$PATH:/usr
/sbin
:/usr
/bin
:/sbin
:/bin
94 if [ -e /etc
/os-release
]
96 # This is a shell friendly configuration file. We can just source it.
97 # What we're looking for in here is the ID, VERSION_ID and the CPE_NAME
99 echo "Host CPE ID from /etc/os-release: ${CPE_NAME}"
102 if [ "${CPE_NAME}" = "" -a -e /etc
/system-release-cpe
]
104 CPE_NAME
=$
(head -n1 /etc
/system-release-cpe
)
105 CPE_URI
=$
(expr ${CPE_NAME} : '\([^:]*:[^:]*\)')
106 if [ "${CPE_URI}" != "cpe:/o" ]
110 echo "Host CPE ID from /etc/system-release-cpe: ${CPE_NAME}"
111 # Probably a better way to do this but sill remain posix
112 # compatible but this works, shrug...
113 # Must be nice and not introduce convenient bashisms here.
114 ID
=$
(expr ${CPE_NAME} : '[^:]*:[^:]*:[^:]*:\([^:]*\)')
115 VERSION_ID
=$
(expr ${CPE_NAME} : '[^:]*:[^:]*:[^:]*:[^:]*:\([^:]*\)')
119 if [ "${CPE_NAME}" != "" -a "${ID}" = "fedora" -a "${VERSION_ID}" != "" ]
121 fedora_host_ver
=${VERSION_ID}
123 elif [ -e /etc
/redhat-release
]
125 # Only if all other methods fail, try to parse the redhat-release file.
126 fedora_host_ver
=$
( sed -e '/^Fedora /!d' -e 's/Fedora.*\srelease\s*\([0-9][0-9]*\)\s.*/\1/' < /etc
/redhat-release
)
127 if [ "$fedora_host_ver" != "" ]
136 # disable selinux in fedora
137 mkdir
-p $rootfs_path/selinux
138 echo 0 > $rootfs_path/selinux
/enforce
140 # Also kill it in the /etc/selinux/config file if it's there...
141 if [[ -f $rootfs_path/etc
/selinux
/config
]]
143 sed -i '/^SELINUX=/s/.*/SELINUX=disabled/' $rootfs_path/etc
/selinux
/config
146 # Nice catch from Dwight Engen in the Oracle template.
147 # Wantonly plagerized here with much appreciation.
148 if [ -f $rootfs_path/usr
/sbin
/selinuxenabled
]; then
149 mv $rootfs_path/usr
/sbin
/selinuxenabled
$rootfs_path/usr
/sbin
/selinuxenabled.lxcorig
150 ln -s /bin
/false
$rootfs_path/usr
/sbin
/selinuxenabled
153 # This is a known problem and documented in RedHat bugzilla as relating
154 # to a problem with auditing enabled. This prevents an error in
155 # the container "Cannot make/remove an entry for the specified session"
156 sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc
/pam.d
/login
157 sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc
/pam.d
/sshd
159 if [ -f ${rootfs_path}/etc
/pam.d
/crond
]
161 sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc
/pam.d
/crond
164 # In addition to disabling pam_loginuid in the above config files
165 # we'll also disable it by linking it to pam_permit to catch any
166 # we missed or any that get installed after the container is built.
168 # Catch either or both 32 and 64 bit archs.
169 if [ -f ${rootfs_path}/lib
/security
/pam_loginuid.so
]
171 ( cd ${rootfs_path}/lib
/security
/
172 mv pam_loginuid.so pam_loginuid.so.disabled
173 ln -s pam_permit.so pam_loginuid.so
177 if [ -f ${rootfs_path}/lib64
/security
/pam_loginuid.so
]
179 ( cd ${rootfs_path}/lib64
/security
/
180 mv pam_loginuid.so pam_loginuid.so.disabled
181 ln -s pam_permit.so pam_loginuid.so
185 # Set default localtime to the host localtime if not set...
186 if [ -e /etc
/localtime
-a ! -e ${rootfs_path}/etc
/localtime
]
188 # if /etc/localtime is a symlink, this should preserve it.
189 cp -a /etc
/localtime
${rootfs_path}/etc
/localtime
192 # Deal with some dain bramage in the /etc/init.d/halt script.
193 # Trim it and make it our own and link it in before the default
194 # halt script so we can intercept it. This also preventions package
195 # updates from interferring with our interferring with it.
197 # There's generally not much in the halt script that useful but what's
198 # in there from resetting the hardware clock down is generally very bad.
199 # So we just eliminate the whole bottom half of that script in making
200 # ourselves a copy. That way a major update to the init scripts won't
201 # trash what we've set up.
203 # This is mostly for legacy distros since any modern systemd Fedora
204 # release will not have this script so we won't try to intercept it.
205 if [ -f ${rootfs_path}/etc
/init.d
/halt
]
207 sed -e '/hwclock/,$d' \
208 < ${rootfs_path}/etc
/init.d
/halt \
209 > ${rootfs_path}/etc
/init.d
/lxc-halt
211 echo '$command -f' >> ${rootfs_path}/etc
/init.d
/lxc-halt
212 chmod 755 ${rootfs_path}/etc
/init.d
/lxc-halt
214 # Link them into the rc directories...
216 cd ${rootfs_path}/etc
/rc.d
/rc0.d
217 ln -s ..
/init.d
/lxc-halt S00lxc-halt
218 cd ${rootfs_path}/etc
/rc.d
/rc6.d
219 ln -s ..
/init.d
/lxc-halt S00lxc-reboot
223 # configure the network using the dhcp
224 cat <<EOF > ${rootfs_path}/etc/sysconfig/network-scripts/ifcfg-eth0
229 DHCP_HOSTNAME=\`hostname\`
236 cat <<EOF > ${rootfs_path}/etc/sysconfig/network
241 # set hostname on systemd Fedora systems
242 if [ $release -gt 14 ]; then
243 echo "${utsname}" > ${rootfs_path}/etc
/hostname
247 cat <<EOF > $rootfs_path/etc/hosts
248 127.0.0.1 localhost.localdomain localhost $utsname
249 ::1 localhost6.localdomain6 localhost6
252 # These mknod's really don't make any sense with modern releases of
253 # Fedora with systemd, devtmpfs, and autodev enabled. They are left
254 # here for legacy reasons and older releases with upstart and sysv init.
255 dev_path
="${rootfs_path}/dev"
258 mknod
-m 666 ${dev_path}/null c
1 3
259 mknod
-m 666 ${dev_path}/zero c
1 5
260 mknod
-m 666 ${dev_path}/random c
1 8
261 mknod
-m 666 ${dev_path}/urandom c
1 9
262 mkdir
-m 755 ${dev_path}/pts
263 mkdir
-m 1777 ${dev_path}/shm
264 mknod
-m 666 ${dev_path}/tty c
5 0
265 mknod
-m 666 ${dev_path}/tty0 c
4 0
266 mknod
-m 666 ${dev_path}/tty1 c
4 1
267 mknod
-m 666 ${dev_path}/tty2 c
4 2
268 mknod
-m 666 ${dev_path}/tty3 c
4 3
269 mknod
-m 666 ${dev_path}/tty4 c
4 4
270 mknod
-m 600 ${dev_path}/console c
5 1
271 mknod
-m 666 ${dev_path}/full c
1 7
272 mknod
-m 600 ${dev_path}/initctl p
273 mknod
-m 666 ${dev_path}/ptmx c
5 2
275 # setup console and tty[1-4] for login. note that /dev/console and
276 # /dev/tty[1-4] will be symlinks to the ptys /dev/lxc/console and
277 # /dev/lxc/tty[1-4] so that package updates can overwrite the symlinks.
278 # lxc will maintain these links and bind mount ptys over /dev/lxc/*
279 # since lxc.tty.dir is specified in the config.
281 # allow root login on console, tty[1-4], and pts/0 for libvirt
282 echo "# LXC (Linux Containers)" >>${rootfs_path}/etc
/securetty
283 echo "lxc/console" >>${rootfs_path}/etc
/securetty
284 echo "lxc/tty1" >>${rootfs_path}/etc
/securetty
285 echo "lxc/tty2" >>${rootfs_path}/etc
/securetty
286 echo "lxc/tty3" >>${rootfs_path}/etc
/securetty
287 echo "lxc/tty4" >>${rootfs_path}/etc
/securetty
288 echo "# For libvirt/Virtual Machine Monitor" >>${rootfs_path}/etc
/securetty
289 echo "pts/0" >>${rootfs_path}/etc
/securetty
291 if [ ${root_display_password} = "yes" ]
293 echo "Setting root password to '$root_password'"
295 if [ ${root_store_password} = "yes" ]
297 touch ${config_path}/tmp_root_pass
298 chmod 600 ${config_path}/tmp_root_pass
299 echo ${root_password} > ${config_path}/tmp_root_pass
300 echo "Storing root password in '${config_path}/tmp_root_pass'"
303 echo "root:$root_password" | chroot
$rootfs_path chpasswd
305 if [ ${root_expire_password} = "yes" ]
307 # Also set this password as expired to force the user to change it!
308 chroot
$rootfs_path passwd
-e root
311 # specifying this in the initial packages doesn't always work.
312 # Even though it should have...
313 echo "installing fedora-release package"
314 mount
-o bind /dev
${rootfs_path}/dev
315 mount
-t proc proc
${rootfs_path}/proc
316 # Always make sure /etc/resolv.conf is up to date in the target!
317 cp /etc
/resolv.conf
${rootfs_path}/etc
/
318 # Rebuild the rpm database based on the target rpm version...
319 rm -f ${rootfs_path}/var
/lib
/rpm
/__db
*
320 chroot
${rootfs_path} rpm
--rebuilddb
321 chroot
${rootfs_path} yum
-y install fedora-release
323 if [[ ! -e ${rootfs_path}/sbin
/NetworkManager
]]
325 # NetworkManager has not been installed. Use the
326 # legacy chkconfig command to enable the network startup
327 # scripts in the container.
328 chroot
${rootfs_path} chkconfig network on
331 umount
${rootfs_path}/proc
332 umount
${rootfs_path}/dev
334 # silence some needless startup errors
335 touch ${rootfs_path}/etc
/fstab
337 # give us a console on /dev/console
338 sed -i 's/ACTIVE_CONSOLES=.*$/ACTIVE_CONSOLES="\/dev\/console \/dev\/tty[1-4]"/' \
339 ${rootfs_path}/etc
/sysconfig
/init
344 configure_fedora_init
()
346 sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc
/rc.sysinit
347 sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc
/rc.d
/rc.sysinit
348 # don't mount devpts, for pete's sake
349 sed -i 's/^.*dev.pts.*$/#\0/' ${rootfs_path}/etc
/rc.sysinit
350 sed -i 's/^.*dev.pts.*$/#\0/' ${rootfs_path}/etc
/rc.d
/rc.sysinit
351 chroot
${rootfs_path} chkconfig udev-post off
352 chroot
${rootfs_path} chkconfig network on
354 if [ -d ${rootfs_path}/etc
/init
]
356 # This is to make upstart honor SIGPWR. Should do no harm
357 # on systemd systems and some systems may have both.
358 cat <<EOF >${rootfs_path}/etc/init/power-status-changed.conf
359 # power-status-changed - shutdown on SIGPWR
361 start on power-status-changed
363 exec /sbin/shutdown -h now "SIGPWR received"
368 configure_fedora_systemd
()
370 rm -f ${rootfs_path}/etc
/systemd
/system
/default.target
371 touch ${rootfs_path}/etc
/fstab
372 chroot
${rootfs_path} ln -s /dev
/null
/etc
/systemd
/system
/udev.service
373 chroot
${rootfs_path} ln -s /lib
/systemd
/system
/multi-user.target
/etc
/systemd
/system
/default.target
374 # Make systemd honor SIGPWR
375 chroot
${rootfs_path} ln -s /usr
/lib
/systemd
/system
/halt.target
/etc
/systemd
/system
/sigpwr.target
377 # if desired, prevent systemd from over-mounting /tmp with tmpfs
378 if [ $masktmp -eq 1 ]; then
379 chroot
${rootfs_path} ln -s /dev
/null
/etc
/systemd
/system
/tmp.mount
382 #dependency on a device unit fails it specially that we disabled udev
383 # sed -i 's/After=dev-%i.device/After=/' ${rootfs_path}/lib/systemd/system/getty\@.service
385 # Actually, the After=dev-%i.device line does not appear in the
386 # Fedora 17 or Fedora 18 systemd getty\@.service file. It may be left
387 # over from an earlier version and it's not doing any harm. We do need
388 # to disable the "ConditionalPathExists=/dev/tty0" line or no gettys are
389 # started on the ttys in the container. Lets do it in an override copy of
390 # the service so it can still pass rpm verifies and not be automatically
391 # updated by a new systemd version. -- mhw /\/\|=mhw=|\/\/
393 sed -e 's/^ConditionPathExists=/# ConditionPathExists=/' \
394 -e 's/After=dev-%i.device/After=/' \
395 < ${rootfs_path}/lib
/systemd
/system
/getty\@.service \
396 > ${rootfs_path}/etc
/systemd
/system
/getty\@.service
397 # Setup getty service on the 4 ttys we are going to allow in the
398 # default config. Number should match lxc.tty
399 ( cd ${rootfs_path}/etc
/systemd
/system
/getty.target.wants
400 for i
in 1 2 3 4 ; do ln -sf ..
/getty\@.service getty@tty
${i}.service
; done )
403 ### BEGIN Bootstrap Environment Code... Michael H. Warfield /\/\|=mhw=|\/\/
405 # Ok... Heads up. If you're reading these comments, you're either a
406 # template owner or someone wondering how the hell I did this (or, worse,
407 # someone in the future trying to maintain it). This code is slightly
408 # "evil coding bastard" code with one significant hack / dirty trick
409 # that you would probably miss just reading the code below. I'll mark
410 # it out with comments.
412 # Because of what this code does, it deserves a lot of comments so people
413 # can understand WHY I did it this way...
415 # Ultimate Objective - Build a Fedora container on a host system which does
416 # not have a (complete compatible) version of rpm and/or yum. That basically
417 # means damn near any distro other than Fedora and Ubuntu (which has rpm and
418 # yum available). Only requirements for this function are rsync and
419 # squashfs available to the kernel. If you don't have those, why are you
420 # even attempting to build containers?
422 # Challenge for this function - Bootstrap a Fedora install bootstrap
423 # run time environment which has all the pieces to run rpm and yum and
424 # from which we can build targets containers even where the host system
425 # has no support for rpm, yum, or fedora.
428 # Stage 0 - Download a Fedora LiveOS squashfs core (netinst core).
429 # Stage 1 - Extract filesystem from Stage 0 and update to full rpm & yum
430 # Stage 2 - Use Stage 1 to build a rootfs with python, rpm, and yum.
432 # Stage 2 becomes our bootstrap file system which can be cached
433 # and then used to build other arbitrary vesions of Fedora of a
434 # given architecture. Note that this only has to run once for
435 # Fedora on a given architecture since rpm and yum can build other
436 # versions. We'll arbitrarily pick Fedora 20 to build this. This
437 # will need to change as time goes on.
439 # Programmers Note... A future fall back may be to download the netinst
440 # iso image instead of the LiveOS squasfs image and work from that.
441 # That may be more general but will introduce another substep
442 # (mounting the iso) to the stage0 setup.
444 # This system is designed to be as autonomous as possible so all whitelists
445 # and controls are self-contained.
447 # Initial testing - Whitelist nobody. Build for everybody...
448 # Initial deployment - Whitelist Fedora.
449 # Long term - Whitelist Fedora, Debian, Ubuntu, CentOs, Scientific, and NST.
451 # List of distros which do not (should not) need a bootstrap (but we will test
452 # for rpm and yum none the less... OS SHOULD be taken from CPE values but
453 # Debian / Ubuntu doesn't support CPE yet.
455 # BOOTSTRAP_WHITE_LIST=""
456 BOOTSTRAP_WHITE_LIST
="fedora"
457 # BOOTSTRAP_WHITE_LIST="fedora debian ubuntu centos scientific sl nst"
463 fedora_get_bootstrap
()
465 echo "Bootstrap Environment testing..."
469 # We need rpm. No rpm - not possible to white list...
470 if ! which rpm
> /dev
/null
2>&1
475 # We need yum No yum - not possible to white list...
476 if ! which yum
> /dev
/null
2>&1
481 if [[ ${WHITE_LISTED} != 0 ]]
483 for OS
in ${BOOTSTRAP_WHITE_LIST}
485 if [[ ${ID} = ${OS} ]]
488 OS ${ID} is whitelisted. Installation Bootstrap Environment not required.
496 Fedora Installation Bootstrap Build..."
498 if ! which rsync
> /dev
/null
2>&1
501 Unable to locate rsync. Cravely bailing out before even attempting to build
502 an Installation Bootstrap Please install rsync and then rerun this process.
508 [[ -d ${cache_base} ]] || mkdir
-p ${cache_base}
512 # We know we don't have a cache directory of this version or we
513 # would have never reached this code to begin with. But we may
514 # have another Fedora cache directory from which we could run...
515 # We'll give a preference for close matches preferring higher over
516 # lower - which makes for really ugly code...
518 # Is this a "bashism" that will need cleaning up????
519 BOOTSTRAP_LIST
="$(( $release + 1 ))/rootfs $(( $release - 1 ))/rootfs \
520 $(( $release + 2 ))/rootfs $(( $release - 2 ))/rootfs \
521 $(( $release + 3 ))/rootfs $(( $release - 3 ))/rootfs \
524 for bootstrap
in ${BOOTSTRAP_LIST}
526 if [[ -d ${bootstrap} ]]
529 Existing Bootstrap found. Testing..."
531 mount
-o bind /dev
${bootstrap}/dev
532 mount
-t proc proc
${bootstrap}/proc
533 # Always make sure /etc/resolv.conf is up to date in the target!
534 cp /etc
/resolv.conf
${bootstrap}/etc
/
535 rm -f ${bootstrap}/var
/lib
/rpm
/__db
*
536 chroot
${bootstrap} rpm
--rebuilddb
537 chroot
${bootstrap} yum
-y update
539 umount
${bootstrap}/proc
540 umount
${bootstrap}/dev
545 BOOTSTRAP_DIR
="${cache_base}/${bootstrap}"
546 BOOTSTRAP_CHROOT
="chroot ${BOOTSTRAP_DIR} "
547 BOOTSTRAP_INSTALL_ROOT
=/run
/install
550 Functional Installation Bootstrap exists and appears to be completed.
551 Will use existing Bootstrap: ${BOOTSTRAP_DIR}
556 Installation Bootstrap in ${BOOTSTRAP_DIR} exists
557 but appears to be non-functional. Skipping... It should be removed.
562 TMP_BOOTSTRAP_DIR
=$
( mktemp
-d --tmpdir=${cache_base} bootstrap_XXXXXX
)
564 cd ${TMP_BOOTSTRAP_DIR}
566 mkdir squashfs stage0 stage1 bootstrap
569 # Download the LiveOS squashfs image
570 # mount image to "squashfs"
571 # mount contained LiveOS to stage0
573 # We're going to use the archives.fedoraproject.org mirror for the initial stages...
574 # 1 - It's generally up to date and complete
575 # 2 - It's has high bandwidth access
576 # 3 - It supports rsync and wildcarding (and we need both)
577 # 4 - Not all the mirrors carry the LiveOS images
579 if [[ ! -f ..
/LiveOS
/squashfs.img
]]
582 Downloading stage 0 LiveOS squashfs file system from archives.fedoraproject.org...
583 Have a beer or a cup of coffee. This will take a bit (~300MB).
585 sleep 3 # let him read it...
587 # Right now, we are using Fedora 20 for the inial bootstrap.
588 # We could make this the "current" Fedora rev (F > 15).
590 rsync
-av ${mirrorurl}/fedora
/linux
/releases
/20/Fedora
/$basearch/os
/LiveOS .
594 echo "Download of squashfs image complete."
598 Download of squashfs image failed.
603 echo "Using cached stage 0 LiveOS squashfs file system."
606 mount
-o loop ..
/LiveOS
/squashfs.img squashfs
611 Mount of LiveOS squashfs image failed! You mush have squashfs support
612 available to mount image. Unable to continue. Correct and retry
613 process later! LiveOS image not removed. Process may be rerun
614 without penalty of downloading LiveOS again. If LiveOS is corrupt,
615 remove ${cache_base}/LiveOS before rerunning to redownload.
620 mount
-o loop squashfs
/LiveOS
/rootfs.img stage0
625 Mount of LiveOS stage0 rootfs image failed! LiveOS download may be corrupt.
626 Remove ${cache_base}/LiveOS to force a new download or
627 troubleshoot cached image and then rerun process.
634 # Copy stage0 (which is ro) to stage1 area (rw) for modification.
635 # Unmount stage0 mounts - we're done with stage 0 at this point.
636 # Download our rpm and yum rpm packages.
637 # Force install of rpm and yum into stage1 image (dirty hack!)
639 echo "Stage 0 complete, building Stage 1 image...
640 This will take a couple of minutes. Patience..."
642 echo "Creating Stage 1 r/w copy of r/o Stage 0 squashfs image from LiveOS."
644 rsync
-aAHS stage
0/. stage
1/
651 # Setup stage1 image with pieces to run installs...
654 mount
-o bind /dev dev
655 mount
-t proc proc proc
656 # Always make sure /etc/resolv.conf is up to date in the target!
657 cp /etc
/resolv.conf etc
/
661 echo "Updating Stage 1 image with full rpm and yum packages"
663 # Retrieve our 2 rpm packages we need to force down the throat
664 # of this LiveOS image we're camped out on. This is the beginning
665 # of the butt ugly hack. Look close or you may missing it...
667 rsync
-av ${mirrorurl}/fedora
/linux
/releases
/20/Fedora
/$basearch/os
/Packages
/r
/rpm-
[0-9]* \
668 ${mirrorurl}/fedora
/linux
/releases
/20/Fedora
/$basearch/os
/Packages
/y
/yum-
[0-9]* .
671 # The --nodeps is STUPID but F15 had a bogus dependency on RawHide?!?!
672 chroot . rpm
-ivh --nodeps rpm-
* yum-
*
675 # The LiveOS image contains rpm (but not rpmdb) and yum (but not
676 # yummain.py - What the hell good does yum do with no
677 # yummain.py?!?! - Sigh...). It contains all the supporting
678 # pieces but the rpm database has not be initialized and it
679 # doesn't know all the dependences (seem to) have been met.
680 # So we do a "--nodeps" rpm install in the chrooted environment
681 # to force the installation of the full rpm and yum packages.
683 # For the purists - Yes, I know the rpm database is wildly out
684 # of whack now. That's why this is a butt ugly hack / dirty trick.
685 # But, this is just the stage1 image that we are going to discard as
686 # soon as the stage2 image is built, so we don't care. All we care
687 # is that the stage2 image ends up with all the pieces it need to
688 # run yum and rpm and that the stage2 rpm database is coherent.
690 # NOW we can really go to work!
693 # Download our Fedora Release rpm packages.
694 # Install fedora-release into bootstrap to initialize fs and databases.
695 # Install rpm, and yum into bootstrap image using yum
697 echo "Stage 1 creation complete. Building stage 2 Installation Bootstrap"
699 mount
-o bind ..
/bootstrap run
/install
700 rsync
-av ${mirrorurl}/fedora
/linux
/releases
/20/Fedora
/$basearch/os
/Packages
/f
/fedora-release-20
* .
702 # The --nodeps is STUPID but F15 had a bogus dependency on RawHide?!?!
703 chroot . rpm
--root /run
/install --nodeps -ivh fedora-release-
*
705 # yum will take $basearch from host, so force the arch we want
706 sed -i "s|\$basearch|$basearch|" .
/run
/install
/etc
/yum.repos.d
/*
708 chroot . yum
-y --nogpgcheck --installroot /run
/install install python rpm yum
714 # That's it! We should now have a viable installation BOOTSTRAP in
715 # bootstrap We'll do a yum update in that to verify and then
716 # move it to the cache location before cleaning up.
719 mount
-o bind /dev dev
720 mount
-t proc proc proc
721 # Always make sure /etc/resolv.conf is up to date in the target!
722 cp /etc
/resolv.conf etc
/
724 # yum will take $basearch from host, so force the arch we want
725 sed -i "s|\$basearch|$basearch|" .
/etc
/yum.repos.d
/*
727 chroot . yum
-y update
739 Build of Installation Bootstrap failed. Temp directory
740 not removed so it can be investigated.
745 # We know have a working run time environment in rootfs...
748 rm -rf ${TMP_BOOTSTRAP_DIR}
751 Build of Installation Bootstrap complete! We now return you to your
752 normally scheduled template creation.
756 BOOTSTRAP_DIR
="${cache_base}/bootstrap"
757 BOOTSTRAP_CHROOT
="chroot ${BOOTSTRAP_DIR} "
758 BOOTSTRAP_INSTALL_ROOT
=/run
/install
764 fedora_bootstrap_mounts
()
766 if [[ ${BOOTSTRAP} -ne 1 ]]
771 BOOTSTRAP_CHROOT
="chroot ${BOOTSTRAP_DIR} "
773 echo "Mounting Bootstrap mount points"
775 [[ -d ${BOOTSTRAP_DIR}/run
/install ]] || mkdir
-p ${BOOTSTRAP_DIR}/run
/install
777 mount
-o bind ${INSTALL_ROOT} ${BOOTSTRAP_DIR}/run
/install
778 mount
-o bind /dev
${BOOTSTRAP_DIR}/dev
779 mount
-t proc proc
${BOOTSTRAP_DIR}/proc
780 # Always make sure /etc/resolv.conf is up to date in the target!
781 cp /etc
/resolv.conf
${BOOTSTRAP_DIR}/etc
/
784 fedora_bootstrap_umounts
()
786 if [[ ${BOOTSTRAP} -ne 1 ]]
791 umount
${BOOTSTRAP_DIR}/proc
792 umount
${BOOTSTRAP_DIR}/dev
793 umount
${BOOTSTRAP_DIR}/run
/install
797 # This is the code to create the initial roofs for Fedora. It may
798 # require a run time environment by calling the routines above...
803 # check the mini fedora was not already downloaded
804 INSTALL_ROOT
=$cache/partial
805 mkdir
-p $INSTALL_ROOT
806 if [ $?
-ne 0 ]; then
807 echo "Failed to create '$INSTALL_ROOT' directory"
811 # download a mini fedora into a cache
812 echo "Downloading fedora minimal ..."
814 # These will get changed if it's decided that we need a
815 # boostrap environment (can not build natively). These
816 # are the defaults for the non-boostrap (native) mode.
818 BOOTSTRAP_INSTALL_ROOT
=${INSTALL_ROOT}
822 PKG_LIST
="yum initscripts passwd rsyslog vim-minimal openssh-server openssh-clients dhclient chkconfig rootfiles policycoreutils fedora-release"
823 MIRRORLIST_URL
="http://mirrors.fedoraproject.org/mirrorlist?repo=fedora-$release&arch=$basearch"
825 if [[ ${release} -lt 17 ]]
827 # The reflects the move of db_dump and db_load from db4_utils to
828 # libdb_utils in Fedora 17 and above and it's inclusion as a dep...
829 # Prior to Fedora 11, we need to explicitly include it!
830 PKG_LIST
="${PKG_LIST} db4-utils"
833 if [[ ${release} -ge 21 ]]
835 # Since Fedora 21, a separate fedora-repos package is needed.
836 # Before, the information was conained in fedora-release.
837 PKG_LIST
="${PKG_LIST} fedora-repos"
842 # We're splitting the old loop into two loops plus a directory retrival.
843 # First loop... Try and retrive a mirror list with retries and a slight
844 # delay between attempts...
845 for trynumber
in 1 2 3 4; do
846 [ $trynumber != 1 ] && echo "Trying again..."
847 # This code is mildly "brittle" in that it assumes a certain
848 # page format and parsing HTML. I've done worse. :-P
849 MIRROR_URLS
=$
(curl
-s -S -f "$MIRRORLIST_URL" |
sed -e '/^http:/!d' -e '2,6!d')
850 if [ $?
-eq 0 ] && [ -n "$MIRROR_URLS" ]
855 echo "Failed to get a mirror on try $trynumber"
859 # This will fall through if we didn't get any URLS above
860 for MIRROR_URL
in ${MIRROR_URLS}
862 if [ "$release" -gt "16" ]; then
863 RELEASE_URL
="$MIRROR_URL/Packages/f"
865 RELEASE_URL
="$MIRROR_URL/Packages/"
868 echo "Fetching release rpm name from $RELEASE_URL..."
869 # This code is mildly "brittle" in that it assumes a certain directory
870 # page format and parsing HTML. I've done worse. :-P
871 RELEASE_RPM
=$
(curl
-L -f "$RELEASE_URL" |
sed -e "/fedora-release-${release}-/!d" -e 's/.*<a href=\"//' -e 's/\">.*//' )
872 if [ $?
-ne 0 -o "${RELEASE_RPM}" = "" ]; then
873 echo "Failed to identify fedora release rpm."
877 echo "Fetching fedora release rpm from ${RELEASE_URL}/${RELEASE_RPM}......"
878 curl
-L -f "${RELEASE_URL}/${RELEASE_RPM}" > ${INSTALL_ROOT}/${RELEASE_RPM}
879 if [ $? -ne 0 ]; then
880 echo "Failed to download fedora release rpm
${RELEASE_RPM}.
"
884 # F21 and newer need fedora-repos in addition to fedora-release.
885 if [ "$release" -ge "21" ]; then
886 echo "Fetching repos rpm name from
$RELEASE_URL...
"
887 REPOS_RPM=$(curl -L -f "$RELEASE_URL" | sed -e "/fedora-repos-
${release}-/!d
" -e 's/.*<a href=\"//' -e 's/\">.*//' )
888 if [ $? -ne 0 -o "${REPOS_RPM}" = "" ]; then
889 echo "Failed to identify fedora repos rpm.
"
893 echo "Fetching fedora repos rpm from
${RELEASE_URL}/${REPOS_RPM}...
"
894 curl -L -f "${RELEASE_URL}/${REPOS_RPM}" > ${INSTALL_ROOT}/${REPOS_RPM}
895 if [ $?
-ne 0 ]; then
896 echo "Failed to download fedora repos rpm ${RELEASE_RPM}."
906 if [ $DOWNLOAD_OK != yes ]; then
911 mkdir
-p ${INSTALL_ROOT}/var
/lib
/rpm
913 if ! fedora_get_bootstrap
915 echo "Fedora Bootstrap setup failed"
919 fedora_bootstrap_mounts
921 ${BOOTSTRAP_CHROOT}rpm
--root ${BOOTSTRAP_INSTALL_ROOT} --initdb
923 # The --nodeps is STUPID but F15 had a bogus dependency on RawHide?!?!
924 ${BOOTSTRAP_CHROOT}rpm --root ${BOOTSTRAP_INSTALL_ROOT} --nodeps -ivh ${BOOTSTRAP_INSTALL_ROOT}/${RELEASE_RPM}
926 # F21 and newer need fedora-repos in addition to fedora-release...
927 # Note that fedora-release and fedora-system have a mutual dependency.
928 # So installing the reops package after the release package we can
929 # spare one --nodeps.
930 if [ "$release" -ge "21" ]; then
931 ${BOOTSTRAP_CHROOT}rpm --root ${BOOTSTRAP_INSTALL_ROOT} -ivh ${BOOTSTRAP_INSTALL_ROOT}/${REPOS_RPM}
934 # yum will take $basearch from host, so force the arch we want
935 sed -i "s|\$basearch|$basearch|" ${BOOTSTRAP_DIR}/${BOOTSTRAP_INSTALL_ROOT}/etc
/yum.repos.d
/*
937 ${BOOTSTRAP_CHROOT}yum --installroot ${BOOTSTRAP_INSTALL_ROOT} -y --nogpgcheck install ${PKG_LIST}
941 if [[ ${BOOTSTRAP} -eq 1 ]]
943 # Here we have a bit of a sticky problem. We MIGHT have just installed
944 # this template cache using versions of yum and rpm in the bootstrap
945 # chroot that use a different database version than the target version.
946 # That can be a very big problem. Solution is to rebuild the rpmdatabase
947 # with the target database now that we are done building the cache. In the
948 # vast majority of cases, this is a do-not-care with no harm done if we
949 # didn't do it. But it catches several corner cases with older unsupported
950 # releases and it really doesn't cost us a lot of time for a one shot
951 # install that will never be done again for this rev.
953 # Thanks and appreciation to Dwight Engen and the Oracle template for the
954 # database rewrite hint!
956 echo "Fixing up rpm databases"
958 # Change to our target install directory (if we're not already
959 # there) just to simplify some of the logic to follow...
962 rm -f var
/lib
/rpm
/__db
*
963 # Programmers Note (warning):
965 # Pay careful attention to the following commands! It
966 # crosses TWO chroot boundaries linked by a bind mount!
967 # In the bootstrap case, that's the bind mount of ${INSTALL_ROOT}
968 # to the ${BOOTSTRAP_CHROOT}/run/install directory! This is
969 # a deliberate hack across that bind mount to do a database
970 # translation between two environments, neither of which may
971 # be the host environment! It's ugly and hard to follow but,
972 # if you don't understand it, don't mess with it! The pipe
973 # is in host space between the two chrooted environments!
974 # This is also why we cd'ed into the INSTALL_ROOT directory
975 # in advance of this loop, so everything is relative to the
976 # current working directory and congruent with the same working
977 # space in both chrooted environments. The output into the new
978 # db is also done in INSTALL_ROOT space but works in either host
979 # space or INSTALL_ROOT space for the mv, so we don't care. It's
980 # just not obvious what's happening in the db_dump and db_load
983 for db
in var
/lib
/rpm
/* ; do
984 ${BOOTSTRAP_CHROOT} db_dump
${BOOTSTRAP_INSTALL_ROOT}/$db | chroot . db_load
$db.new
987 # finish up by rebuilding the database...
988 # This should be redundant but we do it for completeness and
989 # any corner cases I may have missed...
990 mount
-t proc proc proc
991 mount
-o bind /dev dev
992 chroot . rpm
--rebuilddb
997 fedora_bootstrap_umounts
999 if [ ${RC} -ne 0 ]; then
1000 echo "Failed to download the rootfs, aborting."
1004 mv "$INSTALL_ROOT" "$cache/rootfs"
1005 echo "Download complete."
1013 # make a local copy of the minifedora
1014 echo -n "Copying rootfs to $rootfs_path ..."
1015 #cp -a $cache/rootfs-$basearch $rootfs_path || return 1
1016 # i prefer rsync (no reason really)
1017 mkdir
-p $rootfs_path
1018 rsync
-Ha $cache/rootfs
/ $rootfs_path/
1025 mount
-o bind /dev
${cache}/rootfs
/dev
1026 mount
-t proc proc
${cache}/rootfs
/proc
1027 # Always make sure /etc/resolv.conf is up to date in the target!
1028 cp /etc
/resolv.conf
${cache}/rootfs
/etc
/
1029 chroot
${cache}/rootfs yum
-y update
1030 umount
${cache}/rootfs
/proc
1031 umount
${cache}/rootfs
/dev
1036 mkdir
-p @LOCALSTATEDIR@
/lock
/subsys
/
1039 if [ $?
-ne 0 ]; then
1040 echo "Cache repository is busy."
1044 echo "Checking cache download in $cache/rootfs ... "
1045 if [ ! -e "$cache/rootfs" ]; then
1047 if [ $?
-ne 0 ]; then
1048 echo "Failed to download 'fedora base'"
1052 echo "Cache found. Updating..."
1054 if [ $?
-ne 0 ]; then
1055 echo "Failed to update 'fedora base', continuing with last known good cache"
1057 echo "Update finished"
1061 echo "Copy $cache/rootfs to $rootfs_path ... "
1063 if [ $?
-ne 0 ]; then
1064 echo "Failed to copy rootfs"
1069 ) 9>@LOCALSTATEDIR@
/lock
/subsys
/lxc-fedora
1074 # Generate a random hardware (MAC) address composed of FE followed by
1078 openssl rand
-hex 5 |
sed -e 's/\(..\)/:\1/g; s/^/fe/'
1081 copy_configuration
()
1083 mkdir
-p $config_path
1085 grep -q "^lxc.rootfs.path" $config_path/config
2>/dev
/null ||
echo "
1086 lxc.rootfs.path = $rootfs_path
1087 " >> $config_path/config
1089 # The following code is to create static MAC addresses for each
1090 # interface in the container. This code will work for multiple
1091 # interfaces in the default config. It will also strip any
1092 # hwaddr stanzas out of the default config since we can not share
1093 # MAC addresses between containers.
1094 mv $config_path/config
$config_path/config.def
1097 # This should catch variable expansions from the default config...
1098 if expr "${LINE}" : '.*\$' > /dev
/null
2>&1
1100 LINE
=$
(eval "echo \"${LINE}\"")
1103 # There is a tab and a space in the regex bracket below!
1104 # Seems that \s doesn't work in brackets.
1105 KEY
=$
(expr "${LINE}" : '\s*\([^ ]*\)\s*=')
1107 if [[ "${KEY}" != "lxc.net.0.hwaddr" ]]
1109 echo "${LINE}" >> $config_path/config
1111 if [[ "${KEY}" == "lxc.net.0.link" ]]
1113 echo "lxc.net.0.hwaddr = $(create_hwaddr)" >> $config_path/config
1116 done < $config_path/config.def
1118 rm -f $config_path/config.def
1120 if [ -e "@LXCTEMPLATECONFIG@/fedora.common.conf" ]; then
1122 # Include common configuration
1123 lxc.include = @LXCTEMPLATECONFIG@/fedora.common.conf
1124 " >> $config_path/config
1127 # Append things which require expansion here...
1128 cat <<EOF >> $config_path/config
1130 lxc.uts.name = $utsname
1132 # When using LXC with apparmor, uncomment the next line to run unconfined:
1133 #lxc.aa_profile = unconfined
1135 # example simple networking setup, uncomment to enable
1136 #lxc.net.0.type = $lxc_network_type
1137 #lxc.net.0.flags = up
1138 #lxc.net.0.link = $lxc_network_link
1139 #lxc.net.0.name = eth0
1140 # Additional example for veth network type
1141 # static MAC address,
1142 #lxc.net.0.hwaddr = 00:16:3e:77:52:20
1143 # persistent veth device name on host side
1144 # Note: This may potentially collide with other containers of same name!
1145 #lxc.net.0.veth.pair = v-$name-e0
1149 if [ $?
-ne 0 ]; then
1150 echo "Failed to add configuration"
1160 if [ ! -e $cache ]; then
1164 # lock, so we won't purge while someone is creating a repository
1167 if [ $?
!= 0 ]; then
1168 echo "Cache repository is busy."
1172 echo -n "Purging the download cache for Fedora-$release..."
1173 rm --preserve-root --one-file-system -rf $cache && echo "Done." ||
exit 1
1175 ) 9>@LOCALSTATEDIR@
/lock
/subsys
/lxc-fedora
1182 $1 -n|--name=<container_name>
1183 [-p|--path=<path>] [-c|--clean] [-R|--release=<Fedora_release>]
1184 [--fqdn=<network name of container>] [-a|--arch=<arch of the container>]
1188 -n,--name container name, used to as an identifier for that container
1190 -p,--path path to where the container will be created,
1191 defaults to @LXCPATH@.
1192 --rootfs path for actual rootfs.
1193 -c,--clean clean the cache
1194 -R,--release Fedora release for the new container.
1195 Defaults to host's release if the host is Fedora.
1196 --fqdn fully qualified domain name (FQDN) for DNS and system naming
1197 -a,--arch Define what arch the container will be [i686,x86_64]
1198 --mask-tmp Prevent systemd from over-mounting /tmp with tmpfs.
1199 -h,--help print this help
1204 options
=$
(getopt
-o a
:hp
:n
:cR
: -l help,path
:,rootfs
:,name
:,clean
,release
:,arch
:,fqdn
:,mask-tmp
-- "$@")
1205 if [ $?
-ne 0 ]; then
1206 usage $
(basename $0)
1213 eval set -- "$options"
1217 -h|
--help) usage
$0 && exit 0;;
1218 -p|
--path) path
=$2; shift 2;;
1219 --rootfs) rootfs_path
=$2; shift 2;;
1220 -n|
--name) name
=$2; shift 2;;
1221 -c|
--clean) clean
=1; shift 1;;
1222 -R|
--release) release
=$2; shift 2;;
1223 -a|
--arch) newarch
=$2; shift 2;;
1224 --fqdn) utsname
=$2; shift 2;;
1225 --mask-tmp) masktmp
=1; shift 1;;
1226 --) shift 1; break ;;
1231 if [ ! -z "$clean" -a -z "$path" ]; then
1237 # Map a few architectures to their generic Fedora repository archs.
1238 # The two ARM archs are a bit of a guesstimate for the v5 and v6
1239 # archs. V6 should have hardware floating point (Rasberry Pi).
1240 # The "arm" arch is safer (no hardware floating point). So
1241 # there may be cases where we "get it wrong" for some v6 other
1244 i686
) basearch
=i386
;;
1245 armv3l|armv4l|armv5l
) basearch
=arm
;;
1246 armv6l|armv7l|armv8l
) basearch
=armhfp
;;
1250 mirrorurl
="archives.fedoraproject.org::fedora-archive"
1252 ppc64|s390x
) mirrorurl
="archives.fedoraproject.org::fedora-secondary" ;;
1256 # Somebody wants to specify an arch. This is very limited case.
1257 # i386/i586/i686 on i386/x86_64
1260 if [ "${newarch}" != "" -a "${newarch}" != "${arch}" ]
1262 case "${newarch}" in
1264 if [ "${basearch}" = "i386" -o "${basearch}" = "x86_64" ]
1266 # Make the arch a generic x86 32 bit...
1278 if [ "${basearch}" = "bad" ]
1280 echo "You cannot build a ${newarch} Fedora container on a ${arch} host. Sorry!"
1285 # Allow the cache base to be set by environment variable
1286 cache_base
=${LXC_CACHE_PATH:-"@LOCALSTATEDIR@/cache/lxc"}/fedora
/$basearch
1288 # Let's do something better for the initial root password.
1289 # It's not perfect but it will defeat common scanning brute force
1290 # attacks in the case where ssh is exposed. It will also be set to
1291 # expired, forcing the user to change it at first login.
1292 if [ "${root_password}" = "" ]
1294 root_password
=Root-
${name}-${RANDOM}
1296 # If it's got a ding in it, try and expand it!
1297 if [ $
(expr "${root_password}" : '.*$.') != 0 ]
1299 root_password
=$
(eval echo "${root_password}")
1302 # If it has more than 3 consecutive X's in it, feed it
1303 # through mktemp as a template.
1304 if [ $
(expr "${root_password}" : '.*XXXX') != 0 ]
1306 root_password
=$
(mktemp
-u ${root_password})
1310 if [ -z "${utsname}" ]; then
1314 # This follows a standard "resolver" convention that an FQDN must have
1315 # at least two dots or it is considered a local relative host name.
1316 # If it doesn't, append the dns domain name of the host system.
1318 # This changes one significant behavior when running
1319 # "lxc_create -n Container_Name" without using the
1323 # utsname and hostname = Container_Name
1325 # utsname and hostname = Container_Name.Domain_Name
1327 if [ $
(expr "$utsname" : '.*\..*\.') = 0 ]; then
1328 if [[ "$(dnsdomainname)" != "" && "$(dnsdomainname)" != "localdomain" ]]; then
1329 utsname
=${utsname}.$
(dnsdomainname
)
1335 type curl
>/dev
/null
2>&1
1336 if [ $?
-ne 0 ]; then
1337 needed_pkgs
="curl $needed_pkgs"
1339 type openssl
>/dev
/null
2>&1
1340 if [ $?
-ne 0 ]; then
1341 needed_pkgs
="openssl $needed_pkgs"
1344 if [ -n "$needed_pkgs" ]; then
1345 echo "Missing commands: $needed_pkgs"
1346 echo "Please install these using \"sudo yum install $needed_pkgs\""
1350 if [ -z "$path" ]; then
1351 path
=$default_path/$name
1354 if [ -z "$release" ]; then
1355 if [ "$is_fedora" -a "$fedora_host_ver" ]; then
1356 release
=$fedora_host_ver
1358 echo "This is not a fedora host and release missing, defaulting to 22 use -R|--release to specify release"
1363 if [ "$(id -u)" != "0" ]; then
1364 echo "This script should be run as 'root'"
1368 if [ -z "$rootfs_path" ]; then
1369 rootfs_path
=$path/rootfs
1370 # check for 'lxc.rootfs.path' passed in through default config by lxc-create
1371 if grep -q '^lxc.rootfs.path' $path/config
2>/dev
/null
; then
1372 rootfs_path
=$
(sed -e '/^lxc.rootfs.path\s*=/!d' -e 's/\s*#.*//' \
1373 -e 's/^lxc.rootfs.path\s*=\s*//' -e q
$path/config
)
1377 cache
=$cache_base/$release
1381 echo "Interrupted, so cleaning up"
1382 lxc-destroy
-n $name
1383 # maybe was interrupted before copy config
1389 trap revert SIGHUP SIGINT SIGTERM
1392 if [ $?
-ne 0 ]; then
1393 echo "failed write configuration file"
1398 if [ $?
-ne 0 ]; then
1399 echo "failed to install fedora"
1404 if [ $?
-ne 0 ]; then
1405 echo "failed to configure fedora for a container"
1409 # If the systemd configuration directory exists - set it up for what we need.
1410 if [ -d ${rootfs_path}/etc
/systemd
/system
]
1412 configure_fedora_systemd
1415 # This configuration (rc.sysinit) is not inconsistent with the systemd stuff
1416 # above and may actually coexist on some upgraded systems. Let's just make
1417 # sure that, if it exists, we update this file, even if it's not used...
1418 if [ -f ${rootfs_path}/etc
/rc.sysinit
]
1420 configure_fedora_init
1423 if [ ! -z "$clean" ]; then
1428 Container rootfs and config have been created.
1429 Edit the config file to check/enable networking setup.
1432 if [[ -d ${cache_base}/bootstrap
]]
1434 echo "You have successfully built a Fedora container and cache. This cache may
1435 be used to create future containers of various revisions. The directory
1436 ${cache_base}/bootstrap contains a bootstrap
1437 which may no longer needed and can be removed.
1441 if [[ -e ${cache_base}/LiveOS
]]
1443 echo "A LiveOS directory exists at ${cache_base}/LiveOS.
1444 This is only used in the creation of the bootstrap run-time-environment
1449 if [ ${root_display_password} = "yes" ]
1451 echo "The temporary password for root is: '$root_password'
1453 You may want to note that password down before starting the container.
1457 if [ ${root_store_password} = "yes" ]
1459 echo "The temporary root password is stored in:
1461 '${config_path}/tmp_root_pass'
1465 if [ ${root_prompt_password} = "yes" ]
1467 echo "Invoking the passwd command in the container to set the root password.
1469 chroot ${rootfs_path} passwd
1471 chroot
${rootfs_path} passwd
1473 if [ ${root_expire_password} = "yes" ]
1475 if ( mountpoint
-q -- "${rootfs_path}" )
1477 echo "To reset the root password, you can do:
1479 lxc-start -n ${name}
1480 lxc-attach -n ${name} -- passwd
1485 The root password is set up as "expired
" and will require it to be changed
1486 at first login, which you should do as soon as possible. If you lose the
1487 root password or wish to change it without starting the container, you
1488 can change it from the host by running the following command (which will
1489 also reset the expired flag):
1491 chroot ${rootfs_path} passwd