fix(deploy): discover workspace source via container inspect (not mountinfo)
This commit is contained in:
@@ -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).
|
||||
|
||||
Reference in New Issue
Block a user