woodpecker-ci / woodpecker

Woodpecker is a simple, yet powerful CI/CD engine with great extensibility.
https://woodpecker-ci.org
Apache License 2.0
4.17k stars 360 forks source link

`2.4.1` backend docker run error `cannot create /root/.netrc: Permission denied` #3552

Open sinlov opened 6 months ago

sinlov commented 6 months ago

Component

server, agent

Describe the bug

labels: # https://woodpecker-ci.org/docs/usage/workflow-syntax#labels
  backend: docker
  platform: linux/amd64

steps:
  python-poetry-gcc:
    image: fnndsc/python-poetry:1.7.1
    pull: false
    commands:
      - whoami
      - id

will be error as

/bin/sh: 3: cannot create /root/.netrc: Permission denied

but if use woodpecker 2.4.0 can run and print

+ whoami
mambauser
+ id
uid=1000(mambauser) gid=1000(mambauser) groups=1000(mambauser)

System Info

## woodpecker v2.4.1
labels: # https://woodpecker-ci.org/docs/usage/workflow-syntax#labels
  backend: docker
  platform: linux/amd64

steps:
  python-poetry-gcc:
    image: fnndsc/python-poetry:1.7.1
    pull: false
    commands:
      - whoami
      - id

Additional context

beacuse fnndsc/python-poetry:1.7.1 image not use root

Validations

qwerty287 commented 5 months ago

Are you sure that's a woodpecker issue? We didn't change anything related to docker in 2.4.1. For non-root images see #1077

sinlov commented 5 months ago

Are you sure that's a woodpecker issue? We didn't change anything related to docker in 2.4.1. For non-root images see #1077

Confirm that 2.4.1 has appeared, 2.4.0 In the same host environment, the docker-compose file only changes the version number and can be used

docker information

Client: Docker Engine - Community
 Version:           26.0.0
 API version:       1.45
 Go version:        go1.21.8
 Git commit:        2ae903e
 Built:             Wed Mar 20 15:17:48 2024
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          26.0.0
  API version:      1.45 (minimum version 1.24)
  Go version:       go1.21.8
  Git commit:       8b79278
  Built:            Wed Mar 20 15:17:48 2024
  OS/Arch:          linux/amd64
  Experimental:     true
 containerd:
  Version:          1.6.28
  GitCommit:        ae07eda36dd25f8a1b98dfbf587313b99c0190bb
 runc:
  Version:          1.1.12
  GitCommit:        v1.1.12-0-g51d5e94
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

some config of .docker-python-poetry-gcc.yml

labels:
  backend: docker
  platform: linux/amd64

skip_clone: true

steps:
  init:
    image: sinlov/woodpecker-plugin-env:1.13.0 # https://hub.docker.com/r/sinlov/woodpecker-plugin-env/tags
    pull: false
    settings:
      # debug: true
      env_printer_padding_left_max: 36 # padding left max
  python-poetry-gcc:
    image: fnndsc/python-poetry:1.7.1
    pull: false
    commands:
      - export HOME="$(getent passwd $(id -u) | cut '-d:' -f6)"
      - whoami
      - id
      - pwd
      - ls -alFh

截屏2024-04-10 01 50 01

...
CI_SYSTEM_PLATFORM                   linux/amd[6](https://woodpecker.xxxxxx.com/repos/1/pipeline/26/2#L6)4
CI_SYSTEM_VERSION                    2.4.1

CI_WORKFLOW_NAME                     docker-python-poetry-gcc
...
....
/bin/sh: 3: cannot create /root/.netrc: Permission denied

截屏2024-04-10 01 47 37

CI_SYSTEM_PLATFORM                   linux/amd[6](https://woodpecker.xxxxxxxx.cn/repos/1/pipeline/11/7#L6)4
CI_SYSTEM_VERSION                    2.4.0

CI_WORKFLOW_NAME                     docker-python-poetry-gcc
...

+ export HOME="$(getent passwd $(id -u) | cut '-d:' -f6)"
+ whoami
mambauser
+ id
uid=1000(mambauser) gid=1000(mambauser) groups=1000(mambauser)
+ pwd
/woodpecker/src/gitea.xxxxxxxx.cn/woodpecker-zoo/guidance-woodpecker-docker
+ ls -alFh
total 2.0K
drwxr-xr-x 2 root root 2 Apr  9 17:44 ./
drwxr-xr-x 3 root root 3 Apr  9 17:44 ../

Inheriting the mirror image separately, maintaining a mirror to change user to root will fx. but rolling back the version will lead to unnecessary trouble.

FROM fnndsc/python-poetry:1.7.1

USER root:root

RUN apt-get update \
  && apt-get install -y make gcc \
  && apt-get autoclean \
  && apt-get clean \
  && apt-get autoremove \
  && rm -rf /var/lib/apt/lists/*

# USER mambauser:mambauser

drone runer drone/drone-runner-docker:1.8.2 can change user as

...
  - name: python-poetry-build
    image: fnndsc/python-poetry:1.7.1 # https://hub.docker.com/r/fnndsc/python-poetry/tags
    pull: if-not-exists
    user: root # for image fnndsc/python-poetry:1.7.1 default use `mambauser` can not management file
    volumes:
      - name: tmp-python-poetry-gcc-cache
        path: /root/.cache
      - name: tmp-python-poetry-gcc-local
        path: /root/.local
    commands:
      - whoami
      - id
      - pwd
      - ls -alFh .
...
RaymiiOrg commented 4 months ago

Experiencing this issue as well after upgrading from 1.0.0 to 2.4.1. Reverting back to 2.4.0 did not fix it.

My docker environment is alpine 3.19

RaymiiOrg commented 4 months ago

The docker image I used has a

USER: 

section. I have rebuilt that image without the USER: part and now the problem does not occur anymore.

Hentioe commented 3 months ago

This is probably because Woodpecker incorrectly modified some environment variables when starting the container, causing the user executed in the container to not match the HOME variable. This also caused other related failures on my side, and I had to manually set the HOME variable.

SourceCodeBot commented 2 months ago

since the milestones changed, is that issue planed for 2.x.x or 3.x.x?

qwerty287 commented 2 months ago

3.x.x. because we'll release 3.0.0 next.

xoxys commented 1 month ago

See https://github.com/woodpecker-ci/woodpecker/blob/main/pipeline/backend/common/script.go#L31

Why do we hard-code HOME=/root while we don't enforce that the container user is root? Either we don't hard-code HOME or we set --user=root if we start step containers. Or am I missing something?

As @Hentioe said already setting HOME=/home/<container-user> manually works, however keep in mind you have to set it in the commands section via export HOME=/home/<container-user>, using the step environment option doesn't work.

@woodpecker-ci/maintainers do you have a preferred way? I tend to drop the hard-coded HOME env var, but not sure about side effects.

6543 commented 1 month ago

yes we can drop the hardcoded home var

xoxys commented 1 month ago

Ok, but what happens if $HOME is not set by the container, e.g. on distroless/scratch containers or due to any other reason? We rely on it at some parts e.g. to write $HOME/.netrc.

zc-devs commented 1 month ago

on distroless/scratch

There is no shell.

$HOME is not set by the container

What if I run container as user and group 12345 (suppose, there is no such user/group)? I guess, container works under arbitrary user or not. The same with HOME.


If HOME is not set, we probably could set it to workspace root (/woodpecker).

mortbauer commented 2 weeks ago

Any fix or workaround for this, just trying to make the switch from drone and falling over this?

qwerty287 commented 2 weeks ago

What about https://github.com/woodpecker-ci/woodpecker/issues/3552#issuecomment-2207428369?

mortbauer commented 2 weeks ago

@qwerty287 thanks for the suggestion but doesn't seem to work for me, will adapt the image i use for now.

zc-devs commented 2 weeks ago

manually set the HOME variable

doesn't seem to work for me

@mortbauer, what exactly did you try?

3164, #1077

pat-s commented 4 days ago

I've debugged this a bit (using 2.7.0) and I think there are two different issues here:

  1. In "trusted" mode when using a non-root user: $HOME is hard-coded to root and can't be overwritten and the .netrc injection is happening before the first command starts.
  2. In "untrusted" mode when using a non-root user (related to #1077): While the .netrc injection does not happen here, a manual clone as the first command still fails because the container user is starting in $CI_WORKSPACE (which belongs to root) and doesn't have permissions there.

For (1), I currently only see the option to use an image with root as the container user until the hard-coded $HOME is removed and we ensured that the .netrc injection is happening dynamically in whatever $HOME is in the container (currently is still hard-coded to /root in the codebase).

For (2), the following should be a generic snippet that works for most pipelines (untrusted) and containers:

      - export HOME=/home/$(whoami)
      - cd ~ && git clone --depth 1 https://<username>:$$<secret token>@<forge URL>/${CI_REPO}.git && cd ${CI_REPO_NAME}

In addition, we should ensure that $CI_WORKSPACE is owned by the container user so the cd ~ is not needed.


Manually setting HOME in environment: doesn't have an effect as it does not overwrite the hard-coded default.