From 17b473df2354119c3b404033f381842668f45526 Mon Sep 17 00:00:00 2001 From: usimd <11619247+usimd@users.noreply.github.com> Date: Sun, 3 Nov 2024 20:54:48 +0100 Subject: [PATCH] Add APT proxy and document use case --- .github/workflows/integration-test.yml | 22 ++++++++++++ .vscode/launch.json | 17 +++++++++ README.md | 48 ++++++++++++++++++++++++++ __test__/pi-gen-config.test.ts | 11 ++++-- action.yml | 7 +++- src/configure.ts | 1 + src/pi-gen-config.ts | 11 ++++++ 7 files changed, 113 insertions(+), 4 deletions(-) create mode 100644 .vscode/launch.json diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 47cbf7e..4b32eaf 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -61,6 +61,20 @@ jobs: - name: Compile action code before test run: npm ci && npm run package + - name: Restore package cache + uses: actions/cache@v4 + with: + path: /var/cache/apt-cacher-ng + key: ${{ runner.os }}-${{ github.job }} + restore-keys: | + ${{ runner.os }} + + - name: Setup APT proxy on runner + run: | + sudo apt-get install -y apt-cacher-ng --no-install-suggests --no-install-recommends + sudo echo "Port: 9999" >> /etc/apt-cacher-ng/acng.conf + sudo service apt-cacher-ng restart + - name: Run pi-gen build uses: ./ id: build @@ -81,6 +95,7 @@ jobs: timezone: ${{ env.CONFIG_TIMEZONE }} pubkey-ssh-first-user: ${{ env.CONFIG_PUBLIC_KEY }} increase-runner-disk-size: ${{ github.event_name != 'workflow_dispatch' || inputs.increase-runner-disk }} + apt-proxy: http://172.17.0.1:9999 - name: List working directory run: tree @@ -112,4 +127,11 @@ jobs: with: labels: test + - name: Debug APT proxy + if: always() + run: | + sudo tail -n 100 /etc/apt-cacher-ng/acng.conf + sudo service apt-cacher-ng status + sudo tail -n 200 /var/log/syslog /var/log/apt-cacher-ng/* + \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..a876f37 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,17 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug Jest Tests", + "type": "node", + "request": "launch", + "runtimeArgs": [ + "--inspect-brk", + "${workspaceRoot}/node_modules/.bin/jest", + "--runInBand" + ], + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen" + } + ] + } \ No newline at end of file diff --git a/README.md b/README.md index 3a8527e..3ad48e2 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,11 @@ tries to make sure the stage is respected and its changes are included in the fi ```yaml - uses: usimd/pi-gen-action@v1 with: + # If you require the use of an apt proxy, set it here. This proxy setting will not + # be included in the image, making it safe to use an apt-cacher or similar package + # for development. + apt-proxy: '' + # Compression to apply on final image (either "none", "zip", "xz" or "gz"). compression: zip @@ -197,6 +202,7 @@ tries to make sure the stage is respected and its changes are included in the fi - [Upload final image as artifact](#upload-final-image-as-artifact) - [Modify `pi-gen` internal stages](#modify-pi-gen-internal-stages) - [Increase GitHub Actions runner disk space](#increase-github-actions-runner-disk-space) +- [Use an APT proxy to define where to pull packages from](#use-fast-apt-proxy-for-pi-gen) ### Install NodeJS from Nodesource in the target image ```yaml @@ -314,6 +320,48 @@ jobs: increase-runner-disk-size: true ``` +### Use APT proxy for `pi-gen` + +There might be scenarios where you need to specifically select the package +mirror to pull from: +* custom runners with limited network access +* improved download speed when selecting a fast mirror via CDN does not suffice +* speed up build by caching pulled packages on the runner + +The latter is sketched below by adding `apt-cacher-ng` to the runner where its +cache directory is stored as a GitHub Actions cache. If you want to set up such +a scenario, remember to tweak the caching behavior of `apt-cacher-ng` so it +can make best use of the restored cache. + +``` +jobs: + pi-gen-with-apt-proxy: + runs-on: ubuntu-latest + steps: + - name: Restore package cache + uses: actions/cache@v4 + with: + path: /var/cache/apt-cacher-ng + key: ${{ runner.os }}-${{ github.job }} + restore-keys: + - ${{ runner.os }} + + - name: Setup APT proxy on runner + run: | + sudo apt-get install -y apt-cacher-ng --no-install-suggests --no-install-recommends + sudo echo "Port: 9999" >> /etc/apt-cacher-ng/acng.conf + sudo service apt-cacher-ng restart + + - uses: usimd/pi-gen-action@v1 + with: + image-name: test + stage-list: stage0 stage1 stage2 custom-stage + # Instead of referring to the runner's container IP directly, you could also add + # a new host entry to the pi-gen container: + # docker-opts: --add-host=host.docker.internal:host-gateway + apt-proxy: http://172.17.0.1:9999 +``` + ## License The scripts and documentation in this project are released under the [MIT License](LICENSE) diff --git a/__test__/pi-gen-config.test.ts b/__test__/pi-gen-config.test.ts index 7bcb4d9..ab22999 100644 --- a/__test__/pi-gen-config.test.ts +++ b/__test__/pi-gen-config.test.ts @@ -141,6 +141,11 @@ describe('PiGenConfig', () => { 'pubkeySshFirstUser', 'ssh-foo vnqf493rn34xzrm234yru13ß48rnz1x034ztn== foo@bar.com', 'pubkey-ssh-first-user does not seem to be a valid list of public key according to "ssh-keygen -l", here\'s its output' + ], + [ + 'aptProxy', + 'this/is/not/valid', + 'apt-proxy is not a valid URL. Make it point to a correct http/https address' ] ])( 'rejects %s with invalid value %s', @@ -152,9 +157,9 @@ describe('PiGenConfig', () => { expect(await validateConfig(piGenConfig)).toBeUndefined() piGenConfig[property as keyof PiGenConfig] = value - expect(async () => await validateConfig(piGenConfig)).rejects.toThrow( - error - ) + await expect( + async () => await validateConfig(piGenConfig) + ).rejects.toThrow(error) } ) diff --git a/action.yml b/action.yml index 328ea88..3190d1b 100644 --- a/action.yml +++ b/action.yml @@ -4,7 +4,12 @@ author: Simon Domke inputs: # pi-gen variables - + apt-proxy: + description: | + If you require the use of an apt proxy, set it here. This proxy setting will not be included in the image, + making it safe to use an apt-cacher or similar package for development. + required: false + default: '' image-name: description: Final image name. required: true diff --git a/src/configure.ts b/src/configure.ts index 6ecd63e..b04c35d 100644 --- a/src/configure.ts +++ b/src/configure.ts @@ -56,6 +56,7 @@ export async function configure(): Promise { userConfig.setfcap = core.getInput('setfcap') || DEFAULT_CONFIG.setfcap userConfig.piGenRelease = core.getInput('pi-gen-release') || DEFAULT_CONFIG.piGenRelease + userConfig.aptProxy = core.getInput('apt-proxy') || DEFAULT_CONFIG.aptProxy await validateConfig(userConfig) diff --git a/src/pi-gen-config.ts b/src/pi-gen-config.ts index bc4e04a..bc75339 100644 --- a/src/pi-gen-config.ts +++ b/src/pi-gen-config.ts @@ -6,6 +6,7 @@ import * as exec from '@actions/exec' import * as io from '@actions/io' export interface PiGenConfig { + aptProxy?: string imgName: string piGenRelease: string release: string @@ -220,6 +221,16 @@ export async function validateConfig(config: PiGenConfig): Promise { } } } + + if (config.aptProxy) { + try { + new URL(config.aptProxy) + } catch (error) { + throw new Error( + 'apt-proxy is not a valid URL. Make it point to a correct http/https address' + ) + } + } } function camelCaseToSnakeCase(label: string): string {