@appforge-ci/admin-cli 0.3.13 → 0.3.15
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/dist/commands/agents.d.ts +10 -0
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +109 -13
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/agents.test.js +41 -1
- package/dist/commands/agents.test.js.map +1 -1
- package/dist/lib/bootstrap.d.ts.map +1 -1
- package/dist/lib/bootstrap.js +16 -4
- package/dist/lib/bootstrap.js.map +1 -1
- package/dist/lib/runner-user.d.ts +7 -0
- package/dist/lib/runner-user.d.ts.map +1 -1
- package/dist/lib/runner-user.js +18 -8
- package/dist/lib/runner-user.js.map +1 -1
- package/dist/lib/vm-user-apply.d.ts +77 -0
- package/dist/lib/vm-user-apply.d.ts.map +1 -0
- package/dist/lib/vm-user-apply.js +286 -0
- package/dist/lib/vm-user-apply.js.map +1 -0
- package/dist/lib/vm-user-apply.test.d.ts +2 -0
- package/dist/lib/vm-user-apply.test.d.ts.map +1 -0
- package/dist/lib/vm-user-apply.test.js +272 -0
- package/dist/lib/vm-user-apply.test.js.map +1 -0
- package/dist/lib/vm-user.d.ts +35 -0
- package/dist/lib/vm-user.d.ts.map +1 -0
- package/dist/lib/vm-user.js +99 -0
- package/dist/lib/vm-user.js.map +1 -0
- package/dist/lib/vm-user.test.d.ts +2 -0
- package/dist/lib/vm-user.test.d.ts.map +1 -0
- package/dist/lib/vm-user.test.js +75 -0
- package/dist/lib/vm-user.test.js.map +1 -0
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner-user.d.ts","sourceRoot":"","sources":["../../src/lib/runner-user.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,eAAO,MAAM,mBAAmB,cAAc,CAAC;AAC/C;qFACqF;AACrF,eAAO,MAAM,sBAAsB,YAAY,CAAC;AAEhD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,KAAK,GAAG,MAAM,CAEhF;AAED;;uFAEuF;AACvF,wBAAgB,UAAU,CAAC,QAAQ,GAAE,MAAqB,GAAG,OAAO,GAAG,KAAK,CAE3E;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC;0GACsG;IACtG,YAAY,IAAI,MAAM,CAAC;IACvB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACvC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAC7C,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9B,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,yBAAyB,EAAE,
|
|
1
|
+
{"version":3,"file":"runner-user.d.ts","sourceRoot":"","sources":["../../src/lib/runner-user.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,eAAO,MAAM,mBAAmB,cAAc,CAAC;AAC/C;qFACqF;AACrF,eAAO,MAAM,sBAAsB,YAAY,CAAC;AAEhD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,KAAK,GAAG,MAAM,CAEhF;AAED;;uFAEuF;AACvF,wBAAgB,UAAU,CAAC,QAAQ,GAAE,MAAqB,GAAG,OAAO,GAAG,KAAK,CAE3E;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC;0GACsG;IACtG,YAAY,IAAI,MAAM,CAAC;IACvB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACvC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAC7C,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9B,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,yBAAyB,EAAE,qBAoCvC,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8FAA8F;IAC9F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG;IAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CASjE;AAED;;;qCAGqC;AACrC,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAOnD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,qBAAiD,GACtD,MAAM,CAuBR;AAED,0GAA0G;AAC1G,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,qBAAiD,GAAG,MAAM,CAO9G;AAED;sEACsE;AACtE,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,qBAAiD,GAAG,MAAM,CAgBnJ;AAED,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,wBAA6B,EAAE,IAAI,GAAE,qBAAiD,GAAG,IAAI,CA0BpI"}
|
package/dist/lib/runner-user.js
CHANGED
|
@@ -73,11 +73,13 @@ export const realInstallRunnerUserDeps = {
|
|
|
73
73
|
run(cmd, args) {
|
|
74
74
|
// eslint-disable-next-line no-console
|
|
75
75
|
console.log(` $ ${cmd} ${args.join(" ")}`);
|
|
76
|
-
|
|
76
|
+
// cwd "/": a helper that drops to another account (createhomedir -u) must not inherit the operator's own,
|
|
77
|
+
// unreadable-to-others, working directory (it printed "getcwd: cannot access parent directories").
|
|
78
|
+
execFileSync(cmd, args, { stdio: "inherit", cwd: "/" });
|
|
77
79
|
},
|
|
78
80
|
tryRun(cmd, args) {
|
|
79
81
|
try {
|
|
80
|
-
execFileSync(cmd, args, { stdio: "ignore" });
|
|
82
|
+
execFileSync(cmd, args, { stdio: "ignore", cwd: "/" });
|
|
81
83
|
return true;
|
|
82
84
|
}
|
|
83
85
|
catch {
|
|
@@ -118,32 +120,40 @@ export function nextFreeUid(listing) {
|
|
|
118
120
|
}
|
|
119
121
|
return max + 1;
|
|
120
122
|
}
|
|
121
|
-
/**
|
|
122
|
-
|
|
123
|
+
/**
|
|
124
|
+
* Creates a plain, ordinary (not hidden, not admin) account with its own home directory, or leaves it alone if it
|
|
125
|
+
* already exists. Shared by `install-runner-user` and `install-vm-user`. The account is created WITHOUT a password
|
|
126
|
+
* (it cannot authenticate until the operator sets one) and is deliberately not hidden: both callers need a real
|
|
127
|
+
* login session for GUI frameworks. Returns its home directory.
|
|
128
|
+
*/
|
|
129
|
+
export function ensureOrdinaryUser(user, realName, banner, deps = realInstallRunnerUserDeps) {
|
|
123
130
|
const home = `/Users/${user}`;
|
|
124
131
|
if (deps.userExists(user)) {
|
|
125
132
|
deps.log(` user '${user}' already exists, leaving it alone`);
|
|
126
133
|
return home;
|
|
127
134
|
}
|
|
128
|
-
deps.log(`\n==>
|
|
135
|
+
deps.log(`\n==> ${banner}`);
|
|
129
136
|
const uid = nextFreeUid(deps.listUserUids());
|
|
130
137
|
const gid = uid;
|
|
131
138
|
deps.run("sudo", ["dscl", ".", "-create", `/Groups/${user}`]);
|
|
132
139
|
deps.run("sudo", ["dscl", ".", "-create", `/Groups/${user}`, "PrimaryGroupID", String(gid)]);
|
|
133
140
|
deps.run("sudo", ["dscl", ".", "-create", `/Users/${user}`]);
|
|
134
141
|
deps.run("sudo", ["dscl", ".", "-create", `/Users/${user}`, "UserShell", "/bin/zsh"]);
|
|
135
|
-
deps.run("sudo", ["dscl", ".", "-create", `/Users/${user}`, "RealName",
|
|
142
|
+
deps.run("sudo", ["dscl", ".", "-create", `/Users/${user}`, "RealName", realName]);
|
|
136
143
|
deps.run("sudo", ["dscl", ".", "-create", `/Users/${user}`, "UniqueID", String(uid)]);
|
|
137
144
|
deps.run("sudo", ["dscl", ".", "-create", `/Users/${user}`, "PrimaryGroupID", String(gid)]);
|
|
138
145
|
deps.run("sudo", ["dscl", ".", "-create", `/Users/${user}`, "NFSHomeDirectory", home]);
|
|
139
146
|
// No -create .../Password at all: an account with no AuthenticationAuthority entry cannot authenticate by
|
|
140
147
|
// password until one is set. `createhomedir` below needs no password to run (root does it on the
|
|
141
|
-
// account's behalf). Deliberately NOT marking IsHidden
|
|
142
|
-
// ordinary account, not a service account.
|
|
148
|
+
// account's behalf). Deliberately NOT marking IsHidden, see the docblock above.
|
|
143
149
|
deps.run("sudo", ["createhomedir", "-c", "-u", user]);
|
|
144
150
|
deps.log(` created ${home} (uid ${uid})`);
|
|
145
151
|
return home;
|
|
146
152
|
}
|
|
153
|
+
/** Creates the dedicated account, or leaves it alone if it already exists. Returns its home directory. */
|
|
154
|
+
export function ensureRunnerUser(user, deps = realInstallRunnerUserDeps) {
|
|
155
|
+
return ensureOrdinaryUser(user, "AppForge CI runner (dedicated)", `Creating the dedicated '${user}' account (so this Mac's CI runner no longer shares a uid with the build agent)`, deps);
|
|
156
|
+
}
|
|
147
157
|
/** Downloads and extracts the runner release into `<home>/actions-runner`, owned by `user`. A no-op (besides
|
|
148
158
|
* logging) if that directory already looks like a runner install. */
|
|
149
159
|
export function ensureRunnerDownloaded(user, home, version, deps = realInstallRunnerUserDeps) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner-user.js","sourceRoot":"","sources":["../../src/lib/runner-user.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,2GAA2G;AAC3G,uGAAuG;AACvG,yGAAyG;AACzG,4BAA4B;AAE5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,WAAW,CAAC;AAC/C;qFACqF;AACrF,MAAM,CAAC,MAAM,sBAAsB,GAAG,SAAS,CAAC;AAEhD,MAAM,UAAU,iBAAiB,CAAC,OAAe,EAAE,IAAqB;IACtE,OAAO,wDAAwD,OAAO,uBAAuB,IAAI,IAAI,OAAO,SAAS,CAAC;AACxH,CAAC;AAED;;uFAEuF;AACvF,MAAM,UAAU,UAAU,CAAC,WAAmB,OAAO,CAAC,IAAI;IACxD,OAAO,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;AAChD,CAAC;AAeD,MAAM,CAAC,MAAM,yBAAyB,GAA0B;IAC9D,UAAU,CAAC,IAAI;QACb,IAAI,CAAC;YACH,YAAY,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,UAAU,IAAI,EAAE,EAAE,UAAU,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YACxF,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,YAAY;QACV,IAAI,CAAC;YACH,OAAO,YAAY,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QAC1F,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IACD,GAAG,CAAC,GAAG,EAAE,IAAI;QACX,sCAAsC;QACtC,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5C,YAAY,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"runner-user.js","sourceRoot":"","sources":["../../src/lib/runner-user.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,2GAA2G;AAC3G,uGAAuG;AACvG,yGAAyG;AACzG,4BAA4B;AAE5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,WAAW,CAAC;AAC/C;qFACqF;AACrF,MAAM,CAAC,MAAM,sBAAsB,GAAG,SAAS,CAAC;AAEhD,MAAM,UAAU,iBAAiB,CAAC,OAAe,EAAE,IAAqB;IACtE,OAAO,wDAAwD,OAAO,uBAAuB,IAAI,IAAI,OAAO,SAAS,CAAC;AACxH,CAAC;AAED;;uFAEuF;AACvF,MAAM,UAAU,UAAU,CAAC,WAAmB,OAAO,CAAC,IAAI;IACxD,OAAO,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;AAChD,CAAC;AAeD,MAAM,CAAC,MAAM,yBAAyB,GAA0B;IAC9D,UAAU,CAAC,IAAI;QACb,IAAI,CAAC;YACH,YAAY,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,UAAU,IAAI,EAAE,EAAE,UAAU,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YACxF,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,YAAY;QACV,IAAI,CAAC;YACH,OAAO,YAAY,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QAC1F,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IACD,GAAG,CAAC,GAAG,EAAE,IAAI;QACX,sCAAsC;QACtC,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5C,0GAA0G;QAC1G,mGAAmG;QACnG,YAAY,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IAC1D,CAAC;IACD,MAAM,CAAC,GAAG,EAAE,IAAI;QACd,IAAI,CAAC;YACH,YAAY,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;YACvD,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;IAClC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IACtD,sCAAsC;IACtC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,IAAI,EAAE,UAAU,EAAE;CACnB,CAAC;AAYF;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAMpC;IACC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACrC,OAAO;QACL,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC;QACtI,uGAAuG;QACvG,gGAAgG;QAChG,UAAU,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC;QACvC,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC;KACzB,CAAC;AACJ,CAAC;AAED;;;qCAGqC;AACrC,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,IAAI,GAAG,GAAG,GAAG,CAAC;IACd,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC;YAAE,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,GAAG,GAAG,CAAC,CAAC;AACjB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAAY,EACZ,QAAgB,EAChB,MAAc,EACd,OAA8B,yBAAyB;IAEvD,MAAM,IAAI,GAAG,UAAU,IAAI,EAAE,CAAC;IAC9B,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,IAAI,CAAC,GAAG,CAAC,WAAW,IAAI,oCAAoC,CAAC,CAAC;QAC9D,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;IAC5B,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;IAC7C,MAAM,GAAG,GAAG,GAAG,CAAC;IAChB,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,WAAW,IAAI,EAAE,CAAC,CAAC,CAAC;IAC9D,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,WAAW,IAAI,EAAE,EAAE,gBAAgB,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7F,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC;IAC7D,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,IAAI,EAAE,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;IACtF,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,IAAI,EAAE,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;IACnF,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,IAAI,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACtF,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,IAAI,EAAE,EAAE,gBAAgB,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC5F,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,IAAI,EAAE,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAC,CAAC;IACvF,0GAA0G;IAC1G,iGAAiG;IACjG,gFAAgF;IAChF,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IACtD,IAAI,CAAC,GAAG,CAAC,aAAa,IAAI,SAAS,GAAG,GAAG,CAAC,CAAC;IAC3C,OAAO,IAAI,CAAC;AACd,CAAC;AAED,0GAA0G;AAC1G,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,OAA8B,yBAAyB;IACpG,OAAO,kBAAkB,CACvB,IAAI,EACJ,gCAAgC,EAChC,2BAA2B,IAAI,iFAAiF,EAChH,IAAI,CACL,CAAC;AACJ,CAAC;AAED;sEACsE;AACtE,MAAM,UAAU,sBAAsB,CAAC,IAAY,EAAE,IAAY,EAAE,OAAe,EAAE,OAA8B,yBAAyB;IACzI,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;IACzC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC;QACxC,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,iDAAiD,CAAC,CAAC;QACpE,OAAO,GAAG,CAAC;IACb,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,gDAAgD,OAAO,KAAK,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;IACnF,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjB,MAAM,GAAG,GAAG,iBAAiB,CAAC,OAAO,EAAE,IAAI,CAAC,IAAuB,CAAC,CAAC;IACrE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,uBAAuB,CAAC,CAAC;IACnD,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;IAChD,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;IAC9C,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAC1B,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,IAAI,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC;IAC1D,IAAI,CAAC,GAAG,CAAC,kBAAkB,GAAG,EAAE,CAAC,CAAC;IAClC,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,OAAiC,EAAE,EAAE,OAA8B,yBAAyB;IAC5H,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,mBAAmB,CAAC;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,sBAAsB,CAAC;IACvD,MAAM,IAAI,GAAG,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAG,sBAAsB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAE9D,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,UAAU,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IAC3I,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACvC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,oBAAoB,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,CAAC,CAAC;QACnJ,IAAI,CAAC,GAAG,CAAC,gDAAgD,UAAU,GAAG,CAAC,CAAC;QACxE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC;QAChD,IAAI,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;QAC7D,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAC7B,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC3B,IAAI,CAAC,GAAG,CAAC,YAAY,IAAI,sGAAsG,CAAC,CAAC;IACnI,CAAC;SAAM,CAAC;QACN,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,oBAAoB,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC;QACrI,IAAI,CAAC,GAAG,CACN,0HAA0H;YACxH,2HAA2H;YAC3H,sDAAsD,IAAI,aAAa;YACvE,aAAa,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI;YAC5C,UAAU,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI;YAClC,UAAU,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CACnC,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { type InstallVmUserDeps } from "./vm-user.js";
|
|
2
|
+
/**
|
|
3
|
+
* `install-vm-user --apply`: the helper-account layout (appforge-ci#812, option C) as ONE idempotent, non-interactive command,
|
|
4
|
+
* for a fleet (appforge-ci#836). Run as root over SSH or from an MDM script; `--dry-run` prints every step and changes nothing.
|
|
5
|
+
*
|
|
6
|
+
* What it does, each step skipped when it is already true:
|
|
7
|
+
* 1. creates the helper account (an ordinary account, as install-vm-user always did);
|
|
8
|
+
* 2. when it created the account (or `--reset-password` was given): sets a random password, makes the account the
|
|
9
|
+
* auto-login account (`sysadminctl -autologin set`, falling back to writing /etc/kcpassword), and reads the setting back.
|
|
10
|
+
* The password is generated here, used once for this and never printed or stored anywhere else. An existing
|
|
11
|
+
* account's password is NEVER reset without `--reset-password`;
|
|
12
|
+
* 3. makes the shared folder both accounts use (owner = the agent's account, group = the helper, mode 770);
|
|
13
|
+
* 4. adds the knobs to the agent's LaunchDaemon plist (APPFORGE_STATUS_MIRROR_DIR, APPFORGE_VM_INVENTORY_FILE, and
|
|
14
|
+
* APPFORGE_VM_TOOLING_DIR, which makes the agent deliver the signed VM tooling bundle into the shared folder) and
|
|
15
|
+
* reloads the agent's LaunchDaemon. (install-service would drop knobs that its shell does not export, and it has to run as the agent's
|
|
16
|
+
* own account with that account's sudo, which a root-run MDM script does not have; editing the one plist is the
|
|
17
|
+
* idempotent equivalent. install-service refuses to drop these knobs later unless told to.)
|
|
18
|
+
*
|
|
19
|
+
* Refuses (changing nothing) on a laptop, with FileVault on, when not root, when the agent's account is unknown, when the
|
|
20
|
+
* agent is not a boot-time LaunchDaemon, and when a GitHub Actions runner is a LaunchAgent of another account: the auto-login
|
|
21
|
+
* switch would leave it waiting for a manual login after every reboot (#780).
|
|
22
|
+
*
|
|
23
|
+
* 5. installs the helper's reconcile LaunchAgent (~/Library/LaunchAgents/com.appforge.vm-reconcile.plist, owned by the helper, so
|
|
24
|
+
* it loads at the helper's own login): it runs `reconcile-bundle.sh` from the tooling bundle the agent delivers into the shared
|
|
25
|
+
* folder (`<folder>/vm-tooling/current`, appforge-ci#836 B2) every 300 s, with the host name derived from the computer name,
|
|
26
|
+
* the agent's status and the inventory mirror wired to the shared folder, and the agent's own node. No git, no credential. It
|
|
27
|
+
* exits quietly until the first bundle has been delivered.
|
|
28
|
+
* The host files ship with `spec.enabled: false` unless a release enables them, so a Mac that is fully set up still applies
|
|
29
|
+
* nothing until its host file opts in.
|
|
30
|
+
*/
|
|
31
|
+
export declare const AGENT_DAEMON_PLIST = "/Library/LaunchDaemons/com.appforge.agent.plist";
|
|
32
|
+
export declare const LOGINWINDOW_PREFS = "/Library/Preferences/com.apple.loginwindow";
|
|
33
|
+
export declare const KCPASSWORD_PATH = "/etc/kcpassword";
|
|
34
|
+
export interface ApplyVmUserDeps extends InstallVmUserDeps {
|
|
35
|
+
euid(): number;
|
|
36
|
+
/** The account that ran sudo, or null (an MDM script runs as plain root). */
|
|
37
|
+
sudoUser(): string | null;
|
|
38
|
+
readText(path: string): string | null;
|
|
39
|
+
listDir(path: string): string[] | null;
|
|
40
|
+
randomPassword(): string;
|
|
41
|
+
/** Like `run`, but never echoes the arguments (they hold a secret); `label` is what gets logged. */
|
|
42
|
+
runSecret(cmd: string, args: string[], label: string): void;
|
|
43
|
+
/** Writes a root-only file. */
|
|
44
|
+
writeSecretFile(path: string, data: Buffer): void;
|
|
45
|
+
/** Writes a text file (mode 0644) and gives it to `owner:group`. */
|
|
46
|
+
writeOwnedText(path: string, text: string, owner: string, group: string): void;
|
|
47
|
+
}
|
|
48
|
+
export declare const realApplyVmUserDeps: ApplyVmUserDeps;
|
|
49
|
+
export declare const HELPER_AGENT_LABEL = "com.appforge.vm-reconcile";
|
|
50
|
+
export interface HelperAgentPlistOptions {
|
|
51
|
+
shareDir: string;
|
|
52
|
+
/** The node the agent runs with (absolute). */
|
|
53
|
+
nodePath: string;
|
|
54
|
+
/** The helper account's home directory. */
|
|
55
|
+
home: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The helper's reconcile LaunchAgent. Runs `reconcile-bundle.sh` from the delivered bundle's `current` folder with the host name
|
|
59
|
+
* derived on the Mac (`auto`). The `[ -f ]` guard makes it a quiet no-op until the agent has delivered the first bundle.
|
|
60
|
+
*/
|
|
61
|
+
export declare function helperAgentPlist(o: HelperAgentPlistOptions): string;
|
|
62
|
+
/** The /etc/kcpassword encoding of an auto-login password: XOR with the fixed key, zero-padded to a multiple of 12. */
|
|
63
|
+
export declare function kcpasswordBytes(password: string): Buffer;
|
|
64
|
+
/** Accounts whose GitHub Actions runner is a LaunchAgent (found through each runner dir's `.service` file, as the doctor does). */
|
|
65
|
+
export declare function runnerLaunchAgentAccounts(deps: Pick<ApplyVmUserDeps, "listDir" | "readText">): string[];
|
|
66
|
+
export interface ApplyVmUserOptions {
|
|
67
|
+
user: string;
|
|
68
|
+
agentUser?: string;
|
|
69
|
+
dryRun?: boolean;
|
|
70
|
+
/** Set a new random password and make an EXISTING account the auto-login account. */
|
|
71
|
+
resetPassword?: boolean;
|
|
72
|
+
shareDir?: string;
|
|
73
|
+
}
|
|
74
|
+
/** The reasons --apply refuses; empty means go ahead. */
|
|
75
|
+
export declare function applyRefusals(opts: ApplyVmUserOptions, deps: ApplyVmUserDeps): string[];
|
|
76
|
+
export declare function applyVmUser(opts: ApplyVmUserOptions, deps?: ApplyVmUserDeps): void;
|
|
77
|
+
//# sourceMappingURL=vm-user-apply.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vm-user-apply.d.ts","sourceRoot":"","sources":["../../src/lib/vm-user-apply.ts"],"names":[],"mappings":"AAIA,OAAO,EAA2D,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAG/G;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,eAAO,MAAM,kBAAkB,oDAAoD,CAAC;AACpF,eAAO,MAAM,iBAAiB,+CAA+C,CAAC;AAC9E,eAAO,MAAM,eAAe,oBAAoB,CAAC;AAEjD,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD,IAAI,IAAI,MAAM,CAAC;IACf,6EAA6E;IAC7E,QAAQ,IAAI,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACtC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;IACvC,cAAc,IAAI,MAAM,CAAC;IACzB,oGAAoG;IACpG,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5D,+BAA+B;IAC/B,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAClD,oEAAoE;IACpE,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAChF;AAED,eAAO,MAAM,mBAAmB,EAAE,eAmCjC,CAAC;AAGF,eAAO,MAAM,kBAAkB,8BAA8B,CAAC;AAM9D,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,uBAAuB,GAAG,MAAM,CA2CnE;AAID,uHAAuH;AACvH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAKxD;AAED,mIAAmI;AACnI,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,GAAG,UAAU,CAAC,GAAG,MAAM,EAAE,CAYvG;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qFAAqF;IACrF,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,yDAAyD;AACzD,wBAAgB,aAAa,CAAC,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,eAAe,GAAG,MAAM,EAAE,CAgBvF;AASD,wBAAgB,WAAW,CAAC,IAAI,EAAE,kBAAkB,EAAE,IAAI,GAAE,eAAqC,GAAG,IAAI,CA8GvG"}
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import { randomBytes } from "node:crypto";
|
|
3
|
+
import { readFileSync, readdirSync, writeFileSync, chmodSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { STATUS_SHARE_DIR, realInstallVmUserDeps, vmUserRefusals } from "./vm-user.js";
|
|
6
|
+
import { ensureOrdinaryUser } from "./runner-user.js";
|
|
7
|
+
/**
|
|
8
|
+
* `install-vm-user --apply`: the helper-account layout (appforge-ci#812, option C) as ONE idempotent, non-interactive command,
|
|
9
|
+
* for a fleet (appforge-ci#836). Run as root over SSH or from an MDM script; `--dry-run` prints every step and changes nothing.
|
|
10
|
+
*
|
|
11
|
+
* What it does, each step skipped when it is already true:
|
|
12
|
+
* 1. creates the helper account (an ordinary account, as install-vm-user always did);
|
|
13
|
+
* 2. when it created the account (or `--reset-password` was given): sets a random password, makes the account the
|
|
14
|
+
* auto-login account (`sysadminctl -autologin set`, falling back to writing /etc/kcpassword), and reads the setting back.
|
|
15
|
+
* The password is generated here, used once for this and never printed or stored anywhere else. An existing
|
|
16
|
+
* account's password is NEVER reset without `--reset-password`;
|
|
17
|
+
* 3. makes the shared folder both accounts use (owner = the agent's account, group = the helper, mode 770);
|
|
18
|
+
* 4. adds the knobs to the agent's LaunchDaemon plist (APPFORGE_STATUS_MIRROR_DIR, APPFORGE_VM_INVENTORY_FILE, and
|
|
19
|
+
* APPFORGE_VM_TOOLING_DIR, which makes the agent deliver the signed VM tooling bundle into the shared folder) and
|
|
20
|
+
* reloads the agent's LaunchDaemon. (install-service would drop knobs that its shell does not export, and it has to run as the agent's
|
|
21
|
+
* own account with that account's sudo, which a root-run MDM script does not have; editing the one plist is the
|
|
22
|
+
* idempotent equivalent. install-service refuses to drop these knobs later unless told to.)
|
|
23
|
+
*
|
|
24
|
+
* Refuses (changing nothing) on a laptop, with FileVault on, when not root, when the agent's account is unknown, when the
|
|
25
|
+
* agent is not a boot-time LaunchDaemon, and when a GitHub Actions runner is a LaunchAgent of another account: the auto-login
|
|
26
|
+
* switch would leave it waiting for a manual login after every reboot (#780).
|
|
27
|
+
*
|
|
28
|
+
* 5. installs the helper's reconcile LaunchAgent (~/Library/LaunchAgents/com.appforge.vm-reconcile.plist, owned by the helper, so
|
|
29
|
+
* it loads at the helper's own login): it runs `reconcile-bundle.sh` from the tooling bundle the agent delivers into the shared
|
|
30
|
+
* folder (`<folder>/vm-tooling/current`, appforge-ci#836 B2) every 300 s, with the host name derived from the computer name,
|
|
31
|
+
* the agent's status and the inventory mirror wired to the shared folder, and the agent's own node. No git, no credential. It
|
|
32
|
+
* exits quietly until the first bundle has been delivered.
|
|
33
|
+
* The host files ship with `spec.enabled: false` unless a release enables them, so a Mac that is fully set up still applies
|
|
34
|
+
* nothing until its host file opts in.
|
|
35
|
+
*/
|
|
36
|
+
export const AGENT_DAEMON_PLIST = "/Library/LaunchDaemons/com.appforge.agent.plist";
|
|
37
|
+
export const LOGINWINDOW_PREFS = "/Library/Preferences/com.apple.loginwindow";
|
|
38
|
+
export const KCPASSWORD_PATH = "/etc/kcpassword";
|
|
39
|
+
export const realApplyVmUserDeps = {
|
|
40
|
+
...realInstallVmUserDeps,
|
|
41
|
+
euid: () => (typeof process.geteuid === "function" ? process.geteuid() : -1),
|
|
42
|
+
sudoUser: () => process.env.SUDO_USER?.trim() || null,
|
|
43
|
+
readText(path) {
|
|
44
|
+
try {
|
|
45
|
+
return readFileSync(path, "utf8");
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
listDir(path) {
|
|
52
|
+
try {
|
|
53
|
+
return readdirSync(path);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
// 31 characters on purpose: kcpassword pads to a multiple of 12 with zero bytes, and a length that is already a multiple
|
|
60
|
+
// of 12 leaves no terminator for the reader of the file.
|
|
61
|
+
randomPassword: () => randomBytes(24).toString("base64url").slice(0, 31),
|
|
62
|
+
runSecret(cmd, args, label) {
|
|
63
|
+
// eslint-disable-next-line no-console
|
|
64
|
+
console.log(` $ ${label}`);
|
|
65
|
+
execFileSync(cmd, args, { stdio: ["ignore", "inherit", "inherit"], cwd: "/" });
|
|
66
|
+
},
|
|
67
|
+
writeSecretFile(path, data) {
|
|
68
|
+
writeFileSync(path, data, { mode: 0o600 });
|
|
69
|
+
chmodSync(path, 0o600);
|
|
70
|
+
},
|
|
71
|
+
writeOwnedText(path, text, owner, group) {
|
|
72
|
+
writeFileSync(path, text, { mode: 0o644 });
|
|
73
|
+
chmodSync(path, 0o644);
|
|
74
|
+
execFileSync("chown", [`${owner}:${group}`, path], { cwd: "/" });
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
const AGENT_LABEL = "com.appforge.agent";
|
|
78
|
+
export const HELPER_AGENT_LABEL = "com.appforge.vm-reconcile";
|
|
79
|
+
function xml(s) {
|
|
80
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* The helper's reconcile LaunchAgent. Runs `reconcile-bundle.sh` from the delivered bundle's `current` folder with the host name
|
|
84
|
+
* derived on the Mac (`auto`). The `[ -f ]` guard makes it a quiet no-op until the agent has delivered the first bundle.
|
|
85
|
+
*/
|
|
86
|
+
export function helperAgentPlist(o) {
|
|
87
|
+
const current = `${o.shareDir}/vm-tooling/current`;
|
|
88
|
+
const log = `${o.home}/.appforge-infra/reconcile.log`;
|
|
89
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
90
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
91
|
+
<plist version="1.0">
|
|
92
|
+
<dict>
|
|
93
|
+
<key>Label</key>
|
|
94
|
+
<string>${HELPER_AGENT_LABEL}</string>
|
|
95
|
+
<key>ProgramArguments</key>
|
|
96
|
+
<array>
|
|
97
|
+
<string>/bin/bash</string>
|
|
98
|
+
<string>-c</string>
|
|
99
|
+
<string>[ -f "$0" ] || exit 0; exec /bin/bash "$0" "$1" auto</string>
|
|
100
|
+
<string>${xml(current)}/reconcile-bundle.sh</string>
|
|
101
|
+
<string>${xml(current)}</string>
|
|
102
|
+
</array>
|
|
103
|
+
<key>ProcessType</key>
|
|
104
|
+
<string>Background</string>
|
|
105
|
+
<key>Nice</key>
|
|
106
|
+
<integer>19</integer>
|
|
107
|
+
<key>EnvironmentVariables</key>
|
|
108
|
+
<dict>
|
|
109
|
+
<key>PATH</key>
|
|
110
|
+
<string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
|
111
|
+
<key>APPFORGE_NODE</key>
|
|
112
|
+
<string>${xml(o.nodePath)}</string>
|
|
113
|
+
<key>APPFORGE_AGENT_STATUS</key>
|
|
114
|
+
<string>${xml(o.shareDir)}/status.json</string>
|
|
115
|
+
<key>APPFORGE_INVENTORY_MIRROR_DIR</key>
|
|
116
|
+
<string>${xml(o.shareDir)}</string>
|
|
117
|
+
</dict>
|
|
118
|
+
<key>StartInterval</key>
|
|
119
|
+
<integer>300</integer>
|
|
120
|
+
<key>RunAtLoad</key>
|
|
121
|
+
<true/>
|
|
122
|
+
<key>StandardOutPath</key>
|
|
123
|
+
<string>${xml(log)}</string>
|
|
124
|
+
<key>StandardErrorPath</key>
|
|
125
|
+
<string>${xml(log)}</string>
|
|
126
|
+
</dict>
|
|
127
|
+
</plist>
|
|
128
|
+
`;
|
|
129
|
+
}
|
|
130
|
+
const KC_KEY = [0x7d, 0x89, 0x52, 0x23, 0xd2, 0xbc, 0xdd, 0xea, 0xa3, 0xb9, 0x1f];
|
|
131
|
+
/** The /etc/kcpassword encoding of an auto-login password: XOR with the fixed key, zero-padded to a multiple of 12. */
|
|
132
|
+
export function kcpasswordBytes(password) {
|
|
133
|
+
const raw = [...Buffer.from(password, "utf8")];
|
|
134
|
+
const remainder = raw.length % 12;
|
|
135
|
+
if (remainder > 0)
|
|
136
|
+
raw.push(...new Array(12 - remainder).fill(0));
|
|
137
|
+
return Buffer.from(raw.map((byte, i) => byte ^ KC_KEY[i % KC_KEY.length]));
|
|
138
|
+
}
|
|
139
|
+
/** Accounts whose GitHub Actions runner is a LaunchAgent (found through each runner dir's `.service` file, as the doctor does). */
|
|
140
|
+
export function runnerLaunchAgentAccounts(deps) {
|
|
141
|
+
const found = new Set();
|
|
142
|
+
for (const name of deps.listDir("/Users") ?? []) {
|
|
143
|
+
if (name === "Shared" || name.startsWith("."))
|
|
144
|
+
continue;
|
|
145
|
+
const home = join("/Users", name);
|
|
146
|
+
for (const entry of (deps.listDir(home) ?? []).filter((e) => /^actions-runner/i.test(e))) {
|
|
147
|
+
const svc = deps.readText(join(home, entry, ".service"))?.trim();
|
|
148
|
+
const owner = svc ? /^\/Users\/([^/]+)\/Library\/LaunchAgents\//.exec(svc)?.[1] : undefined;
|
|
149
|
+
if (owner)
|
|
150
|
+
found.add(owner);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return [...found];
|
|
154
|
+
}
|
|
155
|
+
/** The reasons --apply refuses; empty means go ahead. */
|
|
156
|
+
export function applyRefusals(opts, deps) {
|
|
157
|
+
const reasons = vmUserRefusals(deps);
|
|
158
|
+
if (deps.euid() !== 0)
|
|
159
|
+
reasons.push("--apply has to run as root (sudo appforge-admin agents install-vm-user --apply, or an MDM script)");
|
|
160
|
+
const agentUser = opts.agentUser ?? deps.sudoUser();
|
|
161
|
+
if (!agentUser)
|
|
162
|
+
reasons.push("cannot tell which account runs the agent: pass --agent-user <name> (an MDM script runs as root, with no sudo user)");
|
|
163
|
+
else if (!deps.userExists(agentUser))
|
|
164
|
+
reasons.push(`the agent's account '${agentUser}' does not exist`);
|
|
165
|
+
if (deps.readText(AGENT_DAEMON_PLIST) === null) {
|
|
166
|
+
reasons.push(`the agent is not installed as a boot-time LaunchDaemon (${AGENT_DAEMON_PLIST} is missing): install it first (appforge-agent install-service --daemon); the agent cannot hold the console session in this layout`);
|
|
167
|
+
}
|
|
168
|
+
const orphaned = runnerLaunchAgentAccounts(deps).filter((a) => a !== opts.user);
|
|
169
|
+
if (orphaned.length > 0) {
|
|
170
|
+
reasons.push(`a GitHub Actions runner is a LaunchAgent of ${orphaned.join(", ")}: making '${opts.user}' the auto-login account would leave it waiting for a manual login after every reboot (appforge-ci#780). Move the runner to a boot-time LaunchDaemon first`);
|
|
171
|
+
}
|
|
172
|
+
return reasons;
|
|
173
|
+
}
|
|
174
|
+
export function applyVmUser(opts, deps = realApplyVmUserDeps) {
|
|
175
|
+
const { user } = opts;
|
|
176
|
+
const refusals = applyRefusals(opts, deps);
|
|
177
|
+
if (refusals.length > 0)
|
|
178
|
+
throw new Error(`refused: ${refusals.join("; ")}`);
|
|
179
|
+
const agentUser = (opts.agentUser ?? deps.sudoUser());
|
|
180
|
+
const shareDir = opts.shareDir ?? STATUS_SHARE_DIR;
|
|
181
|
+
const existed = deps.userExists(user);
|
|
182
|
+
const loginPref = () => deps.capture("/usr/bin/defaults", ["read", LOGINWINDOW_PREFS, "autoLoginUser"])?.trim() ?? "";
|
|
183
|
+
const setPassword = !existed || opts.resetPassword === true;
|
|
184
|
+
const helperPlistPath = `/Users/${user}/Library/LaunchAgents/${HELPER_AGENT_LABEL}.plist`;
|
|
185
|
+
// The agent's own node, so the helper runs the same one: the first argument of the agent's LaunchDaemon.
|
|
186
|
+
const agentNode = () => deps.capture("/usr/bin/plutil", ["-extract", "ProgramArguments.0", "raw", "-o", "-", AGENT_DAEMON_PLIST])?.trim() || "/opt/homebrew/bin/node";
|
|
187
|
+
const desiredHelperPlist = () => helperAgentPlist({ shareDir, nodePath: agentNode(), home: `/Users/${user}` });
|
|
188
|
+
const existingHelperPlist = () => deps.readText(helperPlistPath);
|
|
189
|
+
const steps = [
|
|
190
|
+
{
|
|
191
|
+
title: `create the '${user}' account`,
|
|
192
|
+
skip: () => (existed ? "already exists" : null),
|
|
193
|
+
run: () => void ensureOrdinaryUser(user, "AppForge VM helper (dedicated)", `Creating the dedicated '${user}' account (it will hold this Mac's graphical session and run the VM tooling)`, deps),
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
title: `set a random password for '${user}' and make it the auto-login account`,
|
|
197
|
+
skip: () => {
|
|
198
|
+
if (setPassword)
|
|
199
|
+
return null;
|
|
200
|
+
return loginPref() === user
|
|
201
|
+
? "already the auto-login account (its password is not touched)"
|
|
202
|
+
: `the account exists and is not the auto-login account; its password is not touched without --reset-password, so auto-login is NOT set`;
|
|
203
|
+
},
|
|
204
|
+
run: () => {
|
|
205
|
+
const password = deps.randomPassword();
|
|
206
|
+
deps.runSecret("dscl", [".", "-passwd", `/Users/${user}`, password], `dscl . -passwd /Users/${user} <random password, not shown>`);
|
|
207
|
+
try {
|
|
208
|
+
deps.runSecret("sysadminctl", ["-autologin", "set", "-userName", user, "-password", password], `sysadminctl -autologin set -userName ${user} -password <random password, not shown>`);
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
deps.log(" sysadminctl could not set auto-login; writing /etc/kcpassword and the loginwindow preference instead");
|
|
212
|
+
}
|
|
213
|
+
if (loginPref() !== user) {
|
|
214
|
+
deps.writeSecretFile(KCPASSWORD_PATH, kcpasswordBytes(password));
|
|
215
|
+
deps.run("defaults", ["write", LOGINWINDOW_PREFS, "autoLoginUser", "-string", user]);
|
|
216
|
+
}
|
|
217
|
+
if (loginPref() !== user)
|
|
218
|
+
throw new Error(`auto-login for '${user}' did not stick: ${LOGINWINDOW_PREFS} autoLoginUser reads "${loginPref()}"`);
|
|
219
|
+
deps.log(` auto-login is now '${user}' (read back); it takes effect at the next boot`);
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
title: `make the shared folder ${shareDir} (owner ${agentUser}, group ${user}, mode 770)`,
|
|
224
|
+
run: () => deps.run("install", ["-d", "-o", agentUser, "-g", user, "-m", "770", shareDir]),
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
title: `add the mirror knobs to the agent's LaunchDaemon plist and reload the agent`,
|
|
228
|
+
skip: () => {
|
|
229
|
+
const have = (key) => deps.capture("/usr/bin/plutil", ["-extract", `EnvironmentVariables.${key}`, "raw", "-o", "-", AGENT_DAEMON_PLIST])?.trim();
|
|
230
|
+
return have("APPFORGE_STATUS_MIRROR_DIR") === shareDir && have("APPFORGE_VM_INVENTORY_FILE") === `${shareDir}/inventory.json` && have("APPFORGE_VM_TOOLING_DIR") === shareDir
|
|
231
|
+
? "already set"
|
|
232
|
+
: null;
|
|
233
|
+
},
|
|
234
|
+
run: () => {
|
|
235
|
+
deps.run("plutil", ["-replace", "EnvironmentVariables.APPFORGE_STATUS_MIRROR_DIR", "-string", shareDir, AGENT_DAEMON_PLIST]);
|
|
236
|
+
deps.run("plutil", ["-replace", "EnvironmentVariables.APPFORGE_VM_INVENTORY_FILE", "-string", `${shareDir}/inventory.json`, AGENT_DAEMON_PLIST]);
|
|
237
|
+
deps.run("plutil", ["-replace", "EnvironmentVariables.APPFORGE_VM_TOOLING_DIR", "-string", shareDir, AGENT_DAEMON_PLIST]);
|
|
238
|
+
// launchd keeps the job definition it loaded: `kickstart -k` restarts the process with the OLD environment, so the new knobs
|
|
239
|
+
// would not reach the agent until the next reboot (found on the rehearsal mini, appforge-ci#841). Reload the job instead.
|
|
240
|
+
deps.log(" reloading the agent's LaunchDaemon so it picks up the new settings (a few seconds without the agent)");
|
|
241
|
+
deps.tryRun("launchctl", ["bootout", `system/${AGENT_LABEL}`]);
|
|
242
|
+
let loaded = false;
|
|
243
|
+
for (let attempt = 0; attempt < 5 && !loaded; attempt++) {
|
|
244
|
+
if (attempt > 0)
|
|
245
|
+
deps.tryRun("sleep", ["1"]);
|
|
246
|
+
loaded = deps.tryRun("launchctl", ["bootstrap", "system", AGENT_DAEMON_PLIST]);
|
|
247
|
+
}
|
|
248
|
+
if (!loaded) {
|
|
249
|
+
deps.log(` the agent is NOT running: run \`sudo launchctl bootstrap system ${AGENT_DAEMON_PLIST}\` and read the error`);
|
|
250
|
+
deps.run("launchctl", ["bootstrap", "system", AGENT_DAEMON_PLIST]);
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
title: `install the helper's reconcile LaunchAgent (runs the delivered VM tooling from ${shareDir}/vm-tooling/current)`,
|
|
256
|
+
skip: () => (existingHelperPlist() === desiredHelperPlist() ? "already installed, unchanged" : null),
|
|
257
|
+
run: () => {
|
|
258
|
+
const home = `/Users/${user}`;
|
|
259
|
+
deps.run("install", ["-d", "-o", user, "-g", user, "-m", "755", `${home}/Library`, `${home}/Library/LaunchAgents`]);
|
|
260
|
+
deps.run("install", ["-d", "-o", user, "-g", user, "-m", "755", `${home}/.appforge-infra`]);
|
|
261
|
+
deps.writeOwnedText(helperPlistPath, desiredHelperPlist(), user, user);
|
|
262
|
+
deps.log(` wrote ${helperPlistPath}; it loads at ${user}'s next login (the reboot)`);
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
];
|
|
266
|
+
deps.log(`${opts.dryRun ? "DRY RUN: nothing will be changed. " : ""}Setting up the helper-account layout for '${user}' (agent account '${agentUser}'):`);
|
|
267
|
+
let n = 0;
|
|
268
|
+
for (const step of steps) {
|
|
269
|
+
n += 1;
|
|
270
|
+
const reason = step.skip?.() ?? null;
|
|
271
|
+
if (reason !== null) {
|
|
272
|
+
deps.log(`\n[${n}/${steps.length}] ${step.title}: skipped, ${reason}`);
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
deps.log(`\n[${n}/${steps.length}] ${step.title}`);
|
|
276
|
+
if (!opts.dryRun)
|
|
277
|
+
step.run();
|
|
278
|
+
}
|
|
279
|
+
if (!opts.dryRun && loginPref() !== user) {
|
|
280
|
+
deps.log(`\nWARNING: '${user}' is NOT the auto-login account (${LOGINWINDOW_PREFS} autoLoginUser reads "${loginPref() || "nothing"}"): macOS guests will not start after a reboot until it is. Re-run with --reset-password to set one.`);
|
|
281
|
+
}
|
|
282
|
+
deps.log(opts.dryRun
|
|
283
|
+
? "\nDry run finished: re-run without --dry-run to apply."
|
|
284
|
+
: `\nDone. Reboot to start the helper's session: its reconcile LaunchAgent loads at login and starts applying once the agent has delivered the signed VM tooling for its own version (a tagged release; appforge-ci#836).`);
|
|
285
|
+
}
|
|
286
|
+
//# sourceMappingURL=vm-user-apply.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vm-user-apply.js","sourceRoot":"","sources":["../../src/lib/vm-user-apply.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vm-user-apply.test.d.ts","sourceRoot":"","sources":["../../src/lib/vm-user-apply.test.ts"],"names":[],"mappings":"AAAA,OAAO,iCAAiC,CAAC"}
|