[lxc-devel] [PATCH 1/1] templates/lxc-fedora Rework for distro independence.

Michael H. Warfield mhw at WittsEnd.com
Wed Oct 2 20:22:45 UTC 2013


This patch reworks the Fedora template to operate in the most "distro
agnostic" manner possible.  It should even run on distros where rpm and
yum are not present and not available or may be incompatible.  It
depends on the most basic set of system facilities like rsync but does
require squashfs support also be available to mount a LiveOS runtime.

Based on comments at Linux Plumbers, what I had been referring to as a
"run time environment" or RTE has been renamed in the code to refer to
it as a "bootstrap".  It has been tested on Fedora (of course),
OpenSuse, Ubuntu, and Oracle (latest host versions of each) building
Fedora containers of F19 back through F9.  Varying levels of database
problems were encountered from F11 and back and are "will not fix" due
to versions being long EOL.  F15 and F16 build but do not run "out of
the box" due to systemd version issues and those are also "will not fix"
for the same reasons.

Signed-off-by: Michael H. Warfield <mhw at WittsEnd.com>

-- 
diff --git a/templates/lxc-fedora.in b/templates/lxc-fedora.in
index 1386f23..d406012 100644
--- a/templates/lxc-fedora.in
+++ b/templates/lxc-fedora.in
@@ -10,6 +10,7 @@
 # Authors:
 # Daniel Lezcano <daniel.lezcano at free.fr>
 # Ramez Hanna <rhanna at informatiq.org>
+# Michael H. Warfield <mhw at WittsEnd.com>
 
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -29,6 +30,7 @@
 arch=$(uname -m)
 cache_base=@LOCALSTATEDIR@/cache/lxc/fedora/$arch
 default_path=@LXCPATH@
+# We really need something better here!
 root_password=root
 
 # is this fedora?
@@ -148,8 +150,19 @@ EOF
     echo "root:$root_password" | chroot $rootfs_path chpasswd
 
     # specifying this in the initial packages doesn't always work.
+    # Even though it should have...
     echo "installing fedora-release package"
-    chroot ${rootfs_path} yum --releasever=${release} -y install fedora-release
+    mount -o bind /dev ${rootfs_path}/dev
+    mount -t proc proc ${rootfs_path}/proc
+    # Always make sure /etc/resolv.conf is up to date in the target!
+    cp /etc/resolv.conf ${rootfs_path}/etc/
+    # Rebuild the rpm database based on the target rpm version...
+    rm -f ${rootfs_path}/var/lib/rpm/__db*
+    chroot ${rootfs_path} rpm --rebuilddb
+    chroot ${rootfs_path} yum -y install fedora-release
+    # This just makes sure the rpm db is synced to that version...
+    umount ${rootfs_path}/proc
+    umount ${rootfs_path}/dev
 
     # silence some needless startup errors
     touch ${rootfs_path}/etc/fstab
@@ -198,6 +211,396 @@ configure_fedora_systemd()
         for i in 1 2 3 4 ; do ln -sf ../getty\@.service getty at tty${i}.service; done )
 }
 
+### BEGIN Bootstrap Environment Code...  Michael H. Warfield /\/\|=mhw=|\/\/
+
+# Ok...  Heads up.  If you're reading these comments, you're either a
+# template owner or someone wondering how the hell I did this (or, worse,
+# someone in the future trying to maintain it).  This code is slightly
+# "evil coding bastard" code with one significant hack / dirty trick
+# that you would probably miss just reading the code below.  I'll mark
+# it out with comments.
+# 
+# Because of what this code does, it deserves a lot of comments so people
+# can understand WHY I did it this way...
+#
+# Ultimate Objective - Build a Fedora container on a host system which does
+# not have a (complete compatible) version of rpm and/or yum.  That basically
+# means damn near any distro other than Fedora and Ubuntu (which has rpm and
+# yum available).  Only requirements for this function are rsync and
+# squashfs available to the kernel.  If you don't have those, why are you
+# even attempting to build containers?
+#
+# Challenge for this function - Bootstrap a Fedora install bootstrap
+# run time environment which has all the pieces to run rpm and yum and
+# from which we can build targets containers even where the host system
+# has no support for rpm, yum, or fedora.
+#
+# Steps:
+#       Stage 0 - Download a Fedora LiveOS squashfs core (netinst core).
+#       Stage 1 - Extract filesystem from Stage 0 and update to full rpm & yum
+#       Stage 2 - Use Stage 1 to build a rootfs with python, rpm, and yum.
+#
+#       Stage 2 becomes our bootstrap file system which can be cached
+#       and then used to build other arbitrary vesions of Fedora of a
+#       given architecture.  Not that this only has to run once for
+#       Fedora on a given architecture since rpm and yum can build other
+#       versions.  We'll arbitrarily pick Fedora 19 to build this.  This
+#       will need to change as time goes on.
+
+# Programmers Note...  A future fall back may be to download the netinst
+#       iso image instead of the LiveOS squasfs image and work from that.
+#       That may be more general but will introduce another substep
+#       (mounting the iso) to the stage0 setup.
+
+# This system is designed to be as autonomous as possible so all whitelists
+# and controlls are self-contained.
+
+# Initial testing - Whitelist nobody.  Build for everybody...
+# Initial deployment - Whitelist Fedora.
+# Long term - Whitelist Fedora, Debian, Ubuntu, CentOs, Scientific, and NST.
+
+# List of distros which do not (should not) need a bootstrap (but we will test
+# for rpm and yum none the less...  OS SHOULD be taken from CPE values but
+# Debian / Ubuntu doesn't support CPE yet.
+
+# BOOTSTRAP_WHITE_LIST=""
+BOOTSTRAP_WHITE_LIST="fedora"
+# BOOTSTRAP_WHITE_LIST="fedora debian ubuntu centos scientific sl nst"
+
+BOOTSTRAP=0
+BOOTSTRAP_DIR=
+BOOTSTRAP_CHROOT=
+
+fedora_get_bootstrap()
+{
+    echo "Bootstrap Environment testing..."
+
+    WHITE_LISTED=1
+
+    # We need rpm.  No rpm - not possible to white list...
+    if ! which rpm > /dev/null 2>&1
+    then
+        WHITE_LISTED=0
+    fi
+
+    # We need yum  No yum - not possible to white list...
+    if ! which yum > /dev/null 2>&1
+    then
+        WHITE_LISTED=0
+    fi
+
+    if [[ ${WHITE_LISTED} != 0 ]]
+    then
+        for OS in ${BOOTSTRAP_WHITE_LIST}
+        do
+            if [[ ${ID} = ${OS} ]]
+            then
+                echo "
+OS ${ID} is whitelisted.  Installation Bootstrap Environment not required.
+"
+                return 0;
+            fi
+        done
+    fi
+
+    echo "
+Fedora Installation Bootstrap Build..."
+
+    if ! which rsync > /dev/null 2>&1
+    then
+        echo "
+Unable to locate rsync.  Cravely bailing out before even attempting to build
+an Installation Bootstrap  Please install rsync and then rerun this process.
+"
+
+        return 255
+    fi
+
+    [[ -d ${cache_base} ]] || mkdir -p ${cache_base}
+
+    cd ${cache_base}
+
+    # We know we don't have a cache directory of this version or we
+    # would have never reached this code to begin with.  But we may
+    # have another Fedora cache directory from which we could run...
+    # We'll give a preference for close matches prefering higher over
+    # lower - which makes for really ugly code...
+
+    # Is this a "bashism" that will need cleaning up????
+    BOOTSTRAP_LIST="$(( $release + 1 ))/rootfs $(( $release - 1 ))/rootfs \
+$(( $release + 2 ))/rootfs $(( $release - 2 ))/rootfs \
+$(( $release + 3 ))/rootfs $(( $release - 3 ))/rootfs \
+bootstrap"
+
+    for bootstrap in ${BOOTSTRAP_LIST}
+    do
+        if [[ -d ${bootstrap} ]]
+        then
+            echo "
+Existing Bootstrap found.  Testing..."
+
+            mount -o bind /dev ${bootstrap}/dev
+            mount -t proc proc ${bootstrap}/proc
+            # Always make sure /etc/resolv.conf is up to date in the target!
+            cp /etc/resolv.conf ${bootstrap}/etc/
+            rm -f ${bootstrap}/var/lib/rpm/__db*
+            chroot ${bootstrap} rpm --rebuilddb
+            chroot ${bootstrap} yum -y update
+            RC=$?
+            umount ${bootstrap}/proc
+            umount ${bootstrap}/dev
+
+            if [[ 0 == ${RC} ]]
+            then
+                BOOTSTRAP=1
+                BOOTSTRAP_DIR="${cache_base}/${bootstrap}"
+                BOOTSTRAP_CHROOT="chroot ${BOOTSTRAP_DIR} "
+                BOOTSTRAP_INSTALL_ROOT=/run/install
+
+            echo "
+Functional Installation Bootstrap exists and appears to be completed.
+Will use existing Bootstrap:  ${BOOTSTRAP_DIR}
+"
+            return 0
+        fi
+        echo "
+Installation Bootstrap in ${BOOTSTRAP_DIR} exists
+but appears to be non-functional.  Skipping...  It should be removed.
+"
+    fi
+    done
+
+    TMP_BOOTSTRAP_DIR=$( mktemp -d --tmpdir=${cache_base} bootstrap_XXXXXX )
+
+    cd ${TMP_BOOTSTRAP_DIR}
+
+    mkdir squashfs stage0 stage1 bootstrap
+
+### Stage 0 setup.
+#       Download the LiveOS squashfs image
+#       mount image to "squashfs"
+#       mount contained LiveOS to stage0
+
+# We're going to use the kernel.org mirror for the initial stages...
+#       1 - It's generally up to date and comnplete
+#       2 - It's has high bandwidth access
+#       3 - It supports rsync and wildcarding (and we need both)
+#       4 - Not all the mirrors carry the LiveOS images
+
+    if [[ ! -f ../LiveOS/squashfs.img ]]
+    then
+        echo "
+Downloading stage 0 LiveOS squashfs file system from mirrors.kernel.org...
+Have a beer or a cup of coffee.  This will take a bit (~300MB).
+"
+        sleep 3 # let him read it...
+
+        # Right now, we are using Fedora 19 for the inial bootstrap.
+        # We could make this the "current" Fedora rev (F > 15).
+
+        rsync -av mirrors.kernel.org::fedora/releases/19/Fedora/x86_64/os/LiveOS .
+
+        if [[ 0 == $? ]]
+        then
+            echo "Download of squashfs image complete."
+            mv LiveOS ..
+        else
+            echo "
+Download of squashfs image failed.
+"
+            return 255
+        fi
+    else
+        echo "Using cached stage 0 LiveOS squashfs file system."
+    fi
+
+    mount -o loop ../LiveOS/squashfs.img squashfs
+
+    if [[ $? != 0 ]]
+    then
+        echo "
+Mount of LiveOS squashfs image failed!  You mush have squashfs support
+available to mount image.  Unable to continue.  Correct and retry
+process later!  LiveOS image not removed.  Process may be rerun
+without penalty of downloading LiveOS again.  If LiveOS is corrupt,
+remove ${cache_base}/LiveOS before rerunning to redownload.
+"
+        return 255
+    fi
+
+    mount -o loop squashfs/LiveOS/rootfs.img stage0
+
+    if [[ $? != 0 ]]
+    then
+        echo "
+Mount of LiveOS stage0 rootfs image failed!  LiveOS download may be corrupt.
+Remove ${cache_base}/LiveOS to force a new download or
+troubleshoot cached image and then rerun process.
+"
+        return 255
+    fi
+
+
+### Stage 1 setup.
+#       Copy stage0 (which is ro) to stage1 area (rw) for modification.
+#       Unmount stage0 mounts - we're done with stage 0 at this point.
+#       Download our rpm and yum rpm packages.
+#       Force install of rpm and yum into stage1 image (dirty hack!)
+
+    echo "Stage 0 complete, building Stage 1 image...
+This will take a couple of minutes.  Patience..."
+
+    echo "Creating Stage 1 r/w copy of r/o Stage 0 squashfs image from LiveOS."
+
+    rsync -aAHS stage0/. stage1/
+
+    umount stage0
+    umount squashfs
+
+    cd stage1
+
+    # Setup stage1 image with pieces to run installs...
+
+
+    mount -o bind /dev dev
+    mount -t proc proc proc
+    # Always make sure /etc/resolv.conf is up to date in the target!
+    cp /etc/resolv.conf etc/
+
+    mkdir run/install
+
+    echo "Updating Stage 1 image with full rpm and yum packages"
+
+    # Retrieve our 2 rpm packages we need to force down the throat
+    # of this LiveOS image we're camped out on.  This is the beginning
+    # of the butt ugly hack.  Look close or you may missing it...
+
+    rsync -av mirrors.kernel.org::fedora/releases/19/Fedora/x86_64/os/Packages/r/rpm-[0-9]* \
+        mirrors.kernel.org::fedora/releases/19/Fedora/x86_64/os/Packages/y/yum-[0-9]* .
+
+    # And here it is...
+    # The --nodeps is STUPID but F15 had a bogus dependency on RawHide?!?!
+    chroot . rpm -ivh --nodeps rpm-* yum-*
+    # Did you catch it?
+
+    # The LiveOS image contains rpm (but not rpmdb) and yum (but not
+    # yummain.py - What the hell good does yum do with no
+    # yummain.py?!?! - Sigh...).  It contains all the supporting
+    # pieces but the rpm database has not be initialized and it
+    # doesn't know all the dependences (seem to) have been met.
+    # So we do a "--nodeps" rpm install in the chrooted environment
+    # to force the installation of the full rpm and yum packages.
+    #
+    # For the purists - Yes, I know the rpm database is wildly out
+    # of whack now.  That's why this is a butt ugly hack / dirty trick.
+    # But, this is just the stage1 image that we are going to discard as
+    # soon as the stage2 image is built, so we don't care.  All we care
+    # is that the stage2 image ends up with all the pieces it need to
+    # run yum and rpm and that the stage2 rpm database is coherent.
+    #
+    # NOW we can really go to work!
+
+### Stage 2 setup.
+#       Download our Fedora Release rpm packages.
+#       Install fedora-release into bootstrap to initialize fs and databases.
+#       Install rpm, and yum into bootstrap image using yum
+
+    echo "Stage 1 creation complete.  Building stage 2 Installation Bootstrap"
+
+    mount -o bind ../bootstrap run/install
+    rsync -av mirrors.kernel.org::fedora/releases/19/Fedora/x86_64/os/Packages/f/fedora-release-19* .
+
+    # The --nodeps is STUPID but F15 had a bogus dependency on RawHide?!?!
+    chroot . rpm --root /run/install --nodeps -ivh fedora-release-*
+    chroot . yum -y --nogpgcheck --installroot /run/install install python rpm yum
+
+    umount run/install
+    umount proc
+    umount dev
+
+#       That's it!  We should now have a viable installation BOOTSTRAP in
+#       bootstrap  We'll do a yum update in that to verify and then
+#       move it to the cache location before cleaning up.
+
+    cd ../bootstrap
+    mount -o bind /dev dev
+    mount -t proc proc proc
+    # Always make sure /etc/resolv.conf is up to date in the target!
+    cp /etc/resolv.conf etc/
+
+    chroot . yum -y update
+
+    RC=$?
+
+    umount proc
+    umount dev
+
+    cd ..
+
+    if [[ ${RC} != 0 ]]
+    then
+        echo "
+Build of Installation Bootstrap failed.  Temp directory
+not removed so it can be investigated.
+"
+        return 255
+    fi
+
+    # We know have a working run time environment in rootfs...
+    mv bootstrap ..
+    cd ..
+    rm -rf ${TMP_BOOTSTRAP_DIR}
+
+    echo "
+Build of Installation Bootstrap complete!  We now return you to your
+normally scheduled template creation.
+"
+
+    BOOTSTRAP=1
+    BOOTSTRAP_DIR="${cache_base}/bootstrap"
+    BOOTSTRAP_CHROOT="chroot ${BOOTSTRAP_DIR} "
+    BOOTSTRAP_INSTALL_ROOT=/run/install
+
+    return 0
+}
+
+
+fedora_bootstrap_mounts()
+{
+    if [[ ${BOOTSTRAP} -ne 1 ]]
+    then
+        return 0
+    fi
+
+    BOOTSTRAP_CHROOT="chroot ${BOOTSTRAP_DIR} "
+
+    echo "Mounting Bootstrap mount points"
+
+    [[ -d ${BOOTSTRAP_DIR}/run/install ]] || mkdir -p ${BOOTSTRAP_DIR}/run/install
+
+    mount -o bind ${INSTALL_ROOT} ${BOOTSTRAP_DIR}/run/install
+    mount -o bind /dev ${BOOTSTRAP_DIR}/dev
+    mount -t proc proc ${BOOTSTRAP_DIR}/proc
+    # Always make sure /etc/resolv.conf is up to date in the target!
+    cp /etc/resolv.conf ${BOOTSTRAP_DIR}/etc/
+}
+
+fedora_bootstrap_umounts()
+{
+    if [[ ${BOOTSTRAP} -ne 1 ]]
+    then
+        return 0
+    fi
+
+    umount ${BOOTSTRAP_DIR}/proc
+    umount ${BOOTSTRAP_DIR}/dev
+    umount ${BOOTSTRAP_DIR}/run/install
+}
+
+
+# This is the code to create the initial roofs for Fedora.  It may
+# require a run time environment by calling the routines above...
+
 download_fedora()
 {
 
@@ -211,10 +614,24 @@ download_fedora()
 
     # download a mini fedora into a cache
     echo "Downloading fedora minimal ..."
-    YUM="yum --installroot $INSTALL_ROOT -y --nogpgcheck"
+
+    # These will get changed if it's decided that we need a 
+    # boostrap environment (can not build natively)
+
+    BOOTSTRAP_INSTALL_ROOT=${INSTALL_ROOT}
+    BOOTSTRAP_CHROOT=
+
     PKG_LIST="yum initscripts passwd rsyslog vim-minimal dhclient chkconfig rootfiles policycoreutils fedora-release"
     MIRRORLIST_URL="http://mirrors.fedoraproject.org/mirrorlist?repo=fedora-$release&arch=$arch"
 
+    if [[ ${release} -lt 17 ]]
+    then
+        # The reflects the move of db_dump and db_load from db4_utils to
+        # libdb_utils in Fedora 17 and above and it's inclusion as a dep...
+        # Prior to Fedora 11, we need to explicitly include it!
+        PKG_LIST="${PKG_LIST} db4-utils"
+    fi
+
     DOWNLOAD_OK=no
 
     # We're splitting the old loop into two loops plus a directory retrival.
@@ -237,9 +654,7 @@ download_fedora()
      # This will fall through if we didn't get any URLS above
      for MIRROR_URL in ${MIRROR_URLS}
      do
-        if [ "$release" -eq "19" ]; then
-            RELEASE_URL="$MIRROR_URL/Packages/f/fedora-release-$release-2.noarch.rpm"
-        elif [ "$release" -gt "16" ]; then
+        if [ "$release" -gt "16" ]; then
             RELEASE_URL="$MIRROR_URL/Packages/f"
         else
             RELEASE_URL="$MIRROR_URL/Packages/"
@@ -270,12 +685,82 @@ download_fedora()
         return 1
     fi
 
-    mkdir -p $INSTALL_ROOT/var/lib/rpm
-    rpm --root $INSTALL_ROOT  --initdb
-    rpm --root $INSTALL_ROOT -ivh ${INSTALL_ROOT}/${RELEASE_RPM}
-    $YUM install $PKG_LIST
+    mkdir -p ${INSTALL_ROOT}/var/lib/rpm
 
-    if [ $? -ne 0 ]; then
+    if ! fedora_get_bootstrap
+    then
+        echo "Fedora Bootstrap setup failed"
+        return 1
+    fi
+
+    fedora_bootstrap_mounts
+
+    ${BOOTSTRAP_CHROOT}rpm --root ${BOOTSTRAP_INSTALL_ROOT} --initdb
+    # The --nodeps is STUPID but F15 had a bogus dependency on RawHide?!?!
+    ${BOOTSTRAP_CHROOT}rpm --root ${BOOTSTRAP_INSTALL_ROOT} --nodeps -ivh ${BOOTSTRAP_INSTALL_ROOT}/${RELEASE_RPM}
+    ${BOOTSTRAP_CHROOT}yum --installroot ${BOOTSTRAP_INSTALL_ROOT} -y --nogpgcheck install ${PKG_LIST}
+
+    RC=$?
+
+    if [[ ${BOOTSTRAP} -eq 1 ]]
+    then
+    # Here we have a bit of a sticky problem.  We MIGHT have just installed
+    # this template cache using versions of yum and rpm in the bootstrap
+    # chroot that use a different database version than the target version.
+    # That can be a very big problem.  Solution is to rebuild the rpmdatabase
+    # with the target database now that we are done building the cache.  In the
+    # vast majority of cases, this is a do-not-care with no harm done if we
+    # didn't do it.  But it catches several corner cases with older unsupported
+    # releases and it really doesn't cost us a lot of time for a one shot
+    # install that will never be done again for this rev.
+    #
+    # Thanks and appreciation to Dwight Engen and the Oracle template for the
+    # database rewrite hint!
+
+        echo "Fixing up rpm databases"
+
+        # Change to our target install directory (if we're not already
+        # there) just to simplify some of the logic to follow...
+        cd ${INSTALL_ROOT}
+
+        rm -f var/lib/rpm/__db*
+        # Programmers Note (warning):
+        #
+        # Pay careful attention to the following commands!  It
+        # crosses TWO chroot boundaries linked by a bind mount!
+        # In the bootstrap case, that's the bind mount of ${INSTALL_ROOT}
+        # to the ${BOOTSTRAP_CHROOT}/run/install directory!  This is
+        # a deliberate hack across that bind mount to do a database
+        # translation between two environments, neither of which may
+        # be the host environment!  It's ugly and hard to follow but,
+        # if you don't understand it, don't mess with it!  The pipe
+        # is in host space between the two chrooted environments!
+        # This is also why we cd'ed into the INSTALL_ROOT directory
+        # in advance of this loop, so everything is relative to the
+        # current working directory and congruent with the same working
+        # space in both chrooted environments.  The output into the new
+        # db is also done in INSTALL_ROOT space but works in either host
+        # space or INSTALL_ROOT space for the mv, so we don't care.  It's
+        # just not obvious what's happening in the db_dump and db_load
+        # commands...
+        #
+        for db in var/lib/rpm/* ; do
+            ${BOOTSTRAP_CHROOT} db_dump ${BOOTSTRAP_INSTALL_ROOT}/$db | chroot . db_load $db.new
+            mv $db.new $db
+        done
+        # finish up by rebuilding the database...
+        # This should be redundant but we do it for completeness and
+        # any corner cases I may have missed...
+        mount -t proc proc proc
+        mount -o bind /dev dev
+        chroot . rpm --rebuilddb
+        umount dev
+        umount proc
+    fi
+
+    fedora_bootstrap_umounts
+
+    if [ ${RC} -ne 0 ]; then
         echo "Failed to download the rootfs, aborting."
         return 1
     fi
@@ -300,8 +785,13 @@ copy_fedora()
 
 update_fedora()
 {
-    YUM="yum --installroot $cache/rootfs -y --nogpgcheck"
-    $YUM update
+    mount -o bind /dev ${cache}/rootfs/dev
+    mount -t proc proc ${cache}/rootfs/proc
+    # Always make sure /etc/resolv.conf is up to date in the target!
+    cp /etc/resolv.conf ${cache}/rootfs/etc/
+    chroot ${cache}/rootfs yum -y update
+    umount ${cache}/rootfs/proc
+    umount  ${cache}/rootfs/dev
 }
 
 install_fedora()
@@ -456,11 +946,6 @@ do
     esac
 done
 
-if [ -z "$name" ]; then
-    usage $(basename $0)
-    exit 1
-fi
-
 if [ ! -z "$clean" -a -z "$path" ]; then
     clean || exit 1
     exit 0
@@ -490,10 +975,6 @@ if [ $(expr "$utsname" : '.*\..*\.') = 0 ]; then
 fi
 
 needed_pkgs=""
-type yum >/dev/null 2>&1
-if [ $? -ne 0 ]; then
-    needed_pkgs="yum $needed_pkgs"
-fi
 
 type curl >/dev/null 2>&1
 if [ $? -ne 0 ]; then
@@ -593,3 +1074,21 @@ if [ ! -z $clean ]; then
     exit 0
 fi
 echo "container rootfs and config created"
+
+if [[ -d ${cache_base}/bootstrap ]]
+then
+    echo "
+You have successfully built a Fedora container and cache.  This cache may
+be used to create future containers of various revisions.  The directory
+${cache_base}/bootstrap contains a bootstrap
+which may no longer needed and can be removed.
+"
+fi
+
+if [[ -e ${cache_base}/LiveOS ]]
+then
+    echo "A LiveOS directory exists at ${cache_base}/LiveOS.
+This is only used in the creation of the bootstrap run-time-environment
+and may be removed.
+"
+fi
-- 

-- 
Michael H. Warfield (AI4NB) | (770) 985-6132 |  mhw at WittsEnd.com
   /\/\|=mhw=|\/\/          | (678) 463-0932 |  http://www.wittsend.com/mhw/
   NIC whois: MHW9          | An optimist believes we live in the best of all
 PGP Key: 0x674627FF        | possible worlds.  A pessimist is sure of it!
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 482 bytes
Desc: This is a digitally signed message part
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20131002/bf162a85/attachment.pgp>


More information about the lxc-devel mailing list