Merge branch 'fix/restore-skip-chown-non-root'
All checks were successful
check / check (push) Successful in 2m0s
All checks were successful
check / check (push) Successful in 2m0s
This commit is contained in:
@@ -126,6 +126,10 @@ func (v *Vaultik) Restore(opts *RestoreOptions) error {
|
|||||||
v.UI.Duration(result.Duration),
|
v.UI.Duration(result.Duration),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if os.Geteuid() != 0 {
|
||||||
|
v.UI.Warning("Restore did not preserve file ownership: chown(2) requires root. Re-run as root (e.g. with sudo) if you need original UID/GID preserved.")
|
||||||
|
}
|
||||||
|
|
||||||
if result.FilesFailed > 0 {
|
if result.FilesFailed > 0 {
|
||||||
v.UI.Warning("%d file(s) failed to restore:", result.FilesFailed)
|
v.UI.Warning("%d file(s) failed to restore:", result.FilesFailed)
|
||||||
for _, path := range result.FailedFiles {
|
for _, path := range result.FailedFiles {
|
||||||
@@ -247,6 +251,7 @@ func (v *Vaultik) restoreAllFiles(
|
|||||||
blobCache: blobCache,
|
blobCache: blobCache,
|
||||||
sweeper: sweeper,
|
sweeper: sweeper,
|
||||||
result: result,
|
result: result,
|
||||||
|
runningAsRoot: os.Geteuid() == 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Periodic progress output, matching the snapshot create cadence.
|
// Periodic progress output, matching the snapshot create cadence.
|
||||||
@@ -536,6 +541,13 @@ type restoreSession struct {
|
|||||||
blobCache *blobDiskCache
|
blobCache *blobDiskCache
|
||||||
sweeper *restoreSweeper
|
sweeper *restoreSweeper
|
||||||
result *RestoreResult
|
result *RestoreResult
|
||||||
|
// runningAsRoot gates chown(2). On every Unix-ish kernel, only
|
||||||
|
// root can chown a file to an arbitrary UID/GID — non-root chown
|
||||||
|
// always fails with EPERM. Attempting it anyway produces N
|
||||||
|
// guaranteed-failed syscalls + N noisy debug lines, so we skip
|
||||||
|
// the call entirely as non-root and emit one warning at the end
|
||||||
|
// of the restore explaining that ownership was not preserved.
|
||||||
|
runningAsRoot bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// restoreFile dispatches to the right per-kind restorer.
|
// restoreFile dispatches to the right per-kind restorer.
|
||||||
@@ -580,11 +592,13 @@ func (s *restoreSession) restoreDirectory(file *database.File, targetPath string
|
|||||||
if err := s.v.Fs.Chmod(targetPath, os.FileMode(file.Mode)); err != nil {
|
if err := s.v.Fs.Chmod(targetPath, os.FileMode(file.Mode)); err != nil {
|
||||||
log.Debug("Failed to set directory permissions", "path", targetPath, "error", err)
|
log.Debug("Failed to set directory permissions", "path", targetPath, "error", err)
|
||||||
}
|
}
|
||||||
|
if s.runningAsRoot {
|
||||||
if _, ok := s.v.Fs.(*afero.OsFs); ok {
|
if _, ok := s.v.Fs.(*afero.OsFs); ok {
|
||||||
if err := os.Chown(targetPath, int(file.UID), int(file.GID)); err != nil {
|
if err := os.Chown(targetPath, int(file.UID), int(file.GID)); err != nil {
|
||||||
log.Debug("Failed to set directory ownership", "path", targetPath, "error", err)
|
log.Debug("Failed to set directory ownership", "path", targetPath, "error", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if err := s.v.Fs.Chtimes(targetPath, file.MTime, file.MTime); err != nil {
|
if err := s.v.Fs.Chtimes(targetPath, file.MTime, file.MTime); err != nil {
|
||||||
log.Debug("Failed to set directory mtime", "path", targetPath, "error", err)
|
log.Debug("Failed to set directory mtime", "path", targetPath, "error", err)
|
||||||
}
|
}
|
||||||
@@ -671,11 +685,13 @@ func (s *restoreSession) restoreRegularFile(file *database.File, targetPath stri
|
|||||||
if err := s.v.Fs.Chmod(targetPath, os.FileMode(file.Mode)); err != nil {
|
if err := s.v.Fs.Chmod(targetPath, os.FileMode(file.Mode)); err != nil {
|
||||||
log.Debug("Failed to set file permissions", "path", targetPath, "error", err)
|
log.Debug("Failed to set file permissions", "path", targetPath, "error", err)
|
||||||
}
|
}
|
||||||
|
if s.runningAsRoot {
|
||||||
if _, ok := s.v.Fs.(*afero.OsFs); ok {
|
if _, ok := s.v.Fs.(*afero.OsFs); ok {
|
||||||
if err := os.Chown(targetPath, int(file.UID), int(file.GID)); err != nil {
|
if err := os.Chown(targetPath, int(file.UID), int(file.GID)); err != nil {
|
||||||
log.Debug("Failed to set file ownership", "path", targetPath, "error", err)
|
log.Debug("Failed to set file ownership", "path", targetPath, "error", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if err := s.v.Fs.Chtimes(targetPath, file.MTime, file.MTime); err != nil {
|
if err := s.v.Fs.Chtimes(targetPath, file.MTime, file.MTime); err != nil {
|
||||||
log.Debug("Failed to set file mtime", "path", targetPath, "error", err)
|
log.Debug("Failed to set file mtime", "path", targetPath, "error", err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user