diff options
-rw-r--r-- | CHANGELOG.txt | 15 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | VERSION.txt | 2 | ||||
-rwxr-xr-x | lib/container/key | 152 | ||||
-rwxr-xr-x | lib/container/limit | 208 | ||||
-rwxr-xr-x | lib/container/start | 96 | ||||
-rw-r--r-- | share/bash-completion/container | 21 | ||||
-rw-r--r-- | share/config/container.conf.in | 13 | ||||
-rw-r--r-- | share/man/container-create-curl.1.txt | 129 | ||||
-rw-r--r-- | share/man/container-create.1.txt | 6 | ||||
-rw-r--r-- | share/man/container-key.1.txt | 86 | ||||
-rw-r--r-- | share/man/container-limit.1.txt | 109 | ||||
-rw-r--r-- | share/man/container.1.txt | 6 | ||||
-rwxr-xr-x | share/scripts/curl | 490 | ||||
-rwxr-xr-x | share/scripts/curl.d/0001-debconf | 54 | ||||
-rw-r--r-- | share/scripts/curl.d/0001-debconf.templates | 11 |
16 files changed, 1383 insertions, 17 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 330e383..de65ba1 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,10 +1,17 @@ -2019-03-02 Daniel Baumann <daniel.baumann@open-infrastructure.net> +2019-03-04 Daniel Baumann <daniel.baumann@open-infrastructure.net> - * Releasing version 20190301-lts1. + * Releasing version 20190304. + + [ Daniel Baumann ] + * Readding key command. + * Readding limit command. + * Readding curl container create script. + * Correcting version strings in changelog. + * Correcting variable name in makefile. 2019-03-01 Daniel Baumann <daniel.baumann@open-infrastructure.net> - * Releasing version 2019-03-01. + * Releasing version 20190301. [ Daniel Baumann ] * Adding a end message in container create command. @@ -29,7 +36,7 @@ 2019-02-22 Daniel Baumann <daniel.baumann@open-infrastructure.net> - * Releasing version 2019-02-22. + * Releasing version 20190222. * Backward incompatible changes: - replaced Progress Linux 4 and Progress Linux 4+ support in @@ -68,7 +68,7 @@ install: build cp -r lib/* $(DESTDIR)/usr/lib/$(PROJECT) mkdir -p $(DESTDIR)/usr/share/$(PROJECT)/$(PROGRAM) - cp -r VERSION.txt $(DESTDIR)/usr/share/$(PROJECT)/${PROGRAM} + cp -r VERSION.txt $(DESTDIR)/usr/share/$(PROJECT)/$(PROGRAM) cp -r share/config share/hooks share/scripts $(DESTDIR)/usr/share/$(PROJECT)/$(PROGRAM) mkdir -p $(DESTDIR)/usr/share/bash-completion/completions diff --git a/VERSION.txt b/VERSION.txt index 7182ca9..6cc47af 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -20190301-lts1 +20190304 diff --git a/lib/container/key b/lib/container/key new file mode 100755 index 0000000..1b59555 --- /dev/null +++ b/lib/container/key @@ -0,0 +1,152 @@ +#!/bin/sh + +# Copyright (C) 2014-2019 Daniel Baumann <daniel.baumann@open-infrastructure.net> +# +# 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 <http://www.gnu.org/licenses/>. + +set -e + +PROJECT="open-infrastructure" +PROGRAM="container" +COMMAND="$(basename ${0})" + +KEYS="/etc/${PROJECT}/${PROGRAM}/keys" + +Parameters () +{ + GETOPT_LONGOPTIONS="add:,list,remove:," + GETOPT_OPTIONS="a:,l,r:," + + 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 + -a|--add) + ADD="${2}" + ACTION="add" + shift 2 + ;; + + -l|--list) + ACTION="list" + shift 1 + ;; + + -r|--remove) + REMOVE="${2}" + ACTION="remove" + shift 2 + ;; + + --) + shift 1 + break + ;; + + *) + echo "'${COMMAND}': getopt error" >&2 + exit 1 + ;; + esac + done +} + +Usage () +{ + echo "Usage: ${PROGRAM} ${COMMAND} [-a|--add KEY] [-l|--list] [-r|--remove KEY]" >&2 + exit 1 +} + +Parameters "${@}" + +if [ -z "${ACTION}" ] +then + Usage +fi + +# Pre hooks +for FILE in "${HOOKS}/pre-${COMMAND}".* "${HOOKS}/${NAME}.pre-${COMMAND}" +do + if [ -x "${FILE}" ] + then + "${FILE}" + fi +done + +# Run +if [ ! -e "${KEYS}" ] +then + mkdir -p "${KEYS}" + + chown root:root "${KEYS}" + chmod 0700 "${KEYS}" + +cat > "${KEYS}/gnupg.conf" << EOF +keyserver hkps://hkps.pool.sks-keyservers.net +keyserver-options include-revoked +keyserver-options no-honor-keyserver-url + +cert-digest-algo SHA512 +default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES ZLIB ZIP Uncompressed +personal-cipher-preferences AES256 AES192 AES +personal-compress-preferences ZLIB ZIP Uncompressed +personal-digest-preferences SHA512 SHA384 SHA256 SHA224 + +no-comments +no-emit-version +no-greeting +keyid-format 0xlong +list-options show-keyring +list-options show-uid-validity +verify-options show-uid-validity +with-fingerprint + +charset utf-8 +EOF + +fi + +case "${ACTION}" in + add) + gpg --homedir "${KEYS}" --import "${ADD}" + ;; + + list) + gpg --homedir "${KEYS}" --list-keys + ;; + + remove) + gpg --homedir "${KEYS}" --delete-keys "${REMOVE}" + ;; +esac + +# Post hooks +for FILE in "${HOOKS}/post-${COMMAND}".* "${HOOKS}/${NAME}.post-${COMMAND}" +do + if [ -x "${FILE}" ] + then + "${FILE}" + fi +done diff --git a/lib/container/limit b/lib/container/limit new file mode 100755 index 0000000..b1ec170 --- /dev/null +++ b/lib/container/limit @@ -0,0 +1,208 @@ +#!/bin/sh + +# Copyright (C) 2014-2019 Daniel Baumann <daniel.baumann@open-infrastructure.net> +# +# 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 <http://www.gnu.org/licenses/>. + +set -e + +PROJECT="open-infrastructure" +PROGRAM="container" +COMMAND="$(basename ${0})" + +HOOKS="/etc/${PROJECT}/${PROGRAM}/hooks" +MACHINES="/var/lib/machines" + +Parameters () +{ + GETOPT_LONGOPTIONS="name:,blockio-device-weight:,blockio-read-bandwidth:,blockio-weight:,blockio-write-bandwidth:,cpu-quota:,cpu-shares:,memory-limit:,tasks-max:," + GETOPT_OPTIONS="n:b:c:m:t:," + + 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 + ;; + + -c|--cpu-quota) + CPU_QUOTA="${2}" + shift 2 + ;; + + --cpu-shares) + CPU_SHARES="${2}" + shift 2 + ;; + + -m|--memory-limit) + MEMORY_LIMIT="${2}" + shift 2 + ;; + + -t|--tasks-max) + TASKS_MAX="${2}" + shift 2 + ;; + + --blockio-device-weight) + BLOCK_IO_DEVICE_WEIGHT="${2}" + shift 2 + ;; + + --blockio-read-bandwidth) + BLOCK_IO_READ_BANDWIDTH="${2}" + shift 2 + ;; + + -b|--blockio-weight) + BLOCK_IO_WEIGHT="${2}" + shift 2 + ;; + + --blockio-write-bandwidth) + BLOCK_IO_WRITE_BANDWIDTH="${2}" + shift 2 + ;; + + --) + shift 1 + break + ;; + + *) + echo "'${COMMAND}': getopt error" >&2 + exit 1 + ;; + esac + done +} + +Usage () +{ + echo "Usage: ${PROGRAM} ${COMMAND} -n|--name NAME [--blockio-device-weight \"DEVICE WEIGHT\"] [--blockio-read-bandwidth \"DEVICE BYTES\"] [-b|--blockio-weight WEIGHT] [--blockio-write-bandwidth \"DEVICE BYTES\"] [-c|--cpu-quota QUOTA] [--cpu-shares SHARES] [-m|--memory-limit BYTES] [-t|--tasks-max NUMBER]" >&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 + +if [ -n "${BLOCK_IO_DEVICE_WEIGHT}" ] +then + BLOCK_IO_DEVICE_WEIGHT="BlockIODeviceWeight=${BLOCK_IO_DEVICE_WEIGHT}" + SET_PROPERTY="true" +fi + +if [ -n "${BLOCK_IO_READ_BANDWIDTH}" ] +then + BLOCK_IO_READ_BANDWIDTH="BlockIOReadBandwidth=${BLOCK_IO_READ_BANDWIDTH}" + SET_PROPERTY="true" +fi + +if [ -n "${BLOCK_IO_WEIGHT}" ] +then + BLOCK_IO_WEIGHT="BlockIOWeight=${BLOCK_IO_WEIGHT}" + SET_PROPERTY="true" +fi + +if [ -n "${BLOCK_IO_WRITE_BANDWIDTH}" ] +then + BLOCK_IO_WRITE_BANDWIDTH="BlockIOReadBandwidth=${BLOCK_IO_WRITE_BANDWIDTH}" + SET_PROPERTY="true" +fi + +if [ -n "${CPU_QUOTA}" ] +then + CPU_QUOTA="CPUQuota=${CPU_QUOTA}" + SET_PROPERTY="true" +fi + +if [ -n "${CPU_SHARES}" ] +then + CPU_SHARES="CPUShares=${CPU_SHARES}" + SET_PROPERTY="true" +fi + +if [ -n "${MEMORY_LIMIT}" ] +then + MEMORY_LIMIT="MemoryLimit=${MEMORY_LIMIT}" + SET_PROPERTY="true" +fi + +if [ -n "${TASKS_MAX}" ] +then + TASKS_MAX="TasksMax=${TASKS_MAX}" + SET_PROPERTY="true" +fi + +if [ "${SET_PROPERTY}" != "true" ] +then + Usage +fi + +# Pre hooks +for FILE in "${HOOKS}/pre-${COMMAND}".* "${HOOKS}/${NAME}.pre-${COMMAND}" +do + if [ -x "${FILE}" ] + then + "${FILE}" + fi +done + +# Run +systemctl --runtime set-property ${NAME} ${BLOCK_IO_DEVICE_WEIGHT} ${BLOCK_IO_READ_BANDWIDTH} ${BLOCK_IO_WEIGHT} ${BLOCK_IO_WRITE_BANDWIDTH} ${CPU_QUOTA} ${CPU_SHARES} ${MEMORY_LIMIT} ${TASKS_MAX} + +# Post hooks +for FILE in "${HOOKS}/post-${COMMAND}".* "${HOOKS}/${NAME}.post-${COMMAND}" +do + if [ -x "${FILE}" ] + then + "${FILE}" + fi +done diff --git a/lib/container/start b/lib/container/start index 82f9314..d5e9059 100755 --- a/lib/container/start +++ b/lib/container/start @@ -398,6 +398,70 @@ EOF REGISTER="--register=no" ;; esac + + BLOCK_IO_DEVICE_WEIGHT="$(awk -F= '/^BlockIODeviceWeight=/ { print $2 }' ${CONFIG}/${NAME}.conf)" + + if [ -n "${BLOCK_IO_DEVICE_WEIGHT}" ] + then + BLOCK_IO_DEVICE_WEIGHT="BlockIODeviceWeight=${BLOCK_IO_DEVICE_WEIGHT}" + SET_PROPERTY="true" + fi + + BLOCK_IO_READ_BANDWIDTH="$(awk -F= '/^BlockIOReadBandwidth=/ { print $2 }' ${CONFIG}/${NAME}.conf)" + + if [ -n "${BLOCK_IO_READ_BANDWIDTH}" ] + then + BLOCK_IO_READ_BANDWIDTH="BlockIOReadBandwidth=${BLOCK_IO_READ_BANDWIDTH}" + SET_PROPERTY="true" + fi + + BLOCK_IO_WEIGHT="$(awk -F= '/^BlockIOWeight=/ { print $2 }' ${CONFIG}/${NAME}.conf)" + + if [ -n "${BLOCK_IO_WEIGHT}" ] + then + BLOCK_IO_WEIGHT="BlockIOWeight=${BLOCK_IO_WEIGHT}" + SET_PROPERTY="true" + fi + + BLOCK_IO_WRITE_BANDWIDTH="$(awk -F= '/^BlockIOWriteBandwidth=/ { print $2 }' ${CONFIG}/${NAME}.conf)" + + if [ -n "${BLOCK_IO_WRITE_BANDWIDTH}" ] + then + BLOCK_IO_WRITE_BANDWIDTH="BlockIOWriteBandwidth=${BLOCK_IO_WRITE_BANDWIDTH}" + SET_PROPERTY="true" + fi + + CPU_QUOTA="$(awk -F= '/^CPUQuota=/ { print $2 }' ${CONFIG}/${NAME}.conf)" + + if [ -n "${CPU_QUOTA}" ] + then + CPU_QUOTA="CPUQuota=${CPU_QUOTA}" + SET_PROPERTY="true" + fi + + CPU_SHARES="$(awk -F= '/^CPUShares=/ { print $2 }' ${CONFIG}/${NAME}.conf)" + + if [ -n "${CPU_SHARES}" ] + then + CPU_SHARES="CPUShares=${CPU_SHARES}" + SET_PROPERTY="true" + fi + + MEMORY_LIMIT="$(awk -F= '/^MemoryLimit=/ { print $2 }' ${CONFIG}/${NAME}.conf)" + + if [ -n "${MEMORY_LIMIT}" ] + then + MEMORY_LIMIT="MemoryLimit=${MEMORY_LIMIT}" + SET_PROPERTY="true" + fi + + TASKS_MAX="$(awk -F= '/^TasksMax=/ { print $2 }' ${CONFIG}/${NAME}.conf)" + + if [ -n "${TASKS_MAX}" ] + then + TASKS_MAX="TasksMax=${TASKS_MAX}" + SET_PROPERTY="true" + fi fi case "${SYSTEMCTL}" in @@ -408,14 +472,26 @@ case "${SYSTEMCTL}" in ;; esac -# Run -${SETARCH} systemd-nspawn --keep-unit ${BIND} ${BIND_RO} ${BOOT} ${CAPABILITY} ${DIRECTORY} ${DROP_CAPABILITY} ${MACHINE} ${NETWORK_VETH_EXTRA} ${LINK_JOURNAL} ${REGISTER} +case "${START}" in + true) + case "${SET_PROPERTY}" in + true) + systemctl --runtime set-property ${NAME} ${BLOCK_IO_DEVICE_WEIGHT} ${BLOCK_IO_READ_BANDWIDTH} ${BLOCK_IO_WEIGHT} ${BLOCK_IO_WRITE_BANDWIDTH} ${CPU_QUOTA} ${CPU_SHARES} ${MEMORY_LIMIT} ${TASKS_MAX} + ;; + esac + ;; + + *) + # Run + ${SETARCH} systemd-nspawn --keep-unit ${BIND} ${BIND_RO} ${BOOT} ${CAPABILITY} ${DIRECTORY} ${DROP_CAPABILITY} ${MACHINE} ${NETWORK_VETH_EXTRA} ${LINK_JOURNAL} ${REGISTER} -# Post hooks -for FILE in "${HOOKS}/post-${COMMAND}".* "${HOOKS}/${NAME}.post-${COMMAND}" -do - if [ -x "${FILE}" ] - then - "${FILE}" - fi -done + # Post hooks + for FILE in "${HOOKS}/post-${COMMAND}".* "${HOOKS}/${NAME}.post-${COMMAND}" + do + if [ -x "${FILE}" ] + then + "${FILE}" + fi + done + ;; +esac diff --git a/share/bash-completion/container b/share/bash-completion/container index 0013394..e130710 100644 --- a/share/bash-completion/container +++ b/share/bash-completion/container @@ -98,6 +98,27 @@ _container() esac ;; + key) + opts="-a --add -l --list -r --remove" + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + + limit) + case "${prev}" in + -n|--name) + opts="$(container list -a -f shell)" + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + ;; + + *) + opts="-n --name --blockio-device-weight --blockio-read-bandwidth -b --blockio-weight --blockio-write-bandwidth -c --cpu-quota --cpu-shares -m --memory-limit -t --tasks-max" + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + ;; + esac + ;; + list|ls) case "${prev}" in -h|--host) diff --git a/share/config/container.conf.in b/share/config/container.conf.in index b0f35cb..ebf91b9 100644 --- a/share/config/container.conf.in +++ b/share/config/container.conf.in @@ -1,5 +1,6 @@ -# /etc/open-infrastructure/container/config/@NAME@.conf +# compute-tools: @NAME@ +[start] cnt.auto=@CNT_AUTO@ cnt.container-server=@CNT_CONTAINER_SERVER@ cnt.network-bridge=@CNT_NETWORK_BRIDGE@ @@ -15,3 +16,13 @@ machine=@MACHINE@ network-veth-extra=@NETWORK_VETH_EXTRA@ private-users=@PRIVATE_USERS@ register=@REGISTER@ + +[limit] +BlockIODeviceWeight= +BlockIOReadBandwidth= +BlockIOWeight= +BlockIOWriteBandwidth= +CPUQuota= +CPUShares= +MemoryLimit= +TasksMax= diff --git a/share/man/container-create-curl.1.txt b/share/man/container-create-curl.1.txt new file mode 100644 index 0000000..40028c9 --- /dev/null +++ b/share/man/container-create-curl.1.txt @@ -0,0 +1,129 @@ +// Copyright (C) 2014-2019 Daniel Baumann <daniel.baumann@open-infrastructure.net> +// +// 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 <http://www.gnu.org/licenses/>. + +CONTAINER-CREATE-CURL(1) +======================== +:doctype: manpage +:man manual: Open Infrastructure +:man source: compute-tools +:man version: {revnumber} + + +NAME +---- +container-create-curl - Create a Debian based container by downloading a tarball over the network + + +SYNOPSIS +-------- +*container create -s curl* ['OPTIONS'] + + +DESCRIPTION +----------- +The curl container creation script uses curl(1) to download a tarball over the +network to create a Debian based container. + +Depending on the tarball this script otherwise creates a pure Debian system with three modificiations: + + * hostname is set (container name) in /etc/hostname + * systemd machine-id is generated in /etc/machine-id + * root password is set (user specified or 16 random characters) + + +OPTIONS +------- +The following script options are available: + +*-n, --name='NAME'*:: + Specify container name. + +*-a, --architecture='ARCHITECTURE'*:: + Specify container architecture. + +"--clean*:: + Remove downloaded tarball after successfull container creation. + +*-p, --root-password='PASSWORD'*:: + Specify the root password, defaults to a random 16 character password. + +*--server='SERVER'*:: + Specify the image server to download from, defaults to https://get.open-infrastructure.net/system/container/debian. + +*--setup='SETUP'*:: + Specify the setup image name to download, defaults to the value specified through --system using the setup.tar.${COMPRESSION} suffix. + +*--system='SYSTEM'*:: + Specify the system image name to download, defaults to debian-stretch-current_${ARCHITECTURE}.system.tar.${COMPRESSION} (where ${ARCHITECTURE} is the host systems architecture and ${COMPRESSION} either lz, xz, or gz depending on compressor availability on the host system). + + +EXAMPLES +-------- +*Create a Debian 9 (stretch) based container with same architecture as the host system:*:: + sudo container create -s curl -n stretch.example.net + +*Create a Debian 9 (stretch) based container with different architecture as the host system:*:: + sudo container create -s curl -n stretch-i386.example.net -- --system debian-stretch-current_i386.system.tar.xz + +FILES +----- +The following files are used: + +*/etc/open-infrastructure/container/config*:: + Container configuration files. + +*/usr/share/open-infrastructure/container/scripts*:: + Container creation scripts. + +*/usr/share/doc/compute-tools*:: + Container documentation. + +*/var/lib/machines*:: + Container directory. + +*/var/cache/open-infrastructure/container*:: + Container cache directory. + + +CONTAINER IMAGES +---------------- + +compute-tools will download tarballs from a server expecting that the images are tarballs with either gzip, lzip, xz, or no compression. See container-images.sh as an example on how to create your own container images. + + +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 <software@lists.open-infrastructure.net>. + +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 <daniel.baumann@open-infrastructure.net> and others. diff --git a/share/man/container-create.1.txt b/share/man/container-create.1.txt index 5ba4637..7f1f0a9 100644 --- a/share/man/container-create.1.txt +++ b/share/man/container-create.1.txt @@ -72,6 +72,9 @@ SCRIPTS ------- The following container scripts are available: +*curl*:: + Basic script to create Debian based container, see container-create-curl(1). + *debootstrap*:: Basic script to create Debian based container, see container-create-debootstrap(1). @@ -84,6 +87,9 @@ The following container scripts are available: EXAMPLES -------- +*Create example.net container using curl script:*:: + sudo container create -n example.net -s curl + *Create example.net container using debootstrap script:*:: sudo container create -n example.net -s debootstrap diff --git a/share/man/container-key.1.txt b/share/man/container-key.1.txt new file mode 100644 index 0000000..7e7f376 --- /dev/null +++ b/share/man/container-key.1.txt @@ -0,0 +1,86 @@ +// Copyright (C) 2014-2019 Daniel Baumann <daniel.baumann@open-infrastructure.net> +// +// 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 <http://www.gnu.org/licenses/>. + +CONTAINER-KEY(1) +================ +:doctype: manpage +:man manual: Open Infrastructure +:man source: compute-tools +:man version: {revnumber} + + +NAME +---- +container-key - Manage GnuPG keyring for container operations + + +SYNOPSIS +-------- +*container key* ['OPTIONS'] + + +DESCRIPTION +----------- +The container key manages the GnuPG keyring for container operations. + + +OPTIONS +------- +The following container options are available: + +*-a, --add='KEY'*:: + Add a key to the keyring. + +*-l, --list'*:: + List keys in the keyring. + +*-r, --remove='KEY'*:: + Remove a key from the keyring. + + +EXAMPLES +-------- +*Add a key to the keyring:*:: + gpg --keyserver hkps://hkps.pool.sks-keyservers.net --recv 0x1E9B3AED2D9FA8F6 + gpg --armor --export 0x1E9B3AED2D9FA8F6 | sudo container key --add - + +*Remove a key from the keyring:*:: + sudo container key --remove 0x1E9B3AED2D9FA8F6 + + +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 <software@lists.open-infrastructure.net>. + +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 <daniel.baumann@open-infrastructure.net> and others. diff --git a/share/man/container-limit.1.txt b/share/man/container-limit.1.txt new file mode 100644 index 0000000..62f0288 --- /dev/null +++ b/share/man/container-limit.1.txt @@ -0,0 +1,109 @@ +// Copyright (C) 2014-2019 Daniel Baumann <daniel.baumann@open-infrastructure.net> +// +// 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 <http://www.gnu.org/licenses/>. + +CONTAINER-LIMIT(1) +================== +:doctype: manpage +:man manual: Open Infrastructure +:man source: compute-tools +:man version: {revnumber} + + +NAME +---- +container-limit - Limit ressources of a container + + +SYNOPSIS +-------- +*container limit* ['OPTIONS'] + + +DESCRIPTION +----------- +The container limit command limits ressources available to a container at runtime. + + +OPTIONS +------- +The following container options are available: + +*-n, --name='NAME'*:: + Specify container name. + +*--blockio-device-weight='DEVICE WEIGHT'*:: + Specify device specific blockio weight, see systemd.resource-control(5). + +*--blockio-read-bandwidth='DEVICE BYTES'*:: + Specify device specific blockio read bandwidth, see systemd.resource-control(5). + +*-b, --blockio-weight='WEIGHT'*:: + Specify general blockio weight, see systemd.resource-control(5). + +*--blockio-write-bandwidth='DEVICE BYTES'*:: + Specify device specific blockio write bandwidth, see systemd.resource-control(5). + +*-c, --cpu-quota='QUOTA'*:: + Specify CPU quota, see systemd.resource-control(5). + +*--cpu-shares='SHARES'*:: + Specify CPU shares, see systemd.resource-control(5). + +*-m, --memory-limit='BYTES'*:: + Specify memory limit, see systemd.resource-control(5). + +*-t, --tasks-max='NUMBER'*:: + Specify tasks max, see systemd.resource-control(5). + + +EXAMPLES +-------- +*Set blockio weight for the example.net container:*:: + sudo container limit -n example.net --blockio-weight 100 + +*Set CPU quota for the example.net container:*:: + sudo container limit -n example.net --cpu-quota 10% + +*Set memory limit for the example.net container to 1GB:*:: + sudo container limit -n example.net --memory-limit 1G + +*Set tasks max for the example.net container to 100:*:: + sudo container limit -n example.net --tasks-max 100 + + +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 <software@lists.open-infrastructure.net>. + +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 <daniel.baumann@open-infrastructure.net> and others. diff --git a/share/man/container.1.txt b/share/man/container.1.txt index 224d6cc..aba9141 100644 --- a/share/man/container.1.txt +++ b/share/man/container.1.txt @@ -75,6 +75,12 @@ The following container commands are available: *enter*:: Enter a container namespace, see container-enter(1). +*key*:: + Manage GnuPG keyring for container operations, see container-key(1). + +*limit*:: + Limit ressources of a container, see container-limit(1). + *list*:: List container on the system, see container-list(1). diff --git a/share/scripts/curl b/share/scripts/curl new file mode 100755 index 0000000..6b8db26 --- /dev/null +++ b/share/scripts/curl @@ -0,0 +1,490 @@ +#!/bin/sh + +# Copyright (C) 2014-2019 Daniel Baumann <daniel.baumann@open-infrastructure.net> +# +# 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 <http://www.gnu.org/licenses/>. + +set -e + +PROJECT="open-infrastructure" +SOFTWARE="compute-tools" +PROGRAM="container" +SCRIPT="${0}" + +HOOKS="/etc/${PROJECT}/${PROGRAM}/hooks" +KEYS="/etc/${PROJECT}/${PROGRAM}/keys" +MACHINES="/var/lib/machines" +CACHE="/var/cache/${PROJECT}/${PROGRAM}/system" + +Parameters () +{ + GETOPT_LONGOPTIONS="bind:,bind-ro:,script:,name:,architecture:,clean,password:,server:,setup:,system:," + GETOPT_OPTIONS="b:,s:,n:,a:,p:" + + PARAMETERS="$(getopt --longoptions ${GETOPT_LONGOPTIONS} --name=${SCRIPT} --options ${GETOPT_OPTIONS} --shell sh -- ${@})" + + if [ "${?}" != "0" ] + then + echo "'${SCRIPT}': getopt exit" >&2 + exit 1 + fi + + eval set -- "${PARAMETERS}" + + while true + do + case "${1}" in + -b|--bind) + # ignore + shift 2 + ;; + + --bind-ro) + # ignore + shift 2 + ;; + + --cnt.auto) + # ignore + shift 2 + ;; + + --cnt.container-server) + # ignore + shift 2 + ;; + + -s|--script) + # ignore + shift 2 + ;; + + -n|--name) + NAME="${2}" + shift 2 + ;; + + -a|--architecture) + ARCHITECTURE="${2}" + shift 2 + ;; + + --clean) + CLEAN="true" + shift 1 + ;; + + -p|--password) + PASSWORD="${2}" + shift 2 + ;; + + --server) + SERVER="${2}" + shift 2 + ;; + + --setup) + SETUP="${2}" + shift 2 + ;; + + --system) + SYSTEM="${2}" + shift 2 + ;; + + --) + shift 1 + break + ;; + + *) + echo "'${SCRIPT}': getopt error" >&2 + exit 1 + ;; + esac + done +} + +Usage () +{ + echo "Usage: container create -n|--name NAME -s|--script ${SCRIPT} -- [--clean] [-p|--password PASSWORD] [--server SERVER] [--setup SETUP] [--system SYSTEM]" >&2 + exit 1 +} + +Parameters "${@}" + +if [ -z "${NAME}" ] +then + Usage +fi + +if [ -e "${MACHINES}/${NAME}" ] +then + echo "'${NAME}': container already exists" >&2 + exit 1 +fi + +if [ ! -x /usr/bin/curl ] +then + echo "'${NAME}': /usr/bin/curl - no such file." >&2 + exit 1 +fi + +if [ "$(id -u)" -ne 0 ] +then + echo "'${NAME}': need root privileges" >&2 + exit 1 +fi + +COMPRESSIONS="" + +if [ -x /usr/bin/lzip ] +then + COMPRESSIONS="${COMPRESSIONS} lz" +fi + +if [ -x /usr/bin/xz ] +then + COMPRESSIONS="${COMPRESSIONS} xz" +fi + +if [ -x /bin/gzip ] +then + COMPRESSIONS="${COMPRESSIONS} gz" +fi + +if [ -z "${COMPRESSIONS}" ] +then + echo "'${NAME}': no supported compressor available (lz, xz, gz)." + exit 1 +fi + +SERVER="${SERVER:-https://get.open-infrastructure.net/system/container/debian}" +PASSWORD="${PASSWORD:-$(dd if=/dev/urandom bs=12 count=1 2> /dev/null | base64)}" + +VERSION="$(container version)" + +export SERVER + +Debconf () +{ + # Configure local debconf + mkdir -p "${DEBCONF_TMPDIR}/debconf" + +cat > "${DEBCONF_TMPDIR}/debconf.systemrc" << EOF +Config: configdb +Templates: templatedb + +Name: config +Driver: File +Mode: 644 +Reject-Type: password +Filename: ${DEBCONF_TMPDIR}/debconf/config.dat + +Name: passwords +Driver: File +Mode: 600 +Backup: false +Required: false +Accept-Type: password +Filename: ${DEBCONF_TMPDIR}/debconf/passwords.dat + +Name: configdb +Driver: Stack +Stack: config, passwords + +Name: templatedb +Driver: File +Mode: 644 +Filename: ${DEBCONF_TMPDIR}/debconf/templates.dat +EOF + + DEBCONF_SYSTEMRC="${DEBCONF_TMPDIR}/debconf.systemrc" + export DEBCONF_SYSTEMRC +} + +# Pre hooks +for FILE in "${HOOKS}/pre-${SCRIPT}".* "${HOOKS}/${NAME}.pre-${SCRIPT}" +do + if [ -x "${FILE}" ] + then + "${FILE}" + fi +done + +# Run + +# FIXME: default server via configuration file + +CURL_OPTIONS="" + +if curl -V | grep -qs http2 +then + CURL_OPTIONS="${CURL_OPTIONS} --http2" +fi + +if [ -z "${SYSTEM}" ] +then + # Downloading container list + if curl --fail --head --output /dev/null --silent "${SERVER}/container-list.txt" + then + mkdir -p "/tmp/${SOFTWARE}" + DEBCONF_TMPDIR="$(mktemp -d -p "/tmp/${SOFTWARE}" -t $(basename ${0}).XXXX)" + export DEBCONF_TMPDIR + + if [ -z "${ARCHITECTURE}" ] + then + case "$(dpkg --print-architecture)" in + amd64) + GREP_PATTERN="(amd64|i386)" + ;; + esac + fi + + GREP_PATTERN="${GREP_PATTERN:-${ARCHITECTURE}}" + + echo "Downloading $(echo ${SERVER} | awk -F/ '{ print $3 }') container list" + curl --fail --location --progress-bar --user-agent ${SOFTWARE}/${VERSION} ${CURL_OPTIONS} \ + "${SERVER}/container-list.txt" | grep -E "${GREP_PATTERN}" > "${DEBCONF_TMPDIR}/container-list.txt" + + umask 0022 + + Debconf + + # Run debconf parts + for DEBCONF_SCRIPT in /usr/share/${PROJECT}/${PROGRAM}/scripts/curl.d/* + do + if [ -x "${DEBCONF_SCRIPT}" ] + then + "${DEBCONF_SCRIPT}" + fi + done + + # Read-in configuration from debconf + . "${DEBCONF_TMPDIR}/debconf.default" + + # Remove debconf temporary files + rm --preserve-root --one-file-system -rf "${DEBCONF_TMPDIR}" + rmdir --ignore-fail-on-non-empty "/tmp/${SOFTWARE}" 2>&1 || true + fi +fi + +for COMPRESSION in ${COMPRESSIONS} +do + if curl --fail --head --output /dev/null --silent "${SERVER}/${SYSTEM}.${COMPRESSION}" + then + SYSTEM="${SYSTEM}.${COMPRESSION}" + break + fi +done + +# Downloading container files +mkdir -p "${CACHE}" + +SETUP="${SETUP:-$(echo ${SYSTEM} | sed -e 's|.system.tar.|.setup.tar.|')}" + +for FILE in "${SYSTEM}" "${SYSTEM}.gpg" "${SYSTEM}.sha512" \ + "${SETUP}" "${SETUP}.gpg" "${SETUP}.sha512" +do + if curl --fail --head --output /dev/null --silent "${SERVER}/${FILE}" + then + case "${FILE}" in + *.sha512) + if [ -e "${CACHE}/$(basename ${FILE} .sha512).gpg" ] + then + continue + fi + ;; + esac + + if [ -e "${CACHE}/${FILE}" ] + then + CURL_TIME_COND="--time-cond ${CACHE}/${FILE}" + else + CURL_TIME_COND="" + fi + + echo "Downloading ${FILE}" + curl --fail --location --progress-bar --user-agent ${SOFTWARE}/${VERSION} ${CURL_OPTIONS} ${CURL_TIME_COND} \ + "${SERVER}/${FILE}" -o "${CACHE}/${FILE}" + fi +done + +cd "${CACHE}" + +for FILE in "${SYSTEM}" "${SETUP}" +do + if [ ! -e "${FILE}" ] + then + continue + fi + + if [ -e "${FILE}.gpg" ] + then + echo -n "Verifying ${FILE}:" + + set +e + gpg --homedir "${KEYS}" --verify "${FILE}.gpg" "${FILE}" > /dev/null 2>&1 + GNUPG="${?}" + set -e + + case "${GNUPG}" in + 0) + echo " gpg ok." + continue + ;; + + *) + echo " gpg failed." + exit 1 + ;; + esac + elif [ -e "${FILE}.sha512" ] + then + echo -n "Verifying ${FILE}:" + + set +e + sha512sum --check "${FILE}.sha512" --status + SHA512SUM="${?}" + set -e + + case "${SHA512SUM}" in + 0) + echo " sha512 ok." + ;; + + *) + echo " sha512 failed." + exit 1 + ;; + esac + fi +done + +cd "${OLDPWD}" + +case "${SYSTEM}" in + *.gz) + TAR_OPTIONS="--gzip" + + if [ ! -e /bin/gzip ] + then + echo -en "\n" + echo "'${NAME}': /bin/lzip - no such file." >&2 + exit 1 + fi + ;; + + *.lz) + TAR_OPTIONS="--lzip" + + if [ ! -e /usr/bin/lzip ] + then + echo -en "\n" + echo "'${NAME}': /usr/bin/lzip - no such file." >&2 + exit 1 + fi + ;; + + *.xz) + TAR_OPTIONS="--xz" + + if [ ! -e /usr/bin/xz ] + then + echo -en "\n" + echo "'${NAME}': /usr/bin/xz - no such file." >&2 + exit 1 + fi + ;; + + *) + TAR_OPTIONS="" + ;; +esac + +for FILE in "${SYSTEM}" "${SETUP}" +do + if [ ! -e "${CACHE}/${FILE}" ] + then + continue + fi + + case "${FILE}" in + *.system.tar.*) + DIRECTORY="${MACHINES}/${NAME}" + ;; + + *.setup.tar.*) + DIRECTORY="${MACHINES}/${NAME}/setup" + ;; + esac + + mkdir -p "${DIRECTORY}" + + if [ -e /usr/bin/pv ] + then + echo "Unpacking ${FILE}" + pv --format '%p' --width 77 "${CACHE}/${FILE}" | tar xf - ${TAR_OPTIONS} -C "${DIRECTORY}" --strip 1 + else + echo -n "Unpacking ${FILE}:" + tar xf "${CACHE}/${FILE}" ${TAR_OPTIONS} -C "${DIRECTORY}" --strip 1 + echo " ok." + fi +done + +if [ -x "${MACHINES}/${NAME}/setup/container" ] +then + chroot "${MACHINES}/${NAME}" /usr/bin/env -i \ + LC_ALL="C" PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games" TERM="${TERM}" \ + DEBIAN_FRONTEND="dialog" DEBIAN_PRIORITY="low" \ + DEBCONF_NONINTERACTIVE_SEEN="true" DEBCONF_NOWARNINGS="true" \ + NAME="${NAME}" \ + /setup/container + + rm -rf "${MACHINES}/${NAME}/setup" +fi + +# Creating machine-id +chroot "${MACHINES}/${NAME}" systemd-machine-id-setup > /dev/null 2>&1 + +# Setting hostname +echo "${NAME}" > "${MACHINES}/${NAME}/etc/hostname" + +# Copying resolv.conf +cp -L /etc/resolv.conf "${MACHINES}/${NAME}/etc/resolv.conf" + +# Setting root password +echo root:${PASSWORD} | chroot "${MACHINES}/${NAME}" chpasswd +echo "${NAME}: root password set to '${PASSWORD}'." + +# Remove cache +case "${CLEAN}" in + true) + rm -f "${CACHE}/${SYSTEM}" "${CACHE}/${SYSTEM}.sha512" + rm -f "${CACHE}/${SETUP}" "${CACHE}/${SETUP}.sha512" + ;; +esac + +# Post hooks +for FILE in "${HOOKS}/post-${SCRIPT}".* "${HOOKS}/${NAME}.post-${SCRIPT}" +do + if [ -x "${FILE}" ] + then + "${FILE}" + fi +done diff --git a/share/scripts/curl.d/0001-debconf b/share/scripts/curl.d/0001-debconf new file mode 100755 index 0000000..3f98f74 --- /dev/null +++ b/share/scripts/curl.d/0001-debconf @@ -0,0 +1,54 @@ +#!/bin/sh + +# Copyright (C) 2014-2019 Daniel Baumann <daniel.baumann@open-infrastructure.net> +# +# 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 <http://www.gnu.org/licenses/>. + +set -e + +DEBCONF_NOWARNINGS="true" +export DEBCONF_NOWARNINGS + +. /usr/share/debconf/confmodule + +System () +{ + TITLE="$(echo ${SERVER} | awk -F/ '{ print $3 }')" + + SYSTEMS="$(for SYSTEM in $(cat ${DEBCONF_TMPDIR}/container-list.txt | cut -d\| -f2 | sed -e 's| |#|g'); do echo -n "$(echo ${SYSTEM} | sed -e 's|#| |g'), "; done | sed -e 's|, $||')" + SYSTEMS_C="$(for SYSTEM_C in $(cat ${DEBCONF_TMPDIR}/container-list.txt | cut -d\| -f1); do echo -n "${SYSTEM_C}, "; done | sed -e 's|, $||')" + + db_subst cnt-curl/title TITLE "${TITLE}" + + db_subst cnt-curl/system CHOICES "${SYSTEMS}" + db_subst cnt-curl/system CHOICES_C "${SYSTEMS_C}" + + db_fset cnt-curl/system seen false + + db_settitle cnt-curl/title + db_input high cnt-curl/system || true + db_go + + db_get cnt-curl/system + SYSTEM="${RET}" # select + + echo "SYSTEM=\"${SYSTEM}\"" >> "${DEBCONF_TMPDIR}/debconf.default" + export SYSTEM +} + +System + +db_stop diff --git a/share/scripts/curl.d/0001-debconf.templates b/share/scripts/curl.d/0001-debconf.templates new file mode 100644 index 0000000..c87e47e --- /dev/null +++ b/share/scripts/curl.d/0001-debconf.templates @@ -0,0 +1,11 @@ +Template: cnt-curl/title +Type: title +Description: ${TITLE} + +Template: cnt-curl/system +Type: select +Default: +Choices-C: ${CHOICES_C} +Choices: ${CHOICES} +Description: Container list: + Select the system to use for creating the container. |