Commit b6e91b67 by Daniel Lezcano Committed by Daniel Lezcano

update the fedora template

Update the fedora template in order to call it from the lxc-create script. Signed-off-by: 's avatarDaniel Lezcano <dlezcano@fr.ibm.com>
parent f1fa1a08
#!/bin/bash #!/bin/bash
# set -ex
DISTRO="fedora" #
CACHE="@LOCALSTATEDIR@/cache/lxc/${DISTRO}" # template script for generating fedora container for LXC
#
# Default container name #
NAME="fedora" # lxc: linux Container library
CONFFILE="lxc.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 # Authors:
INITTAB="/etc/inittab" # Daniel Lezcano <daniel.lezcano@free.fr>
FSTAB="/etc/fstab"
SSHD_CONFIG="/etc/ssh/sshd_config"
################################################################################ # This library is free software; you can redistribute it and/or
# DISTRO custom configuration files # 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() { # You should have received a copy of the GNU Lesser General Public
mkdir -p ${ROOTFS}/selinux # License along with this library; if not, write to the Free Software
echo 0 > ${ROOTFS}/selinux/enforce # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
}
# custom fstab
write_distro_fstab() { DISTRO=fedora-10
cat <<EOF > ${ROOTFS}/${FSTAB}
tmpfs /dev/shm tmpfs defaults 0 0
EOF
}
# custom inittab configure_fedora()
{
write_distro_inittab() { rootfs=$1
cat <<EOF > ${ROOTFS}/${INITTAB} hostname=$2
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 # disable selinux in fedora
write_distro_network() { mkdir -p $rootfs/selinux
cat <<EOF > ${ROOTFS}/etc/sysconfig/network-scripts/ifcfg-lo echo 0 > $rootfs/selinux/enforce
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 # configure the network using the dhcp
cat <<EOF > $rootfs/etc/network/interfaces
auto lo
iface lo inet loopback
write_distro_hostname() { auto eth0
cat <<EOF > ${ROOTFS}/etc/sysconfig/network iface eth0 inet dhcp
NETWORKING=yes
HOSTNAME=${UTSNAME}
EOF EOF
}
# custom sshd configuration file # set the hostname
cat <<EOF > $rootfs/etc/hostname
write_distro_sshd_config() { $hostname
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 EOF
} # set minimal hosts
cat <<EOF > $rootfs/etc/hosts
################################################################################ 127.0.0.1 localhost $hostname
# 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.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 EOF
}
create() { # provide the lxc service
cat <<EOF > $rootfs/etc/init/lxc.conf
# fake some events needed for correct startup other services
# choose a container name, default is already in shell NAME variable description "Container Upstart"
echo -n "What is the name for the container ? [${NAME}] "
read _NAME_
if [ ! -z "${_NAME_}" ]; then start on startup
NAME=${_NAME_}
fi
# choose a hostname, default is the container name script
echo -n "What hostname do you wish for this container ? [${NAME}] " rm -rf /var/run/*.pid
read _UTSNAME_ rm -rf /var/run/network/*
/sbin/initctl emit stopped JOB=udevtrigger --no-wait
/sbin/initctl emit started JOB=udev --no-wait
end script
EOF
if [ ! -z "${_UTSNAME_}" ]; then cat <<EOF > $rootfs/etc/init/console.conf
UTSNAME=${_UTSNAME_} # console - getty
else #
UTSNAME=${NAME} # This service maintains a console on tty1 from the point the system is
fi # started until it is shut down again.
# choose an ipv4 address, better to choose the same network than start on stopped rc RUNLEVEL=[2345]
# your host stop on runlevel [!2345]
echo -n "What IP address do you wish for this container ? [${IPV4}] "
read _IPV4_
if [ ! -z "${_IPV4_}" ]; then respawn
IPV4=${_IPV4_} exec /sbin/getty -8 38400 /dev/console
fi EOF
# choose the gateway ip address cat <<EOF > $rootfs/lib/init/fstab
echo -n "What is the gateway IP address ? [${GATEWAY}] " # /lib/init/fstab: lxc system fstab
read _GATEWAY_ 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 "${_GATEWAY_}" ]; then # reconfigure some services
GATEWAY=${_GATEWAY_} if [ -z "$LANG" ]; then
chroot $rootfs locale-gen en_US.UTF-8
chroot $rootfs update-locale LANG=en_US.UTF-8
else
chroot $rootfs locale-gen $LANG
chroot $rootfs update-locale LANG=$LANG
fi fi
# choose the MTU size # remove pointless services in a container
echo -n "What is the MTU size ? [$MTU] " chroot $rootfs /usr/sbin/update-rc.d -f ondemand remove
read _MTU_
if [ ! -z "$_MTU_" ]; then
MTU=$_MTU_
fi
# the rootfs name will be build with the container name chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls u*.conf); do mv $f $f.orig; done'
ROOTFS="./rootfs.${NAME}" 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'
# check if the rootfs does already exist echo "Please change root-password !"
if [ ! -e "${ROOTFS}" ]; then echo "root:root" | chroot $rootfs chpasswd
mkdir -p @LOCALSTATEDIR@/lock/subsys/
(
flock -n -x 200
return 0
}
RES=$? download_fedora()
if [ "${RES}" != "0" ]; then {
echo "Cache repository is busy." cache=$1
break arch=$2
fi
# check the mini distro was not already downloaded # check the mini fedora was not already downloaded
echo -n "Checking cache download ..." mkdir -p "$cache/partial-$arch"
if [ ! -e "${CACHE}/rootfs" ]; then if [ $? -ne 0 ]; then
echo "Failed to create '$cache/partial-$arch' directory"
echo "not cached" return 1
# 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 fi
${RPM} --nodeps -ihv "${CACHE}/partial/${PKG}.rpm" # download a mini fedora into a cache
echo "Downloading fedora minimal ..."
echo "Downloading ${DISTRO} minimal ..." febootstrap $DISTRO $cache/partial-$arch
yum --installroot="${CACHE}/partial" -y groupinstall Base if [ $? -ne 0 ]; then
RESULT=$?
if [ "${RESULT}" != "0" ]; then
echo "Failed to download the rootfs, aborting." echo "Failed to download the rootfs, aborting."
exit 1 return 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 fi
write_lxc_configuration mv "$1/partial-$arch" "$1/rootfs-$arch"
echo "Download complete."
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 return 0
rm -f ${CONFFILE} }
if [ "${RES}" != "0" ]; then copy_fedora()
echo "Failed to create '${NAME}'" {
exit 1 cache=$1
fi arch=$2
rootfs=$3
echo "Done." # make a local copy of the minifedora
echo -e "\nYou can run your container with the 'lxc-start -n ${NAME}'\n" 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}] " arch=$(arch)
read _NAME_
if [ ! -z "${_NAME_}" ]; then echo "Checking cache download in $cache/rootfs-$arch ... "
NAME=${_NAME_} 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 fi
ROOTFS="./rootfs.${NAME}" echo "Copy $cache/rootfs-$arch to $rootfs ... "
copy_fedora $cache $arch $rootfs
echo -n "Shall I remove the rootfs [y/n] ? " if [ $? -ne 0 ]; then
read echo "Failed to copy rootfs"
if [ "${REPLY}" = "y" ]; then return 1
rm -rf ${ROOTFS}
fi fi
return 0 return 0
}
help() { ) 200>/var/lock/subsys/lxc
cat <<EOF
This script is a helper to create ${DISTRO} system containers. return $?
}
The script will create the container configuration file following copy_configuration()
the informations submitted interactively with 'lxc-${DISTRO} create' {
path=$1
rootfs=$2
name=$3
The first creation will download, with yum, a ${DISTRO} minimal cat <<EOF >> $path/config
install and store it into a cache. lxc.utsname = $name
The script will copy from the cache the root filesystem to the lxc.tty = 4
current directory. lxc.pts = 1024
lxc.rootfs = $rootfs
lxc.mount = $path/fstab
If there is a problem with the container, (bad configuration for lxc.console = /dev/console
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} lxc.cgroup.devices.deny = a
create' again, specifying another name and new parameters. # /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 cat <<EOF > $path/fstab
'lxc-${DISTRO} purge' 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 exit 0
fi fi
# lock, so we won't purge while someone is creating a repository # lock, so we won't purge while someone is creating a repository
( (
flock -n -x 200 flock -n -x 200
if [ $? != 0 ]; then
RES=$?
if [ "${RES}" != "0" ]; then
echo "Cache repository is busy." echo "Cache repository is busy."
exit 1 exit 1
fi fi
echo -n "Purging the download cache..." 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 exit 0
) 200> "@LOCALSTATEDIR@/lock/subsys/lxc" ) 200>/var/lock/subsys/lxc
}
usage()
{
cat <<EOF
$1 -h|--help -p|--path=<path> --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 if [ "$(id -u)" != "0" ]; then
echo "This script should be run as 'root'" echo "This script should be run as 'root'"
exit 1 exit 1
fi fi
# Detect which executable we were run as, lxc-fedora or lxc-redhat rootfs=$path/rootfs
case "$0" in
*lxc-redhat) install_fedora $rootfs
DISTRO="redhat";; if [ $? -ne 0 ]; then
*) # default is fedora echo "failed to install fedora"
DISTRO="fedora";; exit 1
esac fi
CACHE="@LOCALSTATEDIR@/cache/lxc/${DISTRO}"
configure_fedora $rootfs $name
case "$1" in if [ $? -ne 0 ]; then
create) echo "failed to configure fedora for a container"
create;; exit 1
destroy) fi
destroy;;
help) copy_configuration $path $rootfs $name
help;; if [ $? -ne 0 ]; then
purge) echo "failed write configuration file"
purge;; exit 1
*) fi
echo "Usage: $0 {create|destroy|purge|help}"
exit 1;; if [ ! -z $clean ]; then
esac clean || exit 1
exit 0
fi
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment