From: Michael H. Warfield Date: Thu, 23 Jan 2014 20:58:16 +0000 (-0500) Subject: Update CentOS and Fedora templates to support archtectures option. X-Git-Tag: lxc-1.0.0.beta3~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=08754f305b580801ae800df32ace5dc7b9b191d9;p=thirdparty%2Flxc.git Update CentOS and Fedora templates to support archtectures option. Added code to the CentOS and Fedora templates so that x86 32 bit containers may be built on x86_64 platforms. Like archectectures may also be trivially used as well. Option added is "-a {arch}". Additionally cleaned up some bash specific logic. Signed-off-by: Michael H. Warfield Acked-by: Stéphane Graber --- diff --git a/templates/lxc-centos.in b/templates/lxc-centos.in index 82dc651d6..2f0c79668 100644 --- a/templates/lxc-centos.in +++ b/templates/lxc-centos.in @@ -27,8 +27,6 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #Configurations -arch=$(arch) -cache_base=@LOCALSTATEDIR@/cache/lxc/centos/$arch default_path=@LXCPATH@ # Some combinations of the tunning knobs below do not exactly make sense. @@ -134,22 +132,6 @@ then fi fi -# Map a few architectures to their generic Centos repository archs. -# -# CentOS currently doesn't support ARM but it's copied here from -# the Fedora template for completeness and that it will in the future. -# -# The two ARM archs are a bit of a guesstimate for the v5 and v6 -# archs. V6 should have hardware floating point (Rasberry Pi). -# The "arm" arch is safer (no hardware floating point). So -# there may be cases where we "get it wrong" for some v6 other -# than RPi. -case "$arch" in -i686) arch=i386 ;; -armv3l|armv4l|armv5l) arch=arm ;; -armv6l|armv7l|armv8l) arch=armhfp ;; -esac - force_mknod() { # delete a device node if exists, and create a new one @@ -385,11 +367,11 @@ download_centos() cat < $REPO_FILE [base] name=CentOS-$release - Base -mirrorlist=http://mirrorlist.centos.org/?release=$release&arch=$arch&repo=os +mirrorlist=http://mirrorlist.centos.org/?release=$release&arch=$basearch&repo=os [updates] name=CentOS-$release - Updates -mirrorlist=http://mirrorlist.centos.org/?release=$release&arch=$arch&repo=updates +mirrorlist=http://mirrorlist.centos.org/?release=$release&arch=$basearch&repo=updates EOF # create minimal device nodes, needed for "yum install" and "yum update" process @@ -519,8 +501,7 @@ install_centos() create_hwaddr() { - echo $(dd if=/dev/urandom bs=8 count=1 2>/dev/null | md5sum | - sed -e 's/\(..\)\(..\)\(..\)\(..\)\(..\).*/fe:\1:\2:\3:\4:\5/') + openssl rand -hex 5 | sed -e 's/\(..\)/:\1/g; s/^/fe/' } copy_configuration() @@ -630,23 +611,24 @@ usage: Mandatory args: -n,--name container name, used to as an identifier for that container from now on Optional args: - -p,--path path to where the container rootfs will be created, defaults to /var/lib/lxc. The container config will go under /var/lib/lxc in that case + -p,--path path to where the container rootfs will be created, defaults to /var/lib/lxc/name. -c,--clean clean the cache -R,--release Centos release for the new container. if the host is Centos, then it will defaultto the host's release. --fqdn fully qualified domain name (FQDN) for DNS and system naming - -A,--arch NOT USED YET. Define what arch the container will be [i686,x86_64] + -a,--arch Define what arch the container will be [i686,x86_64] -h,--help print this help EOF return 0 } -options=$(getopt -o hp:n:cR: -l help,path:,rootfs:,name:,clean,release:,fqdn: -- "$@") +options=$(getopt -o a:hp:n:cR: -l help,path:,rootfs:,name:,clean,release:,arch:,fqdn: -- "$@") if [ $? -ne 0 ]; then usage $(basename $0) exit 1 fi -eval set -- "$options" +arch=$(arch) +eval set -- "$options" while true do case "$1" in @@ -656,6 +638,7 @@ do -n|--name) name=$2; shift 2;; -c|--clean) clean=$2; shift 2;; -R|--release) release=$2; shift 2;; + -a|--arch) newarch=$2; shift 2;; --fqdn) utsname=$2; shift 2;; --) shift 1; break ;; *) break ;; @@ -667,6 +650,51 @@ if [ ! -z "$clean" -a -z "$path" ]; then exit 0 fi +basearch=${arch} +# Map a few architectures to their generic CentOS repository archs. +# The two ARM archs are a bit of a guesstimate for the v5 and v6 +# archs. V6 should have hardware floating point (Rasberry Pi). +# The "arm" arch is safer (no hardware floating point). So +# there may be cases where we "get it wrong" for some v6 other +# than RPi. +case "$arch" in +i686) basearch=i386 ;; +armv3l|armv4l|armv5l) basearch=arm ;; +armv6l|armv7l|armv8l) basearch=armhfp ;; +*) ;; +esac + +# Somebody wants to specify an arch. This is very limited case. +# i386/i586/i686 on i386/x86_64 +# - or - +# x86_64 on x86_64 +if [ "${newarch}" != "" -a "${newarch}" != "${arch}" ] +then + case "${newarch}" in + i386|i586|i686) + if [ "${basearch}" = "i386" -o "${basearch}" = "x86_64" ] + then + # Make the arch a generic x86 32 bit... + arch=${newarch} + basearch=i386 + else + basearch=bad + fi + ;; + *) + basearch=bad + ;; + esac + + if [ "${basearch}" = "bad" ] + then + echo "You cannot build a ${newarch} CentOS container on a ${arch} host. Sorry!" + exit 1 + fi +fi + +cache_base=@LOCALSTATEDIR@/cache/lxc/centos/$basearch + # Let's do something better for the initial root password. # It's not perfect but it will defeat common scanning brute force # attacks in the case where ssh is exposed. It will also be set to @@ -758,10 +786,11 @@ if [ -z "$rootfs_path" ]; then rootfs_path=$path/rootfs # check for 'lxc.rootfs' passed in through default config by lxc-create if grep -q '^lxc.rootfs' $path/config 2>/dev/null ; then - rootfs_path=`grep 'lxc.rootfs =' $path/config | awk -F= '{ print $2 }'` + rootfs_path=$(sed -e '/^lxc.rootfs\s*=/!d' -e 's/\s*#.*//' \ + -e 's/^lxc.rootfs\s*=\s*//' -e q $path/config) fi fi -config_path=$default_path/$name +config_path=$path cache=$cache_base/$release revert() @@ -770,7 +799,6 @@ revert() lxc-destroy -n $name # maybe was interrupted before copy config rm -rf $path - rm -rf $default_path/$name echo "exiting..." exit 1 } diff --git a/templates/lxc-fedora.in b/templates/lxc-fedora.in index 12c810d8a..2230b5c67 100644 --- a/templates/lxc-fedora.in +++ b/templates/lxc-fedora.in @@ -27,8 +27,6 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #Configurations -arch=$(uname -m) -cache_base=@LOCALSTATEDIR@/cache/lxc/fedora/$arch default_path=@LXCPATH@ # Some combinations of the tunning knobs below do not exactly make sense. @@ -113,18 +111,6 @@ then fi fi -# Map a few architectures to their generic Fedora repository archs. -# The two ARM archs are a bit of a guesstimate for the v5 and v6 -# archs. V6 should have hardware floating point (Rasberry Pi). -# The "arm" arch is safer (no hardware floating point). So -# there may be cases where we "get it wrong" for some v6 other -# than RPi. -case "$arch" in -i686) arch=i386 ;; -armv3l|armv4l|armv5l) arch=arm ;; -armv6l|armv7l|armv8l) arch=armhfp ;; -esac - configure_fedora() { @@ -394,7 +380,7 @@ configure_fedora_systemd() # # 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 +# given architecture. Note 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 20 to build this. This # will need to change as time goes on. @@ -550,7 +536,7 @@ Have a beer or a cup of coffee. This will take a bit (~300MB). # Right now, we are using Fedora 20 for the inial bootstrap. # We could make this the "current" Fedora rev (F > 15). - rsync -av mirrors.kernel.org::fedora/releases/20/Fedora/$arch/os/LiveOS . + rsync -av mirrors.kernel.org::fedora/releases/20/Fedora/$basearch/os/LiveOS . if [[ 0 == $? ]] then @@ -627,8 +613,8 @@ This will take a couple of minutes. Patience..." # 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/20/Fedora/$arch/os/Packages/r/rpm-[0-9]* \ - mirrors.kernel.org::fedora/releases/20/Fedora/$arch/os/Packages/y/yum-[0-9]* . + rsync -av mirrors.kernel.org::fedora/releases/20/Fedora/$basearch/os/Packages/r/rpm-[0-9]* \ + mirrors.kernel.org::fedora/releases/20/Fedora/$basearch/os/Packages/y/yum-[0-9]* . # And here it is... # The --nodeps is STUPID but F15 had a bogus dependency on RawHide?!?! @@ -660,10 +646,14 @@ This will take a couple of minutes. Patience..." echo "Stage 1 creation complete. Building stage 2 Installation Bootstrap" mount -o bind ../bootstrap run/install - rsync -av mirrors.kernel.org::fedora/releases/20/Fedora/$arch/os/Packages/f/fedora-release-20* . + rsync -av mirrors.kernel.org::fedora/releases/20/Fedora/$basearch/os/Packages/f/fedora-release-20* . # The --nodeps is STUPID but F15 had a bogus dependency on RawHide?!?! chroot . rpm --root /run/install --nodeps -ivh fedora-release-* + + # yum will take $basearch from host, so force the arch we want + sed -i "s|\$basearch|$basearch|" ./etc/yum.repos.d/* + chroot . yum -y --nogpgcheck --installroot /run/install install python rpm yum umount run/install @@ -680,6 +670,9 @@ This will take a couple of minutes. Patience..." # Always make sure /etc/resolv.conf is up to date in the target! cp /etc/resolv.conf etc/ + # yum will take $basearch from host, so force the arch we want + sed -i "s|\$basearch|$basearch|" ./etc/yum.repos.d/* + chroot . yum -y update RC=$? @@ -774,7 +767,7 @@ download_fedora() BOOTSTRAP_CHROOT= PKG_LIST="yum initscripts passwd rsyslog vim-minimal openssh-server openssh-clients dhclient chkconfig rootfiles policycoreutils fedora-release" - MIRRORLIST_URL="http://mirrors.fedoraproject.org/mirrorlist?repo=fedora-$release&arch=$arch" + MIRRORLIST_URL="http://mirrors.fedoraproject.org/mirrorlist?repo=fedora-$release&arch=$basearch" if [[ ${release} -lt 17 ]] then @@ -850,6 +843,10 @@ download_fedora() ${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} + + # yum will take $basearch from host, so force the arch we want + sed -i "s|\$basearch|$basearch|" ${BOOTSTRAP_INSTALL_ROOT}/etc/yum.repos.d/* + ${BOOTSTRAP_CHROOT}yum --installroot ${BOOTSTRAP_INSTALL_ROOT} -y --nogpgcheck install ${PKG_LIST} RC=$? @@ -928,7 +925,7 @@ copy_fedora() # make a local copy of the minifedora echo -n "Copying rootfs to $rootfs_path ..." - #cp -a $cache/rootfs-$arch $rootfs_path || return 1 + #cp -a $cache/rootfs-$basearch $rootfs_path || return 1 # i prefer rsync (no reason really) mkdir -p $rootfs_path rsync -Ha $cache/rootfs/ $rootfs_path/ @@ -991,8 +988,7 @@ install_fedora() # 5 random bytes... create_hwaddr() { - echo $(dd if=/dev/urandom bs=8 count=1 2>/dev/null | md5sum | - sed -e 's/\(..\)\(..\)\(..\)\(..\)\(..\).*/fe:\1:\2:\3:\4:\5/') + openssl rand -hex 5 | sed -e 's/\(..\)/:\1/g; s/^/fe/' } copy_configuration() @@ -1098,7 +1094,7 @@ usage() cat < - [-p|--path=] [-c|--clean] [-R|--release=] [--fqdn=] [-A|--arch=] + [-p|--path=] [-c|--clean] [-R|--release=] [--fqdn=] [-a|--arch=] [-h|--help] Mandatory args: -n,--name container name, used to as an identifier for that container from now on @@ -1108,19 +1104,20 @@ Optional args: -c,--clean clean the cache -R,--release Fedora release for the new container. if the host is Fedora, then it will default to the host's release. --fqdn fully qualified domain name (FQDN) for DNS and system naming - -A,--arch NOT USED YET. Define what arch the container will be [i686,x86_64] + -a,--arch Define what arch the container will be [i686,x86_64] -h,--help print this help EOF return 0 } -options=$(getopt -o hp:n:cR: -l help,path:,rootfs:,name:,clean,release:,fqdn: -- "$@") +options=$(getopt -o a:hp:n:cR: -l help,path:,rootfs:,name:,clean,release:,arch:,fqdn: -- "$@") if [ $? -ne 0 ]; then usage $(basename $0) exit 1 fi -eval set -- "$options" +arch=$(arch) +eval set -- "$options" while true do case "$1" in @@ -1130,6 +1127,7 @@ do -n|--name) name=$2; shift 2;; -c|--clean) clean=$2; shift 2;; -R|--release) release=$2; shift 2;; + -a|--arch) newarch=$2; shift 2;; --fqdn) utsname=$2; shift 2;; --) shift 1; break ;; *) break ;; @@ -1141,6 +1139,52 @@ if [ ! -z "$clean" -a -z "$path" ]; then exit 0 fi + +basearch=${arch} +# Map a few architectures to their generic Fedora repository archs. +# The two ARM archs are a bit of a guesstimate for the v5 and v6 +# archs. V6 should have hardware floating point (Rasberry Pi). +# The "arm" arch is safer (no hardware floating point). So +# there may be cases where we "get it wrong" for some v6 other +# than RPi. +case "$arch" in +i686) basearch=i386 ;; +armv3l|armv4l|armv5l) basearch=arm ;; +armv6l|armv7l|armv8l) basearch=armhfp ;; +*) ;; +esac + +# Somebody wants to specify an arch. This is very limited case. +# i386/i586/i686 on i386/x86_64 +# - or - +# x86_64 on x86_64 +if [ "${newarch}" != "" -a "${newarch}" != "${arch}" ] +then + case "${newarch}" in + i386|i586|i686) + if [ "${basearch}" = "i386" -o "${basearch}" = "x86_64" ] + then + # Make the arch a generic x86 32 bit... + arch=${newarch} + basearch=i386 + else + basearch=bad + fi + ;; + *) + basearch=bad + ;; + esac + + if [ "${basearch}" = "bad" ] + then + echo "You cannot build a ${newarch} Fedora container on a ${arch} host. Sorry!" + exit 1 + fi +fi + +cache_base=@LOCALSTATEDIR@/cache/lxc/fedora/$basearch + # Let's do something better for the initial root password. # It's not perfect but it will defeat common scanning brute force # attacks in the case where ssh is exposed. It will also be set to @@ -1230,10 +1274,11 @@ if [ -z "$rootfs_path" ]; then rootfs_path=$path/rootfs # check for 'lxc.rootfs' passed in through default config by lxc-create if grep -q '^lxc.rootfs' $path/config 2>/dev/null ; then - rootfs_path=$(awk -F= '/^lxc.rootfs =/{ print $2 }' $path/config) + rootfs_path=$(sed -e '/^lxc.rootfs\s*=/!d' -e 's/\s*#.*//' \ + -e 's/^lxc.rootfs\s*=\s*//' -e q $path/config) fi fi -config_path=$default_path/$name +config_path=$path cache=$cache_base/$release revert() @@ -1242,7 +1287,6 @@ revert() lxc-destroy -n $name # maybe was interrupted before copy config rm -rf $path - rm -rf $default_path/$name echo "exiting..." exit 1 }