Skip to content
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

Add Dockerfile "freeze" support by pinning ARG and ENV variables #508

Closed
rnjudge opened this issue Dec 17, 2019 · 6 comments
Closed

Add Dockerfile "freeze" support by pinning ARG and ENV variables #508

rnjudge opened this issue Dec 17, 2019 · 6 comments
Milestone

Comments

@rnjudge
Copy link
Contributor

rnjudge commented Dec 17, 2019

Description
The goal of this task is to extract ARG and ENV build stage variables and pin them to the corresponding frozen Dockerfile. For example:

ARG variable=$value --> ARG variable=actual_value
ENV variable=$value --> ENV variable=actual_value

To Do

  1. Research dockerfile-parse and see if it would be helpful to parse commands at all. There is some prototyping with it here: https://gist.github.com/joshuagl/2d30d79373f87858db9863d2a44d6150

  2. Possibly re-write the get_base_instruction or create a new function in tern/analyze/docker/dockerfile.py and try to incorporate dockerfile-parse to get all the commands that we want to run plus their ARG and ENV values.

Super Issues
#454

@ForgetMe17
Copy link
Contributor

I would like to work on this issue.

@rnjudge
Copy link
Contributor Author

rnjudge commented Mar 10, 2020

The work for parsing the ENV variables is already completed so you may want to look at that for hints. There is still work required for parsing the ARG variables. ARG is slightly different than ENV in that it is only available during the build of a Docker image (RUN etc), not after the image is created and containers are started from it (ENTRYPOINT, CMD). You will likely want to write a function in dockerfile.py called expand_args and replace_args with functionality that achieves a similar outcome to the existing replace_env and expand_env functions. An example for what you are trying to accomplish:

If the Dockerfile before the "freeze" looks like this:

ARG VERSION=latest
FROM debian:${VERSION}    # the {} are optional here, could also use $VERSION

We would want the resulting "frozen" dockerfile to look like this:

ARG VERSION=latest
FROM debain:latest

Note that ARG variables can be used in a variety of commands, not just FROM. They can also be variables themselves being passed in via the docker build --build-arg variable=value command that can only be determined after an image is built. You can inspectARG values can after an image is built by viewing the docker history of an image. Example:

ARG PYTHON_VERSION
FROM python:${PYTHON_VERSION}

@ForgetMe17
Copy link
Contributor

ForgetMe17 commented Mar 11, 2020

We can use docker history <image-id> to get the history command that builds the images.. But it seems that we cannot trace the dockerfile from a built image, so i am thinking how can we find that . My solution is to apply docker history to all the images and find ARG and their values. Then we can select the target ARG in the parsing dockerfile.
Here is another problem: ARG declared before FROM is outside of a build stage, so in this situation we cannot find the value of ARG in the docker history.
Another posible way is using the docker-compose.yml which contains the 'ARG' given to the dokcer build.

@rnjudge
Copy link
Contributor Author

rnjudge commented Mar 11, 2020

That all sounds a little complicated for this functionality :) And we already have functionality in Tern that finds the commands that created each image layer. Why don't you start with this: for all of the ARG values in the dockerfile, do a straight up replacement for variables based on the text in dfobj.structure. If the variable is not defined in the dockerfile, you can leave it for now. Let's first just focus on translating something like this:

ARG VERSION=latest
FROM debian:${VERSION}    # the {} are optional here, could also use $VERSION```

to this:

ARG VERSION=latest
FROM debain:latest

Does that sound good?

@ForgetMe17
Copy link
Contributor

That all sounds a little complicated for this functionality :) And we already have functionality in Tern that finds the commands that created each image layer. Why don't you start with this: for all of the ARG values in the dockerfile, do a straight up replacement for variables based on the text in dfobj.structure. If the variable is not defined in the dockerfile, you can leave it for now. Let's first just focus on translating something like this:

ARG VERSION=latest
FROM debian:${VERSION}    # the {} are optional here, could also use $VERSION```

to this:

ARG VERSION=latest
FROM debain:latest

Does that sound good?

Yes!

ForgetMe17 added a commit to ForgetMe17/tern that referenced this issue Mar 12, 2020
Replace the arg varibles in the dockerfile.

Work towards tern-tools#508.

Signed-off-by: WangJL <hazard15020@gmail.com>
ForgetMe17 added a commit to ForgetMe17/tern that referenced this issue Mar 12, 2020
Replace the arg varibles in the dockerfile.

Work towards tern-tools#508.

Signed-off-by: WangJL <hazard15020@gmail.com>
ForgetMe17 added a commit to ForgetMe17/tern that referenced this issue Mar 12, 2020
Replace the arg varibles in the dockerfile if known.

Work towards tern-tools#508.

Signed-off-by: WangJL <hazard15020@gmail.com>
ForgetMe17 added a commit to ForgetMe17/tern that referenced this issue Mar 12, 2020
Replace the arg varibles in the dockerfile if known.

Work towards tern-tools#508.

Signed-off-by: WangJL <hazard15020@gmail.com>
ForgetMe17 added a commit to ForgetMe17/tern that referenced this issue Mar 14, 2020
Replace the arg variables in the dockerfile if known.

Work towards tern-tools#508.

Signed-off-by: WangJL <hazard15020@gmail.com>
ForgetMe17 added a commit to ForgetMe17/tern that referenced this issue Mar 17, 2020
Replace the arg variables in the dockerfile if known.

In tern/analyze/docker/dockerfile.py, add function expand_arg
which finds the defination of ARG variables and replace them
using function replace_env.

Add test dockerfile tests/dockerfiles/buildpack_deps_jessie_arg.

Add a testcase in tests/dockerfiles/buildpack_deps_jessie_arg.:

Work towards tern-tools#508.

Signed-off-by: WangJL <hazard15020@gmail.com>
nishakm pushed a commit that referenced this issue Mar 17, 2020
Replace the arg variables in the dockerfile if known.

In tern/analyze/docker/dockerfile.py, add function expand_arg
which finds the defination of ARG variables and replace them
using function replace_env.

Add test dockerfile tests/dockerfiles/buildpack_deps_jessie_arg.

Add a testcase in tests/dockerfiles/buildpack_deps_jessie_arg.:

Work towards #508.

Signed-off-by: WangJL <hazard15020@gmail.com>
@nishakm
Copy link
Contributor

nishakm commented Mar 24, 2020

Fixed in 69f1b45

@nishakm nishakm closed this as completed Mar 24, 2020
rnjudge pushed a commit to rnjudge/tern that referenced this issue Jun 5, 2020
Replace the arg variables in the dockerfile if known.

In tern/analyze/docker/dockerfile.py, add function expand_arg
which finds the defination of ARG variables and replace them
using function replace_env.

Add test dockerfile tests/dockerfiles/buildpack_deps_jessie_arg.

Add a testcase in tests/dockerfiles/buildpack_deps_jessie_arg.:

Work towards tern-tools#508.

Signed-off-by: WangJL <hazard15020@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants