@vaharoni/devops 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -62,8 +62,9 @@ export declare class CommandExecutor {
62
62
  env?: object;
63
63
  }): number;
64
64
  /** Should be used for CLI commands intended to be used locally. Provides interactivity. Unlike exec(), stdout is not returned. */
65
- spawn({ env }?: {
66
- env?: {} | undefined;
65
+ spawn({ env, pipeStdoutTo }?: {
66
+ env?: object;
67
+ pipeStdoutTo?: "stderr";
67
68
  }): Promise<unknown>;
68
69
  _prepareFullCommand(): string;
69
70
  _getProcessEnv(envOverride?: {}): {
@@ -1 +1 @@
1
- {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/cli/common.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/cli/common.ts"],"names":[],"mappings":"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"}
@@ -144,17 +144,21 @@ export class CommandExecutor {
144
144
  }
145
145
  }
146
146
  /** Should be used for CLI commands intended to be used locally. Provides interactivity. Unlike exec(), stdout is not returned. */
147
- spawn({ env = {} } = {}) {
147
+ spawn({ env, pipeStdoutTo } = {}) {
148
148
  this._checkEnvYamlFiles();
149
149
  const fullCommand = this._prepareFullCommand();
150
150
  const envToUse = this._getProcessEnv(env);
151
+ const stdio = pipeStdoutTo === "stderr" ? ["inherit", "pipe", "inherit"] : "inherit";
151
152
  return new Promise((resolve) => {
152
153
  try {
153
154
  const childProcess = spawn(fullCommand, {
154
- stdio: "inherit",
155
+ stdio,
155
156
  env: envToUse,
156
157
  shell: true,
157
158
  });
159
+ if (pipeStdoutTo === "stderr") {
160
+ childProcess.stdout?.pipe(process.stderr);
161
+ }
158
162
  childProcess.on("close", (code) => {
159
163
  if (code !== 0) {
160
164
  console.error(chalk.red(`Process exited with code ${code}`));
@@ -1,6 +1,7 @@
1
1
  import { CLICommandParser } from "../common";
2
2
  declare function run(cmdObj: CLICommandParser): void;
3
- export declare const console: {
3
+ export declare const consoleCommand: {
4
+ command: string;
4
5
  oneLiner: string;
5
6
  keyExamples: string;
6
7
  run: typeof run;
@@ -1 +1 @@
1
- {"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../../src/cli/core/console.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,gBAAgB,EAAqB,MAAM,WAAW,CAAC;AAgBhE,iBAAS,GAAG,CAAC,MAAM,EAAE,gBAAgB,QAmBpC;AAED,eAAO,MAAM,OAAO;;;;CAAiC,CAAC"}
1
+ {"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../../src/cli/core/console.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAsC,MAAM,WAAW,CAAC;AAsBjF,iBAAS,GAAG,CAAC,MAAM,EAAE,gBAAgB,QA2BpC;AAMD,eAAO,MAAM,cAAc;;;;;CAAqD,CAAC"}
@@ -1,15 +1,21 @@
1
- import { getConst } from "../../libs/config";
2
- import { envToNamespace, imageDebugName, } from "../../libs/k8s-constants";
1
+ import { generateDebugPod } from "../../libs/k8s-generate";
3
2
  import { kubectlCommand } from "../../libs/k8s-helpers";
4
- import { CLICommandParser, printUsageAndExit } from "../common";
5
- const oneLiner = "Get a shell into the debug pod of an image";
3
+ import { getImageVersion } from "../../libs/k8s-image-config";
4
+ import { CLICommandParser, CommandExecutor, printUsageAndExit } from "../common";
5
+ import yaml from "yaml";
6
+ const oneLiner = "Spin up a debug pod of the specified image and get a shell into it.";
6
7
  const keyExamples = `
7
8
  $ devops console main-node
8
9
  `.trim();
9
10
  const usage = `
10
11
  ${oneLiner}
11
12
 
12
- Each image has a debug pod. This command gets a shell into the debug pod of the specified image.
13
+ USAGE
14
+ devops console <image> [--version <version>]
15
+
16
+ Options:
17
+ --version <version> The version (git SHA) of the image to use.
18
+ If not specified, the live version of the image (obtained using 'devops image version get <image>') is used.
13
19
 
14
20
  EXAMPLES
15
21
  ${keyExamples}
@@ -17,17 +23,28 @@ EXAMPLES
17
23
  function run(cmdObj) {
18
24
  if (cmdObj.help || cmdObj.args.length === 0)
19
25
  printUsageAndExit(usage);
20
- const image = cmdObj.args[0];
21
- const debugName = imageDebugName(image);
22
- const namespace = envToNamespace(cmdObj.env);
23
- const podName = cmdObj
24
- .executorFromEnv(kubectlCommand(`get pod -n ${namespace} -l app=${debugName} -o name`, {
25
- namespace,
26
- }), { quiet: true })
27
- .exec()
28
- .trim();
29
- cmdObj
30
- .executorFromEnv(kubectlCommand(`exec -it ${podName} -- /bin/bash`, { namespace }))
31
- .spawn();
26
+ const parsed = cmdObj.parseOptions({ params: ["--version"] });
27
+ if (parsed.args.length !== 1)
28
+ printUsageAndExit(usage);
29
+ const image = parsed.args[0];
30
+ const version = parsed.options["--version"];
31
+ const gitSha = version ?? getImageVersion(cmdObj.env, image);
32
+ if (!gitSha) {
33
+ console.error(`No git SHA found for image ${image} in environment ${cmdObj.env}`);
34
+ process.exit(1);
35
+ }
36
+ const debugYaml = generateDebugPod(cmdObj.env, image, gitSha);
37
+ if (!debugYaml) {
38
+ console.error(`The image ${image} does not specify debug-template in images.yaml`);
39
+ process.exit(1);
40
+ }
41
+ const userName = new CommandExecutor(`kubectl auth whoami -o jsonpath='{.status.userInfo.username}'`).exec();
42
+ const debugManifestsJson = JSON.stringify(yaml.parse(debugYaml));
43
+ const randomId = Math.random().toString(36).substring(2, 10);
44
+ const podName = ['ephemeral-console', slugify(userName), slugify(image), randomId].filter(Boolean).join('-');
45
+ new CommandExecutor(kubectlCommand(`run ${podName} --restart=Never --rm -it --image=overridden --overrides='${debugManifestsJson}'`, { monorepoEnv: cmdObj.env })).spawn();
46
+ }
47
+ function slugify(str, maxLength = 20) {
48
+ return str.toLowerCase().trim().replace(/[^a-zA-Z0-9]/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '').slice(0, maxLength);
32
49
  }
33
- export const console = { oneLiner, keyExamples, run };
50
+ export const consoleCommand = { command: 'console', oneLiner, keyExamples, run };
@@ -1,6 +1,6 @@
1
1
  import {} from "../../libs/k8s-image-config";
2
2
  import { CLICommandParser, printUsageAndExit, StrongParams } from "../common";
3
- import { generateDbMigrateJob, generateDebugDeployment, generateWorkspaceDeployment, ImageContextGenerator } from "../../libs/k8s-generate";
3
+ import { generateDbMigrateJob, generateDebugPod, generateWorkspaceDeployment, ImageContextGenerator } from "../../libs/k8s-generate";
4
4
  import chalk from "chalk";
5
5
  import { getWorkspace } from "../../libs/discovery";
6
6
  import { getWorkspaceImages } from "../../libs/discovery/images";
@@ -93,7 +93,7 @@ const handlers = {
93
93
  'debug': (opts) => {
94
94
  const image = opts.required('workspaceOrImage');
95
95
  console.warn(chalk.green(`\nThis is a sample of generated manifests for the debug image ${image}:\n`));
96
- console.log(generateDebugDeployment(opts.required('env'), image, 'dummy-sha'));
96
+ console.log(generateDebugPod(opts.required('env'), image, 'dummy-sha'));
97
97
  },
98
98
  },
99
99
  };
@@ -1 +1 @@
1
- {"version":3,"file":"cloudrun-helpers.d.ts","sourceRoot":"","sources":["../../src/libs/cloudrun-helpers.ts"],"names":[],"mappings":"AA0CA,wBAAsB,QAAQ,CAAC,KAAK,EAAE,MAAM,iBA0B3C;AAED,wBAAsB,MAAM,CAAC,EAC3B,KAAK,EACL,GAAG,EACH,GAAG,EACH,MAAM,EACN,UAAe,EACf,oBAA4B,EAC5B,GAAY,EACZ,MAAgB,EAChB,YAAgB,EAChB,YAAgB,EAChB,OAAe,EACf,SAAc,GACf,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,iBAsBA"}
1
+ {"version":3,"file":"cloudrun-helpers.d.ts","sourceRoot":"","sources":["../../src/libs/cloudrun-helpers.ts"],"names":[],"mappings":"AA0CA,wBAAsB,QAAQ,CAAC,KAAK,EAAE,MAAM,iBA2B3C;AAED,wBAAsB,MAAM,CAAC,EAC3B,KAAK,EACL,GAAG,EACH,GAAG,EACH,MAAM,EACN,UAAe,EACf,oBAA4B,EAC5B,GAAY,EACZ,MAAgB,EAChB,YAAgB,EAChB,YAAgB,EAChB,OAAe,EACf,SAAc,GACf,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,iBAsBA"}
@@ -44,18 +44,19 @@ export async function buildDev(image) {
44
44
  const sha = randomBytes(12).toString("hex");
45
45
  const buildDir = new CommandExecutor(`devops prep-build ${image}`, {
46
46
  env,
47
+ quiet: true
47
48
  }).exec().trim();
48
49
  const tag = containerRegistryRepoPath(image, env, sha);
49
50
  console.warn(`Building ${tag} from ${buildDir}`);
50
- await new CommandExecutor(`docker build --platform linux/amd64 -t ${tag} ${buildDir} --build-arg MONOREPO_ENV=${env}`, { env }).spawn();
51
+ await new CommandExecutor(`docker build --platform linux/amd64 -t ${tag} ${buildDir} --build-arg MONOREPO_ENV=${env}`, { env }).spawn({ pipeStdoutTo: "stderr" });
51
52
  console.warn(`Pushing ${tag}`);
52
- await new CommandExecutor(`docker push ${tag}`, { env }).spawn();
53
+ await new CommandExecutor(`docker push ${tag}`, { env }).spawn({ pipeStdoutTo: "stderr" });
53
54
  console.warn(`\n✅ Built and pushed ${tag}\n`);
54
55
  console.warn('Run "devops cloudrun deploy" next. For example:');
55
- console.warn(chalk.blue(`./devops cloudrun deploy ${image} ${sha} --env ${env} --allow-unauthenticated --region us-east1 --forward-env ENV1,ENV2 --service-account RUNTIME_SA`));
56
+ console.warn(chalk.blue(`./devops cloudrun deploy ${image} ${sha} --env ${env} --allow-unauthenticated --region us-east1 --forward-env ENV1,ENV2 -- --service-account RUNTIME_SA`));
56
57
  console.warn(chalk.yellow(`\n\nRUNTIME_SA is the name of the service account used to run the Cloud Run service.`));
57
58
  console.warn(chalk.yellow(`Find it with "gcloud iam service-accounts list"\n`));
58
- console.log(tag);
59
+ console.log(sha);
59
60
  }
60
61
  export async function deploy({ image, env, sha, region, forwardEnv = [], allowUnauthenticated = false, cpu = "0.25", memory = "256Mi", minInstances = 0, maxInstances = 1, timeout = "60s", extraArgs = "", }) {
61
62
  verifyCloudrunImage(image);
@@ -1,7 +1,7 @@
1
1
  import type { PackageData, TemplateDbMigrateObject, TemplateDebugObject, TemplateDeploymentObject, TemplateSharedContext } from "../types";
2
2
  export declare function generateImageDeployments(monorepoEnv: string, image: string, gitSha: string): string;
3
3
  export declare function generateWorkspaceDeployment(packageData: PackageData, monorepoEnv: string, image: string, gitSha: string): string;
4
- export declare function generateDebugDeployment(monorepoEnv: string, image: string, gitSha: string): string | undefined;
4
+ export declare function generateDebugPod(monorepoEnv: string, image: string, gitSha: string): string | undefined;
5
5
  export declare function generateDbMigrateJob(monorepoEnv: string, image: string, gitSha: string): string;
6
6
  export declare class ImageContextGenerator {
7
7
  monorepoEnv: string;
@@ -1 +1 @@
1
- {"version":3,"file":"k8s-generate.d.ts","sourceRoot":"","sources":["../../src/libs/k8s-generate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AA6B3I,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,UAcf;AAED,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAOvH;AAED,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,sBASf;AAED,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,UAOf;AA6FD,qBAAa,qBAAqB;IAIb,WAAW,EAAE,MAAM;IAAS,KAAK,EAAE,MAAM;IAAS,MAAM,EAAE,MAAM;IAHnF,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,YAAY,EAAE,IAAI,CAAC,qBAAqB,EAAE,cAAc,CAAC,CAAC;gBAEvC,WAAW,EAAE,MAAM,EAAS,KAAK,EAAE,MAAM,EAAS,MAAM,EAAE,MAAM;IAYnF,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,wBAAwB;IAmB7D,YAAY,IAAI,uBAAuB;IAOvC,QAAQ,IAAI,mBAAmB;CAMhC"}
1
+ {"version":3,"file":"k8s-generate.d.ts","sourceRoot":"","sources":["../../src/libs/k8s-generate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AA6B3I,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,UAaf;AAED,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAOvH;AAED,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,sBASf;AAED,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,UAOf;AA+FD,qBAAa,qBAAqB;IAIb,WAAW,EAAE,MAAM;IAAS,KAAK,EAAE,MAAM;IAAS,MAAM,EAAE,MAAM;IAHnF,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,YAAY,EAAE,IAAI,CAAC,qBAAqB,EAAE,cAAc,CAAC,CAAC;gBAEvC,WAAW,EAAE,MAAM,EAAS,KAAK,EAAE,MAAM,EAAS,MAAM,EAAE,MAAM;IAYnF,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,wBAAwB;IAmB7D,YAAY,IAAI,uBAAuB;IAOvC,QAAQ,IAAI,mBAAmB;CAMhC"}
@@ -30,8 +30,7 @@ export function generateImageDeployments(monorepoEnv, image, gitSha) {
30
30
  const renderFn = (template) => Handlebars.compile(template)(context);
31
31
  return generateManifestForDeployment(projectData.rootPath, projectData.deployment.template, renderFn);
32
32
  });
33
- const debug = generateDebugDeployment(monorepoEnv, image, gitSha);
34
- const manifest = [debug, ...apps].filter(Boolean).join("\n---\n");
33
+ const manifest = apps.filter(Boolean).join("\n---\n");
35
34
  return ensureProperDomainsPresent(manifest, monorepoEnv, image);
36
35
  }
37
36
  export function generateWorkspaceDeployment(packageData, monorepoEnv, image, gitSha) {
@@ -42,7 +41,7 @@ export function generateWorkspaceDeployment(packageData, monorepoEnv, image, git
42
41
  const manifest = generateManifestForDeployment(packageData.rootPath, packageData.deployment.template, renderFn).join("\n---\n");
43
42
  return ensureProperDomainsPresent(manifest, monorepoEnv, image);
44
43
  }
45
- export function generateDebugDeployment(monorepoEnv, image, gitSha) {
44
+ export function generateDebugPod(monorepoEnv, image, gitSha) {
46
45
  verifyNotCloudrunImage(image);
47
46
  const generator = new ImageContextGenerator(monorepoEnv, image, gitSha);
48
47
  const context = generator.getDebug();
@@ -50,7 +49,7 @@ export function generateDebugDeployment(monorepoEnv, image, gitSha) {
50
49
  const debugTemplate = getImageData(image)["debug-template"];
51
50
  if (!debugTemplate)
52
51
  return;
53
- return generateManifestsFromTemplateName(debugTemplate, renderFn).map(x => yaml.stringify(x)).join("\n---\n");
52
+ return generateManifestsFromTemplateName(debugTemplate, renderFn, { validate: false }).map(x => yaml.stringify(x)).join("\n---\n");
54
53
  }
55
54
  export function generateDbMigrateJob(monorepoEnv, image, gitSha) {
56
55
  verifyNotCloudrunImage(image);
@@ -79,13 +78,13 @@ function generateManifestForDeployment(rootPath, templateName, renderFn) {
79
78
  return Object.values(mergedTemplates).map(x => yaml.stringify(x));
80
79
  }
81
80
  // L2 generation
82
- function generateManifestsFromTemplateName(templateName, renderFn) {
81
+ function generateManifestsFromTemplateName(templateName, renderFn, options = { validate: true }) {
83
82
  const entries = manifestFilesForTemplate(templateName);
84
83
  if (!entries) {
85
84
  console.error(`No entries found for ${templateName} in ${MANIFEST_INDEX_FILE_PATH}`);
86
85
  process.exit(1);
87
86
  }
88
- return generateManifestsFromFileList(entries.map(entry => path.join(MANIFEST_FOLDER_PATH, entry)), renderFn);
87
+ return generateManifestsFromFileList(entries.map(entry => path.join(MANIFEST_FOLDER_PATH, entry)), renderFn, options);
89
88
  }
90
89
  // L2 generation
91
90
  function generateManifestFromFilesInFolder(folderPath, renderFn) {
@@ -97,19 +96,21 @@ function generateManifestFromFilesInFolder(folderPath, renderFn) {
97
96
  return generateManifestsFromFileList(files, renderFn);
98
97
  }
99
98
  // L3 generation
100
- function generateManifestsFromFileList(filesList, renderFn) {
99
+ function generateManifestsFromFileList(filesList, renderFn, options = { validate: true }) {
101
100
  return filesList.flatMap((filePath) => {
102
101
  try {
103
102
  const manifestFileStr = fs.readFileSync(filePath, 'utf8');
104
103
  const renderedStr = renderFn(manifestFileStr);
105
104
  const res = yaml.parseAllDocuments(renderedStr);
106
- res.forEach((doc) => {
107
- if (!doc.get("kind") || !doc.getIn(["metadata", "name"])) {
108
- console.error(`Invalid manifest file ${filePath}: kind and metadata.name must be present`);
109
- console.error(doc.toString());
110
- process.exit(1);
111
- }
112
- });
105
+ if (options.validate) {
106
+ res.forEach((doc) => {
107
+ if (!doc.get("kind") || !doc.getIn(["metadata", "name"])) {
108
+ console.error(`Invalid manifest file ${filePath}: kind and metadata.name must be present`);
109
+ console.error(doc.toString());
110
+ process.exit(1);
111
+ }
112
+ });
113
+ }
113
114
  return res.map(x => x.toJSON());
114
115
  }
115
116
  catch (e) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vaharoni/devops",
3
3
  "type": "module",
4
- "version": "1.2.0",
4
+ "version": "1.2.2",
5
5
  "description": "Devops utility",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
package/src/cli/common.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import chalk from "chalk";
2
- import { execSync, spawn } from "child_process";
2
+ import { execSync, spawn, type StdioOptions } from "child_process";
3
3
  import fs from "fs";
4
4
  import { globSync } from "glob";
5
5
  import { allSupportedEnvs } from "../libs/k8s-constants";
@@ -222,18 +222,23 @@ export class CommandExecutor {
222
222
  }
223
223
 
224
224
  /** Should be used for CLI commands intended to be used locally. Provides interactivity. Unlike exec(), stdout is not returned. */
225
- spawn({ env = {} } = {}) {
225
+ spawn({ env, pipeStdoutTo }: { env?: object; pipeStdoutTo?: "stderr" } = {}) {
226
226
  this._checkEnvYamlFiles();
227
227
  const fullCommand = this._prepareFullCommand();
228
228
  const envToUse = this._getProcessEnv(env);
229
+ const stdio: StdioOptions = pipeStdoutTo === "stderr" ? ["inherit", "pipe", "inherit"] : "inherit";
229
230
  return new Promise((resolve) => {
230
231
  try {
231
232
  const childProcess = spawn(fullCommand, {
232
- stdio: "inherit",
233
+ stdio,
233
234
  env: envToUse,
234
235
  shell: true,
235
236
  });
236
237
 
238
+ if (pipeStdoutTo === "stderr") {
239
+ childProcess.stdout?.pipe(process.stderr);
240
+ }
241
+
237
242
  childProcess.on("close", (code) => {
238
243
  if (code !== 0) {
239
244
  console.error(chalk.red(`Process exited with code ${code}`));
@@ -1,12 +1,10 @@
1
- import { getConst } from "../../libs/config";
2
- import {
3
- envToNamespace,
4
- imageDebugName,
5
- } from "../../libs/k8s-constants";
1
+ import { generateDebugPod } from "../../libs/k8s-generate";
6
2
  import { kubectlCommand } from "../../libs/k8s-helpers";
7
- import { CLICommandParser, printUsageAndExit } from "../common";
3
+ import { getImageVersion } from "../../libs/k8s-image-config";
4
+ import { CLICommandParser, CommandExecutor, printUsageAndExit } from "../common";
5
+ import yaml from "yaml";
8
6
 
9
- const oneLiner = "Get a shell into the debug pod of an image";
7
+ const oneLiner = "Spin up a debug pod of the specified image and get a shell into it.";
10
8
  const keyExamples = `
11
9
  $ devops console main-node
12
10
  `.trim();
@@ -14,7 +12,12 @@ $ devops console main-node
14
12
  const usage = `
15
13
  ${oneLiner}
16
14
 
17
- Each image has a debug pod. This command gets a shell into the debug pod of the specified image.
15
+ USAGE
16
+ devops console <image> [--version <version>]
17
+
18
+ Options:
19
+ --version <version> The version (git SHA) of the image to use.
20
+ If not specified, the live version of the image (obtained using 'devops image version get <image>') is used.
18
21
 
19
22
  EXAMPLES
20
23
  ${keyExamples}
@@ -22,23 +25,35 @@ EXAMPLES
22
25
 
23
26
  function run(cmdObj: CLICommandParser) {
24
27
  if (cmdObj.help || cmdObj.args.length === 0) printUsageAndExit(usage);
25
- const image = cmdObj.args[0];
26
- const debugName = imageDebugName(image);
27
- const namespace = envToNamespace(cmdObj.env);
28
- const podName = cmdObj
29
- .executorFromEnv(
30
- kubectlCommand(`get pod -n ${namespace} -l app=${debugName} -o name`, {
31
- namespace,
32
- }),
33
- { quiet: true }
34
- )
35
- .exec()
36
- .trim();
37
- cmdObj
38
- .executorFromEnv(
39
- kubectlCommand(`exec -it ${podName} -- /bin/bash`, { namespace })
40
- )
41
- .spawn();
28
+ const parsed = cmdObj.parseOptions({ params: ["--version"] });
29
+ if (parsed.args.length !== 1) printUsageAndExit(usage);
30
+ const image = parsed.args[0];
31
+ const version = parsed.options["--version"];
32
+
33
+ const gitSha = version ?? getImageVersion(cmdObj.env, image);
34
+ if (!gitSha) {
35
+ console.error(`No git SHA found for image ${image} in environment ${cmdObj.env}`);
36
+ process.exit(1);
37
+ }
38
+ const debugYaml = generateDebugPod(cmdObj.env, image, gitSha);
39
+ if (!debugYaml) {
40
+ console.error(`The image ${image} does not specify debug-template in images.yaml`);
41
+ process.exit(1);
42
+ }
43
+
44
+ const userName = new CommandExecutor(`kubectl auth whoami -o jsonpath='{.status.userInfo.username}'`).exec();
45
+
46
+ const debugManifestsJson = JSON.stringify(yaml.parse(debugYaml));
47
+ const randomId = Math.random().toString(36).substring(2, 10);
48
+ const podName = ['ephemeral-console', slugify(userName), slugify(image), randomId].filter(Boolean).join('-');
49
+
50
+ new CommandExecutor(kubectlCommand(
51
+ `run ${podName} --restart=Never --rm -it --image=overridden --overrides='${debugManifestsJson}'`, { monorepoEnv: cmdObj.env })
52
+ ).spawn();
53
+ }
54
+
55
+ function slugify(str: string, maxLength = 20) {
56
+ return str.toLowerCase().trim().replace(/[^a-zA-Z0-9]/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '').slice(0, maxLength);
42
57
  }
43
58
 
44
- export const console = { oneLiner, keyExamples, run };
59
+ export const consoleCommand = { command: 'console', oneLiner, keyExamples, run };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  } from "../../libs/k8s-image-config";
3
3
  import { CLICommandParser, printUsageAndExit, StrongParams } from "../common";
4
- import { generateDbMigrateJob, generateDebugDeployment, generateWorkspaceDeployment, ImageContextGenerator } from "../../libs/k8s-generate";
4
+ import { generateDbMigrateJob, generateDebugPod, generateWorkspaceDeployment, ImageContextGenerator } from "../../libs/k8s-generate";
5
5
  import chalk from "chalk";
6
6
  import { getWorkspace } from "../../libs/discovery";
7
7
  import { getWorkspaceImages } from "../../libs/discovery/images";
@@ -130,7 +130,7 @@ const handlers = {
130
130
  const image = opts.required('workspaceOrImage');
131
131
  console.warn(chalk.green(`\nThis is a sample of generated manifests for the debug image ${image}:\n`))
132
132
  console.log(
133
- generateDebugDeployment(
133
+ generateDebugPod(
134
134
  opts.required('env'),
135
135
  image,
136
136
  'dummy-sha'
@@ -46,7 +46,8 @@ export async function buildDev(image: string) {
46
46
  const sha = randomBytes(12).toString("hex");
47
47
 
48
48
  const buildDir = new CommandExecutor(`devops prep-build ${image}`, {
49
- env,
49
+ env,
50
+ quiet: true
50
51
  }).exec().trim();
51
52
 
52
53
  const tag = containerRegistryRepoPath(image, env, sha);
@@ -55,17 +56,17 @@ export async function buildDev(image: string) {
55
56
  await new CommandExecutor(
56
57
  `docker build --platform linux/amd64 -t ${tag} ${buildDir} --build-arg MONOREPO_ENV=${env}`,
57
58
  { env }
58
- ).spawn();
59
+ ).spawn({ pipeStdoutTo: "stderr" });
59
60
 
60
61
  console.warn(`Pushing ${tag}`);
61
- await new CommandExecutor(`docker push ${tag}`, { env }).spawn();
62
+ await new CommandExecutor(`docker push ${tag}`, { env }).spawn({ pipeStdoutTo: "stderr" });
62
63
 
63
64
  console.warn(`\n✅ Built and pushed ${tag}\n`);
64
65
  console.warn('Run "devops cloudrun deploy" next. For example:')
65
- console.warn(chalk.blue(`./devops cloudrun deploy ${image} ${sha} --env ${env} --allow-unauthenticated --region us-east1 --forward-env ENV1,ENV2 --service-account RUNTIME_SA`));
66
+ console.warn(chalk.blue(`./devops cloudrun deploy ${image} ${sha} --env ${env} --allow-unauthenticated --region us-east1 --forward-env ENV1,ENV2 -- --service-account RUNTIME_SA`));
66
67
  console.warn(chalk.yellow(`\n\nRUNTIME_SA is the name of the service account used to run the Cloud Run service.`));
67
68
  console.warn(chalk.yellow(`Find it with "gcloud iam service-accounts list"\n`));
68
- console.log(tag);
69
+ console.log(sha);
69
70
  }
70
71
 
71
72
  export async function deploy({
@@ -41,8 +41,7 @@ export function generateImageDeployments(
41
41
  const renderFn = (template: string) => Handlebars.compile(template)(context);
42
42
  return generateManifestForDeployment(projectData.rootPath, projectData.deployment!.template, renderFn);
43
43
  });
44
- const debug = generateDebugDeployment(monorepoEnv, image, gitSha);
45
- const manifest = [debug, ...apps].filter(Boolean).join("\n---\n");
44
+ const manifest = apps.filter(Boolean).join("\n---\n");
46
45
  return ensureProperDomainsPresent(manifest, monorepoEnv, image);
47
46
  }
48
47
 
@@ -55,7 +54,7 @@ export function generateWorkspaceDeployment(packageData: PackageData, monorepoEn
55
54
  return ensureProperDomainsPresent(manifest, monorepoEnv, image);
56
55
  }
57
56
 
58
- export function generateDebugDeployment(
57
+ export function generateDebugPod(
59
58
  monorepoEnv: string,
60
59
  image: string,
61
60
  gitSha: string
@@ -66,7 +65,7 @@ export function generateDebugDeployment(
66
65
  const renderFn = (template: string) => Handlebars.compile(template)(context);
67
66
  const debugTemplate = getImageData(image)["debug-template"];
68
67
  if (!debugTemplate) return;
69
- return generateManifestsFromTemplateName(debugTemplate, renderFn).map(x => yaml.stringify(x)).join("\n---\n");
68
+ return generateManifestsFromTemplateName(debugTemplate, renderFn, { validate: false }).map(x => yaml.stringify(x)).join("\n---\n");
70
69
  }
71
70
 
72
71
  export function generateDbMigrateJob(
@@ -107,13 +106,13 @@ function generateManifestForDeployment(rootPath: string, templateName: string, r
107
106
 
108
107
  // L2 generation
109
108
 
110
- function generateManifestsFromTemplateName(templateName: string, renderFn: RenderFn): object[] {
109
+ function generateManifestsFromTemplateName(templateName: string, renderFn: RenderFn, options: { validate: boolean } = { validate: true }): object[] {
111
110
  const entries = manifestFilesForTemplate(templateName);
112
111
  if (!entries) {
113
112
  console.error(`No entries found for ${templateName} in ${MANIFEST_INDEX_FILE_PATH}`);
114
113
  process.exit(1);
115
114
  }
116
- return generateManifestsFromFileList(entries.map(entry => path.join(MANIFEST_FOLDER_PATH, entry)), renderFn);
115
+ return generateManifestsFromFileList(entries.map(entry => path.join(MANIFEST_FOLDER_PATH, entry)), renderFn, options);
117
116
  }
118
117
 
119
118
  // L2 generation
@@ -129,19 +128,21 @@ function generateManifestFromFilesInFolder(folderPath: string, renderFn: RenderF
129
128
 
130
129
  // L3 generation
131
130
 
132
- function generateManifestsFromFileList(filesList: string[], renderFn: RenderFn): object[] {
131
+ function generateManifestsFromFileList(filesList: string[], renderFn: RenderFn, options: { validate: boolean } = { validate: true }): object[] {
133
132
  return filesList.flatMap((filePath) => {
134
133
  try {
135
134
  const manifestFileStr = fs.readFileSync(filePath, 'utf8');
136
135
  const renderedStr = renderFn(manifestFileStr);
137
136
  const res = yaml.parseAllDocuments(renderedStr);
138
- res.forEach((doc) => {
139
- if (!doc.get("kind") || !doc.getIn(["metadata", "name"])) {
140
- console.error(`Invalid manifest file ${filePath}: kind and metadata.name must be present`);
141
- console.error(doc.toString())
142
- process.exit(1);
143
- }
144
- })
137
+ if (options.validate) {
138
+ res.forEach((doc) => {
139
+ if (!doc.get("kind") || !doc.getIn(["metadata", "name"])) {
140
+ console.error(`Invalid manifest file ${filePath}: kind and metadata.name must be present`);
141
+ console.error(doc.toString())
142
+ process.exit(1);
143
+ }
144
+ })
145
+ }
145
146
  return res.map(x => x.toJSON());
146
147
  } catch (e) {
147
148
  if (e instanceof Error) {
@@ -1,45 +1,42 @@
1
- apiVersion: apps/v1
2
- kind: Deployment
1
+ apiVersion: v1
2
+ kind: Pod
3
3
  metadata:
4
+ # Name and namespace should not be stated - they are provided by the runner
4
5
  labels:
5
6
  app: {{debug_pod_name}}
6
7
  env: {{monorepo_env}}
7
- name: {{debug_pod_name}}
8
- namespace: {{namespace}}
8
+ ephemeral-shell: "true"
9
9
  spec:
10
- selector:
11
- matchLabels:
12
- app: {{debug_pod_name}}
13
- template:
14
- metadata:
15
- labels:
16
- app: {{debug_pod_name}}
17
- env: {{monorepo_env}}
18
- spec:
19
- volumes:
10
+ volumes:
11
+ - name: secret-injection-hook
12
+ secret:
13
+ secretName: {{env_secret_name}}
14
+ containers:
15
+ - image: {{image_path}}
16
+ name: {{debug_pod_name}}
17
+ stdin: true
18
+ tty: true
19
+ command:
20
+ - ./node-exec.sh
21
+ args:
22
+ - /bin/bash
23
+ env:
24
+ - name: MONOREPO_ENV
25
+ value: {{monorepo_env}}
26
+ - name: MONOREPO_NAMESPACE
27
+ value: {{namespace}}
28
+ - name: IS_KUBERNETES
29
+ value: 'true'
30
+ - name: MONOREPO_BASE_SECRET
31
+ valueFrom:
32
+ secretKeyRef:
33
+ name: {{env_secret_name}}
34
+ key: {{env_base_secret_key}}
35
+ volumeMounts:
20
36
  - name: secret-injection-hook
21
- secret:
22
- secretName: {{env_secret_name}}
23
- containers:
24
- - image: {{image_path}}
25
- name: {{debug_pod_name}}
26
- env:
27
- - name: MONOREPO_ENV
28
- value: {{monorepo_env}}
29
- - name: MONOREPO_NAMESPACE
30
- value: {{namespace}}
31
- - name: IS_KUBERNETES
32
- value: 'true'
33
- - name: MONOREPO_BASE_SECRET
34
- valueFrom:
35
- secretKeyRef:
36
- name: {{env_secret_name}}
37
- key: {{env_base_secret_key}}
38
- volumeMounts:
39
- - name: secret-injection-hook
40
- mountPath: /etc/kubernetes/secrets
41
- readOnly: true
42
- resources:
43
- requests:
44
- memory: 250Mi
45
- cpu: 100m
37
+ mountPath: /etc/kubernetes/secrets
38
+ readOnly: true
39
+ resources:
40
+ requests:
41
+ memory: 250Mi
42
+ cpu: 100m