dockerproxy: all volumes to be mounted in child containers

this will allow jupyterhub notebooks to access volumes
This commit is contained in:
Girish Ramakrishnan
2023-11-27 22:07:31 +01:00
parent 8d20ca2053
commit 740c0fe318
2 changed files with 20 additions and 9 deletions

View File

@@ -17,7 +17,8 @@ const apps = require('./apps.js'),
path = require('path'),
paths = require('./paths.js'),
safe = require('safetydance'),
util = require('util');
util = require('util'),
volumes = require('./volumes.js');
let gHttpServer = null;
@@ -62,7 +63,7 @@ function attachDockerRequest(req, res, next) {
}
// eslint-disable-next-line no-unused-vars
function containersCreate(req, res, next) {
async function containersCreate(req, res, next) {
safe.set(req.body, 'HostConfig.NetworkMode', 'cloudron'); // overwrite the network the container lives in
safe.set(req.body, 'NetworkingConfig', {}); // drop any custom network configs
safe.set(req.body, 'Labels', Object.assign({}, safe.query(req.body, 'Labels'), { appId: req.app.id, isCloudronManaged: String(false) })); // overwrite the app id to track containers of an app
@@ -70,19 +71,28 @@ function containersCreate(req, res, next) {
const appDataDir = path.join(paths.APPS_DATA_DIR, req.app.id, 'data');
debug('Original bind mounts:', req.body.HostConfig.Binds);
debug('containersCreate: original bind mounts:', req.body.HostConfig.Binds);
const result = await volumes.list();
const volumesByName = {};
result.forEach(r => volumesByName[r.name] = r);
const binds = [];
for (const bind of (req.body.HostConfig.Binds || [])) {
if (!bind.startsWith('/app/data/')) {
for (const bind of (req.body.HostConfig.Binds || [])) { // bind is of the host:container:rw format
if (bind.startsWith('/app/data')) {
binds.push(bind.replace(new RegExp('^/app/data/'), appDataDir + '/'));
} else if (bind.startsWith('/media/')) {
const volumeName = bind.match(new RegExp('/media/([^:/]+)/?'))[1];
const volume = volumesByName[volumeName];
if (volume) binds.push(bind.replace(new RegExp(`^/media/${volumeName}`), volume.hostPath));
else debug(`containersCreate: dropped unknown volume ${volumeName}`);
} else {
req.dockerRequest.abort();
return next(new HttpError(400, 'Binds must be under /app/data/'));
return next(new HttpError(400, 'Binds must be under /app/data/ or /media'));
}
binds.push(bind.replace(new RegExp('^/app/data/'), appDataDir + '/'));
}
debug('Rewritten bind mounts:', binds);
debug('containersCreate: rewritten bind mounts:', binds);
safe.set(req.body, 'HostConfig.Binds', binds);
const plainBody = JSON.stringify(req.body);