Commit b9b3a92f by Michael H. Warfield Committed by Serge Hallyn

lxc-fedora template - Fix retries, use os-release for release, add utsname.

Hey all! Patch for the Fedora template. Several things... 1) A month or so ago, I floated an idea of adding an option for utsname which Serge seemed to like but we let it float for more feedback (none came). 2) In private mail to Serge and Stéphane I mentioned the idea of using the CPE (Common Platform Enumeration) for host distro and version identification. I heard back from Serge but not Stéphane. CPE is a standard promoted by NIST and Mitre (along with CVE and CVSS) as part of the security community as a common identification mechanism. It's supported by RedHat based distros and many others (notable exception Ubuntu). I've patched the Fedora template to parse first the /etc/os-release file or, alternatively, the /etc/system-release-cpe file for the distro ID and version instead of the human readable /etc/redhat-release. There's more that can be done with that in the realm of cross distro container builds, I suspect. 3) At the time of working on 1&2 I noticed that the retry logic in the Fedora template just didn't seem right. I believe I posted a message asking for clarification on that behavior. A recently post in the -users list indicating that someone could not create a Fedora 19 container (because the release ver string was 19-2 and the template was only looking for -1) prompted me to rework the retry logic for handling the mirror list and servers as well as revamp the download logic to properly identify the correct release package. The patch for all of the above is attached below the jump. It's been tested on Fedora 17 through Fedora 19 hosts and has created containers for F11, F12, F13, F14, F16, F17, F18, and F19. F15 failed for rpm dependency issues that are not worth fixing (IMHO). Regards, Mike -- Michael H. Warfield (AI4NB) | (770) 985-6132 | mhw@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! -- Signed-off-by: 's avatarMichael H. Warfield <mhw@WittsEnd.com> Signed-off-by: 's avatarSerge Hallyn <serge.hallyn@ubuntu.com>
parent 3327917f
...@@ -33,8 +33,43 @@ root_password=root ...@@ -33,8 +33,43 @@ root_password=root
# is this fedora? # is this fedora?
# Alow for weird remixes like the Raspberry Pi # Alow for weird remixes like the Raspberry Pi
if [ -e /etc/redhat-release ] #
# Use the Mitre standard CPE identifier for the release ID if possible...
# This may be in /etc/os-release or /etc/system-release-cpe. We
# should be able to use EITHER. Give preference to /etc/os-release for now.
if [ -e /etc/os-release ]
then
# This is a shell friendly configuration file. We can just source it.
# What we're looking for in here is the ID, VERSION_ID and the CPE_NAME
. /etc/os-release
echo "Host CPE ID from /etc/os-release: ${CPE_NAME}"
fi
if [ "${CPE_NAME}" = "" -a -e /etc/system-release-cpe ]
then
CPE_NAME=$(head -n1 /etc/system-release-cpe)
CPE_URI=$(expr ${CPE_NAME} : '\([^:]*:[^:*]\)')
if [ "${CPE_URI}" != "cpe:/o" ]
then
CPE_NAME=
else
echo "Host CPE ID from /etc/system-release-cpe: ${CPE_NAME}"
# Probably a better way to do this but sill remain posix
# compatible but this works, shrug...
# Must be nice and not introduce convenient bashisms here.
ID=$(expr ${CPE_NAME} : '[^:]*:[^:]*:[^:]*:\([^:]*\)')
VERSION_ID=$(expr ${CPE_NAME} : '[^:]*:[^:]*:[^:]*:[^:]*:\([^:]*\)')
fi
fi
if [ ${CPE_NAME} != "" -a ${ID} = "fedora" -a ${VERSION_ID} != "" ]
then then
fedora_host_ver=${VERSION_ID}
is_fedora=true
elif [ -e /etc/redhat-release ]
then
# Only if all other methods fail, try to parse the redhat-release file.
fedora_host_ver=$( sed -e '/^Fedora /!d' -e 's/Fedora.*\srelease\s*\([0-9][0-9]*\)\s.*/\1/' < /etc/redhat-release ) fedora_host_ver=$( sed -e '/^Fedora /!d' -e 's/Fedora.*\srelease\s*\([0-9][0-9]*\)\s.*/\1/' < /etc/redhat-release )
if [ "$fedora_host_ver" != "" ] if [ "$fedora_host_ver" != "" ]
then then
...@@ -66,7 +101,7 @@ configure_fedora() ...@@ -66,7 +101,7 @@ configure_fedora()
DEVICE=eth0 DEVICE=eth0
BOOTPROTO=dhcp BOOTPROTO=dhcp
ONBOOT=yes ONBOOT=yes
HOSTNAME=${name} HOSTNAME=${utsname}
NM_CONTROLLED=no NM_CONTROLLED=no
TYPE=Ethernet TYPE=Ethernet
MTU=${MTU} MTU=${MTU}
...@@ -75,17 +110,17 @@ EOF ...@@ -75,17 +110,17 @@ EOF
# set the hostname # set the hostname
cat <<EOF > ${rootfs_path}/etc/sysconfig/network cat <<EOF > ${rootfs_path}/etc/sysconfig/network
NETWORKING=yes NETWORKING=yes
HOSTNAME=${name} HOSTNAME=${utsname}
EOF EOF
# set hostname on systemd Fedora systems # set hostname on systemd Fedora systems
if [ $release -gt 14 ]; then if [ $release -gt 14 ]; then
echo "${name}" > ${rootfs_path}/etc/hostname echo "${utsname}" > ${rootfs_path}/etc/hostname
fi fi
# set minimal hosts # set minimal hosts
cat <<EOF > $rootfs_path/etc/hosts cat <<EOF > $rootfs_path/etc/hosts
127.0.0.1 localhost $name 127.0.0.1 localhost.localdomain localhost $utsname
::1 localhost6.localdomain6 localhost6 ::1 localhost6.localdomain6 localhost6
EOF EOF
...@@ -181,27 +216,53 @@ download_fedora() ...@@ -181,27 +216,53 @@ download_fedora()
MIRRORLIST_URL="http://mirrors.fedoraproject.org/mirrorlist?repo=fedora-$release&arch=$arch" MIRRORLIST_URL="http://mirrors.fedoraproject.org/mirrorlist?repo=fedora-$release&arch=$arch"
DOWNLOAD_OK=no DOWNLOAD_OK=no
for trynumber in 1 2 3; do
# We're splitting the old loop into two loops plus a directory retrival.
# First loop... Try and retrive a mirror list with retries and a slight
# delay between attempts...
for trynumber in 1 2 3 4; do
[ $trynumber != 1 ] && echo "Trying again..." [ $trynumber != 1 ] && echo "Trying again..."
MIRROR_URL=$(curl -s -S -f "$MIRRORLIST_URL" | head -n2 | tail -n1) # This code is mildly "brittle" in that it assumes a certain
if [ $? -ne 0 ] || [ -z "$MIRROR_URL" ]; then # page format and parsing HTML. I've done worse. :-P
echo "Failed to get a mirror" MIRROR_URLS=$(curl -s -S -f "$MIRRORLIST_URL" | sed -e '/^http:/!d' -e '2,6!d')
continue if [ $? -eq 0 ] && [ -n "$MIRROR_URLS" ]
fi then
break
fi
echo "Failed to get a mirror on try $trynumber"
sleep 3
done
# This will fall through if we didn't get any URLS above
for MIRROR_URL in ${MIRROR_URLS}
do
if [ "$release" -gt "16" ]; then if [ "$release" -gt "16" ]; then
RELEASE_URL="$MIRROR_URL/Packages/f/fedora-release-$release-1.noarch.rpm" RELEASE_URL="$MIRROR_URL/Packages/f"
else else
RELEASE_URL="$MIRROR_URL/Packages/fedora-release-$release-1.noarch.rpm" RELEASE_URL="$MIRROR_URL/Packages/"
fi
echo "Fetching rpm name from $RELEASE_URL..."
# This code is mildly "brittle" in that it assumes a certain directory
# page format and parsing HTML. I've done worse. :-P
RELEASE_RPM=$(curl -L -f "$RELEASE_URL" | sed -e "/fedora-release-${release}-/!d" -e 's/.*<a href=\"//' -e 's/\">.*//' )
if [ $? -ne 0 -o "${RELEASE_RPM}" = "" ]; then
echo "Failed to identify fedora release rpm."
continue
fi fi
echo "Fetching from $RELEASE_URL"
curl -f "$RELEASE_URL" > $INSTALL_ROOT/fedora-release-$release.noarch.rpm echo "Fetching fedora release rpm from ${RELEASE_URL}/${RELEASE_RPM}......"
curl -L -f "${RELEASE_URL}/${RELEASE_RPM}" > ${INSTALL_ROOT}/${RELEASE_RPM}
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "Failed to download fedora release rpm" echo "Failed to download fedora release rpm ${RELEASE_RPM}."
continue continue
fi fi
DOWNLOAD_OK=yes DOWNLOAD_OK=yes
break break
done done
if [ $DOWNLOAD_OK != yes ]; then if [ $DOWNLOAD_OK != yes ]; then
echo "Aborting" echo "Aborting"
return 1 return 1
...@@ -209,7 +270,7 @@ download_fedora() ...@@ -209,7 +270,7 @@ download_fedora()
mkdir -p $INSTALL_ROOT/var/lib/rpm mkdir -p $INSTALL_ROOT/var/lib/rpm
rpm --root $INSTALL_ROOT --initdb rpm --root $INSTALL_ROOT --initdb
rpm --root $INSTALL_ROOT -ivh $INSTALL_ROOT/fedora-release-$release.noarch.rpm rpm --root $INSTALL_ROOT -ivh ${INSTALL_ROOT}/${RELEASE_RPM}
$YUM install $PKG_LIST $YUM install $PKG_LIST
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
...@@ -287,7 +348,7 @@ copy_configuration() ...@@ -287,7 +348,7 @@ copy_configuration()
mkdir -p $config_path mkdir -p $config_path
grep -q "^lxc.rootfs" $config_path/config 2>/dev/null || echo "lxc.rootfs = $rootfs_path" >> $config_path/config grep -q "^lxc.rootfs" $config_path/config 2>/dev/null || echo "lxc.rootfs = $rootfs_path" >> $config_path/config
cat <<EOF >> $config_path/config cat <<EOF >> $config_path/config
lxc.utsname = $name lxc.utsname = $utsname
lxc.tty = 4 lxc.tty = 4
lxc.pts = 1024 lxc.pts = 1024
lxc.mount = $config_path/fstab lxc.mount = $config_path/fstab
...@@ -355,7 +416,7 @@ usage() ...@@ -355,7 +416,7 @@ usage()
cat <<EOF cat <<EOF
usage: usage:
$1 -n|--name=<container_name> $1 -n|--name=<container_name>
[-p|--path=<path>] [-c|--clean] [-R|--release=<Fedora_release>] [-A|--arch=<arch of the container>] [-p|--path=<path>] [-c|--clean] [-R|--release=<Fedora_release>] [--fqdn=<network name of container>] [-A|--arch=<arch of the container>]
[-h|--help] [-h|--help]
Mandatory args: Mandatory args:
-n,--name container name, used to as an identifier for that container from now on -n,--name container name, used to as an identifier for that container from now on
...@@ -364,13 +425,14 @@ Optional args: ...@@ -364,13 +425,14 @@ Optional args:
--rootfs path for actual rootfs. --rootfs path for actual rootfs.
-c,--clean clean the cache -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. -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 NOT USED YET. Define what arch the container will be [i686,x86_64]
-h,--help print this help -h,--help print this help
EOF EOF
return 0 return 0
} }
options=$(getopt -o hp:n:cR: -l help,path:,rootfs:,name:,clean,release: -- "$@") options=$(getopt -o hp:n:cR: -l help,path:,rootfs:,name:,clean,release:,fqdn: -- "$@")
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
usage $(basename $0) usage $(basename $0)
exit 1 exit 1
...@@ -386,6 +448,7 @@ do ...@@ -386,6 +448,7 @@ do
-n|--name) name=$2; shift 2;; -n|--name) name=$2; shift 2;;
-c|--clean) clean=$2; shift 2;; -c|--clean) clean=$2; shift 2;;
-R|--release) release=$2; shift 2;; -R|--release) release=$2; shift 2;;
--fqdn) utsname=$2; shift 2;;
--) shift 1; break ;; --) shift 1; break ;;
*) break ;; *) break ;;
esac esac
...@@ -396,6 +459,29 @@ if [ ! -z "$clean" -a -z "$path" ]; then ...@@ -396,6 +459,29 @@ if [ ! -z "$clean" -a -z "$path" ]; then
exit 0 exit 0
fi fi
if [ -z "${utsname}" ]; then
utsname=${name}
fi
# This follows a standard "resolver" convention that an FQDN must have
# at least two dots or it is considered a local relative host name.
# If it doesn't, append the dns domain name of the host system.
#
# This changes one significant behavior when running
# "lxc_create -n Container_Name" without using the
# --fqdn option.
#
# Old behavior:
# utsname and hostname = Container_Name
# New behavior:
# utsname and hostname = Container_Name.Domain_Name
if [ $(expr "$utsname" : '.*\..*\.') = 0 ]; then
if [ -n "$(dnsdomainname)" ]; then
utsname=${utsname}.$(dnsdomainname)
fi
fi
needed_pkgs="" needed_pkgs=""
type yum >/dev/null 2>&1 type yum >/dev/null 2>&1
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
...@@ -421,8 +507,8 @@ if [ -z "$release" ]; then ...@@ -421,8 +507,8 @@ if [ -z "$release" ]; then
if [ "$is_fedora" -a "$fedora_host_ver" ]; then if [ "$is_fedora" -a "$fedora_host_ver" ]; then
release=$fedora_host_ver release=$fedora_host_ver
else else
echo "This is not a fedora host and release missing, defaulting to 17. use -R|--release to specify release" echo "This is not a fedora host and release missing, defaulting to 18. use -R|--release to specify release"
release=17 release=18
fi fi
fi fi
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment