lxc-centos.in revision b4f7af7a520b23c873e404562ec518a576e63d4c
6bdda696b3ea703c47e87fea61017ec655f91d92nd# template script for generating centos container for LXC
6bdda696b3ea703c47e87fea61017ec655f91d92nd# lxc: linux Container library
6bdda696b3ea703c47e87fea61017ec655f91d92nd# Daniel Lezcano <daniel.lezcano@free.fr>
6bdda696b3ea703c47e87fea61017ec655f91d92nd# Ramez Hanna <rhanna@informatiq.org>
6bdda696b3ea703c47e87fea61017ec655f91d92nd# Fajar A. Nugraha <github@fajar.net>
6bdda696b3ea703c47e87fea61017ec655f91d92nd# Michael H. Warfield <mhw@WittsEnd.com>
6bdda696b3ea703c47e87fea61017ec655f91d92nd# This library is free software; you can redistribute it and/or
6bdda696b3ea703c47e87fea61017ec655f91d92nd# modify it under the terms of the GNU Lesser General Public
6bdda696b3ea703c47e87fea61017ec655f91d92nd# License as published by the Free Software Foundation; either
6bdda696b3ea703c47e87fea61017ec655f91d92nd# version 2.1 of the License, or (at your option) any later version.
6bdda696b3ea703c47e87fea61017ec655f91d92nd# This library is distributed in the hope that it will be useful,
16b55a35cff91315d261d1baa776138af465c4e4fuankg# but WITHOUT ANY WARRANTY; without even the implied warranty of
16b55a35cff91315d261d1baa776138af465c4e4fuankg # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16b55a35cff91315d261d1baa776138af465c4e4fuankg# Lesser General Public License for more details.
6bdda696b3ea703c47e87fea61017ec655f91d92nd# You should have received a copy of the GNU Lesser General Public
6bdda696b3ea703c47e87fea61017ec655f91d92nd# License along with this library; if not, write to the Free Software
6bdda696b3ea703c47e87fea61017ec655f91d92nd# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
6bdda696b3ea703c47e87fea61017ec655f91d92nd#Configurations
6bdda696b3ea703c47e87fea61017ec655f91d92nd# Some combinations of the tunning knobs below do not exactly make sense.
6bdda696b3ea703c47e87fea61017ec655f91d92nd# but that's ok.
6bdda696b3ea703c47e87fea61017ec655f91d92nd# If the "root_password" is non-blank, use it, else set a default.
6bdda696b3ea703c47e87fea61017ec655f91d92nd# This can be passed to the script as an environment variable and is
6bdda696b3ea703c47e87fea61017ec655f91d92nd# set by a shell conditional assignment. Looks weird but it is what it is.
6bdda696b3ea703c47e87fea61017ec655f91d92nd# If the root password contains a ding ($) then try to expand it.
6bdda696b3ea703c47e87fea61017ec655f91d92nd# That will pick up things like ${name} and ${RANDOM}.
6bdda696b3ea703c47e87fea61017ec655f91d92nd# If the root password contians more than 3 consecutive X's, pass it as
6bdda696b3ea703c47e87fea61017ec655f91d92nd# a template to mktemp and take the result.
6bdda696b3ea703c47e87fea61017ec655f91d92nd# If root_display_password = yes, display the temporary root password at exit.
6bdda696b3ea703c47e87fea61017ec655f91d92nd# If root_store_password = yes, store it in the configuration directory
6bdda696b3ea703c47e87fea61017ec655f91d92nd# If root_prompt_password = yes, invoke "passwd" to force the user to change
6bdda696b3ea703c47e87fea61017ec655f91d92nd# the root password after the container is created.
6bdda696b3ea703c47e87fea61017ec655f91d92nd# These are conditional assignments... The can be overridden from the
6bdda696b3ea703c47e87fea61017ec655f91d92nd# preexisting environment variables...
6bdda696b3ea703c47e87fea61017ec655f91d92nd# Make sure this is in single quotes to defer expansion to later!
6bdda696b3ea703c47e87fea61017ec655f91d92nd# :{root_password='Root-${name}-${RANDOM}'}
6bdda696b3ea703c47e87fea61017ec655f91d92nd# Now, it doesn't make much sense to display, store, and force change
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg# together. But, we gotta test, right???
6bdda696b3ea703c47e87fea61017ec655f91d92nd# Prompting for something interactive has potential for mayhem
6bdda696b3ea703c47e87fea61017ec655f91d92nd# with users running under the API... Don't default to "yes"
6bdda696b3ea703c47e87fea61017ec655f91d92nd# These are only going into comments in the resulting config...
6bdda696b3ea703c47e87fea61017ec655f91d92nd# is this centos?
6bdda696b3ea703c47e87fea61017ec655f91d92nd# Alow for weird remixes like the Raspberry Pi
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg# Use the Mitre standard CPE identifier for the release ID if possible...
6bdda696b3ea703c47e87fea61017ec655f91d92nd# This may be in /etc/os-release or /etc/system-release-cpe. We
6bdda696b3ea703c47e87fea61017ec655f91d92nd# should be able to use EITHER. Give preference to /etc/os-release for now.
6bdda696b3ea703c47e87fea61017ec655f91d92nd# This is a shell friendly configuration file. We can just source it.
6bdda696b3ea703c47e87fea61017ec655f91d92nd# What we're looking for in here is the ID, VERSION_ID and the CPE_NAME
6bdda696b3ea703c47e87fea61017ec655f91d92nd echo "Host CPE ID from /etc/os-release: ${CPE_NAME}"
6bdda696b3ea703c47e87fea61017ec655f91d92nd # Probably a better way to do this but sill remain posix
6bdda696b3ea703c47e87fea61017ec655f91d92nd # compatible but this works, shrug...
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg # Must be nice and not introduce convenient bashisms here.
6bdda696b3ea703c47e87fea61017ec655f91d92nd # According to the official registration at Mitre and NIST,
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg # this should have been something like this for CentOS:
6bdda696b3ea703c47e87fea61017ec655f91d92nd # cpe:/o:centos:centos:6
6bdda696b3ea703c47e87fea61017ec655f91d92nd # or this:
6bdda696b3ea703c47e87fea61017ec655f91d92nd # cpe:/o:centos:centos:6.5
6bdda696b3ea703c47e87fea61017ec655f91d92nd # The "enterprise_linux" is a bone toss back to RHEL.
6bdda696b3ea703c47e87fea61017ec655f91d92nd # Since CentOS and RHEL are so tightly coupled, we'll
6bdda696b3ea703c47e87fea61017ec655f91d92nd # take the RHEL version if we're running on it and do the
6bdda696b3ea703c47e87fea61017ec655f91d92nd # equivalent version for CentOS.
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg # Instead we got this: cpe:/o:centos:linux:6
6bdda696b3ea703c47e87fea61017ec655f91d92nd VERSION_ID=$(expr ${CPE_NAME} : '[^:]*:[^:]*:[^:]*:[^:]*:\([^:]*\)')
6bdda696b3ea703c47e87fea61017ec655f91d92nd echo "Host CPE ID from /etc/system-release-cpe: ${CPE_NAME}"
6bdda696b3ea703c47e87fea61017ec655f91d92ndif [ "${CPE_NAME}" != "" -a "${ID}" = "centos" -a "${VERSION_ID}" != "" ]
6bdda696b3ea703c47e87fea61017ec655f91d92ndelif [ "${CPE_NAME}" != "" -a "${ID}" = "redhat" -a "${VERSION_ID}" != "" ]
6bdda696b3ea703c47e87fea61017ec655f91d92nd # Only if all other methods fail, try to parse the redhat-release file.
6bdda696b3ea703c47e87fea61017ec655f91d92nd centos_host_ver=$( sed -e '/^CentOS /!d' -e 's/CentOS.*\srelease\s*\([0-9][0-9.]*\)\s.*/\1/' < /etc/centos-release )
6bdda696b3ea703c47e87fea61017ec655f91d92nd# Map a few architectures to their generic Centos repository archs.
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg# CentOS currently doesn't support ARM but it's copied here from
6bdda696b3ea703c47e87fea61017ec655f91d92nd# the Fedora template for completeness and that it will in the future.
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg# The two ARM archs are a bit of a guesstimate for the v5 and v6
6bdda696b3ea703c47e87fea61017ec655f91d92nd# archs. V6 should have hardware floating point (Rasberry Pi).
6bdda696b3ea703c47e87fea61017ec655f91d92nd# The "arm" arch is safer (no hardware floating point). So
6bdda696b3ea703c47e87fea61017ec655f91d92nd# there may be cases where we "get it wrong" for some v6 other
6bdda696b3ea703c47e87fea61017ec655f91d92nd rm -f $2 && mknod -m $1 $2 $3 $4 $5
6bdda696b3ea703c47e87fea61017ec655f91d92nd # Also kill it in the /etc/selinux/config file if it's there...
6bdda696b3ea703c47e87fea61017ec655f91d92nd sed -i '/^SELINUX=/s/.*/SELINUX=disabled/' $rootfs_path/etc/selinux/config
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg if [ -f $rootfs_path/usr/sbin/selinuxenabled ]; then
6bdda696b3ea703c47e87fea61017ec655f91d92nd mv $rootfs_path/usr/sbin/selinuxenabled $rootfs_path/usr/sbin/selinuxenabled.lxcorig
6bdda696b3ea703c47e87fea61017ec655f91d92nd # This is a known problem and documented in RedHat bugzilla as relating
6bdda696b3ea703c47e87fea61017ec655f91d92nd # to a problem with auditing enabled. This prevents an error in
6bdda696b3ea703c47e87fea61017ec655f91d92nd # the container "Cannot make/remove an entry for the specified session"
6bdda696b3ea703c47e87fea61017ec655f91d92nd sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/login
6bdda696b3ea703c47e87fea61017ec655f91d92nd sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/sshd
6bdda696b3ea703c47e87fea61017ec655f91d92nd if [ -f ${rootfs_path}/etc/pam.d/crond ]
6bdda696b3ea703c47e87fea61017ec655f91d92nd sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/crond
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg # In addition to disabling pam_loginuid in the above config files
6bdda696b3ea703c47e87fea61017ec655f91d92nd # we'll also disable it by linking it to pam_permit to catch any
6bdda696b3ea703c47e87fea61017ec655f91d92nd # we missed or any that get installed after the container is built.
6bdda696b3ea703c47e87fea61017ec655f91d92nd # Deal with some dain bramage in the /etc/init.d/halt script.
6bdda696b3ea703c47e87fea61017ec655f91d92nd # Trim it and make it our own and link it in before the default
6bdda696b3ea703c47e87fea61017ec655f91d92nd # halt script so we can intercept it. This also preventions package
6bdda696b3ea703c47e87fea61017ec655f91d92nd # updates from interferring with our interferring with it.
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg # There's generally not much in the halt script that useful but what's
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg # in there from resetting the hardware clock down is generally very bad.
6bdda696b3ea703c47e87fea61017ec655f91d92nd # So we just eliminate the whole bottom half of that script in making
6bdda696b3ea703c47e87fea61017ec655f91d92nd # ourselves a copy. That way a major update to the init scripts won't
6bdda696b3ea703c47e87fea61017ec655f91d92nd if [ -f ${rootfs_path}/etc/init.d/halt ]
6bdda696b3ea703c47e87fea61017ec655f91d92nd cat <<EOF > ${rootfs_path}/etc/sysconfig/network-scripts/ifcfg-eth0
6bdda696b3ea703c47e87fea61017ec655f91d92ndDEVICE=eth0
6bdda696b3ea703c47e87fea61017ec655f91d92ndBOOTPROTO=dhcp
6bdda696b3ea703c47e87fea61017ec655f91d92ndHOSTNAME=${UTSNAME}
6bdda696b3ea703c47e87fea61017ec655f91d92ndNM_CONTROLLED=no
6bdda696b3ea703c47e87fea61017ec655f91d92ndTYPE=Ethernet
sed -i 's|si::sysinit:/etc/rc.d/rc.sysinit|si::bootwait:/etc/rc.d/lxc.sysinit|' $rootfs_path/etc/inittab
chmod 600 ${config_path}/tmp_root_pass
echo ${root_password} > ${config_path}/tmp_root_pass
if [ $? -ne 0 ]; then
PKG_LIST="yum initscripts passwd rsyslog vim-minimal openssh-server openssh-clients dhclient chkconfig rootfiles policycoreutils"
force_mknod 666 $INSTALL_ROOT/dev/null c 1 3
force_mknod 666 $INSTALL_ROOT/dev/urandom c 1 9
if [ $? -ne 0 ]; then
if [ ! -e $INSTALL_ROOT/var/lib/rpm/Packages -a -e $INSTALL_ROOT/$HOME/.rpmdb/Packages ]; then
mv $INSTALL_ROOT/$HOME/.rpmdb/[A-Z]* $INSTALL_ROOT/var/lib/rpm/
ret=$?
mknod -m 666 $INSTALL_ROOT/$INSTALL_ROOT/dev/null c 1 3
mknod -m 666 $INSTALL_ROOT/$INSTALL_ROOT/dev/urandom c 1 9
if [ $? -ne 0 ]; then
rm -f $REPO_FILE
rsync -a $cache/rootfs/ $rootfs_path/
if [ $? -ne 0 ]; then
flock -x 9
if [ $? -ne 0 ]; then
if [ $? -ne 0 ]; then
if [ $? -ne 0 ]; then
if [ $? -ne 0 ]; then
while read LINE
echo ${LINE} >> $config_path/config
done < $config_path/config.def
if [ $? -ne 0 ]; then
if [ ! -e $cache ]; then
flock -x 9
cat <<EOF
-p,--path path to where the container rootfs will be created, defaults to /var/lib/lxc. The container config will go under /var/lib/lxc in that case
-R,--release Centos release for the new container. if the host is Centos, then it will defaultto the host's release.
eval set -- "$options"
# utsname and hostname = Container_Name.Domain_Name
if [ -z "$path" ]; then
if [ -z "$release" ]; then
echo "This is not a CentOS or Redhat host and release is missing, defaulting to 6 use -R|--release to specify release"
if [ -z "$rootfs_path" ]; then
# check for 'lxc.rootfs' passed in through default config by lxc-create
if [ ! -z $clean ]; then
echo "The temporary password for root is: '$root_password'