[lxc-devel] [PATCH] Various fixes for Fedora/CentOS/OpenSUSE templates and systemd.

Michael H. Warfield mhw at WittsEnd.com
Mon Sep 15 00:57:58 UTC 2014


Various fixes for Fedora/CentOS/OpenSUSE templates and systemd.

This patch integrates several fixes for several template issues
and open bugzilla bugs at the Fedora project.

The lxc-centos template now supports CentOS 7 and correct configuration
of systemd in CentOS.

The CentOS and Fedora template have been fixed for a rootfs bug that
was a skew between the parsed parameter (rootfs) and the working variable
(rootfs_path) by normalizing to "rootfs", congruent with several other
templates.  This should fix the backing store problem.

The user password generation logic has been refactored out of the
Fedora and CentOS templates into a new template/functions file.  This
is the beginning of a security fix that has been reported as a bug in
Fedora and Debian.  The functions support random password generation
and/or disabled password on accounts.  Templates need to convert over
and avoid static passwords like "root:root" or "ubuntu:ubuntu" in order
to avoid this security issue.  Function supports multiple user setup.

The template/functions file includes a function for static MAC address
generation (not yet used) and may contain other common functions we
standardize on.

Added "fedora" user to lxc-fedora template.

Added "centos" user to lxc-centos template.

Dropping "setfcap" has been moved to a comment for Fedora, CentOS,
and SUSE due to it's interference with yum update in containers
(yum fails to update several packages including httpd).

Added "sudo" to the package list for CentOS and Fedora.

Set the apparmor profile for CentOS, Fedora, and SUSE containers to
"unconfined", until someone comes up with something better, in order
to have containers run out of the box on apparmor hosts.  Commented
code in the individual templates has been moved to explicit settings
in the common config files.

Addressed systemd-journald runaway CPU issue by setting lxc.kmsg = 0
in affected template (including Mandriva) and establishing a run time
default to autoswitch lxc.kmsg depending on the state of lxc.autodev
(systemd case).  lxc.kmsg will be set to 0 in the case of lxc.autodev = 1
and set to 1 in the case of lxc.autodev = 0, unless overridden in
the config file.

Signed-off-by: Michael H. Warfield <mhw at WittsEnd.com>
---
 config/templates/centos.common.conf.in   |   8 +-
 config/templates/fedora.common.conf.in   |   8 +-
 config/templates/opensuse.common.conf.in |   7 +-
 configure.ac                             |   1 +
 src/lxc/conf.c                           |  23 +-
 templates/Makefile.am                    |   1 +
 templates/functions.in                   | 208 +++++++++++++++++
 templates/lxc-centos.in                  | 387 ++++++++++++++++---------------
 templates/lxc-fedora.in                  | 318 ++++++++++---------------
 templates/lxc-openmandriva.in            |   1 +
 templates/lxc-opensuse.in                |  50 +++-
 11 files changed, 612 insertions(+), 400 deletions(-)
 create mode 100644 templates/functions.in

diff --git a/config/templates/centos.common.conf.in b/config/templates/centos.common.conf.in
index 4ce2fda..7f39ddf 100644
--- a/config/templates/centos.common.conf.in
+++ b/config/templates/centos.common.conf.in
@@ -20,4 +20,10 @@ lxc.mount.auto = proc:mixed sys:ro
 # lxc.cap.drop = setuid           # breaks sshd,nfs statd
 # lxc.cap.drop = audit_control    # breaks sshd (set_loginuid failed)
 # lxc.cap.drop = audit_write
-lxc.cap.drop = setfcap setpcap sys_nice sys_pacct sys_rawio
+# lxc.cap.drop = setfcap          # setfcap causes all sorts of problems with yum update
+lxc.cap.drop = sys_nice sys_pacct sys_rawio
+
+# This lets LXC CentOS containers run on hosts with apparmor.
+# It does nothing on hosts which do not have apparmor enabled.
+lxc.aa_profile = unconfined
+
diff --git a/config/templates/fedora.common.conf.in b/config/templates/fedora.common.conf.in
index acebe3c..7794945 100644
--- a/config/templates/fedora.common.conf.in
+++ b/config/templates/fedora.common.conf.in
@@ -18,4 +18,10 @@ lxc.include = @LXCTEMPLATECONFIG@/common.conf
 # lxc.cap.drop = audit_control    # breaks sshd (set_loginuid failed)
 # lxc.cap.drop = audit_write
 # lxc.cap.drop = setpcap          # big big login delays in Fedora 20 systemd
-lxc.cap.drop = setfcap sys_nice sys_pacct sys_rawio
+# lxc.cap.drop = setfcap          # setfcap causes all sorts of problems with yum update
+lxc.cap.drop = sys_nice sys_pacct sys_rawio
+
+# This lets LXC Fedora containers run on hosts with apparmor.
+# It does nothing on hosts which do not have apparmor enabled.
+lxc.aa_profile = unconfined
+
diff --git a/config/templates/opensuse.common.conf.in b/config/templates/opensuse.common.conf.in
index 4026975..813d296 100644
--- a/config/templates/opensuse.common.conf.in
+++ b/config/templates/opensuse.common.conf.in
@@ -21,5 +21,10 @@ lxc.autodev = 1
 # lxc.cap.drop = audit_control    # breaks sshd (set_loginuid failed)
 # lxc.cap.drop = audit_write
 # lxc.cap.drop = setpcap          # big big login delays in Fedora 20 systemd
-# lxc.cap.drop = setfcap
+# lxc.cap.drop = setfcap          # setfcap causes all sorts of problems with yum update
 lxc.cap.drop = sys_nice sys_pacct sys_rawio
+
+# This lets LXC SUSE containers run on hosts with apparmor.
+# It does nothing on hosts which do not have apparmor enabled.
+lxc.aa_profile = unconfined
+
diff --git a/configure.ac b/configure.ac
index 5d5f974..c1a575b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -731,6 +731,7 @@ AC_CONFIG_FILES([
 	hooks/Makefile
 
 	templates/Makefile
+	templates/functions
 	templates/lxc-alpine
 	templates/lxc-altlinux
 	templates/lxc-archlinux
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 5e61c35..7e1e564 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -2862,7 +2862,8 @@ struct lxc_conf *lxc_conf_init(void)
 		free(new);
 		return NULL;
 	}
-	new->kmsg = 1;
+	/* Unless this is overriden, decide this based on autodev */
+	new->kmsg = -1;
 	lxc_list_init(&new->cgroup);
 	lxc_list_init(&new->network);
 	lxc_list_init(&new->mount_list);
@@ -4159,6 +4160,26 @@ int lxc_setup(struct lxc_handler *handler)
 			ERROR("failed to mount /dev in the container");
 			return -1;
 		}
+		if (lxc_conf->kmsg < 0) {
+			/*
+			 * Autodev is generally used for systemd.  If systemd
+			 * is running then journald is likely to be running.  If
+			 * journald is running we should NOT symlink /dev/kmsg!
+			 * If we do set the symlink, a logging loop is created
+			 * and journald eats CPU time for lunch!
+			 */
+			lxc_conf->kmsg = 0;
+
+			/*
+			 * Note: This can be overridden by those who know what
+			 *	they are doing and why by explicitly setting
+			 *	lxc.autodev in the container config and setting
+			 *	lxc.kmsg to what ever they like.  Then it's a
+			 *	self-inflicted injury.
+			 */
+		}
+	} else if (lxc_conf->kmsg < 0) {
+			lxc_conf->kmsg = 1;
 	}
 
 	/* do automatic mounts (mainly /proc and /sys), but exclude
diff --git a/templates/Makefile.am b/templates/Makefile.am
index ac870a1..4f05069 100644
--- a/templates/Makefile.am
+++ b/templates/Makefile.am
@@ -1,6 +1,7 @@
 templatesdir=@LXCTEMPLATEDIR@
 
 templates_SCRIPTS = \
+	functions \
 	lxc-alpine \
 	lxc-altlinux \
 	lxc-archlinux \
diff --git a/templates/functions.in b/templates/functions.in
new file mode 100644
index 0000000..ee80120
--- /dev/null
+++ b/templates/functions.in
@@ -0,0 +1,208 @@
+#!/bin/sh -
+
+# templates/functions
+
+# Misc functions for template support.
+
+# Authors:
+# 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
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+###
+# User creation and password support.
+###
+
+# Some combinations of the tuning knobs below do not exactly make sense.
+# but that's ok.
+#
+# If the "root_password" is non-blank, use it, else set a default.
+# This can be passed to the script as an environment variable and is
+# set by a shell conditional assignment.  Looks weird but it is what it is.
+#
+# If the root password contains a ding ($) then try to expand it.
+# That will pick up things like ${name} and ${RANDOM}.
+# If the root password contians more than 3 consecutive X's, pass it as
+# a template to mktemp and take the result.
+#
+# If root_display_password = yes, display the temporary root password at exit.
+# If root_store_password = yes, store it in the configuration directory
+# If root_prompt_password = yes, invoke "passwd" to force the user to change
+# the root password after the container is created.
+# If root_expire_password = yes, you will be prompted to change the root
+# password at the first login.
+#
+# These are conditional assignments...  The can be overridden from the
+# preexisting environment variables in the calling template or from
+# the user environment...
+#
+# Default user...
+: ${LXC_DEFAULT_USER='root'}
+# Make sure this is in single quotes to defer expansion to later!
+# :{root_password='Root-${name}-${RANDOM}'}
+: ${LXC_PASSWORD='Root-${name}-XXXXXX'}
+
+# Now, it doesn't make much sense to display, store, and force change
+# together.  But, we gotta test, right???
+: ${LXC_DISPLAY_PASSWORD='no'}
+: ${LXC_STORE_PASSWORD='yes'}
+
+# Expire root password? Default to yes, but can be overridden from
+# the environment variable
+: ${LXC_EXPIRE_PASSWORD='yes'}
+
+
+# Then above environment variables are for convention and for
+# convenience of use by the calling template.  They may be
+# overriden by the environment, calling line parameters, or the
+# whim of the template writer.  They can be ignored entirely.
+# The values used in setting up a user are the values passed in
+# calling lxc_setup_user().
+
+# lxc_setup_user username password/hash display store expire
+#
+#   Set the user password, creating the user if necessary...
+#
+
+lxc_setup_user() {
+    local CONTAINER_NAME="${1}"
+    local ROOTFS="${2}"
+    local CONFIG_PATH="${3}"
+    local USER="${4}"
+    local PASSWD="${5}"
+    local DISPLAY="${6}"
+    local STORE="${7}"
+    local EXPIRE="${8}"
+
+    # The required groups in this list should alraedy be created.
+    # Groups that don't exist will not be created and will be ignored.
+    # Might be worth making that a tunable parameter as well.  Maybe...
+    local groups="sudo admin wheel"
+
+    # See if the user exists.  For root, this should not be a question.
+    # for non-root defaults (like ubuntu) we may need to create the user.
+    PWENT=$(chroot ${ROOTFS} getent passwd ${USER})
+
+    if [ "$?" != 0 ]
+    then
+        chroot ${ROOTFS} useradd ${USER}
+        for group in $groups; do
+            # We do this individually so that, if a group doesn't exist,
+            # all the groups that do exist have the user added.
+            chroot ${ROOTFS} usermod -a -G ${group} ${USER} >/dev/null 2>&1 || true
+        done
+    fi
+
+    if [ ${PASSWD} = "PROMPT" ]
+    then
+        echo "Invoking the passwd command in the container to set the ${USER} password.
+
+        chroot ${ROOTFS} passwd ${USER}
+"
+        chroot ${ROOTFS} passwd ${USER}
+    elif [ $(expr "${PASSWD}" : '$$') != 0 -o \
+           $(expr "${PASSWD}" : '*$') != 0 -o \
+           $(expr "${PASSWD}" : '!!$') != 0 ]
+    then
+        # Matches one of 3 common "disabled" conventions so treat them
+        # as if they were "hashed" passwords to be copied literally
+        # by chpasswd.  Result is an account with no valid password.
+        if [ ${DISPLAY} = "yes" ]
+        then
+            echo "Disabling ${USER} password"
+        fi
+        echo "${USER}:${PASSWD}" | chroot ${ROOTFS} chpasswd -e
+    elif [ $(expr "${PASSWD}" : '$[0-9][0-9]*$.') != 0 ]
+    then
+        # Matches on a $[0-9]$ hash indicator for a real password hash.
+        if [ ${DISPLAY} = "yes" ]
+        then
+            echo "Setting ${USER} password hash to ${PASSWORD}"
+        fi
+        echo "${USER}:${PASSWD}" | chroot ${ROOTFS} chpasswd -e
+    else
+        # Anything else, assume a clear text password template...
+
+        # Let's do something better for the initial user password.
+        # It's not perfect but it will defeat common scanning brute force
+        # attacks in the case where ssh is exposed.  It may also be set to
+        # expired, forcing the user to change it at first login.
+        if [ "${PASSWD}" = "" ]
+        then
+            PASSWD=${USER}-${CONTAINER_NAME}-${RANDOM}
+        fi
+
+        # If it's got a ding in it, try and expand it!
+        # In theory, this could also access and external program.
+        if [ $(expr "${PASSWD}" : '.*$.') != 0 ]
+        then
+            PASSWD=$(eval echo "${PASSWD}")
+        fi
+
+        # If it has more than 3 consequtive X's in it, feed it
+        # through mktemp as a template.
+        if [ $(expr "${PASSWD}" : '.*XXXX') != 0 ]
+        then
+            PASSWD=$(mktemp -u ${PASSWD})
+        fi
+        if [ ${STORE} = "yes" ]
+        then
+            touch ${config_path}/tmp_pass
+            chmod 600 ${config_path}/tmp_pass
+            # Append the user and password to the file.
+            # We might be ultimately adding more than one.
+            echo ${USER}:${PASSWD} >> ${config_path}/tmp_pass
+
+            echo "The temporary password for ${USER} is stored in:
+
+        '${config_path}/tmp_pass'
+"
+        fi
+
+        if [ ${DISPLAY} = "yes" ]
+        then
+            echo "Setting ${USER} password to '$PASSWORD'"
+        fi
+        echo "${USER}:${PASSWD}" | chroot ${ROOTFS} chpasswd
+    fi
+
+    if [ ${EXPIRE} = "yes" ]
+    then
+        # Also set this password as expired to force the user to change it!
+        chroot ${ROOTFS} passwd -e ${USER}
+        echo "
+The password for ${USER} 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
+${USER} 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} passwd
+"
+    fi
+}
+
+
+###
+# HW Mac address generation support.
+###
+
+# Generate a random hardware (MAC) address composed of FE followed by
+# 5 random bytes...
+lxc_create_hwaddr()
+{
+    openssl rand -hex 5 | sed -e 's/\(..\)/:\1/g; s/^/fe/'
+}
+
diff --git a/templates/lxc-centos.in b/templates/lxc-centos.in
index 1586a90..3f9ef4d 100644
--- a/templates/lxc-centos.in
+++ b/templates/lxc-centos.in
@@ -1,7 +1,7 @@
 #!/bin/bash
 
 #
-# template script for generating centos container for LXC
+# template script for generating a CentOS container for LXC
 
 #
 # lxc: linux Container library
@@ -28,44 +28,13 @@
 
 #Configurations
 default_path=@LXCPATH@
+template_path=@LXCTEMPLATEDIR@
 
-# Some combinations of the tuning knobs below do not exactly make sense.
-# but that's ok.
-#
-# If the "root_password" is non-blank, use it, else set a default.
-# This can be passed to the script as an environment variable and is
-# set by a shell conditional assignment.  Looks weird but it is what it is.
-#
-# If the root password contains a ding ($) then try to expand it.
-# That will pick up things like ${name} and ${RANDOM}.
-# If the root password contians more than 3 consecutive X's, pass it as
-# a template to mktemp and take the result.
-#
-# If root_display_password = yes, display the temporary root password at exit.
-# If root_store_password = yes, store it in the configuration directory
-# If root_prompt_password = yes, invoke "passwd" to force the user to change
-# the root password after the container is created.
-# If root_expire_password = yes, you will be prompted to change the root
-# password at the first login.
-#
-# These are conditional assignments...  The can be overridden from the
-# preexisting environment variables...
-#
-# Make sure this is in single quotes to defer expansion to later!
-# :{root_password='Root-${name}-${RANDOM}'}
-: ${root_password='Root-${name}-XXXXXX'}
-
-# Now, it doesn't make much sense to display, store, and force change
-# together.  But, we gotta test, right???
-: ${root_display_password='no'}
-: ${root_store_password='yes'}
-# Prompting for something interactive has potential for mayhem
-# with users running under the API...  Don't default to "yes"
-: ${root_prompt_password='no'}
-
-# Expire root password? Default to yes, but can be overridden from
-# the environment variable
-: ${root_expire_password='yes'}
+# Load up some common functions
+if [ -f ${template_path}/functions ]
+then
+    . ${template_path}/functions
+fi
 
 # These are only going into comments in the resulting config...
 lxc_network_type=veth
@@ -161,31 +130,31 @@ configure_centos()
 {
 
     # disable selinux in centos
-    mkdir -p $rootfs_path/selinux
-    echo 0 > $rootfs_path/selinux/enforce
+    mkdir -p ${rootfs}/selinux
+    echo 0 > ${rootfs}/selinux/enforce
 
     # Also kill it in the /etc/selinux/config file if it's there...
-    if [ -f $rootfs_path/etc/selinux/config ]
+    if [ -f ${rootfs}/etc/selinux/config ]
     then
-        sed -i '/^SELINUX=/s/.*/SELINUX=disabled/' $rootfs_path/etc/selinux/config
+        sed -i '/^SELINUX=/s/.*/SELINUX=disabled/' ${rootfs}/etc/selinux/config
     fi
 
     # Nice catch from Dwight Engen in the Oracle template.
     # Wantonly plagerized here with much appreciation.
-    if [ -f $rootfs_path/usr/sbin/selinuxenabled ]; then
-        mv $rootfs_path/usr/sbin/selinuxenabled $rootfs_path/usr/sbin/selinuxenabled.lxcorig
-        ln -s /bin/false $rootfs_path/usr/sbin/selinuxenabled
+    if [ -f ${rootfs}/usr/sbin/selinuxenabled ]; then
+        mv ${rootfs}/usr/sbin/selinuxenabled ${rootfs}/usr/sbin/selinuxenabled.lxcorig
+        ln -s /bin/false ${rootfs}/usr/sbin/selinuxenabled
     fi
 
     # This is a known problem and documented in RedHat bugzilla as relating
     # to a problem with auditing enabled.  This prevents an error in
     # the container "Cannot make/remove an entry for the specified session"
-    sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/login
-    sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/sshd
+    sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs}/etc/pam.d/login
+    sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs}/etc/pam.d/sshd
 
-    if [ -f ${rootfs_path}/etc/pam.d/crond ]
+    if [ -f ${rootfs}/etc/pam.d/crond ]
     then
-        sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/crond
+        sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs}/etc/pam.d/crond
     fi
 
     # In addition to disabling pam_loginuid in the above config files
@@ -193,27 +162,27 @@ configure_centos()
     # we missed or any that get installed after the container is built.
     #
     # Catch either or both 32 and 64 bit archs.
-    if [ -f ${rootfs_path}/lib/security/pam_loginuid.so ]
+    if [ -f ${rootfs}/lib/security/pam_loginuid.so ]
     then
-        ( cd ${rootfs_path}/lib/security/
+        ( cd ${rootfs}/lib/security/
         mv pam_loginuid.so pam_loginuid.so.disabled
         ln -s pam_permit.so pam_loginuid.so
         )
     fi
 
-    if [ -f ${rootfs_path}/lib64/security/pam_loginuid.so ]
+    if [ -f ${rootfs}/lib64/security/pam_loginuid.so ]
     then
-        ( cd ${rootfs_path}/lib64/security/
+        ( cd ${rootfs}/lib64/security/
         mv pam_loginuid.so pam_loginuid.so.disabled
         ln -s pam_permit.so pam_loginuid.so
         )
     fi
 
     # Set default localtime to the host localtime if not set...
-    if [ -e /etc/localtime -a ! -e ${rootfs_path}/etc/localtime ]
+    if [ -e /etc/localtime -a ! -e ${rootfs}/etc/localtime ]
     then
         # if /etc/localtime is a symlink, this should preserve it.
-        cp -a /etc/localtime ${rootfs_path}/etc/localtime
+        cp -a /etc/localtime ${rootfs}/etc/localtime
     fi
 
     # Deal with some dain bramage in the /etc/init.d/halt script.
@@ -226,26 +195,26 @@ configure_centos()
     # So we just eliminate the whole bottom half of that script in making
     # ourselves a copy.  That way a major update to the init scripts won't
     # trash what we've set up.
-    if [ -f ${rootfs_path}/etc/init.d/halt ]
+    if [ -f ${rootfs}/etc/init.d/halt ]
     then
         sed -e '/hwclock/,$d' \
-            < ${rootfs_path}/etc/init.d/halt \
-            > ${rootfs_path}/etc/init.d/lxc-halt
+            < ${rootfs}/etc/init.d/halt \
+            > ${rootfs}/etc/init.d/lxc-halt
 
-        echo '$command -f' >> ${rootfs_path}/etc/init.d/lxc-halt
-        chmod 755 ${rootfs_path}/etc/init.d/lxc-halt
+        echo '$command -f' >> ${rootfs}/etc/init.d/lxc-halt
+        chmod 755 ${rootfs}/etc/init.d/lxc-halt
 
         # Link them into the rc directories...
         (
-             cd ${rootfs_path}/etc/rc.d/rc0.d
+             cd ${rootfs}/etc/rc.d/rc0.d
              ln -s ../init.d/lxc-halt S00lxc-halt
-             cd ${rootfs_path}/etc/rc.d/rc6.d
+             cd ${rootfs}/etc/rc.d/rc6.d
              ln -s ../init.d/lxc-halt S00lxc-reboot
         )
     fi
 
     # configure the network using the dhcp
-    cat <<EOF > ${rootfs_path}/etc/sysconfig/network-scripts/ifcfg-eth0
+    cat <<EOF > ${rootfs}/etc/sysconfig/network-scripts/ifcfg-eth0
 DEVICE=eth0
 BOOTPROTO=dhcp
 ONBOOT=yes
@@ -257,25 +226,30 @@ DHCP_HOSTNAME=$name
 EOF
 
     # set the hostname
-    cat <<EOF > ${rootfs_path}/etc/sysconfig/network
+    cat <<EOF > ${rootfs}/etc/sysconfig/network
 NETWORKING=yes
 HOSTNAME=${UTSNAME}
 EOF
 
+    # set hostname on systemd systems
+    if [ $release -gt 6 ]; then
+        echo "${utsname}" > ${rootfs}/etc/hostname
+    fi
+
     # set minimal hosts
-    cat <<EOF > $rootfs_path/etc/hosts
+    cat <<EOF > ${rootfs}/etc/hosts
 127.0.0.1 localhost $name
 EOF
 
     # set minimal fstab
-    cat <<EOF > $rootfs_path/etc/fstab
+    cat <<EOF > ${rootfs}/etc/fstab
 /dev/root               /                       rootfs   defaults        0 0
 none                    /dev/shm                tmpfs    nosuid,nodev    0 0
 EOF
 
     # create lxc compatibility init script
     if [ "$release" = "6" ]; then
-        cat <<EOF > $rootfs_path/etc/init/lxc-sysinit.conf
+        cat <<EOF > ${rootfs}/etc/init/lxc-sysinit.conf
 start on startup
 env container
 
@@ -291,23 +265,23 @@ pre-start script
 end script
 EOF
     elif [ "$release" = "5" ]; then
-        cat <<EOF > $rootfs_path/etc/rc.d/lxc.sysinit
+        cat <<EOF > ${rootfs}/etc/rc.d/lxc.sysinit
 #! /bin/bash
 rm -f /etc/mtab /var/run/*.{pid,lock} /var/lock/subsys/*
 rm -rf {/,/var}/tmp/*
 echo "/dev/root               /                       rootfs   defaults        0 0" > /etc/mtab
 exit 0
 EOF
-        chmod 755 $rootfs_path/etc/rc.d/lxc.sysinit
-        sed -i 's|si::sysinit:/etc/rc.d/rc.sysinit|si::bootwait:/etc/rc.d/lxc.sysinit|'  $rootfs_path/etc/inittab
+        chmod 755 ${rootfs}/etc/rc.d/lxc.sysinit
+        sed -i 's|si::sysinit:/etc/rc.d/rc.sysinit|si::bootwait:/etc/rc.d/lxc.sysinit|'  ${rootfs}/etc/inittab
         # prevent mingetty from calling vhangup(2) since it fails with userns.
         # Same issue as oracle template: prevent mingetty from calling vhangup(2)
         # commit 2e83f7201c5d402478b9849f0a85c62d5b9f1589.
-        sed -i 's|^1:|co:2345:respawn:/sbin/mingetty --nohangup console\n1:|' $rootfs_path/etc/inittab
-        sed -i 's|^\([56]:\)|#\1|' $rootfs_path/etc/inittab
+        sed -i 's|^1:|co:2345:respawn:/sbin/mingetty --nohangup console\n1:|' ${rootfs}/etc/inittab
+        sed -i 's|^\([56]:\)|#\1|' ${rootfs}/etc/inittab
     fi
 
-    dev_path="${rootfs_path}/dev"
+    dev_path="${rootfs}/dev"
     rm -rf $dev_path
     mkdir -p $dev_path
     mknod -m 666 ${dev_path}/null c 1 3
@@ -334,59 +308,39 @@ EOF
     # since lxc.devttydir is specified in the config.
 
     # allow root login on console, tty[1-4], and pts/0 for libvirt
-    echo "# LXC (Linux Containers)" >>${rootfs_path}/etc/securetty
-    echo "lxc/console"  >>${rootfs_path}/etc/securetty
-    echo "lxc/tty1"     >>${rootfs_path}/etc/securetty
-    echo "lxc/tty2"     >>${rootfs_path}/etc/securetty
-    echo "lxc/tty3"     >>${rootfs_path}/etc/securetty
-    echo "lxc/tty4"     >>${rootfs_path}/etc/securetty
-    echo "# For libvirt/Virtual Machine Monitor" >>${rootfs_path}/etc/securetty
-    echo "pts/0"        >>${rootfs_path}/etc/securetty
+    echo "# LXC (Linux Containers)" >>${rootfs}/etc/securetty
+    echo "lxc/console"  >>${rootfs}/etc/securetty
+    echo "lxc/tty1"     >>${rootfs}/etc/securetty
+    echo "lxc/tty2"     >>${rootfs}/etc/securetty
+    echo "lxc/tty3"     >>${rootfs}/etc/securetty
+    echo "lxc/tty4"     >>${rootfs}/etc/securetty
+    echo "# For libvirt/Virtual Machine Monitor" >>${rootfs}/etc/securetty
+    echo "pts/0"        >>${rootfs}/etc/securetty
 
     # prevent mingetty from calling vhangup(2) since it fails with userns.
     # Same issue as oracle template: prevent mingetty from calling vhangup(2)
     # commit 2e83f7201c5d402478b9849f0a85c62d5b9f1589.
-    sed -i 's|mingetty|mingetty --nohangup|' $container_rootfs/etc/init/tty.conf
-
-    if [ ${root_display_password} = "yes" ]
-    then
-        echo "Setting root password to '$root_password'"
-    fi
-    if [ ${root_store_password} = "yes" ]
+    if [ -f ${rootfs}/etc/init/tty.conf ]
     then
-        touch ${config_path}/tmp_root_pass
-        chmod 600 ${config_path}/tmp_root_pass
-        echo ${root_password} > ${config_path}/tmp_root_pass
-        echo "Storing root password in '${config_path}/tmp_root_pass'"
+        sed -i 's|mingetty|mingetty --nohangup|' ${rootfs}/etc/init/tty.conf
     fi
 
-    echo "root:$root_password" | chroot $rootfs_path chpasswd
-
-    if [ ${root_expire_password} = "yes" ]
-    then
-        # Also 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
 }
 
 configure_centos_init()
 {
-    sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc/rc.sysinit
-    sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc/rc.d/rc.sysinit
+    sed -i 's|.sbin.start_udev||' ${rootfs}/etc/rc.sysinit
+    sed -i 's|.sbin.start_udev||' ${rootfs}/etc/rc.d/rc.sysinit
     if [ "$release" = "6" ]; then
-        chroot ${rootfs_path} chkconfig udev-post off
+        chroot ${rootfs} chkconfig udev-post off
     fi
-    chroot ${rootfs_path} chkconfig network on
+    chroot ${rootfs} chkconfig network on
 
-    if [ -d ${rootfs_path}/etc/init ]
+    if [ -d ${rootfs}/etc/init ]
     then
        # This is to make upstart honor SIGPWR
-        cat <<EOF >${rootfs_path}/etc/init/power-status-changed.conf
+        cat <<EOF >${rootfs}/etc/init/power-status-changed.conf
 #  power-status-changed - shutdown on SIGPWR
 #
 start on power-status-changed
@@ -396,6 +350,35 @@ EOF
     fi
 }
 
+configure_centos_systemd()
+{
+    rm -f ${rootfs}/etc/systemd/system/default.target
+    touch ${rootfs}/etc/fstab
+    chroot ${rootfs} ln -s /dev/null /etc/systemd/system/udev.service
+    chroot ${rootfs} ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target
+    # Make systemd honor SIGPWR
+    chroot ${rootfs} ln -s /usr/lib/systemd/system/halt.target /etc/systemd/system/sigpwr.target
+    #dependency on a device unit fails it specially that we disabled udev
+    # sed -i 's/After=dev-%i.device/After=/' ${rootfs}/lib/systemd/system/getty\@.service
+    #
+    # Actually, the After=dev-%i.device line does not appear in the
+    # Fedora 17 or Fedora 18 systemd getty\@.service file.  It may be left
+    # over from an earlier version and it's not doing any harm.  We do need
+    # to disable the "ConditionalPathExists=/dev/tty0" line or no gettys are
+    # started on the ttys in the container.  Lets do it in an override copy of
+    # the service so it can still pass rpm verifies and not be automatically
+    # updated by a new systemd version.  --  mhw  /\/\|=mhw=|\/\/
+
+    sed -e 's/^ConditionPathExists=/# ConditionPathExists=/' \
+        -e 's/After=dev-%i.device/After=/' \
+        < ${rootfs}/lib/systemd/system/getty\@.service \
+        > ${rootfs}/etc/systemd/system/getty\@.service
+    # Setup getty service on the 4 ttys we are going to allow in the
+    # default config.  Number should match lxc.tty
+    ( cd ${rootfs}/etc/systemd/system/getty.target.wants
+        for i in 1 2 3 4 ; do ln -sf ../getty\@.service getty at tty${i}.service; done )
+}
+
 download_centos()
 {
 
@@ -410,19 +393,19 @@ download_centos()
     # 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-minimal sudo openssh-server openssh-clients dhclient chkconfig rootfiles policycoreutils"
 
     # 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
-	cat <<EOF > $REPO_FILE
+        cat <<EOF > $REPO_FILE
 [base]
 name=local repository
 baseurl="$repo"
 EOF
 else
-	cat <<EOF > $REPO_FILE
+        cat <<EOF > $REPO_FILE
 [base]
 name=CentOS-$release - Base
 mirrorlist=http://mirrorlist.centos.org/?release=$release&arch=$basearch&repo=os
@@ -434,20 +417,23 @@ EOF
     fi
 
     # create minimal device nodes, needed for "yum install" and "yum update" process
-    mkdir -p $INSTALL_ROOT/dev
-    force_mknod 666 $INSTALL_ROOT/dev/null c 1 3
-    force_mknod 666 $INSTALL_ROOT/dev/urandom c 1 9
+    mkdir -p $INSTALL_ROOT/dev $INSTALL_ROOT/proc
+
+    # CentOS7 needs these, even if they are overkill for 5&6.
+    mount -o bind /dev ${INSTALL_ROOT}/dev
+    mount -t proc proc ${INSTALL_ROOT}/proc
+    # Always make sure /etc/resolv.conf is up to date in the target!
+    cp /etc/resolv.conf ${INSTALL_ROOT}/etc/
 
     $YUM install $PKG_LIST
 
     if [ $? -ne 0 ]; then
         echo "Failed to download the rootfs, aborting."
+        umount ${INSTALL_ROOT}/proc
+        umount ${INSTALL_ROOT}/dev
         return 1
     fi
 
-    # use same nameservers as hosts, needed for "yum update later"
-    cp /etc/resolv.conf $INSTALL_ROOT/etc/
-
     # check whether rpmdb is under $HOME
     if [ ! -e $INSTALL_ROOT/var/lib/rpm/Packages -a -e $INSTALL_ROOT/$HOME/.rpmdb/Packages ]; then
         echo "Fixing rpmdb location ..."
@@ -469,17 +455,26 @@ EOF
         mv $INSTALL_ROOT/etc/yum.repos.d/*.repo $INSTALL_ROOT/etc/yum.repos.disabled/
         mv $REPO_FILE.tmp $REPO_FILE
         mkdir -p $INSTALL_ROOT/$INSTALL_ROOT/etc
-        cp /etc/resolv.conf $INSTALL_ROOT/$INSTALL_ROOT/etc/
         mkdir -p $INSTALL_ROOT/$INSTALL_ROOT/dev
-        mknod -m 666 $INSTALL_ROOT/$INSTALL_ROOT/dev/null c 1 3
-        mknod -m 666 $INSTALL_ROOT/$INSTALL_ROOT/dev/urandom c 1 9
+        mkdir -p $INSTALL_ROOT/$INSTALL_ROOT/proc
+        # CentOS7 needs these, even if they are overkill for 5&6.
+        mount -o bind /dev ${INSTALL_ROOT}/${INSTALL_ROOT}/dev
+        mount -t proc proc ${INSTALL_ROOT}/${INSTALL_ROOT}/proc
+        # Always make sure /etc/resolv.conf is up to date in the target!
+        cp /etc/resolv.conf $INSTALL_ROOT/$INSTALL_ROOT/etc/
         mkdir -p $INSTALL_ROOT/$INSTALL_ROOT/var/cache/yum
         cp -al $INSTALL_ROOT/var/cache/yum/* $INSTALL_ROOT/$INSTALL_ROOT/var/cache/yum/
         chroot $INSTALL_ROOT $YUM install $PKG_LIST
         if [ $? -ne 0 ]; then
             echo "Failed to download the rootfs, aborting."
+            umount ${INSTALL_ROOT}/${INSTALL_ROOT}/proc
+            umount ${INSTALL_ROOT}/${INSTALL_ROOT}/dev
+            umount ${INSTALL_ROOT}/proc
+            umount ${INSTALL_ROOT}/dev
             return 1
         fi
+        umount ${INSTALL_ROOT}/proc
+        umount ${INSTALL_ROOT}/dev
         mv $INSTALL_ROOT/$INSTALL_ROOT $INSTALL_ROOT.tmp
         rm -rf $INSTALL_ROOT
         mv $INSTALL_ROOT.tmp $INSTALL_ROOT
@@ -488,6 +483,9 @@ EOF
     rm -f $REPO_FILE
     rm -rf $INSTALL_ROOT/var/cache/yum/*
 
+    umount ${INSTALL_ROOT}/proc
+    umount ${INSTALL_ROOT}/dev
+
     mv "$INSTALL_ROOT" "$cache/rootfs"
     echo "Download complete."
 
@@ -498,11 +496,11 @@ copy_centos()
 {
 
     # make a local copy of the mini centos
-    echo -n "Copying rootfs to $rootfs_path ..."
-    #cp -a $cache/rootfs-$arch $rootfs_path || return 1
+    echo -n "Copying rootfs to ${rootfs} ..."
+    #cp -a $cache/rootfs-$arch ${rootfs} || return 1
     # i prefer rsync (no reason really)
-    mkdir -p $rootfs_path
-    rsync -a $cache/rootfs/ $rootfs_path/
+    mkdir -p ${rootfs}
+    rsync -a $cache/rootfs/ ${rootfs}/
     echo
     return 0
 }
@@ -510,11 +508,24 @@ copy_centos()
 update_centos()
 {
     YUM="chroot $cache/rootfs yum -y --nogpgcheck"
+
+    # CentOS7 needs these, even if they are overkill for 5&6.
+    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/
+
     $YUM update
     if [ $? -ne 0 ]; then
+        umount ${cache}/rootfs/dev
+        umount ${cache}/rootfs/proc
         return 1
     fi
     $YUM clean packages
+
+    echo
+    umount ${cache}/rootfs/dev
+    umount ${cache}/rootfs/proc
 }
 
 install_centos()
@@ -544,7 +555,7 @@ install_centos()
         fi
     fi
 
-    echo "Copy $cache/rootfs to $rootfs_path ... "
+    echo "Copy $cache/rootfs to ${rootfs} ... "
     copy_centos
     if [ $? -ne 0 ]; then
         echo "Failed to copy rootfs"
@@ -568,7 +579,7 @@ copy_configuration()
     mkdir -p $config_path
 
     grep -q "^lxc.rootfs" $config_path/config 2>/dev/null || echo "
-lxc.rootfs = $rootfs_path
+lxc.rootfs = ${rootfs}
 " >> $config_path/config
 
     # The following code is to create static MAC addresses for each
@@ -612,11 +623,19 @@ lxc.include = @LXCTEMPLATECONFIG@/centos.common.conf
 lxc.arch = $arch
 lxc.utsname = $utsname
 
-lxc.autodev = $auto_dev
+EOF
 
-# When using LXC with apparmor, uncomment the next line to run unconfined:
-#lxc.aa_profile = unconfined
+    if [ "${auto_dev}" != "0" ]
+    then
+        # Keep systemd and journald happy...
+        echo "\
+lxc.autodev = 1
+lxc.kmsg = 0
+" >> $config_path/config
+    fi
 
+    # Throw on some commments...
+    cat <<EOF >> $config_path/config
 # example simple networking setup, uncomment to enable
 #lxc.network.type = $lxc_network_type
 #lxc.network.flags = up
@@ -699,7 +718,7 @@ do
         -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;;
         --)             shift 1; break ;;
@@ -757,28 +776,6 @@ 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
-# expired, forcing the user to change it at first login.
-if [ "${root_password}" = "" ]
-then
-    root_password=Root-${name}-${RANDOM}
-else
-    # If it's got a ding in it, try and expand it!
-    if [ $(expr "${root_password}" : '.*$.') != 0 ]
-    then
-        root_password=$(eval echo "${root_password}")
-    fi
-
-    # If it has more than 3 consequtive X's in it, feed it
-    # through mktemp as a template.
-    if [ $(expr "${root_password}" : '.*XXXX') != 0 ]
-    then
-        root_password=$(mktemp -u ${root_password})
-    fi
-fi
-
 if [ -z "${utsname}" ]; then
     utsname=${name}
 fi
@@ -844,14 +841,15 @@ if [ "$(id -u)" != "0" ]; then
 fi
 
 
-if [ -z "$rootfs_path" ]; then
-    rootfs_path=$path/rootfs
+if [ -z "${rootfs}" ]; then
+    rootfs=$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=$(sed -e '/^lxc.rootfs\s*=/!d' -e 's/\s*#.*//' \
+        rootfs=$(sed -e '/^lxc.rootfs\s*=/!d' -e 's/\s*#.*//' \
             -e 's/^lxc.rootfs\s*=\s*//' -e q $path/config)
     fi
 fi
+
 config_path=$path
 cache=$cache_base/$release
 
@@ -885,51 +883,54 @@ if [ $? -ne 0 ]; then
     exit 1
 fi
 
-configure_centos_init
+# If the systemd configuration directory exists - set it up for what we need.
+if [ -d ${rootfs}/etc/systemd/system ]
+then
+    configure_centos_systemd
+fi
+
+# This configuration (rc.sysinit) is not inconsistent with the systemd stuff
+# above and may actually coexist on some upgraded systems.  Let's just make
+# sure that, if it exists, we update this file, even if it's not used...
+if [ -f ${rootfs}/etc/rc.sysinit ]
+then
+    configure_centos_init
+fi
 
 if [ ! -z $clean ]; then
     clean || exit 1
     exit 0
 fi
+
 echo "
 Container rootfs and config have been created.
 Edit the config file to check/enable networking setup.
 "
 
-if [ ${root_display_password} = "yes" ]
-then
-    echo "The temporary password for root is: '$root_password'
+# Set up the superuser user.
+# Several of the LXC_ variables are environment variables set up
+# in the "functions" file but can be overriden byt the calling environment
+# or by the template or ignored in calling this function.
+lxc_setup_user \
+    "${name}" \
+    "${rootfs}" \
+    "${config_path}" \
+    "${LXC_DEFAULT_USER}" \
+    "${LXC_PASSWORD}" \
+    "${LXC_DISPLAY_PASSWORD}" \
+    "${LXC_STORE_PASSWORD}" \
+    "${LXC_EXPIRE_PASSWORD}"
+
+# Add a "centos" user using the same template and config.
+# This is congruent with several other templates...
+lxc_setup_user \
+    "${name}" \
+    "${rootfs}" \
+    "${config_path}" \
+    "centos" \
+    "${LXC_PASSWORD}" \
+    "${LXC_DISPLAY_PASSWORD}" \
+    "${LXC_STORE_PASSWORD}" \
+    "${LXC_EXPIRE_PASSWORD}"
 
-You may want to note that password down before starting the container.
-"
-fi
-
-if [ ${root_store_password} = "yes" ]
-then
-    echo "The temporary root password is stored in:
-
-        '${config_path}/tmp_root_pass'
-"
-fi
-
-if [ ${root_prompt_password} = "yes" ]
-then
-    echo "Invoking the passwd command in the container to set the root password.
-
-        chroot ${rootfs_path} passwd
-"
-    chroot ${rootfs_path} passwd
-else
-    if [ ${root_expire_password} = "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
+exit 0
diff --git a/templates/lxc-fedora.in b/templates/lxc-fedora.in
index a56e7ec..bfc2fc7 100644
--- a/templates/lxc-fedora.in
+++ b/templates/lxc-fedora.in
@@ -28,44 +28,13 @@
 
 #Configurations
 default_path=@LXCPATH@
+template_path=@LXCTEMPLATEDIR@
 
-# Some combinations of the tuning knobs below do not exactly make sense.
-# but that's ok.
-#
-# If the "root_password" is non-blank, use it, else set a default.
-# This can be passed to the script as an environment variable and is
-# set by a shell conditional assignment.  Looks weird but it is what it is.
-#
-# If the root password contains a ding ($) then try to expand it.
-# That will pick up things like ${name} and ${RANDOM}.
-# If the root password contians more than 3 consecutive X's, pass it as
-# a template to mktemp and take the result.
-#
-# If root_display_password = yes, display the temporary root password at exit.
-# If root_store_password = yes, store it in the configuration directory
-# If root_prompt_password = yes, invoke "passwd" to force the user to change
-# the root password after the container is created.
-# If root_expire_password = yes, you will be prompted to change the root
-# password at the first login.
-#
-# These are conditional assignments...  The can be overridden from the
-# preexisting environment variables...
-#
-# Make sure this is in single quotes to defer expansion to later!
-# :{root_password='Root-${name}-${RANDOM}'}
-: ${root_password='Root-${name}-XXXXXX'}
-
-# Now, it doesn't make much sense to display, store, and force change
-# together.  But, we gotta test, right???
-: ${root_display_password='no'}
-: ${root_store_password='yes'}
-# Prompting for something interactive has potential for mayhem
-# with users running under the API...  Don't default to "yes"
-: ${root_prompt_password='no'}
-
-# Expire root password? Default to yes, but can be overridden from
-# the environment variable
-: ${root_expire_password='yes'}
+# Load up some common functions
+if [ -f ${template_path}/functions ]
+then
+    . ${template_path}/functions
+fi
 
 # These are only going into comments in the resulting config...
 lxc_network_type=veth
@@ -134,31 +103,31 @@ configure_fedora()
 {
 
     # disable selinux in fedora
-    mkdir -p $rootfs_path/selinux
-    echo 0 > $rootfs_path/selinux/enforce
+    mkdir -p ${rootfs}/selinux
+    echo 0 > ${rootfs}/selinux/enforce
 
     # Also kill it in the /etc/selinux/config file if it's there...
-    if [[ -f $rootfs_path/etc/selinux/config ]]
+    if [[ -f ${rootfs}/etc/selinux/config ]]
     then
-        sed -i '/^SELINUX=/s/.*/SELINUX=disabled/' $rootfs_path/etc/selinux/config
+        sed -i '/^SELINUX=/s/.*/SELINUX=disabled/' ${rootfs}/etc/selinux/config
     fi
 
     # Nice catch from Dwight Engen in the Oracle template.
     # Wantonly plagerized here with much appreciation.
-    if [ -f $rootfs_path/usr/sbin/selinuxenabled ]; then
-        mv $rootfs_path/usr/sbin/selinuxenabled $rootfs_path/usr/sbin/selinuxenabled.lxcorig
-        ln -s /bin/false $rootfs_path/usr/sbin/selinuxenabled
+    if [ -f ${rootfs}/usr/sbin/selinuxenabled ]; then
+        mv ${rootfs}/usr/sbin/selinuxenabled ${rootfs}/usr/sbin/selinuxenabled.lxcorig
+        ln -s /bin/false ${rootfs}/usr/sbin/selinuxenabled
     fi
 
     # This is a known problem and documented in RedHat bugzilla as relating
     # to a problem with auditing enabled.  This prevents an error in
     # the container "Cannot make/remove an entry for the specified session"
-    sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/login
-    sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/sshd
+    sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs}/etc/pam.d/login
+    sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs}/etc/pam.d/sshd
 
-    if [ -f ${rootfs_path}/etc/pam.d/crond ]
+    if [ -f ${rootfs}/etc/pam.d/crond ]
     then
-        sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/crond
+        sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs}/etc/pam.d/crond
     fi
 
     # In addition to disabling pam_loginuid in the above config files
@@ -166,27 +135,27 @@ configure_fedora()
     # we missed or any that get installed after the container is built.
     #
     # Catch either or both 32 and 64 bit archs.
-    if [ -f ${rootfs_path}/lib/security/pam_loginuid.so ]
+    if [ -f ${rootfs}/lib/security/pam_loginuid.so ]
     then
-        ( cd ${rootfs_path}/lib/security/
+        ( cd ${rootfs}/lib/security/
         mv pam_loginuid.so pam_loginuid.so.disabled
         ln -s pam_permit.so pam_loginuid.so
         )
     fi
 
-    if [ -f ${rootfs_path}/lib64/security/pam_loginuid.so ]
+    if [ -f ${rootfs}/lib64/security/pam_loginuid.so ]
     then
-        ( cd ${rootfs_path}/lib64/security/
+        ( cd ${rootfs}/lib64/security/
         mv pam_loginuid.so pam_loginuid.so.disabled
         ln -s pam_permit.so pam_loginuid.so
         )
     fi
 
     # Set default localtime to the host localtime if not set...
-    if [ -e /etc/localtime -a ! -e ${rootfs_path}/etc/localtime ]
+    if [ -e /etc/localtime -a ! -e ${rootfs}/etc/localtime ]
     then
         # if /etc/localtime is a symlink, this should preserve it.
-        cp -a /etc/localtime ${rootfs_path}/etc/localtime
+        cp -a /etc/localtime ${rootfs}/etc/localtime
     fi
 
     # Deal with some dain bramage in the /etc/init.d/halt script.
@@ -202,26 +171,26 @@ configure_fedora()
     #
     # This is mostly for legacy distros since any modern systemd Fedora
     # release will not have this script so we won't try to intercept it.
-    if [ -f ${rootfs_path}/etc/init.d/halt ]
+    if [ -f ${rootfs}/etc/init.d/halt ]
     then
         sed -e '/hwclock/,$d' \
-            < ${rootfs_path}/etc/init.d/halt \
-            > ${rootfs_path}/etc/init.d/lxc-halt
+            < ${rootfs}/etc/init.d/halt \
+            > ${rootfs}/etc/init.d/lxc-halt
 
-        echo '$command -f' >> ${rootfs_path}/etc/init.d/lxc-halt
-        chmod 755 ${rootfs_path}/etc/init.d/lxc-halt
+        echo '$command -f' >> ${rootfs}/etc/init.d/lxc-halt
+        chmod 755 ${rootfs}/etc/init.d/lxc-halt
 
         # Link them into the rc directories...
         (
-             cd ${rootfs_path}/etc/rc.d/rc0.d
+             cd ${rootfs}/etc/rc.d/rc0.d
              ln -s ../init.d/lxc-halt S00lxc-halt
-             cd ${rootfs_path}/etc/rc.d/rc6.d
+             cd ${rootfs}/etc/rc.d/rc6.d
              ln -s ../init.d/lxc-halt S00lxc-reboot
         )
     fi
 
     # configure the network using the dhcp
-    cat <<EOF > ${rootfs_path}/etc/sysconfig/network-scripts/ifcfg-eth0
+    cat <<EOF > ${rootfs}/etc/sysconfig/network-scripts/ifcfg-eth0
 DEVICE=eth0
 BOOTPROTO=dhcp
 ONBOOT=yes
@@ -232,18 +201,18 @@ MTU=${MTU}
 EOF
 
     # set the hostname
-    cat <<EOF > ${rootfs_path}/etc/sysconfig/network
+    cat <<EOF > ${rootfs}/etc/sysconfig/network
 NETWORKING=yes
 HOSTNAME=${utsname}
 EOF
 
     # set hostname on systemd Fedora systems
     if [ $release -gt 14 ]; then
-        echo "${utsname}" > ${rootfs_path}/etc/hostname
+        echo "${utsname}" > ${rootfs}/etc/hostname
     fi
 
     # set minimal hosts
-    cat <<EOF > $rootfs_path/etc/hosts
+    cat <<EOF > ${rootfs}/etc/hosts
 127.0.0.1 localhost.localdomain localhost $utsname
 ::1                 localhost6.localdomain6 localhost6
 EOF
@@ -251,7 +220,7 @@ EOF
     # These mknod's really don't make any sense with modern releases of
     # Fedora with systemd, devtmpfs, and autodev enabled.  They are left
     # here for legacy reasons and older releases with upstart and sysv init.
-    dev_path="${rootfs_path}/dev"
+    dev_path="${rootfs}/dev"
     rm -rf $dev_path
     mkdir -p $dev_path
     mknod -m 666 ${dev_path}/null c 1 3
@@ -278,83 +247,63 @@ EOF
     # since lxc.devttydir is specified in the config.
 
     # allow root login on console, tty[1-4], and pts/0 for libvirt
-    echo "# LXC (Linux Containers)" >>${rootfs_path}/etc/securetty
-    echo "lxc/console"  >>${rootfs_path}/etc/securetty
-    echo "lxc/tty1"     >>${rootfs_path}/etc/securetty
-    echo "lxc/tty2"     >>${rootfs_path}/etc/securetty
-    echo "lxc/tty3"     >>${rootfs_path}/etc/securetty
-    echo "lxc/tty4"     >>${rootfs_path}/etc/securetty
-    echo "# For libvirt/Virtual Machine Monitor" >>${rootfs_path}/etc/securetty
-    echo "pts/0"        >>${rootfs_path}/etc/securetty
-
-    if [ ${root_display_password} = "yes" ]
-    then
-        echo "Setting root password to '$root_password'"
-    fi
-    if [ ${root_store_password} = "yes" ]
-    then
-        touch ${config_path}/tmp_root_pass
-        chmod 600 ${config_path}/tmp_root_pass
-        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
-
-    if [ ${root_expire_password} = "yes" ]
-    then
-        # Also set this password as expired to force the user to change it!
-        chroot $rootfs_path passwd -e root
-    fi
+    echo "# LXC (Linux Containers)" >>${rootfs}/etc/securetty
+    echo "lxc/console"  >>${rootfs}/etc/securetty
+    echo "lxc/tty1"     >>${rootfs}/etc/securetty
+    echo "lxc/tty2"     >>${rootfs}/etc/securetty
+    echo "lxc/tty3"     >>${rootfs}/etc/securetty
+    echo "lxc/tty4"     >>${rootfs}/etc/securetty
+    echo "# For libvirt/Virtual Machine Monitor" >>${rootfs}/etc/securetty
+    echo "pts/0"        >>${rootfs}/etc/securetty
 
     # specifying this in the initial packages doesn't always work.
     # Even though it should have...
     echo "installing fedora-release package"
-    mount -o bind /dev ${rootfs_path}/dev
-    mount -t proc proc ${rootfs_path}/proc
+    mount -o bind /dev ${rootfs}/dev
+    mount -t proc proc ${rootfs}/proc
     # Always make sure /etc/resolv.conf is up to date in the target!
-    cp /etc/resolv.conf ${rootfs_path}/etc/
+    cp /etc/resolv.conf ${rootfs}/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
+    rm -f ${rootfs}/var/lib/rpm/__db*
+    chroot ${rootfs} rpm --rebuilddb
+    chroot ${rootfs} yum -y install fedora-release
 
-    if [[ ! -e ${rootfs_path}/sbin/NetworkManager ]]
+    if [[ ! -e ${rootfs}/sbin/NetworkManager ]]
     then
         # NetworkManager has not been installed.  Use the
         # legacy chkconfig command to enable the network startup
         # scripts in the container.
-        chroot ${rootfs_path} chkconfig network on
+        chroot ${rootfs} chkconfig network on
     fi
 
-    umount ${rootfs_path}/proc
-    umount ${rootfs_path}/dev
+    umount ${rootfs}/proc
+    umount ${rootfs}/dev
 
     # silence some needless startup errors
-    touch ${rootfs_path}/etc/fstab
+    touch ${rootfs}/etc/fstab
 
     # give us a console on /dev/console
     sed -i 's/ACTIVE_CONSOLES=.*$/ACTIVE_CONSOLES="\/dev\/console \/dev\/tty[1-4]"/' \
-        ${rootfs_path}/etc/sysconfig/init
+        ${rootfs}/etc/sysconfig/init
 
     return 0
 }
 
 configure_fedora_init()
 {
-    sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc/rc.sysinit
-    sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc/rc.d/rc.sysinit
+    sed -i 's|.sbin.start_udev||' ${rootfs}/etc/rc.sysinit
+    sed -i 's|.sbin.start_udev||' ${rootfs}/etc/rc.d/rc.sysinit
     # don't mount devpts, for pete's sake
-    sed -i 's/^.*dev.pts.*$/#\0/' ${rootfs_path}/etc/rc.sysinit
-    sed -i 's/^.*dev.pts.*$/#\0/' ${rootfs_path}/etc/rc.d/rc.sysinit
-    chroot ${rootfs_path} chkconfig udev-post off
-    chroot ${rootfs_path} chkconfig network on
+    sed -i 's/^.*dev.pts.*$/#\0/' ${rootfs}/etc/rc.sysinit
+    sed -i 's/^.*dev.pts.*$/#\0/' ${rootfs}/etc/rc.d/rc.sysinit
+    chroot ${rootfs} chkconfig udev-post off
+    chroot ${rootfs} chkconfig network on
 
-    if [ -d ${rootfs_path}/etc/init ]
+    if [ -d ${rootfs}/etc/init ]
     then
        # This is to make upstart honor SIGPWR.  Should do no harm
        # on systemd systems and some systems may have both.
-        cat <<EOF >${rootfs_path}/etc/init/power-status-changed.conf
+        cat <<EOF >${rootfs}/etc/init/power-status-changed.conf
 #  power-status-changed - shutdown on SIGPWR
 #
 start on power-status-changed
@@ -366,14 +315,14 @@ EOF
 
 configure_fedora_systemd()
 {
-    rm -f ${rootfs_path}/etc/systemd/system/default.target
-    touch ${rootfs_path}/etc/fstab
-    chroot ${rootfs_path} ln -s /dev/null /etc/systemd/system/udev.service
-    chroot ${rootfs_path} ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target
+    rm -f ${rootfs}/etc/systemd/system/default.target
+    touch ${rootfs}/etc/fstab
+    chroot ${rootfs} ln -s /dev/null /etc/systemd/system/udev.service
+    chroot ${rootfs} ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target
     # Make systemd honor SIGPWR
-    chroot ${rootfs_path} ln -s /usr/lib/systemd/system/halt.target /etc/systemd/system/sigpwr.target
+    chroot ${rootfs} ln -s /usr/lib/systemd/system/halt.target /etc/systemd/system/sigpwr.target
     #dependency on a device unit fails it specially that we disabled udev
-    # sed -i 's/After=dev-%i.device/After=/' ${rootfs_path}/lib/systemd/system/getty\@.service
+    # sed -i 's/After=dev-%i.device/After=/' ${rootfs}/lib/systemd/system/getty\@.service
     #
     # Actually, the After=dev-%i.device line does not appear in the
     # Fedora 17 or Fedora 18 systemd getty\@.service file.  It may be left
@@ -385,11 +334,11 @@ configure_fedora_systemd()
 
     sed -e 's/^ConditionPathExists=/# ConditionPathExists=/' \
         -e 's/After=dev-%i.device/After=/' \
-        < ${rootfs_path}/lib/systemd/system/getty\@.service \
-        > ${rootfs_path}/etc/systemd/system/getty\@.service
+        < ${rootfs}/lib/systemd/system/getty\@.service \
+        > ${rootfs}/etc/systemd/system/getty\@.service
     # Setup getty service on the 4 ttys we are going to allow in the
     # default config.  Number should match lxc.tty
-    ( cd ${rootfs_path}/etc/systemd/system/getty.target.wants
+    ( cd ${rootfs}/etc/systemd/system/getty.target.wants
         for i in 1 2 3 4 ; do ln -sf ../getty\@.service getty at tty${i}.service; done )
 }
 
@@ -970,11 +919,11 @@ copy_fedora()
 {
 
     # make a local copy of the minifedora
-    echo -n "Copying rootfs to $rootfs_path ..."
-    #cp -a $cache/rootfs-$basearch $rootfs_path || return 1
+    echo -n "Copying rootfs to ${rootfs} ..."
+    #cp -a $cache/rootfs-$basearch ${rootfs} || return 1
     # i prefer rsync (no reason really)
-    mkdir -p $rootfs_path
-    rsync -Ha $cache/rootfs/ $rootfs_path/
+    mkdir -p ${rootfs}
+    rsync -Ha $cache/rootfs/ ${rootfs}/
     echo
     return 0
 }
@@ -1017,7 +966,7 @@ install_fedora()
             fi
         fi
 
-        echo "Copy $cache/rootfs to $rootfs_path ... "
+        echo "Copy $cache/rootfs to ${rootfs} ... "
         copy_fedora
         if [ $? -ne 0 ]; then
             echo "Failed to copy rootfs"
@@ -1042,7 +991,7 @@ copy_configuration()
     mkdir -p $config_path
 
     grep -q "^lxc.rootfs" $config_path/config 2>/dev/null || echo "
-lxc.rootfs = $rootfs_path
+lxc.rootfs = ${rootfs}
 " >> $config_path/config
 
     # The following code is to create static MAC addresses for each
@@ -1088,11 +1037,19 @@ lxc.include = @LXCTEMPLATECONFIG@/fedora.common.conf
 lxc.arch = $arch
 lxc.utsname = $utsname
 
-lxc.autodev = $auto_dev
+EOF
 
-# When using LXC with apparmor, uncomment the next line to run unconfined:
-#lxc.aa_profile = unconfined
+    if [ "${auto_dev}" != "0" ]
+    then
+        # Keep systemd and journald happy...
+        echo "\
+lxc.autodev = 1
+lxc.kmsg = 0
+" >> $config_path/config
+    fi
 
+    # Throw on some commments...
+    cat <<EOF >> $config_path/config
 # example simple networking setup, uncomment to enable
 #lxc.network.type = $lxc_network_type
 #lxc.network.flags = up
@@ -1232,28 +1189,6 @@ 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
-# expired, forcing the user to change it at first login.
-if [ "${root_password}" = "" ]
-then
-    root_password=Root-${name}-${RANDOM}
-else
-    # If it's got a ding in it, try and expand it!
-    if [ $(expr "${root_password}" : '.*$.') != 0 ]
-    then
-        root_password=$(eval echo "${root_password}")
-    fi
-
-    # If it has more than 3 consequtive X's in it, feed it
-    # through mktemp as a template.
-    if [ $(expr "${root_password}" : '.*XXXX') != 0 ]
-    then
-        root_password=$(mktemp -u ${root_password})
-    fi
-fi
-
 if [ -z "${utsname}" ]; then
     utsname=${name}
 fi
@@ -1317,11 +1252,11 @@ if [ "$(id -u)" != "0" ]; then
 fi
 
 
-if [ -z "$rootfs_path" ]; then
-    rootfs_path=$path/rootfs
+if [ -z "${rootfs}" ]; then
+    rootfs=$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=$(sed -e '/^lxc.rootfs\s*=/!d' -e 's/\s*#.*//' \
+        rootfs=$(sed -e '/^lxc.rootfs\s*=/!d' -e 's/\s*#.*//' \
             -e 's/^lxc.rootfs\s*=\s*//' -e q $path/config)
     fi
 fi
@@ -1359,7 +1294,7 @@ if [ $? -ne 0 ]; then
 fi
 
 # If the systemd configuration directory exists - set it up for what we need.
-if [ -d ${rootfs_path}/etc/systemd/system ]
+if [ -d ${rootfs}/etc/systemd/system ]
 then
     configure_fedora_systemd
 fi
@@ -1367,7 +1302,7 @@ fi
 # This configuration (rc.sysinit) is not inconsistent with the systemd stuff
 # above and may actually coexist on some upgraded systems.  Let's just make
 # sure that, if it exists, we update this file, even if it's not used...
-if [ -f ${rootfs_path}/etc/rc.sysinit ]
+if [ -f ${rootfs}/etc/rc.sysinit ]
 then
     configure_fedora_init
 fi
@@ -1376,6 +1311,7 @@ if [ ! -z $clean ]; then
     clean || exit 1
     exit 0
 fi
+
 echo "
 Container rootfs and config have been created.
 Edit the config file to check/enable networking setup.
@@ -1398,40 +1334,30 @@ and may be removed.
 "
 fi
 
-if [ ${root_display_password} = "yes" ]
-then
-    echo "The temporary password for root is: '$root_password'
-
-You may want to note that password down before starting the container.
-"
-fi
-
-if [ ${root_store_password} = "yes" ]
-then
-    echo "The temporary root password is stored in:
-
-        '${config_path}/tmp_root_pass'
-"
-fi
-
-if [ ${root_prompt_password} = "yes" ]
-then
-    echo "Invoking the passwd command in the container to set the root password.
-
-        chroot ${rootfs_path} passwd
-"
-    chroot ${rootfs_path} passwd
-else
-    if [ ${root_expire_password} = "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
+# Set up the superuser user.
+# Several of the LXC_ variables are environment variables set up
+# in the "functions" file but can be overriden byt the calling environment
+# or by the template or ignored in calling this function.
+lxc_setup_user \
+    "${name}" \
+    "${rootfs}" \
+    "${config_path}" \
+    "${LXC_DEFAULT_USER}" \
+    "${LXC_PASSWORD}" \
+    "${LXC_DISPLAY_PASSWORD}" \
+    "${LXC_STORE_PASSWORD}" \
+    "${LXC_EXPIRE_PASSWORD}"
+
+# Add a "fedora" user using the same template and config.
+# This is congruent with several other templates...
+lxc_setup_user \
+    "${name}" \
+    "${rootfs}" \
+    "${config_path}" \
+    "fedora" \
+    "${LXC_PASSWORD}" \
+    "${LXC_DISPLAY_PASSWORD}" \
+    "${LXC_STORE_PASSWORD}" \
+    "${LXC_EXPIRE_PASSWORD}"
+
+exit 0
diff --git a/templates/lxc-openmandriva.in b/templates/lxc-openmandriva.in
index 4fdaece..fb47957 100644
--- a/templates/lxc-openmandriva.in
+++ b/templates/lxc-openmandriva.in
@@ -230,6 +230,7 @@ copy_configuration()
     cat <<EOF >> $config_path/config
 lxc.utsname = $name
 lxc.autodev = 1
+lxc.kmsg = 0
 lxc.tty = 4
 lxc.pts = 1024
 lxc.mount = $config_path/fstab
diff --git a/templates/lxc-opensuse.in b/templates/lxc-opensuse.in
index c4dce5d..cc43aa0 100644
--- a/templates/lxc-opensuse.in
+++ b/templates/lxc-opensuse.in
@@ -26,6 +26,16 @@
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
+#Configurations
+default_path=@LXCPATH@
+template_path=@LXCTEMPLATEDIR@
+
+# Load up some common functions
+if [ -f ${template_path}/functions ]
+then
+    . ${template_path}/functions
+fi
+
 # Detect use under userns (unsupported)
 for arg in "$@"; do
     [ "$arg" = "--" ] && break
@@ -108,9 +118,6 @@ EOF
 
     touch $rootfs/etc/sysconfig/kernel
 
-    echo "Please change root-password !"
-    echo "root:root" | chpasswd -R $rootfs
-
     return 0
 }
 
@@ -265,7 +272,7 @@ copy_configuration()
     name=$3
 
     grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "
-lxc.rootfs = $rootfs_path
+lxc.rootfs = ${rootfs}
 " >> $path/config
 
     # The following code is to create static MAC addresses for each
@@ -313,10 +320,11 @@ lxc.include = @LXCTEMPLATECONFIG@/opensuse.common.conf
 lxc.arch = $arch
 lxc.utsname = $name
 
-lxc.mount = $path/fstab
+# Keep systemd and journald happy...
+lxc.autodev = 1
+lxc.kmsg = 0
 
-# When using LXC with apparmor, uncomment the next line to run unconfined:
-#lxc.aa_profile = unconfined
+lxc.mount = $path/fstab
 
 # example simple networking setup, uncomment to enable
 #lxc.network.type = $lxc_network_type
@@ -452,3 +460,31 @@ if [ ! -z $clean ]; then
     clean || exit 1
     exit 0
 fi
+
+# Set up the superuser user.
+# Several of the LXC_ variables are environment variables set up
+# in the "functions" file but can be overriden byt the calling environment
+# or by the template or ignored in calling this function.
+lxc_setup_user \
+    "${name}" \
+    "${rootfs}" \
+    "${config_path}" \
+    "${LXC_DEFAULT_USER}" \
+    "${LXC_PASSWORD}" \
+    "${LXC_DISPLAY_PASSWORD}" \
+    "${LXC_STORE_PASSWORD}" \
+    "${LXC_EXPIRE_PASSWORD}"
+
+# Add a "suse" user using the same template and config.
+# This is congruent with several other templates...
+lxc_setup_user \
+    "${name}" \
+    "${rootfs}" \
+    "${config_path}" \
+    "suse" \
+    "${LXC_PASSWORD}" \
+    "${LXC_DISPLAY_PASSWORD}" \
+    "${LXC_STORE_PASSWORD}" \
+    "${LXC_EXPIRE_PASSWORD}"
+
+exit 0
-- 
1.9.3



Regards,
Mike
-- 
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: 465 bytes
Desc: This is a digitally signed message part
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20140914/5c2c741f/attachment-0001.sig>


More information about the lxc-devel mailing list