From 7abf253243bfd7991b53cbe5804b2b988714565b Mon Sep 17 00:00:00 2001 From: yu-i-i Date: Mon, 2 Feb 2026 16:59:34 +0100 Subject: [PATCH] Sandboxed Compiles: support configurable texlive image root via env var --- services/clsi/README.md | 2 +- services/clsi/app/js/CompileController.js | 2 +- services/clsi/app/js/DockerRunner.js | 5 +++-- services/clsi/buildscript.txt | 2 +- services/clsi/config/settings.defaults.cjs | 2 +- services/clsi/docker-compose.ci.yml | 2 +- services/clsi/docker-compose.yml | 2 +- .../web/app/src/Features/Project/ProjectOptionsHandler.mjs | 2 +- services/web/modules/sandboxed-compiles/index.mjs | 3 +++ 9 files changed, 13 insertions(+), 9 deletions(-) diff --git a/services/clsi/README.md b/services/clsi/README.md index e7edc98ad4..f5529bcc25 100644 --- a/services/clsi/README.md +++ b/services/clsi/README.md @@ -29,7 +29,7 @@ The CLSI can be configured through the following environment variables: - `PROCESS_LIFE_SPAN_LIMIT_MS` - Process life span limit in milliseconds - `SMOKE_TEST` - Whether to run smoke tests - `TEXLIVE_IMAGE` - The TeX Live Docker image to use for sibling containers, e.g. `us-east1-docker.pkg.dev/overleaf-ops/ol-docker/texlive-full:2025.1` -- `TEX_LIVE_IMAGE_NAME_OVERRIDE` - The name of the registry for the Docker image e.g. `us-east1-docker.pkg.dev/overleaf-ops/ol-docker` +- `TEX_LIVE_DOCKER_IMAGE_ROOT` - The name of the registry for the Docker image e.g. `us-east1-docker.pkg.dev/overleaf-ops/ol-docker` - `TEXLIVE_IMAGE_USER` - When using sibling containers, the user to run as in the TeX Live image. Defaults to `tex` - `TEXLIVE_OPENOUT_ANY` - Sets the `openout_any` environment variable for TeX Live (see the `\openout` primitive [documentation](http://tug.org/texinfohtml/web2c.html#tex-invocation)) diff --git a/services/clsi/app/js/CompileController.js b/services/clsi/app/js/CompileController.js index 7b4f97d82c..1359ff38d0 100644 --- a/services/clsi/app/js/CompileController.js +++ b/services/clsi/app/js/CompileController.js @@ -138,7 +138,7 @@ function compile(req, res, next) { compiler: request.compiler, draft: request.draft, imageName: request.imageName - ? request.imageName + ? Path.basename(request.imageName) : undefined, rootResourcePath: request.rootResourcePath, stopOnFirstError: request.stopOnFirstError, diff --git a/services/clsi/app/js/DockerRunner.js b/services/clsi/app/js/DockerRunner.js index ecfc6b5b54..02185cc1c0 100644 --- a/services/clsi/app/js/DockerRunner.js +++ b/services/clsi/app/js/DockerRunner.js @@ -41,8 +41,8 @@ const DockerRunner = { } if (Settings.texliveImageNameOveride != null) { - const img = image.split('/') - image = `${Settings.texliveImageNameOveride}/${img[2]}` + const img = Path.basename(image) + image = `${Settings.texliveImageNameOveride}/${img}` } if (compileGroup === 'synctex-output') { @@ -238,6 +238,7 @@ const DockerRunner = { const match = image.match(/:([0-9]+)\.[0-9]+|:TL([0-9]+)/) // the rolling build does not follow our .. convention const year = match ? match[1] || match[2] : 'rolling' + env.PATH = `/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/texlive/${year}/bin/x86_64-linux/` const options = { Cmd: command, diff --git a/services/clsi/buildscript.txt b/services/clsi/buildscript.txt index c62ead4875..16872c9a87 100644 --- a/services/clsi/buildscript.txt +++ b/services/clsi/buildscript.txt @@ -1,7 +1,7 @@ clsi --data-dirs=cache,compiles,output --dependencies= ---env-add=DOWNLOAD_HOST=http://clsi-nginx:8080,ALLOWED_COMPILE_GROUPS=clsi-perf simple-latex-file,ENABLE_PDF_CACHING=true,PDF_CACHING_ENABLE_WORKER_POOL=true,ALLOWED_IMAGES=quay.io/sharelatex/texlive-full:2017.1 quay.io/sharelatex/texlive-full:2025.1 quay.io/sharelatex/pandoc:3.9 quay.io/sharelatex/pdftocairo:24.02,TEXLIVE_IMAGE=quay.io/sharelatex/texlive-full:2025.1,TEX_LIVE_IMAGE_NAME_OVERRIDE=us-east1-docker.pkg.dev/overleaf-ops/ol-docker,TEXLIVE_IMAGE_USER=tex,SANDBOXED_COMPILES=true,SANDBOXED_COMPILES_HOST_DIR_COMPILES=$PWD/compiles,SANDBOXED_COMPILES_HOST_DIR_OUTPUT=$PWD/output,ENABLE_PANDOC_CONVERSIONS=true,ENABLE_PDF_CONVERSIONS=true +--env-add=DOWNLOAD_HOST=http://clsi-nginx:8080,ALLOWED_COMPILE_GROUPS=clsi-perf simple-latex-file,ENABLE_PDF_CACHING=true,PDF_CACHING_ENABLE_WORKER_POOL=true,ALLOWED_IMAGES=quay.io/sharelatex/texlive-full:2017.1 quay.io/sharelatex/texlive-full:2025.1 quay.io/sharelatex/pandoc:3.9 quay.io/sharelatex/pdftocairo:24.02,TEXLIVE_IMAGE=quay.io/sharelatex/texlive-full:2025.1,TEX_LIVE_DOCKER_IMAGE_ROOT=us-east1-docker.pkg.dev/overleaf-ops/ol-docker,TEXLIVE_IMAGE_USER=tex,SANDBOXED_COMPILES=true,SANDBOXED_COMPILES_HOST_DIR_COMPILES=$PWD/compiles,SANDBOXED_COMPILES_HOST_DIR_OUTPUT=$PWD/output,ENABLE_PANDOC_CONVERSIONS=true,ENABLE_PDF_CONVERSIONS=true --env-pass-through= --esmock-loader=False --node-version=24.14.1 diff --git a/services/clsi/config/settings.defaults.cjs b/services/clsi/config/settings.defaults.cjs index 84a3d5c883..63e085d892 100644 --- a/services/clsi/config/settings.defaults.cjs +++ b/services/clsi/config/settings.defaults.cjs @@ -93,7 +93,7 @@ module.exports = { parallelFileDownloads: parseInt(process.env.FILESTORE_PARALLEL_FILE_DOWNLOADS, 10) || 1, filestoreDomainOveride: process.env.FILESTORE_DOMAIN_OVERRIDE, - texliveImageNameOveride: process.env.TEX_LIVE_IMAGE_NAME_OVERRIDE, + texliveImageNameOveride: process.env.TEX_LIVE_DOCKER_IMAGE_ROOT, texliveOpenoutAny: process.env.TEXLIVE_OPENOUT_ANY, texliveMaxPrintLine: process.env.TEXLIVE_MAX_PRINT_LINE, enablePdfCaching: process.env.ENABLE_PDF_CACHING === 'true', diff --git a/services/clsi/docker-compose.ci.yml b/services/clsi/docker-compose.ci.yml index a02654cbd2..4bc5df7f17 100644 --- a/services/clsi/docker-compose.ci.yml +++ b/services/clsi/docker-compose.ci.yml @@ -32,7 +32,7 @@ services: PDF_CACHING_ENABLE_WORKER_POOL: true ALLOWED_IMAGES: quay.io/sharelatex/texlive-full:2017.1 quay.io/sharelatex/texlive-full:2025.1 quay.io/sharelatex/pandoc:3.9 quay.io/sharelatex/pdftocairo:24.02 TEXLIVE_IMAGE: quay.io/sharelatex/texlive-full:2025.1 - TEX_LIVE_IMAGE_NAME_OVERRIDE: us-east1-docker.pkg.dev/overleaf-ops/ol-docker + TEX_LIVE_DOCKER_IMAGE_ROOT: us-east1-docker.pkg.dev/overleaf-ops/ol-docker TEXLIVE_IMAGE_USER: tex SANDBOXED_COMPILES: true SANDBOXED_COMPILES_HOST_DIR_COMPILES: $PWD/compiles diff --git a/services/clsi/docker-compose.yml b/services/clsi/docker-compose.yml index 1ea4549b20..e38ff70d75 100644 --- a/services/clsi/docker-compose.yml +++ b/services/clsi/docker-compose.yml @@ -55,7 +55,7 @@ services: PDF_CACHING_ENABLE_WORKER_POOL: true ALLOWED_IMAGES: quay.io/sharelatex/texlive-full:2017.1 quay.io/sharelatex/texlive-full:2025.1 quay.io/sharelatex/pandoc:3.9 quay.io/sharelatex/pdftocairo:24.02 TEXLIVE_IMAGE: quay.io/sharelatex/texlive-full:2025.1 - TEX_LIVE_IMAGE_NAME_OVERRIDE: us-east1-docker.pkg.dev/overleaf-ops/ol-docker + TEX_LIVE_DOCKER_IMAGE_ROOT: us-east1-docker.pkg.dev/overleaf-ops/ol-docker TEXLIVE_IMAGE_USER: tex SANDBOXED_COMPILES: true SANDBOXED_COMPILES_HOST_DIR_COMPILES: $PWD/compiles diff --git a/services/web/app/src/Features/Project/ProjectOptionsHandler.mjs b/services/web/app/src/Features/Project/ProjectOptionsHandler.mjs index 5a0d0bd768..d22b69ce20 100644 --- a/services/web/app/src/Features/Project/ProjectOptionsHandler.mjs +++ b/services/web/app/src/Features/Project/ProjectOptionsHandler.mjs @@ -45,7 +45,7 @@ const ProjectOptionsHandler = { if (!isAllowed) { throw new OError('invalid imageName', { imageName }) } - return settings.imageRoot + '/' + imageName + return imageName }, async setImageName(projectId, imageName) { diff --git a/services/web/modules/sandboxed-compiles/index.mjs b/services/web/modules/sandboxed-compiles/index.mjs index d494a3eec4..456b03aaa0 100644 --- a/services/web/modules/sandboxed-compiles/index.mjs +++ b/services/web/modules/sandboxed-compiles/index.mjs @@ -20,3 +20,6 @@ if (process.env.SANDBOXED_COMPILES === 'true') { } Settings.currentImageName = process.env.TEX_LIVE_DOCKER_IMAGE } + +const SandboxedCompilesModule = {} +export default SandboxedCompilesModule