|
| 1 | +import { conatServer } from "@cocalc/backend/data"; |
| 2 | +import { join } from "node:path"; |
| 3 | + |
| 4 | +export function dataPath(HOME: string): string { |
| 5 | + return join(HOME, ".cache", "cocalc"); |
| 6 | +} |
| 7 | + |
| 8 | +// see also packages/project/secret-token.ts |
| 9 | +export function secretTokenPath(HOME: string) { |
| 10 | + const data = dataPath(HOME); |
| 11 | + return join(data, "secret-token"); |
| 12 | +} |
| 13 | + |
| 14 | +const ENV_VARS_DELETE = [ |
| 15 | + "PGDATA", |
| 16 | + "PGHOST", |
| 17 | + "PGUSER", |
| 18 | + "PGDATABASE", |
| 19 | + "PROJECTS", |
| 20 | + "BASE_PATH", |
| 21 | + "PORT", |
| 22 | + "DATA", |
| 23 | + "LOGS", |
| 24 | + "PWD", |
| 25 | + "LINES", |
| 26 | + "COLUMNS", |
| 27 | + "LS_COLORS", |
| 28 | + "INIT_CWD", |
| 29 | + "DEBUG_FILE", |
| 30 | + "SECRETS", |
| 31 | +] as const; |
| 32 | + |
| 33 | +function sanitizedEnv(env: { [key: string]: string | undefined }): { |
| 34 | + [key: string]: string; |
| 35 | +} { |
| 36 | + const env2 = { ...env }; |
| 37 | + // Remove some potentially confusing env variables |
| 38 | + for (const key of ENV_VARS_DELETE) { |
| 39 | + delete env2[key]; |
| 40 | + } |
| 41 | + // Comment about stripping things starting with /root: |
| 42 | + // These tend to creep in as npm changes, e.g., 'npm_config_userconfig' is |
| 43 | + // suddenly /root/.npmrc, and due to permissions this will break starting |
| 44 | + // projects with a mysterious "exit code 243" and no further info, which |
| 45 | + // is really hard to track down. |
| 46 | + for (const key in env2) { |
| 47 | + if ( |
| 48 | + key.startsWith("npm_") || |
| 49 | + key.startsWith("COCALC_") || |
| 50 | + key.startsWith("CONAT_") || |
| 51 | + key.startsWith("PNPM_") || |
| 52 | + key.startsWith("__NEXT") || |
| 53 | + key.startsWith("NODE_") || |
| 54 | + env2[key]?.startsWith("/root") || |
| 55 | + env2[key] == null |
| 56 | + ) { |
| 57 | + delete env2[key]; |
| 58 | + } |
| 59 | + } |
| 60 | + return env2 as { [key: string]: string }; |
| 61 | +} |
| 62 | + |
| 63 | +export function getEnvironment({ |
| 64 | + HOME, |
| 65 | + project_id, |
| 66 | + env: extra, |
| 67 | +}: { |
| 68 | + HOME: string; |
| 69 | + project_id: string; |
| 70 | + env?: { [key: string]: string }; |
| 71 | +}): { [key: string]: string } { |
| 72 | + const extra_env: string = Buffer.from(JSON.stringify(extra ?? {})).toString( |
| 73 | + "base64", |
| 74 | + ); |
| 75 | + |
| 76 | + // we only support "user" as the username here: |
| 77 | + const USER = "user"; |
| 78 | + const DATA = dataPath(HOME); |
| 79 | + |
| 80 | + return { |
| 81 | + ...sanitizedEnv(process.env), |
| 82 | + ...{ |
| 83 | + HOME, |
| 84 | + DATA, |
| 85 | + LOGS: DATA, |
| 86 | + // DEBUG: so interesting stuff gets logged, but not too much unless we really need it. |
| 87 | + DEBUG: "cocalc:*,-cocalc:silly:*", |
| 88 | + // important to explicitly set the COCALC_ vars since server env has own in a project |
| 89 | + COCALC_PROJECT_ID: project_id, |
| 90 | + COCALC_USERNAME: USER, |
| 91 | + USER, |
| 92 | + COCALC_EXTRA_ENV: extra_env, |
| 93 | + PATH: `${HOME}/bin:${HOME}/.local/bin:${process.env.PATH}`, |
| 94 | + CONAT_SERVER: conatServer, |
| 95 | + COCALC_SECRET_TOKEN: secretTokenPath(HOME), |
| 96 | + }, |
| 97 | + }; |
| 98 | +} |
0 commit comments