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

feat: add support for a persistent ccache #66

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
} >> "$GITHUB_OUTPUT"
- name: Set up QEMU
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3
if: matrix.arch != '386' && matrix.arch != 'amd64'
if: matrix.arch != 'amd64'
with:
platforms: ${{ steps.prep.outputs.qemu_platform }}
- name: Set up buildx
Expand Down
10 changes: 10 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# syntax=docker/dockerfile:1.10.0@sha256:865e5dd094beca432e8c0a1d5e1c465db5f998dca4e439981029b3b81fb39ed5

Check warning on line 1 in Dockerfile

View workflow job for this annotation

GitHub Actions / 386:tcp image

Base image platform does not match expected target platform

InvalidBaseImagePlatform: Base image ksmanis/portage was pulled with platform "linux/amd64", expected "linux/386" for current build

Check warning on line 1 in Dockerfile

View workflow job for this annotation

GitHub Actions / 386:tcp image

Base image platform does not match expected target platform

InvalidBaseImagePlatform: Base image ksmanis/portage was pulled with platform "linux/amd64", expected "linux/386" for current build

Check warning on line 1 in Dockerfile

View workflow job for this annotation

GitHub Actions / 386:ssh image

Base image platform does not match expected target platform

InvalidBaseImagePlatform: Base image ksmanis/portage was pulled with platform "linux/amd64", expected "linux/386" for current build

Check warning on line 1 in Dockerfile

View workflow job for this annotation

GitHub Actions / 386:ssh image

Base image platform does not match expected target platform

InvalidBaseImagePlatform: Base image ksmanis/portage was pulled with platform "linux/amd64", expected "linux/386" for current build

Check warning on line 1 in Dockerfile

View workflow job for this annotation

GitHub Actions / arm/v6:tcp image

Base image platform does not match expected target platform

InvalidBaseImagePlatform: Base image ksmanis/portage was pulled with platform "linux/amd64", expected "linux/arm/v6" for current build

Check warning on line 1 in Dockerfile

View workflow job for this annotation

GitHub Actions / arm/v6:tcp image

Base image platform does not match expected target platform

InvalidBaseImagePlatform: Base image ksmanis/portage was pulled with platform "linux/amd64", expected "linux/arm/v6" for current build

Check warning on line 1 in Dockerfile

View workflow job for this annotation

GitHub Actions / arm/v6:ssh image

Base image platform does not match expected target platform

InvalidBaseImagePlatform: Base image ksmanis/portage was pulled with platform "linux/amd64", expected "linux/arm/v6" for current build

Check warning on line 1 in Dockerfile

View workflow job for this annotation

GitHub Actions / arm/v6:ssh image

Base image platform does not match expected target platform

InvalidBaseImagePlatform: Base image ksmanis/portage was pulled with platform "linux/amd64", expected "linux/arm/v6" for current build

Check warning on line 1 in Dockerfile

View workflow job for this annotation

GitHub Actions / arm/v7:tcp image

Base image platform does not match expected target platform

InvalidBaseImagePlatform: Base image ksmanis/portage was pulled with platform "linux/amd64", expected "linux/arm/v7" for current build

Check warning on line 1 in Dockerfile

View workflow job for this annotation

GitHub Actions / arm/v7:tcp image

Base image platform does not match expected target platform

InvalidBaseImagePlatform: Base image ksmanis/portage was pulled with platform "linux/amd64", expected "linux/arm/v7" for current build

Check warning on line 1 in Dockerfile

View workflow job for this annotation

GitHub Actions / arm/v7:ssh image

Base image platform does not match expected target platform

InvalidBaseImagePlatform: Base image ksmanis/portage was pulled with platform "linux/amd64", expected "linux/arm/v7" for current build

Check warning on line 1 in Dockerfile

View workflow job for this annotation

GitHub Actions / arm/v7:ssh image

Base image platform does not match expected target platform

InvalidBaseImagePlatform: Base image ksmanis/portage was pulled with platform "linux/amd64", expected "linux/arm/v7" for current build

Check warning on line 1 in Dockerfile

View workflow job for this annotation

GitHub Actions / arm64:tcp image

Base image platform does not match expected target platform

InvalidBaseImagePlatform: Base image ksmanis/portage was pulled with platform "linux/amd64", expected "linux/arm64" for current build

Check warning on line 1 in Dockerfile

View workflow job for this annotation

GitHub Actions / arm64:tcp image

Base image platform does not match expected target platform

InvalidBaseImagePlatform: Base image ksmanis/portage was pulled with platform "linux/amd64", expected "linux/arm64" for current build

Check warning on line 1 in Dockerfile

View workflow job for this annotation

GitHub Actions / arm64:ssh image

Base image platform does not match expected target platform

InvalidBaseImagePlatform: Base image ksmanis/portage was pulled with platform "linux/amd64", expected "linux/arm64" for current build

Check warning on line 1 in Dockerfile

View workflow job for this annotation

GitHub Actions / arm64:ssh image

Base image platform does not match expected target platform

InvalidBaseImagePlatform: Base image ksmanis/portage was pulled with platform "linux/amd64", expected "linux/arm64" for current build

Check warning on line 1 in Dockerfile

View workflow job for this annotation

GitHub Actions / ppc64le:tcp image

Base image platform does not match expected target platform

InvalidBaseImagePlatform: Base image ksmanis/portage was pulled with platform "linux/amd64", expected "linux/ppc64le" for current build

Check warning on line 1 in Dockerfile

View workflow job for this annotation

GitHub Actions / ppc64le:tcp image

Base image platform does not match expected target platform

InvalidBaseImagePlatform: Base image ksmanis/portage was pulled with platform "linux/amd64", expected "linux/ppc64le" for current build

Check warning on line 1 in Dockerfile

View workflow job for this annotation

GitHub Actions / ppc64le:ssh image

Base image platform does not match expected target platform

InvalidBaseImagePlatform: Base image ksmanis/portage was pulled with platform "linux/amd64", expected "linux/ppc64le" for current build

Check warning on line 1 in Dockerfile

View workflow job for this annotation

GitHub Actions / ppc64le:ssh image

Base image platform does not match expected target platform

InvalidBaseImagePlatform: Base image ksmanis/portage was pulled with platform "linux/amd64", expected "linux/ppc64le" for current build
FROM ksmanis/stage3:20240930@sha256:8e8a7c86ab167ea0b740664492e78dc97c33cc59f6fff13bf4ac40bca7804a37 AS distcc-builder
ARG CCACHE_DIR=/var/cache/ccache
ENV CCACHE_DIR=$CCACHE_DIR
RUN --mount=type=bind,from=ksmanis/gentoo-distcc:tcp,source=/var/cache/binpkgs,target=/cache \
--mount=type=bind,from=ksmanis/portage,source=/var/db/repos/gentoo,target=/var/db/repos/gentoo \
set -eux; \
Expand All @@ -8,10 +10,18 @@
emerge --info; \
emerge distcc; \
distcc --version; \
emerge ccache; \
ccache --version; \
echo "CCACHE_DIR=${CCACHE_DIR}" > /etc/env.d/02distcc-ssh-ccache; \
KSmanis marked this conversation as resolved.
Show resolved Hide resolved
env-update; \
mkdir "${CCACHE_DIR}"; \
chmod 0775 "${CCACHE_DIR}"; \
chown distcc:distcc "${CCACHE_DIR}"; \
emerge --oneshot gentoolkit; \
eclean packages; \
CLEAN_DELAY=0 emerge --depclean gentoolkit; \
find /var/cache/distfiles/ -mindepth 1 -delete -print
VOLUME $CCACHE_DIR

FROM distcc-builder AS distcc-tcp
ARG TARGETPLATFORM
Expand Down
57 changes: 57 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,63 @@ through the optional `SSH_USERNAME` environment variable:
docker run -d -p 30022:22 -e SSH_USERNAME=bob -e AUTHORIZED_KEYS="..." --name gentoo-distcc-ssh --rm ksmanis/gentoo-distcc:ssh
```

### Persistent [ccache(1)](https://ccache.dev/manual/latest.html)

Ccache speeds up recompilation by caching the result of previous compilations
and detecting when the same compilation is being done again. That can help save
time on compilation if you end up recompiling for any reason i.e. because you
have multiple gentoo machines which have an overlapping package selection.

Check the [gentoo wiki](https://wiki.gentoo.org/wiki/Ccache) to learn more. If
you only have one gentoo machine and it has enough disk space to host its own
cache, you might be better off with one local ccache on that machine with
`FEATURES="ccache"`. If you want to also add a cache to the container, keep
reading.

To enable the use of `ccache` you have to set `DISTCC_CCACHE_ENABLE` to `1`. And
to further make it persist over multiple container runs you need to mount a
container volume or a host directory to `/var/cache/ccache`.

#### Example with a persistent ccache in a docker volume

Create a new volume for persistency:

```shell
docker volume create gentoo-distcc-ccache
```

```shell
docker run -d -p 3632:3632 --name gentoo-distcc-tcp --rm -v gentoo-distcc-ccache:/var/cache/ccache/:rw -e DISTCC_CCACHE_ENABLE=1 ksmanis/gentoo-distcc:tcp
```

For the ssh variant of the container images it works exactly the same way.

#### Notes on ccache

To check the status of the cache you can run `ccache -s` with the container
image like that:

```shell
docker run -t -i --rm -v gentoo-distcc-ccache:/var/cache/ccache/:rw ksmanis/gentoo-distcc:tcp watch -d ccache -s
```

In case you created a container with the ssh variant, you can also ssh into it
and run `ccache -s`.

```shell
ssh localhost-distcc ccache -s
```

You should see the cache filling up and if you compile the same package twice
you should see cache hits coming in. If you are using `FEATURES="ccache"` from
gentoo you might want to disable it for a test. Otherwise local cache hits will
prevent remote compilation.

When you choose a bind-mount the cache is a shared folder between the host and
the container. If both want to access it you might have to play with `chown` and
`CCACHE_UMASK` (or `umask` in ccache.conf). Note that a world writable cache
will have security implications on all systems using distcc.

## Testing

A manual way to test the containers is to compile a sample C file:
Expand Down
10 changes: 7 additions & 3 deletions docker-entrypoint-ssh.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ fi

if [ "$1" = "sshd" ]; then
# Create user and set up SSH access
id "${SSH_USERNAME}" >/dev/null 2>&1 || useradd "${SSH_USERNAME}"
id "${SSH_USERNAME}" >/dev/null 2>&1 || useradd -g distcc "${SSH_USERNAME}"
mkdir -p "/home/${SSH_USERNAME}/.ssh"
chown "${SSH_USERNAME}:${SSH_USERNAME}" "/home/${SSH_USERNAME}/.ssh"
chown "${SSH_USERNAME}:distcc" "/home/${SSH_USERNAME}/.ssh"
chmod 700 "/home/${SSH_USERNAME}/.ssh"
echo "${AUTHORIZED_KEYS}" > "/home/${SSH_USERNAME}/.ssh/authorized_keys"
chown "${SSH_USERNAME}:${SSH_USERNAME}" "/home/${SSH_USERNAME}/.ssh/authorized_keys"
chown "${SSH_USERNAME}:distcc" "/home/${SSH_USERNAME}/.ssh/authorized_keys"
chmod 600 "/home/${SSH_USERNAME}/.ssh/authorized_keys"
# Create missing SSH host keys
ssh-keygen -A
Expand All @@ -26,6 +26,10 @@ if [ "$1" = "sshd" ]; then
fi
# Execute sshd using absolute path
shift
if [ "${DISTCC_CCACHE_ENABLE}" = 1 ]; then
echo "PATH=/usr/lib/ccache/bin" >> /etc/env.d/02distcc-ssh-ccache
env-update
fi
exec /usr/sbin/sshd "$@"
fi

Expand Down
3 changes: 3 additions & 0 deletions docker-entrypoint-tcp.sh
henning-schild marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ set -e
# * if hyphenated flag arguments (e.g., '-f', '-foo', or '--foo') were
# passed to the Docker command line
if [ "$#" -eq 0 ] || [ "${1#-}" != "$1" ]; then
if [ "${DISTCC_CCACHE_ENABLE}" = 1 ]; then
export PATH="/usr/lib/ccache/bin:$PATH"
fi
exec distccd --daemon --no-detach --log-level notice --log-stderr --allow-private "$@"
fi

Expand Down
Loading