Skip to content

Commit

Permalink
Document unprivileged user in GitHub workflows
Browse files Browse the repository at this point in the history
At some point GitHub changed things so that the entrypoint script does
not run, so the `AS_USER` variable does nothing. Which is just as well,
because that user would have no permissions, so even a checkout will
fail.

So remove the GitHib-specific stuff from `entrypoint.sh` and separately
document running the container with the CLI and as a GitHub workflow.
Add a new section describing how to use `gosu` directly in a GitHub
workflow to execute commands as an unprivileged user.

Thanks to @pgguru for figuring out the technique.
  • Loading branch information
theory committed Feb 5, 2024
1 parent 475d691 commit 32b4573
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 35 deletions.
70 changes: 44 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@ PGXN Extension Build and Test Tools Docker Image

[![Test & Release Status](https://github.com/pgxn/docker-pgxn-tools/workflows/CI/CD/badge.svg)](https://github.com/pgxn/docker-pgxn-tools/actions)

``` sh
docker run -it --rm -w /repo --volume "$PWD:/repo" pgxn/pgxn-tools \
sh -c 'pg-start 12 && pg-build-test'
```

This project provides a simple Docker image to enable the automated testing of
PGXN extensions against multiple versions of PostgreSQL, as well as publishing
releases to PGXN. The image contains these utilities:
Expand All @@ -23,11 +18,25 @@ The image is based on the Debian Bookworm Slim image, and uses the
[PostgreSQL Apt] repository to install PostgreSQL, supporting versions
[back to 8.2], as well as the latest prerelease version.

Unprivileged User
-----------------

Running a Container
-------------------

To run pgxn-tools in Docker, use the standard Docker CLI, like so:

``` sh
docker run -it --rm -w /repo --volume "$PWD:/repo" pgxn/pgxn-tools \
sh -c 'pg-start 16 && pg-build-test'
```

This example mounts the current directory inside the container. Once inside, it
starts Postgres 16 then builds and runs the tests for the extension in that
directory.

### Unprivileged User

By default the container runs as `root`. To run as an unprivileged user, pass
the `AS_USER` environment variable, and a user with that name will be created
the `AS_USER` environment variable and a user with that name will be created
with `sudo` privileges (already used by `pg-start` and `pg-build-test`):

``` sh
Expand All @@ -46,11 +55,6 @@ docker run -it --rm -w /repo -e AS_USER=worker -e LOCAL_UID=$(id -u) \
sh -c 'sudo pg-start 14 && pg-build-test'
```

If no `LOCAL_UID` is set but `GITHUB_EVENT_PATH` is set (as it is in GitHub
workflows), the UID will be set to the same value as the owner of the
`GITHUB_EVENT_PATH` file. This allows the user to have full access to the
GitHub project volume.

### Postgres User

The `postgres` user, created by `pg-start`, also has full permission to use
Expand All @@ -77,20 +81,11 @@ jobs:
- name: Start PostgreSQL ${{ matrix.pg }}
run: pg-start ${{ matrix.pg }}
- name: Check out the repo
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Test on PostgreSQL ${{ matrix.pg }}
run: pg-build-test
```
If you need to run the tests as an unprivileged user, pass the `AS_USER`
variable as a container option:

``` yaml
container:
image: pgxn/pgxn-tools
options: -e AS_USER=randy
```

This example demonstrates automatic publishing of a release whenever a tag is
pushed matching `v*`. It publishes both to GitHub (using the [create-release]
and [upload-release-asset] actions) and to PGXN:
Expand All @@ -99,8 +94,8 @@ and [upload-release-asset] actions) and to PGXN:
name: Release
on:
push:
tags:
- 'v*' # Push events matching v1.0, v20.15.10, etc.
# Push events matching v1.0, v20.15.10, etc.
tags: ['v[0-9]+.[0-9]+.[0-9]+']
jobs:
release:
name: Release on GitHub and PGXN
Expand All @@ -111,7 +106,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Check out the repo
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Bundle the Release
id: bundle
run: pgxn-bundle
Expand Down Expand Up @@ -141,6 +136,27 @@ jobs:
asset_content_type: application/zip
```

### Unprivileged User Workflow

GitHub workflows [require the root user] to work with the workspace. To perform
tasks as an unprivileged user, first set things up as the root user, then use
[gosu] to execute a command as the `postgres` (can still run `sudo`) or `nobody`
(no privileges at all) user. For example:

``` yaml
container: pgxn/pgxn-tools
steps:
- uses: actions/checkout@v4
- run: pg-start 16
- run: chown -R postgres:postgres .
- run: gosu postgres pg-build-test
```

The checkout action, `pg-start`, and `chown` commands run as `root`. Then, with
the current directory's files all owned the newly-created `postgres` user, the
last `run` commands executes `pg-build-test` as `postgres`, with the necessary
permissions to write files to the workspace directory.

Tools
-----

Expand Down Expand Up @@ -388,7 +404,9 @@ Copyright (c) 2020-2024 The PGXN Maintainers. Distributed under the
[`pgxn-release`]: bin/pgxn-release
[PostgreSQL Apt]: https://wiki.postgresql.org/wiki/Apt
[back to 8.2]: http://apt.postgresql.org/pub/repos/apt/dists/bookworm-pgdg/
[require the root user]: https://docs.github.com/en/actions/creating-actions/dockerfile-support-for-github-actions#user
[GithHub Workflow]: https://help.github.com/en/actions/configuring-and-managing-workflows
[gosu]: https://github.com/tianon/gosu
[create-release]: https://github.com/actions/create-release
[upload-release-asset]: https://github.com/actions/upload-release-asset
[git-archive-all]: https://github.com/Kentzo/git-archive-all
Expand Down
10 changes: 1 addition & 9 deletions bin/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,9 @@ set -e
# Just continue if unprivileged user not requested.
[ -z "$AS_USER" ] && exec "$@"

USER_ID=${LOCAL_UID:-0}
USER_ID=${LOCAL_UID:-1001}
USERNAME=worker

if [ $USER_ID == 0 ]; then
if [ -n "${GITHUB_EVENT_PATH}" ]; then
USER_ID=$(stat -f %u "${GITHUB_EVENT_PATH}")
else
USER_ID=1001
fi
fi

echo "Starting with UID $USER_ID"
useradd --system --create-home --shell /bin/bash -g root -G sudo -u $USER_ID "$AS_USER"
export HOME="/home/$AS_USER"
Expand Down

0 comments on commit 32b4573

Please sign in to comment.