diff --git a/src/services/sysroot-service.test.ts b/src/services/sysroot-service.test.ts index 908c15656..9bf25a21a 100644 --- a/src/services/sysroot-service.test.ts +++ b/src/services/sysroot-service.test.ts @@ -125,6 +125,17 @@ describe('buildSysrootStageService', () => { expect(service.command[0]).toContain('.awf-sysroot-ready'); }); + it('escapes $d as $$d for Docker Compose variable interpolation', () => { + const service = buildSysrootStageService({ + config: makeConfig({ runnerTopology: 'arc-dind' }), + registry: 'ghcr.io/github/gh-aw-firewall', + imageTag: 'latest', + }); + // Docker Compose treats $var as variable interpolation; $$ escapes to literal $ + expect(service.command[0]).toContain('/$$d'); + expect(service.command[0]).not.toMatch(/\/\$d[^$]/); + }); + it('uses network_mode none (no network needed for copy)', () => { const service = buildSysrootStageService({ config: makeConfig({ runnerTopology: 'arc-dind' }), diff --git a/src/services/sysroot-service.ts b/src/services/sysroot-service.ts index 528ac8cc8..45e2f9b3a 100644 --- a/src/services/sysroot-service.ts +++ b/src/services/sysroot-service.ts @@ -44,7 +44,9 @@ export function buildSysrootStageService(params: SysrootServiceParams): any { 'fi; ' + 'echo "Copying sysroot filesystem..."; ' + 'for d in usr lib bin sbin etc; do ' + - ' [ -d "/$d" ] && cp -a "/$d" /sysroot/; ' + + // Use $$ to escape Docker Compose variable interpolation — Compose + // treats bare $d as a variable reference and replaces it with "". + ' [ -d "/$$d" ] && cp -a "/$$d" /sysroot/; ' + 'done; ' + 'if [ -d /lib64 ]; then cp -a /lib64 /sysroot/; fi; ' + 'touch /sysroot/.awf-sysroot-ready; ' +