Call through to cp -p for copying

This commit is contained in:
Frederik Ring 2021-12-10 12:45:34 +01:00
parent 7a5068446a
commit 038116c3a3
3 changed files with 11 additions and 48 deletions

View File

@ -14,7 +14,6 @@ import (
"path"
"path/filepath"
"strings"
"syscall"
"time"
"github.com/docker/docker/api/types"
@ -449,7 +448,7 @@ func (s *script) copyBackup() error {
if err := os.Chown(s.file, s.c.BackupUID, s.c.BackupGID); err != nil {
return fmt.Errorf("copyBackup: error changing owner on temp file: %w", err)
}
if err := copyFile(s.file, path.Join(s.c.BackupArchive, name), s.c.BackupGID, s.c.BackupUID); err != nil {
if err := copyFile(s.file, path.Join(s.c.BackupArchive, name)); err != nil {
return fmt.Errorf("copyBackup: error copying file to local archive: %w", err)
}
s.logger.Infof("Stored copy of backup `%s` in local archive `%s`.", s.file, s.c.BackupArchive)
@ -688,45 +687,9 @@ func lock(lockfile string) func() error {
}
// copy creates a copy of the file located at `dst` at `src`.
func copyFile(src, dst string, uid, gid int) error {
in, err := os.Open(src)
if err != nil {
return fmt.Errorf("copyFile: error opening source file: %w", err)
}
defer in.Close()
out, err := touch(dst, uid, gid)
if err != nil {
return fmt.Errorf("copyFile: error creating destination: %w", err)
}
_, err = io.Copy(out, in)
if err != nil {
out.Close()
return fmt.Errorf("copyFile: error copying: %w", err)
}
return out.Close()
}
func touch(file string, uid, gid int) (*os.File, error) {
if uid < 1 || gid < 1 {
out, err := os.Create(file)
if err != nil {
return nil, fmt.Errorf("touch: error creating destination: %w", err)
}
return out, nil
}
cmd := exec.Command("sudo", "-u", fmt.Sprintf("%d", uid), "touch", file)
syscall.Umask(0077)
cmd.SysProcAttr = &syscall.SysProcAttr{}
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
if err := cmd.Run(); err != nil {
return nil, fmt.Errorf("touch: error creating destination for owner %d:%d: %w", uid, gid, err)
}
return os.Open(file)
func copyFile(src, dst string) error {
cmd := exec.Command("cp", "-p", src, dst)
return cmd.Run()
}
// join takes a list of errors and joins them into a single error

View File

@ -30,8 +30,8 @@ services:
BACKUP_PRUNING_LEEWAY: 5s
BACKUP_PRUNING_PREFIX: test
GPG_PASSPHRASE: 1234secret
BACKUP_UID: '1000'
BACKUP_GID: '1000'
BACKUP_UID: ${BACKUP_UID:-1000}
BACKUP_GID: ${BACKUP_GID:-1000}
volumes:
- ./local:/archive
- app_data:/backup/app_data:ro

View File

@ -6,11 +6,11 @@ cd $(dirname $0)
mkdir -p local
docker-compose up -d
BACKUP_UID=$(id -u) BACKUP_GID=$(id -g) docker-compose up -d
sleep 5
docker-compose exec offen ln -s /var/opt/offen/offen.db /var/opt/offen/db.link
docker-compose exec backup backup
BACKUP_UID=$(id -u) BACKUP_GID=$(id -g) docker-compose exec offen ln -s /var/opt/offen/offen.db /var/opt/offen/db.link
BACKUP_UID=$(id -u) BACKUP_GID=$(id -g) docker-compose exec backup backup
docker run --rm -it \
-v compose_backup_data:/data alpine \
@ -21,8 +21,8 @@ echo "[TEST:PASS] Found relevant files in untared remote backup."
test -L ./local/test.latest.tar.gz.gpg
owner=$(stat -c '%U:%G' ./local/test.tar.gz.gpg)
if [ "$owner" != "1000:1000" ]; then
echo "[TEST:FAIL] Expected backup file to have correct owners, got $owner"
if [ "$owner" != "$(id -un):$(id -gn)" ]; then
echo "[TEST:FAIL] Expected backup file to have correct owners, expected "$(id -un):$(id -gn)", got $owner"
exit 1
fi