From 0af993195cbd57cff700c7c90ee8f95c2a1ef8aa Mon Sep 17 00:00:00 2001 From: "Michael H. Warfield" Date: Mon, 25 Aug 2014 15:00:46 -0400 Subject: [PATCH] Rework init scripts MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This commit is based on the work of: Signed-off-by: Michael H. Warfield A generic changelog would be: - Bring support for lxcbr0 to all distributions - Share the container startup and network configuration logic across distributions and init systems. - Have all the init scripts call the helper script. - Support for the various different distro-specific configuration locations to configure lxc-net and container startup. Changes on top of Mike's original version: - Remove sysconfig/lxc-net as it's apparently only there as a workaround for an RPM limitation and is breaking Debian systems by including a useless file which will get registered as a package provided conffile in the dpkg database and will therefore cause conffile prompts on upgrades... - Go with a consistant coding style in the various init scripts. - Split out the common logic from the sysvinit scripts and ship both in their respective location rather than have them be copies. - Fix the upstart jobs so they actually work (there's no such thing as libexec on Debian systems). Signed-off-by: Stéphane Graber Acked-by: Serge E. Hallyn --- config/Makefile.am | 2 +- config/etc/Makefile.am | 2 +- ...default.conf.ubuntu => default.conf.lxcbr} | 0 config/init/Makefile.am | 2 +- config/init/common/Makefile.am | 2 + .../lxc.in => common/lxc-containers.in} | 119 +++++++++-------- config/init/common/lxc-net.in | 123 ++++++++++++++++++ config/init/systemd/Makefile.am | 17 +-- config/init/systemd/lxc-net.service.in | 4 +- config/init/systemd/lxc.service.in | 4 +- config/init/sysvinit/Makefile.am | 23 +++- config/init/sysvinit/lxc-containers.in | 45 +++++++ config/init/sysvinit/lxc-net.in | 45 +++++++ config/init/upstart/Makefile.am | 2 +- .../upstart/{lxc-net.conf => lxc-net.conf.in} | 4 +- config/sysconfig/Makefile.am | 6 + config/sysconfig/lxc.in | 29 +++++ configure.ac | 23 +++- lxc.spec.in | 110 +++++++++++++++- src/lxc/Makefile.am | 6 +- src/lxc/lxc.net | 103 --------------- 21 files changed, 469 insertions(+), 202 deletions(-) rename config/etc/{default.conf.ubuntu => default.conf.lxcbr} (100%) create mode 100644 config/init/common/Makefile.am rename config/init/{sysvinit/lxc.in => common/lxc-containers.in} (51%) create mode 100644 config/init/common/lxc-net.in create mode 100644 config/init/sysvinit/lxc-containers.in create mode 100644 config/init/sysvinit/lxc-net.in rename config/init/upstart/{lxc-net.conf => lxc-net.conf.in} (57%) create mode 100644 config/sysconfig/Makefile.am create mode 100644 config/sysconfig/lxc.in delete mode 100755 src/lxc/lxc.net diff --git a/config/Makefile.am b/config/Makefile.am index 37fd24ba2..54f8859e1 100644 --- a/config/Makefile.am +++ b/config/Makefile.am @@ -1 +1 @@ -SUBDIRS = apparmor bash etc init selinux templates yum +SUBDIRS = apparmor bash etc init selinux templates yum sysconfig diff --git a/config/etc/Makefile.am b/config/etc/Makefile.am index a830aef35..d5d0a9aac 100644 --- a/config/etc/Makefile.am +++ b/config/etc/Makefile.am @@ -1,7 +1,7 @@ configdir = $(sysconfdir)/lxc config_DATA = default.conf -EXTRA_DIST = default.conf.ubuntu default.conf.libvirt default.conf.unknown +EXTRA_DIST = default.conf.lxcbr default.conf.libvirt default.conf.unknown distclean-local: @$(RM) -f default.conf diff --git a/config/etc/default.conf.ubuntu b/config/etc/default.conf.lxcbr similarity index 100% rename from config/etc/default.conf.ubuntu rename to config/etc/default.conf.lxcbr diff --git a/config/init/Makefile.am b/config/init/Makefile.am index e2ffe28ad..1a9c7b280 100644 --- a/config/init/Makefile.am +++ b/config/init/Makefile.am @@ -1 +1 @@ -SUBDIRS = systemd sysvinit upstart +SUBDIRS = common systemd sysvinit upstart diff --git a/config/init/common/Makefile.am b/config/init/common/Makefile.am new file mode 100644 index 000000000..8c0134c7a --- /dev/null +++ b/config/init/common/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST = lxc-containers.in lxc-net.in +pkglibexec_SCRIPTS = lxc-containers lxc-net diff --git a/config/init/sysvinit/lxc.in b/config/init/common/lxc-containers.in similarity index 51% rename from config/init/sysvinit/lxc.in rename to config/init/common/lxc-containers.in index 7cad8c8e4..9d1d604b6 100644 --- a/config/init/sysvinit/lxc.in +++ b/config/init/common/lxc-containers.in @@ -1,23 +1,14 @@ #!/bin/sh -# -# lxc Start/Stop LXC autoboot containers -# -# chkconfig: 345 99 01 -# description: Starts/Stops all LXC containers configured for autostart. -# -### BEGIN INIT INFO -# Provides: lxc -# Default-Start: 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Bring up/down LXC autostart containers -# Description: Bring up/down LXC autostart containers -### END INIT INFO sysconfdir="@SYSCONFDIR@" +distrosysconfdir="@LXC_DISTRO_SYSCONF@" bindir="@BINDIR@" localstatedir="@LOCALSTATEDIR@" -# These can be overridden in @SYSCONFDIR@/sysconfig/lxc +# These can be overridden in @LXC_DISTRO_SYSCONF@/lxc + +# Autostart containers? +LXC_AUTO="true" # BOOTGROUPS - What groups should start on bootup? # Comma separated list of groups. @@ -27,7 +18,7 @@ localstatedir="@LOCALSTATEDIR@" BOOTGROUPS="onboot," # SHUTDOWNDELAY - Wait time for a container to shut down. -# ner shutdown can result in lengthy system +# Container shutdown can result in lengthy system # shutdown times. Even 5 seconds per container can be # too long. SHUTDOWNDELAY=5 @@ -47,14 +38,22 @@ test ! -r "$sysconfdir"/rc.d/init.d/functions || # provide action() fallback if ! type action >/dev/null 2>&1; then + # Real basic fallback for sysvinit "action" verbage. action() { - echo "$@" + echo -n "$1 " + "$@" && echo "OK" || echo "Failed" } fi +if [ -d "$localstatedir"/lock/subsys ] +then + lockdir="$localstatedir"/lock/subsys +else + lockdir="$localstatedir"/lock +fi + # Source any configurable options -test ! -r "$sysconfdir"/sysconfig/lxc || - . "$sysconfdir"/sysconfig/lxc +[ ! -f "$distrosysconfdir"/lxc ] || . "$distrosysconfdir"/lxc # Check for needed utility program [ -x "$bindir"/lxc-autostart ] || exit 1 @@ -80,52 +79,58 @@ wait_for_bridge() BRNAME=`grep '^[ ]*lxc.network.link' "$sysconfdir"/lxc/default.conf | sed 's/^.*=[ ]*//'` if [ -z "$BRNAME" ]; then - return 0 + return 0 fi for try in `seq 1 30`; do - eval $cmd |grep "^$BRNAME" >/dev/null 2>&1 - if [ $? = 0 ]; then - return - fi - sleep 1 + eval $cmd |grep "^$BRNAME" >/dev/null 2>&1 + if [ $? = 0 ]; then + return + fi + sleep 1 done } # See how we were called. case "$1" in - start) - [ ! -f "$localstatedir"/lock/subsys/lxc ] || { exit 0; } - - if [ -n "$BOOTGROUPS" ] - then - BOOTGROUPS="-g $BOOTGROUPS" - fi - - # Start containers - wait_for_bridge - # Start autoboot containers first then the NULL group "onboot,". - action $"Starting LXC autoboot containers: " "$bindir"/lxc-autostart $OPTIONS $BOOTGROUPS - touch "$localstatedir"/lock/subsys/lxc - ;; - stop) - if [ -n "$SHUTDOWNDELAY" ] - then - SHUTDOWNDELAY="-t $SHUTDOWNDELAY" - fi - - # The stop is serialized and can take excessive time. We need to avoid - # delaying the system shutdown / reboot as much as we can since it's not - # parallelized... Even 5 second timout may be too long. - action $"Stopping LXC containers: " "$bindir"/lxc-autostart $STOPOPTS $SHUTDOWNDELAY - rm -f "$localstatedir"/lock/subsys/lxc - ;; - restart|reload|force-reload) - $0 stop - $0 start - ;; - *) - echo "Usage: $0 {start|stop|restart|reload|force-reload}" - exit 2 + start) + [ "x$LXC_AUTO" = "xtrue" ] || { exit 0; } + + [ ! -f "$lockdir"/lxc ] || { exit 0; } + + if [ -n "$BOOTGROUPS" ]; then + BOOTGROUPS="-g $BOOTGROUPS" + fi + + # Start containers + wait_for_bridge + + # Start autoboot containers first then the NULL group "onboot,". + action $"Starting LXC autoboot containers: " "$bindir"/lxc-autostart $OPTIONS $BOOTGROUPS + touch "$lockdir"/lxc + ;; + + stop) + if [ -n "$SHUTDOWNDELAY" ]; then + SHUTDOWNDELAY="-t $SHUTDOWNDELAY" + fi + + # The stop is serialized and can take excessive time. We need to avoid + # delaying the system shutdown / reboot as much as we can since it's not + # parallelized... Even 5 second timout may be too long. + action $"Stopping LXC containers: " "$bindir"/lxc-autostart $STOPOPTS $SHUTDOWNDELAY + rm -f "$lockdir"/lxc + ;; + + restart|reload|force-reload) + $0 stop + $0 start + ;; + + *) + echo "Usage: $0 {start|stop|restart|reload|force-reload}" + exit 2 + ;; esac + exit $? diff --git a/config/init/common/lxc-net.in b/config/init/common/lxc-net.in new file mode 100644 index 000000000..c921ab726 --- /dev/null +++ b/config/init/common/lxc-net.in @@ -0,0 +1,123 @@ +#!/bin/sh - + +distrosysconfdir="@LXC_DISTRO_SYSCONF@" +localstatedir="@LOCALSTATEDIR@" +varrun="@RUNTIME_PATH@/lxc" + +# These can be overridden in @LXC_DISTRO_SYSCONF@/lxc +# or in @LXC_DISTRO_SYSCONF@/lxc-net + +USE_LXC_BRIDGE="true" +LXC_BRIDGE="lxcbr0" +LXC_ADDR="10.0.3.1" +LXC_NETMASK="255.255.255.0" +LXC_NETWORK="10.0.3.0/24" +LXC_DHCP_RANGE="10.0.3.2,10.0.3.254" +LXC_DHCP_MAX="253" +LXC_DHCP_CONFILE="" +LXC_DOMAIN="" + +[ ! -f $distrosysconfdir/lxc ] || . $distrosysconfdir/lxc + +if [ -d "$localstatedir"/lock/subsys ]; then + lockdir="$localstatedir"/lock/subsys +else + lockdir="$localstatedir"/lock +fi + +start() { + [ ! -f "${lockdir}"/lxc-net ] || { exit 0; } + + [ "x$USE_LXC_BRIDGE" = "xtrue" ] || { exit 0; } + + use_iptables_lock="-w" + iptables -w -L -n > /dev/null 2>&1 || use_iptables_lock="" + cleanup() { + # dnsmasq failed to start, clean up the bridge + iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p udp --dport 67 -j ACCEPT + iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p tcp --dport 67 -j ACCEPT + iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p udp --dport 53 -j ACCEPT + iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p tcp --dport 53 -j ACCEPT + iptables $use_iptables_lock -D FORWARD -i ${LXC_BRIDGE} -j ACCEPT + iptables $use_iptables_lock -D FORWARD -o ${LXC_BRIDGE} -j ACCEPT + iptables $use_iptables_lock -t nat -D POSTROUTING -s ${LXC_NETWORK} ! -d ${LXC_NETWORK} -j MASQUERADE || true + iptables $use_iptables_lock -t mangle -D POSTROUTING -o ${LXC_BRIDGE} -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill + ifconfig ${LXC_BRIDGE} down || true + brctl delbr ${LXC_BRIDGE} || true + } + + if [ -d /sys/class/net/${LXC_BRIDGE} ]; then + exit 0; + fi + + # set up the lxc network + brctl addbr ${LXC_BRIDGE} || { echo "Missing bridge support in kernel"; stop; exit 0; } + echo 1 > /proc/sys/net/ipv4/ip_forward + mkdir -p "${varrun}" + ifconfig ${LXC_BRIDGE} ${LXC_ADDR} netmask ${LXC_NETMASK} up + iptables $use_iptables_lock -I INPUT -i ${LXC_BRIDGE} -p udp --dport 67 -j ACCEPT + iptables $use_iptables_lock -I INPUT -i ${LXC_BRIDGE} -p tcp --dport 67 -j ACCEPT + iptables $use_iptables_lock -I INPUT -i ${LXC_BRIDGE} -p udp --dport 53 -j ACCEPT + iptables $use_iptables_lock -I INPUT -i ${LXC_BRIDGE} -p tcp --dport 53 -j ACCEPT + iptables $use_iptables_lock -I FORWARD -i ${LXC_BRIDGE} -j ACCEPT + iptables $use_iptables_lock -I FORWARD -o ${LXC_BRIDGE} -j ACCEPT + iptables $use_iptables_lock -t nat -A POSTROUTING -s ${LXC_NETWORK} ! -d ${LXC_NETWORK} -j MASQUERADE + iptables $use_iptables_lock -t mangle -A POSTROUTING -o ${LXC_BRIDGE} -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill + + LXC_DOMAIN_ARG="" + if [ -n "$LXC_DOMAIN" ]; then + LXC_DOMAIN_ARG="-s $LXC_DOMAIN -S /$LXC_DOMAIN/" + fi + dnsmasq $LXC_DOMAIN_ARG -u lxc-dnsmasq --strict-order --bind-interfaces --pid-file="${varrun}"/dnsmasq.pid --conf-file=${LXC_DHCP_CONFILE} --listen-address ${LXC_ADDR} --dhcp-range ${LXC_DHCP_RANGE} --dhcp-lease-max=${LXC_DHCP_MAX} --dhcp-no-override --except-interface=lo --interface=${LXC_BRIDGE} --dhcp-leasefile=/var/lib/misc/dnsmasq.${LXC_BRIDGE}.leases --dhcp-authoritative || cleanup + touch "${varrun}"/network_up + touch "${lockdir}"/lxc-net +} + +stop() { + [ "x$USE_LXC_BRIDGE" = "xtrue" ] || { exit 0; } + + [ -f "${varrun}/network_up" ] || { exit 0; } + # if $LXC_BRIDGE has attached interfaces, don't shut it down + ls /sys/class/net/${LXC_BRIDGE}/brif/* > /dev/null 2>&1 && exit 0; + + if [ -d /sys/class/net/${LXC_BRIDGE} ]; then + use_iptables_lock="-w" + iptables -w -L -n > /dev/null 2>&1 || use_iptables_lock="" + ifconfig ${LXC_BRIDGE} down + iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p udp --dport 67 -j ACCEPT + iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p tcp --dport 67 -j ACCEPT + iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p udp --dport 53 -j ACCEPT + iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p tcp --dport 53 -j ACCEPT + iptables $use_iptables_lock -D FORWARD -i ${LXC_BRIDGE} -j ACCEPT + iptables $use_iptables_lock -D FORWARD -o ${LXC_BRIDGE} -j ACCEPT + iptables $use_iptables_lock -t nat -D POSTROUTING -s ${LXC_NETWORK} ! -d ${LXC_NETWORK} -j MASQUERADE || true + iptables $use_iptables_lock -t mangle -D POSTROUTING -o ${LXC_BRIDGE} -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill + pid=`cat "${varrun}"/dnsmasq.pid 2>/dev/null` && kill -9 $pid || true + rm -f "${varrun}"/dnsmasq.pid + brctl delbr ${LXC_BRIDGE} + fi + rm -f "${varrun}"/network_up + rm -f "${lockdir}"/lxc-net +} + +# See how we were called. +case "$1" in + start) + start + ;; + + stop) + stop + ;; + + restart|reload|force-reload) + $0 stop + $0 start + ;; + + *) + echo "Usage: $0 {start|stop|restart|reload|force-reload}" + exit 2 +esac + +exit $? diff --git a/config/init/systemd/Makefile.am b/config/init/systemd/Makefile.am index 5959cd85a..4201d98a7 100644 --- a/config/init/systemd/Makefile.am +++ b/config/init/systemd/Makefile.am @@ -2,21 +2,12 @@ EXTRA_DIST = \ lxc-devsetup \ lxc-apparmor-load \ lxc.service.in \ - lxc-net.service.in \ - $(NULL) + lxc-net.service.in if INIT_SCRIPT_SYSTEMD -lxc-autostart-helper: ../sysvinit/lxc.in $(top_builddir)/config.status - $(AM_V_GEN)sed \ - -e 's|[@]SYSCONFDIR[@]|$(sysconfdir)|g' \ - -e 's|[@]LOCALSTATEDIR[@]|$(localstatedir)|g' \ - -e 's|[@]BINDIR[@]|$(bindir)|g' \ - < $< > $@-t && \ - chmod a+x $@-t && \ - mv $@-t $@ -BUILT_SOURCES = lxc-autostart-helper lxc.service lxc-net.service +BUILT_SOURCES = lxc.service lxc-net.service -install-systemd: lxc.service lxc-net.service lxc-devsetup lxc-apparmor-load lxc-autostart-helper +install-systemd: lxc.service lxc-net.service lxc-devsetup lxc-apparmor-load $(MKDIR_P) $(DESTDIR)$(SYSTEMD_UNIT_DIR) $(INSTALL_DATA) lxc.service lxc-net.service $(DESTDIR)$(SYSTEMD_UNIT_DIR)/ @@ -25,7 +16,7 @@ uninstall-systemd: rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/lxc-net.service rmdir $(DESTDIR)$(SYSTEMD_UNIT_DIR) || : -pkglibexec_SCRIPTS = lxc-devsetup lxc-apparmor-load lxc-autostart-helper +pkglibexec_SCRIPTS = lxc-devsetup lxc-apparmor-load install-data-local: install-systemd uninstall-local: uninstall-systemd diff --git a/config/init/systemd/lxc-net.service.in b/config/init/systemd/lxc-net.service.in index 37d1d6941..c05470255 100644 --- a/config/init/systemd/lxc-net.service.in +++ b/config/init/systemd/lxc-net.service.in @@ -6,5 +6,5 @@ Before=lxc.service [Service] Type=oneshot RemainAfterExit=yes -ExecStart=@DATADIR@/lxc/lxc.net start -ExecStop=@DATADIR@/lxc/lxc.net stop +ExecStart=@LIBEXECDIR@/lxc/lxc-net start +ExecStop=@LIBEXECDIR@/lxc/lxc-net stop diff --git a/config/init/systemd/lxc.service.in b/config/init/systemd/lxc.service.in index f64610f7c..33da98768 100644 --- a/config/init/systemd/lxc.service.in +++ b/config/init/systemd/lxc.service.in @@ -8,8 +8,8 @@ Type=oneshot RemainAfterExit=yes ExecStartPre=@LIBEXECDIR@/lxc/lxc-devsetup ExecStartPre=@LIBEXECDIR@/lxc/lxc-apparmor-load -ExecStart=@LIBEXECDIR@/lxc/lxc-autostart-helper start -ExecStop=@LIBEXECDIR@/lxc/lxc-autostart-helper stop +ExecStart=@LIBEXECDIR@/lxc/lxc-containers start +ExecStop=@LIBEXECDIR@/lxc/lxc-containers stop # Environment=BOOTUP=serial # Environment=CONSOLETYPE=serial StandardOutput=syslog diff --git a/config/init/sysvinit/Makefile.am b/config/init/sysvinit/Makefile.am index 66c190d08..e8b9f4f3d 100644 --- a/config/init/sysvinit/Makefile.am +++ b/config/init/sysvinit/Makefile.am @@ -1,13 +1,24 @@ -EXTRA_DIST = lxc +EXTRA_DIST = lxc-containers.in lxc-net.in if INIT_SCRIPT_SYSV -install-sysvinit: lxc - $(MKDIR_P) $(DESTDIR)$(sysconfdir)/rc.d/init.d - $(INSTALL_SCRIPT) lxc $(DESTDIR)$(sysconfdir)/rc.d/init.d/lxc +# If we're installing for sysv init, install the helper scripts +# directly to the rc directory under the appropriate name. + +if HAVE_DEBIAN +initdir = "init.d" +else +initdir = "rc.d/init.d" +endif + +install-sysvinit: lxc-containers lxc-net + $(MKDIR_P) $(DESTDIR)$(sysconfdir)/$(initdir) + $(INSTALL_SCRIPT) lxc-containers $(DESTDIR)$(sysconfdir)/$(initdir)/lxc + $(INSTALL_SCRIPT) lxc-net $(DESTDIR)$(sysconfdir)/$(initdir)/lxc-net uninstall-sysvinit: - rm -f $(DESTDIR)$(sysconfdir)/rc.d/init.d/lxc - rmdir $(DESTDIR)$(sysconfdir)/rc.d/init.d || : + rm -f $(DESTDIR)$(sysconfdir)/$(initdir)/lxc + rm -f $(DESTDIR)$(sysconfdir)/$(initdir)/lxc-net + rmdir $(DESTDIR)$(sysconfdir)/$(initdir) || : install-data-local: install-sysvinit uninstall-local: uninstall-sysvinit diff --git a/config/init/sysvinit/lxc-containers.in b/config/init/sysvinit/lxc-containers.in new file mode 100644 index 000000000..9d92115cf --- /dev/null +++ b/config/init/sysvinit/lxc-containers.in @@ -0,0 +1,45 @@ +#!/bin/sh +# +# lxc Start/Stop LXC autoboot containers +# +# chkconfig: 345 99 01 +# description: Starts/Stops all LXC containers configured for autostart. +# +### BEGIN INIT INFO +# Provides: lxc +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Bring up/down LXC autostart containers +# Description: Bring up/down LXC autostart containers +### END INIT INFO + +start() { + @LIBEXECDIR@/lxc/lxc-containers start +} + +stop() { + @LIBEXECDIR@/lxc/lxc-containers stop +} + +# See how we were called. +case "$1" in + start) + start + ;; + + stop) + stop + ;; + + restart|reload|force-reload) + $0 stop + $0 start + ;; + + *) + echo "Usage: $0 {start|stop|restart|reload|force-reload}" + exit 2 + ;; +esac + +exit $? diff --git a/config/init/sysvinit/lxc-net.in b/config/init/sysvinit/lxc-net.in new file mode 100644 index 000000000..6e22505f3 --- /dev/null +++ b/config/init/sysvinit/lxc-net.in @@ -0,0 +1,45 @@ +#!/bin/sh - +# +# lxc-net Start/Stop LXC Networking +# +# chkconfig: 345 99 01 +# description: Starts/Stops LXC Network Bridge +# +### BEGIN INIT INFO +# Provides: lxc-net +# Default-Start: 2 3 4 5 +# Default-Stop: 1 +# Short-Description: Bring up/down LXC Network Bridge +# Description: Bring up/down LXC Network Bridge +### END INIT INFO + +start() { + @LIBEXECDIR@/lxc/lxc-net start +} + +stop() { + @LIBEXECDIR@/lxc/lxc-net stop +} + +# See how we were called. +case "$1" in + start) + start + ;; + + stop) + stop + ;; + + restart|reload|force-reload) + $0 stop + $0 start + ;; + + *) + echo "Usage: $0 {start|stop|restart|reload|force-reload}" + exit 2 + ;; +esac + +exit $? diff --git a/config/init/upstart/Makefile.am b/config/init/upstart/Makefile.am index 32b90b918..916b85076 100644 --- a/config/init/upstart/Makefile.am +++ b/config/init/upstart/Makefile.am @@ -1,4 +1,4 @@ -EXTRA_DIST = lxc.conf lxc-instance.conf lxc-net.conf +EXTRA_DIST = lxc.conf lxc-instance.conf lxc-net.conf.in if INIT_SCRIPT_UPSTART install-upstart: lxc.conf lxc-instance.conf lxc-net.conf diff --git a/config/init/upstart/lxc-net.conf b/config/init/upstart/lxc-net.conf.in similarity index 57% rename from config/init/upstart/lxc-net.conf rename to config/init/upstart/lxc-net.conf.in index 38f6ea3d3..71c549994 100644 --- a/config/init/upstart/lxc-net.conf +++ b/config/init/upstart/lxc-net.conf.in @@ -4,5 +4,5 @@ author "Serge Hallyn " start on starting lxc stop on stopped lxc -pre-start exec /usr/share/lxc/lxc.net start -post-stop exec /usr/share/lxc/lxc.net stop +pre-start exec @LIBEXECDIR@/lxc/lxc-net start +post-stop exec @LIBEXECDIR@/lxc/lxc-net stop diff --git a/config/sysconfig/Makefile.am b/config/sysconfig/Makefile.am new file mode 100644 index 000000000..3829a01c5 --- /dev/null +++ b/config/sysconfig/Makefile.am @@ -0,0 +1,6 @@ +sysconfigdir="@LXC_DISTRO_SYSCONF@" + +sysconfig_DATA = \ + lxc + +EXTRA_DIST = $(sysconfig_DATA) diff --git a/config/sysconfig/lxc.in b/config/sysconfig/lxc.in new file mode 100644 index 000000000..c5b9aca15 --- /dev/null +++ b/config/sysconfig/lxc.in @@ -0,0 +1,29 @@ +# LXC_AUTO - whether or not to start containers at boot +LXC_AUTO="true" + +# BOOTGROUPS - What groups should start on bootup? +# Comma separated list of groups. +# Leading comma, trailing comma or embedded double +# comma indicates when the NULL group should be run. +# Example (default): boot the onboot group first then the NULL group +BOOTGROUPS="onboot," + +# SHUTDOWNDELAY - Wait time for a container to shut down. +# Container shutdown can result in lengthy system +# shutdown times. Even 5 seconds per container can be +# too long. +SHUTDOWNDELAY=5 + +# OPTIONS can be used for anything else. +# If you want to boot everything then +# options can be "-a" or "-a -A". +OPTIONS= + +# STOPOPTS are stop options. The can be used for anything else to stop. +# If you want to kill containers fast, use -k +STOPOPTS="-a -A -s" + +USE_LXC_BRIDGE="false" # overridden in lxc-net + +[ -f @LXC_DISTRO_SYSCONF@/lxc-net ] && . @LXC_DISTRO_SYSCONF@/lxc-net + diff --git a/configure.ac b/configure.ac index 3e73d4946..7b5458766 100644 --- a/configure.ac +++ b/configure.ac @@ -60,13 +60,16 @@ if test "z$with_distro" = "z"; then fi case $with_distro in ubuntu|raspbian) - distroconf=default.conf.ubuntu + distroconf=default.conf.lxcbr + distrosysconf="$sysconfdir/default" ;; - redhat|centos|fedora|oracle|oracleserver) - distroconf=default.conf.libvirt + redhat|centos|fedora|oracle|oracleserver|suse|opensuse*) + distroconf=default.conf.lxcbr + distrosysconf="$sysconfdir/sysconfig" ;; *) distroconf=default.conf.unknown + distrosysconf="$sysconfdir/default" ;; esac AC_MSG_RESULT([$with_distro]) @@ -84,7 +87,7 @@ AC_ARG_WITH([init-script], case "$with_init_script" in distro) case $with_distro in - fedora) + fedora|opensuse*) init_script=systemd ;; redhat|centos|oracle|oracleserver) @@ -520,6 +523,7 @@ AS_AC_EXPAND(LXCPATH, "$with_config_path") AS_AC_EXPAND(LXC_GLOBAL_CONF, "$with_global_conf") AS_AC_EXPAND(LXC_USERNIC_CONF, "$with_usernic_conf") AS_AC_EXPAND(LXC_USERNIC_DB, "$with_usernic_db") +AS_AC_EXPAND(LXC_DISTRO_SYSCONF, "$distrosysconf") AS_AC_EXPAND(LXCROOTFSMOUNT, "$with_rootfs_path") AS_AC_EXPAND(LXCTEMPLATEDIR, "$datadir/lxc/templates") AS_AC_EXPAND(LXCTEMPLATECONFIG, "$datadir/lxc/config") @@ -602,11 +606,16 @@ AC_CONFIG_FILES([ config/bash/Makefile config/bash/lxc config/init/Makefile - config/init/sysvinit/Makefile - config/init/sysvinit/lxc + config/init/common/Makefile + config/init/common/lxc-containers + config/init/common/lxc-net config/init/systemd/Makefile config/init/systemd/lxc.service config/init/systemd/lxc-net.service + config/init/sysvinit/Makefile + config/init/sysvinit/lxc-containers + config/init/sysvinit/lxc-net + config/init/upstart/lxc-net.conf config/init/upstart/Makefile config/etc/Makefile config/templates/Makefile @@ -636,6 +645,8 @@ AC_CONFIG_FILES([ config/templates/ubuntu.userns.conf config/templates/userns.conf config/yum/Makefile + config/sysconfig/Makefile + config/sysconfig/lxc doc/Makefile doc/api/Makefile diff --git a/lxc.spec.in b/lxc.spec.in index 57912a1fe..52b63268b 100644 --- a/lxc.spec.in +++ b/lxc.spec.in @@ -28,7 +28,16 @@ %if 0%{?fedora} >= 14 || 0%{?rhel} >= 7 || 0%{?suse_version} >= 1210 %global with_systemd 1 %define init_script systemd +# +# BuildRequires systemd-units on fedora and rhel +%if 0%{?fedora} >= 14 || 0%{?rhel} >= 7 BuildRequires: systemd-units +# +# BuildRequires systemd on openSUSE and SUSE +%endif +%if 0%{?suse_version} >= 1210 +BuildRequires: systemd +%endif %else %global with_systemd 0 %define init_script sysvinit @@ -53,8 +62,25 @@ Summary: Linux Containers userspace tools Group: Applications/System License: LGPLv2+ BuildRoot: %{_tmppath}/%{name}-%{version}-build -Requires: openssl rsync -BuildRequires: libcap libcap-devel docbook2X graphviz +Requires: openssl rsync dnsmasq +# Note for Suse. The "docbook2X" BuildRequires does properly +# match docbook2x on Suse in a case insensitive manner +BuildRequires: libcap libcap-devel docbook2X graphviz libxslt pkgconfig + +# +# Additional packages for openSUSE and SUSE +# +%if 0%{?suse_version} >= 1210 +PreReq: permissions +BuildRequires: libapparmor-devel linux-glibc-devel lsb-release docbook-utils + +# +# libseccomp-devel only needed on i386/i586/i686 and X86_64 +# +%ifarch %ix86 x86_64 +BuildRequires: libseccomp-devel +%endif +%endif %if %{with_python} Requires: python3 @@ -104,6 +130,9 @@ PATH=$PATH:/usr/sbin:/sbin %configure $args \ %endif %if %{with_python} --enable-python \ +%endif +%if "x%{_unitdir}" != "x" + --with-systemdsystemunitdir=%{_unitdir} \ %endif --disable-rpath \ --with-init-script=%{init_script} @@ -117,28 +146,102 @@ find %{buildroot} -type f -name '*.la' -exec rm -f {} ';' %clean rm -rf %{buildroot} +%pre +# Ensure that lxcdnsmasq uid & gid gets correctly allocated +if getent passwd lxc-dnsmasq >/dev/null 2>&1 ; then : ; else \ + /usr/sbin/useradd -M -r -s /sbin/nologin \ + -c "LXC Networking Service" -d %_localstatedir/%name lxc-dnsmasq 2> /dev/null \ + || exit 1 +fi + %post +# This test should trigger a network configure on a new install. +if [ ! -f %{_sysconfdir}/sysconfig/lxc-net ] || ! grep -q 'USE_LXC_BRIDGE=' %{_sysconfdir}/sysconfig/lxc-net +then + # Grab a random 10net subnet. Need to add test logic... + while [ true ] + do + SUBNET=10.$(($RANDOM % 256)).$(($RANDOM % 256)) + if ! ip -4 route ls | grep -q "^$SUBNET" + then + break + fi + done + + cat > %{_sysconfdir}/sysconfig/lxc-net </config) for any containers +# already created using the default config to reflect the new bridge +# name. +# If you have the dnsmasq daemon installed, you'll also have to update +# /etc/dnsmasq.d/lxc and restart the system wide dnsmasq daemon. +LXC_BRIDGE="lxcbr0" +LXC_ADDR="$SUBNET.1" +LXC_NETMASK="255.255.255.0" +LXC_NETWORK="$SUBNET.0/24" +LXC_DHCP_RANGE="$SUBNET.2,$SUBNET.254" +LXC_DHCP_MAX="253" +# Uncomment the next line if you'd like to use a conf-file for the lxcbr0 +# dnsmasq. For instance, you can use 'dhcp-host=mail1,10.0.3.100' to have +# container 'mail1' always get ip address 10.0.3.100. +#LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf + +# Uncomment the next line if you want lxcbr0's dnsmasq to resolve the .lxc +# domain. You can then add "server=/lxc/10.0.3.1' (or your actual $LXC_ADDR) +# to /etc/dnsmasq.conf, after which 'container1.lxc' will resolve on your +# host. +#LXC_DOMAIN="lxc" +EOF +fi + %post libs -p /sbin/ldconfig %postun libs -p /sbin/ldconfig %files %defattr(-,root,root) %{_bindir}/* +# openSUSE/SUSE +%if 0%{?suse_version} >= 1210 +%dir %{_sysconfdir}/apparmor.d +%dir %{_sysconfdir}/apparmor.d/abstractions +%dir %{_sysconfdir}/apparmor.d/abstractions/%{name} +%config %{_sysconfdir}/apparmor.d/abstractions/%{name}/container-base +%config %{_sysconfdir}/apparmor.d/abstractions/%{name}/start-container +%config %{_sysconfdir}/apparmor.d/%{name}-containers +%dir %{_sysconfdir}/apparmor.d/%{name} +%config %{_sysconfdir}/apparmor.d/%{name}/%{name}-default +%config %{_sysconfdir}/apparmor.d/%{name}/%{name}-default-with-mounting +%config %{_sysconfdir}/apparmor.d/%{name}/%{name}-default-with-nesting +%config %{_sysconfdir}/apparmor.d/usr.bin.%{name}-start +%endif %{_mandir}/man1/lxc* %{_mandir}/man5/lxc* %{_mandir}/man7/lxc* +# not openSUSE/SUSE +%if %{undefined suse_version} %{_mandir}/ja/man1/lxc* %{_mandir}/ja/man5/lxc* %{_mandir}/ja/man7/lxc* +%endif %{_datadir}/doc/* %{_datadir}/lxc/* %{_sysconfdir}/bash_completion.d +%{_sysconfdir}/sysconfig/* %config(noreplace) %{_sysconfdir}/lxc/* +%config(noreplace) %{_sysconfdir}/sysconfig/* %if %{with_systemd} +%{_unitdir}/lxc-net.service %{_unitdir}/lxc.service %else %{_sysconfdir}/rc.d/init.d/lxc +%{_sysconfdir}/rc.d/init.d/lxc-net %endif %files libs @@ -154,7 +257,8 @@ rm -rf %{buildroot} %attr(4111,root,root) %{_libexecdir}/%{name}/lxc-user-nic %if %{with_systemd} %attr(555,root,root) %{_libexecdir}/%{name}/lxc-devsetup -%attr(555,root,root) %{_libexecdir}/%{name}/lxc-autostart-helper +%attr(555,root,root) %{_libexecdir}/%{name}/lxc-net +%attr(555,root,root) %{_libexecdir}/%{name}/lxc-containers %endif %if %{with_python} diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am index c65a15db9..da3f78e1f 100644 --- a/src/lxc/Makefile.am +++ b/src/lxc/Makefile.am @@ -165,9 +165,8 @@ bin_SCRIPTS = lxc-checkconfig EXTRA_DIST = \ lxc-device \ lxc-ls \ - lxc-top.lua \ - lxc.net \ - lxc-restore-net + lxc-restore-net \ + lxc-top.lua if ENABLE_PYTHON bin_SCRIPTS += lxc-device @@ -256,7 +255,6 @@ endif install-exec-local: install-soPROGRAMS mkdir -p $(DESTDIR)$(datadir)/lxc install -c -m 644 lxc.functions $(DESTDIR)$(datadir)/lxc - install -c -m 755 lxc.net $(DESTDIR)$(datadir)/lxc mv $(DESTDIR)$(libdir)/liblxc.so $(DESTDIR)$(libdir)/liblxc.so.$(VERSION) cd $(DESTDIR)$(libdir); \ ln -sf liblxc.so.$(VERSION) liblxc.so.$(firstword $(subst ., ,$(VERSION))); \ diff --git a/src/lxc/lxc.net b/src/lxc/lxc.net deleted file mode 100755 index 9ec96953d..000000000 --- a/src/lxc/lxc.net +++ /dev/null @@ -1,103 +0,0 @@ -#!/bin/sh -set -eu - -USE_LXC_BRIDGE="true" -LXC_BRIDGE="lxcbr0" -LXC_ADDR="10.0.3.1" -LXC_NETMASK="255.255.255.0" -LXC_NETWORK="10.0.3.0/24" -LXC_DHCP_RANGE="10.0.3.2,10.0.3.254" -LXC_DHCP_MAX="253" -LXC_DHCP_CONFILE="" -varrun="/run/lxc" -LXC_DOMAIN="" - -start() { - [ -f /etc/default/lxc ] && . /etc/default/lxc - - [ "x$USE_LXC_BRIDGE" = "xtrue" ] || { stop; exit 0; } - - use_iptables_lock="-w" - iptables -w -L -n > /dev/null 2>&1 || use_iptables_lock="" - cleanup() { - # dnsmasq failed to start, clean up the bridge - iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p udp --dport 67 -j ACCEPT - iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p tcp --dport 67 -j ACCEPT - iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p udp --dport 53 -j ACCEPT - iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p tcp --dport 53 -j ACCEPT - iptables $use_iptables_lock -D FORWARD -i ${LXC_BRIDGE} -j ACCEPT - iptables $use_iptables_lock -D FORWARD -o ${LXC_BRIDGE} -j ACCEPT - iptables $use_iptables_lock -t nat -D POSTROUTING -s ${LXC_NETWORK} ! -d ${LXC_NETWORK} -j MASQUERADE || true - iptables $use_iptables_lock -t mangle -D POSTROUTING -o ${LXC_BRIDGE} -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill - ifconfig ${LXC_BRIDGE} down || true - brctl delbr ${LXC_BRIDGE} || true - } - - if [ -d /sys/class/net/${LXC_BRIDGE} ]; then - if [ ! -f ${varrun}/network_up ]; then - # bridge exists, but we didn't start it - stop; - fi - exit 0; - fi - - # set up the lxc network - brctl addbr ${LXC_BRIDGE} || { echo "Missing bridge support in kernel"; stop; exit 0; } - echo 1 > /proc/sys/net/ipv4/ip_forward - mkdir -p ${varrun} - ifconfig ${LXC_BRIDGE} ${LXC_ADDR} netmask ${LXC_NETMASK} up - iptables $use_iptables_lock -I INPUT -i ${LXC_BRIDGE} -p udp --dport 67 -j ACCEPT - iptables $use_iptables_lock -I INPUT -i ${LXC_BRIDGE} -p tcp --dport 67 -j ACCEPT - iptables $use_iptables_lock -I INPUT -i ${LXC_BRIDGE} -p udp --dport 53 -j ACCEPT - iptables $use_iptables_lock -I INPUT -i ${LXC_BRIDGE} -p tcp --dport 53 -j ACCEPT - iptables $use_iptables_lock -I FORWARD -i ${LXC_BRIDGE} -j ACCEPT - iptables $use_iptables_lock -I FORWARD -o ${LXC_BRIDGE} -j ACCEPT - iptables $use_iptables_lock -t nat -A POSTROUTING -s ${LXC_NETWORK} ! -d ${LXC_NETWORK} -j MASQUERADE - iptables $use_iptables_lock -t mangle -A POSTROUTING -o ${LXC_BRIDGE} -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill - - LXC_DOMAIN_ARG="" - if [ -n "$LXC_DOMAIN" ]; then - LXC_DOMAIN_ARG="-s $LXC_DOMAIN -S /$LXC_DOMAIN/" - fi - DNSMASQ_USER="lxc-dnsmasq" - if ! getent passwd ${DNSMASQ_USER} >/dev/null; then - DNSMASQ_USER="dnsmasq" - fi - dnsmasq $LXC_DOMAIN_ARG -u ${DNSMASQ_USER} --strict-order --bind-interfaces --pid-file=${varrun}/dnsmasq.pid --conf-file=${LXC_DHCP_CONFILE} --listen-address ${LXC_ADDR} --dhcp-range ${LXC_DHCP_RANGE} --dhcp-lease-max=${LXC_DHCP_MAX} --dhcp-no-override --except-interface=lo --interface=${LXC_BRIDGE} --dhcp-leasefile=/var/lib/misc/dnsmasq.${LXC_BRIDGE}.leases --dhcp-authoritative || cleanup - touch ${varrun}/network_up -} - -stop() { - [ -f /etc/default/lxc ] && . /etc/default/lxc - [ -f "${varrun}/network_up" ] || exit 0; - # if $LXC_BRIDGE has attached interfaces, don't shut it down - ls /sys/class/net/${LXC_BRIDGE}/brif/* > /dev/null 2>&1 && exit 0; - - if [ -d /sys/class/net/${LXC_BRIDGE} ]; then - use_iptables_lock="-w" - iptables -w -L -n > /dev/null 2>&1 || use_iptables_lock="" - ifconfig ${LXC_BRIDGE} down - iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p udp --dport 67 -j ACCEPT - iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p tcp --dport 67 -j ACCEPT - iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p udp --dport 53 -j ACCEPT - iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p tcp --dport 53 -j ACCEPT - iptables $use_iptables_lock -D FORWARD -i ${LXC_BRIDGE} -j ACCEPT - iptables $use_iptables_lock -D FORWARD -o ${LXC_BRIDGE} -j ACCEPT - iptables $use_iptables_lock -t nat -D POSTROUTING -s ${LXC_NETWORK} ! -d ${LXC_NETWORK} -j MASQUERADE || true - iptables $use_iptables_lock -t mangle -D POSTROUTING -o ${LXC_BRIDGE} -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill - pid=`cat ${varrun}/dnsmasq.pid 2>/dev/null` && kill -9 $pid || true - rm -f ${varrun}/dnsmasq.pid - brctl delbr ${LXC_BRIDGE} - fi - rm -f ${varrun}/network_up -} - -if [ "$1" = start ]; then - start -elif [ "$1" = stop ]; then - stop -else - echo "Usage: $0 start|stop" >&2 - exit 1 -fi - -- 2.39.5