From: Daniel Lezcano Date: Mon, 7 Jun 2010 09:33:55 +0000 (+0200) Subject: update the fedora template X-Git-Tag: lxc-0.7.0~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b6e91b67178aa06eeae82bb09bd5eee2869689de;p=thirdparty%2Flxc.git update the fedora template Update the fedora template in order to call it from the lxc-create script. Signed-off-by: Daniel Lezcano --- diff --git a/templates/lxc-fedora.in b/templates/lxc-fedora.in index 7d7a6c52e..f4f19c014 100644 --- a/templates/lxc-fedora.in +++ b/templates/lxc-fedora.in @@ -1,413 +1,334 @@ #!/bin/bash -# set -ex -DISTRO="fedora" -CACHE="@LOCALSTATEDIR@/cache/lxc/${DISTRO}" +# +# template script for generating fedora container for LXC +# -# Default container name -NAME="fedora" -CONFFILE="lxc.conf" -UTSNAME= -IPV4="172.20.0.21" -GATEWAY="172.20.0.1" -MTU="1500" +# +# lxc: linux Container library -# These paths are within the container so do not need to obey configure prefixes -INITTAB="/etc/inittab" -FSTAB="/etc/fstab" -SSHD_CONFIG="/etc/ssh/sshd_config" +# Authors: +# Daniel Lezcano -################################################################################ -# DISTRO custom configuration files -################################################################################ +# 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. -# custom selinux +# 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. -write_distro_selinux() { - mkdir -p ${ROOTFS}/selinux - echo 0 > ${ROOTFS}/selinux/enforce -} +# 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 -# custom fstab +DISTRO=fedora-10 -write_distro_fstab() { -cat < ${ROOTFS}/${FSTAB} -tmpfs /dev/shm tmpfs defaults 0 0 -EOF -} +configure_fedora() +{ + rootfs=$1 + hostname=$2 + + # disable selinux in fedora + mkdir -p $rootfs/selinux + echo 0 > $rootfs/selinux/enforce -# custom inittab - -write_distro_inittab() { -cat < ${ROOTFS}/${INITTAB} -id:3:initdefault: -si::sysinit:/etc/init.d/rcS -l0:0:wait:/etc/init.d/rc 0 -l1:1:wait:/etc/init.d/rc 1 -l2:2:wait:/etc/init.d/rc 2 -l3:3:wait:/etc/init.d/rc 3 -l4:4:wait:/etc/init.d/rc 4 -l5:5:wait:/etc/init.d/rc 5 -l6:6:wait:/etc/init.d/rc 6 -# Normally not reached, but fallthrough in case of emergency. -z6:6:respawn:/sbin/sulogin -1:2345:respawn:/sbin/getty 38400 console -c1:12345:respawn:/sbin/getty 38400 tty1 linux -c2:12345:respawn:/sbin/getty 38400 tty2 linux -c3:12345:respawn:/sbin/getty 38400 tty3 linux -c4:12345:respawn:/sbin/getty 38400 tty4 linux + # configure the network using the dhcp + cat < $rootfs/etc/network/interfaces +auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet dhcp EOF -} -# custom network configuration -write_distro_network() { -cat < ${ROOTFS}/etc/sysconfig/network-scripts/ifcfg-lo -DEVICE=lo -IPADDR=127.0.0.1 -NETMASK=255.0.0.0 -NETWORK=127.0.0.0 -# If you're having problems with gated making 127.0.0.0/8 a martian, -# you can change this to something else (255.255.255.255, for example) -BROADCAST=127.255.255.255 -ONBOOT=yes -NAME=loopback + # set the hostname + cat < $rootfs/etc/hostname +$hostname EOF -cat < ${ROOTFS}/etc/sysconfig/network-scripts/ifcfg-eth0 -DEVICE=eth0 -BOOTPROTO=static -HWADDR=52:54:00:12:34:56 -ONBOOT=yes -HOSTNAME=${UTSNAME} -NM_CONTROLLED=no -TYPE=Ethernet -IPADDR=${IPV4} -NETWORK=$(ipcalc -sn ${IPV4} 255.255.255.0) -GATEWAY=${GATEWAY} -BROADCAST=$(ipcalc -sb ${IPV4} 255.255.255.0) -NETMASK=255.255.255.0 -MTU=${MTU} + # set minimal hosts + cat < $rootfs/etc/hosts +127.0.0.1 localhost $hostname EOF -} -# custom hostname + # provide the lxc service + cat < $rootfs/etc/init/lxc.conf +# fake some events needed for correct startup other services -write_distro_hostname() { -cat < ${ROOTFS}/etc/sysconfig/network -NETWORKING=yes -HOSTNAME=${UTSNAME} -EOF -} - -# custom sshd configuration file - -write_distro_sshd_config() { -cat < ${ROOTFS}/${SSHD_CONFIG} -Port 22 -Protocol 2 -HostKey /etc/ssh/ssh_host_rsa_key -HostKey /etc/ssh/ssh_host_dsa_key -UsePrivilegeSeparation yes -KeyRegenerationInterval 3600 -ServerKeyBits 768 -SyslogFacility AUTH -LogLevel INFO -LoginGraceTime 120 -PermitRootLogin yes -StrictModes yes -RSAAuthentication yes -PubkeyAuthentication yes -IgnoreRhosts yes -RhostsRSAAuthentication no -HostbasedAuthentication no -PermitEmptyPasswords yes -ChallengeResponseAuthentication no -EOF -} +description "Container Upstart" -################################################################################ -# lxc configuration files -################################################################################ +start on startup -write_lxc_configuration() { -cat < ${CONFFILE} -lxc.utsname = ${UTSNAME} -lxc.tty = 4 -lxc.network.type = veth -lxc.network.flags = up -lxc.network.link = br0 -lxc.network.name = eth0 -lxc.network.mtu = ${MTU} -lxc.rootfs = ${ROOTFS} -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 -lxc.cgroup.devices.allow = c 4:0 rwm -lxc.cgroup.devices.allow = c 4:1 rwm -# /dev/{,u}random -lxc.cgroup.devices.allow = c 1:9 rwm -lxc.cgroup.devices.allow = c 1:8 rwm -# /dev/pts/* - pts namespaces are "coming soon" -lxc.cgroup.devices.allow = c 136:* rwm -lxc.cgroup.devices.allow = c 5:2 rwm -# rtc -lxc.cgroup.devices.allow = c 254:0 rwm +script + rm -rf /var/run/*.pid + rm -rf /var/run/network/* + /sbin/initctl emit stopped JOB=udevtrigger --no-wait + /sbin/initctl emit started JOB=udev --no-wait +end script EOF -} -create() { + cat < $rootfs/etc/init/console.conf +# console - getty +# +# This service maintains a console on tty1 from the point the system is +# started until it is shut down again. - # choose a container name, default is already in shell NAME variable - echo -n "What is the name for the container ? [${NAME}] " - read _NAME_ +start on stopped rc RUNLEVEL=[2345] +stop on runlevel [!2345] - if [ ! -z "${_NAME_}" ]; then - NAME=${_NAME_} - fi +respawn +exec /sbin/getty -8 38400 /dev/console +EOF - # choose a hostname, default is the container name - echo -n "What hostname do you wish for this container ? [${NAME}] " - read _UTSNAME_ + cat < $rootfs/lib/init/fstab +# /lib/init/fstab: lxc system fstab +none /spu spufs gid=spu,optional 0 0 +none /tmp none defaults 0 0 +none /var/lock tmpfs nodev,noexec,nosuid,showthrough 0 0 +none /lib/init/rw tmpfs mode=0755,nosuid,optional 0 0 +EOF - if [ ! -z "${_UTSNAME_}" ]; then - UTSNAME=${_UTSNAME_} + # reconfigure some services + if [ -z "$LANG" ]; then + chroot $rootfs locale-gen en_US.UTF-8 + chroot $rootfs update-locale LANG=en_US.UTF-8 else - UTSNAME=${NAME} + chroot $rootfs locale-gen $LANG + chroot $rootfs update-locale LANG=$LANG fi - # choose an ipv4 address, better to choose the same network than - # your host - echo -n "What IP address do you wish for this container ? [${IPV4}] " - read _IPV4_ + # remove pointless services in a container + chroot $rootfs /usr/sbin/update-rc.d -f ondemand remove - if [ ! -z "${_IPV4_}" ]; then - IPV4=${_IPV4_} - fi + chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls u*.conf); do mv $f $f.orig; done' + chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls tty[2-9].conf); do mv $f $f.orig; done' + chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls plymouth*.conf); do mv $f $f.orig; done' + chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls hwclock*.conf); do mv $f $f.orig; done' + chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls module*.conf); do mv $f $f.orig; done' - # choose the gateway ip address - echo -n "What is the gateway IP address ? [${GATEWAY}] " - read _GATEWAY_ + echo "Please change root-password !" + echo "root:root" | chroot $rootfs chpasswd - if [ ! -z "${_GATEWAY_}" ]; then - GATEWAY=${_GATEWAY_} - fi + return 0 +} - # choose the MTU size - echo -n "What is the MTU size ? [$MTU] " - read _MTU_ +download_fedora() +{ + cache=$1 + arch=$2 - if [ ! -z "$_MTU_" ]; then - MTU=$_MTU_ + # check the mini fedora was not already downloaded + mkdir -p "$cache/partial-$arch" + if [ $? -ne 0 ]; then + echo "Failed to create '$cache/partial-$arch' directory" + return 1 fi - # the rootfs name will be build with the container name - ROOTFS="./rootfs.${NAME}" - - # check if the rootfs does already exist - if [ ! -e "${ROOTFS}" ]; then - mkdir -p @LOCALSTATEDIR@/lock/subsys/ - ( - flock -n -x 200 - - - RES=$? - if [ "${RES}" != "0" ]; then - echo "Cache repository is busy." - break - fi - - # check the mini distro was not already downloaded - echo -n "Checking cache download ..." - if [ ! -e "${CACHE}/rootfs" ]; then - - echo "not cached" - - # Rather than write a special yum config we just make the - # default RPM and yum layout in ${CACHE}. The alternative is - # to copy /etc/yum/yum.conf or /etc/yum.conf and fiddle with - # some settings. - mkdir -p "${CACHE}/partial/var/lib/rpm" - mkdir -p "${CACHE}/partial/var/log" - touch "${CACHE}/partial/var/log/yum.log" - - RELEASE="$(yum info ${DISTRO}-release | \ - awk -F '[[:space:]]*:[[:space:]]*' \ - '/^Release/ { release = $2 } - /^Version/ { version = $2 } - END { print version "-" release }')" - - PKG="${DISTRO}-release-${RELEASE}.noarch" - RPM="rpm --root ${CACHE}/partial" - - echo "Initializing RPM cache ..." - ${RPM} --initdb - echo "Downloading distribution release file ${PKG}" - yumdownloader --destdir="${CACHE}/partial" "${PKG}" - RESULT=$? - - if [ "${RESULT}" != "0" ]; then - echo "Enable to download the distribution release file" - exit 1 - fi - - ${RPM} --nodeps -ihv "${CACHE}/partial/${PKG}.rpm" - - echo "Downloading ${DISTRO} minimal ..." - yum --installroot="${CACHE}/partial" -y groupinstall Base - RESULT=$? - if [ "${RESULT}" != "0" ]; then - echo "Failed to download the rootfs, aborting." - exit 1 - fi - mv "${CACHE}/partial" "${CACHE}/rootfs" - echo "Download complete." - else - echo "Found." - fi - - # make a local copy of the mini - echo -n "Copying rootfs ..." - cp -a ${CACHE}/rootfs ${ROOTFS} && echo "Done." || exit - ) 200> "@LOCALSTATEDIR@/lock/subsys/lxc" + # download a mini fedora into a cache + echo "Downloading fedora minimal ..." + febootstrap $DISTRO $cache/partial-$arch + if [ $? -ne 0 ]; then + echo "Failed to download the rootfs, aborting." + return 1 fi -write_lxc_configuration - -write_distro_inittab + mv "$1/partial-$arch" "$1/rootfs-$arch" + echo "Download complete." -write_distro_hostname - -write_distro_fstab - -write_distro_network - -write_distro_sshd_config - -write_distro_selinux - -@BINDIR@/lxc-create -n ${NAME} -f ${CONFFILE} -RES=$? + return 0 +} -# remove the configuration files -rm -f ${CONFFILE} +copy_fedora() +{ + cache=$1 + arch=$2 + rootfs=$3 -if [ "${RES}" != "0" ]; then - echo "Failed to create '${NAME}'" - exit 1 -fi - -echo "Done." -echo -e "\nYou can run your container with the 'lxc-start -n ${NAME}'\n" + # make a local copy of the minifedora + echo -n "Copying rootfs to $rootfs ..." + cp -a $cache/rootfs-$arch $rootfs || return 1 + return 0 } -destroy() { +install_fedora() +{ + cache="/var/cache/lxc/fedora" + rootfs=$1 + mkdir -p /var/lock/subsys/ + ( + flock -n -x 200 + if [ $? -ne 0 ]; then + echo "Cache repository is busy." + return 1 + fi - echo -n "What is the name for the container ? [${NAME}] " - read _NAME_ + arch=$(arch) - if [ ! -z "${_NAME_}" ]; then - NAME=${_NAME_} - fi + echo "Checking cache download in $cache/rootfs-$arch ... " + if [ ! -e "$cache/rootfs-$arch" ]; then + download_fedora $cache $arch + if [ $? -ne 0 ]; then + echo "Failed to download 'fedora base'" + return 1 + fi + fi - @BINDIR@/lxc-destroy -n ${NAME} - RETVAL=$? - if [ ! ${RETVAL} -eq 0 ]; then - echo "Failed to destroyed '${NAME}'" - return ${RETVAL} - fi + echo "Copy $cache/rootfs-$arch to $rootfs ... " + copy_fedora $cache $arch $rootfs + if [ $? -ne 0 ]; then + echo "Failed to copy rootfs" + return 1 + fi - ROOTFS="./rootfs.${NAME}" + return 0 - echo -n "Shall I remove the rootfs [y/n] ? " - read - if [ "${REPLY}" = "y" ]; then - rm -rf ${ROOTFS} - fi + ) 200>/var/lock/subsys/lxc - return 0 + return $? } -help() { - cat <> $path/config +lxc.utsname = $name -The script will create the container configuration file following -the informations submitted interactively with 'lxc-${DISTRO} create' - -The first creation will download, with yum, a ${DISTRO} minimal -install and store it into a cache. - -The script will copy from the cache the root filesystem to the -current directory. +lxc.tty = 4 +lxc.pts = 1024 +lxc.rootfs = $rootfs +lxc.mount = $path/fstab -If there is a problem with the container, (bad configuration for -example), you can destroy the container with 'lxc-${DISTRO} destroy' -but without removing the rootfs and recreate it again with -'lxc-${DISTRO} create'. +lxc.console = /dev/console -If you want to create another ${DISTRO} container, call the 'lxc-${DISTRO} - create' again, specifying another name and new parameters. +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 +lxc.cgroup.devices.allow = c 4:0 rwm +lxc.cgroup.devices.allow = c 4:1 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 -At any time you can purge the ${DISTRO} cache download by calling -'lxc-${DISTRO} purge' + cat < $path/fstab +proc $rootfs/proc proc nodev,noexec,nosuid 0 0 +devpts $rootfs/dev/pts devpts defaults 0 0 +sysfs $rootfs/sys sysfs defaults 0 0 +EOF -Have fun :) + if [ $? -ne 0 ]; then + echo "Failed to add configuration" + return 1 + fi -EOF + return 0 } -purge() { +clean() +{ + cache="/var/cache/lxc/fedora" - if [ ! -e ${CACHE} ]; then + if [ ! -e $cache ]; then exit 0 fi # lock, so we won't purge while someone is creating a repository ( flock -n -x 200 - - RES=$? - if [ "${RES}" != "0" ]; then + if [ $? != 0 ]; then echo "Cache repository is busy." exit 1 fi echo -n "Purging the download cache..." - rm --preserve-root --one-file-system -rf ${CACHE} && echo "Done." || exit 1 + rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1 exit 0 - ) 200> "@LOCALSTATEDIR@/lock/subsys/lxc" + ) 200>/var/lock/subsys/lxc +} + +usage() +{ + cat < --clean +EOF + return 0 } -# Note: assuming uid==0 is root -- might break with userns?? +options=$(getopt -o hp:n:c -l help,path:,name:,clean -- "$@") +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;; + -n|--name) name=$2; shift 2;; + -c|--clean) clean=$2; shift 2;; + --) shift 1; break ;; + *) break ;; + esac +done + +if [ ! -z "$clean" -a -z "$path" ]; then + clean || exit 1 + exit 0 +fi + +type febootstrap +if [ $? -ne 0 ]; then + echo "'febootstrap' command is missing" + exit 1 +fi + +if [ -z "$path" ]; then + echo "'path' parameter is required" + exit 1 +fi + if [ "$(id -u)" != "0" ]; then - echo "This script should be run as 'root'" - exit 1 + echo "This script should be run as 'root'" + exit 1 +fi + +rootfs=$path/rootfs + +install_fedora $rootfs +if [ $? -ne 0 ]; then + echo "failed to install fedora" + exit 1 fi -# Detect which executable we were run as, lxc-fedora or lxc-redhat -case "$0" in - *lxc-redhat) - DISTRO="redhat";; - *) # default is fedora - DISTRO="fedora";; -esac -CACHE="@LOCALSTATEDIR@/cache/lxc/${DISTRO}" - -case "$1" in - create) - create;; - destroy) - destroy;; - help) - help;; - purge) - purge;; - *) - echo "Usage: $0 {create|destroy|purge|help}" - exit 1;; -esac +configure_fedora $rootfs $name +if [ $? -ne 0 ]; then + echo "failed to configure fedora for a container" + exit 1 +fi + +copy_configuration $path $rootfs $name +if [ $? -ne 0 ]; then + echo "failed write configuration file" + exit 1 +fi + +if [ ! -z $clean ]; then + clean || exit 1 + exit 0 +fi