# Modified for Oracle Linux 5
# Wim Coekaerts <wim.coekaerts@oracle.com>
#
-# Modified for Oracle Linux 6, combined OL4,5,6 into one template script
+# Modified for Oracle Linux 6,7 combined OL4,5,6 into one template script
# Dwight Engen <dwight.engen@oracle.com>
#
# This library is free software; you can redistribute it and/or
# Make sure the usual locations are in PATH
export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
-# use virbr0 that is setup by default by libvirtd
-lxc_network_type=veth
-lxc_network_link=virbr0
-
die()
{
echo "failed: $1"
}
# fix up the container_rootfs
-container_rootfs_configure()
+container_rootfs_patch()
{
- echo "Configuring container for Oracle Linux $container_release_major.$container_release_minor"
+ echo "Patching container rootfs $container_rootfs for Oracle Linux $container_release_major.$container_release_minor"
+
+ # copy ourself into the container to be used to --patch the rootfs when
+ # yum update on certain packages is done. we do this here instead of in
+ # container_rootfs_configure() in case the patching done in this function
+ # is updated in the future, we can inject the updated version of ourself
+ # into older containers.
+ if [ $container_rootfs != "/" ]; then
+ cp -f `readlink -f $0` $container_rootfs/usr/bin/lxc-patch
+ if [ $container_release_major -lt "6" ]; then
+ mkdir -p $container_rootfs/usr/lib/yum-plugins
+ cp @DATADIR@/lxc/lxc-patch.py $container_rootfs/usr/lib/yum-plugins
+ fi
+ if [ $container_release_major -ge "6" ]; then
+ mkdir -p $container_rootfs/usr/share/yum-plugins
+ cp @DATADIR@/lxc/lxc-patch.py $container_rootfs/usr/share/yum-plugins
+ fi
+ mkdir -p $container_rootfs/etc/yum/pluginconf.d
+ cat <<EOF > $container_rootfs/etc/yum/pluginconf.d/lxc-patch.conf
+[main]
+enabled=1
+packages=dbus,initscripts,iptables,openssh-server,setup,selinux-policy,readahead,udev,util-linux,util-linux-ng
+EOF
+ fi
+
+ if [ $container_release_major = "4" ]; then
+ # yum plugin type of TYPE_INTERFACE works in all releases but gives a
+ # deprecation warning on major > 4, so we default to TYPE_INTERACTIVE
+ # and fix it up here
+ sed -i 's|TYPE_INTERACTIVE|TYPE_INTERFACE|' $container_rootfs/usr/lib/yum-plugins/lxc-patch.py
+ if [ -f $container_rootfs/etc/yum.repos.d/ULN-Base.repo ]; then
+ mv $container_rootfs/etc/yum.repos.d/ULN-Base.repo \
+ $container_rootfs/etc/yum.repos.d/ULN-Base.repo.lxc-disabled
+ fi
+ echo "plugins = 1" >>$container_rootfs/etc/yum.conf
+ fi
# "disable" selinux in the guest. The policy in the container isn't
# likely to match the hosts (unless host == guest exactly) and the
fi
sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*close|#session required pam_selinux.so close|' $container_rootfs/etc/pam.d/login
sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*open|#session required pam_selinux.so open|' $container_rootfs/etc/pam.d/login
+ sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*close|#session required pam_selinux.so close|' $container_rootfs/etc/pam.d/sshd
+ sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*open|#session required pam_selinux.so open|' $container_rootfs/etc/pam.d/sshd
# setting /proc/$$/loginuid doesn't work under user namespace, which
# prevents logins from working
ln -s /bin/false $container_rootfs/usr/sbin/selinuxenabled
fi
+ # ensure /dev/ptmx refers to the newinstance devpts of the container, or
+ # pty's will get crossed up with the hosts (https://lkml.org/lkml/2012/1/23/512)
+ rm -f $container_rootfs/dev/ptmx
+ ln -s pts/ptmx $container_rootfs/dev/ptmx
+
+ # OL7 has systemd, no rc.sysinit
+ if [ $container_release_major = "7" ]; then
+ # with newer systemd (OL7.2), getty service include container-getty.service
+ # let that be the one who manage the getty service instead
+ if [ ! -f $container_rootfs/usr/lib/systemd/system/container-getty@.service ]; then
+ # from mhw in the fedora template: We do need to disable the
+ # "ConditionalPathExists=/dev/tty0" line or no gettys are started on
+ # the ttys in the container. Lets do it in an override copy of the
+ # service so it can still pass rpm verifies and not be automatically
+ # updated by a new systemd version.
+ sed -e 's/^ConditionPathExists=/#LXC ConditionPathExists=/' \
+ < $container_rootfs/usr/lib/systemd/system/getty\@.service \
+ > $container_rootfs/etc/systemd/system/getty\@.service
+ # Setup getty service on the 4 ttys we are going to allow in the
+ # default config. Number should match lxc.tty
+ ( cd $container_rootfs/etc/systemd/system/getty.target.wants
+ for i in 1 2 3 4 ; do ln -sf ../getty\@.service getty@tty${i}.service; done )
+ # We only want to spawn a getty on /dev/console in lxc, libvirt-lxc
+ # symlinks /dev/console to /dev/tty1
+ sed -i '/Before=getty.target/a ConditionVirtualization=lxc' $container_rootfs/usr/lib/systemd/system/console-getty.service
+ fi
+
+ # disable some systemd services, set default boot, sigpwr target
+ rm -f $container_rootfs/usr/lib/systemd/system/sysinit.target.wants/kmod-static-nodes.service
+ chroot $container_rootfs systemctl -q disable graphical.target
+ chroot $container_rootfs systemctl -q enable multi-user.target
+
+ # systemd in userns won't be able to set /proc/self/oom_score_adj which
+ # prevents the dbus service from starting
+ sed -i 's|^OOMScoreAdjust|#LXC OOMScoreAdjust|' $container_rootfs/usr/lib/systemd/system/dbus.service
+ return
+ fi
+
# silence error in checking for selinux
sed -i 's|cat /proc/self/attr/current|cat /proc/self/attr/current 2>/dev/null|' $container_rootfs/etc/rc.sysinit
sed -i 's|cat /proc/self/attr/current|cat /proc/self/attr/current 2>/dev/null|' $container_rootfs/etc/rc.d/rc.sysinit
sed -i 's|session[ \t]*required[ \t]*/lib/security/\$ISA/pam_limits.so|#session required /lib/security/$ISA/pam_limits.so|' $container_rootfs/etc/pam.d/system-auth
fi
- # configure the network to use dhcp. we set DHCP_HOSTNAME so the guest
- # will report its name and be resolv'able by the hosts dnsmasq
- cat <<EOF > $container_rootfs/etc/sysconfig/network-scripts/ifcfg-eth0
-DEVICE=eth0
-BOOTPROTO=dhcp
-ONBOOT=yes
-HOSTNAME=$name
-DHCP_HOSTNAME=$name
-NM_CONTROLLED=no
-TYPE=Ethernet
-EOF
-
# avoid error in ol5 attempting to copy non-existent resolv.conf
if [ $container_release_major = "5" ]; then
sed -i 's|resolv.conf.predhclient|resolv.conf.predhclient 2>/dev/null|' $container_rootfs/sbin/dhclient-script
fi
- # set the hostname
- cat <<EOF > $container_rootfs/etc/sysconfig/network
-NETWORKING=yes
-NETWORKING_IPV6=no
-HOSTNAME=$name
-EOF
-
# disable interactive ovmd asking questions
if [ -f $container_rootfs/etc/sysconfig/ovmd ]; then
sed -i 's|INITIAL_CONFIG=yes|INITIAL_CONFIG=no|' $container_rootfs/etc/sysconfig/ovmd
fi
- # set minimal hosts
- echo "127.0.0.1 localhost $name" > $container_rootfs/etc/hosts
+ # disable disabling of ipv4 forwarding and defrag on shutdown since
+ # we mount /proc/sys ro
+ if [ $container_release_major = "5" ]; then
+ sed -i 's|-f /proc/sys/net/ipv4/ip_forward|-w /proc/sys/net/ipv4/ip_forward|' $container_rootfs/etc/rc.d/init.d/network
+ sed -i 's|-f /proc/sys/net/ipv4/ip_always_defrag|-w /proc/sys/net/ipv4/ip_always_defrag|' $container_rootfs/etc/rc.d/init.d/network
+ fi
# disable ipv6 on ol6
rm -f $container_rootfs/etc/sysconfig/network-scripts/init.ipv6-global
- # this file has to exist for libvirt/Virtual machine monitor to boot the container
- touch $container_rootfs/etc/mtab
-
- # don't put devpts,proc, nor sysfs in here, it will already be mounted for us by lxc/libvirt
- cat <<EOF > $container_rootfs/etc/fstab
-EOF
-
# remove module stuff for iptables it just shows errors that are not
# relevant in a container
if [ -f "$container_rootfs/etc/sysconfig/iptables-config" ]; then
sed -i 's|action $"Setting network parameters|# LXC action $"Setting network parameters|' $container_rootfs/etc/init.d/NetworkManager 2>/dev/null
fi
- # sem_open(3) checks that /dev/shm is SHMFS_SUPER_MAGIC, so make sure to mount /dev/shm (normally done by dracut initrd) as tmpfs
- if [ $container_release_major = "4" -o $container_release_major = "5" ]; then
- echo "mount -t tmpfs tmpfs /dev/shm" >>$container_rootfs/etc/rc.sysinit
- echo "mount -t tmpfs tmpfs /dev/shm" >>$container_rootfs/etc/rc.d/rc.sysinit
- fi
-
- if [ $container_release_major = "6" ]; then
- sed -i 's|mount -n -o remount /dev/shm >/dev/null 2>&1$|mount -t tmpfs tmpfs /dev/shm # LXC|' $container_rootfs/etc/rc.sysinit
- sed -i 's|mount -n -o remount /dev/shm >/dev/null 2>&1$|mount -t tmpfs tmpfs /dev/shm # LXC|' $container_rootfs/etc/rc.d/rc.sysinit
- fi
-
# no need to attempt to mount /
sed -i 's|mount -f /$|# LXC mount -f /|' $container_rootfs/etc/rc.sysinit
sed -i 's|mount -f /$|# LXC mount -f /|' $container_rootfs/etc/rc.d/rc.sysinit
sed -i 's|^/sbin/hwclock|# LXC /sbin/nohwclock|' $container_rootfs/etc/rc.d/rc.sysinit
# dont start lvm
- sed -i 's|action $"Setting up Logical Volume Management:"|#action $"Setting up Logical Volume Management:"|' $container_rootfs/etc/rc.sysinit
- sed -i 's|action $"Setting up Logical Volume Management:"|/bin/true #action $"Setting up Logical Volume Management:"|' $container_rootfs/etc/rc.d/rc.sysinit
+ if [ $container_release_major -lt "6" -a -f $container_rootfs/sbin/lvm.static ]; then
+ mv $container_rootfs/sbin/lvm.static $container_rootfs/sbin/lvm.static.lxc-disabled
+ fi
+ if [ $container_release_major = "6" ]; then
+ touch $container_rootfs/.nolvm
+ fi
# fix assumptions that plymouth is available
sed -i 's|\[ "$PROMPT" != no \] && plymouth|[ "$PROMPT" != no ] \&\& [ -n "$PLYMOUTH" ] \&\& plymouth|' $container_rootfs/etc/rc.sysinit
rm -f $container_rootfs/etc/init/quit-plymouth.conf
rm -f $container_rootfs/etc/init/splash-manager.conf
+ # dont try to unmount /dev/lxc devices
+ sed -i 's|&& $1 !~ /^\\/dev\\/ram/|\&\& $2 !~ /^\\/dev\\/lxc/ \&\& $1 !~ /^\\/dev\\/ram/|' $container_rootfs/etc/init.d/halt
+
+ # don't try to unmount swap
+ sed -i 's|\[ -f /proc/swaps \]|# LXC [ -f /proc/swaps ]|' $container_rootfs/etc/init.d/halt
+
+ # sem_open(3) checks that /dev/shm is SHMFS_SUPER_MAGIC, so make sure to
+ # mount /dev/shm (normally done by dracut initrd) as tmpfs
+ if [ $container_release_major = "4" -o $container_release_major = "5" ]; then
+ grep -q "mount -t tmpfs tmpfs /dev/shm" $container_rootfs/etc/rc.sysinit
+ if [ $? -eq 1 ]; then
+ echo "mkdir -p /dev/shm && mount -t tmpfs tmpfs /dev/shm" >>$container_rootfs/etc/rc.sysinit
+ echo "mkdir -p /dev/shm && mount -t tmpfs tmpfs /dev/shm" >>$container_rootfs/etc/rc.d/rc.sysinit
+ fi
+ fi
+ if [ $container_release_major = "6" ]; then
+ sed -i 's|mount -n -o remount /dev/shm >/dev/null 2>&1$|mkdir -p /dev/shm \&\& mount -t tmpfs tmpfs /dev/shm # LXC|' $container_rootfs/etc/rc.sysinit
+ sed -i 's|mount -n -o remount /dev/shm >/dev/null 2>&1$|mkdir -p /dev/shm \&\& mount -t tmpfs tmpfs /dev/shm # LXC|' $container_rootfs/etc/rc.d/rc.sysinit
+ fi
+
+ # there might be other services that are useless but the below set is a good start
+ # some of these might not exist in the image, so we silence chkconfig complaining
+ # about the service file not being found
+ for service in \
+ acpid apmd auditd autofs cpuspeed dund gpm haldaemon hidd \
+ ip6tables irqbalance iscsi iscsid isdn kdump kudzu \
+ lm_sensors lvm2-monitor mdmonitor microcode_ctl \
+ ntpd pcmcia postfix sendmail udev-post xfs ;
+ do
+ chroot $container_rootfs chkconfig 2>/dev/null $service off
+ done
+
+ for service in rsyslog ;
+ do
+ chroot $container_rootfs chkconfig 2>/dev/null $service on
+ done
+}
+
+container_rootfs_configure()
+{
+ container_rootfs_patch
+ echo "Configuring container for Oracle Linux $container_release_major.$container_release_minor"
+
+ # configure the network to use dhcp. we set DHCP_HOSTNAME so the guest
+ # will report its name and be resolv'able by the hosts dnsmasq
+ cat <<EOF > $container_rootfs/etc/sysconfig/network-scripts/ifcfg-eth0
+DEVICE=eth0
+BOOTPROTO=dhcp
+ONBOOT=yes
+HOSTNAME=$name
+DHCP_HOSTNAME=\`hostname\`
+NM_CONTROLLED=no
+TYPE=Ethernet
+EOF
+
+ # set the hostname
+ if [ $container_release_major -ge "7" ]; then
+ # systemd honors /etc/hostname
+ echo "$name" >$container_rootfs/etc/hostname
+ fi
+ cat <<EOF > $container_rootfs/etc/sysconfig/network
+NETWORKING=yes
+NETWORKING_IPV6=no
+HOSTNAME=$name
+EOF
+
+ # set minimal hosts
+ echo "127.0.0.1 localhost $name" > $container_rootfs/etc/hosts
+
+ # this file has to exist for libvirt/Virtual machine monitor to boot the container
+ touch $container_rootfs/etc/mtab
+
# setup console and tty[1-4] for login. note that /dev/console and
# /dev/tty[1-4] will be symlinks to the ptys /dev/lxc/console and
# /dev/lxc/tty[1-4] so that package updates can overwrite the symlinks.
# lxc will maintain these links and bind mount ptys over /dev/lxc/*
- # since lxc.devttydir is specified in the config.
+ # since lxc.tty.dir is specified in the config.
# allow root login on console, tty[1-4], and pts/0 for libvirt
echo "# LXC (Linux Containers)" >>$container_rootfs/etc/securetty
echo "lxc/console" >>$container_rootfs/etc/securetty
- echo "lxc/tty1" >>$container_rootfs/etc/securetty
- echo "lxc/tty2" >>$container_rootfs/etc/securetty
- echo "lxc/tty3" >>$container_rootfs/etc/securetty
- echo "lxc/tty4" >>$container_rootfs/etc/securetty
+ for i in 1 2 3 4; do
+ echo "lxc/tty$i" >>$container_rootfs/etc/securetty
+ done
echo "# For libvirt/Virtual Machine Monitor" >>$container_rootfs/etc/securetty
- echo "pts/0" >>$container_rootfs/etc/securetty
+ for i in 0 1 2 3 4; do
+ echo "pts/$i" >>$container_rootfs/etc/securetty
+ done
# prevent mingetty from calling vhangup(2) since it fails with userns
if [ -f $container_rootfs/etc/init/tty.conf ]; then
sed -i 's|mingetty|mingetty --nohangup|' $container_rootfs/etc/init/tty.conf
fi
- # dont try to unmount /dev/lxc devices
- sed -i 's|&& $1 !~ /^\\/dev\\/ram/|\&\& $2 !~ /^\\/dev\\/lxc/ \&\& $1 !~ /^\\/dev\\/ram/|' $container_rootfs/etc/init.d/halt
-
- # don't try to unmount swap
- sed -i 's|\[ -f /proc/swaps \]|# LXC [ -f /proc/swaps ]|' $container_rootfs/etc/init.d/halt
+ # create maygetty which only spawns a getty on the console when running
+ # under lxc, not libvirt-lxc which symlinks /dev/console to the same pty
+ # as /dev/tty1
+ cat <<EOF >$container_rootfs/sbin/maygetty
+#!/bin/sh
+if [ "\$container" = "lxc" ]; then
+ exec /sbin/mingetty \$@
+fi
+exec sleep infinity
+EOF
+ chmod 755 $container_rootfs/sbin/maygetty
# start a getty on /dev/console, /dev/tty[1-4]
if [ $container_release_major = "4" -o $container_release_major = "5" ]; then
sed -i 's|mingetty|mingetty --nohangup|' $container_rootfs/etc/inittab
- sed -i '/1:2345:respawn/i cns:2345:respawn:/sbin/mingetty --nohangup --noclear console' $container_rootfs/etc/inittab
+ sed -i '/1:2345:respawn/i cns:2345:respawn:/sbin/maygetty --nohangup --noclear console' $container_rootfs/etc/inittab
sed -i '/5:2345:respawn/d' $container_rootfs/etc/inittab
sed -i '/6:2345:respawn/d' $container_rootfs/etc/inittab
fi
start on stopped rc RUNLEVEL=[2345]
stop on runlevel [!2345]
+env container
respawn
-exec /sbin/mingetty --nohangup --noclear /dev/console
+exec /sbin/maygetty --nohangup --noclear /dev/console
EOF
fi
# /com/ubuntu/upstart socket.
if [ $container_release_major = "4" -o $container_release_major = "5" ]; then
sed -i 's|pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; |pf::powerfail:/sbin/shutdown -f -h now "|' $container_rootfs/etc/inittab
- else
+ elif [ $container_release_major = "6" ]; then
cat <<EOF > $container_rootfs/etc/init/power-status-changed.conf
# power-status-changed - used to cleanly shut down the container
#
EOF
fi
- # there might be other services that are useless but the below set is a good start
- # some of these might not exist in the image, so we silence chkconfig complaining
- # about the service file not being found
- for service in \
- acpid apmd auditd autofs cpuspeed dund gpm haldaemon hidd \
- ip6tables irqbalance iscsi iscsid isdn kdump kudzu \
- lm_sensors lvm2-monitor mdmonitor microcode_ctl \
- ntpd pcmcia postfix sendmail udev-post xfs ;
- do
- chroot $container_rootfs chkconfig 2>/dev/null $service off
- done
-
- for service in rsyslog ;
- do
- chroot $container_rootfs chkconfig 2>/dev/null $service on
- done
+ # start with a clean /var/log/messages
+ rm -f $container_rootfs/var/log/messages
- # create required devices. note that /dev/console will be created by lxc
- # or libvirt itself to be a symlink to the right pty.
- # take care to not nuke /dev in case $container_rootfs isn't set
- dev_path="$container_rootfs/dev"
- if [ $container_rootfs != "/" -a -d $dev_path ]; then
- rm -rf $dev_path
- mkdir -p $dev_path
- if can_chcon; then
- # ensure symlinks created in /dev have the right context
- chcon -t device_t $dev_path
+ # set initial timezone as on host
+ if [ -f /etc/sysconfig/clock ]; then
+ . /etc/sysconfig/clock
+ if [ $container_release_major = "5" -o $container_release_major = "6" ]; then
+ echo ZONE=$ZONE > $container_rootfs/etc/sysconfig/clock
+ chroot $container_rootfs tzdata-update
+ else
+ ZONE="${ZONE// /_}"
+ chroot $container_rootfs ln -sf ../usr/share/zoneinfo/$ZONE /etc/localtime
+ fi
+ else
+ ZONE=`readlink /etc/localtime | sed -s "s/\.\.\/usr\/share\/zoneinfo\///g"`
+ if [ "$ZONE" ]; then
+ if [ $container_release_major = "5" -o $container_release_major = "6" ]; then
+ echo ZONE=$ZONE > $container_rootfs/etc/sysconfig/clock
+ chroot $container_rootfs tzdata-update
+ else
+ # if /etc/localtime is a symlink, this should preserve it.
+ cp -a /etc/localtime $container_rootfs/etc/localtime
+ fi
+ else
+ echo "Timezone in container is not configured. Adjust it manually."
fi
fi
- 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 666 $dev_path/full c 1 7
- mknod -m 600 $dev_path/initctl p
-
- # set selinux labels same as host
- if can_chcon; then
- for node in null zero random urandom pts shm \
- tty tty0 tty1 tty2 tty3 tty4 full ;
- do
- chcon --reference /dev/$node $dev_path/$node 2>/dev/null
- done
- fi
-
- # ensure /dev/ptmx refers to the newinstance devpts of the container, or
- # pty's will get crossed up with the hosts (https://lkml.org/lkml/2012/1/23/512)
- rm -f $container_rootfs/dev/ptmx
- ln -s pts/ptmx $container_rootfs/dev/ptmx
- # start with a clean /var/log/messages
- rm -f $container_rootfs/var/log/messages
-
- # add oracle user, set root password
+ # add oracle user
chroot $container_rootfs useradd -m -s /bin/bash oracle
- echo "oracle:oracle" | chroot $container_rootfs chpasswd
- echo "root:root" | chroot $container_rootfs chpasswd
- printf "Added container user:\033[1moracle\033[0m password:\033[1moracle\033[0m\n"
- printf "Added container user:\033[1mroot\033[0m password:\033[1mroot\033[0m\n"
+ printf "Added container user:\033[1moracle\033[0m\n"
+ printf "Added container user:\033[1mroot\033[0m\n"
}
# create the container's lxc config file
echo "lxc.include = @LXCTEMPLATECONFIG@/oracle.common.conf" >> $cfg_dir/config
fi
- # generate a hwaddr for the container with a high mac address
- # see http://sourceforge.net/tracker/?func=detail&aid=3411497&group_id=163076&atid=826303
- local hwaddr="fe:`dd if=/dev/urandom bs=8 count=1 2>/dev/null |od -t x8 | \
- head -n 1 |awk '{print $2}' | cut -c1-10 |\
- sed 's/\(..\)/\1:/g; s/.$//'`"
cat <<EOF >> $cfg_dir/config || die "unable to create $cfg_dir/config"
# Container configuration for Oracle Linux $container_release_major.$container_release_minor
lxc.arch = $arch
echo "lxc.cap.drop = sys_resource" >>$cfg_dir/config
fi
+ # systemd services like logind and journald need these
+ if [ $container_release_major != "7" ]; then
+ echo "lxc.cap.drop = setfcap setpcap" >>$cfg_dir/config
+ fi
+
echo "# Networking" >>$cfg_dir/config
- # see if the network settings were already specified
- lxc_network_type=`grep '^lxc.network.type' $cfg_dir/config | awk -F'[= \t]+' '{ print $2 }'`
- if [ -z "$lxc_network_type" -a \
- \( $host_distribution = "OracleServer" -o \
- $host_distribution = "Fedora" \) ]; then
- echo "lxc.network.type = veth" >>$cfg_dir/config
- echo "lxc.network.flags = up" >>$cfg_dir/config
- echo "lxc.network.link = virbr0" >>$cfg_dir/config
+ # see if the default network settings were already specified
+ lxc_network_type=`grep '^lxc.net.0.type' $cfg_dir/config | awk -F'[= \t]+' '{ print $2 }'`
+ if [ -z "$lxc_network_type" ]; then
+ echo "lxc.net.0.type = veth" >>$cfg_dir/config
+ lxc_network_type=veth
+ fi
+
+ lxc_network_link=`grep '^lxc.net.0.link' $cfg_dir/config | awk -F'[= \t]+' '{ print $2 }'`
+ if [ -z "$lxc_network_link" ]; then
+ echo "lxc.net.0.link = lxcbr0" >>$cfg_dir/config
+ lxc_network_link=lxcbr0
+ fi
+
+ lxc_network_hwaddr=`grep '^lxc.net.0.hwaddr' $cfg_dir/config | awk -F'[= \t]+' '{ print $2 }'`
+ if [ -z "$lxc_network_hwaddr" ]; then
+ # generate a hwaddr for the container
+ # see http://sourceforge.net/tracker/?func=detail&aid=3411497&group_id=163076&atid=826303
+ local hwaddr="00:16:3e:`dd if=/dev/urandom bs=8 count=1 2>/dev/null |od -t x8 | \
+ head -n1 | awk '{print $2}' | cut -c1-6 | \
+ sed 's/\(..\)/\1:/g; s/.$//'`"
+ echo "lxc.net.0.hwaddr = $hwaddr" >>$cfg_dir/config
+ fi
+
+ lxc_network_flags=`grep '^lxc.net.0.flags' $cfg_dir/config | awk -F'[= \t]+' '{ print $2 }'`
+ if [ -z "$lxc_network_flags" ]; then
+ echo "lxc.net.0.flags = up" >>$cfg_dir/config
fi
cat <<EOF >> $cfg_dir/config || die "unable to create $cfg_dir/config"
-lxc.network.name = eth0
-lxc.network.mtu = 1500
-lxc.network.hwaddr = $hwaddr
+lxc.net.0.name = eth0
+lxc.net.0.mtu = 1500
EOF
}
fi
}
+container_rootfs_repo_create()
+{
+ echo "# LXC generated .repo file" >$1
+ echo "[$2]" >>$1
+ echo "name=Oracle Linux $container_release_major.$container_release_minor ($basearch)" >>$1
+ echo "baseurl=$3/" >>$1
+ echo "enabled=1" >>$1
+ echo "skip_if_unavailable=1" >>$1
+
+ if [ "$4" != "" ]; then
+ echo "gpgkey=$yum_url/RPM-GPG-KEY-oracle-ol$container_release_major" >>$1
+ echo "gpgcheck=1" >>$1
+ else
+ echo "gpgcheck=0" >>$1
+ fi
+}
+
+container_rootfs_dev_create()
+{
+ # create required devices. note that /dev/console will be created by lxc
+ # or libvirt itself to be a symlink to the right pty.
+ # take care to not nuke /dev in case $container_rootfs isn't set
+ dev_path="$container_rootfs/dev"
+ if [ $container_rootfs != "/" -a -d $dev_path ]; then
+ rm -rf $dev_path
+ fi
+ mkdir -p $dev_path
+ if can_chcon; then
+ # ensure symlinks created in /dev have the right context
+ chcon -t device_t $dev_path
+ fi
+ 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/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 666 $dev_path/full c 1 7
+ mknod -m 600 $dev_path/initctl p
+
+ # set selinux labels same as host
+ if can_chcon; then
+ for node in null zero random urandom pts shm \
+ tty tty0 tty1 tty2 tty3 tty4 full ;
+ do
+ chcon --reference /dev/$node $dev_path/$node 2>/dev/null
+ done
+ fi
+}
+
container_rootfs_create()
{
+ if can_chcon; then
+ chcon --reference / $container_rootfs 2>/dev/null
+ fi
+
cmds="rpm wget yum"
if [ $container_release_major -lt "6" ]; then
if [ $host_distribution = "Ubuntu" -o $host_distribution = "Debian" ]; then
db_dump_cmd="db5.1_dump"
- db_load_cmd="db4.3_load"
fi
if [ $host_distribution = "OracleServer" -o \
$host_distribution = "Fedora" ]; then
db_dump_cmd="db_dump"
- db_load_cmd="db43_load"
fi
- cmds="$cmds $db_dump_cmd $db_load_cmd file"
+ cmds="$cmds $db_dump_cmd file"
fi
for cmd in $cmds; do
which $cmd >/dev/null 2>&1
fi
done
- mkdir -p @LOCALSTATEDIR@/lock/subsys/lxc
+ mkdir -p @LOCALSTATEDIR@/lock/subsys
(
flock -x 9
if [ $? -ne 0 ]; then
die "The template is busy."
fi
- echo "Downloading release $container_release_major.$container_release_minor for $basearch"
+ echo "Yum installing release $container_release_major.$container_release_minor for $basearch"
- # get yum repo file
if [ -n "$repourl" ]; then
yum_url=$repourl
else
yum_url=http://public-yum.oracle.com
fi
- if [ $container_release_major = "4" ]; then
- repofile=public-yum-el4.repo
- elif [ $container_release_major = "5" ]; then
- repofile=public-yum-el5.repo
- elif [ $container_release_major = "6" ]; then
- repofile=public-yum-ol6.repo
+ if [ $container_release_major = "4" -o $container_release_major = "5" ]; then
+ latest_L="el"
+ latest_U="EL"
else
- die "Unsupported release $container_release_major"
- fi
- mkdir -p $container_rootfs/etc/yum.repos.d
- wget -q $yum_url/$repofile -O $container_rootfs/etc/yum.repos.d/$repofile
- if [ $? -ne 0 ]; then
- die "Failed to download repo file $yum_url/$repofile"
- fi
-
- # yum will take $basearch from host, so force the arch we want
- sed -i "s|\$basearch|$basearch|" $container_rootfs/etc/yum.repos.d/$repofile
-
- # replace url if they specified one
- if [ -n "$repourl" ]; then
- sed -i "s|baseurl=http://public-yum.oracle.com/repo|baseurl=$repourl/repo|" $container_rootfs/etc/yum.repos.d/$repofile
- sed -i "s|gpgkey=http://public-yum.oracle.com|gpgkey=$repourl|" $container_rootfs/etc/yum.repos.d/$repofile
+ latest_L="ol"
+ latest_U="OL"
fi
- # disable all repos, then enable the repo for the version we are installing.
- if [ $container_release_minor = "latest" ]; then
- if [ $container_release_major = "4" -o $container_release_major = "5" ]; then
- repo="el"$container_release_major"_"$container_release_minor
+ if [ -n "$baseurl" ]; then
+ # create .repo pointing at baseurl
+ repo="lxc-install"
+ mkdir -p $container_rootfs/etc/yum.repos.d
+ container_rootfs_repo_create \
+ $container_rootfs/etc/yum.repos.d/lxc-install.repo $repo $baseurl
+ else
+ # get public-yum repo file
+ if [ $container_release_major = "4" ]; then
+ repofile=public-yum-el4.repo
+ elif [ $container_release_major = "5" ]; then
+ repofile=public-yum-el5.repo
+ elif [ $container_release_major = "6" ]; then
+ repofile=public-yum-ol6.repo
+ elif [ $container_release_major = "7" ]; then
+ repofile=public-yum-ol7.repo
else
- repo="ol"$container_release_major"_"$container_release_minor
+ die "Unsupported release $container_release_major"
fi
- elif [ $container_release_major = "6" ]; then
- if [ $container_release_minor = "0" ]; then
- repo="ol"$container_release_major"_ga_base"
- else
- repo="ol"$container_release_major"_u"$container_release_minor"_base"
+
+ mkdir -p $container_rootfs/etc/yum.repos.d
+ wget -q $yum_url/$repofile -O $container_rootfs/etc/yum.repos.d/$repofile
+ if [ $? -ne 0 ]; then
+ die "Unable to download repo file $yum_url/$repofile, release unavailable"
fi
- elif [ $container_release_major = "5" ]; then
- if [ $container_release_minor = "0" ]; then
- repo="el"$container_release_major"_ga_base"
- elif [ $container_release_minor -lt "6" ]; then
+
+ # yum will take $basearch from host, so force the arch we want
+ sed -i "s|\$basearch|$basearch|" $container_rootfs/etc/yum.repos.d/$repofile
+
+ # replace url if they specified one
+ if [ -n "$repourl" ]; then
+ sed -i "s|baseurl=http://public-yum.oracle.com/repo|baseurl=$repourl/repo|" $container_rootfs/etc/yum.repos.d/$repofile
+ sed -i "s|gpgkey=http://public-yum.oracle.com|gpgkey=$repourl|" $container_rootfs/etc/yum.repos.d/$repofile
+ fi
+
+ # disable all repos, then enable the repo for the version we are installing.
+ if [ $container_release_minor = "latest" ]; then
+ repo=$latest_L""$container_release_major"_"$container_release_minor
+ elif [ $container_release_major = "7" ]; then
+ repo="ol"$container_release_major"_u"$container_release_minor"_base"
+ elif [ $container_release_major = "6" ]; then
+ if [ $container_release_minor = "0" ]; then
+ repo="ol"$container_release_major"_ga_base"
+ else
+ repo="ol"$container_release_major"_u"$container_release_minor"_base"
+ fi
+ elif [ $container_release_major = "5" ]; then
+ if [ $container_release_minor = "0" ]; then
+ repo="el"$container_release_major"_ga_base"
+ elif [ $container_release_minor -lt "6" ]; then
+ repo="el"$container_release_major"_u"$container_release_minor"_base"
+ else
+ repo="ol"$container_release_major"_u"$container_release_minor"_base"
+ fi
+ elif [ $container_release_major = "4" -a $container_release_minor -gt "5" ]; then
repo="el"$container_release_major"_u"$container_release_minor"_base"
else
- repo="ol"$container_release_major"_u"$container_release_minor"_base"
+ die "Unsupported release $container_release_major.$container_release_minor"
fi
- elif [ $container_release_major = "4" -a $container_release_minor -gt "5" ]; then
- repo="el"$container_release_major"_u"$container_release_minor"_base"
- else
- die "Unsupported release $container_release_major.$container_release_minor"
+ sed -i "s|enabled=1|enabled=0|" $container_rootfs/etc/yum.repos.d/$repofile
+ sed -i "/\[$repo\]/,/\[/ s/enabled=0/enabled=1/" $container_rootfs/etc/yum.repos.d/$repofile
fi
- sed -i "s|enabled=1|enabled=0|" $container_rootfs/etc/yum.repos.d/$repofile
- sed -i "/\[$repo\]/,/\[/ s/enabled=0/enabled=1/" $container_rootfs/etc/yum.repos.d/$repofile
+
+ container_rootfs_dev_create
+
+ # don't put devpts,proc, nor sysfs in here, it will already be mounted for us by lxc/libvirt
+ echo "" >$container_rootfs/etc/fstab
# create rpm db, download and yum install minimal packages
mkdir -p $container_rootfs/var/lib/rpm
rpm --root $container_rootfs --initdb
yum_args="--installroot $container_rootfs --disablerepo=* --enablerepo=$repo -y --nogpgcheck"
min_pkgs="yum initscripts passwd rsyslog vim-minimal openssh-server openssh-clients dhclient chkconfig rootfiles policycoreutils oraclelinux-release"
+ if [ $container_release_major -lt "6" ]; then
+ min_pkgs="$min_pkgs db4-utils"
+ fi
# we unshare the mount namespace because yum installing the ol4
# packages causes $rootfs/proc to be mounted on
fi
if [ x"$redo_pkgs" != x ]; then
rpm --root $container_rootfs --nodeps -e $redo_pkgs
- yum $yum_args install $redo_pkgs
+ lxc-unshare -s MOUNT yum -- $yum_args install $redo_pkgs
if [ $? -ne 0 ]; then
die "Unable to reinstall packages"
fi
fi
+ # if installing from a baseurl, create a .repo that the container
+ # can use to update to _latest from http://public-yum.oracle.com
+ if [ -n "$baseurl" ]; then
+ container_rootfs_repo_create \
+ "$container_rootfs/etc/yum.repos.d/public-yum-"$latestL""$container_release_major".repo" \
+ $latest_L""$container_release_major"_latest" \
+ $yum_url"/repo/OracleLinux/"$latest_U""$container_release_major"/latest/$basearch" gpg
+ fi
+
# these distributions put the rpm database in a place the guest is
# not expecting it, so move it
if [ $host_distribution = "Ubuntu" -o $host_distribution = "Debian" ]; then
echo "Fixing (downgrading) rpm database from version $db_version"
rm -f $container_rootfs/var/lib/rpm/__db*
for db in $container_rootfs/var/lib/rpm/* ; do
- $db_dump_cmd $db |$db_load_cmd $db.new
+ $db_dump_cmd $db |chroot $container_rootfs db_load /var/lib/rpm/`basename $db`.new
mv $db.new $db
done
fi
chroot $container_rootfs rpm --rebuilddb >/dev/null 2>&1
) 9>@LOCALSTATEDIR@/lock/subsys/lxc-oracle-$name
+ if [ $? -ne 0 ]; then
+ exit 1
+ fi
}
container_release_get()
-R|--release=<release> release to download for the new container
--rootfs=<path> rootfs path
-r|--rpms=<rpm name> additional rpms to install into container
- -u|--url=<url> replace yum repo url (ie. local yum mirror)
+ -u|--url=<url> replace yum repo url (ie. Oracle public-yum mirror)
+ --baseurl=<url> use package repository (ie. file:///mnt)
+ arch and release must also be specified
-t|--templatefs=<path> copy/clone rootfs at path instead of downloading
+ -P|--patch=<path> only patch the rootfs at path for use as a container
-h|--help
Release is of the format "major.minor", for example "5.8", "6.3", or "6.latest"
+This template supports Oracle Linux releases 4.6 - 7.0
EOF
return 0
}
-options=$(getopt -o hp:n:a:R:r:u:t: -l help,rootfs:,path:,name:,arch:,release:,rpms:,url:,templatefs: -- "$@")
+options=$(getopt -o hp:n:a:R:r:u:t: -l help,rootfs:,path:,name:,arch:,release:,rpms:,url:,templatefs:,patch:,baseurl: -- "$@")
if [ $? -ne 0 ]; then
usage $(basename $0)
exit 1
fi
-arch=$(uname -m)
eval set -- "$options"
while true
do
-r|--rpms) user_pkgs=$2; shift 2;;
-u|--url) repourl=$2; shift 2;;
-t|--templatefs) template_rootfs=$2; shift 2;;
+ --patch) patch_rootfs=$2; shift 2;;
+ --baseurl) baseurl=$2; shift 2;;
--) shift 1; break ;;
*) break ;;
esac
exit 1
fi
+if [ -n "$baseurl" ]; then
+ if [ "$arch" = "" -o "$container_release_version" = "" ]; then
+ echo "The --arch and --release must be specified when using --baseurl"
+ usage
+ exit 1
+ fi
+fi
+
+if [ "$arch" = "" ]; then
+ arch=$(uname -m)
+fi
+
+if [ -n "$patch_rootfs" ]; then
+ container_rootfs="$patch_rootfs"
+ container_release_get $container_rootfs
+ container_rootfs_patch
+ exit 0
+fi
+
if [ -z $name ]; then
echo "Container name must be given"
usage