summaryrefslogtreecommitdiffstats
path: root/lib/container
diff options
context:
space:
mode:
Diffstat (limited to 'lib/container')
-rwxr-xr-xlib/container/auto90
-rwxr-xr-xlib/container/create16
-rwxr-xr-xlib/container/list54
-rwxr-xr-xlib/container/start102
-rwxr-xr-xlib/container/stop41
5 files changed, 268 insertions, 35 deletions
diff --git a/lib/container/auto b/lib/container/auto
new file mode 100755
index 0000000..247b667
--- /dev/null
+++ b/lib/container/auto
@@ -0,0 +1,90 @@
+#!/bin/sh
+
+# container-tools - Manage systemd-nspawn containers
+# Copyright (C) 2014-2016 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+set -e
+
+COMMAND="$(basename ${0})"
+
+CONFIG="/etc/container-tools/config"
+
+Parameters ()
+{
+ LONG_OPTIONS="start,stop"
+ OPTIONS="s,t"
+
+ PARAMETERS="$(getopt --longoptions ${LONG_OPTIONS} --name=${COMMAND} --options ${OPTIONS} --shell sh -- ${@})"
+
+ if [ "${?}" != "0" ]
+ then
+ echo "'${COMMAND}': getopt exit" >&2
+ exit 1
+ fi
+
+ eval set -- "${PARAMETERS}"
+
+ while true
+ do
+ case "${1}" in
+ -s|--start)
+ ACTION="start"
+ shift 1
+ ;;
+
+ -t|--stop)
+ ACTION="stop"
+ shift 1
+ ;;
+
+ --)
+ shift 1
+ break
+ ;;
+
+ *)
+ echo "'${COMMAND}': getopt error" >&2
+ exit 1
+ ;;
+ esac
+ done
+}
+
+Usage ()
+{
+ echo "Usage: container ${COMMAND} -s|--start -t|--stop" >&2
+ exit 1
+}
+
+Parameters "${@}"
+
+if [ -z "${ACTION}" ]
+then
+ Usage
+fi
+
+HOST="$(hostname -f)"
+
+# Run
+for FILE in "${CONFIG}"/*.conf
+do
+ if grep -Eqs "^ *cnt.auto=true" "${FILE}" || grep -Eqs "^ *cnt.auto=${HOST}" "${FILE}"
+ then
+ CONTAINER="$(basename ${FILE} .conf)"
+
+ cnt ${ACTION} -n ${CONTAINER} || true
+ fi
+done
diff --git a/lib/container/create b/lib/container/create
index fab9f5b..0b0aa3a 100755
--- a/lib/container/create
+++ b/lib/container/create
@@ -25,7 +25,7 @@ MACHINES="/var/lib/machines"
Parameters ()
{
- LONG_OPTIONS="name:,cnt.autostart:,bind:,capability:,drop-capability:script:"
+ LONG_OPTIONS="name:,cnt.auto:,bind:,capability:,drop-capability:script:"
OPTIONS="n:,b:,c:,d:,s:"
PARAMETERS="$(getopt --longoptions ${LONG_OPTIONS} --name=${COMMAND} --options ${OPTIONS} --shell sh -- ${@})"
@@ -46,8 +46,8 @@ Parameters ()
shift 2
;;
- --cnt.autostart)
- CNT_AUTOSTART="${2}"
+ --cnt.auto)
+ CNT_AUTO="${2}"
shift 2
;;
@@ -86,7 +86,7 @@ Parameters ()
Usage ()
{
- echo "Usage: container ${COMMAND} -n|--name NAME [--cnt.autostart=true|false|FQDN] [-b|--bind DIRECTORY:DIRECTORY[:OPTIONS]] [-c|--capability CAPABILITY[,CAPABILITY]] [-d|--drop-capability DROP_CAPABILITY[,DROP_CAPABILITY]] [-s|--script SCRIPT] [-- SCRIPT_OPTIONS]" >&2
+ echo "Usage: container ${COMMAND} -n|--name NAME [--cnt.auto=true|false|FQDN] [-b|--bind DIRECTORY:DIRECTORY[:OPTIONS]] [-c|--capability CAPABILITY[,CAPABILITY]] [-d|--drop-capability DROP_CAPABILITY[,DROP_CAPABILITY]] [-s|--script SCRIPT] [-- SCRIPT_OPTIONS]" >&2
exit 1
}
@@ -110,7 +110,7 @@ then
echo "'${SCRIPT}': no such script" >&2
fi
-CNT_AUTOSTART="${CNT_AUTOSTART:-$(hostname -f)}"
+CNT_AUTO="${CNT_AUTO:-$(hostname -f)}"
BINDS="$(echo ${BIND} | sed -e 's|;| |g')"
@@ -127,7 +127,8 @@ done
# config
mkdir -p "${CONFIG}"
-sed -e "s|@CNT_AUTOSTART@|${CNT_AUTOSTART}|g" \
+sed -e "s|@CNT_AUTO@|${CNT_AUTO}|g" \
+ -e "s|@CNT_NETWORK_BRIDGE@|${CNT_NETWORK_BRIDGE}|g" \
-e "s|@NAME@|${NAME}|g" \
-e "s|@BIND@|${BIND}|g" \
-e "s|@BOOT@|yes|g" \
@@ -135,8 +136,7 @@ sed -e "s|@CNT_AUTOSTART@|${CNT_AUTOSTART}|g" \
-e "s|@DIRECTORY@|${MACHINES}/${NAME}|g" \
-e "s|@DROP_CAPABILITY@|${DROP_CAPABILITY}|g" \
-e "s|@MACHINE@|${NAME}|g" \
- -e "s|@NETWORK_VETH@|yes|g" \
- -e "s|@NETWORK_BRIDGE@|br0|g" \
+ -e "s|@NETWORK_VETH_EXTRA@|${NETWORK_VETH_EXTRA}|g" \
-e "s|@LINK_JOURNAL@|no|g" \
-e "s|@REGISTER@|yes|g" \
/usr/share/container-tools/config/container.conf.in > "${CONFIG}/${NAME}.conf"
diff --git a/lib/container/list b/lib/container/list
index 5ab5755..8b55e09 100755
--- a/lib/container/list
+++ b/lib/container/list
@@ -94,7 +94,7 @@ case "${FORMAT}" in
NORMAL="$(tput sgr0)"
cat << EOF
-Container IPv4 Address Status
+Container IPv4 Address(es) Status
--------------------------------------------------------------------------------
EOF
@@ -118,9 +118,9 @@ do
if [ -e "${MACHINES}/${CONTAINER}/etc/network/interfaces" ]
then
- ADDRESS="$(awk '/address/ { print $2 }' ${MACHINES}/${CONTAINER}/etc/network/interfaces)"
+ ADDRESSES="$(awk '/address/ { print $2 }' ${MACHINES}/${CONTAINER}/etc/network/interfaces)"
else
- ADDRESS="n/a"
+ ADDRESSES="n/a"
fi
case "${STATE}" in
@@ -142,7 +142,21 @@ do
;;
full)
- printf "%-72s %-29s %-7s\n" "${BLUE}${CONTAINER}${NORMAL}" "${YELLOW}${ADDRESS}${NORMAL}" "${STATUS}"
+ FIRST_LINE="true"
+
+ for ADDRESS in ${ADDRESSES}
+ do
+ case "${FIRST_LINE}" in
+ true)
+ FIRST_LINE="false"
+ printf "%-69s %-29s %-7s\n" "${BLUE}${CONTAINER}${NORMAL}" "${YELLOW}${ADDRESS}${NORMAL}" " ${STATUS}"
+ ;;
+
+ *)
+ printf "%-54s %-29s\n" "" "${ADDRESS}"
+ ;;
+ esac
+ done
;;
esac
;;
@@ -156,7 +170,21 @@ do
;;
full)
- printf "%-72s %-29s %-7s\n" "${BLUE}${CONTAINER}${NORMAL}" "${YELLOW}${ADDRESS}${NORMAL}" "${STATUS}"
+ FIRST_LINE="true"
+
+ for ADDRESS in ${ADDRESSES}
+ do
+ case "${FIRST_LINE}" in
+ true)
+ FIRST_LINE="false"
+ printf "%-69s %-29s %-7s\n" "${BLUE}${CONTAINER}${NORMAL}" "${YELLOW}${ADDRESS}${NORMAL}" " ${STATUS}"
+ ;;
+
+ *)
+ printf "%-54s %-29s\n" "" "${ADDRESS}"
+ ;;
+ esac
+ done
;;
esac
;;
@@ -175,7 +203,21 @@ do
;;
full)
- printf "%-72s %-29s %-7s\n" "${BLUE}${CONTAINER}${NORMAL}" "${YELLOW}${ADDRESS}${NORMAL}" "${STATUS}"
+ FIRST_LINE="true"
+
+ for ADDRESS in ${ADDRESSES}
+ do
+ case "${FIRST_LINE}" in
+ true)
+ FIRST_LINE="false"
+ printf "%-69s %-29s %-7s\n" "${BLUE}${CONTAINER}${NORMAL}" "${YELLOW}${ADDRESS}${NORMAL}" " ${STATUS}"
+ ;;
+
+ *)
+ printf "%-54s %-29s\n" "" "${ADDRESS}"
+ ;;
+ esac
+ done
;;
esac
;;
diff --git a/lib/container/start b/lib/container/start
index 8d5429b..d026bf1 100755
--- a/lib/container/start
+++ b/lib/container/start
@@ -23,9 +23,12 @@ COMMAND="$(basename ${0})"
CONFIG="/etc/container-tools/config"
MACHINES="/var/lib/machines"
+START="false"
+SYSTEMCTL="true"
+
Parameters ()
{
- LONG_OPTIONS="name:"
+ LONG_OPTIONS="name:,nspawn,start"
OPTIONS="n:"
PARAMETERS="$(getopt --longoptions ${LONG_OPTIONS} --name=${COMMAND} --options ${OPTIONS} --shell sh -- ${@})"
@@ -46,6 +49,19 @@ Parameters ()
shift 2
;;
+ --nspawn)
+ # internal option
+ SYSTEMCTL="false"
+ shift 1
+ ;;
+
+ --start)
+ # internal option
+ START="true"
+ SYSTEMCTL="false"
+ shift 1
+ ;;
+
--)
shift 1
break
@@ -78,12 +94,16 @@ then
exit 1
fi
-STATE="$(machinectl show ${NAME} 2>&1 | awk -F= '/^State=/ { print $2 }')"
+case "${START}" in
+ false)
+ STATE="$(machinectl show ${NAME} 2>&1 | awk -F= '/^State=/ { print $2 }')"
-case "${STATE}" in
- running)
- echo "'${NAME}': container is already started" >&2
- exit 1
+ case "${STATE}" in
+ running)
+ echo "'${NAME}': container is already started" >&2
+ exit 1
+ ;;
+ esac
;;
esac
@@ -185,27 +205,58 @@ then
MACHINE="--machine=${NAME}"
- NETWORK_BRIDGE="$(awk -F= '/^network-bridge=/ { print $2 }' ${CONFIG}/${NAME}.conf)"
+ NETWORK_VETH_EXTRA_CONF="$(awk -F= '/^network-veth-extra=/ { print $2 }' ${CONFIG}/${NAME}.conf)"
+ NETWORK_VETH_EXTRA=""
- case "${NETWORK_BRIDGE}" in
+ case "${NETWORK_VETH_EXTRA_CONF}" in
"")
- NETWORK_BRIDGE=""
;;
*)
- NETWORK_BRIDGE="--network-bridge=${NETWORK_BRIDGE}"
+ for VETH in ${NETWORK_VETH_EXTRA_CONF}
+ do
+ NETWORK_VETH_EXTRA="${NETWORK_VETH_EXTRA} --network-veth-extra=${VETH}"
+ INTERFACE="$(echo ${VETH} | awk -F: '{ print $1 }')"
+
+cat > "/etc/network/interfaces.d/${INTERFACE}" << EOF
+allow-hotplug ${INTERFACE}
+iface ${INTERFACE} inet manual
+ pre-up ifconfig ${INTERFACE} up
+ post-down ifconfig ${INTERFACE} down
+EOF
+
+ done
;;
esac
- NETWORK_VETH="$(awk -F= '/^network-veth=/ { print $2 }' ${CONFIG}/${NAME}.conf || echo yes)"
+ NETWORK_BRIDGES="$(awk -F= '/^cnt.network-bridge=/ { print $2 }' ${CONFIG}/${NAME}.conf)"
- case "${NETWORK_VETH}" in
- yes)
- NETWORK_VETH="--network-veth"
+ case "${NETWORK_BRIDGES}" in
+ "")
;;
*)
- NETWORK_VETH=""
+ for BRIDGE_DEFINITION in ${NETWORK_BRIDGES}
+ do
+ INTERFACE="$(echo ${BRIDGE_DEFINITION} | awk -F: '{ print $1 }')"
+ BRIDGE="$(echo ${BRIDGE_DEFINITION} | awk -F: '{ print $2 }')"
+
+ if [ -n "${BRIDGE}" ] && [ -n "${INTERFACE}" ]
+ then
+
+cat > "/etc/network/interfaces.d/${INTERFACE}" << EOF
+allow-hotplug ${INTERFACE}
+iface ${INTERFACE} inet manual
+ pre-up ifconfig ${INTERFACE} up
+ post-up brctl addif ${BRIDGE} ${INTERFACE}
+ pre-down brctl delif ${BRIDGE} ${INTERFACE}
+ post-down ifconfig ${INTERFACE} down
+EOF
+
+ else
+ echo "Warning bridge definition '${BRIDGE_DEFINITION}' not recognized (expected <bridge>:<interface>): Ignoring"
+ fi
+ done
;;
esac
@@ -298,14 +349,25 @@ then
fi
fi
-# Run
-case "${SET_PROPERTY}" in
+case "${SYSTEMCTL}" in
true)
- ${SETARCH} systemd-nspawn ${BIND} ${BOOT} ${CAPABILITY} ${DIRECTORY} ${DROP_CAPABILITY} ${MACHINE} ${NETWORK_BRIDGE} ${NETWORK_VETH} ${LINK_JOURNAL} ${REGISTER} & \
- systemctl --runtime set-property ${NAME} ${BLOCK_IO_DEVICE_WEIGHT} ${BLOCK_IO_READ_BANDWITH} ${BLOCK_IO_WEIGHT} ${BLOCK_IO_WRITE_BANDWITH} ${CPU_QUOTA} ${CPU_SHARES} ${MEMORY_LIMIT} ${TASKS_MAX}
+ systemctl start container@${NAME}.service
+ # FIXME start console .. after sleep? + configuration option
+ exit 0
+ ;;
+esac
+
+case "${START}" in
+ true)
+ case "${SET_PROPERTY}" in
+ true)
+ systemctl --runtime set-property ${NAME} ${BLOCK_IO_DEVICE_WEIGHT} ${BLOCK_IO_READ_BANDWITH} ${BLOCK_IO_WEIGHT} ${BLOCK_IO_WRITE_BANDWITH} ${CPU_QUOTA} ${CPU_SHARES} ${MEMORY_LIMIT} ${TASKS_MAX}
+ ;;
+ esac
;;
*)
- ${SETARCH} systemd-nspawn ${BIND} ${BOOT} ${CAPABILITY} ${DIRECTORY} ${DROP_CAPABILITY} ${MACHINE} ${NETWORK_BRIDGE} ${NETWORK_VETH} ${LINK_JOURNAL} ${REGISTER}
+ # Run
+ ${SETARCH} systemd-nspawn --keep-unit ${BIND} ${BOOT} ${CAPABILITY} ${DIRECTORY} ${DROP_CAPABILITY} ${MACHINE} ${NETWORK_VETH_EXTRA} ${LINK_JOURNAL} ${REGISTER}
;;
esac
diff --git a/lib/container/stop b/lib/container/stop
index cd3de10..67cc403 100755
--- a/lib/container/stop
+++ b/lib/container/stop
@@ -20,11 +20,14 @@ set -e
COMMAND="$(basename ${0})"
+CONFIG="/etc/container-tools/config"
MACHINES="/var/lib/machines"
+CLEAN="false"
+
Parameters ()
{
- LONG_OPTIONS="name:,force"
+ LONG_OPTIONS="name:,force,clean"
OPTIONS="n:,f"
PARAMETERS="$(getopt --longoptions ${LONG_OPTIONS} --name=${COMMAND} --options ${OPTIONS} --shell sh -- ${@})"
@@ -49,6 +52,12 @@ Parameters ()
FORCE="true"
;;
+ --clean)
+ # internal option
+ CLEAN="true"
+ shift 1
+ ;;
+
--)
shift 1
break
@@ -83,6 +92,36 @@ fi
STATE="$(machinectl show ${NAME} 2>&1 | awk -F= '/^State=/ { print $2 }')"
+# Removing network configuration
+case "${CLEAN}" in
+ true)
+ NETWORK_VETH_EXTRA_CONF="$(awk -F= '/^network-veth-extra=/ { print $2 }' ${CONFIG}/${NAME}.conf)"
+
+ case "${NETWORK_VETH_EXTRA_CONF}" in
+ "")
+ ;;
+
+ *)
+ for VETH in ${NETWORK_VETH_EXTRA_CONF}
+ do
+ INTERFACE="$(echo ${VETH} | awk -F: '{ print $1 }')"
+ FILE="/etc/network/interfaces.d/${INTERFACE}"
+
+ if [ -f "${FILE}" ]
+ then
+ rm -f "${FILE}"
+ fi
+ done
+ ;;
+ esac
+
+ exit 0
+ ;;
+
+ *)
+ ;;
+esac
+
case "${STATE}" in
running)
;;