mirror_lxc/scripts/lxc-fedora.in
Matty 4f3f0d4b01 lxc-fedora fixes
Howdy,

I was playing around with LXC containers this past weekend, and
noticed a couple of issues with the lxc-fedora script:

#1: Line 96 should be ${ROOTFS}/etc/sysconfig/network instead of
${ROOTFS}/sysconfig/network

#2 Line 249 contains a reference to $PKG, which isn't used in the
program. I adjusted the variable to point to the correct package, and
use this in the calls to yumdownloader:

    PKG="${DISTRO}-release.noarch.rpm"
                   .....
    yumdownloader --destdir="${CACHE}/partial" "${PKG}"

#3 The $CACHE/partial path is escaped unnecessarily:

   RPM="rpm --root \"${CACHE}/partial\""

#4 The program assumes yumdownloader will work, which isn't always the
case. I added an if statement to check the return code:


   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

#5 The package name passed to yumdownloader is incorrect:

   yumdownloader --destdir="${CACHE}/partial" "${DISTRO}-release.noarch.rpm"

   On Fedora 10 and 11, this evaluates to:

   fedora-release.noarch.rpm

   When we need it to evaluate to:

   fedora-{RELEASE_VER}.release.noarch

   This is fixed in the PKG variable listed above.

A patch that addresses these issues is attached.

Thanks,
- Ryan

Signed-off-by: Matty <matty91@gmail.com>
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
2009-06-24 13:13:18 +02:00

425 lines
9.5 KiB
Bash

#!/bin/bash
# set -ex
DISTRO="fedora"
CACHE="@LOCALSTATEDIR@/cache/lxc/${DISTRO}"
# Default container name
NAME="fedora"
CONFFILE="lxc.conf"
MNTFILE="mount.conf"
UTSNAME=
IPV4="172.20.0.21"
GATEWAY="172.20.0.1"
MTU="1500"
# 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"
################################################################################
# DISTRO custom configuration files
################################################################################
# custom selinux
write_distro_selinux() {
mkdir -p ${ROOTFS}/selinux
echo 0 > ${ROOTFS}/selinux/enforce
}
# custom fstab
write_distro_fstab() {
cat <<EOF > ${ROOTFS}/${FSTAB}
tmpfs /dev/shm tmpfs defaults 0 0
EOF
}
# custom inittab
write_distro_inittab() {
cat <<EOF > ${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
EOF
}
# custom network configuration
write_distro_network() {
cat <<EOF > ${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
EOF
cat <<EOF > ${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}
EOF
}
# custom hostname
write_distro_hostname() {
cat <<EOF > ${ROOTFS}/etc/sysconfig/network
NETWORKING=yes
HOSTNAME=${UTSNAME}
EOF
}
# custom sshd configuration file
write_distro_sshd_config() {
cat <<EOF > ${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
}
################################################################################
# lxc configuration files
################################################################################
write_lxc_configuration() {
cat <<EOF > ${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.mount = ${MNTFILE}
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
EOF
}
write_lxc_mounts() {
cat <<EOF > ${MNTFILE}
EOF
}
create() {
# choose a container name, default is already in shell NAME variable
echo -n "What is the name for the container ? [${NAME}] "
read _NAME_
if [ ! -z "${_NAME_}" ]; then
NAME=${_NAME_}
fi
# choose a hostname, default is the container name
echo -n "What hostname do you wish for this container ? [${NAME}] "
read _UTSNAME_
if [ ! -z "${_UTSNAME_}" ]; then
UTSNAME=${_UTSNAME_}
else
UTSNAME=${NAME}
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_
if [ ! -z "${_IPV4_}" ]; then
IPV4=${_IPV4_}
fi
# choose the gateway ip address
echo -n "What is the gateway IP address ? [${GATEWAY}] "
read _GATEWAY_
if [ ! -z "${_GATEWAY_}" ]; then
GATEWAY=${_GATEWAY_}
fi
# choose the MTU size
echo -n "What is the MTU size ? [$MTU] "
read _MTU_
if [ ! -z "$_MTU_" ]; then
MTU=$_MTU_
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"
fi
write_lxc_mounts
write_lxc_configuration
write_distro_inittab
write_distro_hostname
write_distro_fstab
write_distro_network
write_distro_sshd_config
write_distro_selinux
@BINDIR@/lxc-create -n ${NAME} -f ${CONFFILE}
RES=$?
# remove the configuration files
rm -f ${CONFFILE}
rm -f ${MNTFILE}
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"
}
destroy() {
echo -n "What is the name for the container ? [${NAME}] "
read _NAME_
if [ ! -z "${_NAME_}" ]; then
NAME=${_NAME_}
fi
@BINDIR@/lxc-destroy -n ${NAME}
RETVAL=$?
if [ ! ${RETVAL} -eq 0 ]; then
echo "Failed to destroyed '${NAME}'"
return ${RETVAL}
fi
ROOTFS="./rootfs.${NAME}"
echo -n "Shall I remove the rootfs [y/n] ? "
read
if [ "${REPLY}" = "y" ]; then
rm -rf ${ROOTFS}
fi
return 0
}
help() {
cat <<EOF
This script is a helper to create ${DISTRO} system containers.
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.
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'.
If you want to create another ${DISTRO} container, call the 'lxc-${DISTRO}
create' again, specifying another name and new parameters.
At any time you can purge the ${DISTRO} cache download by calling
'lxc-${DISTRO} purge'
Have fun :)
EOF
}
purge() {
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
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
exit 0
) 200> "@LOCALSTATEDIR@/lock/subsys/lxc"
}
# Note: assuming uid==0 is root -- might break with userns??
if [ "$(id -u)" != "0" ]; then
echo "This script should be run as 'root'"
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