Loading Dockerfile +2 −0 Original line number Diff line number Diff line Loading @@ -2,8 +2,10 @@ FROM debian:buster-slim as collect COPY LICENCE.txt /stage/LICENCE.txt COPY bootstrap-stage.bash /stage/scripts/bootstrap-stage COPY collect-binaries.bash /stage/scripts/collect-binaries COPY config-nsswitch.bash /stage/scripts/config-nsswitch COPY stage-useradd.bash /stage/scripts/stage-useradd RUN /stage/scripts/collect-binaries /bin/bash FROM scratch Loading bootstrap-stage.bash 0 → 100755 +63 −0 Original line number Diff line number Diff line #!/bin/bash # Copyright (c) 2020 Dom Sekotill <dom.sekotill@kodo.org.uk> # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. set -eu -o pipefail declare -r DEFAULT_STAGE=/stage USAGE="Usage: $0 [--help] [-s STAGE] Prepare the necessary components of an image in a staging directory Options: -h|--help Show this message and exit. -s|--stage STAGE Set the output stage directory. If it does not exist it will be created. (default: $DEFAULT_STAGE) Environment: STAGE: An alternate way of providing --stage " export PATH+=:$(dirname $0) export STAGE=${STAGE-$DEFAULT_STAGE} until [[ $# -eq 0 ]]; do case $1 in -h|--help) echo "$USAGE"; exit 0 ;; -s|--stage) STAGE=$2; shift ;; --*=*) set -- ${1%=*} ${1#--*=} "${@:2}"; continue ;; *) echo >&2 "Unknown argument: $1"; exit 2 ;; esac shift done # nsswitch (if present, only on GNU libc platforms) mkdir -p $STAGE/etc collect-binaries /lib/*/libnss* && cat <<-END_CONF >$STAGE/etc/nsswitch.conf passwd: files group: files hosts: files dns END_CONF # Temp directories mkdir -p $STAGE/var/tmp chmod 1777 $STAGE/var/tmp test -h $STAGE/tmp || ln -s /var/tmp $STAGE/tmp config-nsswitch.bash +13 −80 Original line number Diff line number Diff line Loading @@ -20,88 +20,17 @@ # SOFTWARE. set -eu -o pipefail declare -r DEFAULT_STAGE=/stage USAGE="Usage: $0 [--help] [-s STAGE] [USERNAME[:GROUP[,GROUP...]] ...] Prepare the necessary libraries and configuration for name lookups with nsswitch The Name Service Switch system is used by the GNU C library to provide various types of name lookup including: user names, group names, and host names. This script configures an image for those name look-ups. Hostname lookups are configured to use /etc/hosts (as supplied by Docker) and DNS. Users and groups are configured from command line arguments which supply usernames and optional comma separated group names. Only *additional* groups need be specified, not the user's default group which has the same name as the user. The root user is always created if not specified. Options: -h|--help Show this message and exit. -s|--stage STAGE Set the output stage directory. If it does not exist it will be created. (default: $DEFAULT_STAGE) Environment: STAGE: An alternate way of providing --stage " add_group() { local IFS= users=${GROUP_USERS[$1]-} echo "$1:x:$2:${users%,}" >>$STAGE/etc/group unset GROUP_USERS[$1] } add_user() { echo "$1:x:$2:$2::/:/bin/nologin" >>$STAGE/etc/passwd } process_userspec() { declare -a USERS=() declare -A GROUP_USERS=() declare -a groups local IFS=, spec user group i for spec in "$@"; do user=${spec%:*} groups=( ${spec#*:} ) USERS+=( $user ) GROUP_USERS[$user]+="" for group in "${groups[@]}"; do [[ $group = $user ]] && continue GROUP_USERS[$group]+="$user," done done add_user root 0 add_group root 0 i=0 for user in "${USERS[@]}"; do add_user $user $((++i)) add_group $user $i done i=500 for group in "${!GROUP_USERS[@]}"; do add_group $group $((i++)) done cat <<-END_CONF >$STAGE/etc/nsswitch.conf passwd: files group: files hosts: files dns END_CONF } export PATH+=:$(dirname $0) export STAGE=${STAGE-$DEFAULT_STAGE} echo "$(type tput &>/dev/null || exit; tput bold; tput setaf 1)" \ "This script has been deprecated in favour of stage-useradd for adding" \ "usernames and groups." \ "$(type tput &>/dev/null || exit; tput sgr0)" declare -a USERSPEC=() until [[ $# -eq 0 ]]; do case $1 in -h|--help) echo "$USAGE"; exit 0 ;; -s|--stage) STAGE=$2; shift ;; -h|--help) exit 0 ;; -s|--stage) export STAGE=$2; shift ;; --*=*) set -- ${1%=*} ${1#--*=} "${@:2}"; continue ;; --) USERSPEC+=( "$@" ); break ;; *) USERSPEC+=( "$1" ) ;; Loading @@ -109,6 +38,10 @@ until [[ $# -eq 0 ]]; do shift done mkdir -p $STAGE/etc collect-binaries /lib/*/libnss* process_userspec "${USERSPEC[@]}" IFS=, declare -a groups for spec in "${USERSPEC[@]}"; do user=${spec%:*} groups=( ${spec#*:} ) stage-useradd $user "${groups[@]}" done stage-useradd.bash 0 → 100755 +126 −0 Original line number Diff line number Diff line #!/bin/bash # Copyright (c) 2020 Dom Sekotill <dom.sekotill@kodo.org.uk> # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. set -eu -o pipefail declare -r DEFAULT_STAGE=/stage USAGE="Usage: $0 [--help] [-s STAGE] USERNAME [GROUP [GROUP ...]] Add a username to the stage and/or add the user to the given additional groups Arguments: USERNAME The username of the new user to add or user to modify. GROUP A named group to add the user to. Options: -h|--help Show this message and exit. -s|--stage STAGE Set the output stage directory. If it does not exist it will be created. (default: $DEFAULT_STAGE) Environment: STAGE: An alternate way of providing --stage " declare -A USERS=() declare -A GROUP=() declare -r PASSWDFD=3 GROUPFD=4 read_users() { [[ -e $STAGE/etc/passwd ]] || return 0 local IFS=: name while read name _; do [[ $name = root ]] && continue USERS[$name]= done <$STAGE/etc/passwd } read_groups() { [[ -e $STAGE/etc/group ]] || return 0 local IFS=: name users while read name _ _ users; do [[ $name = root ]] && continue GROUP[$name]=$users done <$STAGE/etc/group } add_user() { local user=$1 group for group in "${@:2}"; do [[ $group = $user ]] && continue GROUP[$user]+=$group, done USERS[$user]= } write_group() { local users=${GROUP[$1]-} echo "$1:x:$2:${users%,}" >&$GROUPFD unset GROUP_USERS[$1] } write_user() { echo "$1:x:$2:$2::/:/bin/nologin" >&$PASSWDFD } write_files() { local user group i exec 3>$STAGE/etc/passwd.tmp 4>$STAGE/etc/group.tmp write_user root 0 write_group root 0 i=0 for user in "${!USERS[@]}"; do write_user $user $((++i)) write_group $user $i done i=500 for group in "${!GROUP_USERS[@]}"; do write_group $group $((i++)) done mv $STAGE/etc/passwd.tmp $STAGE/etc/passwd mv $STAGE/etc/group.tmp $STAGE/etc/group } export PATH+=:$(dirname $0) export STAGE=${STAGE-$DEFAULT_STAGE} declare -a ARGS=() until [[ $# -eq 0 ]]; do case $1 in -h|--help) echo "$USAGE"; exit 0 ;; -s|--stage) STAGE=$2; shift ;; --*=*) set -- ${1%=*} ${1#--*=} "${@:2}"; continue ;; --) ARGS+=( "$@" ); break ;; *) ARGS+=( "$1" ) ;; esac shift done [[ -e $STAGE/etc/passwd ]] || bootstrap-stage read_users read_groups add_user "${ARGS[@]}" write_files Loading
Dockerfile +2 −0 Original line number Diff line number Diff line Loading @@ -2,8 +2,10 @@ FROM debian:buster-slim as collect COPY LICENCE.txt /stage/LICENCE.txt COPY bootstrap-stage.bash /stage/scripts/bootstrap-stage COPY collect-binaries.bash /stage/scripts/collect-binaries COPY config-nsswitch.bash /stage/scripts/config-nsswitch COPY stage-useradd.bash /stage/scripts/stage-useradd RUN /stage/scripts/collect-binaries /bin/bash FROM scratch Loading
bootstrap-stage.bash 0 → 100755 +63 −0 Original line number Diff line number Diff line #!/bin/bash # Copyright (c) 2020 Dom Sekotill <dom.sekotill@kodo.org.uk> # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. set -eu -o pipefail declare -r DEFAULT_STAGE=/stage USAGE="Usage: $0 [--help] [-s STAGE] Prepare the necessary components of an image in a staging directory Options: -h|--help Show this message and exit. -s|--stage STAGE Set the output stage directory. If it does not exist it will be created. (default: $DEFAULT_STAGE) Environment: STAGE: An alternate way of providing --stage " export PATH+=:$(dirname $0) export STAGE=${STAGE-$DEFAULT_STAGE} until [[ $# -eq 0 ]]; do case $1 in -h|--help) echo "$USAGE"; exit 0 ;; -s|--stage) STAGE=$2; shift ;; --*=*) set -- ${1%=*} ${1#--*=} "${@:2}"; continue ;; *) echo >&2 "Unknown argument: $1"; exit 2 ;; esac shift done # nsswitch (if present, only on GNU libc platforms) mkdir -p $STAGE/etc collect-binaries /lib/*/libnss* && cat <<-END_CONF >$STAGE/etc/nsswitch.conf passwd: files group: files hosts: files dns END_CONF # Temp directories mkdir -p $STAGE/var/tmp chmod 1777 $STAGE/var/tmp test -h $STAGE/tmp || ln -s /var/tmp $STAGE/tmp
config-nsswitch.bash +13 −80 Original line number Diff line number Diff line Loading @@ -20,88 +20,17 @@ # SOFTWARE. set -eu -o pipefail declare -r DEFAULT_STAGE=/stage USAGE="Usage: $0 [--help] [-s STAGE] [USERNAME[:GROUP[,GROUP...]] ...] Prepare the necessary libraries and configuration for name lookups with nsswitch The Name Service Switch system is used by the GNU C library to provide various types of name lookup including: user names, group names, and host names. This script configures an image for those name look-ups. Hostname lookups are configured to use /etc/hosts (as supplied by Docker) and DNS. Users and groups are configured from command line arguments which supply usernames and optional comma separated group names. Only *additional* groups need be specified, not the user's default group which has the same name as the user. The root user is always created if not specified. Options: -h|--help Show this message and exit. -s|--stage STAGE Set the output stage directory. If it does not exist it will be created. (default: $DEFAULT_STAGE) Environment: STAGE: An alternate way of providing --stage " add_group() { local IFS= users=${GROUP_USERS[$1]-} echo "$1:x:$2:${users%,}" >>$STAGE/etc/group unset GROUP_USERS[$1] } add_user() { echo "$1:x:$2:$2::/:/bin/nologin" >>$STAGE/etc/passwd } process_userspec() { declare -a USERS=() declare -A GROUP_USERS=() declare -a groups local IFS=, spec user group i for spec in "$@"; do user=${spec%:*} groups=( ${spec#*:} ) USERS+=( $user ) GROUP_USERS[$user]+="" for group in "${groups[@]}"; do [[ $group = $user ]] && continue GROUP_USERS[$group]+="$user," done done add_user root 0 add_group root 0 i=0 for user in "${USERS[@]}"; do add_user $user $((++i)) add_group $user $i done i=500 for group in "${!GROUP_USERS[@]}"; do add_group $group $((i++)) done cat <<-END_CONF >$STAGE/etc/nsswitch.conf passwd: files group: files hosts: files dns END_CONF } export PATH+=:$(dirname $0) export STAGE=${STAGE-$DEFAULT_STAGE} echo "$(type tput &>/dev/null || exit; tput bold; tput setaf 1)" \ "This script has been deprecated in favour of stage-useradd for adding" \ "usernames and groups." \ "$(type tput &>/dev/null || exit; tput sgr0)" declare -a USERSPEC=() until [[ $# -eq 0 ]]; do case $1 in -h|--help) echo "$USAGE"; exit 0 ;; -s|--stage) STAGE=$2; shift ;; -h|--help) exit 0 ;; -s|--stage) export STAGE=$2; shift ;; --*=*) set -- ${1%=*} ${1#--*=} "${@:2}"; continue ;; --) USERSPEC+=( "$@" ); break ;; *) USERSPEC+=( "$1" ) ;; Loading @@ -109,6 +38,10 @@ until [[ $# -eq 0 ]]; do shift done mkdir -p $STAGE/etc collect-binaries /lib/*/libnss* process_userspec "${USERSPEC[@]}" IFS=, declare -a groups for spec in "${USERSPEC[@]}"; do user=${spec%:*} groups=( ${spec#*:} ) stage-useradd $user "${groups[@]}" done
stage-useradd.bash 0 → 100755 +126 −0 Original line number Diff line number Diff line #!/bin/bash # Copyright (c) 2020 Dom Sekotill <dom.sekotill@kodo.org.uk> # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. set -eu -o pipefail declare -r DEFAULT_STAGE=/stage USAGE="Usage: $0 [--help] [-s STAGE] USERNAME [GROUP [GROUP ...]] Add a username to the stage and/or add the user to the given additional groups Arguments: USERNAME The username of the new user to add or user to modify. GROUP A named group to add the user to. Options: -h|--help Show this message and exit. -s|--stage STAGE Set the output stage directory. If it does not exist it will be created. (default: $DEFAULT_STAGE) Environment: STAGE: An alternate way of providing --stage " declare -A USERS=() declare -A GROUP=() declare -r PASSWDFD=3 GROUPFD=4 read_users() { [[ -e $STAGE/etc/passwd ]] || return 0 local IFS=: name while read name _; do [[ $name = root ]] && continue USERS[$name]= done <$STAGE/etc/passwd } read_groups() { [[ -e $STAGE/etc/group ]] || return 0 local IFS=: name users while read name _ _ users; do [[ $name = root ]] && continue GROUP[$name]=$users done <$STAGE/etc/group } add_user() { local user=$1 group for group in "${@:2}"; do [[ $group = $user ]] && continue GROUP[$user]+=$group, done USERS[$user]= } write_group() { local users=${GROUP[$1]-} echo "$1:x:$2:${users%,}" >&$GROUPFD unset GROUP_USERS[$1] } write_user() { echo "$1:x:$2:$2::/:/bin/nologin" >&$PASSWDFD } write_files() { local user group i exec 3>$STAGE/etc/passwd.tmp 4>$STAGE/etc/group.tmp write_user root 0 write_group root 0 i=0 for user in "${!USERS[@]}"; do write_user $user $((++i)) write_group $user $i done i=500 for group in "${!GROUP_USERS[@]}"; do write_group $group $((i++)) done mv $STAGE/etc/passwd.tmp $STAGE/etc/passwd mv $STAGE/etc/group.tmp $STAGE/etc/group } export PATH+=:$(dirname $0) export STAGE=${STAGE-$DEFAULT_STAGE} declare -a ARGS=() until [[ $# -eq 0 ]]; do case $1 in -h|--help) echo "$USAGE"; exit 0 ;; -s|--stage) STAGE=$2; shift ;; --*=*) set -- ${1%=*} ${1#--*=} "${@:2}"; continue ;; --) ARGS+=( "$@" ); break ;; *) ARGS+=( "$1" ) ;; esac shift done [[ -e $STAGE/etc/passwd ]] || bootstrap-stage read_users read_groups add_user "${ARGS[@]}" write_files