uninstall: limit cleanup to s.Target

This was specific to when s.Target differs from /. The helpers creating
the path were considering the full traversal, instead they should stop
at target.

E.g. our rootfs is in /foo/bar, and while we build the list of paths to
prune for /foo/bar/baz/bar, we should stop looking at /foo/bar.
This commit is contained in:
Ettore Di Giacinto 2021-10-21 21:26:48 +02:00
parent 7b56e915fa
commit d58a563d52
2 changed files with 34 additions and 17 deletions

View File

@ -23,6 +23,7 @@ import (
"path/filepath" "path/filepath"
"github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/archive"
"github.com/pkg/errors"
) )
func Tar(src, dest string) error { func Tar(src, dest string) error {
@ -131,7 +132,7 @@ func unTarIgnoreOwner(dest string, in io.ReadCloser, mods map[string]archive.Tar
if ok { if ok {
header, data, err = modifier(header.Name, header, tr) header, data, err = modifier(header.Name, header, tr)
if err != nil { if err != nil {
return err return errors.Wrap(err, "running modifier wrapper")
} }
// Override target path // Override target path
@ -157,7 +158,7 @@ func unTarIgnoreOwner(dest string, in io.ReadCloser, mods map[string]archive.Tar
f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode)) f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode))
if err != nil { if err != nil {
return err return errors.Wrap(err, "creating destination")
} }
// copy over contents // copy over contents
@ -188,12 +189,11 @@ tarEof:
} }
// Untar just a wrapper around the docker functions // Untar just a wrapper around the docker functions
func Untar(src, dest string, sameOwner bool) error { func Untar(src, dest string, sameOwner bool) (err error) {
var ans error
in, err := os.Open(src) in, err := os.Open(src)
if err != nil { if err != nil {
return err return errors.Wrap(err, "while opening "+src+" for untar ")
} }
defer in.Close() defer in.Close()
@ -204,10 +204,14 @@ func Untar(src, dest string, sameOwner bool) error {
ContinueOnError: true, ContinueOnError: true,
} }
ans = archive.Untar(in, dest, opts) err = archive.Untar(in, dest, opts)
} else { } else {
ans = unTarIgnoreOwner(dest, in, nil) err = unTarIgnoreOwner(dest, in, nil)
} }
return ans if err != nil {
err = errors.Wrap(err, "while untarring "+src+" into "+dest)
}
return
} }

View File

@ -902,7 +902,7 @@ func (l *LuetInstaller) installPackage(m ArtifactMatch, s *System) error {
err = a.Unpack(l.Options.Context, s.Target, true) err = a.Unpack(l.Options.Context, s.Target, true)
if err != nil && !l.Options.Force { if err != nil && !l.Options.Force {
return errors.Wrap(err, "Error met while unpacking rootfs") return errors.Wrap(err, "error met while unpacking package "+a.Path)
} }
// First create client and download // First create client and download
@ -950,10 +950,14 @@ func (l *LuetInstaller) installerWorker(i int, wg *sync.WaitGroup, c <-chan Arti
return nil return nil
} }
func checkAndPrunePath(ctx *types.Context, path string) { func checkAndPrunePath(ctx *types.Context, target, path string) {
// check if now the target path is empty // check if now the target path is empty
targetPath := filepath.Dir(path) targetPath := filepath.Dir(path)
if target == targetPath {
return
}
fi, err := os.Lstat(targetPath) fi, err := os.Lstat(targetPath)
if err != nil { if err != nil {
// l.Options.Context.Warning("Dir not found (it was before?) ", err.Error()) // l.Options.Context.Warning("Dir not found (it was before?) ", err.Error())
@ -978,8 +982,8 @@ func checkAndPrunePath(ctx *types.Context, path string) {
} }
// We will try to cleanup every path from the file, if the folders left behind are empty // We will try to cleanup every path from the file, if the folders left behind are empty
func pruneEmptyFilePath(ctx *types.Context, path string) { func pruneEmptyFilePath(ctx *types.Context, target string, path string) {
checkAndPrunePath(ctx, path) checkAndPrunePath(ctx, target, path)
// A path is for e.g. /usr/bin/bar // A path is for e.g. /usr/bin/bar
// we want to create an array // we want to create an array
@ -987,14 +991,19 @@ func pruneEmptyFilePath(ctx *types.Context, path string) {
// excluding the target (in the case above was /) // excluding the target (in the case above was /)
paths := strings.Split(path, string(os.PathSeparator)) paths := strings.Split(path, string(os.PathSeparator))
currentPath := filepath.Join(string(os.PathSeparator), paths[0]) currentPath := filepath.Join(string(os.PathSeparator), paths[0])
allPaths := []string{currentPath} allPaths := []string{}
if strings.HasPrefix(currentPath, target) && target != currentPath {
allPaths = append(allPaths, currentPath)
}
for _, p := range paths[1:] { for _, p := range paths[1:] {
currentPath = filepath.Join(currentPath, p) currentPath = filepath.Join(currentPath, p)
if strings.HasPrefix(currentPath, target) && target != currentPath {
allPaths = append(allPaths, currentPath) allPaths = append(allPaths, currentPath)
} }
}
match.ReverseAny(allPaths) match.ReverseAny(allPaths)
for _, p := range allPaths { for _, p := range allPaths {
checkAndPrunePath(ctx, p) checkAndPrunePath(ctx, target, p)
} }
} }
@ -1058,9 +1067,11 @@ func (l *LuetInstaller) uninstall(p pkg.Package, s *System) error {
if err = os.Remove(target); err != nil { if err = os.Remove(target); err != nil {
l.Options.Context.Warning("Failed removing file (maybe not present in the system target anymore ?)", target, err.Error()) l.Options.Context.Warning("Failed removing file (maybe not present in the system target anymore ?)", target, err.Error())
} else {
l.Options.Context.Debug("Removed", target)
} }
pruneEmptyFilePath(l.Options.Context, target) pruneEmptyFilePath(l.Options.Context, s.Target, target)
} }
for _, f := range notPresent { for _, f := range notPresent {
@ -1073,9 +1084,11 @@ func (l *LuetInstaller) uninstall(p pkg.Package, s *System) error {
if err = os.Remove(target); err != nil { if err = os.Remove(target); err != nil {
l.Options.Context.Debug("Failed removing file (not present in the system target)", target, err.Error()) l.Options.Context.Debug("Failed removing file (not present in the system target)", target, err.Error())
} else {
l.Options.Context.Debug("Removed", target)
} }
pruneEmptyFilePath(l.Options.Context, target) pruneEmptyFilePath(l.Options.Context, s.Target, target)
} }
err = s.Database.RemovePackageFiles(p) err = s.Database.RemovePackageFiles(p)