settings.defaults.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. const Path = require('path')
  2. module.exports = {
  3. compileSizeLimit: process.env.COMPILE_SIZE_LIMIT || '7mb',
  4. processLifespanLimitMs:
  5. parseInt(process.env.PROCESS_LIFE_SPAN_LIMIT_MS) || 60 * 60 * 24 * 1000 * 2,
  6. catchErrors: process.env.CATCH_ERRORS === 'true',
  7. path: {
  8. compilesDir:
  9. process.env.CLSI_COMPILES_PATH || Path.resolve(__dirname, '../compiles'),
  10. outputDir:
  11. process.env.CLSI_OUTPUT_PATH || Path.resolve(__dirname, '../output'),
  12. clsiCacheDir:
  13. process.env.CLSI_CACHE_PATH || Path.resolve(__dirname, '../cache'),
  14. synctexBaseDir(projectId) {
  15. return Path.join(this.compilesDir, projectId)
  16. },
  17. },
  18. internal: {
  19. clsi: {
  20. port: 3013,
  21. host: process.env.LISTEN_ADDRESS || 'localhost',
  22. },
  23. load_balancer_agent: {
  24. report_load: true,
  25. load_port: 3048,
  26. local_port: 3049,
  27. },
  28. },
  29. apis: {
  30. clsi: {
  31. // Internal requests (used by tests only at the time of writing).
  32. url: `http://${process.env.CLSI_HOST || 'localhost'}:3013`,
  33. // External url prefix for output files, e.g. for requests via load-balancers.
  34. outputUrlPrefix: `${process.env.ZONE ? `/zone/${process.env.ZONE}` : ''}`,
  35. },
  36. clsiPerf: {
  37. host: `${process.env.CLSI_PERF_HOST || 'localhost'}:${
  38. process.env.CLSI_PERF_PORT || '3043'
  39. }`,
  40. },
  41. },
  42. smokeTest: process.env.SMOKE_TEST || false,
  43. project_cache_length_ms: 1000 * 60 * 60 * 24,
  44. parallelFileDownloads: process.env.FILESTORE_PARALLEL_FILE_DOWNLOADS || 1,
  45. filestoreDomainOveride: process.env.FILESTORE_DOMAIN_OVERRIDE,
  46. texliveImageNameOveride: process.env.TEX_LIVE_IMAGE_NAME_OVERRIDE,
  47. texliveOpenoutAny: process.env.TEXLIVE_OPENOUT_ANY,
  48. texliveMaxPrintLine: process.env.TEXLIVE_MAX_PRINT_LINE,
  49. sentry: {
  50. dsn: process.env.SENTRY_DSN,
  51. },
  52. enablePdfCaching: process.env.ENABLE_PDF_CACHING === 'true',
  53. enablePdfCachingDark: process.env.ENABLE_PDF_CACHING_DARK === 'true',
  54. pdfCachingMinChunkSize:
  55. parseInt(process.env.PDF_CACHING_MIN_CHUNK_SIZE, 10) || 1024,
  56. pdfCachingMaxProcessingTime:
  57. parseInt(process.env.PDF_CACHING_MAX_PROCESSING_TIME, 10) || 10 * 1000,
  58. pdfCachingEnableWorkerPool:
  59. process.env.PDF_CACHING_ENABLE_WORKER_POOL === 'true',
  60. pdfCachingWorkerPoolSize:
  61. parseInt(process.env.PDF_CACHING_WORKER_POOL_SIZE, 10) || 4,
  62. pdfCachingWorkerPoolBackLogLimit:
  63. parseInt(process.env.PDF_CACHING_WORKER_POOL_BACK_LOG_LIMIT, 10) || 40,
  64. }
  65. if (process.env.ALLOWED_COMPILE_GROUPS) {
  66. try {
  67. module.exports.allowedCompileGroups =
  68. process.env.ALLOWED_COMPILE_GROUPS.split(' ')
  69. } catch (error) {
  70. console.error(error, 'could not apply allowed compile group setting')
  71. process.exit(1)
  72. }
  73. }
  74. if (process.env.DOCKER_RUNNER) {
  75. let seccompProfilePath
  76. module.exports.clsi = {
  77. dockerRunner: process.env.DOCKER_RUNNER === 'true',
  78. docker: {
  79. runtime: process.env.DOCKER_RUNTIME,
  80. image:
  81. process.env.TEXLIVE_IMAGE || 'quay.io/sharelatex/texlive-full:2017.1',
  82. env: {
  83. HOME: '/tmp',
  84. CLSI: 1,
  85. },
  86. socketPath: '/var/run/docker.sock',
  87. user: process.env.TEXLIVE_IMAGE_USER || 'tex',
  88. },
  89. optimiseInDocker: true,
  90. expireProjectAfterIdleMs: 24 * 60 * 60 * 1000,
  91. checkProjectsIntervalMs: 10 * 60 * 1000,
  92. }
  93. try {
  94. // Override individual docker settings using path-based keys, e.g.:
  95. // compileGroupDockerConfigs = {
  96. // priority: { 'HostConfig.CpuShares': 100 }
  97. // beta: { 'dotted.path.here', 'value'}
  98. // }
  99. const compileGroupConfig = JSON.parse(
  100. process.env.COMPILE_GROUP_DOCKER_CONFIGS || '{}'
  101. )
  102. // Automatically clean up wordcount and synctex containers
  103. const defaultCompileGroupConfig = {
  104. wordcount: { 'HostConfig.AutoRemove': true },
  105. synctex: { 'HostConfig.AutoRemove': true },
  106. }
  107. module.exports.clsi.docker.compileGroupConfig = Object.assign(
  108. defaultCompileGroupConfig,
  109. compileGroupConfig
  110. )
  111. } catch (error) {
  112. console.error(error, 'could not apply compile group docker configs')
  113. process.exit(1)
  114. }
  115. try {
  116. seccompProfilePath = Path.resolve(__dirname, '../seccomp/clsi-profile.json')
  117. module.exports.clsi.docker.seccomp_profile = JSON.stringify(
  118. JSON.parse(require('fs').readFileSync(seccompProfilePath))
  119. )
  120. } catch (error) {
  121. console.error(
  122. error,
  123. `could not load seccomp profile from ${seccompProfilePath}`
  124. )
  125. process.exit(1)
  126. }
  127. if (process.env.APPARMOR_PROFILE) {
  128. try {
  129. module.exports.clsi.docker.apparmor_profile = process.env.APPARMOR_PROFILE
  130. } catch (error) {
  131. console.error(error, 'could not apply apparmor profile setting')
  132. process.exit(1)
  133. }
  134. }
  135. if (process.env.ALLOWED_IMAGES) {
  136. try {
  137. module.exports.clsi.docker.allowedImages =
  138. process.env.ALLOWED_IMAGES.split(' ')
  139. } catch (error) {
  140. console.error(error, 'could not apply allowed images setting')
  141. process.exit(1)
  142. }
  143. }
  144. module.exports.path.synctexBaseDir = () => '/compile'
  145. module.exports.path.sandboxedCompilesHostDir = process.env.COMPILES_HOST_DIR
  146. module.exports.path.synctexBinHostPath = process.env.SYNCTEX_BIN_HOST_PATH
  147. }