diff --git a/sftp/hooks/init b/sftp/hooks/init index 48094b0..a26e3ad 100755 --- a/sftp/hooks/init +++ b/sftp/hooks/init @@ -19,9 +19,10 @@ set -e service_def=$(get_compose_service_def "$SERVICE_NAME") +existing_gids=($(cached_cmd_on_base_image "$SERVICE_NAME" getent group | cut -f 1,3 -d :)) users_def=$(echo "$service_def" | shyaml get-value options.users 2>/dev/null) || true -build_script="$(make_build_script "$users_def")" || exit 1 +build_script="$(make_build_script "$users_def" "${existing_gids[@]}")" || exit 1 echo "build-script:" >&2 echo "$build_script" | prefix " $GRAY|$NORMAL " >&2 docker_update "$SERVICE_NAME" "$build_script" -v "$SERVICE_DATASTORE/home":"/home" || exit 1 diff --git a/sftp/lib/common b/sftp/lib/common index 79f3a24..7610908 100644 --- a/sftp/lib/common +++ b/sftp/lib/common @@ -9,22 +9,33 @@ make_build_script() { touch "$cache_file" || return 1 return 0 fi + ## remaining arguments are the group_label:gid list that should be + ## avoided for creation (because already existent ?) + shift - local users_def="$1" \ - code fixed_groups_code groups_code volume_keys \ - created_groups first_group + local code fixed_groups_code groups_code \ + created_groups first_group gids if [ -z "$users_def" ]; then return 0 fi - e "set -eux"$'\n' code="" fixed_groups_code="" groups_code="" - volume_keys=() - + gids=() declare -A created_groups + for group in "$@"; do + if [[ "$group" != *":"* ]]; then + err "Invalid group specification given from script" + return 1 + fi + gid=${group##*:} + gids+=("$gid") + group_label=${group%%:*} + created_groups[$group_label]="$gid" + done + while read-0 user user_def; do code+="mkdir -p \"/home/$user\""$'\n' @@ -34,28 +45,51 @@ make_build_script() { ## first_group= - groups=() first=1 while read-0 group; do - [ "${created_groups[$group]}" ] && continue + gid="unspecified" if [[ "$group" == *":"* ]]; then gid=${group##*:} - group=${group%%:*} - fixed_groups_code+="addgroup -g \"$gid\" \"$group\""$'\n' + if ! [[ "$gid" =~ ^[0-9]+$ ]]; then + err "gid part (after ':') should be numerical not '$gid'." + return 1 + fi + group_label=${group%%:*} else - groups_code+="addgroup \"$group\""$'\n' + group_label="$group" fi - created_groups[$group]=1 + if [ "${created_groups[$group_label]}" ]; then ## already met this group + ## double-check we did not give conflicting gid information + if [[ "${created_groups[$group_label]}" != "$gid" ]]; then + err "Conflicting setup: using existing group '$group_label' for user '$user'" \ + "with different GIDs specification" \ + "(previous was ${created_groups[$group_label]}, current one is $gid)." + return 1 + fi + else + if [[ "$gid" != unspecified ]]; then + ## check not already used + if [[ " ${gids[*]} " == *" $gid "* ]]; then + err "gid $gid is alreay used and is not available." + return 1 + fi + fixed_groups_code+="addgroup -g \"$gid\" \"$group_label\""$'\n' + else + groups_code+="addgroup \"$group\""$'\n' + fi + created_groups[$group_label]="$gid" + fi + echo "First: $first" >&2 + echo "First: $group_label" >&2 if [ "$first" ]; then - first_group="$group" + echo "FG1: $first_group" >&2 + first_group="$group_label" first= else - remaining_groups+=("$group") + remaining_groups+=("$group_label") fi - groups+=("$group") done < <(echo "$user_def" | shyaml get-values-0 groups 2>/dev/null) - ## ## User create commands ##