diff --git a/packages/@aws-cdk/core/lib/bundling.ts b/packages/@aws-cdk/core/lib/bundling.ts index 1034517534f10..e078153386c6e 100644 --- a/packages/@aws-cdk/core/lib/bundling.ts +++ b/packages/@aws-cdk/core/lib/bundling.ts @@ -112,7 +112,7 @@ export class BundlingDockerImage { ...options.user ? ['-u', options.user] : [], - ...flatten(volumes.map(v => ['-v', `${v.hostPath}:${v.containerPath}`])), + ...flatten(volumes.map(v => ['-v', `${v.hostPath}:${v.containerPath}:${v.consistency ?? DockerVolumeConsistency.DELEGATED}`])), ...flatten(Object.entries(environment).map(([k, v]) => ['--env', `${k}=${v}`])), ...options.workingDirectory ? ['-w', options.workingDirectory] @@ -138,6 +138,32 @@ export interface DockerVolume { * The path where the file or directory is mounted in the container */ readonly containerPath: string; + + /** + * Mount consistency. Only applicable for macOS + * + * @default DockerConsistency.DELEGATED + * @see https://docs.docker.com/storage/bind-mounts/#configure-mount-consistency-for-macos + */ + readonly consistency?: DockerVolumeConsistency; +} + +/** + * Supported Docker volume consistency types. Only valid on macOS due to the way file storage works on Mac + */ +export enum DockerVolumeConsistency { + /** + * Read/write operations inside the Docker container are applied immediately on the mounted host machine volumes + */ + CONSISTENT = 'consistent', + /** + * Read/write operations on mounted Docker volumes are first written inside the container and then synchronized to the host machine + */ + DELEGATED = 'delegated', + /** + * Read/write operations on mounted Docker volumes are first applied on the host machine and then synchronized to the container + */ + CACHED = 'cached', } /** diff --git a/packages/@aws-cdk/core/test/test.bundling.ts b/packages/@aws-cdk/core/test/test.bundling.ts index 2ba23a83ffce9..558765010ccfe 100644 --- a/packages/@aws-cdk/core/test/test.bundling.ts +++ b/packages/@aws-cdk/core/test/test.bundling.ts @@ -34,7 +34,7 @@ export = { test.ok(spawnSyncStub.calledWith('docker', [ 'run', '--rm', '-u', 'user:group', - '-v', '/host-path:/container-path', + '-v', '/host-path:/container-path:delegated', '--env', 'VAR1=value1', '--env', 'VAR2=value2', '-w', '/working-directory', diff --git a/packages/@aws-cdk/core/test/test.staging.ts b/packages/@aws-cdk/core/test/test.staging.ts index e229d29ed1e8b..98e8f665de9b7 100644 --- a/packages/@aws-cdk/core/test/test.staging.ts +++ b/packages/@aws-cdk/core/test/test.staging.ts @@ -122,7 +122,7 @@ export = { const assembly = app.synth(); test.deepEqual( readDockerStubInput(), - `run --rm ${USER_ARG} -v /input:/asset-input -v /output:/asset-output -w /asset-input alpine DOCKER_STUB_SUCCESS`, + `run --rm ${USER_ARG} -v /input:/asset-input:delegated -v /output:/asset-output:delegated -w /asset-input alpine DOCKER_STUB_SUCCESS`, ); test.deepEqual(fs.readdirSync(assembly.directory), [ 'asset.2f37f937c51e2c191af66acf9b09f548926008ec68c575bd2ee54b6e997c0e00', @@ -158,7 +158,7 @@ export = { test.equal( readDockerStubInput(), - `run --rm ${USER_ARG} -v /input:/asset-input -v /output:/asset-output -w /asset-input alpine DOCKER_STUB_SUCCESS_NO_OUTPUT`, + `run --rm ${USER_ARG} -v /input:/asset-input:delegated -v /output:/asset-output:delegated -w /asset-input alpine DOCKER_STUB_SUCCESS_NO_OUTPUT`, ); test.done(); }, @@ -182,7 +182,7 @@ export = { // THEN test.equal( readDockerStubInput(), - `run --rm ${USER_ARG} -v /input:/asset-input -v /output:/asset-output -w /asset-input alpine DOCKER_STUB_SUCCESS`, + `run --rm ${USER_ARG} -v /input:/asset-input:delegated -v /output:/asset-output:delegated -w /asset-input alpine DOCKER_STUB_SUCCESS`, ); test.equal(asset.assetHash, '33cbf2cae5432438e0f046bc45ba8c3cef7b6afcf47b59d1c183775c1918fb1f'); @@ -226,7 +226,7 @@ export = { }), /Cannot specify `bundle` for `assetHashType`/); test.equal( readDockerStubInput(), - `run --rm ${USER_ARG} -v /input:/asset-input -v /output:/asset-output -w /asset-input alpine DOCKER_STUB_SUCCESS`, + `run --rm ${USER_ARG} -v /input:/asset-input:delegated -v /output:/asset-output:delegated -w /asset-input alpine DOCKER_STUB_SUCCESS`, ); test.done(); @@ -280,7 +280,7 @@ export = { }), /Failed to run bundling Docker image for asset stack\/Asset/); test.equal( readDockerStubInput(), - `run --rm ${USER_ARG} -v /input:/asset-input -v /output:/asset-output -w /asset-input this-is-an-invalid-docker-image DOCKER_STUB_FAIL`, + `run --rm ${USER_ARG} -v /input:/asset-input:delegated -v /output:/asset-output:delegated -w /asset-input this-is-an-invalid-docker-image DOCKER_STUB_FAIL`, ); test.done();