[lxc-devel] [PATCH] Enhancements to the centos template

Michael H. Warfield mhw at WittsEnd.com
Fri Mar 14 00:11:42 UTC 2014


Ok...  Back from the -users list, now I'll get into some details...
 
On Thu, 2014-03-13 at 23:49 +0800, Mingjiang Shi wrote:
> Hi All,
> This patch introduces the following enhancements to the centos
> templates.
> 1. Added option to not expire the root password

I have no heartburn over making that optional but the other password
parameters are being done with tuning knobs.  I think I would prefer to
add a tuning knob for that.

I should mentioned that I, personally, actually never use those
generated passwords anyways and generally immediately follow the
lxc-create command with a command like this:

chroot /var/lib/lxc/${Container}/rootfs passwd

That resets the password to one I'm providing without even using the
generated one and it resets the expired bit, so you're done anyways.  We
really can't "prompt for" the password in the template because of issues
regarding interactive prompts in API functions, from what I understand.

> 2. Added option to copy the host ssh public key to the container so
> that one can ssh to the my containers without using password

Ubuntu and Gentoo seem to already do this in a different way using a
different parameter than what you're suggesting...

They:
-S auth_key
Copies specified auth_key to root users authorized_keys file.

You:
-s
Copies the user's authorized_keys file to root in the container.

I'm not sure I would implement that feature your way at all.  It has
some problems.  That template can only be run under "uid 0" (root).
Older versions of sudo would leave HOME set to the calling user, causing
it to act one way, newer version set it to /root resulting in another
behavior.  That sort of potential ambiguity is not a good practice.

I'm also not sure copying the two public id files is the right another
either.  It may be for you, it certainly wouldn't be for me.  My hosts
don't have the individual id files on them (and certainly no private
keys) and only have the authoritized_keys file (which a number of public
id keys).  I have no need for the private keys on those hosts, since
they're only connected to from a secure remote workstation and I use key
agent forwarding for subsequent connections between remote systems.

My choice there would be the method in the Ubuntu template (the Gentoo
template has a typo in it that likely renders that feature non-operable
in a non-obvious way {hangs on line 620}).

> 3. Added option to set static IP to the container. Used when run
> services which needs static ip address, such as hadoop.

Ok...  Here I have some heartburn.  Not from adding the IP, but the way
it's done.  Two other templates, lxc-altlinux and lxc-openmadrivia, are
already doing this but using different parameters.

Your option:

--ip)           use_static_ip=yes; ip=$2;

Their options:

-4|--ipv4)      ipv4=$2;
-6|--ipv6)      ipv6=$2;

I realize that you may not care about IPv6, but I certainly do.

Even in the IPv4 case, you've assumed a /24.  That may be often true but
it certainly is not universally true and you don't provide a way to
specify that either by included CIDR or by netmask.

You specify the /24 CIDR into the config but then don't specify the
netmask in the ifcfg files.  That would not end well on my network,
which is an old "class B" subneted in may variable ways (to say nothing
of the 10./8 or 172.16/12 or others below 128./8).  If someone happen to
be using the 10. net on their private bridge and you give one machine a
10.1.1.1, the system is going to try and configure itself to 10.1.1.1/8,
with a broadcast of 10.255.255.255.  172.17.1.1 would end up being
172.17.1.1/16 with a broadcast of 172.17.255.255.  Not the intended
result at all.

You're not sanity checking those IP addresses to insure they are valid
addresses or usable addresses.  Yeah, it'll cause the container's
networking to blow up down the road but it would be nice to catch the
easy typos before getting that far.  Sanity checking addresses like that
is a non-trivial task, though, I will admit.

I also have some heartburn here as to multiple interfaces.  You may have
only one in each container, I happen to have at least two in each.  It's
not clear how that structures out when you're merely cat'ing the
"lxc.network.ipv4 =" line to the end of the config file.  It would be
after the definition of veth1 (the second interface).  I think it will
only apply to veth0, since these are not tightly associated, but I'll
have to tinker with it a bit.  I generally find that just setting up the
ifcfg-eth* files are sufficient.

I think we could have a whole long discussion over assignment of static
IPv4 and IPv6 addresses much along the lines that took place a couple of
months ago with regards to assigning persistent mac addresses to
containers.  I also need to have a closer look at how those other two
templates are handling netmasks and netblocks and multiple interfaces.

> Let me know if you have any questions. Thanks!

Other problems I have with your attached patch...

It makes other changes to the template that are not documented,
reasoned, or commented on.

You've added packages to the package list, and I wouldn't normally
disagree with them (I add most of them myself) but we've been trying to
keep the minimal config as minimal as possible.  Yeah, I would place
"sudo" on the list of "should be there" but "wget"?  Yeah, I like wget
but I have no heartburn with curl and if we all added our fav's to the
default for everybody, I'm not sure we'd be happy with the result.
There's been some discussion over "additional packages" (like Oracle
does) but not much.

You've "flipped case" on some variables for no apparent reason.  I know
that's a gimish gamash of upper and lower case variable names and (even
though I'm not the original author - 4th down on the list in fact) but,
if you start making arbitrary changes in style, outside of what's been
established, it creates unnecessary patching in git and the potential
for "patch wars".  Such changes are also potential for trouble if you
"miss something" and "something unintended occurs".  I inherited the
gimish gamash and have made no effort to "clean it up", I admit.

If you change something, even if you think it's trivial or just cleaning
something up, you should comment on it either in the code or in the
patch header comments or both.

You've got some good ideas but this needs more discussion in the realm
of all the templates and some of the details may work fine on your
network but you break on mine and others.  Options should "work in
general" as much as possible and not be for specific setups.

> Tests have been run:
> 1. Created a container without using the newly added options, the
> current behaviors are preserved, i.e. root password need to be changed
> at first log, dynamic ip address and no public key is copied.
> 2. Tested the new behaviors are working by creating a container using
> the newly added options.

> Signed-off-by: Mingjiang Shi <mrjewes at gmail dot com>

At minimum for the networking issues and parameter usage that is
inconsistent with the other existing templates, this isn't ready yet.

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

> ---
> diff --git a/templates/lxc-centos.in b/templates/lxc-centos.in
> index 55e0531..3c0e9e6 100644
> --- a/templates/lxc-centos.in
> +++ b/templates/lxc-centos.in
> @@ -229,31 +229,57 @@ configure_centos()
>               cd ${rootfs_path}/etc/rc.d/rc6.d
>               ln -s ../init.d/lxc-halt S00lxc-reboot
>          )
>      fi
>  
> +    if [ $use_static_ip == "yes" ];then
> +    # configure the network using static ip
> +    cat <<EOF >
> ${rootfs_path}/etc/sysconfig/network-scripts/ifcfg-eth0
> +DEVICE=eth0
> +BOOTPROTO=none
> +ONBOOT=yes
> +HOSTNAME=${utsname}
> +NM_CONTROLLED=no
> +TYPE=Ethernet
> +MTU=${MTU}
> +EOF
> +    # set static route, add the default gateway
> +    cat <<EOF > ${rootfs_path}/etc/sysconfig/static-routes
> +any net default gw ${gw}
> +EOF
> +
> +    # set minimal hosts, don't resolve the hostname to 127.0.0.1
> +    # resolve it to the static ip
> +    cat <<EOF > $rootfs_path/etc/hosts
> +127.0.0.1 localhost 
> +$ip ${utsname} $name
> +EOF
> +
> +    else
>      # configure the network using the dhcp
>      cat <<EOF >
> ${rootfs_path}/etc/sysconfig/network-scripts/ifcfg-eth0
>  DEVICE=eth0
>  BOOTPROTO=dhcp
>  ONBOOT=yes
> -HOSTNAME=${UTSNAME}
> +HOSTNAME=${utsname}
>  NM_CONTROLLED=no
>  TYPE=Ethernet
>  MTU=${MTU}
>  EOF
>  
> +    # set minimal hosts
> +    cat <<EOF > $rootfs_path/etc/hosts
> +127.0.0.1 localhost $name
> +EOF
> +    fi
> +
>      # set the hostname
>      cat <<EOF > ${rootfs_path}/etc/sysconfig/network
>  NETWORKING=yes
> -HOSTNAME=${UTSNAME}
> +HOSTNAME=${utsname}
>  EOF
>  
> -    # set minimal hosts
> -    cat <<EOF > $rootfs_path/etc/hosts
> -127.0.0.1 localhost $name
> -EOF
>  
>      # set minimal fstab
>      cat <<EOF > $rootfs_path/etc/fstab
>  /dev/root               /                       rootfs   defaults
>      0 0
>  none                    /dev/shm                tmpfs
>  nosuid,nodev    0 0
> @@ -337,12 +363,15 @@ EOF
>          echo ${root_password} > ${config_path}/tmp_root_pass
>          echo "Storing root password in
> '${config_path}/tmp_root_pass'"
>      fi
>  
>      echo "root:$root_password" | chroot $rootfs_path chpasswd
> -    # Also set this password as expired to force the user to change
> it!
> -    chroot $rootfs_path passwd -e root
> +    
> +    if [ $expire_root_passwd == "yes" ];then
> +        # Set this password as expired to force the user to change
> it!
> +        chroot $rootfs_path passwd -e root
> +    fi
>  
>      # This will need to be enhanced for CentOS 7 when systemd
>      # comes into play...   /\/\|=mhw=|\/\/
>  
>      return 0
> @@ -370,11 +399,11 @@ download_centos()
>      fi
>  
>      # download a mini centos into a cache
>      echo "Downloading centos minimal ..."
>      YUM="yum --installroot $INSTALL_ROOT -y --nogpgcheck"
> -    PKG_LIST="yum initscripts passwd rsyslog vim-minimal
> openssh-server openssh-clients dhclient chkconfig rootfiles
> policycoreutils"
> +    PKG_LIST="yum initscripts passwd rsyslog vim openssh-server
> openssh-clients dhclient chkconfig rootfiles policycoreutils wget tar
> sudo zip unzip which"
>  
>      # use temporary repository definition
>      REPO_FILE=$INSTALL_ROOT/etc/yum.repos.d/lxc-centos-temp.repo
>      mkdir -p $(dirname $REPO_FILE)
>      if [ -n "$repo" ]; then
> @@ -559,10 +588,15 @@ lxc.rootfs = $rootfs_path
>              fi
>          fi
>      done < $config_path/config.def
>  
>      rm -f $config_path/config.def
> +    
> +    # append the container ip address
> +    if [ $use_static_ip == "yes" ];then
> +      echo "lxc.network.ipv4 = ${ip}/24" >> $config_path/config
> +    fi
>  
>      if [ -e "@LXCTEMPLATECONFIG@/centos.common.conf" ]; then
>          echo "
>  # Include common configuration
>  lxc.include = @LXCTEMPLATECONFIG@/centos.common.conf
> @@ -635,46 +669,87 @@ Optional args:
>    -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
>       --repo         repository to use (url)
> +     --ip           specify a static ip, must use with --gw option
> +     --gw           specify the default gateway, required if --ip
> option is used.
> +  -E,               don't set the root password expired
> +  -s,               Copy the current ssh public key to the authorized
> host list of the container
>    -a,--arch         Define what arch the container will be
> [i686,x86_64]
>    -h,--help         print this help
>  EOF
>      return 0
>  }
>  
> -options=$(getopt -o a:hp:n:cR: -l
> help,path:,rootfs:,name:,clean,release:,repo:,arch:,fqdn: -- "$@")
> +copy_ssh_key_to_container()
> +{
> +    # create the .ssh folder and set permission
> +    container_ssh_dir=${rootfs_path}/root/.ssh
> +    if [ ! -d $container_ssh_dir ];then
> +        mkdir -p $container_ssh_dir
> +        chmod 700 $container_ssh_dir
> +    fi
> +    
> +    # copy the id_rsa.pub to authorized_keys if exists
> +    my_ssh_id=$HOME/.ssh/id_rsa.pub
> +    if [ -f $my_ssh_id ];then
> +        cat $my_ssh_id >> $container_ssh_dir/authorized_keys
> +    fi
> +
> +    # copy the id_dsa.pub to authorized_keys if exists
> +    my_ssh_id=$HOME/.ssh/id_dsa.pub
> +    if [ -f $my_ssh_id ];then
> +        cat $my_ssh_id >> $container_ssh_dir/authorized_keys
> +    fi
> +}
> +
> +options=$(getopt -o a:hp:n:cR:Es -l
> help,path:,rootfs:,name:,clean,release:,repo:,arch:,fqdn:,ip:,gw: --
> "$@")
>  if [ $? -ne 0 ]; then
>      usage $(basename $0)
>      exit 1
>  fi
>  
>  arch=$(arch)
> +use_static_ip=no
> +ip=
> +gw=
> +expire_root_passwd=yes
> +copy_ssh_id=no
>  eval set -- "$options"
>  while true
>  do
>      case "$1" in
>          -h|--help)      usage $0 && exit 0;;
>          -p|--path)      path=$2; shift 2;;
>          --rootfs)       rootfs=$2; shift 2;;
>          -n|--name)      name=$2; shift 2;;
>          -c|--clean)     clean=$2; shift 2;;
>          -R|--release)   release=$2; shift 2;;
> - --repo) repo="$2"; shift 2;;
> +    --repo) repo="$2"; shift 2;;
>          -a|--arch)      newarch=$2; shift 2;;
>          --fqdn)         utsname=$2; shift 2;;
> +        --ip)           use_static_ip=yes; ip=$2; shift 2;;
> +        --gw)           gw=$2; shift 2;;
> +        -E)             expire_root_passwd=no; shift 1;;
> +        -s)             copy_ssh_id=yes; shift 1;;
>          --)             shift 1; break ;;
>          *)              break ;;
>      esac
>  done
>  
>  if [ ! -z "$clean" -a -z "$path" ]; then
>      clean || exit 1
>      exit 0
>  fi
>  
> +if [ ! -z "$ip" -a -z "$gw" ];then
> +    echo "Missing the default gateway, use --gw option to specify the
> default gateway"
> +    usage $0
> +    exit 1
> +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
> @@ -846,10 +921,15 @@ if [ $? -ne 0 ]; then
>      exit 1
>  fi
>  
>  configure_centos_init
>  
> +# copy the ssh public key to authorized keys in the container
> +if [ $copy_ssh_id == "yes" ];then
> +    copy_ssh_key_to_container
> +fi
> +
>  if [ ! -z $clean ]; then
>      clean || exit 1
>      exit 0
>  fi
>  echo "
> @@ -879,15 +959,17 @@ then
>  
>          chroot ${rootfs_path} passwd
>  "
>      chroot ${rootfs_path} passwd
>  else
> -    echo "
> -The root password is set up as "expired" and will require it to be
> changed
> -at first login, which you should do as soon as possible.  If you lose
> the
> -root password or wish to change it without starting the container,
> you
> -can change it from the host by running the following command (which
> will
> -also reset the expired flag):
> -
> -        chroot ${rootfs_path} passwd
> -"
> +    if [ $expire_root_passwd == "yes" ];then
> +    echo "
> + The root password is set up as "expired" and will require it to be
> changed
> + at first login, which you should do as soon as possible.  If you
> lose the
> + root password or wish to change it without starting the container,
> you
> + can change it from the host by running the following command (which
> will
> + also reset the expired flag):
> +
> + chroot ${rootfs_path} passwd
> + "
> +    fi
>  fi
> ---
> 
> 
> -- 
> Thanks
> -Mingjiang
> 
> -- 
> This message has been scanned for viruses and 
> dangerous content by MailScanner, and is 
> believed to be clean. 
> _______________________________________________
> lxc-devel mailing list
> lxc-devel at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/lxc-devel

-- 
Michael H. Warfield (AI4NB) | (770) 978-7061 |  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/20140313/c49ed9a7/attachment.pgp>


More information about the lxc-devel mailing list