Skip to content

Commit 9536a9f

Browse files
committed
Update UID only if GID is in use
1 parent 64807ce commit 9536a9f

7 files changed

Lines changed: 82 additions & 4 deletions

File tree

scripts/updateUID.Dockerfile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ RUN eval $(sed -n "s/${REMOTE_USER}:[^:]*:\([^:]*\):\([^:]*\):[^:]*:\([^:]*\).*/
1818
echo "UIDs and GIDs are the same ($NEW_UID:$NEW_GID)."; \
1919
elif [ "$OLD_UID" != "$NEW_UID" -a -n "$EXISTING_USER" ]; then \
2020
echo "User with UID exists ($EXISTING_USER=$NEW_UID)."; \
21-
elif [ "$OLD_GID" != "$NEW_GID" -a -n "$EXISTING_GROUP" ]; then \
22-
echo "Group with GID exists ($EXISTING_GROUP=$NEW_GID)."; \
2321
else \
22+
if [ "$OLD_GID" != "$NEW_GID" -a -n "$EXISTING_GROUP" ]; then \
23+
echo "Group with GID exists ($EXISTING_GROUP=$NEW_GID)."; \
24+
NEW_GID="$OLD_GID"; \
25+
fi; \
2426
echo "Updating UID:GID from $OLD_UID:$OLD_GID to $NEW_UID:$NEW_GID."; \
2527
sed -i -e "s/\(${REMOTE_USER}:[^:]*:\)[^:]*:[^:]*/\1${NEW_UID}:${NEW_GID}/" /etc/passwd; \
2628
if [ "$OLD_GID" != "$NEW_GID" ]; then \
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"build": {
3+
"dockerfile": "Dockerfile"
4+
},
5+
"remoteUser": "foo"
6+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
FROM debian:latest
2+
3+
RUN addgroup --gid 4321 foo
4+
RUN adduser --uid 1234 --gid 4321 foo
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"build": {
3+
"dockerfile": "Dockerfile",
4+
"args": {
5+
"LOCAL_GID": "${localEnv:LOCAL_GID}"
6+
}
7+
},
8+
"remoteUser": "foo"
9+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
FROM debian:latest
2+
3+
ARG LOCAL_GID
4+
RUN addgroup --gid $LOCAL_GID bar || true
5+
6+
RUN addgroup --gid 4321 foo
7+
RUN adduser --uid 1234 --gid 4321 foo

src/test/testUtils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,13 @@ export async function shellPtyExec(command: string, options: { stdin?: string }
8787
}).then(res => ({ code: 0, ...res }), error => error);
8888
}
8989

90-
export async function devContainerUp(cli: string, workspaceFolder: string, options?: { cwd?: string; useBuildKit?: boolean; userDataFolder?: string; logLevel?: string; extraArgs?: string; prefix?: string }): Promise<UpResult> {
90+
export async function devContainerUp(cli: string, workspaceFolder: string, options?: { cwd?: string; useBuildKit?: boolean; userDataFolder?: string; logLevel?: string; extraArgs?: string; prefix?: string; env?: NodeJS.ProcessEnv }): Promise<UpResult> {
9191
const buildkitOption = (options?.useBuildKit ?? false) ? '' : ' --buildkit=never';
9292
const userDataFolderOption = (options?.userDataFolder ?? false) ? ` --user-data-folder=${options?.userDataFolder}` : '';
9393
const logLevelOption = (options?.logLevel ?? false) ? ` --log-level ${options?.logLevel}` : '';
9494
const extraArgs = (options?.extraArgs ?? false) ? ` ${options?.extraArgs}` : '';
9595
const prefix = (options?.prefix ?? false) ? `${options?.prefix} ` : '';
96-
const shellExecOptions = { cwd: options?.cwd };
96+
const shellExecOptions = { cwd: options?.cwd, env: options?.env };
9797
const res = await shellExec(`${prefix}${cli} up --workspace-folder ${workspaceFolder}${buildkitOption}${userDataFolderOption}${extraArgs} ${logLevelOption}`, shellExecOptions);
9898
const response = JSON.parse(res.stdout);
9999
assert.equal(response.outcome, 'success');

src/test/updateUID.test.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import * as assert from 'assert';
7+
import * as path from 'path';
8+
import { devContainerDown, devContainerUp, shellExec } from './testUtils';
9+
10+
const pkg = require('../../package.json');
11+
12+
(process.platform === 'linux' ? describe : describe.skip)('Dev Containers CLI', function () {
13+
this.timeout('120s');
14+
15+
const tmp = path.relative(process.cwd(), path.join(__dirname, 'tmp'));
16+
const cli = `npx --prefix ${tmp} devcontainer`;
17+
18+
before('Install', async () => {
19+
await shellExec(`rm -rf ${tmp}/node_modules`);
20+
await shellExec(`mkdir -p ${tmp}`);
21+
await shellExec(`npm --prefix ${tmp} install devcontainers-cli-${pkg.version}.tgz`);
22+
});
23+
24+
describe('updateUID', () => {
25+
it('should update UID and GID', async () => {
26+
const testFolder = `${__dirname}/configs/updateUID`;
27+
const containerId = (await devContainerUp(cli, testFolder)).containerId;
28+
const uid = await shellExec(`${cli} exec --workspace-folder ${testFolder} id -u`);
29+
assert.strictEqual(uid.stdout.trim(), String(process.getuid!()));
30+
const gid = await shellExec(`${cli} exec --workspace-folder ${testFolder} id -g`);
31+
assert.strictEqual(gid.stdout.trim(), String(process.getgid!()));
32+
await devContainerDown({ containerId });
33+
});
34+
35+
it('should update only UID when GID exists', async () => {
36+
const testFolder = `${__dirname}/configs/updateUIDOnly`;
37+
const containerId = (await devContainerUp(cli, testFolder, {
38+
env: {
39+
...process.env,
40+
LOCAL_GID: String(process.getgid!())
41+
}
42+
})).containerId;
43+
const uid = await shellExec(`${cli} exec --workspace-folder ${testFolder} id -u`);
44+
assert.strictEqual(uid.stdout.trim(), String(process.getuid!()));
45+
const gid = await shellExec(`${cli} exec --workspace-folder ${testFolder} id -g`);
46+
assert.strictEqual(gid.stdout.trim(), String(4321));
47+
await devContainerDown({ containerId });
48+
});
49+
});
50+
});

0 commit comments

Comments
 (0)