From 7f20036b15aa4ad04889751c81dbba97f56541d4 Mon Sep 17 00:00:00 2001 From: Diulgher Artiom <42372666+GeneralTao2@users.noreply.github.com> Date: Sun, 2 Apr 2023 12:12:10 +0300 Subject: [PATCH] Possibility to use -u (user) option in docker exec (#203) * Add user option for docker exec * Add test for user option * Return test version for image * remove gitea config file * refactor tests * remove comments & fix image name * add docs * cleanup * Update README.md with suggested correction Co-authored-by: Frederik Ring * fix backup command & bind folder instead of volume --------- Co-authored-by: tao Co-authored-by: Frederik Ring --- README.md | 2 ++ cmd/backup/exec.go | 8 ++++++-- test/user/.gitignore | 2 ++ test/user/docker-compose.yml | 30 ++++++++++++++++++++++++++++++ test/user/run.sh | 30 ++++++++++++++++++++++++++++++ 5 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 test/user/.gitignore create mode 100644 test/user/docker-compose.yml create mode 100644 test/user/run.sh diff --git a/README.md b/README.md index 371bbc7..4d58f16 100644 --- a/README.md +++ b/README.md @@ -644,6 +644,8 @@ volumes: The backup procedure is guaranteed to wait for all `pre` or `post` commands to finish before proceeding. However there are no guarantees about the order in which they are run, which could also happen concurrently. +By default the backup command is executed by the root user. It is possible to specify a custom user in container labels with the format `docker-volume-backup.[step]-[pre|post]-[user]`. The option will allow you to run a specific step command by specified user. Make sure the user exists and present in `passwd` inside the target container. + ### Encrypting your backup using GPG The image supports encrypting backups using GPG out of the box. diff --git a/cmd/backup/exec.go b/cmd/backup/exec.go index acc0efd..235c69c 100644 --- a/cmd/backup/exec.go +++ b/cmd/backup/exec.go @@ -21,7 +21,7 @@ import ( "golang.org/x/sync/errgroup" ) -func (s *script) exec(containerRef string, command string) ([]byte, []byte, error) { +func (s *script) exec(containerRef string, command string, user string) ([]byte, []byte, error) { args, _ := argv.Argv(command, nil, nil) commandEnv := []string{ fmt.Sprintf("COMMAND_RUNTIME_ARCHIVE_FILEPATH=%s", s.file), @@ -31,6 +31,7 @@ func (s *script) exec(containerRef string, command string) ([]byte, []byte, erro AttachStdin: true, AttachStderr: true, Env: commandEnv, + User: user, }) if err != nil { return nil, nil, fmt.Errorf("exec: error creating container exec: %w", err) @@ -159,8 +160,11 @@ func (s *script) runLabeledCommands(label string) error { cmd, _ = c.Labels["docker-volume-backup.exec-post"] } + userLabelName := fmt.Sprintf("%s.user", label) + user := c.Labels[userLabelName] + s.logger.Infof("Running %s command %s for container %s", label, cmd, strings.TrimPrefix(c.Names[0], "/")) - stdout, stderr, err := s.exec(c.ID, cmd) + stdout, stderr, err := s.exec(c.ID, cmd, user) if s.c.ExecForwardOutput { os.Stderr.Write(stderr) os.Stdout.Write(stdout) diff --git a/test/user/.gitignore b/test/user/.gitignore new file mode 100644 index 0000000..f7f57bb --- /dev/null +++ b/test/user/.gitignore @@ -0,0 +1,2 @@ +local +backup \ No newline at end of file diff --git a/test/user/docker-compose.yml b/test/user/docker-compose.yml new file mode 100644 index 0000000..0c2d4bb --- /dev/null +++ b/test/user/docker-compose.yml @@ -0,0 +1,30 @@ +version: '2.4' + +services: + alpine: + image: alpine:3.17.3 + tty: true + volumes: + - app_data:/tmp + labels: + - docker-volume-backup.archive-pre.user=testuser + - docker-volume-backup.archive-pre=/bin/sh -c 'whoami > /tmp/whoami.txt' + + + backup: + image: offen/docker-volume-backup:${TEST_VERSION:-canary} + deploy: + restart_policy: + condition: on-failure + environment: + BACKUP_FILENAME: test.tar.gz + BACKUP_CRON_EXPRESSION: 0 0 5 31 2 ? + EXEC_FORWARD_OUTPUT: "true" + volumes: + - ./local:/archive + - app_data:/backup/data:ro + - /var/run/docker.sock:/var/run/docker.sock + +volumes: + app_data: + archive: \ No newline at end of file diff --git a/test/user/run.sh b/test/user/run.sh new file mode 100644 index 0000000..26ce8e5 --- /dev/null +++ b/test/user/run.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +set -e + +cd $(dirname $0) +. ../util.sh +current_test=$(basename $(pwd)) + +docker compose up -d + +user_name=testuser +docker exec user-alpine-1 adduser --disabled-password "$user_name" + +docker compose exec backup backup + +tar -xvf ./local/test.tar.gz +if [ ! -f ./backup/data/whoami.txt ]; then + fail "Could not find file written by pre command." +fi +pass "Found expected file." + +tar -xvf ./local/test.tar.gz +if [ "$(cat ./backup/data/whoami.txt)" != "$user_name" ]; then + fail "Could not find expected user name." +fi +pass "Found expected user." + +docker compose down --volumes +sudo rm -rf ./local +