lxc-centos.in revision b4f7af7a520b23c873e404562ec518a576e63d4c
6bdda696b3ea703c47e87fea61017ec655f91d92nd#!/bin/bash
6bdda696b3ea703c47e87fea61017ec655f91d92nd
6bdda696b3ea703c47e87fea61017ec655f91d92nd#
6bdda696b3ea703c47e87fea61017ec655f91d92nd# template script for generating centos container for LXC
6bdda696b3ea703c47e87fea61017ec655f91d92nd
6bdda696b3ea703c47e87fea61017ec655f91d92nd#
6bdda696b3ea703c47e87fea61017ec655f91d92nd# lxc: linux Container library
6bdda696b3ea703c47e87fea61017ec655f91d92nd
6bdda696b3ea703c47e87fea61017ec655f91d92nd# Authors:
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
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
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
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
6bdda696b3ea703c47e87fea61017ec655f91d92nd#Configurations
6bdda696b3ea703c47e87fea61017ec655f91d92ndarch=$(arch)
6bdda696b3ea703c47e87fea61017ec655f91d92ndcache_base=@LOCALSTATEDIR@/cache/lxc/centos/$arch
6bdda696b3ea703c47e87fea61017ec655f91d92nddefault_path=@LXCPATH@
6bdda696b3ea703c47e87fea61017ec655f91d92nd
6bdda696b3ea703c47e87fea61017ec655f91d92nd# Some combinations of the tunning knobs below do not exactly make sense.
6bdda696b3ea703c47e87fea61017ec655f91d92nd# but that's ok.
6bdda696b3ea703c47e87fea61017ec655f91d92nd#
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#
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#
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#
6bdda696b3ea703c47e87fea61017ec655f91d92nd# These are conditional assignments... The can be overridden from the
6bdda696b3ea703c47e87fea61017ec655f91d92nd# preexisting environment variables...
6bdda696b3ea703c47e87fea61017ec655f91d92nd#
6bdda696b3ea703c47e87fea61017ec655f91d92nd# Make sure this is in single quotes to defer expansion to later!
6bdda696b3ea703c47e87fea61017ec655f91d92nd# :{root_password='Root-${name}-${RANDOM}'}
6bdda696b3ea703c47e87fea61017ec655f91d92nd: ${root_password='Root-${name}-XXXXXX'}
6bdda696b3ea703c47e87fea61017ec655f91d92nd
6bdda696b3ea703c47e87fea61017ec655f91d92nd# Now, it doesn't make much sense to display, store, and force change
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg# together. But, we gotta test, right???
6bdda696b3ea703c47e87fea61017ec655f91d92nd: ${root_display_password='no'}
6bdda696b3ea703c47e87fea61017ec655f91d92nd: ${root_store_password='yes'}
6bdda696b3ea703c47e87fea61017ec655f91d92nd# Prompting for something interactive has potential for mayhem
6bdda696b3ea703c47e87fea61017ec655f91d92nd# with users running under the API... Don't default to "yes"
6bdda696b3ea703c47e87fea61017ec655f91d92nd: ${root_prompt_password='no'}
6bdda696b3ea703c47e87fea61017ec655f91d92nd
6bdda696b3ea703c47e87fea61017ec655f91d92nd# These are only going into comments in the resulting config...
6bdda696b3ea703c47e87fea61017ec655f91d92ndlxc_network_type=veth
6bdda696b3ea703c47e87fea61017ec655f91d92ndlxc_network_link=lxcbr0
6bdda696b3ea703c47e87fea61017ec655f91d92nd
6bdda696b3ea703c47e87fea61017ec655f91d92nd# is this centos?
6bdda696b3ea703c47e87fea61017ec655f91d92nd# Alow for weird remixes like the Raspberry Pi
6bdda696b3ea703c47e87fea61017ec655f91d92nd#
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
6bdda696b3ea703c47e87fea61017ec655f91d92ndif [ -e /etc/os-release ]
6bdda696b3ea703c47e87fea61017ec655f91d92ndthen
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 . /etc/os-release
6bdda696b3ea703c47e87fea61017ec655f91d92nd echo "Host CPE ID from /etc/os-release: ${CPE_NAME}"
6bdda696b3ea703c47e87fea61017ec655f91d92ndfi
6bdda696b3ea703c47e87fea61017ec655f91d92nd
6bdda696b3ea703c47e87fea61017ec655f91d92ndif [ "${CPE_NAME}" = "" -a -e /etc/system-release-cpe ]
6bdda696b3ea703c47e87fea61017ec655f91d92ndthen
6bdda696b3ea703c47e87fea61017ec655f91d92nd CPE_NAME=$(head -n1 /etc/system-release-cpe)
6bdda696b3ea703c47e87fea61017ec655f91d92nd CPE_URI=$(expr ${CPE_NAME} : '\([^:]*:[^:]*\)')
6bdda696b3ea703c47e87fea61017ec655f91d92nd if [ "${CPE_URI}" != "cpe:/o" ]
6bdda696b3ea703c47e87fea61017ec655f91d92nd then
6bdda696b3ea703c47e87fea61017ec655f91d92nd CPE_NAME=
6bdda696b3ea703c47e87fea61017ec655f91d92nd else
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 #
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 #
6bdda696b3ea703c47e87fea61017ec655f91d92nd ID=$(expr ${CPE_NAME} : '[^:]*:[^:]*:[^:]*:\([^:]*\)')
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.
6bdda696b3ea703c47e87fea61017ec655f91d92nd if [ ${ID} = "linux" -o ${ID} = "enterprise_linux" ]
6bdda696b3ea703c47e87fea61017ec655f91d92nd then
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg # Instead we got this: cpe:/o:centos:linux:6
6bdda696b3ea703c47e87fea61017ec655f91d92nd ID=$(expr ${CPE_NAME} : '[^:]*:[^:]*:\([^:]*\)')
6bdda696b3ea703c47e87fea61017ec655f91d92nd fi
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg
6bdda696b3ea703c47e87fea61017ec655f91d92nd VERSION_ID=$(expr ${CPE_NAME} : '[^:]*:[^:]*:[^:]*:[^:]*:\([^:]*\)')
6bdda696b3ea703c47e87fea61017ec655f91d92nd echo "Host CPE ID from /etc/system-release-cpe: ${CPE_NAME}"
6bdda696b3ea703c47e87fea61017ec655f91d92nd fi
6bdda696b3ea703c47e87fea61017ec655f91d92ndfi
6bdda696b3ea703c47e87fea61017ec655f91d92nd
6bdda696b3ea703c47e87fea61017ec655f91d92ndif [ "${CPE_NAME}" != "" -a "${ID}" = "centos" -a "${VERSION_ID}" != "" ]
6bdda696b3ea703c47e87fea61017ec655f91d92ndthen
6bdda696b3ea703c47e87fea61017ec655f91d92nd centos_host_ver=${VERSION_ID}
6bdda696b3ea703c47e87fea61017ec655f91d92nd is_centos=true
6bdda696b3ea703c47e87fea61017ec655f91d92ndelif [ "${CPE_NAME}" != "" -a "${ID}" = "redhat" -a "${VERSION_ID}" != "" ]
6bdda696b3ea703c47e87fea61017ec655f91d92ndthen
6bdda696b3ea703c47e87fea61017ec655f91d92nd redhat_host_ver=${VERSION_ID}
6bdda696b3ea703c47e87fea61017ec655f91d92nd is_redhat=true
6bdda696b3ea703c47e87fea61017ec655f91d92ndelif [ -e /etc/centos-release ]
6bdda696b3ea703c47e87fea61017ec655f91d92ndthen
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 if [ "$centos_host_ver" != "" ]
6bdda696b3ea703c47e87fea61017ec655f91d92nd then
6bdda696b3ea703c47e87fea61017ec655f91d92nd is_centos=true
6bdda696b3ea703c47e87fea61017ec655f91d92nd fi
6bdda696b3ea703c47e87fea61017ec655f91d92ndfi
6bdda696b3ea703c47e87fea61017ec655f91d92nd
6bdda696b3ea703c47e87fea61017ec655f91d92nd# Map a few architectures to their generic Centos repository archs.
6bdda696b3ea703c47e87fea61017ec655f91d92nd#
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.
6bdda696b3ea703c47e87fea61017ec655f91d92nd#
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
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg# than RPi.
6bdda696b3ea703c47e87fea61017ec655f91d92ndcase "$arch" in
6bdda696b3ea703c47e87fea61017ec655f91d92ndi686) arch=i386 ;;
6bdda696b3ea703c47e87fea61017ec655f91d92ndarmv3l|armv4l|armv5l) arch=arm ;;
6bdda696b3ea703c47e87fea61017ec655f91d92ndarmv6l|armv7l|armv8l) arch=armhfp ;;
6bdda696b3ea703c47e87fea61017ec655f91d92ndesac
6bdda696b3ea703c47e87fea61017ec655f91d92nd
6bdda696b3ea703c47e87fea61017ec655f91d92ndforce_mknod()
6bdda696b3ea703c47e87fea61017ec655f91d92nd{
6bdda696b3ea703c47e87fea61017ec655f91d92nd # delete a device node if exists, and create a new one
6bdda696b3ea703c47e87fea61017ec655f91d92nd rm -f $2 && mknod -m $1 $2 $3 $4 $5
6bdda696b3ea703c47e87fea61017ec655f91d92nd}
6bdda696b3ea703c47e87fea61017ec655f91d92nd
6bdda696b3ea703c47e87fea61017ec655f91d92ndconfigure_centos()
6bdda696b3ea703c47e87fea61017ec655f91d92nd{
6bdda696b3ea703c47e87fea61017ec655f91d92nd
6bdda696b3ea703c47e87fea61017ec655f91d92nd # disable selinux in centos
6bdda696b3ea703c47e87fea61017ec655f91d92nd mkdir -p $rootfs_path/selinux
6bdda696b3ea703c47e87fea61017ec655f91d92nd echo 0 > $rootfs_path/selinux/enforce
6bdda696b3ea703c47e87fea61017ec655f91d92nd
6bdda696b3ea703c47e87fea61017ec655f91d92nd # Also kill it in the /etc/selinux/config file if it's there...
6bdda696b3ea703c47e87fea61017ec655f91d92nd if [ -f $rootfs_path/etc/selinux/config ]
6bdda696b3ea703c47e87fea61017ec655f91d92nd then
6bdda696b3ea703c47e87fea61017ec655f91d92nd sed -i '/^SELINUX=/s/.*/SELINUX=disabled/' $rootfs_path/etc/selinux/config
6bdda696b3ea703c47e87fea61017ec655f91d92nd fi
6bdda696b3ea703c47e87fea61017ec655f91d92nd
6bdda696b3ea703c47e87fea61017ec655f91d92nd # Nice catch from Dwight Engen in the Oracle template.
6bdda696b3ea703c47e87fea61017ec655f91d92nd # Wantonly plagerized here with much appreciation.
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg if [ -f $rootfs_path/usr/sbin/selinuxenabled ]; then
6bdda696b3ea703c47e87fea61017ec655f91d92nd mv $rootfs_path/usr/sbin/selinuxenabled $rootfs_path/usr/sbin/selinuxenabled.lxcorig
6bdda696b3ea703c47e87fea61017ec655f91d92nd ln -s /bin/false $rootfs_path/usr/sbin/selinuxenabled
6bdda696b3ea703c47e87fea61017ec655f91d92nd fi
6bdda696b3ea703c47e87fea61017ec655f91d92nd
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
6bdda696b3ea703c47e87fea61017ec655f91d92nd if [ -f ${rootfs_path}/etc/pam.d/crond ]
6bdda696b3ea703c47e87fea61017ec655f91d92nd then
6bdda696b3ea703c47e87fea61017ec655f91d92nd sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/crond
6bdda696b3ea703c47e87fea61017ec655f91d92nd fi
6bdda696b3ea703c47e87fea61017ec655f91d92nd
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 #
6bdda696b3ea703c47e87fea61017ec655f91d92nd # Catch either or both 32 and 64 bit archs.
6bdda696b3ea703c47e87fea61017ec655f91d92nd if [ -f ${rootfs_path}/lib/security/pam_loginuid.so ]
6bdda696b3ea703c47e87fea61017ec655f91d92nd then
6bdda696b3ea703c47e87fea61017ec655f91d92nd ( cd ${rootfs_path}/lib/security/
6bdda696b3ea703c47e87fea61017ec655f91d92nd mv pam_loginuid.so pam_loginuid.so.disabled
6bdda696b3ea703c47e87fea61017ec655f91d92nd ln -s pam_permit.so pam_loginuid.so
6bdda696b3ea703c47e87fea61017ec655f91d92nd )
6bdda696b3ea703c47e87fea61017ec655f91d92nd fi
6bdda696b3ea703c47e87fea61017ec655f91d92nd
6bdda696b3ea703c47e87fea61017ec655f91d92nd if [ -f ${rootfs_path}/lib64/security/pam_loginuid.so ]
6bdda696b3ea703c47e87fea61017ec655f91d92nd then
6bdda696b3ea703c47e87fea61017ec655f91d92nd ( cd ${rootfs_path}/lib64/security/
6bdda696b3ea703c47e87fea61017ec655f91d92nd mv pam_loginuid.so pam_loginuid.so.disabled
6bdda696b3ea703c47e87fea61017ec655f91d92nd ln -s pam_permit.so pam_loginuid.so
6bdda696b3ea703c47e87fea61017ec655f91d92nd )
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg fi
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg
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.
6bdda696b3ea703c47e87fea61017ec655f91d92nd #
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 # trash what we've set up.
6bdda696b3ea703c47e87fea61017ec655f91d92nd if [ -f ${rootfs_path}/etc/init.d/halt ]
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg then
6bdda696b3ea703c47e87fea61017ec655f91d92nd sed -e '/hwclock/,$d' \
6bdda696b3ea703c47e87fea61017ec655f91d92nd < ${rootfs_path}/etc/init.d/halt \
6bdda696b3ea703c47e87fea61017ec655f91d92nd > ${rootfs_path}/etc/init.d/lxc-halt
6bdda696b3ea703c47e87fea61017ec655f91d92nd
6bdda696b3ea703c47e87fea61017ec655f91d92nd echo '$command -f' >> ${rootfs_path}/etc/init.d/lxc-halt
6bdda696b3ea703c47e87fea61017ec655f91d92nd chmod 755 ${rootfs_path}/etc/init.d/lxc-halt
6bdda696b3ea703c47e87fea61017ec655f91d92nd
6bdda696b3ea703c47e87fea61017ec655f91d92nd # Link them into the rc directories...
6bdda696b3ea703c47e87fea61017ec655f91d92nd (
6bdda696b3ea703c47e87fea61017ec655f91d92nd cd ${rootfs_path}/etc/rc.d/rc0.d
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg ln -s ../init.d/lxc-halt S00lxc-halt
6bdda696b3ea703c47e87fea61017ec655f91d92nd cd ${rootfs_path}/etc/rc.d/rc6.d
6bdda696b3ea703c47e87fea61017ec655f91d92nd ln -s ../init.d/lxc-halt S00lxc-reboot
6bdda696b3ea703c47e87fea61017ec655f91d92nd )
6bdda696b3ea703c47e87fea61017ec655f91d92nd fi
6bdda696b3ea703c47e87fea61017ec655f91d92nd
6bdda696b3ea703c47e87fea61017ec655f91d92nd # configure the network using the dhcp
6bdda696b3ea703c47e87fea61017ec655f91d92nd cat <<EOF > ${rootfs_path}/etc/sysconfig/network-scripts/ifcfg-eth0
6bdda696b3ea703c47e87fea61017ec655f91d92ndDEVICE=eth0
6bdda696b3ea703c47e87fea61017ec655f91d92ndBOOTPROTO=dhcp
6bdda696b3ea703c47e87fea61017ec655f91d92ndONBOOT=yes
6bdda696b3ea703c47e87fea61017ec655f91d92ndHOSTNAME=${UTSNAME}
6bdda696b3ea703c47e87fea61017ec655f91d92ndNM_CONTROLLED=no
6bdda696b3ea703c47e87fea61017ec655f91d92ndTYPE=Ethernet
6bdda696b3ea703c47e87fea61017ec655f91d92ndMTU=${MTU}
6bdda696b3ea703c47e87fea61017ec655f91d92ndEOF
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg
# set the hostname
cat <<EOF > ${rootfs_path}/etc/sysconfig/network
NETWORKING=yes
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
EOF
# create lxc compatibility init script
if [ "$release" = "6" ]; then
cat <<EOF > $rootfs_path/etc/init/lxc-sysinit.conf
start on startup
env container
pre-start script
if [ "x$container" != "xlxc" -a "x$container" != "xlibvirt" ]; then
stop;
fi
initctl start tty TTY=console
rm -f /var/lock/subsys/*
rm -f /var/run/*.pid
telinit 3
exit 0;
end script
EOF
elif [ "$release" = "5" ]; then
cat <<EOF > $rootfs_path/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
sed -i 's|^1:|co:2345:respawn:/sbin/mingetty console\n1:|' $rootfs_path/etc/inittab
sed -i 's|^\([56]:\)|#\1|' $rootfs_path/etc/inittab
fi
dev_path="${rootfs_path}/dev"
rm -rf $dev_path
mkdir -p $dev_path
mknod -m 666 ${dev_path}/null c 1 3
mknod -m 666 ${dev_path}/zero c 1 5
mknod -m 666 ${dev_path}/random c 1 8
mknod -m 666 ${dev_path}/urandom c 1 9
mkdir -m 755 ${dev_path}/pts
mkdir -m 1777 ${dev_path}/shm
mknod -m 666 ${dev_path}/tty c 5 0
mknod -m 666 ${dev_path}/tty0 c 4 0
mknod -m 666 ${dev_path}/tty1 c 4 1
mknod -m 666 ${dev_path}/tty2 c 4 2
mknod -m 666 ${dev_path}/tty3 c 4 3
mknod -m 666 ${dev_path}/tty4 c 4 4
mknod -m 600 ${dev_path}/console c 5 1
mknod -m 666 ${dev_path}/full c 1 7
mknod -m 600 ${dev_path}/initctl p
mknod -m 666 ${dev_path}/ptmx c 5 2
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
# Also set this password as expired to force the user to change it!
chroot $rootfs_path passwd -e root
# 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
if [ "$release" = "6" ]; then
chroot ${rootfs_path} chkconfig udev-post off
fi
chroot ${rootfs_path} chkconfig network on
}
download_centos()
{
# check the mini centos was not already downloaded
INSTALL_ROOT=$cache/partial
mkdir -p $INSTALL_ROOT
if [ $? -ne 0 ]; then
echo "Failed to create '$INSTALL_ROOT' directory"
return 1
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"
# use temporary repository definition
REPO_FILE=$INSTALL_ROOT/etc/yum.repos.d/lxc-centos-temp.repo
mkdir -p $(dirname $REPO_FILE)
cat <<EOF > $REPO_FILE
[base]
name=CentOS-$release - Base
mirrorlist=http://mirrorlist.centos.org/?release=$release&arch=$arch&repo=os
[updates]
name=CentOS-$release - Updates
mirrorlist=http://mirrorlist.centos.org/?release=$release&arch=$arch&repo=updates
EOF
# 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
$YUM install $PKG_LIST
if [ $? -ne 0 ]; then
echo "Failed to download the rootfs, aborting."
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 ..."
mv $INSTALL_ROOT/$HOME/.rpmdb/[A-Z]* $INSTALL_ROOT/var/lib/rpm/
rm -rf $INSTALL_ROOT/$HOME/.rpmdb
chroot $INSTALL_ROOT rpm --rebuilddb 2>/dev/null
fi
# check whether rpmdb version is correct
chroot $INSTALL_ROOT rpm --quiet -q yum 2>/dev/null
ret=$?
# if "rpm -q" doesn't work due to rpmdb version difference,
# then we need to redo the process using the newly-installed yum
if [ $ret -gt 0 ]; then
echo "Reinstalling packages ..."
mv $REPO_FILE $REPO_FILE.tmp
mkdir $INSTALL_ROOT/etc/yum.repos.disabled
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/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."
return 1
fi
mv $INSTALL_ROOT/$INSTALL_ROOT $INSTALL_ROOT.tmp
rm -rf $INSTALL_ROOT
mv $INSTALL_ROOT.tmp $INSTALL_ROOT
fi
rm -f $REPO_FILE
rm -rf $INSTALL_ROOT/var/cache/yum/*
mv "$INSTALL_ROOT" "$cache/rootfs"
echo "Download complete."
return 0
}
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
# i prefer rsync (no reason really)
mkdir -p $rootfs_path
rsync -a $cache/rootfs/ $rootfs_path/
echo
return 0
}
update_centos()
{
YUM="chroot $cache/rootfs yum -y --nogpgcheck"
$YUM update
if [ $? -ne 0 ]; then
return 1
fi
$YUM clean packages
}
install_centos()
{
mkdir -p /var/lock/subsys/
(
flock -x 9
if [ $? -ne 0 ]; then
echo "Cache repository is busy."
return 1
fi
echo "Checking cache download in $cache/rootfs ... "
if [ ! -e "$cache/rootfs" ]; then
download_centos
if [ $? -ne 0 ]; then
echo "Failed to download 'centos base'"
return 1
fi
else
echo "Cache found. Updating..."
update_centos
if [ $? -ne 0 ]; then
echo "Failed to update 'centos base', continuing with last known good cache"
else
echo "Update finished"
fi
fi
echo "Copy $cache/rootfs to $rootfs_path ... "
copy_centos
if [ $? -ne 0 ]; then
echo "Failed to copy rootfs"
return 1
fi
return 0
) 9>/var/lock/subsys/lxc-centos
return $?
}
create_hwaddr()
{
echo $(dd if=/dev/urandom bs=8 count=1 2>/dev/null | md5sum |
sed -e 's/\(..\)\(..\)\(..\)\(..\)\(..\).*/fe:\1:\2:\3:\4:\5/')
}
copy_configuration()
{
mkdir -p $config_path
grep -q "^lxc.rootfs" $config_path/config 2>/dev/null || echo "
lxc.rootfs = $rootfs_path
" >> $config_path/config
# The following code is to create static MAC addresses for each
# interface in the container. This code will work for multiple
# interfaces in the default config.
mv $config_path/config $config_path/config.def
while read LINE
do
# This should catch variable expansions from the default config...
if expr "${LINE}" : '.*\$' > /dev/null 2>&1
then
LINE=$(eval "echo \"${LINE}\"")
fi
# There is a tab and a space in the regex bracket below!
# Seems that \s doesn't work in brackets.
KEY=$(expr "${LINE}" : '\s*\([^ ]*\)\s*=')
if [[ "${KEY}" != "lxc.network.hwaddr" ]]
then
echo ${LINE} >> $config_path/config
if [[ "${KEY}" == "lxc.network.link" ]]
then
echo "lxc.network.hwaddr = $(create_hwaddr)" >> $config_path/config
fi
fi
done < $config_path/config.def
rm -f $config_path/config.def
cat <<EOF >> $config_path/config
lxc.utsname = $utsname
lxc.tty = 4
lxc.pts = 1024
lxc.mount = $config_path/fstab
lxc.cap.drop = sys_module mac_admin mac_override sys_time
lxc.autodev = $auto_dev
# When using LXC with apparmor, uncomment the next line to run unconfined:
#lxc.aa_profile = unconfined
# example simple networking setup, uncomment to enable
#lxc.network.type = $lxc_network_type
#lxc.network.flags = up
#lxc.network.link = $lxc_network_link
#lxc.network.name = eth0
# Additional example for veth network type
# static MAC address,
#lxc.network.hwaddr = 00:16:3e:77:52:20
# persistent veth device name on host side
# Note: This may potentially collide with other containers of same name!
#lxc.network.veth.pair = v-$name-e0
#cgroups
lxc.cgroup.devices.deny = a
# /dev/null and zero
lxc.cgroup.devices.allow = c 1:3 rwm
lxc.cgroup.devices.allow = c 1:5 rwm
# consoles
lxc.cgroup.devices.allow = c 5:1 rwm
lxc.cgroup.devices.allow = c 5:0 rwm
# /dev/{,u}random
lxc.cgroup.devices.allow = c 1:9 rwm
lxc.cgroup.devices.allow = c 1:8 rwm
lxc.cgroup.devices.allow = c 136:* rwm
lxc.cgroup.devices.allow = c 5:2 rwm
# rtc
lxc.cgroup.devices.allow = c 254:0 rwm
EOF
cat <<EOF > $config_path/fstab
proc proc proc nodev,noexec,nosuid 0 0
sysfs sys sysfs defaults 0 0
EOF
if [ $? -ne 0 ]; then
echo "Failed to add configuration"
return 1
fi
return 0
}
clean()
{
if [ ! -e $cache ]; then
exit 0
fi
# lock, so we won't purge while someone is creating a repository
(
flock -x 9
if [ $? != 0 ]; then
echo "Cache repository is busy."
exit 1
fi
echo -n "Purging the download cache for centos-$release..."
rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1
exit 0
) 9>@LOCALSTATEDIR@/lock/subsys/lxc-centos
}
usage()
{
cat <<EOF
usage:
$1 -n|--name=<container_name>
[-p|--path=<path>] [-c|--clean] [-R|--release=<CentOS_release>] [-A|--arch=<arch of the container>]
[-h|--help]
Mandatory args:
-n,--name container name, used to as an identifier for that container from now on
Optional args:
-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
-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
-A,--arch NOT USED YET. Define what arch the container will be [i686,x86_64]
-h,--help print this help
EOF
return 0
}
options=$(getopt -o hp:n:cR: -l help,path:,rootfs:,name:,clean,release:,fqdn: -- "$@")
if [ $? -ne 0 ]; then
usage $(basename $0)
exit 1
fi
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;;
--fqdn) utsname=$2; shift 2;;
--) shift 1; break ;;
*) break ;;
esac
done
if [ ! -z "$clean" -a -z "$path" ]; then
clean || exit 1
exit 0
fi
# 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
# This follows a standard "resolver" convention that an FQDN must have
# at least two dots or it is considered a local relative host name.
# If it doesn't, append the dns domain name of the host system.
#
# This changes one significant behavior when running
# "lxc_create -n Container_Name" without using the
# --fqdn option.
#
# Old behavior:
# utsname and hostname = Container_Name
# New behavior:
# utsname and hostname = Container_Name.Domain_Name
if [ $(expr "$utsname" : '.*\..*\.') = 0 ]; then
if [[ "$(dnsdomainname)" != "" && "$(dnsdomainname)" != "localdomain" ]]; then
utsname=${utsname}.$(dnsdomainname)
fi
fi
type yum >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "'yum' command is missing"
exit 1
fi
if [ -z "$path" ]; then
path=$default_path/$name
fi
if [ -z "$release" ]; then
if [ "$is_centos" -a "$centos_host_ver" ]; then
release=$centos_host_ver
elif [ "$is_redhat" -a "$redhat_host_ver" ]; then
# This is needed to clean out bullshit like 6workstation and 6server.
release=$(expr $redhat_host_ver : '\([0-9.]*\)')
else
echo "This is not a CentOS or Redhat host and release is missing, defaulting to 6 use -R|--release to specify release"
release=6
fi
fi
# CentOS 7 and above should run systemd. We need autodev enabled to keep
# systemd from causing problems.
#
# There is some ambiguity here due to the differnce between versioning
# of point specific releases such as 6.5 and the rolling release 6. We
# only want the major number here if it's a point release...
mrelease=$(expr $release : '\([0-9]*\)')
if [ $mrelease -gt 6 ]; then
auto_dev="1"
else
auto_dev="0"
fi
if [ "$(id -u)" != "0" ]; then
echo "This script should be run as 'root'"
exit 1
fi
if [ -z "$rootfs_path" ]; then
rootfs_path=$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=`grep 'lxc.rootfs =' $path/config | awk -F= '{ print $2 }'`
fi
fi
config_path=$default_path/$name
cache=$cache_base/$release
revert()
{
echo "Interrupted, so cleaning up"
lxc-destroy -n $name
# maybe was interrupted before copy config
rm -rf $path
rm -rf $default_path/$name
echo "exiting..."
exit 1
}
trap revert SIGHUP SIGINT SIGTERM
copy_configuration
if [ $? -ne 0 ]; then
echo "failed write configuration file"
exit 1
fi
install_centos
if [ $? -ne 0 ]; then
echo "failed to install centos"
exit 1
fi
configure_centos
if [ $? -ne 0 ]; then
echo "failed to configure centos for a container"
exit 1
fi
configure_centos_init
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'
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
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