gcb-host 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -1
- package/bin/gcb.js +3 -3
- package/lib/audit.d.ts +4 -4
- package/lib/audit.d.ts.map +1 -1
- package/lib/audit.js +15 -14
- package/lib/audit.js.map +1 -1
- package/lib/broker.d.ts +12 -13
- package/lib/broker.d.ts.map +1 -1
- package/lib/broker.js +77 -53
- package/lib/broker.js.map +1 -1
- package/lib/commands/authorize.d.ts +43 -13
- package/lib/commands/authorize.d.ts.map +1 -1
- package/lib/commands/authorize.js +146 -53
- package/lib/commands/authorize.js.map +1 -1
- package/lib/commands/compose.d.ts +7 -7
- package/lib/commands/compose.d.ts.map +1 -1
- package/lib/commands/compose.js +21 -22
- package/lib/commands/compose.js.map +1 -1
- package/lib/commands/config.d.ts.map +1 -1
- package/lib/commands/config.js +59 -41
- package/lib/commands/config.js.map +1 -1
- package/lib/commands/deployment.d.ts +11 -11
- package/lib/commands/deployment.d.ts.map +1 -1
- package/lib/commands/deployment.js +19 -18
- package/lib/commands/deployment.js.map +1 -1
- package/lib/commands/diagnose.d.ts.map +1 -1
- package/lib/commands/diagnose.js +51 -33
- package/lib/commands/diagnose.js.map +1 -1
- package/lib/commands/doctor.d.ts +5 -5
- package/lib/commands/doctor.d.ts.map +1 -1
- package/lib/commands/doctor.js +53 -32
- package/lib/commands/doctor.js.map +1 -1
- package/lib/commands/host.d.ts +7 -7
- package/lib/commands/host.d.ts.map +1 -1
- package/lib/commands/host.js +147 -92
- package/lib/commands/host.js.map +1 -1
- package/lib/commands/init.d.ts +33 -33
- package/lib/commands/init.d.ts.map +1 -1
- package/lib/commands/init.js +93 -75
- package/lib/commands/init.js.map +1 -1
- package/lib/commands/stage.d.ts +6 -6
- package/lib/commands/stage.d.ts.map +1 -1
- package/lib/commands/stage.js +21 -15
- package/lib/commands/stage.js.map +1 -1
- package/lib/config.d.ts +29 -28
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +101 -85
- package/lib/config.js.map +1 -1
- package/lib/daemon.d.ts +9 -9
- package/lib/daemon.d.ts.map +1 -1
- package/lib/daemon.js +21 -18
- package/lib/daemon.js.map +1 -1
- package/lib/device-flow.d.ts +23 -22
- package/lib/device-flow.d.ts.map +1 -1
- package/lib/device-flow.js +33 -28
- package/lib/device-flow.js.map +1 -1
- package/lib/gh.d.ts +2 -2
- package/lib/gh.d.ts.map +1 -1
- package/lib/gh.js +74 -46
- package/lib/gh.js.map +1 -1
- package/lib/http.d.ts.map +1 -1
- package/lib/http.js +35 -18
- package/lib/http.js.map +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/policy.d.ts +25 -25
- package/lib/policy.d.ts.map +1 -1
- package/lib/policy.js +57 -36
- package/lib/policy.js.map +1 -1
- package/lib/providers/github-app.d.ts +12 -12
- package/lib/providers/github-app.d.ts.map +1 -1
- package/lib/providers/github-app.js +194 -125
- package/lib/providers/github-app.js.map +1 -1
- package/lib/providers/index.d.ts +8 -9
- package/lib/providers/index.d.ts.map +1 -1
- package/lib/providers/index.js +5 -5
- package/lib/providers/index.js.map +1 -1
- package/lib/providers/static.d.ts +3 -3
- package/lib/providers/static.d.ts.map +1 -1
- package/lib/providers/static.js +14 -12
- package/lib/providers/static.js.map +1 -1
- package/lib/proxy.d.ts +10 -10
- package/lib/proxy.d.ts.map +1 -1
- package/lib/proxy.js +18 -16
- package/lib/proxy.js.map +1 -1
- package/lib/public-repo.d.ts +10 -10
- package/lib/public-repo.d.ts.map +1 -1
- package/lib/public-repo.js +17 -14
- package/lib/public-repo.js.map +1 -1
- package/lib/reload.d.ts +4 -4
- package/lib/reload.d.ts.map +1 -1
- package/lib/reload.js +24 -14
- package/lib/reload.js.map +1 -1
- package/package.json +10 -10
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* `authorize` — get a user token for this app, once, from whoever runs it.
|
|
3
3
|
*
|
|
4
4
|
* Run on the host, beside the configuration. It prints a code, waits for that person to type it at
|
|
5
|
-
* GitHub on whatever device has a browser, and stores the refresh token next to the configuration
|
|
6
|
-
* its key — outside every mount, never in the repository. From then on the broker renews the
|
|
7
|
-
* itself and nothing here has to be run again.
|
|
5
|
+
* GitHub on whatever device has a browser, and stores the refresh token next to the configuration
|
|
6
|
+
* and its key — outside every mount, never in the repository. From then on the broker renews the
|
|
7
|
+
* token by itself and nothing here has to be run again.
|
|
8
8
|
*
|
|
9
9
|
* The token is what makes a pull request authored by a person rather than by the app. Only a person
|
|
10
10
|
* can be the author of one that reviewers will not skip, and only the device flow reaches a person
|
|
@@ -13,26 +13,56 @@
|
|
|
13
13
|
* Exit codes: 0 stored, 1 refused.
|
|
14
14
|
*/
|
|
15
15
|
/** Usage text for `authorize`. */
|
|
16
|
-
export declare const AUTHORIZE_USAGE = "Usage: gcb authorize [options]\n\nGet a user token for this app, by authorizing it once from a browser somewhere else. Run it on the host,\nbeside the configuration. It stores a refresh token and prints where; nothing else needs running after\nthat, because the broker renews the token itself.\n\n --config <path>
|
|
16
|
+
export declare const AUTHORIZE_USAGE = "Usage: gcb authorize [options]\n\nGet a user token for this app, by authorizing it once from a browser somewhere else. Run it on the host,\nbeside the configuration. It stores a refresh token and prints where; nothing else needs running after\nthat, because the broker renews the token itself.\n\n --config <path> The configuration (default: $GIT_BROKER_CONFIG, else ./broker.config.yml)\n --host <host> The host block to authorize for (default: github.com)\n --to <path> Where to write the refresh token (default: beside the configuration)\n --broker-container Allow a target inside the broker container's mounts; only when it is not\n shared with the agent container\n --proxy <url> Use this proxy for this command\n --no-proxy Reach GitHub directly for this command\n -h, --help Show this help\n\nThe app needs its client id configured (the App ID will not do), and \"Enable Device Flow\" selected in\nits settings. GitHub returns a refresh token only while \"Expire user authorization tokens\" is selected,\nwhich is its default and what this wants.\n";
|
|
17
17
|
/**
|
|
18
18
|
* Where this command writes the refresh token.
|
|
19
19
|
*
|
|
20
|
-
* Beside the configuration, because the configuration is the path this process was
|
|
21
|
-
* inside it belong to whichever process runs the broker, and for a sidecar those are
|
|
22
|
-
* that do not exist out here. In the usual sidecar layout the configuration and the
|
|
23
|
-
* directory, so this lands in the same file the broker reads; where they differ, the
|
|
24
|
-
* printed rather than discovered later.
|
|
20
|
+
* Beside the configuration, because the configuration is the path this process was _given_: the
|
|
21
|
+
* paths inside it belong to whichever process runs the broker, and for a sidecar those are
|
|
22
|
+
* container paths that do not exist out here. In the usual sidecar layout the configuration and the
|
|
23
|
+
* key sit in one directory, so this lands in the same file the broker reads; where they differ, the
|
|
24
|
+
* difference is printed rather than discovered later.
|
|
25
25
|
*
|
|
26
|
-
* @param configPath -
|
|
27
|
-
* @returns
|
|
26
|
+
* @param configPath - The resolved configuration path.
|
|
27
|
+
* @returns The path to write the refresh token to.
|
|
28
28
|
*/
|
|
29
29
|
export declare function refreshTokenPath(configPath: string): string;
|
|
30
30
|
/**
|
|
31
31
|
* Where the broker will look for it, which is beside the key — from the key's own point of view.
|
|
32
32
|
*
|
|
33
|
-
* @param privateKeyPath -
|
|
34
|
-
* @returns
|
|
33
|
+
* @param privateKeyPath - The path as the configuration records it.
|
|
34
|
+
* @returns The path the broker reads, or `undefined` when the key is not a file.
|
|
35
35
|
*/
|
|
36
36
|
export declare function brokerReadsPath(privateKeyPath: string | undefined): string | undefined;
|
|
37
|
+
/** Inputs for the credential-placement decision. */
|
|
38
|
+
export interface AuthorizationPlacementInput {
|
|
39
|
+
readonly configPath: string;
|
|
40
|
+
readonly to?: string;
|
|
41
|
+
readonly brokerContainer: boolean;
|
|
42
|
+
readonly isInsideContainer?: () => boolean;
|
|
43
|
+
readonly mountedPath?: (target: string) => string | null;
|
|
44
|
+
}
|
|
45
|
+
/** The writable target and the warning to print before starting the device flow. */
|
|
46
|
+
export interface AuthorizationPlacement {
|
|
47
|
+
readonly target: string;
|
|
48
|
+
readonly warning?: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Open and secure the token target before authorization, so a later path swap cannot redirect the
|
|
52
|
+
* write and a permission failure surfaces before the device flow.
|
|
53
|
+
*
|
|
54
|
+
* @param target - The token path.
|
|
55
|
+
* @returns The open descriptor, already mode 0600.
|
|
56
|
+
*/
|
|
57
|
+
export declare function openTokenTarget(target: string): number;
|
|
58
|
+
/**
|
|
59
|
+
* Decide where the refresh token goes, and whether that placement is allowed.
|
|
60
|
+
*
|
|
61
|
+
* @param input - The configuration path, target override and injectable guards.
|
|
62
|
+
* @returns The target and an optional warning.
|
|
63
|
+
* @throws {Error} When the placement would put the token inside a container mount without the
|
|
64
|
+
* explicit broker-container acknowledgement.
|
|
65
|
+
*/
|
|
66
|
+
export declare function resolveAuthorizationPlacement(input: AuthorizationPlacementInput): AuthorizationPlacement;
|
|
37
67
|
export declare function runAuthorize(argv: readonly string[]): Promise<number>;
|
|
38
68
|
//# sourceMappingURL=authorize.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorize.d.ts","sourceRoot":"","sources":["../../src/commands/authorize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;
|
|
1
|
+
{"version":3,"file":"authorize.d.ts","sourceRoot":"","sources":["../../src/commands/authorize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAoBH,kCAAkC;AAClC,eAAO,MAAM,eAAe,mnCAkB3B,CAAA;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAEtF;AAED,oDAAoD;AACpD,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAA;IACjC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAA;IAC1C,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAA;CACzD;AAED,oFAAoF;AACpF,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAmBtD;AAUD;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,2BAA2B,GACjC,sBAAsB,CAsBxB;AAUD,wBAAsB,YAAY,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA4G3E"}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* `authorize` — get a user token for this app, once, from whoever runs it.
|
|
3
3
|
*
|
|
4
4
|
* Run on the host, beside the configuration. It prints a code, waits for that person to type it at
|
|
5
|
-
* GitHub on whatever device has a browser, and stores the refresh token next to the configuration
|
|
6
|
-
* its key — outside every mount, never in the repository. From then on the broker renews the
|
|
7
|
-
* itself and nothing here has to be run again.
|
|
5
|
+
* GitHub on whatever device has a browser, and stores the refresh token next to the configuration
|
|
6
|
+
* and its key — outside every mount, never in the repository. From then on the broker renews the
|
|
7
|
+
* token by itself and nothing here has to be run again.
|
|
8
8
|
*
|
|
9
9
|
* The token is what makes a pull request authored by a person rather than by the app. Only a person
|
|
10
10
|
* can be the author of one that reviewers will not skip, and only the device flow reaches a person
|
|
@@ -12,11 +12,12 @@
|
|
|
12
12
|
*
|
|
13
13
|
* Exit codes: 0 stored, 1 refused.
|
|
14
14
|
*/
|
|
15
|
+
import { closeSync, constants, fchmodSync, fstatSync, ftruncateSync, mkdirSync, openSync, writeFileSync, } from 'node:fs';
|
|
15
16
|
import { dirname, join, resolve as resolvePath } from 'node:path';
|
|
17
|
+
import { fail, insideMountedPath, isInsideContainer, parseArgs, say, warn } from 'gcb-core';
|
|
16
18
|
import { USER_TOKEN_FILE, userTokenPath, loadConfig, resolveConfigPath } from '../config.js';
|
|
17
19
|
import { collectUserToken, startDeviceFlow } from '../device-flow.js';
|
|
18
20
|
import { fetcherFor, parseProxy } from '../http.js';
|
|
19
|
-
import { fail, insideMountedPath, isInsideContainer, parseArgs, say, writeSecretFile } from 'gcb-core';
|
|
20
21
|
/** Usage text for `authorize`. */
|
|
21
22
|
export const AUTHORIZE_USAGE = `Usage: gcb authorize [options]
|
|
22
23
|
|
|
@@ -24,12 +25,14 @@ Get a user token for this app, by authorizing it once from a browser somewhere e
|
|
|
24
25
|
beside the configuration. It stores a refresh token and prints where; nothing else needs running after
|
|
25
26
|
that, because the broker renews the token itself.
|
|
26
27
|
|
|
27
|
-
--config <path>
|
|
28
|
-
--host <host>
|
|
29
|
-
--to <path>
|
|
30
|
-
--
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
--config <path> The configuration (default: $GIT_BROKER_CONFIG, else ./broker.config.yml)
|
|
29
|
+
--host <host> The host block to authorize for (default: github.com)
|
|
30
|
+
--to <path> Where to write the refresh token (default: beside the configuration)
|
|
31
|
+
--broker-container Allow a target inside the broker container's mounts; only when it is not
|
|
32
|
+
shared with the agent container
|
|
33
|
+
--proxy <url> Use this proxy for this command
|
|
34
|
+
--no-proxy Reach GitHub directly for this command
|
|
35
|
+
-h, --help Show this help
|
|
33
36
|
|
|
34
37
|
The app needs its client id configured (the App ID will not do), and "Enable Device Flow" selected in
|
|
35
38
|
its settings. GitHub returns a refresh token only while "Expire user authorization tokens" is selected,
|
|
@@ -38,14 +41,14 @@ which is its default and what this wants.
|
|
|
38
41
|
/**
|
|
39
42
|
* Where this command writes the refresh token.
|
|
40
43
|
*
|
|
41
|
-
* Beside the configuration, because the configuration is the path this process was
|
|
42
|
-
* inside it belong to whichever process runs the broker, and for a sidecar those are
|
|
43
|
-
* that do not exist out here. In the usual sidecar layout the configuration and the
|
|
44
|
-
* directory, so this lands in the same file the broker reads; where they differ, the
|
|
45
|
-
* printed rather than discovered later.
|
|
44
|
+
* Beside the configuration, because the configuration is the path this process was _given_: the
|
|
45
|
+
* paths inside it belong to whichever process runs the broker, and for a sidecar those are
|
|
46
|
+
* container paths that do not exist out here. In the usual sidecar layout the configuration and the
|
|
47
|
+
* key sit in one directory, so this lands in the same file the broker reads; where they differ, the
|
|
48
|
+
* difference is printed rather than discovered later.
|
|
46
49
|
*
|
|
47
|
-
* @param configPath -
|
|
48
|
-
* @returns
|
|
50
|
+
* @param configPath - The resolved configuration path.
|
|
51
|
+
* @returns The path to write the refresh token to.
|
|
49
52
|
*/
|
|
50
53
|
export function refreshTokenPath(configPath) {
|
|
51
54
|
return join(dirname(resolvePath(configPath)), USER_TOKEN_FILE);
|
|
@@ -53,67 +56,157 @@ export function refreshTokenPath(configPath) {
|
|
|
53
56
|
/**
|
|
54
57
|
* Where the broker will look for it, which is beside the key — from the key's own point of view.
|
|
55
58
|
*
|
|
56
|
-
* @param privateKeyPath -
|
|
57
|
-
* @returns
|
|
59
|
+
* @param privateKeyPath - The path as the configuration records it.
|
|
60
|
+
* @returns The path the broker reads, or `undefined` when the key is not a file.
|
|
58
61
|
*/
|
|
59
62
|
export function brokerReadsPath(privateKeyPath) {
|
|
60
63
|
return privateKeyPath === undefined ? undefined : userTokenPath(privateKeyPath);
|
|
61
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Open and secure the token target before authorization, so a later path swap cannot redirect the
|
|
67
|
+
* write and a permission failure surfaces before the device flow.
|
|
68
|
+
*
|
|
69
|
+
* @param target - The token path.
|
|
70
|
+
* @returns The open descriptor, already mode 0600.
|
|
71
|
+
*/
|
|
72
|
+
export function openTokenTarget(target) {
|
|
73
|
+
mkdirSync(dirname(target), { recursive: true, mode: 0o700 });
|
|
74
|
+
const flags = constants.O_WRONLY | constants.O_CREAT | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0);
|
|
75
|
+
const fd = openSync(target, flags, 0o600);
|
|
76
|
+
try {
|
|
77
|
+
const info = fstatSync(fd);
|
|
78
|
+
if (!info.isFile()) {
|
|
79
|
+
throw new Error(`${target} is not a regular file`);
|
|
80
|
+
}
|
|
81
|
+
const uid = process.geteuid?.();
|
|
82
|
+
if (uid !== undefined && info.uid !== uid) {
|
|
83
|
+
throw new Error(`${target} is not owned by the current user`);
|
|
84
|
+
}
|
|
85
|
+
fchmodSync(fd, 0o600);
|
|
86
|
+
return fd;
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
closeSync(fd);
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/** Write the refresh token through the descriptor opened before the device flow. */
|
|
94
|
+
function writeToken(fd, token) {
|
|
95
|
+
ftruncateSync(fd, 0);
|
|
96
|
+
writeFileSync(fd, `${token}\n`);
|
|
97
|
+
// ACL-based shares can ignore the create/open mode; set it again after the write.
|
|
98
|
+
fchmodSync(fd, 0o600);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Decide where the refresh token goes, and whether that placement is allowed.
|
|
102
|
+
*
|
|
103
|
+
* @param input - The configuration path, target override and injectable guards.
|
|
104
|
+
* @returns The target and an optional warning.
|
|
105
|
+
* @throws {Error} When the placement would put the token inside a container mount without the
|
|
106
|
+
* explicit broker-container acknowledgement.
|
|
107
|
+
*/
|
|
108
|
+
export function resolveAuthorizationPlacement(input) {
|
|
109
|
+
const target = input.to ?? refreshTokenPath(input.configPath);
|
|
110
|
+
if ((input.isInsideContainer ?? isInsideContainer)()) {
|
|
111
|
+
throw new Error('run this on the host, not inside the container: the token must not land anywhere the container can read');
|
|
112
|
+
}
|
|
113
|
+
if (input.brokerContainer) {
|
|
114
|
+
return {
|
|
115
|
+
target,
|
|
116
|
+
warning: "writing inside the broker container's mounts; this is only safe when the target is not shared with the agent container",
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
const mounted = (input.mountedPath ?? insideMountedPath)(target);
|
|
120
|
+
if (mounted !== null) {
|
|
121
|
+
throw new Error(`${target} is inside ${mounted}, which is mounted into the container; the refresh token must live\n` +
|
|
122
|
+
' outside every mount — the deployment directory beside the configuration is the usual place');
|
|
123
|
+
}
|
|
124
|
+
return { target };
|
|
125
|
+
}
|
|
62
126
|
/**
|
|
63
127
|
* Run the `authorize` command.
|
|
64
128
|
*
|
|
65
|
-
* @param argv -
|
|
66
|
-
* @returns
|
|
129
|
+
* @param argv - Arguments after the command name.
|
|
130
|
+
* @returns The process exit code: 0 stored, 1 refused.
|
|
67
131
|
*/
|
|
68
132
|
import { assertProxyEnabled } from '../proxy.js';
|
|
69
133
|
export async function runAuthorize(argv) {
|
|
70
|
-
const args = parseArgs(argv, { booleans: ['help', 'no-proxy'] });
|
|
71
|
-
if (args.has('no-proxy') && args.value('proxy') !== undefined)
|
|
134
|
+
const args = parseArgs(argv, { booleans: ['broker-container', 'help', 'no-proxy'] });
|
|
135
|
+
if (args.has('no-proxy') && args.value('proxy') !== undefined) {
|
|
72
136
|
fail('--proxy and --no-proxy are mutually exclusive');
|
|
73
|
-
|
|
137
|
+
}
|
|
138
|
+
if (args.has('proxy') && args.value('proxy') === undefined) {
|
|
74
139
|
fail('--proxy needs a value');
|
|
140
|
+
}
|
|
75
141
|
const proxy = args.has('no-proxy') ? null : args.value('proxy');
|
|
76
|
-
if (proxy !== undefined && parseProxy(proxy) === false)
|
|
142
|
+
if (proxy !== undefined && parseProxy(proxy) === false) {
|
|
77
143
|
fail('--proxy must be an http(s) URL');
|
|
144
|
+
}
|
|
78
145
|
if (args.has('help') || args.has('h')) {
|
|
79
146
|
say(AUTHORIZE_USAGE);
|
|
80
147
|
return 0;
|
|
81
148
|
}
|
|
82
|
-
if (proxy === undefined)
|
|
149
|
+
if (proxy === undefined) {
|
|
83
150
|
assertProxyEnabled();
|
|
151
|
+
}
|
|
84
152
|
const configPath = resolveConfigPath(args.value('config'));
|
|
85
153
|
const host = args.value('host') ?? 'github.com';
|
|
86
154
|
const config = loadConfig(configPath);
|
|
87
155
|
const block = config.hosts[host];
|
|
88
|
-
if (block === undefined)
|
|
156
|
+
if (block === undefined) {
|
|
89
157
|
fail(`no host ${host} in ${configPath}`);
|
|
90
|
-
|
|
158
|
+
}
|
|
159
|
+
if (block.provider !== 'github-app') {
|
|
91
160
|
fail(`${host} is not a github-app host`);
|
|
161
|
+
}
|
|
92
162
|
if (block.clientId === undefined) {
|
|
93
163
|
fail(`${host} has no clientId — a device flow needs the app's client id, and the App ID will not do`);
|
|
94
164
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
165
|
+
let placement;
|
|
166
|
+
try {
|
|
167
|
+
placement = resolveAuthorizationPlacement({
|
|
168
|
+
configPath,
|
|
169
|
+
to: args.value('to'),
|
|
170
|
+
brokerContainer: args.has('broker-container'),
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
fail(error.message);
|
|
175
|
+
}
|
|
176
|
+
if (placement.warning !== undefined) {
|
|
177
|
+
warn(placement.warning);
|
|
178
|
+
}
|
|
179
|
+
say(`the refresh token will be written to ${placement.target}`);
|
|
180
|
+
let tokenFd;
|
|
181
|
+
try {
|
|
182
|
+
tokenFd = openTokenTarget(placement.target);
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
fail(`could not open ${placement.target}: ${error.message}`);
|
|
186
|
+
}
|
|
187
|
+
let failure;
|
|
188
|
+
try {
|
|
189
|
+
const fetcher = fetcherFor(proxy);
|
|
190
|
+
const code = await startDeviceFlow(block.clientId, fetcher);
|
|
191
|
+
say(`Open ${code.verificationUri} and enter: ${code.userCode}`);
|
|
192
|
+
say(`Waiting up to ${Math.round(code.expiresIn / 60)} minutes for that to be authorized…`);
|
|
193
|
+
const token = await collectUserToken(block.clientId, code, fetcher, ms => new Promise(done => setTimeout(done, ms)));
|
|
194
|
+
if (token.refreshToken === undefined) {
|
|
195
|
+
throw new Error('GitHub returned no refresh token, so the token would expire in eight hours with no way to renew.\n' +
|
|
196
|
+
' Select "Expire user authorization tokens" in the app settings and authorize again.');
|
|
197
|
+
}
|
|
198
|
+
writeToken(tokenFd, token.refreshToken);
|
|
114
199
|
}
|
|
115
|
-
|
|
116
|
-
|
|
200
|
+
catch (error) {
|
|
201
|
+
failure = error;
|
|
202
|
+
}
|
|
203
|
+
finally {
|
|
204
|
+
closeSync(tokenFd);
|
|
205
|
+
}
|
|
206
|
+
if (failure !== undefined) {
|
|
207
|
+
fail(failure.message);
|
|
208
|
+
}
|
|
209
|
+
say(`stored the refresh token in ${placement.target} (mode 600)`);
|
|
117
210
|
const readByBroker = brokerReadsPath(block.privateKeyPath);
|
|
118
211
|
if (readByBroker === undefined) {
|
|
119
212
|
// An inline privateKeyPem deployment: the broker has no directory to derive a path from, so it never
|
|
@@ -121,12 +214,12 @@ export async function runAuthorize(argv) {
|
|
|
121
214
|
say('note: this host block keeps its key inline, so the broker has nowhere to look for this file:');
|
|
122
215
|
say(' pull requests will stay app-authored until the key is a file (privateKeyPath)');
|
|
123
216
|
}
|
|
124
|
-
else if (resolvePath(readByBroker)
|
|
125
|
-
say(
|
|
126
|
-
say(' writable, because GitHub rotates the token on every exchange');
|
|
217
|
+
else if (resolvePath(readByBroker) === resolvePath(placement.target)) {
|
|
218
|
+
say('which is where the broker looks for it — keep it writable, since the token is rotated on every use');
|
|
127
219
|
}
|
|
128
220
|
else {
|
|
129
|
-
say(
|
|
221
|
+
say(`note: the broker will look in ${readByBroker} — make sure that is this file, and that it is`);
|
|
222
|
+
say(' writable, because GitHub rotates the token on every exchange');
|
|
130
223
|
}
|
|
131
224
|
say('the broker will use it for pull requests authored by that person; nothing else needs running');
|
|
132
225
|
return 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorize.js","sourceRoot":"","sources":["../../src/commands/authorize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;
|
|
1
|
+
{"version":3,"file":"authorize.js","sourceRoot":"","sources":["../../src/commands/authorize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,EACT,aAAa,EACb,SAAS,EACT,QAAQ,EACR,aAAa,GACd,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,WAAW,CAAA;AAEjE,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,UAAU,CAAA;AAE3F,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAC5F,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAgB,MAAM,mBAAmB,CAAA;AACnF,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEnD,kCAAkC;AAClC,MAAM,CAAC,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;CAkB9B,CAAA;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,UAAkB;IACjD,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,EAAE,eAAe,CAAC,CAAA;AAChE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,cAAkC;IAChE,OAAO,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,cAAc,CAAC,CAAA;AACjF,CAAC;AAiBD;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IAC5D,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC,OAAO,GAAG,CAAC,SAAS,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,IAAI,CAAC,CAAC,CAAA;IAChH,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;IACzC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,SAAS,CAAC,EAAE,CAAC,CAAA;QAC1B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,wBAAwB,CAAC,CAAA;QACpD,CAAC;QACD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,EAAE,EAAE,CAAA;QAC/B,IAAI,GAAG,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,mCAAmC,CAAC,CAAA;QAC/D,CAAC;QACD,UAAU,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;QACrB,OAAO,EAAE,CAAA;IACX,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,SAAS,CAAC,EAAE,CAAC,CAAA;QACb,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC;AAED,oFAAoF;AACpF,SAAS,UAAU,CAAC,EAAU,EAAE,KAAa;IAC3C,aAAa,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;IACpB,aAAa,CAAC,EAAE,EAAE,GAAG,KAAK,IAAI,CAAC,CAAA;IAC/B,kFAAkF;IAClF,UAAU,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;AACvB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,6BAA6B,CAC3C,KAAkC;IAElC,MAAM,MAAM,GAAG,KAAK,CAAC,EAAE,IAAI,gBAAgB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;IAC7D,IAAI,CAAC,KAAK,CAAC,iBAAiB,IAAI,iBAAiB,CAAC,EAAE,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CACb,yGAAyG,CAC1G,CAAA;IACH,CAAC;IACD,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC;QAC1B,OAAO;YACL,MAAM;YACN,OAAO,EACL,wHAAwH;SAC3H,CAAA;IACH,CAAC;IACD,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,WAAW,IAAI,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAA;IAChE,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,GAAG,MAAM,cAAc,OAAO,sEAAsE;YAClG,8FAA8F,CACjG,CAAA;IACH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,CAAA;AACnB,CAAC;AAED;;;;;GAKG;AACH,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAEhD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAuB;IACxD,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC,kBAAkB,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC,CAAA;IACpF,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,SAAS,EAAE,CAAC;QAC9D,IAAI,CAAC,+CAA+C,CAAC,CAAA;IACvD,CAAC;IACD,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,SAAS,EAAE,CAAC;QAC3D,IAAI,CAAC,uBAAuB,CAAC,CAAA;IAC/B,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAC/D,IAAI,KAAK,KAAK,SAAS,IAAI,UAAU,CAAC,KAAK,CAAC,KAAK,KAAK,EAAE,CAAC;QACvD,IAAI,CAAC,gCAAgC,CAAC,CAAA;IACxC,CAAC;IACD,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QACtC,GAAG,CAAC,eAAe,CAAC,CAAA;QACpB,OAAO,CAAC,CAAA;IACV,CAAC;IAED,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,kBAAkB,EAAE,CAAA;IACtB,CAAC;IACD,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC1D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,YAAY,CAAA;IAC/C,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,CAAA;IACrC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAChC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,IAAI,CAAC,WAAW,IAAI,OAAO,UAAU,EAAE,CAAC,CAAA;IAC1C,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;QACpC,IAAI,CAAC,GAAG,IAAI,2BAA2B,CAAC,CAAA;IAC1C,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACjC,IAAI,CACF,GAAG,IAAI,wFAAwF,CAChG,CAAA;IACH,CAAC;IAED,IAAI,SAAiC,CAAA;IACrC,IAAI,CAAC;QACH,SAAS,GAAG,6BAA6B,CAAC;YACxC,UAAU;YACV,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YACpB,eAAe,EAAE,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC;SAC9C,CAAC,CAAA;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAE,KAAe,CAAC,OAAO,CAAC,CAAA;IAChC,CAAC;IACD,IAAI,SAAS,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACpC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;IACzB,CAAC;IACD,GAAG,CAAC,wCAAwC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAA;IAE/D,IAAI,OAAe,CAAA;IACnB,IAAI,CAAC;QACH,OAAO,GAAG,eAAe,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;IAC7C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,kBAAkB,SAAS,CAAC,MAAM,KAAM,KAAe,CAAC,OAAO,EAAE,CAAC,CAAA;IACzE,CAAC;IACD,IAAI,OAA0B,CAAA;IAC9B,IAAI,CAAC;QACH,MAAM,OAAO,GAAY,UAAU,CAAC,KAAK,CAAC,CAAA;QAC1C,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QAC3D,GAAG,CAAC,QAAQ,IAAI,CAAC,eAAe,eAAe,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAA;QAC/D,GAAG,CAAC,iBAAiB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC,qCAAqC,CAAC,CAAA;QAE1F,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAClC,KAAK,CAAC,QAAQ,EACd,IAAI,EACJ,OAAO,EACP,EAAE,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAChD,CAAA;QACD,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CACb,oGAAoG;gBAClG,sFAAsF,CACzF,CAAA;QACH,CAAC;QACD,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,YAAY,CAAC,CAAA;IACzC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,GAAG,KAAc,CAAA;IAC1B,CAAC;YAAS,CAAC;QACT,SAAS,CAAC,OAAO,CAAC,CAAA;IACpB,CAAC;IACD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IACvB,CAAC;IACD,GAAG,CAAC,+BAA+B,SAAS,CAAC,MAAM,aAAa,CAAC,CAAA;IACjE,MAAM,YAAY,GAAG,eAAe,CAAC,KAAK,CAAC,cAAc,CAAC,CAAA;IAC1D,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QAC/B,qGAAqG;QACrG,qFAAqF;QACrF,GAAG,CACD,8FAA8F,CAC/F,CAAA;QACD,GAAG,CAAC,qFAAqF,CAAC,CAAA;IAC5F,CAAC;SAAM,IAAI,WAAW,CAAC,YAAY,CAAC,KAAK,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;QACvE,GAAG,CACD,oGAAoG,CACrG,CAAA;IACH,CAAC;SAAM,CAAC;QACN,GAAG,CACD,iCAAiC,YAAY,gDAAgD,CAC9F,CAAA;QACD,GAAG,CAAC,oEAAoE,CAAC,CAAA;IAC3E,CAAC;IACD,GAAG,CACD,8FAA8F,CAC/F,CAAA;IACD,OAAO,CAAC,CAAA;AACV,CAAC"}
|
|
@@ -10,14 +10,14 @@ export interface ComposeInput {
|
|
|
10
10
|
readonly user: string;
|
|
11
11
|
/** Base image. */
|
|
12
12
|
readonly image: string;
|
|
13
|
-
/**
|
|
13
|
+
/** Npm spec to run, e.g. `gcb@0.0.0`. */
|
|
14
14
|
readonly packageSpec: string;
|
|
15
15
|
/** Compose service and container name. */
|
|
16
16
|
readonly name: string;
|
|
17
17
|
/**
|
|
18
18
|
* Host directory holding the broker's code, as `stage` exports it. When given, the sidecar runs
|
|
19
|
-
* that code with the image's Node instead of fetching the package at start: no registry access
|
|
20
|
-
*
|
|
19
|
+
* that code with the image's Node instead of fetching the package at start: no registry access at
|
|
20
|
+
* boot, and the commit that runs is the one you reviewed.
|
|
21
21
|
*/
|
|
22
22
|
readonly code?: string;
|
|
23
23
|
}
|
|
@@ -26,8 +26,8 @@ export declare const CODE_DIR = "/opt/gcb";
|
|
|
26
26
|
/**
|
|
27
27
|
* Render the compose file.
|
|
28
28
|
*
|
|
29
|
-
* @param input -
|
|
30
|
-
* @returns
|
|
29
|
+
* @param input - The resolved options.
|
|
30
|
+
* @returns The YAML, newline-terminated.
|
|
31
31
|
*/
|
|
32
32
|
export declare function renderCompose(input: ComposeInput): string;
|
|
33
33
|
/** Usage text for `compose`. */
|
|
@@ -35,8 +35,8 @@ export declare const COMPOSE_USAGE = "Usage: gcb compose [options]\n\nPrint a Do
|
|
|
35
35
|
/**
|
|
36
36
|
* Run the `compose` command.
|
|
37
37
|
*
|
|
38
|
-
* @param argv -
|
|
39
|
-
* @returns
|
|
38
|
+
* @param argv - Arguments after the command name.
|
|
39
|
+
* @returns The process exit code.
|
|
40
40
|
*/
|
|
41
41
|
export declare function runCompose(argv: readonly string[]): number;
|
|
42
42
|
//# sourceMappingURL=compose.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../../src/commands/compose.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../../src/commands/compose.ts"],"names":[],"mappings":"AAyBA,4CAA4C;AAC5C,MAAM,WAAW,YAAY;IAC3B,kEAAkE;IAClE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,uEAAuE;IACvE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,yFAAyF;IACzF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,qFAAqF;IACrF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,kBAAkB;IAClB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,yCAAyC;IACzC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,0CAA0C;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,uDAAuD;AACvD,eAAO,MAAM,QAAQ,aAAa,CAAA;AAsBlC;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CA8HzD;AAED,gCAAgC;AAChC,eAAO,MAAM,aAAa,kgCAgBzB,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CA2D1D"}
|
package/lib/commands/compose.js
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `compose` — print a Docker sidecar definition for the broker.
|
|
3
3
|
*
|
|
4
|
-
* The broker runs in its own container with the private key mounted read-only, no published
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* The broker runs in its own container with the private key mounted read-only, no published ports,
|
|
5
|
+
* no capabilities and a read-only root filesystem; the only surface it shares with anything else is
|
|
6
|
+
* the socket directory. The container fetches the published package, so there is no checkout to
|
|
7
|
+
* copy and nothing to build on the host.
|
|
8
8
|
*
|
|
9
|
-
* The mount targets are constants from `deployment.ts`, shared with `init --mode sidecar`, so
|
|
10
|
-
*
|
|
9
|
+
* The mount targets are constants from `deployment.ts`, shared with `init --mode sidecar`, so the
|
|
10
|
+
* paths recorded in `broker.config.yml` and the paths this file mounts cannot drift apart.
|
|
11
11
|
*/
|
|
12
12
|
import fs from 'node:fs';
|
|
13
13
|
import path from 'node:path';
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import { fail, parseArgs, say, warn } from 'gcb-core';
|
|
17
|
-
import { USER_TOKEN_FILE } from '../config.js';
|
|
14
|
+
import { PACKAGE_VERSION, fail, parseArgs, say, warn } from 'gcb-core';
|
|
15
|
+
import { inferMode, loadConfig, resolveConfigPath, deploymentDir, SIDECAR, USER_TOKEN_FILE, } from '../config.js';
|
|
18
16
|
/** Where a code-mounted sidecar expects the broker. */
|
|
19
17
|
export const CODE_DIR = '/opt/gcb';
|
|
20
18
|
/** A volume scalar as YAML, with compose's dollar escaping applied first. */
|
|
@@ -30,16 +28,17 @@ function selectedConfigFile(configPath) {
|
|
|
30
28
|
return fs.realpathSync(configPath);
|
|
31
29
|
}
|
|
32
30
|
catch (error) {
|
|
33
|
-
if (error.code === 'ENOENT')
|
|
31
|
+
if (error.code === 'ENOENT') {
|
|
34
32
|
return configPath;
|
|
33
|
+
}
|
|
35
34
|
throw error;
|
|
36
35
|
}
|
|
37
36
|
}
|
|
38
37
|
/**
|
|
39
38
|
* Render the compose file.
|
|
40
39
|
*
|
|
41
|
-
* @param input -
|
|
42
|
-
* @returns
|
|
40
|
+
* @param input - The resolved options.
|
|
41
|
+
* @returns The YAML, newline-terminated.
|
|
43
42
|
*/
|
|
44
43
|
export function renderCompose(input) {
|
|
45
44
|
const socketDir = input.socketDir.replace(/\/+$/, '');
|
|
@@ -93,10 +92,10 @@ export function renderCompose(input) {
|
|
|
93
92
|
const command = ` - sh
|
|
94
93
|
- -c
|
|
95
94
|
- |
|
|
96
|
-
case "
|
|
95
|
+
case "$\${GCB_PROXY-default}" in
|
|
97
96
|
default) ;;
|
|
98
97
|
"") unset http_proxy https_proxy all_proxy no_proxy HTTP_PROXY HTTPS_PROXY ALL_PROXY NO_PROXY NODE_USE_ENV_PROXY ;;
|
|
99
|
-
*) export http_proxy="
|
|
98
|
+
*) export http_proxy="$$GCB_PROXY" https_proxy="$$GCB_PROXY" no_proxy=localhost,127.0.0.1 NODE_USE_ENV_PROXY=1 ;;
|
|
100
99
|
esac
|
|
101
100
|
${start}`;
|
|
102
101
|
const codeMount = fromCode
|
|
@@ -177,8 +176,8 @@ Print a Docker sidecar definition for the broker (to stdout). Pair it with a con
|
|
|
177
176
|
/**
|
|
178
177
|
* Run the `compose` command.
|
|
179
178
|
*
|
|
180
|
-
* @param argv -
|
|
181
|
-
* @returns
|
|
179
|
+
* @param argv - Arguments after the command name.
|
|
180
|
+
* @returns The process exit code.
|
|
182
181
|
*/
|
|
183
182
|
export function runCompose(argv) {
|
|
184
183
|
const args = parseArgs(argv, { booleans: ['help'] });
|
|
@@ -188,11 +187,11 @@ export function runCompose(argv) {
|
|
|
188
187
|
}
|
|
189
188
|
const explicitConfig = args.value('config');
|
|
190
189
|
const dirArg = args.value('dir');
|
|
191
|
-
const configPath = path.resolve(explicitConfig
|
|
192
|
-
?
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
190
|
+
const configPath = path.resolve(explicitConfig === undefined
|
|
191
|
+
? dirArg === undefined
|
|
192
|
+
? resolveConfigPath()
|
|
193
|
+
: path.join(dirArg, 'broker.config.yml')
|
|
194
|
+
: resolveConfigPath(explicitConfig));
|
|
196
195
|
const configFile = selectedConfigFile(configPath);
|
|
197
196
|
const dir = path.resolve(dirArg ?? deploymentDir(configFile));
|
|
198
197
|
const socketDir = args.value('socket-dir');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compose.js","sourceRoot":"","sources":["../../src/commands/compose.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"compose.js","sourceRoot":"","sources":["../../src/commands/compose.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AA6BA,eAAO,MAAM,YAAY,6nBAUxB,CAAA;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAuEzD"}
|