From 8f2239e2955c8177b4c69418efa12831ceb2e872 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 29 Apr 2019 20:17:45 +0200 Subject: Adding container run command to execute programs within containers. Signed-off-by: Daniel Baumann --- lib/container/run | 127 ++++++++++++++++++++++++++++++++++++++++++ share/man/container-run.1.txt | 80 ++++++++++++++++++++++++++ share/man/container.1.txt | 3 + 3 files changed, 210 insertions(+) create mode 100755 lib/container/run create mode 100644 share/man/container-run.1.txt diff --git a/lib/container/run b/lib/container/run new file mode 100755 index 0000000..f6323c0 --- /dev/null +++ b/lib/container/run @@ -0,0 +1,127 @@ +#!/bin/sh + +# Copyright (C) 2014-2019 Daniel Baumann +# +# SPDX-License-Identifier: GPL-3.0+ +# +# 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 + +PROJECT="open-infrastructure" +PROGRAM="container" +COMMAND="$(basename ${0})" + +HOOKS="/etc/${PROJECT}/${PROGRAM}/hooks" +MACHINES="/var/lib/machines" + +Parameters () +{ + GETOPT_LONGOPTIONS="name:," + GETOPT_OPTIONS="n:," + + PARAMETERS="$(getopt --longoptions ${GETOPT_LONGOPTIONS} --name=${COMMAND} --options ${GETOPT_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: ${PROGRAM} ${COMMAND} -n|--name NAME -- COMMAND" >&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 }')" + +# Pre hooks +for FILE in "${HOOKS}/pre-${COMMAND}".* "${HOOKS}/${NAME}.pre-${COMMAND}" +do + if [ -x "${FILE}" ] + then + "${FILE}" + fi +done + +SSH_CLIENT="${SSH_CLIENT:-127.0.0.1 0 0}" + +RUN="$(echo ${@} | awk -F-- '{ print $2}')" + +# Run +nsenter --all --target "${LEADER}" --wd="${MACHINES}/${NAME}/root" /usr/bin/script -c "LC_ALL=C.UTF-8 /bin/bash -l -c \"${RUN}\"" -q /dev/null + +case "${SSH_CLIENT}" in + 127.0.0.1*) + unset SSH_CLIENT + ;; +esac + +# Post hooks +for FILE in "${HOOKS}/post-${COMMAND}".* "${HOOKS}/${NAME}.post-${COMMAND}" +do + if [ -x "${FILE}" ] + then + "${FILE}" + fi +done diff --git a/share/man/container-run.1.txt b/share/man/container-run.1.txt new file mode 100644 index 0000000..8a713a5 --- /dev/null +++ b/share/man/container-run.1.txt @@ -0,0 +1,80 @@ +// Copyright (C) 2014-2020 Daniel Baumann +// +// SPDX-License-Identifier: GPL-3.0+ +// +// 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 . + +CONTAINER-RUN(1) +================ +:doctype: manpage +:man manual: Open Infrastructure +:man source: compute-tools +:man version: {revnumber} + + +NAME +---- +container-run - Execute commands in a container namespace + + +SYNOPSIS +-------- +*container run* ['OPTIONS'] -- COMMAND +*cnt r* ['OPTIONS'] -- COMMAND + + +DESCRIPTION +----------- +The container run command executes arbitrary commands as root in a container namespace. + + +OPTIONS +------- +The following container options are available: + +*-n, --name='NAME'*:: + Specify container name. Specifying 'ALL' will start all stopped container. + + +EXAMPLES +-------- +*Run 'hostname' in example.net container:*:: + sudo container run -n example.net -- hostname + +*Create and delete a file in example.net container:*:: + sudo container run -n example.net -- 'touch /tmp/foo && rm -f /tmp/foo' + + +SEE ALSO +-------- +compute-tools(7), +container(1). + + +HOMEPAGE +-------- +More information about compute-tools and the Open Infrastructure project can be found on the homepage at https://open-infrastructure.net. + + +CONTACT +------- +Bug reports, feature requests, help, patches, support and everything else +are welcome on the Open Infrastructure Software Mailing List . + +Debian specific bugs can also be reported in the Debian Bug Tracking System at https://bugs.debian.org. + + +AUTHORS +------- +compute-tools were written by Daniel Baumann and others. diff --git a/share/man/container.1.txt b/share/man/container.1.txt index 02cdc64..c0fd182 100644 --- a/share/man/container.1.txt +++ b/share/man/container.1.txt @@ -75,6 +75,9 @@ The following container commands are available: *enter*:: Enter a container namespace, see container-enter(1). +*run*:: + Execute commands in a container namespace, see container-run(1). + *key*:: Manage GnuPG keyring for container operations, see container-key(1). -- cgit v1.2.3