fix(deploy): discover workspace source via container inspect (not mountinfo)

This commit is contained in:
chenxing
2026-08-04 22:56:08 +08:00
parent 1619e41c20
commit f0bd70ff6e
+26 -18
View File
@@ -19,6 +19,15 @@ const fs = require('fs');
const SOCKET = '/var/run/docker.sock';
const HOST_STATIC = '/data/www/userbase';
const HELPER_IMAGE = 'node:20'; // already cached on host (used by the job)
const WS_MOUNT = '/workspace/admin/userbase';
// The job container's ID, derived from its cgroup (robust regardless of hostname).
function getContainerId() {
const cg = fs.readFileSync('/proc/self/cgroup', 'utf8');
const m = cg.match(/[0-9a-f]{64}/);
if (!m) throw new Error('cannot determine container id from cgroup');
return m[0];
}
function dockerReq(method, path, bodyObj) {
return new Promise((resolve, reject) => {
@@ -42,29 +51,28 @@ function dockerReq(method, path, bodyObj) {
});
}
// Locate the host path backing the workspace mountpoint (a docker volume _data dir).
function findWorkspaceSource(mountpoint) {
const txt = fs.readFileSync('/proc/self/mountinfo', 'utf8');
for (const line of txt.split('\n')) {
const parts = line.trim().split(/\s+/);
if (parts.length < 5) continue;
const mp = parts[4];
if (mp === mountpoint || mp.endsWith(mountpoint)) {
const dash = parts.indexOf('-');
if (dash !== -1 && parts.length > dash + 2) {
return parts[dash + 2];
}
// Locate the host path backing the workspace mount by inspecting THIS container
// via the Docker daemon (docker.sock). This is far more reliable than parsing
// /proc/self/mountinfo (which reports the underlying block device, not the bind
// source). The job container's hostname is its short ID.
async function findWorkspaceSource() {
const id = getContainerId();
const r = await dockerReq('GET', `/containers/${id}/json`);
if (r.status >= 400) {
throw new Error('inspect self failed: ' + r.status + ' ' + r.body);
}
const info = JSON.parse(r.body);
const mounts = info.Mounts || [];
for (const m of mounts) {
if (m.Destination === WS_MOUNT) {
return m.Source; // host path of the docker volume _data dir
}
}
return null;
throw new Error('workspace mount ' + WS_MOUNT + ' not found in container inspect');
}
async function main() {
const wsMount = '/workspace/admin/userbase';
const wsSource = findWorkspaceSource(wsMount);
if (!wsSource) {
throw new Error('Could not find workspace source in /proc/self/mountinfo');
}
const wsSource = await findWorkspaceSource();
console.log('workspace source (host path):', wsSource);
// Inside the helper, the workspace is bound at /src (see Binds below).