TechDocs: Pass user and group ID when invoking docker container

Without this, files generated by Docker container will be restricted to the root  user
This commit is contained in:
Himanshu Mishra
2021-02-17 12:40:29 +01:00
parent 2d8e78ed4c
commit 5795f2dc93
2 changed files with 45 additions and 2 deletions
@@ -30,6 +30,7 @@ import {
patchMkdocsYmlPreBuild,
runDockerContainer,
storeEtagMetadata,
UserOptions,
} from './helpers';
const mockEntity = {
@@ -114,7 +115,7 @@ describe('helpers', () => {
imageName,
args,
expect.any(Stream),
{
expect.objectContaining({
Volumes: {
'/content': {},
'/result': {},
@@ -123,7 +124,7 @@ describe('helpers', () => {
HostConfig: {
Binds: [`${docsDir}:/content`, `${outputDir}:/result`],
},
},
}),
);
});
@@ -139,6 +140,30 @@ describe('helpers', () => {
expect(mockDocker.ping).toHaveBeenCalled();
});
it('should pass through the user and group id from the host machine and set the home dir', async () => {
await runDockerContainer({
imageName,
args,
docsDir,
outputDir,
dockerClient: mockDocker,
});
const userOptions: UserOptions = {};
if (process.getuid && process.getgid) {
userOptions.User = `${process.getuid()}:${process.getgid()}`;
}
expect(mockDocker.run).toHaveBeenCalledWith(
imageName,
args,
expect.any(Stream),
expect.objectContaining({
...userOptions,
}),
);
});
describe('where docker is unavailable', () => {
const dockerError = 'a docker error';
@@ -51,6 +51,12 @@ export type RunCommandOptions = {
logStream?: Writable;
};
export type UserOptions = {
User?: string;
};
// To be replaced by a runDockerContainer from backend-common
// shared between Scaffolder and TechDocs and any other plugin.
export async function runDockerContainer({
imageName,
args,
@@ -78,6 +84,17 @@ export async function runDockerContainer({
});
});
const userOptions: UserOptions = {};
// @ts-ignore
if (process.getuid && process.getgid) {
// Files that are created inside the Docker container will be owned by
// root on the host system on non Mac systems, because of reasons. Mainly the fact that
// volume sharing is done using NFS on Mac and actual mounts in Linux world.
// So we set the user in the container as the same user and group id as the host.
// On Windows we don't have process.getuid nor process.getgid
userOptions.User = `${process.getuid()}:${process.getgid()}`;
}
const [{ Error: error, StatusCode: statusCode }] = await dockerClient.run(
imageName,
args,
@@ -91,6 +108,7 @@ export async function runDockerContainer({
HostConfig: {
Binds: [`${docsDir}:/content`, `${outputDir}:/result`],
},
...userOptions,
...createOptions,
},
);