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

Dockerfiles with different file names are not supported #127

Closed
ElijahAhianyo opened this issue Mar 8, 2022 · 5 comments
Closed

Dockerfiles with different file names are not supported #127

ElijahAhianyo opened this issue Mar 8, 2022 · 5 comments

Comments

@ElijahAhianyo
Copy link

As seen in the official docker code base(https://github.com/docker/cli/blob/ab7cc485809455e6f1149aec5c00b6582066a396/cli/command/image/build/context.go#L324), there is a relative check for filenames with the format dockerfile aside the default name Dockerfile.
The library currently supports only the default name. That is because the DOCKERFILE_FILENAME constant
(

DOCKERFILE_FILENAME = 'Dockerfile'
) is a string.

I'm working on a usecase that requires parsing dockerfiles ending in dockerfile if they exist, however I seem to get this error:

self = <dockerfile_parse.parser.DockerfileParser object at 0x7f7977ae21d0>, mode = 'rb'

    @contextmanager
    def _open_dockerfile(self, mode):
        if self.fileobj is not None:
            self.fileobj.seek(0)
            if 'w' in mode:
                self.fileobj.truncate()
            yield self.fileobj
            self.fileobj.seek(0)
        else:
>           with open(self.dockerfile_path, mode) as dockerfile:
E           NotADirectoryError: [Errno 20] Not a directory: '/tmp/pytest-of-eli/pytest-16/test_sets_content_if_dockerfil0/testmodule/dockerfile/Dockerfile'

If this makes sense, I believe DOCKER_FILENAME should have a value of ('Dockerfile', "dockerfile")

I am also willing to submit a PR if this issue is approved

@chmeliik
Copy link
Contributor

chmeliik commented Mar 8, 2022

Hi @ElijahAhianyo, thanks for the report!

As an immediate workaround, you may be able to pass the [dD]ockerfile via the fileobj argument instead of by path:

import dockerfile_parse

with open('./dockerfile', 'rb') as f:
    dockerfile = dockerfile_parse.DockerfileParser(fileobj=f)
    # do stuff with dockerfile

# can't use dockerfile anymore, fileobj is closed

Or, if using a real file object is not convenient:

import io
import dockerfile_parse

with open('./dockerfile', 'rb') as f:
    in_memory_file = io.BytesIO(f.read())

dockerfile = dockerfile_parse.DockerfileParser(fileobj=in_memory_file)
# note that writes to the dockerfile (e.g. via the `envs` or `labels` attributes)
#   will only be reflected in the in_memory_file, not on disk

@chmeliik
Copy link
Contributor

chmeliik commented Mar 8, 2022

As for fixing the problem: maybe it would be good to support any arbitrary filename, rather than just dockerfile and Dockerfile?

For example, podman also supports the Containerfile name: https://docs.podman.io/en/latest/markdown/podman-build.1.html

Not quite sure if there is a nice way to do that while preserving backwards compatibility. Maybe the self.dockerfile_path attribute would have to be smarter:

@property
def dockerfile_path(self):
    if os.path.isfile(self._path):
        return self._path
    else:
        return os.path.join(self._path, DOCKERFILE_FILENAME)

@ElijahAhianyo
Copy link
Author

ElijahAhianyo commented Mar 9, 2022

Hi @ElijahAhianyo, thanks for the report!

As an immediate workaround, you may be able to pass the [dD]ockerfile via the fileobj argument instead of by path:

import dockerfile_parse

with open('./dockerfile', 'rb') as f:
    dockerfile = dockerfile_parse.DockerfileParser(fileobj=f)
    # do stuff with dockerfile

# can't use dockerfile anymore, fileobj is closed

Or, if using a real file object is not convenient:

import io
import dockerfile_parse

with open('./dockerfile', 'rb') as f:
    in_memory_file = io.BytesIO(f.read())

dockerfile = dockerfile_parse.DockerfileParser(fileobj=in_memory_file)
# note that writes to the dockerfile (e.g. via the `envs` or `labels` attributes)
#   will only be reflected in the in_memory_file, not on disk

Hey, @chmeliik Thanks for getting back to me. Tried out your suggestion and seems to work. However, the only downside is having to use the DockerfileParser object while the file is opened or using a yield rather than return in the case where the object is created in another function, but this shouldn't be a problem as I have a work-around for this. Thanks! :)

@MartinBasti
Copy link
Contributor

Can we close this issue then?

@ElijahAhianyo
Copy link
Author

ah yes sure

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