Skip to content

Commit dbfebb4

Browse files
authored
fix(core): allow asset bundling when selinux is enabled (#15742)
---- Revisiting [#9445](#9445) but looking to see if running on linux with selinux enabled. This PR aims to allow for asset bundling on linux os with selinux enabled *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 2c1eb08 commit dbfebb4

File tree

2 files changed

+158
-3
lines changed

2 files changed

+158
-3
lines changed

packages/@aws-cdk/core/lib/bundling.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ export class BundlingDockerImage {
200200
...options.user
201201
? ['-u', options.user]
202202
: [],
203-
...flatten(volumes.map(v => ['-v', `${v.hostPath}:${v.containerPath}:${v.consistency ?? DockerVolumeConsistency.DELEGATED}`])),
203+
...flatten(volumes.map(v => ['-v', `${v.hostPath}:${v.containerPath}:${isSeLinux() ? 'z,' : ''}${v.consistency ?? DockerVolumeConsistency.DELEGATED}`])),
204204
...flatten(Object.entries(environment).map(([k, v]) => ['--env', `${k}=${v}`])),
205205
...options.workingDirectory
206206
? ['-w', options.workingDirectory]
@@ -481,3 +481,28 @@ function dockerExec(args: string[], options?: SpawnSyncOptions) {
481481

482482
return proc;
483483
}
484+
485+
function isSeLinux() : boolean {
486+
if (process.platform != 'linux') {
487+
return false;
488+
}
489+
const prog = 'selinuxenabled';
490+
const proc = spawnSync(prog, [], {
491+
stdio: [ // show selinux status output
492+
'pipe', // get value of stdio
493+
process.stderr, // redirect stdout to stderr
494+
'inherit', // inherit stderr
495+
],
496+
});
497+
if (proc.error) {
498+
// selinuxenabled not a valid command, therefore not enabled
499+
return false;
500+
}
501+
if (proc.status == 0) {
502+
// selinux enabled
503+
return true;
504+
} else {
505+
// selinux not enabled
506+
return false;
507+
}
508+
}

packages/@aws-cdk/core/test/bundling.test.ts

Lines changed: 132 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ nodeunitShim({
1212
},
1313

1414
'bundling with image from registry'(test: Test) {
15+
sinon.stub(process, 'platform').value('darwin');
1516
const spawnSyncStub = sinon.stub(child_process, 'spawnSync').returns({
1617
status: 0,
1718
stderr: Buffer.from('stderr'),
@@ -230,6 +231,7 @@ nodeunitShim({
230231
},
231232

232233
'custom entrypoint is passed through to docker exec'(test: Test) {
234+
sinon.stub(process, 'platform').value('darwin');
233235
const spawnSyncStub = sinon.stub(child_process, 'spawnSync').returns({
234236
status: 0,
235237
stderr: Buffer.from('stderr'),
@@ -343,7 +345,9 @@ nodeunitShim({
343345
test.done();
344346
},
345347

346-
'adding user provided securit-opt'(test: Test) {
348+
'adding user provided security-opt'(test: Test) {
349+
// GIVEN
350+
sinon.stub(process, 'platform').value('darwin');
347351
const spawnSyncStub = sinon.stub(child_process, 'spawnSync').returns({
348352
status: 0,
349353
stderr: Buffer.from('stderr'),
@@ -352,8 +356,9 @@ nodeunitShim({
352356
output: ['stdout', 'stderr'],
353357
signal: null,
354358
});
355-
356359
const image = DockerImage.fromRegistry('alpine');
360+
361+
// GIVEN
357362
image.run({
358363
command: ['cool', 'command'],
359364
environment: {
@@ -379,4 +384,129 @@ nodeunitShim({
379384
], { stdio: ['ignore', process.stderr, 'inherit'] }));
380385
test.done();
381386
},
387+
388+
'ensure selinux docker mount'(test: Test) {
389+
// GIVEN
390+
sinon.stub(process, 'platform').value('linux');
391+
const spawnSyncStub = sinon.stub(child_process, 'spawnSync');
392+
spawnSyncStub.onFirstCall().returns({
393+
status: 0,
394+
stderr: Buffer.from('stderr'),
395+
stdout: Buffer.from('stdout'),
396+
pid: 123,
397+
output: ['selinuxenable-command', 'stderr'],
398+
signal: null,
399+
});
400+
spawnSyncStub.onSecondCall().returns({
401+
status: 0,
402+
stderr: Buffer.from('stderr'),
403+
stdout: Buffer.from('stdout'),
404+
pid: 124,
405+
output: ['docker run command', 'stderr'],
406+
signal: null,
407+
});
408+
409+
// WHEN
410+
const image = DockerImage.fromRegistry('alpine');
411+
image.run({
412+
command: ['cool', 'command'],
413+
volumes: [{ hostPath: '/host-path', containerPath: '/container-path' }],
414+
workingDirectory: '/working-directory',
415+
user: 'user:group',
416+
});
417+
418+
// THEN
419+
test.ok(spawnSyncStub.secondCall.calledWith('docker', [
420+
'run', '--rm',
421+
'-u', 'user:group',
422+
'-v', '/host-path:/container-path:z,delegated',
423+
'-w', '/working-directory',
424+
'alpine',
425+
'cool', 'command',
426+
], { stdio: ['ignore', process.stderr, 'inherit'] }));
427+
test.done();
428+
},
429+
430+
'ensure selinux docker mount on linux with selinux disabled'(test: Test) {
431+
// GIVEN
432+
sinon.stub(process, 'platform').value('linux');
433+
const spawnSyncStub = sinon.stub(child_process, 'spawnSync');
434+
spawnSyncStub.onFirstCall().returns({
435+
status: 1,
436+
stderr: Buffer.from('stderr'),
437+
stdout: Buffer.from('stdout'),
438+
pid: 123,
439+
output: ['selinuxenabled output', 'stderr'],
440+
signal: null,
441+
});
442+
spawnSyncStub.onSecondCall().returns({
443+
status: 0,
444+
stderr: Buffer.from('stderr'),
445+
stdout: Buffer.from('stdout'),
446+
pid: 124,
447+
output: ['docker run command', 'stderr'],
448+
signal: null,
449+
});
450+
451+
// WHEN
452+
const image = DockerImage.fromRegistry('alpine');
453+
image.run({
454+
command: ['cool', 'command'],
455+
volumes: [{ hostPath: '/host-path', containerPath: '/container-path' }],
456+
workingDirectory: '/working-directory',
457+
user: 'user:group',
458+
});
459+
460+
// THEN
461+
test.ok(spawnSyncStub.secondCall.calledWith('docker', [
462+
'run', '--rm',
463+
'-u', 'user:group',
464+
'-v', '/host-path:/container-path:delegated',
465+
'-w', '/working-directory',
466+
'alpine',
467+
'cool', 'command',
468+
], { stdio: ['ignore', process.stderr, 'inherit'] }));
469+
test.done();
470+
},
471+
'ensure no selinux docker mount if selinuxenabled isn\'t an available command'(test: Test) {
472+
// GIVEN
473+
sinon.stub(process, 'platform').value('linux');
474+
const spawnSyncStub = sinon.stub(child_process, 'spawnSync');
475+
spawnSyncStub.onFirstCall().returns({
476+
status: 127,
477+
stderr: Buffer.from('stderr'),
478+
stdout: Buffer.from('stdout'),
479+
pid: 123,
480+
output: ['selinuxenabled output', 'stderr'],
481+
signal: null,
482+
});
483+
spawnSyncStub.onSecondCall().returns({
484+
status: 0,
485+
stderr: Buffer.from('stderr'),
486+
stdout: Buffer.from('stdout'),
487+
pid: 124,
488+
output: ['docker run command', 'stderr'],
489+
signal: null,
490+
});
491+
492+
// WHEN
493+
const image = DockerImage.fromRegistry('alpine');
494+
image.run({
495+
command: ['cool', 'command'],
496+
volumes: [{ hostPath: '/host-path', containerPath: '/container-path' }],
497+
workingDirectory: '/working-directory',
498+
user: 'user:group',
499+
});
500+
501+
// THEN
502+
test.ok(spawnSyncStub.secondCall.calledWith('docker', [
503+
'run', '--rm',
504+
'-u', 'user:group',
505+
'-v', '/host-path:/container-path:delegated',
506+
'-w', '/working-directory',
507+
'alpine',
508+
'cool', 'command',
509+
], { stdio: ['ignore', process.stderr, 'inherit'] }));
510+
test.done();
511+
},
382512
});

0 commit comments

Comments
 (0)