Merge pull request #8805 from RichardDorian/master

Allow custom values for chown
This commit is contained in:
Jose Diaz-Gonzalez
2026-07-08 18:09:31 -04:00
committed by GitHub
5 changed files with 101 additions and 8 deletions

View File

@@ -106,6 +106,8 @@ By default, permissions are set for usage with Herokuish buildpacks. These permi
- `--chown root`: Use `0:0` as the folder permissions.
- This is used for containers that run their processes as root, as is typical for most Dockerfile or Docker image deploys.
- `--chown false`: Skips the `chown` call.
- `--chown <uid>`: Use `<uid>:<uid>` as the folder permissions, where `<uid>` is a custom numeric user/group id.
- This is used for containers that run their processes as a uid/gid that doesn't correspond to any of the above named options.
Users deploying via Dockerfile will want to specify `--chown false` and manually `chown` the created directory if the user and/or group id of the runnning process in the deployed container do not correspond to any of the above options.

View File

@@ -16,13 +16,15 @@ main() {
exit 1
fi
case "$CHOWN_ID" in
0 | 1000 | 2000 | 32767 | 165536 | 166536 | 167536 | 198303) ;;
*)
echo " ! Unsupported chown permissions. Supported values: 0, 1000, 2000, 32767 (and user namespace offset variants)" 1>&2
exit 1
;;
esac
if [[ ! "$CHOWN_ID" =~ ^[0-9]+$ ]]; then
echo " ! Unsupported chown permissions. Value must be a non-negative integer." 1>&2
exit 1
fi
if ((CHOWN_ID > 65535 && (CHOWN_ID < 165536 || CHOWN_ID > 231071))); then
echo " ! Unsupported chown permissions. Supported values: 0-65535 (and user namespace offset variants, 165536-231071)" 1>&2
exit 1
fi
chown -R "$CHOWN_ID:$CHOWN_ID" "${DOKKU_LIB_ROOT}/data/storage/$DIRECTORY"
}

View File

@@ -6,6 +6,7 @@ import (
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/dokku/dokku/plugins/common"
@@ -99,7 +100,13 @@ func ResolveChownID(chownFlag string) (string, error) {
case "false":
return "false", nil
default:
return "", errors.New("Unsupported chown permissions")
id, err := strconv.ParseUint(chownFlag, 10, 16)
if err != nil {
return "", errors.New("Unsupported chown permissions")
} else {
chownID = fmt.Sprint(id)
}
}
userns, err := isUserNamespacesEnabled()

View File

@@ -0,0 +1,17 @@
package storage
import (
"testing"
. "github.com/onsi/gomega"
)
func TestResolveChownIDRejectsOutOfBoundsValues(t *testing.T) {
RegisterTestingT(t)
for _, chownFlag := range []string{"-1", "65536", "100000", "231072", "abc", "1.5", ""} {
_, err := ResolveChownID(chownFlag)
Expect(err).To(HaveOccurred(), "expected %q to be rejected", chownFlag)
Expect(err.Error()).To(ContainSubstring("Unsupported chown permissions"))
}
}

View File

@@ -107,6 +107,38 @@ teardown() {
assert_output_contains "Setting directory ownership to 32767:32767" 1
}
@test "(storage) chown-storage-dir rejects out-of-bounds chown values" {
run /bin/bash -c "DOKKU_LIB_ROOT=$DOKKU_LIB_ROOT $PLUGIN_AVAILABLE_PATH/storage/bin/chown-storage-dir $TEST_APP 65536"
echo "output: $output"
echo "status: $status"
assert_failure
assert_output_contains "Unsupported chown permissions"
run /bin/bash -c "DOKKU_LIB_ROOT=$DOKKU_LIB_ROOT $PLUGIN_AVAILABLE_PATH/storage/bin/chown-storage-dir $TEST_APP 165535"
echo "output: $output"
echo "status: $status"
assert_failure
assert_output_contains "Unsupported chown permissions"
run /bin/bash -c "DOKKU_LIB_ROOT=$DOKKU_LIB_ROOT $PLUGIN_AVAILABLE_PATH/storage/bin/chown-storage-dir $TEST_APP 231072"
echo "output: $output"
echo "status: $status"
assert_failure
assert_output_contains "Unsupported chown permissions"
run /bin/bash -c "DOKKU_LIB_ROOT=$DOKKU_LIB_ROOT $PLUGIN_AVAILABLE_PATH/storage/bin/chown-storage-dir $TEST_APP -1"
echo "output: $output"
echo "status: $status"
assert_failure
assert_output_contains "Value must be a non-negative integer"
run /bin/bash -c "DOKKU_LIB_ROOT=$DOKKU_LIB_ROOT $PLUGIN_AVAILABLE_PATH/storage/bin/chown-storage-dir $TEST_APP abc"
echo "output: $output"
echo "status: $status"
assert_failure
assert_output_contains "Value must be a non-negative integer"
}
@test "(storage) storage:mount, storage:list, storage:umount" {
run /bin/bash -c "dokku storage:mount $TEST_APP /tmp/mount:/mount"
echo "output: $output"
@@ -394,6 +426,39 @@ teardown() {
assert_success
}
@test "(storage:create) --chown accepts a custom numeric uid" {
run /bin/bash -c "dokku storage:create --chown 1500 rdmtest-chown-numeric"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "stat -c '%u:%g' $DOKKU_LIB_ROOT/data/storage/rdmtest-chown-numeric"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "1500:1500"
run /bin/bash -c "dokku storage:destroy rdmtest-chown-numeric --force"
assert_success
}
@test "(storage:create) --chown rejects an out-of-bounds numeric uid" {
run /bin/bash -c "dokku storage:create --chown 65536 rdmtest-chown-oob"
echo "output: $output"
echo "status: $status"
assert_failure
assert_output_contains "Unsupported chown permissions"
run /bin/bash -c "dokku storage:create --chown -1 rdmtest-chown-oob"
echo "output: $output"
echo "status: $status"
assert_failure
assert_output_contains "Unsupported chown permissions"
run /bin/bash -c "dokku storage:list-entries --format json | jq -r '.[].name' | grep '^rdmtest-chown-oob$' || true"
assert_output ""
}
@test "(storage:create) --chown rejects a non-default host path" {
custom_path="/tmp/rdmtest-chown-custom"
rm -rf "$custom_path"