From 0861a2ffbea2812d95ac3f1cb7a1bc803ab8165c Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 25 Jul 2021 11:08:01 +0200 Subject: Adding container get command. Signed-off-by: Daniel Baumann --- Makefile | 1 + libexec/container/get | 284 ++++++++++++++++++++++++++++++++++++++++ share/bash-completion/container | 22 ++++ share/hooks/pre-get.git-pull.sh | 50 +++++++ share/man/container-build.1.rst | 4 - share/man/container-get.1.rst | 130 ++++++++++++++++++ 6 files changed, 487 insertions(+), 4 deletions(-) create mode 100755 libexec/container/get create mode 100755 share/hooks/pre-get.git-pull.sh create mode 100644 share/man/container-get.1.rst diff --git a/Makefile b/Makefile index 1bb8093..47f8df5 100644 --- a/Makefile +++ b/Makefile @@ -124,6 +124,7 @@ install: build ln -sf container-build-debootstrap.1 $(DESTDIR)/usr/share/man/man1/container-build-mmdebstrap.1 ln -sf build $(DESTDIR)/usr/libexec/$(PROGRAM)/b + ln -sf get $(DESTDIR)/usr/libexec/$(PROGRAM)/g ln -sf list $(DESTDIR)/usr/libexec/$(PROGRAM)/ls ln -sf move $(DESTDIR)/usr/libexec/$(PROGRAM)/mv ln -sf remove $(DESTDIR)/usr/libexec/$(PROGRAM)/rm diff --git a/libexec/container/get b/libexec/container/get new file mode 100755 index 0000000..1005f89 --- /dev/null +++ b/libexec/container/get @@ -0,0 +1,284 @@ +#!/bin/sh + +# Copyright (C) 2014-2021 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" +SOFTWARE="compute-tools" +PROGRAM="container" +COMMAND="$(basename ${0})" + +CONFIG="/etc/${SOFTWARE}/config" +HOOKS="/etc/${SOFTWARE}/hooks" +MACHINES="/var/lib/machines" +SCRIPTS="/usr/share/${SOFTWARE}/get-scripts" +CONFIG_TEMPLATE="/usr/share/${SOFTWARE}/config/container.conf.in" + +Parameters () +{ + GETOPT_LONGOPTIONS="name:,cnt.container-server:,cnt.overlay:,cnt.overlay-options:,start:,bind:,bind-ro:,capability:,drop-capability:,script:,verbose," + GETOPT_OPTIONS="n:,b:,c:,d:,s:,v," + + 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 + ;; + + --cnt.auto) + CNT_AUTO="${2}" + shift 2 + ;; + + --cnt.container-server) + CNT_CONTAINER_SERVER="${2}" + shift 2 + ;; + + --cnt.overlay) + CNT_OVERLAY="${2}" + shift 2 + ;; + + --cnt.overlay-options) + CNT_OVERLAY_OPTIONS="${2}" + shift 2 + ;; + + --cnt.start) + CNT_START="${2}" + shift 2 + ;; + + -b|--bind) + BIND="${2}" + shift 2 + ;; + + --bind-ro) + BIND_RO="${2}" + shift 2 + ;; + + -c|--capability) + CAPABILITY="${2}" + shift 2 + ;; + + -d|--drop-capability) + DROP_CAPABILITY="${2}" + shift 2 + ;; + + -s|--script) + SCRIPT="${2}" + shift 2 + ;; + + -v|--verbose) + VERBOSE="true" + shift 1 + ;; + + --) + shift 1 + break + ;; + + *) + echo "'${COMMAND}': getopt error" >&2 + exit 1 + ;; + esac + done +} + +Usage () +{ + echo "Usage: ${PROGRAM} ${COMMAND} -n|--name NAME [--cnt.container-server=true|false|FQDN] [--cnt.overlay=DIRECTORY_LOWER:DIRECTORY_UPPER:DIRECTORY_WORK:DIRECTORY_MERGED] [--cnt.overlay-options=OPTION[,OPTION]] [--cnt.start=OPTION[,OPTION]] [-b|--bind DIRECTORY:DIRECTORY[:OPTIONS]] [--bind-ro DIRECTORY:DIRECTORY[:OPTIONS]] [-c|--capability CAPABILITY[,CAPABILITY]] [-d|--drop-capability DROP_CAPABILITY[,DROP_CAPABILITY]] [-s|--script SCRIPT] [-v|--verbose] [-- SCRIPT_OPTIONS]" >&2 + exit 1 +} + +Parameters "${@}" + +if [ -z "${NAME}" ] +then + Usage +fi + +case "${NAME}" in + ALL) + echo "'${NAME}': name 'ALL' is reserved to expand to all available container" >&2 + exit 1 + ;; +esac + +if [ -e "${CONFIG}/${NAME}.conf" ] +then + echo "'${NAME}': container already exists or ${CONFIG}/${NAME}.conf has not been removed" >&2 + exit 1 +fi + +if [ -z "${SCRIPT}" ] +then + if [ -e "${SCRIPTS}/default" ] + then + TARGET="$(basename $(readlink ${SCRIPTS}/default))" + + case "${TARGET}" in + container_get-script) + TARGET="$(basename $(readlink /etc/alternatives/container_get-script))" + ;; + esac + + if [ -e "${SCRIPTS}/${TARGET}" ] + then + SCRIPT="${TARGET}" + else + echo "default -> '${TARGET}': no such script" >&2 + exit 1 + fi + else + SCRIPT="curl" + fi +else + if [ ! -e "${SCRIPTS}/${SCRIPT}" ] + then + echo "'${SCRIPT}': no such script" >&2 + exit 1 + fi +fi + +case "${VERBOSE}" in + true) + +cat << EOF +################################################################################ +Building container: ${NAME} +################################################################################ +EOF + + ;; +esac + +CNT_CONTAINER_SERVER="${CNT_CONTAINER_SERVER:-$(hostname -f 2> /dev/null || hostname)}" + +# Pre hooks +for FILE in "${HOOKS}/pre-${COMMAND}".* "${HOOKS}/${NAME}.pre-${COMMAND}" +do + if [ -x "${FILE}" ] + then + "${FILE}" + fi +done + +# Creating rw 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 }')" + + mkdir -p "${DIRECTORY}" + done +fi + +# Creating ro bind mounts +if [ -n "${BIND_RO}" ] +then + BINDS_RO="$(echo ${BIND_RO} | sed -e 's|;| |g')" + + for ENTRY in ${BINDS_RO} + do + DIRECTORY="$(echo ${ENTRY} | awk -F: '{ print $1 }')" + + mkdir -p "${DIRECTORY}" + done +fi + +# Creating overlay mounts +if [ -n "${CNT_OVERLAY}" ] +then + CNT_OVERLAYS="$(echo ${CNT_OVERLAY} | sed -e 's|;| |g')" + + for ENTRY in ${CNT_OVERLAYS} + do + DIRECTORY_LOWER="$(echo ${ENTRY} | awk -F: '{ print $1 }')" + DIRECTORY_UPPER="$(echo ${ENTRY} | awk -F: '{ print $2 }')" + DIRECTORY_WORK="$(echo ${ENTRY} | awk -F: '{ print $3 }')" + DIRECTORY_MERGED="$(echo ${ENTRY} | awk -F: '{ print $4 }')" + + for DIRECTORY in "${DIRECTORY_LOWER}" "${DIRECTORY_UPPER}" "${DIRECTORY_WORK}" "${DIRECTORY_MERGED}" + do + mkdir -p "${DIRECTORY}" + done + done +fi + +# config +mkdir -p "${CONFIG}" + +sed -e "s|@CNT_AUTO@|${CNT_AUTO}|g" \ + -e "s|@CNT_CONTAINER_SERVER@|${CNT_CONTAINER_SERVER}|g" \ + -e "s|@CNT_NETWORK_BRIDGE@|${CNT_NETWORK_BRIDGE}|g" \ + -e "s|@CNT_OVERLAY@|${CNT_OVERLAY}|g" \ + -e "s|@CNT_OVERLAY_OPTIONS@|${CNT_OVERLAY_OPTIONS}|g" \ + -e "s|@CNT_START@|${CNT_START}|g" \ + -e "s|@NAME@|${NAME}|g" \ + -e "s|@BIND@|${BIND}|g" \ + -e "s|@BIND_RO@|${BIND_RO}|g" \ + -e "s|@BOOT@|yes|g" \ + -e "s|@CAPABILITY@|${CAPABILITY}|g" \ + -e "s|@DIRECTORY@|${MACHINES}/${NAME}|g" \ + -e "s|@DROP_CAPABILITY@|${DROP_CAPABILITY}|g" \ + -e "s|@LINK_JOURNAL@|no|g" \ + -e "s|@MACHINE@|${NAME}|g" \ + -e "s|@NETWORK_VETH_EXTRA@|${NETWORK_VETH_EXTRA}|g" \ + -e "s|@PRIVATE_USERS@|no|g" \ + -e "s|@REGISTER@|yes|g" \ +"${CONFIG_TEMPLATE}" > "${CONFIG}/${NAME}.conf" + +# Run +"${SCRIPTS}/${SCRIPT}" $(echo "${@}" | sed -e 's| -- | |') + +# Post hooks +for FILE in "${HOOKS}/post-${COMMAND}".* "${HOOKS}/${NAME}.post-${COMMAND}" +do + if [ -x "${FILE}" ] + then + "${FILE}" + fi +done + +# done +echo "'${NAME}': container created." diff --git a/share/bash-completion/container b/share/bash-completion/container index bc0281f..44a48e7 100644 --- a/share/bash-completion/container +++ b/share/bash-completion/container @@ -97,6 +97,28 @@ _container() esac ;; + get|g) + case "${prev}" in + -n|--name) + opts="$(cd /etc/compute-tools/debconf 2>/dev/null && ls *.cfg */*.cfg 2>/dev/null | sed -e 's|.*/||g' -e 's|.cfg$||g')" + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + ;; + + -s|--script) + opts="$(cd /usr/share/compute-tools/get-scripts && find -maxdepth 1 -not -type d -and -not -name 'default' -and -not -name 'debconf' -and -not -name '*.d' -printf '%P\n' | sort)" + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + ;; + + *) + opts="-n --name -c --capability -d --drop-capability -s --script -v --verbose -b --bind --bind-ro" + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + ;; + esac + ;; + info) case "${prev}" in -n|--name) diff --git a/share/hooks/pre-get.git-pull.sh b/share/hooks/pre-get.git-pull.sh new file mode 100755 index 0000000..744f955 --- /dev/null +++ b/share/hooks/pre-get.git-pull.sh @@ -0,0 +1,50 @@ +#!/bin/sh + +# Copyright (C) 2014-2021 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" +SOFTWARE="compute-tools" +PROGRAM="container" + +DIRECTORIES="$(for DIRECTORY in $(find /etc/${SOFTWARE}/debconf/ -type d -name ".git"); do echo $(dirname ${DIRECTORY}); done | sort -uV)" + +for DIRECTORY in ${DIRECTORIES} +do + if [ -e "${DIRECTORY}/.git" ] && [ -e /usr/bin/git ] + then + echo "Updating ${DIRECTORY}..." + + if [ -e "/etc/${SOFTWARE}.conf" ] + then + . "/etc/${SOFTWARE}.conf" + fi + + DEBCONF_ID="${DEBCONF_ID:-HEAD}" + + cd "${DIRECTORY}" + + git clean -dfx + git checkout -f ${DEBCONF_ID} + git pull --rebase + echo + + cd "${OLDPWD}" + fi +done diff --git a/share/man/container-build.1.rst b/share/man/container-build.1.rst index d4d7fc5..38a4aed 100644 --- a/share/man/container-build.1.rst +++ b/share/man/container-build.1.rst @@ -98,10 +98,6 @@ The following **container build** options are available: Examples ======== -Build example.net container using curl script: - - sudo container build -n example.net -s curl - Build example.net container using debootstrap script: sudo container build -n example.net -s debootstrap diff --git a/share/man/container-get.1.rst b/share/man/container-get.1.rst new file mode 100644 index 0000000..edcb1de --- /dev/null +++ b/share/man/container-get.1.rst @@ -0,0 +1,130 @@ +.. Open Infrastructure: compute-tools + +.. Copyright (C) 2014-2021 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-get +============= + +-------------------- +Download a container +-------------------- + +:manual section: 1 +:manual group: Open Infrastructure + +Synopsis +======== + +| **container get** ['OPTIONS'] +| **cnt g** ['OPTIONS'] + +Description +=========== + +The **container get** command downloads a container based on a script. + +Scripts +------- + +The following download scripts are available: + +curl: + Basic script to build Debian based container, see container-create-curl(1). + +default: + Symlink (if existing) to a download script which is used if no script was + specified. On Debian based system this can be managed through + update-alternatives(1), i.e. 'sudo update-alternatives --config + container_get-script'. + +Options +======= + +The following **container get** options are available: + +-n, --name='NAME': + Specify container name. + +-c, --capability='CAPABILITY': + Specify capabilities to grant, see capabilities(7). + +-d, --drop-capability='DROP_CAPABILITY': + Specify capabilities to drop, see capabilities(7). + +-s, --script='SCRIPT': + Specify container build script, defaults to 'debootstrap'. + +-v, --verbose: + Explain what is being done. + +-b, --bind='DIRECTORY:DIRECTORY[:OPTIONS][;DIRECTORY:DIRECTORY[:OPTIONS]]': + Specify container read-write bind mounts, see systemd-nspawn(1) --bind option. + +--bind-ro='DIRECTORY:DIRECTORY[:OPTIONS][;DIRECTORY:DIRECTORY[:OPTIONS]]': + Specify container read-only bind mounts, see systemd-nspawn(1) --bind-ro + option. + +--cnt-overlay='DIRECTORY_LOWER:DIRECTORY_UPPER:DIRECTORY_WORK:DIRECTORY_MERGED[;DIRECTORY_UPPER:DIRECTORY_LOWER:DIRECTORY_WORK:DIRECTORY_MERGED]': + Specify container overlay mounts, see Documentation/filesystems/overlayfs.txt. + +--cnt.overlay-options='OPTION1,OPTION2[;OPTION3,OPTION4]': + Specify container overlay mount options, see + Documentation/filesystems/overlayfs.txt. + +--cnt.start='OPTION1[,OPTION2,...]': + Specify container start options, see container-start(1). + +Examples +======== + +Create example.net container using curl script: + + sudo container get -n example.net -s curl + +Create example.net container with the default download script and start it: + + sudo container get,start -n example.net + +See also +======== + +| compute-tools(7), +| container(1). + +Homepage +======== + +More information about compute-tools and the Open Infrastructure project can be +found on the homepage (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 +(https://bugs.debian.org). + +Authors +======= + +compute-tools were written by Daniel Baumann + and others. -- cgit v1.2.3