@ai-ecoverse/slicc-kernel 1.59.0 → 1.60.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/README.md +22 -3
- package/dist/index.js +37 -8
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +78 -13
- package/dist/kernel-worker.js.map +3 -3
- package/dist/node-process-worker.js +1 -1
- package/dist/node-process-worker.js.map +2 -2
- package/dist/node.js +172 -38
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +1 -1
- package/dist/process-worker.js.map +2 -2
- package/package.json +1 -1
package/dist/kernel-worker.js
CHANGED
|
@@ -2626,6 +2626,29 @@ function userEnv(account, system) {
|
|
|
2626
2626
|
PATH: `${pnpm}/bin:/usr/local/bin:/usr/bin:/bin`
|
|
2627
2627
|
};
|
|
2628
2628
|
}
|
|
2629
|
+
function groupsOf(groups, names) {
|
|
2630
|
+
return names.map((g) => {
|
|
2631
|
+
const row = groups.find((r) => r.name === g);
|
|
2632
|
+
if (!row) throw fsError("ENOENT", `no group ${g}`);
|
|
2633
|
+
return row;
|
|
2634
|
+
});
|
|
2635
|
+
}
|
|
2636
|
+
function homeModeOf(mode) {
|
|
2637
|
+
if (mode === void 0) return void 0;
|
|
2638
|
+
if (!Number.isInteger(mode) || mode < 0 || mode > 4095) {
|
|
2639
|
+
throw fsError("EINVAL", `not a mode: ${String(mode)}`);
|
|
2640
|
+
}
|
|
2641
|
+
return mode;
|
|
2642
|
+
}
|
|
2643
|
+
function joined(name2, rows) {
|
|
2644
|
+
let changed = false;
|
|
2645
|
+
for (const g of rows) {
|
|
2646
|
+
if (g.members.includes(name2)) continue;
|
|
2647
|
+
g.members.push(name2);
|
|
2648
|
+
changed = true;
|
|
2649
|
+
}
|
|
2650
|
+
return changed;
|
|
2651
|
+
}
|
|
2629
2652
|
function homeGroupOf(groups, name2) {
|
|
2630
2653
|
if (name2 === void 0) return void 0;
|
|
2631
2654
|
const found = groups.find((g) => g.name === name2);
|
|
@@ -2641,14 +2664,14 @@ var UserDb = class {
|
|
|
2641
2664
|
this.fs = fs;
|
|
2642
2665
|
this.owners = owners;
|
|
2643
2666
|
}
|
|
2644
|
-
async stampHome(row, shared) {
|
|
2667
|
+
async stampHome(row, shared, homeMode) {
|
|
2645
2668
|
const home = this.fs.resolvePath("/", row.home);
|
|
2646
2669
|
if (!this.owners || !this.fs.chown || !HOME_DIR.test(home)) return;
|
|
2647
2670
|
if (!await this.realDir(home)) return;
|
|
2648
2671
|
const gid = shared?.gid ?? row.gid;
|
|
2649
2672
|
await this.fs.chown(home, { uid: row.uid, gid, follow: false, kind: "adopt" });
|
|
2650
2673
|
const scoop = row.name.startsWith("scoop-");
|
|
2651
|
-
await this.fs.chmod(home, shared ? 1512 : scoop ? 488 : 448);
|
|
2674
|
+
await this.fs.chmod(home, homeMode ?? (shared ? 1512 : scoop ? 488 : 448));
|
|
2652
2675
|
const pnpm = `${home}/.local/share/pnpm`;
|
|
2653
2676
|
if (await this.realDir(pnpm)) await this.fs.chmod(pnpm, scoop ? 488 : 448);
|
|
2654
2677
|
}
|
|
@@ -2762,31 +2785,33 @@ var UserDb = class {
|
|
|
2762
2785
|
const groups = parsed(group);
|
|
2763
2786
|
const found = users.find((r) => r.name === name2);
|
|
2764
2787
|
const shared = homeGroupOf(groups, options.homeGroup);
|
|
2788
|
+
const homeMode = homeModeOf(options.homeMode);
|
|
2765
2789
|
if (found) {
|
|
2790
|
+
const more = groupsOf(groups, options.groups ?? []);
|
|
2791
|
+
if (more.some((g) => g.gid === found.gid)) {
|
|
2792
|
+
throw fsError("EINVAL", `a user is no member of its own group ${name2}`);
|
|
2793
|
+
}
|
|
2766
2794
|
if (found.uid >= FIRST_UID && found.uid <= LAST_UID) {
|
|
2767
2795
|
await this.provision(found);
|
|
2768
|
-
await this.stampHome(found, shared);
|
|
2796
|
+
await this.stampHome(found, shared, homeMode);
|
|
2769
2797
|
}
|
|
2798
|
+
if (joined(name2, more)) await this.fs.writeFile(GROUP, formatGroup(group));
|
|
2770
2799
|
remember();
|
|
2771
2800
|
return this.account(found, groups);
|
|
2772
2801
|
}
|
|
2773
2802
|
const home = homeOf(options.home ?? `/home/${name2}`);
|
|
2774
|
-
const extra = [USERS_GROUP, ...options.groups ?? []]
|
|
2775
|
-
const row2 = groups.find((r) => r.name === g);
|
|
2776
|
-
if (!row2) throw fsError("ENOENT", `no group ${g}`);
|
|
2777
|
-
return row2;
|
|
2778
|
-
});
|
|
2803
|
+
const extra = groupsOf(groups, [USERS_GROUP, ...options.groups ?? []]);
|
|
2779
2804
|
if (groups.some((r) => r.name === name2)) throw fsError("EEXIST", `group ${name2} exists`);
|
|
2780
2805
|
const uid = freeId(users, groups);
|
|
2781
2806
|
const row = { name: name2, uid, gid: uid, gecos: name2, home, shell: "/bin/bash" };
|
|
2782
|
-
|
|
2807
|
+
joined(name2, extra);
|
|
2783
2808
|
group.push({ name: name2, gid: uid, members: [] });
|
|
2784
2809
|
passwd.push(row);
|
|
2785
2810
|
const fresh = !await this.fs.exists(home);
|
|
2786
2811
|
await this.fs.mkdir(home, { recursive: true });
|
|
2787
2812
|
try {
|
|
2788
2813
|
await this.provision(row);
|
|
2789
|
-
await this.stampHome(row, shared);
|
|
2814
|
+
await this.stampHome(row, shared, homeMode);
|
|
2790
2815
|
await this.fs.mkdir("/etc", { recursive: true });
|
|
2791
2816
|
await this.commit(formatPasswd(passwd), formatGroup(group));
|
|
2792
2817
|
} catch (err) {
|
|
@@ -2797,6 +2822,31 @@ var UserDb = class {
|
|
|
2797
2822
|
return this.account(row, parsed(group));
|
|
2798
2823
|
});
|
|
2799
2824
|
}
|
|
2825
|
+
async groups() {
|
|
2826
|
+
const { group } = await this.tables();
|
|
2827
|
+
return parsed(group).map(({ name: name2, gid, members }) => ({ name: name2, gid, members: [...members] }));
|
|
2828
|
+
}
|
|
2829
|
+
addMember(group, user) {
|
|
2830
|
+
return this.member(group, user, true);
|
|
2831
|
+
}
|
|
2832
|
+
removeMember(group, user) {
|
|
2833
|
+
return this.member(group, user, false);
|
|
2834
|
+
}
|
|
2835
|
+
member(name2, user, on) {
|
|
2836
|
+
return this.serial(async () => {
|
|
2837
|
+
const { passwd, group } = await this.tables();
|
|
2838
|
+
const row = parsed(group).find((g) => g.name === name2);
|
|
2839
|
+
if (!row) throw fsError("ENOENT", `no group ${String(name2)}`);
|
|
2840
|
+
const who = parsed(passwd).find((u) => u.name === user);
|
|
2841
|
+
if (!who) throw fsError("ENOENT", `no user ${String(user)}`);
|
|
2842
|
+
if (who.gid === row.gid) throw fsError("EINVAL", `${name2} is the own group of ${user}`);
|
|
2843
|
+
if (row.members.includes(user) !== on) {
|
|
2844
|
+
row.members = on ? [...row.members, user] : row.members.filter((m) => m !== user);
|
|
2845
|
+
await this.fs.writeFile(GROUP, formatGroup(group));
|
|
2846
|
+
}
|
|
2847
|
+
return { name: row.name, gid: row.gid, members: [...row.members] };
|
|
2848
|
+
});
|
|
2849
|
+
}
|
|
2800
2850
|
remove(name2, options = {}) {
|
|
2801
2851
|
return this.serial(async () => {
|
|
2802
2852
|
const { passwd, group } = await this.tables();
|
|
@@ -8779,6 +8829,11 @@ var TOKEN3 = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
|
|
|
8779
8829
|
function message(e) {
|
|
8780
8830
|
return e instanceof Error ? e.message : String(e);
|
|
8781
8831
|
}
|
|
8832
|
+
var ERRNO = /^E[A-Z]+$|^EAI_[A-Z]+$/;
|
|
8833
|
+
function errnoOf(e) {
|
|
8834
|
+
const code = e?.code;
|
|
8835
|
+
return typeof code === "string" && ERRNO.test(code) ? code : "ECONNREFUSED";
|
|
8836
|
+
}
|
|
8782
8837
|
function fail(errno, text) {
|
|
8783
8838
|
return { ok: false, errno, message: text };
|
|
8784
8839
|
}
|
|
@@ -8822,13 +8877,13 @@ var WsHandles = class {
|
|
|
8822
8877
|
let socket;
|
|
8823
8878
|
try {
|
|
8824
8879
|
socket = await transport.websocket({
|
|
8825
|
-
url: req.url,
|
|
8880
|
+
url: toHostLoopback(req.url),
|
|
8826
8881
|
protocols: req.protocols,
|
|
8827
8882
|
headers: req.headers,
|
|
8828
8883
|
signal: entry.abort.signal
|
|
8829
8884
|
});
|
|
8830
8885
|
} catch (e) {
|
|
8831
|
-
return fail(
|
|
8886
|
+
return fail(errnoOf(e), message(e));
|
|
8832
8887
|
}
|
|
8833
8888
|
if (!this.open.has(handle)) {
|
|
8834
8889
|
socket.close(1001, "the program went away");
|
|
@@ -14486,7 +14541,14 @@ function answered(data, remote, uplink) {
|
|
|
14486
14541
|
else return false;
|
|
14487
14542
|
return true;
|
|
14488
14543
|
}
|
|
14489
|
-
var USERS_OPS = /* @__PURE__ */ new Set([
|
|
14544
|
+
var USERS_OPS = /* @__PURE__ */ new Set([
|
|
14545
|
+
"users-add",
|
|
14546
|
+
"users-remove",
|
|
14547
|
+
"users-list",
|
|
14548
|
+
"groups-list",
|
|
14549
|
+
"groups-add-member",
|
|
14550
|
+
"groups-remove-member"
|
|
14551
|
+
]);
|
|
14490
14552
|
function isUsersRequest(req) {
|
|
14491
14553
|
return USERS_OPS.has(req.op);
|
|
14492
14554
|
}
|
|
@@ -14500,6 +14562,9 @@ function failure(err) {
|
|
|
14500
14562
|
function usersOp(l, req) {
|
|
14501
14563
|
if (req.op === "users-add") return l.users.add(req.user);
|
|
14502
14564
|
if (req.op === "users-remove") return l.users.remove(req.name, req.options);
|
|
14565
|
+
if (req.op === "groups-list") return l.users.groups();
|
|
14566
|
+
if (req.op === "groups-add-member") return l.users.addMember(req.group, req.user);
|
|
14567
|
+
if (req.op === "groups-remove-member") return l.users.removeMember(req.group, req.user);
|
|
14503
14568
|
return l.users.list();
|
|
14504
14569
|
}
|
|
14505
14570
|
function hostOptions(req) {
|