Skip to content

Commit

Permalink
fix(core): allow asset bundling when selinux is enabled (#15742)
Browse files Browse the repository at this point in the history
----

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*
  • Loading branch information
maafk committed Sep 2, 2021
1 parent 2c1eb08 commit dbfebb4
Show file tree
Hide file tree
Showing 2 changed files with 158 additions and 3 deletions.
27 changes: 26 additions & 1 deletion packages/@aws-cdk/core/lib/bundling.ts
Expand Up @@ -200,7 +200,7 @@ export class BundlingDockerImage {
...options.user
? ['-u', options.user]
: [],
...flatten(volumes.map(v => ['-v', `${v.hostPath}:${v.containerPath}:${v.consistency ?? DockerVolumeConsistency.DELEGATED}`])),
...flatten(volumes.map(v => ['-v', `${v.hostPath}:${v.containerPath}:${isSeLinux() ? 'z,' : ''}${v.consistency ?? DockerVolumeConsistency.DELEGATED}`])),
...flatten(Object.entries(environment).map(([k, v]) => ['--env', `${k}=${v}`])),
...options.workingDirectory
? ['-w', options.workingDirectory]
Expand Down Expand Up @@ -481,3 +481,28 @@ function dockerExec(args: string[], options?: SpawnSyncOptions) {

return proc;
}

function isSeLinux() : boolean {
if (process.platform != 'linux') {
return false;
}
const prog = 'selinuxenabled';
const proc = spawnSync(prog, [], {
stdio: [ // show selinux status output
'pipe', // get value of stdio
process.stderr, // redirect stdout to stderr
'inherit', // inherit stderr
],
});
if (proc.error) {
// selinuxenabled not a valid command, therefore not enabled
return false;
}
if (proc.status == 0) {
// selinux enabled
return true;
} else {
// selinux not enabled
return false;
}
}
134 changes: 132 additions & 2 deletions packages/@aws-cdk/core/test/bundling.test.ts
Expand Up @@ -12,6 +12,7 @@ nodeunitShim({
},

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

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

'adding user provided securit-opt'(test: Test) {
'adding user provided security-opt'(test: Test) {
// GIVEN
sinon.stub(process, 'platform').value('darwin');
const spawnSyncStub = sinon.stub(child_process, 'spawnSync').returns({
status: 0,
stderr: Buffer.from('stderr'),
Expand All @@ -352,8 +356,9 @@ nodeunitShim({
output: ['stdout', 'stderr'],
signal: null,
});

const image = DockerImage.fromRegistry('alpine');

// GIVEN
image.run({
command: ['cool', 'command'],
environment: {
Expand All @@ -379,4 +384,129 @@ nodeunitShim({
], { stdio: ['ignore', process.stderr, 'inherit'] }));
test.done();
},

'ensure selinux docker mount'(test: Test) {
// GIVEN
sinon.stub(process, 'platform').value('linux');
const spawnSyncStub = sinon.stub(child_process, 'spawnSync');
spawnSyncStub.onFirstCall().returns({
status: 0,
stderr: Buffer.from('stderr'),
stdout: Buffer.from('stdout'),
pid: 123,
output: ['selinuxenable-command', 'stderr'],
signal: null,
});
spawnSyncStub.onSecondCall().returns({
status: 0,
stderr: Buffer.from('stderr'),
stdout: Buffer.from('stdout'),
pid: 124,
output: ['docker run command', 'stderr'],
signal: null,
});

// WHEN
const image = DockerImage.fromRegistry('alpine');
image.run({
command: ['cool', 'command'],
volumes: [{ hostPath: '/host-path', containerPath: '/container-path' }],
workingDirectory: '/working-directory',
user: 'user:group',
});

// THEN
test.ok(spawnSyncStub.secondCall.calledWith('docker', [
'run', '--rm',
'-u', 'user:group',
'-v', '/host-path:/container-path:z,delegated',
'-w', '/working-directory',
'alpine',
'cool', 'command',
], { stdio: ['ignore', process.stderr, 'inherit'] }));
test.done();
},

'ensure selinux docker mount on linux with selinux disabled'(test: Test) {
// GIVEN
sinon.stub(process, 'platform').value('linux');
const spawnSyncStub = sinon.stub(child_process, 'spawnSync');
spawnSyncStub.onFirstCall().returns({
status: 1,
stderr: Buffer.from('stderr'),
stdout: Buffer.from('stdout'),
pid: 123,
output: ['selinuxenabled output', 'stderr'],
signal: null,
});
spawnSyncStub.onSecondCall().returns({
status: 0,
stderr: Buffer.from('stderr'),
stdout: Buffer.from('stdout'),
pid: 124,
output: ['docker run command', 'stderr'],
signal: null,
});

// WHEN
const image = DockerImage.fromRegistry('alpine');
image.run({
command: ['cool', 'command'],
volumes: [{ hostPath: '/host-path', containerPath: '/container-path' }],
workingDirectory: '/working-directory',
user: 'user:group',
});

// THEN
test.ok(spawnSyncStub.secondCall.calledWith('docker', [
'run', '--rm',
'-u', 'user:group',
'-v', '/host-path:/container-path:delegated',
'-w', '/working-directory',
'alpine',
'cool', 'command',
], { stdio: ['ignore', process.stderr, 'inherit'] }));
test.done();
},
'ensure no selinux docker mount if selinuxenabled isn\'t an available command'(test: Test) {
// GIVEN
sinon.stub(process, 'platform').value('linux');
const spawnSyncStub = sinon.stub(child_process, 'spawnSync');
spawnSyncStub.onFirstCall().returns({
status: 127,
stderr: Buffer.from('stderr'),
stdout: Buffer.from('stdout'),
pid: 123,
output: ['selinuxenabled output', 'stderr'],
signal: null,
});
spawnSyncStub.onSecondCall().returns({
status: 0,
stderr: Buffer.from('stderr'),
stdout: Buffer.from('stdout'),
pid: 124,
output: ['docker run command', 'stderr'],
signal: null,
});

// WHEN
const image = DockerImage.fromRegistry('alpine');
image.run({
command: ['cool', 'command'],
volumes: [{ hostPath: '/host-path', containerPath: '/container-path' }],
workingDirectory: '/working-directory',
user: 'user:group',
});

// THEN
test.ok(spawnSyncStub.secondCall.calledWith('docker', [
'run', '--rm',
'-u', 'user:group',
'-v', '/host-path:/container-path:delegated',
'-w', '/working-directory',
'alpine',
'cool', 'command',
], { stdio: ['ignore', process.stderr, 'inherit'] }));
test.done();
},
});

0 comments on commit dbfebb4

Please sign in to comment.