[Devel] [PATCH] liblxc: add scripts/lxc-fedora.in (WAS: Re: [PATCH] liblxc: Update lxc-debian to use the lenny release)
Matt Helsley
matthltc at us.ibm.com
Tue Feb 10 00:28:27 PST 2009
On Mon, 2009-02-09 at 15:43 -0800, Dan Smith wrote:
> DL> It may be possible to use yum like debootstrap for an minbase
> DL> fedora install.
>
> Yep, something like the following should work:
>
> root=/path/to/tmproot
> mkdir -p $root/var/lib/rpm
> rpm --root $root --initdb
> rpm --root $root -Uvfh --nodeps http://fedora.osuosl.org/linux/releases/10/Fedora/i386/os/Packages/fedora-release-10-1.noarch.rpm
> yum --installroot=$root -y groupinstall Base
Looks familiar! ;) I was intrigued by this idea last weekend so I
started such a script. However I only tested it as far as creating a
semi-correct rootfs. With the exception of network configs most of the
configs are still written as for debian. For example I know the selinux
policy enforcement settings need to move, the inittab needs to be
replaced by the proper upstart configs, etc.
Of course it's based heavily on Daniel's excellent lxc-debian script.
Signed-off-by: Matt Helsley <matthltc at us.ibm.com>
---
configure.in | 1
scripts/Makefile.am | 1
scripts/lxc-fedora.in | 404 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 406 insertions(+)
Index: lxc/configure.in
===================================================================
--- lxc.orig/configure.in
+++ lxc/configure.in
@@ -90,6 +90,7 @@ AC_CONFIG_FILES([
scripts/Makefile
scripts/lxc-debian
+ scripts/lxc-fedora
scripts/lxc-sshd
src/Makefile
Index: lxc/scripts/Makefile.am
===================================================================
--- lxc.orig/scripts/Makefile.am
+++ lxc/scripts/Makefile.am
@@ -1,3 +1,4 @@
bin_SCRIPTS = \
lxc-debian \
+ lxc-fedora \
lxc-sshd
Index: lxc/scripts/lxc-fedora.in
===================================================================
--- /dev/null
+++ lxc/scripts/lxc-fedora.in
@@ -0,0 +1,404 @@
+#!/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"
+
+# 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
+EOF
+}
+
+# custom hostname
+
+write_distro_hostname() {
+cat <<EOF > ${ROOTFS}/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.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
+
+ # 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.noarch.rpm"
+ RPM="rpm --root \"${CACHE}/partial\""
+
+ echo "Initializing RPM cache ..."
+ ${RPM} --initdb
+ echo "Downloading ${DISTRO} Release ${RELEASE} description ..."
+ yumdownloader --destdir="${CACHE}/partial" "${DISTRO}-release.noarch.rpm" && \
+ ${RPM} --nodeps -ihv "${CACHE}/partial/${DISTRO}-release*.noarch.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
+
+ at 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
_______________________________________________
Containers mailing list
Containers at lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers
More information about the Devel
mailing list