Skip to content
This repository was archived by the owner on Mar 27, 2024. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ var cacheDir string
var LogLevel string
var format string

var keepOwner bool
const containerDiffEnvCacheDir = "CONTAINER_DIFF_CACHEDIR"

type validatefxn func(args []string) error
Expand Down Expand Up @@ -147,7 +148,7 @@ func getImage(imageName string) (pkgutil.Image, error) {
return pkgutil.Image{}, err
}
}
return pkgutil.GetImage(imageName, includeLayers(), cachePath)
return pkgutil.GetImage(imageName, includeLayers(), keepOwner, cachePath)
}

func getCacheDir(imageName string) (string, error) {
Expand Down Expand Up @@ -239,6 +240,7 @@ func addSharedFlags(cmd *cobra.Command) {
cmd.Flags().BoolVarP(&save, "save", "s", false, "Set this flag to save rather than remove the final image filesystems on exit.")
cmd.Flags().BoolVarP(&util.SortSize, "order", "o", false, "Set this flag to sort any file/package results by descending size. Otherwise, they will be sorted by name.")
cmd.Flags().BoolVarP(&noCache, "no-cache", "n", false, "Set this to force retrieval of image filesystem on each run.")
cmd.Flags().BoolVarP(&keepOwner, "keep-owner", "k", false, "Set this to keep the owner of image filesystem. Make sure you are a root user for setting this value.")
cmd.Flags().StringVarP(&cacheDir, "cache-dir", "c", "", "cache directory base to create .container-diff (default is $HOME).")
cmd.Flags().StringVarP(&outputFile, "output", "w", "", "output file to write to (default writes to the screen).")
cmd.Flags().BoolVar(&forceWrite, "force", false, "force overwrite output file, if exists already.")
Expand Down
16 changes: 8 additions & 8 deletions pkg/util/image_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,13 @@ type ImageHistoryItem struct {
// GetImageForName retrieves an image by name alone.
// It does not return layer information, or respect caching.
func GetImageForName(imageName string) (Image, error) {
return GetImage(imageName, false, "")
return GetImage(imageName, false, false, "")
}

// GetImage infers the source of an image and retrieves a v1.Image reference to it.
// Once a reference is obtained, it attempts to unpack the v1.Image's reader's contents
// into a temp directory on the local filesystem.
func GetImage(imageName string, includeLayers bool, cacheDir string) (Image, error) {
func GetImage(imageName string, includeLayers, keepOwner bool, cacheDir string) (Image, error) {
logrus.Infof("retrieving image: %s", imageName)
var img v1.Image
var err error
Expand Down Expand Up @@ -141,7 +141,7 @@ func GetImage(imageName string, includeLayers bool, cacheDir string) (Image, err
Layers: layers,
}, errors.Wrap(err, "getting extract path for layer")
}
if err := GetFileSystemForLayer(layer, path, nil); err != nil {
if err := GetFileSystemForLayer(layer, path, nil, keepOwner); err != nil {
return Image{
Layers: layers,
}, errors.Wrap(err, "getting filesystem for layer")
Expand All @@ -166,7 +166,7 @@ func GetImage(imageName string, includeLayers bool, cacheDir string) (Image, err
return Image{}, err
}
// extract fs into provided dir
if err := GetFileSystemForImage(img, path, nil); err != nil {
if err := GetFileSystemForImage(img, path, nil, keepOwner); err != nil {
return Image{
FSPath: path,
Layers: layers,
Expand Down Expand Up @@ -241,7 +241,7 @@ func SortMap(m map[string]string) string {
}

// GetFileSystemForLayer unpacks a layer to local disk
func GetFileSystemForLayer(layer v1.Layer, root string, whitelist []string) error {
func GetFileSystemForLayer(layer v1.Layer, root string, whitelist []string, keepOwner bool) error {
empty, err := DirIsEmpty(root)
if err != nil {
return err
Expand All @@ -254,12 +254,12 @@ func GetFileSystemForLayer(layer v1.Layer, root string, whitelist []string) erro
if err != nil {
return err
}
return unpackTar(tar.NewReader(contents), root, whitelist)
return unpackTar(tar.NewReader(contents), root, whitelist, keepOwner)
}

// unpack image filesystem to local disk
// if provided directory is not empty, do nothing
func GetFileSystemForImage(image v1.Image, root string, whitelist []string) error {
func GetFileSystemForImage(image v1.Image, root string, whitelist []string, keepOwner bool) error {
empty, err := DirIsEmpty(root)
if err != nil {
return err
Expand All @@ -268,7 +268,7 @@ func GetFileSystemForImage(image v1.Image, root string, whitelist []string) erro
logrus.Infof("using cached filesystem in %s", root)
return nil
}
if err := unpackTar(tar.NewReader(mutate.Extract(image)), root, whitelist); err != nil {
if err := unpackTar(tar.NewReader(mutate.Extract(image)), root, whitelist, keepOwner); err != nil {
return err
}
return nil
Expand Down
9 changes: 8 additions & 1 deletion pkg/util/tar_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ type OriginalPerm struct {
perm os.FileMode
}

func unpackTar(tr *tar.Reader, path string, whitelist []string) error {
func unpackTar(tr *tar.Reader, path string, whitelist []string, keepOwner bool) error {
originalPerms := make([]OriginalPerm, 0)
for {
header, err := tr.Next()
Expand Down Expand Up @@ -137,6 +137,13 @@ func unpackTar(tr *tar.Reader, path string, whitelist []string) error {
hardlinks[target] = linkname
}
}

if keepOwner {
if err := os.Lchown(target, header.Uid, header.Gid); err != nil {
logrus.Errorf("Error updating owner on %s", target)
return err
}
}
}

for target, linkname := range hardlinks {
Expand Down