@xcanwin/manyoyo 8.6.0 → 8.6.2
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/lib/container-exec.js +20 -1
- package/lib/web/container-manage.js +16 -0
- package/lib/web/index.html +80 -80
- package/lib/web/server.js +91 -7
- package/package.json +1 -1
package/lib/container-exec.js
CHANGED
|
@@ -129,4 +129,23 @@ function buildExecArgs(ctx, containerName, options = {}) {
|
|
|
129
129
|
return { args, cleanup, invalid, containerId };
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
|
|
132
|
+
/**
|
|
133
|
+
* 读出一个容器 exec 时会拿到的合并后 env(managed → 环境变量文件 → box/env),只在宿主机上读文件、不进容器。
|
|
134
|
+
* 旧容器(没有状态目录)返回空对象。调用方只能挑非敏感字段(如 *_MODEL)展示,不要整份下发给前端。
|
|
135
|
+
* @returns {Record<string, string>}
|
|
136
|
+
*/
|
|
137
|
+
function readMergedEnv(ctx, containerName) {
|
|
138
|
+
const homeDir = ctx.homeDir || os.homedir();
|
|
139
|
+
const containerId = resolveContainerId(ctx.dockerExecArgs, containerName);
|
|
140
|
+
if (!containerId || !state.stateExists(homeDir, containerId)) return {};
|
|
141
|
+
const p = state.paths(homeDir, containerId);
|
|
142
|
+
const { lines } = composeEnvLines(readTextOrEmpty(p.managedEnv), readTextOrEmpty(p.env, true), [], state.envFileEntries(homeDir, containerId));
|
|
143
|
+
const env = {};
|
|
144
|
+
lines.forEach(line => {
|
|
145
|
+
const i = line.indexOf('=');
|
|
146
|
+
if (i > 0) env[line.slice(0, i)] = line.slice(i + 1);
|
|
147
|
+
});
|
|
148
|
+
return env;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
module.exports = { ID_LABEL, resolveContainerId, composeEnvLines, buildExecArgs, readMergedEnv };
|
|
@@ -15,6 +15,21 @@ const { isBrowserBackground } = require('../browser-background');
|
|
|
15
15
|
// 全部挂在全局认证网关之后;非只读请求由 handleWebApi 统一校验 X-Requested-With。
|
|
16
16
|
const LEGACY_MESSAGE = '该容器创建于旧版本,重建后可用';
|
|
17
17
|
|
|
18
|
+
// 本机可用于访问端口暴露的 IPv4 地址(绑定 0.0.0.0 时前端据此列出全部访问链接);
|
|
19
|
+
// 回环排第一,容器 / 虚拟网桥的地址对访问者没用,过滤掉
|
|
20
|
+
const VIRTUAL_IFACE_RE = /^(docker|br-|veth|cni|podman|virbr|lo$)/;
|
|
21
|
+
function listHostIps() {
|
|
22
|
+
const ips = ['127.0.0.1'];
|
|
23
|
+
const ifaces = os.networkInterfaces();
|
|
24
|
+
Object.keys(ifaces).forEach(name => {
|
|
25
|
+
if (VIRTUAL_IFACE_RE.test(name)) return;
|
|
26
|
+
(ifaces[name] || []).forEach(addr => {
|
|
27
|
+
if (addr.family === 'IPv4' && !addr.internal && !ips.includes(addr.address)) ips.push(addr.address);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
return ips;
|
|
31
|
+
}
|
|
32
|
+
|
|
18
33
|
function isLoopbackBind(bind) {
|
|
19
34
|
return bind === '127.0.0.1' || bind === '::1';
|
|
20
35
|
}
|
|
@@ -191,6 +206,7 @@ function createContainerManageRoutes({ ctx, state, req, res, deps }) {
|
|
|
191
206
|
policy,
|
|
192
207
|
status: state_.readNetStatus(homeDir, target.id),
|
|
193
208
|
forwards: getPortForwarder().list(target.id),
|
|
209
|
+
hostIps: listHostIps(),
|
|
194
210
|
peers,
|
|
195
211
|
derived,
|
|
196
212
|
unrestricted: isUnrestricted(policy),
|