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

Custom Docker image - Pre-install pre-commit hooks inside image #622

Closed
adlnc opened this issue Feb 14, 2024 · 6 comments
Closed

Custom Docker image - Pre-install pre-commit hooks inside image #622

adlnc opened this issue Feb 14, 2024 · 6 comments

Comments

@adlnc
Copy link

adlnc commented Feb 14, 2024

Describe the bug

Hi, not sure if exactly a bug but I feel like potentially misleading explanation in docs or more likely me missing the point completely. Anyway looking for help and not sure exactly where to ask.

I'm trying to build a container image based on the one featured in this repo: ghcr.io/antonbabenko/pre-commit-terraform.
Looking at #docker-usage I see that the recommended approach is to leave root user inside and leverage "USERID=$(id -u):$(id -g)" env var for the entrypoint script.
So I'm fine with that.

Now all I need is to pre-install the config that I want to share. For that I found this answer from anthony sottile on stackoverflow.

COPY .pre-commit-config.yaml .

RUN \
  git init . && \
  pre-commit install-hooks
  # pre-commit install --install-hooks
Dockerfile
FROM ghcr.io/antonbabenko/pre-commit-terraform:v1.86.0

ENV REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
ENV PRE_COMMIT_CACHE=/usr/pre-commit
ENV PRE_COMMIT_HOME="$PRE_COMMIT_CACHE/.cache/pre-commit"

## install custom ca certs & setup Alpine repositories mirrors
COPY ./custom-ca/* /usr/local/share/ca-certificates/

## setup Alpine repositories mirrors
RUN \
  cat /usr/local/share/ca-certificates/* >> /etc/ssl/certs/ca-certificates.crt && \
  . /etc/os-release && \
  echo "https://internal-mirror.domain/alpine/v${VERSION_ID%.*}/main" > /etc/apk/repositories && \
  echo "https://internal-mirror.domain/alpine/v${VERSION_ID%.*}/community" >> /etc/apk/repositories && \
  apk update && \
  apk -U --no-cache upgrade

WORKDIR $PRE_COMMIT_CACHE

## init pre-commit
COPY .pre-commit-config.yaml .

RUN \
  git init . && \
  pre-commit install --install-hooks
NB: I'm running behind corporate proxies with strong limitations. So you might want to remove that if you want to try yourself. Also I tried to use `PRE_COMMIT_HOME` so I could set a custom folder with open permissions. That didn't help.

So I tried that and got this :

Error message
An unexpected error has occurred: OperationalError: unable to open database file
Failed to write to log at /usr/pre-commit/.cache/pre-commit/pre-commit.log
### version information

pre-commit version: 3.6.0
git --version: git version 2.38.5
sys.version:
    3.12.0 (main, Dec  1 2023, 01:43:25) [GCC 12.2.1 20220924]
sys.executable: /usr/local/bin/python3
os.name: posix
sys.platform: linux

### error information

An unexpected error has occurred: OperationalError: unable to open database file

Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/pre_commit/error_handler.py", line 73, in error_handler
    yield
  File "/usr/local/lib/python3.12/site-packages/pre_commit/main.py", line 414, in main
    return run(args.config, store, args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pre_commit/commands/run.py", line 425, in run
    for hook in all_hooks(config, store)
                ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pre_commit/repository.py", line 242, in all_hooks
    return tuple(
           ^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pre_commit/repository.py", line 245, in <genexpr>
    for hook in _repository_hooks(repo, store, root_config)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pre_commit/repository.py", line 220, in _repository_hooks
    return _cloned_repository_hooks(repo_config, store, root_config)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pre_commit/repository.py", line 186, in _cloned_repository_hooks
    manifest_path = os.path.join(store.clone(repo, rev), C.MANIFEST_FILE)
                                 ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pre_commit/store.py", line 206, in clone
    return self._new_repo(repo, ref, deps, clone_strategy)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pre_commit/store.py", line 150, in _new_repo
    result = _get_result()
             ^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pre_commit/store.py", line 143, in _get_result
    with self.connect() as db:
  File "/usr/local/lib/python3.12/contextlib.py", line 137, in __enter__
    return next(self.gen)
           ^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pre_commit/store.py", line 120, in connect
    with contextlib.closing(sqlite3.connect(db_path)) as db:
                            ^^^^^^^^^^^^^^^^^^^^^^^^
sqlite3.OperationalError: unable to open database file

Which seems to be related to pre-commit running as root ? caused by my pre-commit install-hooks command as far as I understand.

I feel like I have to create a user with specific uid and get rid of the entrypoint script. Missing the ability to handle any uid. Or maybe my installation isn't correct.

Do you have an idea of what would be the best approach in my case ?

Thanks a lot !

@adlnc adlnc added area/docker bug Something isn't working labels Feb 14, 2024
@yermulnik
Copy link
Collaborator

I'm trying to build a container image

Do I get it right that the error pops up when you build container image? If yes, please share your Docker build command with all the parameters used.

@MaxymVlasov
Copy link
Collaborator

To be able to reproduce your build, we need your .pre-commit-config.yaml

## init pre-commit
COPY .pre-commit-config.yaml .

RUN \
  git init . && \
  pre-commit install --install-hooks

@MaxymVlasov MaxymVlasov added question and removed bug Something isn't working labels Feb 14, 2024
@adlnc
Copy link
Author

adlnc commented Feb 14, 2024

Sorry for being unclear about that. It builds fine but crashes on docker run.
To answer both,
I simply use:
docker build -f Dockerfile . -t pre-commit-terraform-custom:test
where the current folder contains
Dockerfile (previous coment) +
.pre-commit-config.yaml

.pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
  rev: v4.5.0
  hooks:
    - id: end-of-file-fixer
    - id: trailing-whitespace
- repo: https://github.com/antonbabenko/pre-commit-terraform
  rev: v1.86.0
  hooks:
    - id: terraform_validate
    - id: terraform_fmt
    - id: terraform_docs
    - id: terraform_tflint

Running the following cmd generates the error reported previously:
docker run -e "USERID=$(id -u):$(id -g)" -v $(pwd):/lint -w /lint pre-commit-terraform-custom:test run -a

NB:

❯ id -u
1000
❯ id -g
1000

@yermulnik
Copy link
Collaborator

yermulnik commented Feb 14, 2024

I'm not sure the solution is best as it's a bit of security hole and is anti-pattern, though given you create and populate pre-commit cache under root perms, and then you attempt to use it under regular user permissions, you may try and fix this "issue" by adjusting perms for PRE_COMMIT_HOME (or even for PRE_COMMIT_CACHE) to allow everyone to read and write everything under that path, e.g. chmod -R a+rwX "$PRE_COMMIT_HOME". But, as stated above, that's a security anti-pattern, and you might try to see what others use to resolve such tasks in the pre-commit repo since your "use case" is about pre-commit framework rather than about pre-commit-terraform IMHO.

@adlnc
Copy link
Author

adlnc commented Feb 15, 2024

ah ... I just feel kind of stupid .. I just added to the final RUN cmd && chmod -R a+rwX "$PRE_COMMIT_HOME" and it does seems to work now. I have no idea why I just did not think of that.

I'm curious to know what you would have done differently to propose another solution. I think I understand what you mean by security hole but not sure about the anti pattern.
This container aims to delivery a "basic" / "default" pre-commit-terraform image for users working on the same terraform code base in order to facilitate the standards (and workstation setup: just an alias pre-commit for that docker run cmd) over different services across my company. It's going to be used on local dev environments, not in any ci jobs for example.
I can't think of any other solution in order to pre-install and cache pre-commit configs and then being able to work in an almost offline (no-internet) environment and without creating a dedicated USER in the container image.
Thanks for your support.

@yermulnik
Copy link
Collaborator

I can't think of any other solution in order to pre-install and cache pre-commit configs and then being able to work in an almost offline (no-internet) environment and without creating a dedicated USER in the container image.

Yep, given that your container is targeted to a wide audience of users with different usernames, the "give read/write to all for pre-commit cache dir" looks reasonable. Moreover perms are scope to the very specific dir, which decreases the probability that users may try and threaten the container for any reason. So, probably, if this works for all your users, you should be ok to go with this solution.

but not sure about the anti pattern.

I mean that giving read-write to any arbitrary user is a security anti-pattern. Which, well, in your use case seems to be the inevitable measure to allow container to have a pre-baked pre-commit stuff.

I'm closing this issue. Please let us know if you still think it's worth keeping it open.

@yermulnik yermulnik closed this as not planned Won't fix, can't repro, duplicate, stale Feb 15, 2024
@MaxymVlasov MaxymVlasov changed the title Docker Usage - Pre installed config Errors Custom Docker image - Pre-install pre-commit hooks inside image Feb 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants