-
Notifications
You must be signed in to change notification settings - Fork 237
Remove Docker dependency for retrieving image filesystem #89
Conversation
…ages in local daemon
…ion manually. fix up image prep
cmd/analyze.go
Outdated
analyzeTypes, err := differs.GetAnalyzers(analyzerArgs) | ||
if err != nil { | ||
glog.Error(err.Error()) | ||
return errors.New("Could not perform image analysis") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you wrap the previous error instead of making a new one? No need to log there either.
pkg/util/image_prep_utils.go
Outdated
if err != nil { | ||
return "", err | ||
errStr = "\nUnable to remove " + path |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, wrap the error you get instead of making a new one.
cmd/diff.go
Outdated
prepper = pkgutil.LOCAL | ||
imageName = strings.Replace(imageName, "daemon://", "", -1) | ||
} else if pkgutil.IsTar(imageName) { | ||
prepper = pkgutil.TAR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we change this to pass an actual type or function instead of a string?
pkg/util/tar_utils.go
Outdated
@@ -41,11 +41,21 @@ func unpackTar(tr *tar.Reader, path string) error { | |||
if strings.Contains(header.Name, ".wh.") { | |||
rmPath := filepath.Join(path, header.Name) | |||
newName := strings.Replace(rmPath, ".wh.", "", 1) | |||
err := os.Remove(rmPath) | |||
if _, err := os.Stat(rmPath); err == nil { | |||
err := os.Remove(rmPath) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: collapse this into the if
cmd/analyze.go
Outdated
var prepper string | ||
if strings.HasPrefix(imageName, "daemon://") { | ||
// force local daemon if we have the corresponding prefix | ||
prepper = pkgutil.LOCAL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just CamelCase for constants
} | ||
return nil | ||
} | ||
|
||
func processImageName(imageName string) string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i would get rid of the nested negated conditions
if pkgutil.IsTar(imageName) || strings.HasPrefix(imageName, "daemon://") return imageName
// default condition
return "remote://" + imageName
or even
if pkgutil.IsTar(imageName)
return ...
if strings.HasPrefix(imageName, "daemon://")
return ...
return ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
pkg/util/image_prepper.go
Outdated
@@ -54,17 +54,23 @@ func getImage(prepper Prepper, source string) (Image, error) { | |||
}, nil | |||
} | |||
|
|||
func (p ImagePrepper) GetImage() (Image, error) { | |||
func (p *ImagePrepper) GetImage() (Image, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its weird that GetImage() actually mutates the fields on the struct. Calling this twice on the same imagePrepper will break, right? I would refactor this. getImage already takes in redundant information since it takes prepper
and prepper.ImagePrepper.Source
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the reason I changed it to do this is to handle the prefixes that the image prepper respects to force a certain source (e.g. daemon://<image_path>
). these need to be removed before actually trying to parse the image reference with the containers/image library. GetImage()
only ever gets called one time per prepper, so there shouldn't be any risk here. getImage()
doesn't need to take the source as parameter though, since it gets it from the prepper
pkg/util/image_prep_utils.go
Outdated
"Cloud Registry": func(ip ImagePrepper) Prepper { return CloudPrepper{ImagePrepper: ip} }, | ||
"Tar": func(ip ImagePrepper) Prepper { return TarPrepper{ImagePrepper: ip} }, | ||
var sourceToPrepMap = map[string]func(ip *ImagePrepper) Prepper{ | ||
"Local Daemon": func(ip *ImagePrepper) Prepper { return DaemonPrepper{ImagePrepper: ip} }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where do these strings come from? I would get rid of them in favor of some function like
func NewPrepperForSource(source string) Prepper
or
func NewPrepperForSource(source ImageSourceType) Prepper
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah this is getting refactored out in an upcoming PR. these are just here for logging at this point
pkg/util/image_prep_utils.go
Outdated
if errMsg != "" { | ||
glog.Error(errMsg) | ||
if err := remove(image.FSPath, true); err != nil { | ||
glog.Error(err.Error()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can just be glog.Error(err)
Also, this won't exit or do anything besides print the error to stdout and the glog error file. Is that what you mean to do here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not new code, but yeah this can fail without impacting the overall run. this should probably get knocked down to a warn though
pkg/util/image_prep_utils.go
Outdated
} | ||
|
||
var err error | ||
func remove(path string, dir bool) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove remove. os.RemoveAll tries to call remove before it deletes the directory. Just calling that directly will be fine
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good call, done
pkg/util/image_prep_utils.go
Outdated
errMsg := remove(image.FSPath, true) | ||
if errMsg != "" { | ||
glog.Error(errMsg) | ||
if err := remove(image.FSPath, true); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove remove
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
cmd/diff.go
Outdated
@@ -108,27 +98,34 @@ func diffImages(image1Arg, image2Arg string, diffArgs []string) error { | |||
|
|||
diffTypes, err := differs.GetAnalyzers(diffArgs) | |||
if err != nil { | |||
glog.Error(err.Error()) | |||
return errors.New("Could not perform image diff") | |||
return fmt.Errorf("Could not perform image diff: %s", err.Error()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here you usually want to just do something like fmt.Errorf("error msg: %s", err)
or fmt.Errorf("error msg: %v", err)
if you might expect a typed error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
closing in favor of #97 |
This PR removes the dependency on the Docker API client for retrieving an image from a remote registry or a local docker daemon, and converting it to an in-memory filesystem. The Docker client is still needed to retrieve image history, and will be used automatically by the container-diff tool itself.
The main motivation for this is for code that uses container-diff as a library to convert both Docker images and tarballs into convenient representations of filesystems, without relying on a functional Docker daemon on the host machine.
By default, the
Image Prepper
in this code will now default to looking for images in the local Docker daemon first, followed by checking a cloud registry. Because this is not necessarily intended behavior when using the container-diff CLI (for example, if you wanted to compare both local and remote versions of an image), the container-diff CLI now requires the prefixdaemon://
to specify an image contained in a local Docker daemon.This also removes support for specifying images by their Docker "Image ID" (e.g.
f5ad8aa3b589
), since this is not supported by the containers/image library.