@certik/skynet 0.22.1 → 0.22.3

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.
Files changed (101) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/build.ts +23 -0
  3. package/dist/abi.d.ts +1 -2
  4. package/dist/abi.js +569 -563
  5. package/dist/address.d.ts +0 -1
  6. package/dist/address.js +22 -21
  7. package/dist/api.d.ts +0 -1
  8. package/dist/api.js +235 -120
  9. package/dist/app.d.ts +1 -2
  10. package/dist/app.js +2030 -276
  11. package/dist/availability.d.ts +0 -1
  12. package/dist/availability.js +126 -56
  13. package/dist/cli.d.ts +0 -1
  14. package/dist/cli.js +28 -24
  15. package/dist/const.d.ts +0 -1
  16. package/dist/const.js +153 -132
  17. package/dist/databricks.d.ts +0 -1
  18. package/dist/databricks.js +198 -58
  19. package/dist/date.d.ts +0 -1
  20. package/dist/date.js +48 -21
  21. package/dist/deploy.d.ts +0 -1
  22. package/dist/deploy.js +427 -292
  23. package/dist/dynamodb.d.ts +3 -4
  24. package/dist/dynamodb.js +432 -281
  25. package/dist/env.d.ts +2 -3
  26. package/dist/env.js +16 -9
  27. package/dist/graphql.d.ts +0 -1
  28. package/dist/graphql.js +26 -23
  29. package/dist/indexer.d.ts +0 -1
  30. package/dist/indexer.js +1050 -441
  31. package/dist/log.d.ts +0 -1
  32. package/dist/log.js +53 -52
  33. package/dist/object-hash.d.ts +0 -1
  34. package/dist/object-hash.js +49 -59
  35. package/dist/opsgenie.d.ts +97 -19
  36. package/dist/opsgenie.js +35 -30
  37. package/dist/por.d.ts +0 -1
  38. package/dist/por.js +113 -123
  39. package/dist/s3.d.ts +7 -8
  40. package/dist/s3.js +103 -91
  41. package/dist/search.d.ts +0 -1
  42. package/dist/search.js +100 -25
  43. package/dist/selector.d.ts +0 -1
  44. package/dist/selector.js +34 -38
  45. package/dist/slack.d.ts +0 -1
  46. package/dist/slack.js +27 -21
  47. package/dist/util.d.ts +0 -1
  48. package/dist/util.js +21 -20
  49. package/examples/api.ts +1 -1
  50. package/examples/indexer.ts +1 -1
  51. package/examples/mode-indexer.ts +1 -1
  52. package/package.json +4 -3
  53. package/{graphql.ts → src/graphql.ts} +1 -1
  54. package/src/opsgenie.ts +176 -0
  55. package/tsconfig.build.json +2 -5
  56. package/tsconfig.json +11 -20
  57. package/dist/abi.d.ts.map +0 -1
  58. package/dist/address.d.ts.map +0 -1
  59. package/dist/api.d.ts.map +0 -1
  60. package/dist/app.d.ts.map +0 -1
  61. package/dist/availability.d.ts.map +0 -1
  62. package/dist/cli.d.ts.map +0 -1
  63. package/dist/const.d.ts.map +0 -1
  64. package/dist/databricks.d.ts.map +0 -1
  65. package/dist/date.d.ts.map +0 -1
  66. package/dist/deploy.d.ts.map +0 -1
  67. package/dist/dynamodb.d.ts.map +0 -1
  68. package/dist/env.d.ts.map +0 -1
  69. package/dist/graphql.d.ts.map +0 -1
  70. package/dist/indexer.d.ts.map +0 -1
  71. package/dist/log.d.ts.map +0 -1
  72. package/dist/object-hash.d.ts.map +0 -1
  73. package/dist/opsgenie.d.ts.map +0 -1
  74. package/dist/por.d.ts.map +0 -1
  75. package/dist/s3.d.ts.map +0 -1
  76. package/dist/search.d.ts.map +0 -1
  77. package/dist/selector.d.ts.map +0 -1
  78. package/dist/slack.d.ts.map +0 -1
  79. package/dist/util.d.ts.map +0 -1
  80. package/opsgenie.ts +0 -69
  81. /package/{abi.ts → src/abi.ts} +0 -0
  82. /package/{address.ts → src/address.ts} +0 -0
  83. /package/{api.ts → src/api.ts} +0 -0
  84. /package/{app.ts → src/app.ts} +0 -0
  85. /package/{availability.ts → src/availability.ts} +0 -0
  86. /package/{cli.ts → src/cli.ts} +0 -0
  87. /package/{const.ts → src/const.ts} +0 -0
  88. /package/{databricks.ts → src/databricks.ts} +0 -0
  89. /package/{date.ts → src/date.ts} +0 -0
  90. /package/{deploy.ts → src/deploy.ts} +0 -0
  91. /package/{dynamodb.ts → src/dynamodb.ts} +0 -0
  92. /package/{env.ts → src/env.ts} +0 -0
  93. /package/{indexer.ts → src/indexer.ts} +0 -0
  94. /package/{log.ts → src/log.ts} +0 -0
  95. /package/{object-hash.ts → src/object-hash.ts} +0 -0
  96. /package/{por.ts → src/por.ts} +0 -0
  97. /package/{s3.ts → src/s3.ts} +0 -0
  98. /package/{search.ts → src/search.ts} +0 -0
  99. /package/{selector.ts → src/selector.ts} +0 -0
  100. /package/{slack.ts → src/slack.ts} +0 -0
  101. /package/{util.ts → src/util.ts} +0 -0
package/dist/deploy.js CHANGED
@@ -1,36 +1,139 @@
1
- import fs from "fs/promises";
1
+ // src/env.ts
2
+ function ensureAndGet(envName, defaultValue) {
3
+ return process.env[envName] || defaultValue;
4
+ }
5
+ function getEnvironment() {
6
+ return ensureAndGet("SKYNET_ENVIRONMENT", "dev");
7
+ }
8
+ function getEnvOrThrow(envName) {
9
+ if (!process.env[envName]) {
10
+ throw new Error(`Must set environment variable ${envName}`);
11
+ }
12
+ return process.env[envName];
13
+ }
14
+ function isProduction() {
15
+ return getEnvironment() === "prd";
16
+ }
17
+ function isDev() {
18
+ return getEnvironment() === "dev";
19
+ }
20
+ // src/selector.ts
21
+ function getSelectorDesc(selector) {
22
+ return Object.keys(selector).map((name) => {
23
+ return ` --${name.padEnd(14)}${selector[name].desc || selector[name].description || ""}`;
24
+ }).join(`
25
+ `);
26
+ }
27
+ function getSelectorFlags(selector) {
28
+ return Object.keys(selector).reduce((acc, name) => {
29
+ const flag = {
30
+ type: selector[name].type || "string",
31
+ ...selector[name]
32
+ };
33
+ if (!selector[name].optional && selector[name].isRequired !== false) {
34
+ flag.isRequired = true;
35
+ }
36
+ return { ...acc, [name]: flag };
37
+ }, {});
38
+ }
39
+ function toSelectorString(selectorFlags, delim = ",") {
40
+ return Object.keys(selectorFlags).sort().map((flag) => {
41
+ return `${flag}=${selectorFlags[flag]}`;
42
+ }).join(delim);
43
+ }
44
+ function normalizeSelectorValue(v) {
45
+ return v.replace(/[^A-Za-z0-9]+/g, "-");
46
+ }
47
+ function getJobName(name, selectorFlags, mode) {
48
+ const selectorNamePart = Object.keys(selectorFlags).sort().map((name2) => selectorFlags[name2]).join("-");
49
+ let jobName = name;
50
+ if (mode) {
51
+ jobName += `-${mode}`;
52
+ }
53
+ if (selectorNamePart.length > 0) {
54
+ jobName += `-${normalizeSelectorValue(selectorNamePart)}`;
55
+ }
56
+ return jobName;
57
+ }
58
+ // src/cli.ts
59
+ import path from "path";
60
+ import fs from "fs";
61
+ function getBinaryName() {
62
+ const binaryNameParts = process.argv[1].split(path.sep);
63
+ const binaryName = binaryNameParts[binaryNameParts.length - 1];
64
+ return binaryName;
65
+ }
66
+ function detectSkynetDirectory() {
67
+ return detectDirectory(process.argv[1], "SkynetAPIDefinitions.yml");
68
+ }
69
+ function detectWorkingDirectory() {
70
+ const wd = detectDirectory(process.argv[1], "package.json");
71
+ const skynetd = detectDirectory(process.argv[1], "SkynetAPIDefinitions.yml");
72
+ return wd.slice(skynetd.length + path.sep.length).replace(path.sep, "/");
73
+ }
74
+ function detectDirectory(fullBinPath, sentinel = "package.json") {
75
+ let parentFolder = path.dirname(fullBinPath);
76
+ while (parentFolder) {
77
+ const sentinelPath = path.join(parentFolder, sentinel);
78
+ if (fs.existsSync(sentinelPath)) {
79
+ return parentFolder;
80
+ }
81
+ const newParentFolder = path.dirname(parentFolder);
82
+ if (newParentFolder === parentFolder) {
83
+ break;
84
+ }
85
+ parentFolder = newParentFolder;
86
+ }
87
+ throw new Error("Cannot detect current working directory");
88
+ }
89
+ function detectBin() {
90
+ const wd = detectDirectory(process.argv[1], "package.json");
91
+ return process.argv[1].slice(wd.length + path.sep.length).replace(path.sep, "/");
92
+ }
93
+ // src/deploy.ts
94
+ import fs2 from "fs/promises";
2
95
  import fso from "fs";
3
96
  import { execa } from "execa";
4
97
  import meow from "meow";
5
98
  import chalk from "chalk";
6
99
  import which from "which";
7
- import { getJobName, getSelectorDesc, getSelectorFlags } from "./selector";
8
- import { getEnvOrThrow } from "./env";
9
- import { getBinaryName, detectSkynetDirectory } from "./cli";
10
- const INTERVAL_ALIASES = {
11
- secondly: "*/1 * * * * * *",
12
- "@secondly": "*/1 * * * * * *",
13
- minutely: "0 * * * * * *",
14
- "@minutely": "0 * * * * * *",
15
- hourly: "0 0 * * * * *",
16
- "@hourly": "0 0 * * * * *",
17
- daily: "0 0 0 * * * *",
18
- "@daily": "0 0 0 * * * *",
19
- weekly: "0 0 0 * * 0 *",
20
- "@weekly": "0 0 0 * * 0 *",
100
+ var INTERVAL_ALIASES = {
101
+ secondly: "*/1 * * * * * *",
102
+ "@secondly": "*/1 * * * * * *",
103
+ minutely: "0 * * * * * *",
104
+ "@minutely": "0 * * * * * *",
105
+ hourly: "0 0 * * * * *",
106
+ "@hourly": "0 0 * * * * *",
107
+ daily: "0 0 0 * * * *",
108
+ "@daily": "0 0 0 * * * *",
109
+ weekly: "0 0 0 * * 0 *",
110
+ "@weekly": "0 0 0 * * 0 *"
21
111
  };
22
- const genConfig = ({ jobName, workingDirectory, cmd, cron, count, restart, killTimeout, cpu, mem, service, additionalEnv = {}, type = "batch", region = "skynet-dc1", isProduction, }) => `job "${jobName}" {
112
+ var genConfig = ({
113
+ jobName,
114
+ workingDirectory,
115
+ cmd,
116
+ cron,
117
+ count,
118
+ restart,
119
+ killTimeout,
120
+ cpu,
121
+ mem,
122
+ service,
123
+ additionalEnv = {},
124
+ type = "batch",
125
+ region = "skynet-dc1",
126
+ isProduction: isProduction2
127
+ }) => `job "${jobName}" {
23
128
  datacenters = ["${region}"]
24
129
 
25
130
  type = "${type}"
26
131
 
27
- ${cron
28
- ? `# Triggers periodically
132
+ ${cron ? `# Triggers periodically
29
133
  periodic {
30
134
  crons = ["${cron}"]
31
135
  prohibit_overlap = true
32
- }`
33
- : ""}
136
+ }` : ""}
34
137
 
35
138
  constraint {
36
139
  attribute = "\${meta.has_nodejs}"
@@ -44,27 +147,23 @@ const genConfig = ({ jobName, workingDirectory, cmd, cron, count, restart, killT
44
147
 
45
148
  group "default" {
46
149
  ${count && count > 1 ? `count = ${count}` : ""}
47
- ${count && count > 1
48
- ? `# Rolling Update
150
+ ${count && count > 1 ? `# Rolling Update
49
151
  update {
50
152
  max_parallel = 1
51
153
  min_healthy_time = "10s"
52
- }`
53
- : ""}
154
+ }` : ""}
54
155
 
55
156
  reschedule {
56
157
  attempts = 0
57
158
  unlimited = false
58
159
  }
59
160
 
60
- ${service
61
- ? `# Setup Service Network
161
+ ${service ? `# Setup Service Network
62
162
  network {
63
163
  port "http" {
64
164
  static = ${service.port}
65
165
  }
66
- }`
67
- : ""}
166
+ }` : ""}
68
167
 
69
168
  task "main" {
70
169
  driver = "raw_exec"
@@ -77,8 +176,7 @@ const genConfig = ({ jobName, workingDirectory, cmd, cron, count, restart, killT
77
176
  ]
78
177
  }
79
178
 
80
- ${service
81
- ? `# Setup API Routes
179
+ ${service ? `# Setup API Routes
82
180
  service {
83
181
  name = "${jobName}"
84
182
  port = "http"
@@ -94,8 +192,7 @@ const genConfig = ({ jobName, workingDirectory, cmd, cron, count, restart, killT
94
192
  timeout = "2s"
95
193
  }
96
194
  }
97
- `
98
- : ""}
195
+ ` : ""}
99
196
 
100
197
  # doppler integration support
101
198
  # it is always there but a project can decide to not use it
@@ -111,12 +208,10 @@ const genConfig = ({ jobName, workingDirectory, cmd, cron, count, restart, killT
111
208
  SKYNET_DEPLOYED_AT="${new Date().toISOString()}"
112
209
  HOME="/root"
113
210
  DOPPLER_PROJECT="${workingDirectory}"
114
- DOPPLER_CONFIG="${isProduction ? "prd" : "dev"}"
115
- SKYNET_ENVIRONMENT="${isProduction ? "prd" : "dev"}"
116
- ${Object.entries(additionalEnv)
117
- .filter((kv) => !!kv[1])
118
- .map(([key, value]) => `${key}="${value}"`)
119
- .join(" \n")}
211
+ DOPPLER_CONFIG="${isProduction2 ? "prd" : "dev"}"
212
+ SKYNET_ENVIRONMENT="${isProduction2 ? "prd" : "dev"}"
213
+ ${Object.entries(additionalEnv).filter((kv) => !!kv[1]).map(([key, value]) => `${key}="${value}"`).join(`
214
+ `)}
120
215
  }
121
216
 
122
217
  kill_timeout = "${killTimeout || "60s"}"
@@ -132,8 +227,7 @@ const genConfig = ({ jobName, workingDirectory, cmd, cron, count, restart, killT
132
227
  # signal the log shipper task to gracefully shutdown when the server exits.
133
228
  leader = true
134
229
 
135
- ${restart
136
- ? `
230
+ ${restart ? `
137
231
  # Restart the job if it fails
138
232
  restart {
139
233
  attempts = ${restart.attempts ?? 2}
@@ -141,8 +235,7 @@ const genConfig = ({ jobName, workingDirectory, cmd, cron, count, restart, killT
141
235
  interval = "${restart.interval ?? "30m"}"
142
236
  delay = "${restart.delay ?? "15s"}"
143
237
  }
144
- `
145
- : `
238
+ ` : `
146
239
  # do not retry from the periodical job will reschedule anyway
147
240
  restart {
148
241
  attempts = 0
@@ -151,144 +244,164 @@ const genConfig = ({ jobName, workingDirectory, cmd, cron, count, restart, killT
151
244
  }
152
245
  }
153
246
  }`;
154
- async function prepareNomad(isProduction) {
155
- if (isProduction) {
156
- console.log("Deploy to Production");
157
- }
158
- else {
159
- const skynetDir = detectSkynetDirectory();
160
- if (!fso.existsSync("/tmp/skynet")) {
161
- await execa("ln", ["-s", skynetDir, "/tmp/skynet"]);
162
- }
163
- console.log("Deploy locally, please start nomad server in a separate terminal");
164
- console.log(`You can start nomad server by running ${chalk.inverse(`${skynetDir}/infra-nomad/dev/start.sh`)}`);
165
- console.log(`Then you can visit ${chalk.underline("http://localhost:4646/ui/jobs")} to check submitted dev jobs.\n`);
247
+ async function prepareNomad(isProduction2) {
248
+ if (isProduction2) {
249
+ console.log("Deploy to Production");
250
+ } else {
251
+ const skynetDir = detectSkynetDirectory();
252
+ if (!fso.existsSync("/tmp/skynet")) {
253
+ await execa("ln", ["-s", skynetDir, "/tmp/skynet"]);
166
254
  }
255
+ console.log("Deploy locally, please start nomad server in a separate terminal");
256
+ console.log(`You can start nomad server by running ${chalk.inverse(`${skynetDir}/infra-nomad/dev/start.sh`)}`);
257
+ console.log(`Then you can visit ${chalk.underline("http://localhost:4646/ui/jobs")} to check submitted dev jobs.
258
+ `);
259
+ }
167
260
  }
168
- function getNomadAddr(isProduction) {
169
- return isProduction ? getEnvOrThrow("NOMAD_ADDR") : "http://127.0.0.1:4646";
261
+ function getNomadAddr(isProduction2) {
262
+ return isProduction2 ? getEnvOrThrow("NOMAD_ADDR") : "http://127.0.0.1:4646";
170
263
  }
171
264
  async function getNomadPath() {
172
- try {
173
- return await which("nomad");
174
- }
175
- catch (missingNomad) {
176
- console.log(`Deploy requires ${chalk.bold("nomad")} binary, please follow ${chalk.underline("https://learn.hashicorp.com/tutorials/nomad/get-started-install")} for installation`, missingNomad);
177
- throw new Error("missing nomad binary");
178
- }
265
+ try {
266
+ return await which("nomad");
267
+ } catch (missingNomad) {
268
+ console.log(`Deploy requires ${chalk.bold("nomad")} binary, please follow ${chalk.underline("https://learn.hashicorp.com/tutorials/nomad/get-started-install")} for installation`, missingNomad);
269
+ throw new Error("missing nomad binary");
270
+ }
179
271
  }
180
272
  async function runNomadJob(nomadPath, nomadAddr, jobName, nomadJobDefinition, isStop, isDryRun) {
181
- try {
182
- if (isStop) {
183
- const nomad = execa(nomadPath, ["job", "stop", jobName], {
184
- env: {
185
- NOMAD_ADDR: nomadAddr,
186
- },
187
- });
188
- nomad.stdout.pipe(process.stdout);
189
- await nomad;
190
- console.log(chalk.green(`Stopped nomad job ${jobName} in ${nomadAddr}`));
191
- }
192
- else if (isDryRun) {
193
- console.log("Definition for", jobName);
194
- console.log("========================================");
195
- console.log(nomadJobDefinition);
273
+ try {
274
+ if (isStop) {
275
+ const nomad = execa(nomadPath, ["job", "stop", jobName], {
276
+ env: {
277
+ NOMAD_ADDR: nomadAddr
196
278
  }
197
- else {
198
- const jobFileName = `/tmp/job-${jobName}`;
199
- await fs.writeFile(jobFileName, nomadJobDefinition);
200
- const nomad = execa(nomadPath, ["job", "run", jobFileName], {
201
- env: {
202
- NOMAD_ADDR: nomadAddr,
203
- },
204
- });
205
- nomad.stdout.pipe(process.stdout);
206
- await nomad;
207
- console.log(chalk.green(`Deployed nomad job ${jobName} to ${nomadAddr}`));
279
+ });
280
+ nomad.stdout.pipe(process.stdout);
281
+ await nomad;
282
+ console.log(chalk.green(`Stopped nomad job ${jobName} in ${nomadAddr}`));
283
+ } else if (isDryRun) {
284
+ console.log("Definition for", jobName);
285
+ console.log("========================================");
286
+ console.log(nomadJobDefinition);
287
+ } else {
288
+ const jobFileName = `/tmp/job-${jobName}`;
289
+ await fs2.writeFile(jobFileName, nomadJobDefinition);
290
+ const nomad = execa(nomadPath, ["job", "run", jobFileName], {
291
+ env: {
292
+ NOMAD_ADDR: nomadAddr
208
293
  }
294
+ });
295
+ nomad.stdout.pipe(process.stdout);
296
+ await nomad;
297
+ console.log(chalk.green(`Deployed nomad job ${jobName} to ${nomadAddr}`));
209
298
  }
210
- catch (nomadExecErr) {
211
- if (nomadExecErr instanceof Error) {
212
- console.log("Nomad Execution Error:");
213
- console.log(nomadExecErr.message);
214
- console.log("");
215
- }
216
- console.log(`Failed to run ${chalk.bold("nomad")} commands, please ensure nomad server is accessible at ${chalk.bold(nomadAddr)}`);
217
- throw new Error("nomad execution error");
299
+ } catch (nomadExecErr) {
300
+ if (nomadExecErr instanceof Error) {
301
+ console.log("Nomad Execution Error:");
302
+ console.log(nomadExecErr.message);
303
+ console.log("");
218
304
  }
305
+ console.log(`Failed to run ${chalk.bold("nomad")} commands, please ensure nomad server is accessible at ${chalk.bold(nomadAddr)}`);
306
+ throw new Error("nomad execution error");
307
+ }
219
308
  }
220
- function createModeDeploy({ binaryName, name, workingDirectory, bin = "bin/indexer", selector = {}, env = {}, region = "skynet-dc1", deltaSchedule, validateSchedule, deltaKillTimeout, deltaCpu, deltaMem, rebuildKillTimeout, rebuildCpu, rebuildMem, validateKillTimeout, validateCpu, validateMem, }) {
221
- async function deployMode({ mode, from, to, stop, production, dryRun, verbose, schedule: cmdSchedule, ...selectorFlags }) {
222
- if (mode === "delta") {
223
- // delta mode will ignore from/to flags
224
- from = 0;
225
- to = 0;
226
- }
227
- const isPeriodic = from === 0 && to === 0 && ["delta", "validate"].includes(mode);
228
- const jobName = getJobName(name, selectorFlags, mode);
229
- const selectorCmdPart = Object.entries(selectorFlags)
230
- .sort()
231
- .map(([name, value]) => `--${name} ${value}`)
232
- .join(" ");
233
- let args = `--mode ${mode} ${selectorCmdPart}`;
234
- if (verbose) {
235
- args += ` --verbose`;
236
- }
237
- let rangeArgs = "";
238
- if (from > 0) {
239
- rangeArgs += ` --from ${from}`;
240
- }
241
- if (to > 0) {
242
- rangeArgs += ` --to ${to}`;
243
- }
244
- const modeResouces = {
245
- rebuild: { cpu: rebuildCpu, mem: rebuildMem, killTimeout: rebuildKillTimeout },
246
- "resume-rebuild": { cpu: rebuildCpu, mem: rebuildMem, killTimeout: rebuildKillTimeout },
247
- validate: {
248
- cpu: validateCpu || rebuildCpu,
249
- mem: validateMem || rebuildMem,
250
- killTimeout: validateKillTimeout || rebuildKillTimeout,
251
- },
252
- delta: { cpu: deltaCpu, mem: deltaMem, killTimeout: deltaKillTimeout },
253
- };
254
- // by default use delta cpu/mem settings
255
- const cpu = modeResouces[mode]?.cpu || deltaCpu;
256
- const mem = modeResouces[mode]?.mem || deltaMem;
257
- const killTimeout = modeResouces[mode]?.killTimeout || deltaKillTimeout;
258
- let deltaCron = typeof deltaSchedule === "function" ? deltaSchedule(jobName) : deltaSchedule;
259
- if (deltaSchedule && cmdSchedule) {
260
- deltaCron = cmdSchedule;
261
- }
262
- let validateCron = typeof validateSchedule === "function" ? validateSchedule(jobName) : validateSchedule;
263
- if (validateSchedule && cmdSchedule) {
264
- validateCron = cmdSchedule;
265
- }
266
- const modeIntervals = {
267
- delta: deltaCron ? INTERVAL_ALIASES[deltaCron] || deltaCron : undefined,
268
- validate: validateCron ? INTERVAL_ALIASES[validateCron] || validateCron : undefined,
269
- };
270
- const mainJobDefinition = genConfig({
271
- jobName,
272
- cron: isPeriodic ? modeIntervals[mode] : undefined,
273
- workingDirectory,
274
- additionalEnv: env,
275
- region,
276
- cmd: `${bin} ${args} ${rangeArgs}`,
277
- killTimeout,
278
- cpu,
279
- mem,
280
- isProduction: production,
281
- });
282
- const nomadPath = await getNomadPath();
283
- await prepareNomad(production);
284
- const nomadAddr = getNomadAddr(production);
285
- await runNomadJob(nomadPath, nomadAddr, jobName, mainJobDefinition, stop, dryRun);
309
+ function createModeDeploy({
310
+ binaryName,
311
+ name,
312
+ workingDirectory,
313
+ bin = "bin/indexer",
314
+ selector = {},
315
+ env = {},
316
+ region = "skynet-dc1",
317
+ deltaSchedule,
318
+ validateSchedule,
319
+ deltaKillTimeout,
320
+ deltaCpu,
321
+ deltaMem,
322
+ rebuildKillTimeout,
323
+ rebuildCpu,
324
+ rebuildMem,
325
+ validateKillTimeout,
326
+ validateCpu,
327
+ validateMem
328
+ }) {
329
+ async function deployMode({
330
+ mode,
331
+ from,
332
+ to,
333
+ stop,
334
+ production,
335
+ dryRun,
336
+ verbose,
337
+ schedule: cmdSchedule,
338
+ ...selectorFlags
339
+ }) {
340
+ if (mode === "delta") {
341
+ from = 0;
342
+ to = 0;
286
343
  }
287
- async function deploy() {
288
- if (!binaryName) {
289
- binaryName = getBinaryName();
290
- }
291
- const cli = meow(`
344
+ const isPeriodic = from === 0 && to === 0 && ["delta", "validate"].includes(mode);
345
+ const jobName = getJobName(name, selectorFlags, mode);
346
+ const selectorCmdPart = Object.entries(selectorFlags).sort().map(([name2, value]) => `--${name2} ${value}`).join(" ");
347
+ let args = `--mode ${mode} ${selectorCmdPart}`;
348
+ if (verbose) {
349
+ args += ` --verbose`;
350
+ }
351
+ let rangeArgs = "";
352
+ if (from > 0) {
353
+ rangeArgs += ` --from ${from}`;
354
+ }
355
+ if (to > 0) {
356
+ rangeArgs += ` --to ${to}`;
357
+ }
358
+ const modeResouces = {
359
+ rebuild: { cpu: rebuildCpu, mem: rebuildMem, killTimeout: rebuildKillTimeout },
360
+ "resume-rebuild": { cpu: rebuildCpu, mem: rebuildMem, killTimeout: rebuildKillTimeout },
361
+ validate: {
362
+ cpu: validateCpu || rebuildCpu,
363
+ mem: validateMem || rebuildMem,
364
+ killTimeout: validateKillTimeout || rebuildKillTimeout
365
+ },
366
+ delta: { cpu: deltaCpu, mem: deltaMem, killTimeout: deltaKillTimeout }
367
+ };
368
+ const cpu = modeResouces[mode]?.cpu || deltaCpu;
369
+ const mem = modeResouces[mode]?.mem || deltaMem;
370
+ const killTimeout = modeResouces[mode]?.killTimeout || deltaKillTimeout;
371
+ let deltaCron = typeof deltaSchedule === "function" ? deltaSchedule(jobName) : deltaSchedule;
372
+ if (deltaSchedule && cmdSchedule) {
373
+ deltaCron = cmdSchedule;
374
+ }
375
+ let validateCron = typeof validateSchedule === "function" ? validateSchedule(jobName) : validateSchedule;
376
+ if (validateSchedule && cmdSchedule) {
377
+ validateCron = cmdSchedule;
378
+ }
379
+ const modeIntervals = {
380
+ delta: deltaCron ? INTERVAL_ALIASES[deltaCron] || deltaCron : undefined,
381
+ validate: validateCron ? INTERVAL_ALIASES[validateCron] || validateCron : undefined
382
+ };
383
+ const mainJobDefinition = genConfig({
384
+ jobName,
385
+ cron: isPeriodic ? modeIntervals[mode] : undefined,
386
+ workingDirectory,
387
+ additionalEnv: env,
388
+ region,
389
+ cmd: `${bin} ${args} ${rangeArgs}`,
390
+ killTimeout,
391
+ cpu,
392
+ mem,
393
+ isProduction: production
394
+ });
395
+ const nomadPath = await getNomadPath();
396
+ await prepareNomad(production);
397
+ const nomadAddr = getNomadAddr(production);
398
+ await runNomadJob(nomadPath, nomadAddr, jobName, mainJobDefinition, stop, dryRun);
399
+ }
400
+ async function deploy() {
401
+ if (!binaryName) {
402
+ binaryName = getBinaryName();
403
+ }
404
+ const cli = meow(`
292
405
  Usage
293
406
 
294
407
  $ ${binaryName} <options>
@@ -309,99 +422,117 @@ ${getSelectorDesc(selector)}
309
422
  ${binaryName} --mode rebuild
310
423
  ${binaryName} --mode validate
311
424
  `, {
312
- importMeta: import.meta,
313
- description: false,
314
- version: false,
315
- flags: {
316
- ...getSelectorFlags(selector),
317
- mode: {
318
- type: "string",
319
- default: "delta",
320
- },
321
- from: {
322
- aliases: ["since"],
323
- type: "number",
324
- default: 0,
325
- },
326
- to: {
327
- aliases: ["until"],
328
- type: "number",
329
- default: 0,
330
- },
331
- schedule: {
332
- type: "string",
333
- },
334
- verbose: {
335
- type: "boolean",
336
- default: false,
337
- },
338
- production: {
339
- aliases: ["prd"],
340
- type: "boolean",
341
- default: false,
342
- },
343
- dryRun: {
344
- type: "boolean",
345
- default: false,
346
- },
347
- stop: {
348
- type: "boolean",
349
- default: false,
350
- },
351
- },
352
- });
353
- try {
354
- return deployMode(cli.flags);
355
- }
356
- catch (err) {
357
- console.error(err);
358
- process.exit(1);
425
+ importMeta: import.meta,
426
+ description: false,
427
+ version: false,
428
+ flags: {
429
+ ...getSelectorFlags(selector),
430
+ mode: {
431
+ type: "string",
432
+ default: "delta"
433
+ },
434
+ from: {
435
+ aliases: ["since"],
436
+ type: "number",
437
+ default: 0
438
+ },
439
+ to: {
440
+ aliases: ["until"],
441
+ type: "number",
442
+ default: 0
443
+ },
444
+ schedule: {
445
+ type: "string"
446
+ },
447
+ verbose: {
448
+ type: "boolean",
449
+ default: false
450
+ },
451
+ production: {
452
+ aliases: ["prd"],
453
+ type: "boolean",
454
+ default: false
455
+ },
456
+ dryRun: {
457
+ type: "boolean",
458
+ default: false
459
+ },
460
+ stop: {
461
+ type: "boolean",
462
+ default: false
359
463
  }
464
+ }
465
+ });
466
+ try {
467
+ return deployMode(cli.flags);
468
+ } catch (err) {
469
+ console.error(err);
470
+ process.exit(1);
360
471
  }
361
- return { deploy };
472
+ }
473
+ return { deploy };
362
474
  }
363
- function createDeploy({ binaryName, name, workingDirectory, bin = "bin/indexer", selector = {}, region = "skynet-dc1", type = "batch", env = {}, count, schedule, restart, killTimeout, cpu, mem, service, }) {
364
- async function deployModeless({ production, stop, dryRun, verbose, schedule: cmdSchedule, ...selectorFlags }) {
365
- const jobName = getJobName(name, selectorFlags);
366
- const selectorCmdPart = Object.entries(selectorFlags)
367
- .sort()
368
- .map(([name, value]) => `--${name} ${value}`)
369
- .join(" ");
370
- let args = `${selectorCmdPart}`;
371
- if (verbose) {
372
- args += ` --verbose`;
373
- }
374
- let cron = typeof schedule === "function" ? schedule(jobName) : schedule;
375
- if (schedule && cmdSchedule) {
376
- // cmd schedule has higher priority
377
- cron = cmdSchedule;
378
- }
379
- const nomadJobDefinition = genConfig({
380
- jobName,
381
- cron: cron ? INTERVAL_ALIASES[cron] || cron : undefined,
382
- count,
383
- restart,
384
- workingDirectory,
385
- additionalEnv: env,
386
- region,
387
- type,
388
- cmd: `${bin} ${args}`,
389
- killTimeout,
390
- cpu,
391
- mem,
392
- service,
393
- isProduction: production,
394
- });
395
- const nomadPath = await getNomadPath();
396
- await prepareNomad(production);
397
- const nomadAddr = getNomadAddr(production);
398
- await runNomadJob(nomadPath, nomadAddr, jobName, nomadJobDefinition, stop, dryRun);
475
+ function createDeploy({
476
+ binaryName,
477
+ name,
478
+ workingDirectory,
479
+ bin = "bin/indexer",
480
+ selector = {},
481
+ region = "skynet-dc1",
482
+ type = "batch",
483
+ env = {},
484
+ count,
485
+ schedule,
486
+ restart,
487
+ killTimeout,
488
+ cpu,
489
+ mem,
490
+ service
491
+ }) {
492
+ async function deployModeless({
493
+ production,
494
+ stop,
495
+ dryRun,
496
+ verbose,
497
+ schedule: cmdSchedule,
498
+ ...selectorFlags
499
+ }) {
500
+ const jobName = getJobName(name, selectorFlags);
501
+ const selectorCmdPart = Object.entries(selectorFlags).sort().map(([name2, value]) => `--${name2} ${value}`).join(" ");
502
+ let args = `${selectorCmdPart}`;
503
+ if (verbose) {
504
+ args += ` --verbose`;
399
505
  }
400
- async function deploy() {
401
- if (!binaryName) {
402
- binaryName = getBinaryName();
403
- }
404
- const cli = meow(`
506
+ let cron = typeof schedule === "function" ? schedule(jobName) : schedule;
507
+ if (schedule && cmdSchedule) {
508
+ cron = cmdSchedule;
509
+ }
510
+ const nomadJobDefinition = genConfig({
511
+ jobName,
512
+ cron: cron ? INTERVAL_ALIASES[cron] || cron : undefined,
513
+ count,
514
+ restart,
515
+ workingDirectory,
516
+ additionalEnv: env,
517
+ region,
518
+ type,
519
+ cmd: `${bin} ${args}`,
520
+ killTimeout,
521
+ cpu,
522
+ mem,
523
+ service,
524
+ isProduction: production
525
+ });
526
+ const nomadPath = await getNomadPath();
527
+ await prepareNomad(production);
528
+ const nomadAddr = getNomadAddr(production);
529
+ await runNomadJob(nomadPath, nomadAddr, jobName, nomadJobDefinition, stop, dryRun);
530
+ }
531
+ async function deploy() {
532
+ if (!binaryName) {
533
+ binaryName = getBinaryName();
534
+ }
535
+ const cli = meow(`
405
536
  Usage
406
537
 
407
538
  $ ${binaryName} <options>
@@ -414,41 +545,45 @@ ${getSelectorDesc(selector)}
414
545
  --verbose Output debug messages
415
546
  --dry-run print nomad job file but do not really execute it
416
547
  `, {
417
- importMeta: import.meta,
418
- description: false,
419
- version: false,
420
- flags: {
421
- ...getSelectorFlags(selector),
422
- schedule: {
423
- type: "string",
424
- },
425
- verbose: {
426
- type: "boolean",
427
- default: false,
428
- },
429
- production: {
430
- aliases: ["prd"],
431
- type: "boolean",
432
- default: false,
433
- },
434
- dryRun: {
435
- type: "boolean",
436
- default: false,
437
- },
438
- stop: {
439
- type: "boolean",
440
- default: false,
441
- },
442
- },
443
- });
444
- try {
445
- return deployModeless(cli.flags);
446
- }
447
- catch (err) {
448
- console.error(err);
449
- process.exit(1);
548
+ importMeta: import.meta,
549
+ description: false,
550
+ version: false,
551
+ flags: {
552
+ ...getSelectorFlags(selector),
553
+ schedule: {
554
+ type: "string"
555
+ },
556
+ verbose: {
557
+ type: "boolean",
558
+ default: false
559
+ },
560
+ production: {
561
+ aliases: ["prd"],
562
+ type: "boolean",
563
+ default: false
564
+ },
565
+ dryRun: {
566
+ type: "boolean",
567
+ default: false
568
+ },
569
+ stop: {
570
+ type: "boolean",
571
+ default: false
450
572
  }
573
+ }
574
+ });
575
+ try {
576
+ return deployModeless(cli.flags);
577
+ } catch (err) {
578
+ console.error(err);
579
+ process.exit(1);
451
580
  }
452
- return { deploy };
581
+ }
582
+ return { deploy };
453
583
  }
454
- export { getJobName, getNomadAddr, createModeDeploy, createDeploy };
584
+ export {
585
+ getNomadAddr,
586
+ getJobName,
587
+ createModeDeploy,
588
+ createDeploy
589
+ };