googlecontainertools / container-diff Goto Github PK
View Code? Open in Web Editor NEWcontainer-diff: Diff your Docker containers
License: Apache License 2.0
container-diff: Diff your Docker containers
License: Apache License 2.0
Currently, the contain() method in package_diff_utils.go does a check for global and local installed packages using very specific logic only really applicable to npm package installations
Currently, their filesystem still comprises of layer folders
$ container-diff gcr.io/google-appengine/php71:2017-08-22-15-24 gcr.io/google-appengine/php71
E0825 16:15:04.495977 16521 image_prep_utils.go:121] open /etc/docker/certs.d/gcr.io: permission denied
E0825 16:15:04.496338 16521 root.go:84] open /etc/docker/certs.d/gcr.io: permission denied
`container-diff diff daemon://registry.access.redhat.com/rhel7:latest daemon://myimage:v1 --types=history --types=apt --types=node
-----Node-----
Packages found only in registry.access.redhat.com/rhel7:latest: None
Packages found only in myimage:v1: None
Version differences: None`
I wanted to compare the exited container and the base image it is based off of but got following error:
$ sudo ~/.local/bin/container-diff diff 422dc563ca32 53fc993ed0ae
E1118 16:14:14.606483 4485 image_prep_utils.go:99] errors:
denied: requested access to the resource is denied
unauthorized: authentication required
E1118 16:14:14.771308 4485 image_prep_utils.go:99] errors:
denied: requested access to the resource is denied
unauthorized: authentication required
E1118 16:14:14.771363 4485 differs.go:62] Error getting diff with AptAnalyzer: stat : no such file or directory
E1118 16:14:14.771391 4485 diff.go:47] Could not retrieve diff: Could not perform diff on { {{[]} []}} and { {{[]} []}}
Steps to reproduce:
Create a container with some content
$ docker run -it fedora bash [12/12]
[root@53fc993ed0ae /]# cat > file
yeah yeah
^C
[root@53fc993ed0ae /]# exit
Get image ID:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
fedora latest 422dc563ca32 3 days ago 252MB
Get the exited container ID:
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
53fc993ed0ae fedora "bash" 19 seconds ago Exited (130) 8 seconds ago keen_shannon
5bcb29c50c7c fedora "bash" 2 minutes ago Exited (127) About a minute ago ecstatic_lewin
...
Do the diff as shown in the top:
$ sudo ~/.local/bin/container-diff diff 422dc563ca32 53fc993ed0ae
E1118 16:14:14.606483 4485 image_prep_utils.go:99] errors:
denied: requested access to the resource is denied
unauthorized: authentication required
E1118 16:14:14.771308 4485 image_prep_utils.go:99] errors:
denied: requested access to the resource is denied
unauthorized: authentication required
E1118 16:14:14.771363 4485 differs.go:62] Error getting diff with AptAnalyzer: stat : no such file or directory
E1118 16:14:14.771391 4485 diff.go:47] Could not retrieve diff: Could not perform diff on { {{[]} []}} and { {{[]} []}}
OS information:
$ cat /etc/redhat-release
Fedora release 25 (Twenty Five)
$ container-diff version
v0.5.0
# SELinux is enabled
$ getenforce
Enforcing
Would be great to be able to get more information related to RPM packages (Fedora, CentOS, RHEL, etc).
Will have a look at this and might come up with a PR.
original comment in GoogleCloudPlatform/runtimes-common#243
Running the linux binary downloaded 2017-08-18 on a Goobuntu workstation shows no packages and incorrect diff.
$ md5sum /usr/local/bin/container-diff-amd64-linux
6b08c116217e7a7aee6c7a7306bf2d54 /usr/local/bin/container-diff-amd64-linux
$ sudo /usr/local/bin/container-diff-amd64-linux gcr.io/google-appengine/python:2017-07-25-110644 gcr.io/google-appengine/python:2017-08-18-131018 >stdout.txt 2>stderr.txt
We should have a command that outputs the current version of the tool.
Not all packages seem to be uploaded to /vendor. Currently a godep restore
is required to build container-diff when checking out the repo. The package that was noted as being missing was:
github.com/sirupsen/logrus/
by default, pip just puts all packages in site-packages. but you can configure it to install them anywhere, for example by passing --target=/some/random/directory to pip install and then adding that directory to your PYTHONPATH. it might be the case that we want to check all directories on the PYTHONPATH when we do the python diff.
Ran the command, it spewed binary in the console
We should retrieve and prepare all image layers in parallel, this should speed things up a bit.
Currently, the code converts docker images to tars using docker save
, which is a docker specific format. We should generalize this to tarballs created in other formats, specifically through the bazel docker_flatten
rule.
Currently container-diff features are toggled on/off using a series of boolean variables. We should change this to instead pass around configuration.
it might be useful to be able to configure the output to show differences that are only unique to the first image, only unique to the second image, etc.
Running arbitrary commands in a Dockerfile can cause many files to be added to a final Docker image, without the user necessarily knowing they were added. We should try and combine the output of docker history
with the file system diff output to show which files were added explicitly or implicitly.
Originally submitted by @r2d4: "I would like to run $ make to build the idiff tool to a .gitignored directory. I think it could be simple for now, with just one target to build the idiff binary, and another one to install to $GOBIN. In the future, it might be cool to also support dockerized builds."
$ sudo ${HOME}/bin/container-diff gcr.io/google-appengine/php71:2017-08-22-15-24 gcr.io/google-appengine/php71
...
...
E0825 16:16:24.508140 16621 differs.go:41] Error getting diff with AptDiffer: stat php712017-08-22-15-24: required key not available
E0825 16:16:24.508224 16621 differs.go:41] Error getting diff with NodeDiffer: stat php712017-08-22-15-24: required key not available
The apt repo's key is installed within the container image.
I ran the tool against my sample AppEngine Flex app image but got permission denied...
$ container-diff us.gcr.io/<project>/appengine/default.20170825t183334
E0825 23:08:13.553821 86961 image_prep_utils.go:121] denied: Permission denied for "latest" from request "/v2/<project>/appengine/default.20170825t183334/manifests/latest".
E0825 23:08:13.563247 86961 root.go:142] denied: Permission denied for "latest" from request "/v2/<project>/appengine/default.20170825t183334/manifests/latest".
E0825 23:08:13.563282 86961 root.go:73] Could not perform image analysis
** Note I replaced my project ID with .
I take it that the tool is not aware of any GCP service authentication. So, I decided to download the image via gcloud docker pull ...
$ gcloud docker -- pull us.gcr.io/<project>/appengine/default.20170825t183334:latest
latest: Pulling from <project>/appengine/default.20170825t183334
685c85508923: Pull complete
a2f1e8cf3cf3: Pull complete
524b56f5f096: Pull complete
Digest: sha256:497755d995423592adf8a3cf2fc01ef3eb6545a7b1a78e87430b7890dbb7ea84
Status: Downloaded newer image for us.gcr.io/<project>/appengine/default.20170825t183334:latest
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
us.gcr.io/<project>/appengine/default.20170825t183334 latest 2683605e0271 5 hours ago 27.3MB
I was hoping that given that the image is now on my local Docker instance that it will be able to read from it, but I think it's still reading off from GCR ...
$ container-diff us.gcr.io/<project>/appengine/default.20170825t183334:latest
E0825 23:11:04.949147 87302 image_prep_utils.go:121] denied: Permission denied for "latest" from request "/v2/<project>/appengine/default.20170825t183334/manifests/latest".
E0825 23:11:04.950083 87302 root.go:142] denied: Permission denied for "latest" from request "/v2/<project>/appengine/default.20170825t183334/manifests/latest".
E0825 23:11:04.950109 87302 root.go:73] Could not perform image analysis
I had to save it to a tar file and run the tool against it to make it work.
I have public images hosted @ gcr.io that I am attempting to diff. When trying to run container-diff, I get the following errors:
aprindle@aprindle:~/runtimes-common/src/github.com/GoogleCloudPlatform/container-diff$ ./container-diff gcr.io/k8s-minikube
/localkube-dind-image:v1.7.0 gcr.io/k8s-minikube/localkube-dind-image:v1.7.0-devshell
E0817 11:31:59.112045 98632 image_prep_utils.go:121] open /etc/docker/certs.d/gcr.io: permission denied
E0817 11:31:59.112369 98632 root.go:75] open /etc/docker/certs.d/gcr.io: permission denied
Running the command with sudo resolves the issue
$ make cross
can't load package: ../go/src/github.com/GoogleCloudPlatform/container-diff/utils/image_prep_utils.go:15:2: case-insensitive import collision: "github.com/GoogleCloudPlatform/container-diff/vendor/github.com/Sirupsen/logrus" and "github.com/GoogleCloudPlatform/container-diff/vendor/github.com/sirupsen/logrus"
GOOS=linux GOARCH=amd64 go build -tags "container_image_ostree_stub containers_image_openpgp" -o out/container-diff-linux-amd64 github.com/GoogleCloudPlatform/container-diff
../go/src/github.com/GoogleCloudPlatform/container-diff/utils/image_prep_utils.go:15:2: case-insensitive import collision: "github.com/GoogleCloudPlatform/container-diff/vendor/github.com/Sirupsen/logrus" and "github.com/GoogleCloudPlatform/container-diff/vendor/github.com/sirupsen/logrus"
make: *** [out/container-diff-linux-amd64] Error 1
We should try and set up some infrastructure to track things like downloads, 7-day active users, etc.
Monitoring downloads will be related to where the release is stored and won't be inside of container-diff itself. Something like 7-day active users will need to be built into the tool. You can look at how minikube does something like this here:
https://github.com/kubernetes/minikube/blob/master/pkg/minikube/notify/notify.go
We should verify that it works without this hack in the newly updated containers/image library.
There are two instances of it in this repo.
ctx := &types.SystemContext{
DockerCertPath: tmpCerts,
}
Not strictly a diff, but an "analyze" (or something similar) command to check out the contents of a single image would be really useful.
Currently container-diff has multiple flag toggles for each differ. The CLI should instead support a better method for passing in a list of differs.
container-diff should use subcommands for functionality instead of everything deriving from the root cmd. Example CLI:
container-diff analyze ...
container-diff diff ...
container-diff version ... (#44)
Ref: #44 (comment)
The crypto
and sys
dependencies from the golang repo are currently incompatible when building for Windows. We need to update these in the /vendor folder.
# github.com/GoogleCloudPlatform/container-diff/vendor/golang.org/x/crypto/ssh/terminal
vendor/golang.org/x/crypto/ssh/terminal/util_windows.go:42: undefined: windows.ENABLE_ECHO_INPUT
vendor/golang.org/x/crypto/ssh/terminal/util_windows.go:42: undefined: windows.ENABLE_PROCESSED_INPUT
vendor/golang.org/x/crypto/ssh/terminal/util_windows.go:42: undefined: windows.ENABLE_LINE_INPUT
vendor/golang.org/x/crypto/ssh/terminal/util_windows.go:42: undefined: windows.ENABLE_PROCESSED_OUTPUT
vendor/golang.org/x/crypto/ssh/terminal/util_windows.go:43: undefined: windows.SetConsoleMode
vendor/golang.org/x/crypto/ssh/terminal/util_windows.go:62: undefined: windows.SetConsoleMode
vendor/golang.org/x/crypto/ssh/terminal/util_windows.go:67: undefined: windows.ConsoleScreenBufferInfo
vendor/golang.org/x/crypto/ssh/terminal/util_windows.go:68: undefined: windows.GetConsoleScreenBufferInfo
vendor/golang.org/x/crypto/ssh/terminal/util_windows.go:91: undefined: windows.ENABLE_ECHO_INPUT
vendor/golang.org/x/crypto/ssh/terminal/util_windows.go:92: undefined: windows.ENABLE_PROCESSED_INPUT
vendor/golang.org/x/crypto/ssh/terminal/util_windows.go:92: too many errors
# github.com/GoogleCloudPlatform/container-diff/vendor/github.com/opencontainers/runc/libcontainer/user
vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go:44: undefined: unix.Getuid
vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go:92: undefined: unix.Getgid```
Readme says:
container-diff is a tool for analyzing and comparing container images. container-diff can examine images along several different criteria, including:
- Docker Image History
- Image file system
- ...
But when I run:
./container-diff-darwin-amd64 diff daemon://golang:1.9-alpine daemon://golang:1.8-alpine
I actually don't get an "image filesystem diff"
-----Apt-----
Packages found only in golang:1.9-alpine: None
Packages found only in golang:1.8-alpine: None
Version differences: None
I actually expected to see something like git status
diff output saying these are the files that are in image A, and not in B (or vice versa) and here are the files that are different between two images.
This tool does not seem to be doing this. So maybe the statement about "Image file system" diffing should be removed.
Currently, unpacked image file systems are automatically removed from the user's file system after the diff has been processed, but should a user wish to save those directories, we should allow them to specify that
Replace type with types in ReadMe file. Types is the actual argument
dk@dk-VirtualBox:~/Docker$ container-diff diff daemon://JustAlpine daemon://AlpineFipsBase
E1016 16:38:53.452142 3392 differs.go:62] Error getting diff with AptAnalyzer: stat : no such file or directory
E1016 16:38:53.452238 3392 diff.go:47] Could not retrieve diff: Could not perform diff on { {{[]} []}} and { {{[]} []}}
dk@dk-VirtualBox:~/Docker$
Related to issue #48 but for remote paths.
$ container-diff analyze us.gcr.io/<project>/appengine/default.20171006t183930:latest
E1010 10:01:15.568136 40141 image_prep_utils.go:99] denied: Permission denied for "latest" from request "/v2/<project>/appengine/default.20171006t183930/manifests/latest".
E1010 10:01:15.569398 40141 analyze.go:46] Error processing image: denied: Permission denied for "latest" from request "/v2/<project>/appengine/default.20171006t183930/manifests/latest".
I'm guessing this has to do with permissions on my project's GCR paths. There's doc on how to make the GCR path public -- https://cloud.google.com/container-registry/docs/access-control. Not easy to figure out the corresponding GS bucket path for it though.
Anyways, filing this feature request if somehow container-diff can be made to use my project's token authentication to analyze a remote image w/o changing ACLs.
I think the real problem here is that ImagePrepper shouldn't have Source be a string but it should actually be a containers/image types.ImageReference, which is exactly what you can pass into all of the containers/images functions without have to worry about parsing it at the end.
Some files are temporarily placed in the current directory.
Command help shows that default is apt, but the ReadMe file states that default give diff of all types
`container-diff diff daemon://registry.access.redhat.com/rhel7:latest daemon://myimage:v1
-----Apt-----
Packages found only in registry.access.redhat.com/rhel7:latest: None
Packages found only in myimage:v1: None
Version differences: None`
Currently there is no integration test that checks that no --types passed results in all differs being used. This allowed #85 to get through.
Currently the code just looks in /usr/local/lib/<python_version>/site-packages
for package installations. Looking at the directories that python could possibly have packages installed in by default, I see:
➜ ~ docker run -it --entrypoint=/bin/bash gcr.io/google-appengine/python
root@7e6805303827:/home/vmagent/app# python -m site
sys.path = [
'/home/vmagent/app',
'/usr/lib/python2.7',
'/usr/lib/python2.7/plat-x86_64-linux-gnu',
'/usr/lib/python2.7/lib-tk',
'/usr/lib/python2.7/lib-old',
'/usr/lib/python2.7/lib-dynload',
'/usr/local/lib/python2.7/dist-packages',
'/usr/lib/python2.7/dist-packages',
]
These values get initialized by python at start time, and are hardcoded into the source. We should at least check the default paths when checking Python packages.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.