From 98e646a8fb214023ab99f661a6ad2550157c6b95 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 1 Jul 2016 11:53:24 +0200 Subject: Merging upstream version 20160701. Signed-off-by: Daniel Baumann --- lib/container/auto | 4 +- lib/container/console | 4 +- lib/container/create | 32 ++++----- lib/container/enter | 96 ++++++++++++++++++++++++++ lib/container/limit | 3 +- lib/container/list | 183 +++++++++++++++----------------------------------- lib/container/remove | 18 +++-- lib/container/rename | 162 ++++++++++++++++++++++++++++++++++++++++++++ lib/container/restart | 4 +- lib/container/start | 10 +-- lib/container/status | 82 ++++++++++++++++++++++ lib/container/stop | 4 +- lib/container/version | 4 +- 13 files changed, 438 insertions(+), 168 deletions(-) create mode 100755 lib/container/enter create mode 100755 lib/container/rename create mode 100755 lib/container/status (limited to 'lib/container') diff --git a/lib/container/auto b/lib/container/auto index 247b667..ac65595 100755 --- a/lib/container/auto +++ b/lib/container/auto @@ -24,8 +24,8 @@ CONFIG="/etc/container-tools/config" Parameters () { - LONG_OPTIONS="start,stop" - OPTIONS="s,t" + LONG_OPTIONS="start,stop," + OPTIONS="s,t," PARAMETERS="$(getopt --longoptions ${LONG_OPTIONS} --name=${COMMAND} --options ${OPTIONS} --shell sh -- ${@})" diff --git a/lib/container/console b/lib/container/console index 779f3a6..84c561d 100755 --- a/lib/container/console +++ b/lib/container/console @@ -24,8 +24,8 @@ MACHINES="/var/lib/machines" Parameters () { - LONG_OPTIONS="name:" - OPTIONS="n:" + LONG_OPTIONS="name:," + OPTIONS="n:," PARAMETERS="$(getopt --longoptions ${LONG_OPTIONS} --name=${COMMAND} --options ${OPTIONS} --shell sh -- ${@})" diff --git a/lib/container/create b/lib/container/create index dea1e76..8080ffa 100755 --- a/lib/container/create +++ b/lib/container/create @@ -22,11 +22,12 @@ COMMAND="$(basename ${0})" CONFIG="/etc/container-tools/config" MACHINES="/var/lib/machines" +SCRIPTS="/usr/share/container-tools/scripts" Parameters () { - LONG_OPTIONS="name:,cnt.auto:,bind:,capability:,drop-capability:script:" - OPTIONS="n:,b:,c:,d:,s:" + 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 -- ${@})" @@ -105,9 +106,9 @@ fi if [ -z "${SCRIPT}" ] then - if [ -e /usr/share/container-tools/scripts/default ] + if [ -e "${SCRIPTS}/default" ] then - TARGET="$(basename $(readlink /usr/share/container-tools/scripts/default))" + TARGET="$(basename $(readlink ${SCRIPTS}/default))" case "${TARGET}" in container-tools_script) @@ -115,7 +116,7 @@ then ;; esac - if [ -e "/usr/share/container-tools/scripts/${TARGET}" ] + if [ -e "${SCRIPTS}/${TARGET}" ] then SCRIPT="${TARGET}" else @@ -126,7 +127,7 @@ then SCRIPT="debian" fi else - if [ ! -e "/usr/share/container-tools/scripts/${SCRIPT}" ] + if [ ! -e "${SCRIPTS}/${SCRIPT}" ] then echo "'${SCRIPT}': no such script" >&2 exit 1 @@ -135,17 +136,18 @@ fi CNT_AUTO="${CNT_AUTO:-$(hostname -f)}" -BINDS="$(echo ${BIND} | sed -e 's|;| |g')" +# Creating bind mounts +if [ -n "${BIND}" ] +then + BINDS="$(echo ${BIND} | sed -e 's|;| |g')" -for ENTRY in ${BINDS} -do - DIRECTORY="$(echo ${ENTRY} | awk -F: '{ print $1 }')" + for BIND in ${BINDS} + do + DIRECTORY="$(echo ${BIND} | awk -F: '{ print $1 }')" - if [ ! -e "${DIRECTORY}" ] - then mkdir -p "${DIRECTORY}" - fi -done + done +fi # config mkdir -p "${CONFIG}" @@ -165,4 +167,4 @@ sed -e "s|@CNT_AUTO@|${CNT_AUTO}|g" \ /usr/share/container-tools/config/container.conf.in > "${CONFIG}/${NAME}.conf" # Run -"/usr/share/container-tools/scripts/${SCRIPT}" $(echo "${@}" | sed -e 's| -- | |') +"${SCRIPTS}/${SCRIPT}" $(echo "${@}" | sed -e 's| -- | |') diff --git a/lib/container/enter b/lib/container/enter new file mode 100755 index 0000000..101b43e --- /dev/null +++ b/lib/container/enter @@ -0,0 +1,96 @@ +#!/bin/sh + +# container-tools - Manage systemd-nspawn containers +# Copyright (C) 2014-2016 Daniel Baumann +# +# 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 . + +set -e + +COMMAND="$(basename ${0})" + +MACHINES="/var/lib/machines" + +Parameters () +{ + LONG_OPTIONS="name:," + OPTIONS="n:," + + 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 + -n|--name) + NAME="${2}" + shift 2 + ;; + + --) + shift 1 + break + ;; + + *) + echo "'${COMMAND}': getopt error" >&2 + exit 1 + ;; + esac + done +} + +Usage () +{ + echo "Usage: container ${COMMAND} -n|--name NAME [-- COMMAND|\"COMMANDS\"]" >&2 + exit 1 +} + +Parameters "${@}" + +if [ -z "${NAME}" ] +then + Usage +fi + +if [ ! -e "${MACHINES}/${NAME}" ] +then + echo "'${NAME}': no such container" >&2 + exit 1 +fi + +STATE="$(machinectl show ${NAME} 2>&1 | awk -F= '/^State=/ { print $2 }')" + +case "${STATE}" in + running) + ;; + + *) + echo "'${NAME}': container is not running" >&2 + exit 1 + ;; +esac + +LEADER="$(machinectl status ${NAME} | awk '/Leader: / { print $2 }')" +COMMANDS="$(echo ${@} | sed -e 's|.*-- ||')" + +# Run +nsenter --target ${LEADER} --mount --uts --ipc --net --pid --root --wd=/root ${COMMANDS} diff --git a/lib/container/limit b/lib/container/limit index c3b0ba8..8b5ffd5 100755 --- a/lib/container/limit +++ b/lib/container/limit @@ -25,8 +25,7 @@ MACHINES="/var/lib/machines" Parameters () { LONG_OPTIONS="name:,blockio-device-weight:,blockio-read-bandwith:,blockio-weight:,blockio-write-bandwith:,cpu-quota:,cpu-shares:,memory-limit:,tasks-max:," - - OPTIONS="n:b:c:m:t:" + OPTIONS="n:b:c:m:t:," PARAMETERS="$(getopt --longoptions ${LONG_OPTIONS} --name=${COMMAND} --options ${OPTIONS} --shell sh -- ${@})" diff --git a/lib/container/list b/lib/container/list index 7f64a18..60ae782 100755 --- a/lib/container/list +++ b/lib/container/list @@ -25,8 +25,8 @@ MACHINES="/var/lib/machines" Parameters () { - LONG_OPTIONS="all,format:,host:,other,started,stopped" - OPTIONS="a,f:,h:,o,s,t" + LONG_OPTIONS="all,format:,host:,other,started,stopped," + OPTIONS="a,f:,h:,o,s,t," PARAMETERS="$(getopt --longoptions ${LONG_OPTIONS} --name=${COMMAND} --options ${OPTIONS} --shell sh -- ${@})" @@ -42,7 +42,7 @@ Parameters () do case "${1}" in -a|--all) - LIST="all" + LIST="${LIST} all" shift 1 ;; @@ -57,17 +57,17 @@ Parameters () ;; -o|--other) - LIST="other" + LIST="${LIST} other" shift 1 ;; -s|--started) - LIST="started" + LIST="${LIST} started" shift 1 ;; -t|--stopped) - LIST="stopped" + LIST="${LIST} stopped" shift 1 ;; @@ -92,7 +92,7 @@ Usage () Parameters "${@}" -LIST="${LIST:-all}" +LIST="${LIST:-started stopped}" FORMAT="${FORMAT:-full}" HOST="${HOST:-$(hostname -f)}" @@ -107,7 +107,7 @@ case "${FORMAT}" in NORMAL="$(tput sgr0)" cat << EOF - Container IPv4 Address(es) +${WHITE} ${NORMAL} Container IPv4 Address(es) -------------------------------------------------------------------------------- EOF @@ -117,6 +117,33 @@ EOF ;; esac +Show () +{ + case "${FORMAT}" in + short) + printf "${CONTAINER}\n" + ;; + + full) + FIRST_LINE="true" + + for ADDRESS in ${ADDRESSES} + do + case "${FIRST_LINE}" in + true) + FIRST_LINE="false" + printf "%-80s %-29s\n" "${STATUS} ${BLUE}${CONTAINER}${NORMAL}" "${YELLOW}${ADDRESS}${NORMAL}" + ;; + + *) + printf "%-80s %-29s\n" "" "${ADDRESS}" + ;; + esac + done + ;; + esac +} + CONTAINERS="$(cd "${MACHINES}" 2>/dev/null && find -maxdepth 1 -type d -and -not -name '.container-tools' -and -not -name 'container-tools' -and -not -name 'lost+found' -and -not -name '.snap' -and -not -name '.snapshot' -printf '%P\n' | sort)" for CONTAINER in ${CONTAINERS} @@ -146,15 +173,9 @@ do STATE="other" fi - if [ -e "${MACHINES}/${CONTAINER}/etc/network/interfaces" ] - then - ADDRESSES="$(awk '/address/ { print $2 }' ${MACHINES}/${CONTAINER}/etc/network/interfaces)" - fi - - ADDRESSES="${ADDRESSES:-n/a}" - case "${STATE}" in running) + STATE="started" STATUS="${GREEN}✔${NORMAL}" ;; @@ -163,128 +184,32 @@ do ;; *) + STATE="stopped" STATUS="${RED}✘${NORMAL}" ;; esac - case "${LIST}" in - all) - case "${FORMAT}" in - short) - printf "${CONTAINER}\n" - ;; - - full) - FIRST_LINE="true" - - for ADDRESS in ${ADDRESSES} - do - case "${FIRST_LINE}" in - true) - FIRST_LINE="false" - printf "%-80s %-29s\n" "${STATUS} ${BLUE}${CONTAINER}${NORMAL}" "${YELLOW}${ADDRESS}${NORMAL}" - ;; - - *) - printf "%-80s %-29s\n" "" "${ADDRESS}" - ;; - esac - done - ;; - esac - ;; + if [ -e "${MACHINES}/${CONTAINER}/etc/network/interfaces" ] + then + ADDRESSES="$(awk '/address/ { print $2 }' ${MACHINES}/${CONTAINER}/etc/network/interfaces)" + fi - other) - case "${STATE}" in - other) - case "${FORMAT}" in - short) - printf "${CONTAINER}\n" - ;; - - full) - FIRST_LINE="true" - - for ADDRESS in ${ADDRESSES} - do - case "${FIRST_LINE}" in - true) - FIRST_LINE="false" - printf "%-80s %-29s\n" "${STATUS} ${BLUE}${CONTAINER}${NORMAL}" "${YELLOW}${ADDRESS}${NORMAL}" - ;; - - *) - printf "%-80s %-29s\n" "" "${ADDRESS}" - ;; - esac - done - ;; - esac - ;; - esac - ;; + ADDRESSES="${ADDRESSES:-n/a}" - started) - case "${STATE}" in - running) - case "${FORMAT}" in - short) - printf "${CONTAINER}\n" - ;; - - full) - FIRST_LINE="true" - - for ADDRESS in ${ADDRESSES} - do - case "${FIRST_LINE}" in - true) - FIRST_LINE="false" - printf "%-80s %-29s\n" "${STATUS} ${BLUE}${CONTAINER}${NORMAL}" "${YELLOW}${ADDRESS}${NORMAL}" - ;; - - *) - printf "%-80s %-29s\n" "" "${ADDRESS}" - ;; - esac - done - ;; - esac - ;; - esac - ;; + if echo ${LIST} | grep -qs all + then + Show + fi - stopped) + for ITEM in other started stopped + do + if echo ${LIST} | grep -qs ${ITEM} + then case "${STATE}" in - running) - ;; - - *) - case "${FORMAT}" in - short) - printf "${CONTAINER}\n" - ;; - - full) - FIRST_LINE="true" - - for ADDRESS in ${ADDRESSES} - do - case "${FIRST_LINE}" in - true) - FIRST_LINE="false" - printf "%-80s %-29s\n" "${STATUS} ${BLUE}${CONTAINER}${NORMAL}" "${YELLOW}${ADDRESS}${NORMAL}" - ;; - - *) - printf "%-80s %-29s\n" "" "${ADDRESS}" - ;; - esac - done - ;; - esac + ${ITEM}) + Show ;; esac - ;; - esac + fi + done done diff --git a/lib/container/remove b/lib/container/remove index 4f26d43..e4bb20c 100755 --- a/lib/container/remove +++ b/lib/container/remove @@ -25,8 +25,8 @@ MACHINES="/var/lib/machines" Parameters () { - LONG_OPTIONS="name:,force" - OPTIONS="n:,f" + LONG_OPTIONS="name:,force," + OPTIONS="n:,f," PARAMETERS="$(getopt --longoptions ${LONG_OPTIONS} --name=${COMMAND} --options ${OPTIONS} --shell sh -- ${@})" @@ -116,13 +116,19 @@ esac # data if [ -e "${CONFIG}/${NAME}.conf" ] then + # Removing bind mounts BIND="$(awk -F= '/^bind=/ { print $2 }' ${CONFIG}/${NAME}.conf)" - DIRECTORY="$(echo ${BIND} | awk -F: '{ print $1 }')" - - if [ -e "${DIRECTORY}" ] + if [ -n "${BIND}" ] then - rmdir --ignore-fail-on-non-empty --parents ${DIRECTORY} || true + BINDS="$(echo ${BIND} | sed -e 's|;| |g')" + + for BIND in ${BINDS} + do + DIRECTORY="$(echo ${BIND} | awk -F: '{ print $1 }')" + + rmdir --ignore-fail-on-non-empty --parents ${DIRECTORY} > /dev/null 2>&1 || true + done fi fi diff --git a/lib/container/rename b/lib/container/rename new file mode 100755 index 0000000..2d27615 --- /dev/null +++ b/lib/container/rename @@ -0,0 +1,162 @@ +#!/bin/sh + +# container-tools - Manage systemd-nspawn containers +# Copyright (C) 2014-2016 Daniel Baumann +# +# 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 . + +set -e + +COMMAND="$(basename ${0})" + +CONFIG="/etc/container-tools/config" +MACHINES="/var/lib/machines" + +Parameters () +{ + LONG_OPTIONS="force,new:,old:," + OPTIONS="f,n:,o:," + + 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 + -f|--force) + FORCE="true" + shift 1 + ;; + + -n|--new) + NEW="${2}" + shift 2 + ;; + + -o|--old) + OLD="${2}" + shift 2 + ;; + + --) + shift 1 + break + ;; + + *) + echo "'${COMMAND}': getopt error" >&2 + exit 1 + ;; + esac + done +} + +Usage () +{ + echo "Usage: container ${COMMAND} [-f|--force] -n|--new NAME -o|--old NAME" >&2 + exit 1 +} + +Parameters "${@}" + +if [ -z "${OLD}" ] || [ -z "${NEW}" ] +then + Usage +fi + +if [ ! -e "${MACHINES}/${OLD}" ] +then + echo "'${OLD}': no such container" >&2 + exit 1 +fi + +if [ ! -e "${MACHINES}/${NEW}" ] +then + echo "'${NEW}': container already exists" >&2 + exit 1 +fi + +STATE="$(machinectl show ${OLD} 2>&1 | awk -F= '/^State=/ { print $2 }')" + +case "${STATE}" in + running) + echo "'${OLD}': container is started" >&2 + exit 1 + ;; +esac + +case "${FORCE}" in + true) + ;; + + *) + if container list --other | grep -qs "^${OLD}$" + then + echo -n "'${OLD}': rename remote container to '${NEW}' [y|N]? " + read FORCE + + FORCE="$(echo ${FORCE} | tr [A-Z] [a-z])" + + case "${FORCE}" in + y|yes) + ;; + + *) + exit 1 + ;; + esac + fi + ;; +esac + +# Run +mv "${CONFIG}/${OLD}.conf" "${CONFIG}/${NEW}.conf" +mv "${MACHINES}/${OLD}" "${MACHINES}/${NEW}" + +# Renaming bind mounts +BIND="$(awk -F= '/^bind=/ { print $2 }' ${CONFIG}/${NAME}.conf)" + +if [ -n "${BIND}" ] +then + BINDS="$(echo ${BIND} | sed -e 's|;| |g')" + + for BIND in ${BINDS} + do + SOURCE_OLD="$(echo ${BIND} | awk -F: '{ print $1 }')" + SOURCE_NEW="$(echo ${SOURCE_OLD} | sed -e "s|${OLD}|${NEW}|g")" + + if [ "${SOURCE_OLD}" != "${SOURCE_NEW}" ] + then + mv "${SOURCE_OLD}" "${SOURCE_NEW}" + fi + + TARGET_OLD="$(echo ${BIND} | awk -F: '{ print $2 }')" + TARGET_NEW="$(echo ${TARGET_OLD} | sed -e "s|${OLD}|${NEW}|g")" + + if [ "${TARGET_OLD}" != "${TARGET_NEW}" ] + then + mv "${MACHINES}/${NEW}/${TARGET_OLD}" "${MACHINES}/${NEW}/${TARGET_NEW}" + fi + done +fi + +# Updating configuration file +sed -i -e "s|${OLD}|${NEW}|g" "${CONFIG}/${NEW}.conf" diff --git a/lib/container/restart b/lib/container/restart index 9b6f18d..295e0de 100755 --- a/lib/container/restart +++ b/lib/container/restart @@ -24,8 +24,8 @@ MACHINES="/var/lib/machines" Parameters () { - LONG_OPTIONS="name:" - OPTIONS="n:" + LONG_OPTIONS="name:," + OPTIONS="n:," PARAMETERS="$(getopt --longoptions ${LONG_OPTIONS} --name=${COMMAND} --options ${OPTIONS} --shell sh -- ${@})" diff --git a/lib/container/start b/lib/container/start index d026bf1..a4dc033 100755 --- a/lib/container/start +++ b/lib/container/start @@ -28,8 +28,8 @@ SYSTEMCTL="true" Parameters () { - LONG_OPTIONS="name:,nspawn,start" - OPTIONS="n:" + LONG_OPTIONS="name:,nspawn,start," + OPTIONS="n:," PARAMETERS="$(getopt --longoptions ${LONG_OPTIONS} --name=${COMMAND} --options ${OPTIONS} --shell sh -- ${@})" @@ -149,11 +149,7 @@ then do DIRECTORY="$(echo ${BIND} | awk -F: '{ print $1 }')" - if [ ! -e "${DIRECTORY}" ] - then - echo "E: '${DIRECTORY}' - no such directory." >&2 - exit 1 - fi + mkdir -p "${DIRECTORY}" done BIND="" diff --git a/lib/container/status b/lib/container/status new file mode 100755 index 0000000..a41d005 --- /dev/null +++ b/lib/container/status @@ -0,0 +1,82 @@ +#!/bin/sh + +# container-tools - Manage systemd-nspawn containers +# Copyright (C) 2016 Simon Spöehel +# +# 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 . + +set -e + +COMMAND="$(basename ${0})" + +CONFIG="/etc/container-tools/config" +MACHINES="/var/lib/machines" + +Parameters () +{ + LONG_OPTIONS="name:," + OPTIONS="n:," + + 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 + -n|--name) + NAME="${2}" + shift 2 + ;; + + --) + shift 1 + break + ;; + + *) + echo "'${COMMAND}': getopt error" >&2 + exit 1 + ;; + esac + done +} + +Usage () +{ + echo "Usage: container ${COMMAND} -n|--name NAME" >&2 + exit 1 +} + +Parameters "${@}" + +if [ -z "${NAME}" ] +then + Usage +fi + +if [ ! -e "${MACHINES}/${NAME}" ] +then + echo "'${NAME}': no such container" >&2 + exit 1 +fi + +# Run +systemctl status container@${NAME}.service diff --git a/lib/container/stop b/lib/container/stop index fb470f6..dc78f05 100755 --- a/lib/container/stop +++ b/lib/container/stop @@ -27,8 +27,8 @@ CLEAN="false" Parameters () { - LONG_OPTIONS="name:,force,clean" - OPTIONS="n:,f" + LONG_OPTIONS="name:,force,clean," + OPTIONS="n:,f," PARAMETERS="$(getopt --longoptions ${LONG_OPTIONS} --name=${COMMAND} --options ${OPTIONS} --shell sh -- ${@})" diff --git a/lib/container/version b/lib/container/version index b7e259d..b57c17d 100755 --- a/lib/container/version +++ b/lib/container/version @@ -18,4 +18,6 @@ set -e -cat /usr/share/container-tools/VERSION.txt +SHARE="/usr/share/container-tools" + +cat "${SHARE}/VERSION.txt" -- cgit v1.2.3