Procházet zdrojové kódy

Merge pull request #16806 from overleaf/ii-compile-dir-readonly

[clsi] Use readOnly bind-mounts for synctex and wordcount containers

GitOrigin-RevId: 8de094350604544dba4571aa849ad41a4a4d88d8
ilkin-overleaf před 2 roky
rodič
revize
640ea9c916

+ 16 - 24
services/clsi/app/js/CompileManager.js

@@ -511,17 +511,12 @@ async function _runSynctex(projectId, userId, command, imageName) {
 async function wordcount(projectId, userId, filename, image) {
   logger.debug({ projectId, userId, filename, image }, 'running wordcount')
   const filePath = `$COMPILE_DIR/${filename}`
-  const command = [
-    'texcount',
-    '-nocol',
-    '-inc',
-    filePath,
-    `-out=${filePath}.wc`,
-  ]
+  const command = ['texcount', '-nocol', '-inc', filePath]
   const compileDir = getCompileDir(projectId, userId)
   const timeout = 60 * 1000
   const compileName = getCompileName(projectId, userId)
   const compileGroup = 'wordcount'
+
   try {
     await fsPromises.mkdir(compileDir, { recursive: true })
   } catch (err) {
@@ -531,22 +526,23 @@ async function wordcount(projectId, userId, filename, image) {
       filename,
     })
   }
-  await CommandRunner.promises.run(
-    compileName,
-    command,
-    compileDir,
-    image,
-    timeout,
-    {},
-    compileGroup
-  )
 
-  let stdout
   try {
-    stdout = await fsPromises.readFile(
-      compileDir + '/' + filename + '.wc',
-      'utf-8'
+    const { stdout } = await CommandRunner.promises.run(
+      compileName,
+      command,
+      compileDir,
+      image,
+      timeout,
+      {},
+      compileGroup
     )
+    const results = _parseWordcountFromOutput(stdout)
+    logger.debug(
+      { projectId, userId, wordcount: results },
+      'word count results'
+    )
+    return results
   } catch (err) {
     throw OError.tag(err, 'error reading word count output', {
       command,
@@ -555,10 +551,6 @@ async function wordcount(projectId, userId, filename, image) {
       userId,
     })
   }
-
-  const results = _parseWordcountFromOutput(stdout)
-  logger.debug({ projectId, userId, wordcount: results }, 'word count results')
-  return results
 }
 
 function _parseWordcountFromOutput(output) {

+ 4 - 0
services/clsi/app/js/DockerRunner.js

@@ -72,6 +72,10 @@ const DockerRunner = {
       image = `${Settings.texliveImageNameOveride}/${img[2]}`
     }
 
+    if (compileGroup === 'synctex' || compileGroup === 'wordcount') {
+      volumes[directory] += ':ro'
+    }
+
     const options = DockerRunner._getContainerOptions(
       command,
       image,

+ 10 - 13
services/clsi/test/unit/js/CompileManagerTests.js

@@ -85,7 +85,15 @@ describe('CompileManager', function () {
     }
     this.CommandRunner = {
       promises: {
-        run: sinon.stub().resolves({ stdout: this.commandOutput }),
+        run: sinon.stub().callsFake((_1, _2, _3, _4, _5, _6, compileGroup) => {
+          if (compileGroup === 'synctex') {
+            return Promise.resolve({ stdout: this.commandOutput })
+          } else {
+            return Promise.resolve({
+              stdout: 'Encoding: ascii\nWords in text: 2',
+            })
+          }
+        }),
       },
     }
     this.DraftModeManager = {
@@ -544,11 +552,6 @@ describe('CompileManager', function () {
 
   describe('wordcount', function () {
     beforeEach(async function () {
-      this.stdout = 'Encoding: ascii\nWords in text: 2'
-      this.fsPromises.readFile
-        .withArgs(Path.join(this.compileDir, 'main.tex.wc'))
-        .resolves(this.stdout)
-
       this.timeout = 60 * 1000
       this.filename = 'main.tex'
       this.image = 'example.com/image'
@@ -563,13 +566,7 @@ describe('CompileManager', function () {
 
     it('should run the texcount command', function () {
       this.filePath = `$COMPILE_DIR/${this.filename}`
-      this.command = [
-        'texcount',
-        '-nocol',
-        '-inc',
-        this.filePath,
-        `-out=${this.filePath}.wc`,
-      ]
+      this.command = ['texcount', '-nocol', '-inc', this.filePath]
 
       expect(this.CommandRunner.promises.run).to.have.been.calledWith(
         `${this.projectId}-${this.userId}`,