@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.
- package/CHANGELOG.md +8 -0
- package/build.ts +23 -0
- package/dist/abi.d.ts +1 -2
- package/dist/abi.js +569 -563
- package/dist/address.d.ts +0 -1
- package/dist/address.js +22 -21
- package/dist/api.d.ts +0 -1
- package/dist/api.js +235 -120
- package/dist/app.d.ts +1 -2
- package/dist/app.js +2030 -276
- package/dist/availability.d.ts +0 -1
- package/dist/availability.js +126 -56
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +28 -24
- package/dist/const.d.ts +0 -1
- package/dist/const.js +153 -132
- package/dist/databricks.d.ts +0 -1
- package/dist/databricks.js +198 -58
- package/dist/date.d.ts +0 -1
- package/dist/date.js +48 -21
- package/dist/deploy.d.ts +0 -1
- package/dist/deploy.js +427 -292
- package/dist/dynamodb.d.ts +3 -4
- package/dist/dynamodb.js +432 -281
- package/dist/env.d.ts +2 -3
- package/dist/env.js +16 -9
- package/dist/graphql.d.ts +0 -1
- package/dist/graphql.js +26 -23
- package/dist/indexer.d.ts +0 -1
- package/dist/indexer.js +1050 -441
- package/dist/log.d.ts +0 -1
- package/dist/log.js +53 -52
- package/dist/object-hash.d.ts +0 -1
- package/dist/object-hash.js +49 -59
- package/dist/opsgenie.d.ts +97 -19
- package/dist/opsgenie.js +35 -30
- package/dist/por.d.ts +0 -1
- package/dist/por.js +113 -123
- package/dist/s3.d.ts +7 -8
- package/dist/s3.js +103 -91
- package/dist/search.d.ts +0 -1
- package/dist/search.js +100 -25
- package/dist/selector.d.ts +0 -1
- package/dist/selector.js +34 -38
- package/dist/slack.d.ts +0 -1
- package/dist/slack.js +27 -21
- package/dist/util.d.ts +0 -1
- package/dist/util.js +21 -20
- package/examples/api.ts +1 -1
- package/examples/indexer.ts +1 -1
- package/examples/mode-indexer.ts +1 -1
- package/package.json +4 -3
- package/{graphql.ts → src/graphql.ts} +1 -1
- package/src/opsgenie.ts +176 -0
- package/tsconfig.build.json +2 -5
- package/tsconfig.json +11 -20
- package/dist/abi.d.ts.map +0 -1
- package/dist/address.d.ts.map +0 -1
- package/dist/api.d.ts.map +0 -1
- package/dist/app.d.ts.map +0 -1
- package/dist/availability.d.ts.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/const.d.ts.map +0 -1
- package/dist/databricks.d.ts.map +0 -1
- package/dist/date.d.ts.map +0 -1
- package/dist/deploy.d.ts.map +0 -1
- package/dist/dynamodb.d.ts.map +0 -1
- package/dist/env.d.ts.map +0 -1
- package/dist/graphql.d.ts.map +0 -1
- package/dist/indexer.d.ts.map +0 -1
- package/dist/log.d.ts.map +0 -1
- package/dist/object-hash.d.ts.map +0 -1
- package/dist/opsgenie.d.ts.map +0 -1
- package/dist/por.d.ts.map +0 -1
- package/dist/s3.d.ts.map +0 -1
- package/dist/search.d.ts.map +0 -1
- package/dist/selector.d.ts.map +0 -1
- package/dist/slack.d.ts.map +0 -1
- package/dist/util.d.ts.map +0 -1
- package/opsgenie.ts +0 -69
- /package/{abi.ts → src/abi.ts} +0 -0
- /package/{address.ts → src/address.ts} +0 -0
- /package/{api.ts → src/api.ts} +0 -0
- /package/{app.ts → src/app.ts} +0 -0
- /package/{availability.ts → src/availability.ts} +0 -0
- /package/{cli.ts → src/cli.ts} +0 -0
- /package/{const.ts → src/const.ts} +0 -0
- /package/{databricks.ts → src/databricks.ts} +0 -0
- /package/{date.ts → src/date.ts} +0 -0
- /package/{deploy.ts → src/deploy.ts} +0 -0
- /package/{dynamodb.ts → src/dynamodb.ts} +0 -0
- /package/{env.ts → src/env.ts} +0 -0
- /package/{indexer.ts → src/indexer.ts} +0 -0
- /package/{log.ts → src/log.ts} +0 -0
- /package/{object-hash.ts → src/object-hash.ts} +0 -0
- /package/{por.ts → src/por.ts} +0 -0
- /package/{s3.ts → src/s3.ts} +0 -0
- /package/{search.ts → src/search.ts} +0 -0
- /package/{selector.ts → src/selector.ts} +0 -0
- /package/{slack.ts → src/slack.ts} +0 -0
- /package/{util.ts → src/util.ts} +0 -0
package/dist/deploy.js
CHANGED
|
@@ -1,36 +1,139 @@
|
|
|
1
|
-
|
|
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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
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="${
|
|
115
|
-
SKYNET_ENVIRONMENT="${
|
|
116
|
-
${Object.entries(additionalEnv)
|
|
117
|
-
|
|
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(
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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(
|
|
169
|
-
|
|
261
|
+
function getNomadAddr(isProduction2) {
|
|
262
|
+
return isProduction2 ? getEnvOrThrow("NOMAD_ADDR") : "http://127.0.0.1:4646";
|
|
170
263
|
}
|
|
171
264
|
async function getNomadPath() {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
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
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
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
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
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
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
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({
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
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
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
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
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
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
|
-
|
|
472
|
+
}
|
|
473
|
+
return { deploy };
|
|
362
474
|
}
|
|
363
|
-
function createDeploy({
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
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
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
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
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
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
|
-
|
|
581
|
+
}
|
|
582
|
+
return { deploy };
|
|
453
583
|
}
|
|
454
|
-
export {
|
|
584
|
+
export {
|
|
585
|
+
getNomadAddr,
|
|
586
|
+
getJobName,
|
|
587
|
+
createModeDeploy,
|
|
588
|
+
createDeploy
|
|
589
|
+
};
|