-
Notifications
You must be signed in to change notification settings - Fork 164
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduces new mechanism to fully scan package dependencies #3934
Conversation
7dd83d8
to
2ce5893
Compare
Converted to draft after our EVE's TSC call yesterday... I had a discussion with @christoph-zededa and @rucoder , we did some tests and it's possible to provide the dependency tree to the Makefile, so I will improve the script to generate a file to be included in the main Makefile, it should be possible to achieve full dependency check, so we will not need to build any package manually after changes.... |
The PR is now ready for review.... your comments are really appreciated 😃 |
Updates in this PR:
|
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.
Yay, we missed proper dependencies detection!
The parser implemented through shell script (in get-deps.sh) has some limitations:
@christoph-zededa collaborated providing some libraries and sample code to parse Dockerfile and YML files accordingly in GO, so I'll convert get-deps.sh to a GO application in order to eliminate such limitations. Converting this PR again to DRAFT while the application is not ready. Notice that the PR is still 100% functional, it can be used locally. |
Check with @deitch as well - I think he found a dockerfile parser as part of the SBoM work a while back. |
We have been doing a lot of this for sbom purposes for a while. First, we use the buildkit sbom creator (which is based on syft) to scan the entire OCI image for each package every time it builds. We attach the sbom to the image itself using the sbom attestations mechanism used by buildkit (in-toto). It is a requirement of ours that all dependencies are included in the SBoM. Second, there are sometimes things that are added to an image that are not obviously scannable. For those, we use dockerfile-add-scanner which is part of lf-edge/eve-build-tools to scan Dockerfiles for I guess the first question I would ask is, can our requirements be met by using what already is in place? If the answer is no, can we use or extend the tools to get what we need? If not, and we need to add a new tool, we should put it in Finally, if none of the above works, and you have to actually scan Dockerfiles, use the buildkit libraries to do so. Dockerfiles are far more complex than you realize, and the ruleset to parsing it can be rough, to put it mildly. In any case, if we can get what we need out of the already generated sbom, your life will be immensely easier. If the sbom is almost there, it is worth seeing if a small change can bring it there. Else go for the dockerfile scanner, or leverage it. |
9d5238a
to
ca4b485
Compare
You mean like this: rene@715e60b ?
I don't think so.
The code in
But those are: "Library and Tools to interact with Edge Virtualization Engine(EVE)" and this is not a library or tool to interact with EVE but a tool to interact with building EVE - the same as other tools that are in eve/tools, e.g. https://github.com/lf-edge/eve/tree/master/tools/compare-sbom-sources
You mean like this: rene@715e60b ? |
Well, there's the answer, then.
The one thing it does well is load up a dockerfile and parse it. It uses the buildkit libs, like you linked to above, specifically these lines to scan the file. Those lines particularly look for URLs, but the basics for parsing a file are there. Remember that you need to track for ARG and ENV as set, and interpolated vars inside the file.
I don't understand. Can you describe further?
Yes, with all of the above (arg, env, etc.). |
When I looked up how to actually parse those Dockerfile I found https://github.com/earthly/earthly - it is combining Makefiles and Dockerfiles into one. But actually I thought instead of calling
Oh, I thought it would do this already; now I added https://github.com/rene/eve/pull/32/files#diff-189b815f942d48c913748f26946e4c9b28e003c0191cb81ac8452cb78ad1a72fR114 . |
Oh that is interesting. I need to spend some time taking a look at it. I always am both excited and hesitant about new build systems. Excited, because they may solve issues; hesitant, because so many come and go, when they just end up reproducing existing problems with a new syntax. In the end, build dependency graphs are a hard problem.
Hmm, there is an interesting conversation to be had here. I don't think it belongs on PR comments, but you raising some really interesting higher-level ideas. I can lay the groundwork at least. The only reason we build these packages as OCI/docker images, is because we consume them as such in our final build image (
Given that, the reason we use
Ideally, In terms of the dependency graph, what do you refer to? Mostly, our |
I mean this graph: #3934 (comment) |
Oh, OK I understand. linuxkit itself has no notion of the dependencies graph, at least in principle. It just calls linuxkit does have some knowledge. Since it manages its own cache, if a Dockerfile references |
0305ab9
to
6b820c1
Compare
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.
LGTM
Updates in this PR:
|
This commit introduces the tool get-deps (under tools/get-deps/), which scans the pkg directory and process each Dockerfile (or Dockerfile.in) file in order to find all build dependencies (containers) of each package. It can also check package dependencies for rootfs images. The final package dependency tree can be generated as a PNG image (using dot tool) or as a Makefile that can be included to the main Makefile. The usage of the tool the following: ./tools/get-deps/get-deps [-r] <-i|-m> <output_file> -i string Generate a PNG image file -m string Generate a Makefile auxiliary file -r Also generates dependencies for rootfs image Examples: ./tools/get-deps/get-deps -i deptree.png ./tools/get-deps/get-deps -r -i deptree.png ./tools/get-deps/get-deps -m pkg-deps.mk Co-authored-by: Christoph Ostarek <christoph@zededa.com> Signed-off-by: Renê de Souza Pinto <rene@renesp.com.br>
Container packages might import other containers (build/run dependencies, etc) using FROM command inside their Dockerfile. However, these dependencies are not exposed to the main Makefile. Using the tool get-deps (tools/get-deps/get-deps) the dependency graph can be generated into a file that can be included in the main Makefile in order to take these package dependencies into account. The script is also able to scan rootfs image container dependencies. This commit changes the main Makefile to call get-deps tool in order to generate a file called pkg-deps.mk with the package dependency included, so we can ensure all dependencies from a package will be built (when changed) in the correct order to avoid build failures, as can be experienced specially when doing batch updates of the eve-alpine container to multiple packages. Unfortunately, rootfs images usually have a lot of package dependencies, leading to a lot of docker build calls when all dependencies are checked, which can increase substantially the build time. In order to void that, the main Makefile will scan rootfs image dependencies only when the ROOTFS_DEPS=y is specified, for example: make ROOTFS_DEPS=y rootfs make ROOTFS_DEPS=y pkgs In summary: - ROOTFS_DEPS not defined: Only package dependencies are scanned. For example, if pkg/pillar depends on pkg/uefi and pkg/dnsmasq to be built and one or both of these packages are changed, then when doing make pkg/pillar, make will ensure the dependencies will be built before pkg/pillar. - ROOTFS_DEPS defined: The dependencies of all packages and the rootfs images will be scanned, which means that any dependency package that was changed will be built before the main target (pkgs, rootfs, live, etc). Signed-off-by: Renê de Souza Pinto <rene@renesp.com.br>
Updates in this PR:
|
This PR aims to help batch upgrades of eve-alpine and/or other container tags, like the one provided by PR #3928
Introduction of get-deps
This PR introduces introduces the script get-deps tool, which scans the pkg directory and process each Dockerfile (or Dockerfile.in) file in order to find all build dependencies (containers) of each package. It can also check package dependencies for rootfs images. The final package dependency tree can be generated as a PNG image using dot tool or as a Makefile that can be included to the main Makefile.
The usage of the script is the following:
./tools/get-deps/get-deps [-r] <-i|-m> <output_file>
The generated dependency tree can be used to easily find conflicts while doing batch upgrades of eve-alpine and/or other container tags. The following image is an example of the output (for master branch):
Scan package dependencies
Container packages might import other containers (build/run dependencies, etc) using FROM command inside their Dockerfile. However, these dependencies are not exposed to the main Makefile. Using the script tools/get-deps.sh the dependency graph can be generated into a file that can be included in the main Makefile in order to take these package dependencies into account. The script is also able to scan rootfs image container dependencies.
This commit changes the main Makefile to call get-deps tool in order to generate a file called pkg-deps.mk with the package dependency included, so we can ensure all dependencies from a package will be built (when changed) in the correct order to avoid build failures, as can be experienced specially when doing batch updates of the eve-alpine container
to multiple packages.
Unfortunately, rootfs images usually have a lot of package dependencies, leading to a lot of docker build calls when all dependencies are checked, which can increase substantially the build time. In order to void that, the main Makefile will scan rootfs image dependencies only when the ROOTFS_DEPS=y is specified, for example:
In summary: