[lxc-devel] [PATCH] lxc-fedora template - Fix retries, use os-release for release, add utsname.

Serge Hallyn serge.hallyn at ubuntu.com
Wed Jul 10 15:58:21 UTC 2013


Quoting Michael H. Warfield (mhw at WittsEnd.com):
> 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

Oh, I though Stéphane had replied, but maybe not.  It comes down to: if
Debian starts using it, we'll pick that up, but we're not going to
differentiate on this.  We already have our own well-established
/etc/lsb*.

Might some helpers in functions.in to parse whatever we could find be
be useful?  In that way we could work toward having all the templates
use somewhat generic means of figuring out where they run, what tools
and packages they need to run, etc.

But, since you're only detecting *fedora* releases below, what you
have seems fine.

Note that splitting up the patch and then putting this email in a
0/N intro email would make replying a much lower threshold activity :)

Looks good though!  So, ...

> 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 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!
> 
> -- 
> 
> Signed-off-by: Michael H. Warfield <mhw at WittsEnd.com>

Acked-by: Serge E. Hallyn <serge.hallyn at ubuntu.com>

> 
> --- 
> diff --git a/templates/lxc-fedora.in b/templates/lxc-fedora.in
> index f5da7b5..23728c6 100644
> --- a/templates/lxc-fedora.in
> +++ b/templates/lxc-fedora.in
> @@ -33,8 +33,43 @@ root_password=root
>  
>  # is this fedora?
>  # 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
> +    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 )
>      if [ "$fedora_host_ver" != "" ]
>      then
> @@ -66,7 +101,7 @@ configure_fedora()
>  DEVICE=eth0
>  BOOTPROTO=dhcp
>  ONBOOT=yes
> -HOSTNAME=${name}
> +HOSTNAME=${utsname}
>  NM_CONTROLLED=no
>  TYPE=Ethernet
>  MTU=${MTU}
> @@ -75,17 +110,17 @@ EOF
>      # set the hostname
>      cat <<EOF > ${rootfs_path}/etc/sysconfig/network
>  NETWORKING=yes
> -HOSTNAME=${name}
> +HOSTNAME=${utsname}
>  EOF
>  
>      # set hostname on systemd Fedora systems
>      if [ $release -gt 14 ]; then
> -        echo "${name}" > ${rootfs_path}/etc/hostname
> +        echo "${utsname}" > ${rootfs_path}/etc/hostname
>      fi
>  
>      # set minimal 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
>  EOF
>  
> @@ -181,27 +216,53 @@ download_fedora()
>      MIRRORLIST_URL="http://mirrors.fedoraproject.org/mirrorlist?repo=fedora-$release&arch=$arch"
>  
>      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..."
> -        MIRROR_URL=$(curl -s -S -f "$MIRRORLIST_URL" | head -n2 | tail -n1)
> -        if [ $? -ne 0 ] || [ -z "$MIRROR_URL" ]; then
> -            echo "Failed to get a mirror"
> -            continue
> -        fi
> +	# This code is mildly "brittle" in that it assumes a certain
> +        # page format and parsing HTML.  I've done worse.  :-P
> +        MIRROR_URLS=$(curl -s -S -f "$MIRRORLIST_URL" | sed -e '/^http:/!d' -e '2,6!d')
> +        if [ $? -eq 0 ] && [ -n "$MIRROR_URLS" ]
> +        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
> -            RELEASE_URL="$MIRROR_URL/Packages/f/fedora-release-$release-1.noarch.rpm"
> +            RELEASE_URL="$MIRROR_URL/Packages/f"
>          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
> -        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
> -            echo "Failed to download fedora release rpm"
> +            echo "Failed to download fedora release rpm ${RELEASE_RPM}."
>              continue
>          fi
> +
>          DOWNLOAD_OK=yes
>          break
>      done
> +
>      if [ $DOWNLOAD_OK != yes ]; then
>          echo "Aborting"
>          return 1
> @@ -209,7 +270,7 @@ download_fedora()
>  
>      mkdir -p $INSTALL_ROOT/var/lib/rpm
>      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
>  
>      if [ $? -ne 0 ]; then
> @@ -287,7 +348,7 @@ copy_configuration()
>      mkdir -p $config_path
>      grep -q "^lxc.rootfs" $config_path/config 2>/dev/null || echo "lxc.rootfs = $rootfs_path" >> $config_path/config
>      cat <<EOF >> $config_path/config
> -lxc.utsname = $name
> +lxc.utsname = $utsname
>  lxc.tty = 4
>  lxc.pts = 1024
>  lxc.mount = $config_path/fstab
> @@ -355,7 +416,7 @@ usage()
>      cat <<EOF
>  usage:
>      $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]
>  Mandatory args:
>    -n,--name         container name, used to as an identifier for that container from now on
> @@ -364,13 +425,14 @@ Optional args:
>    --rootfs          path for actual rootfs.
>    -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]
>    -h,--help         print this help
>  EOF
>      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
>      usage $(basename $0)
>      exit 1
> @@ -386,6 +448,7 @@ do
>          -n|--name)      name=$2; shift 2;;
>          -c|--clean)     clean=$2; shift 2;;
>          -R|--release)   release=$2; shift 2;;
> +        --fqdn)         utsname=$2; shift 2;;
>          --)             shift 1; break ;;
>          *)              break ;;
>      esac
> @@ -396,6 +459,29 @@ if [ ! -z "$clean" -a -z "$path" ]; then
>      exit 0
>  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=""
>  type yum >/dev/null 2>&1
>  if [ $? -ne 0 ]; then
> @@ -421,8 +507,8 @@ if [ -z "$release" ]; then
>      if [ "$is_fedora" -a "$fedora_host_ver" ]; then
>          release=$fedora_host_ver
>      else
> -        echo "This is not a fedora host and release missing, defaulting to 17. use -R|--release to specify release"
> -        release=17
> +        echo "This is not a fedora host and release missing, defaulting to 18. use -R|--release to specify release"
> +        release=18
>      fi
>  fi
>  
> 



> ------------------------------------------------------------------------------
> See everything from the browser to the database with AppDynamics
> Get end-to-end visibility with application monitoring from AppDynamics
> Isolate bottlenecks and diagnose root cause in seconds.
> Start your free trial of AppDynamics Pro today!
> http://pubads.g.doubleclick.net/gampad/clk?id=48808831&iu=/4140/ostg.clktrk

> _______________________________________________
> Lxc-devel mailing list
> Lxc-devel at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/lxc-devel





More information about the lxc-devel mailing list