kourou 0.26.0 → 0.26.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.
- package/README.md +98 -74
- package/lib/commands/app/doctor.js +5 -14
- package/lib/commands/app/scaffold.d.ts +7 -1
- package/lib/commands/app/scaffold.js +62 -11
- package/lib/commands/app/start-services.d.ts +0 -1
- package/lib/commands/app/start-services.js +9 -50
- package/lib/commands/instance/kill.js +2 -1
- package/lib/commands/instance/spawn.d.ts +0 -1
- package/lib/commands/instance/spawn.js +11 -68
- package/lib/commands/paas/logs.js +21 -0
- package/lib/commands/paas/snapshots/cat.d.ts +1 -0
- package/lib/commands/paas/snapshots/cat.js +1 -0
- package/lib/commands/paas/snapshots/dump.d.ts +1 -0
- package/lib/commands/paas/snapshots/dump.js +2 -1
- package/lib/commands/paas/snapshots/restore.d.ts +1 -0
- package/lib/commands/paas/snapshots/restore.js +2 -1
- package/lib/support/docker/checkPrerequisites.d.ts +2 -0
- package/lib/support/docker/checkPrerequisites.js +35 -0
- package/lib/support/execute.js +0 -2
- package/lib/support/kuzzle.js +3 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ $ npm install -g kourou
|
|
|
27
27
|
$ kourou COMMAND
|
|
28
28
|
running command...
|
|
29
29
|
$ kourou (-v|--version|version)
|
|
30
|
-
kourou/0.26.
|
|
30
|
+
kourou/0.26.2 darwin-arm64 node-v18.17.1
|
|
31
31
|
$ kourou --help [COMMAND]
|
|
32
32
|
USAGE
|
|
33
33
|
$ kourou COMMAND
|
|
@@ -126,72 +126,64 @@ All other arguments and options will be passed as-is to the `sdk:query` method.
|
|
|
126
126
|
# Commands
|
|
127
127
|
|
|
128
128
|
<!-- commands -->
|
|
129
|
-
|
|
130
|
-
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
- [`kourou vault:add SECRETS-FILE KEY VALUE`](#kourou-vaultadd-secrets-file-key-value)
|
|
188
|
-
- [`kourou vault:decrypt FILE`](#kourou-vaultdecrypt-file)
|
|
189
|
-
- [`kourou vault:encrypt FILE`](#kourou-vaultencrypt-file)
|
|
190
|
-
- [`kourou vault:show SECRETS-FILE [KEY]`](#kourou-vaultshow-secrets-file-key)
|
|
191
|
-
- [`kourou vault:test SECRETS-FILE`](#kourou-vaulttest-secrets-file)
|
|
192
|
-
- [Where does this weird name come from?](#where-does-this-weird-name-come-from)
|
|
193
|
-
- [Have fun with a quine](#have-fun-with-a-quine)
|
|
194
|
-
- [Telemetry](#telemetry)
|
|
129
|
+
* [`kourou api-key:check TOKEN`](#kourou-api-keycheck-token)
|
|
130
|
+
* [`kourou api-key:create USER`](#kourou-api-keycreate-user)
|
|
131
|
+
* [`kourou api-key:delete USER ID`](#kourou-api-keydelete-user-id)
|
|
132
|
+
* [`kourou api-key:search USER`](#kourou-api-keysearch-user)
|
|
133
|
+
* [`kourou app:debug-proxy`](#kourou-appdebug-proxy)
|
|
134
|
+
* [`kourou app:doctor`](#kourou-appdoctor)
|
|
135
|
+
* [`kourou app:scaffold DESTINATION`](#kourou-appscaffold-destination)
|
|
136
|
+
* [`kourou app:start-services`](#kourou-appstart-services)
|
|
137
|
+
* [`kourou autocomplete [SHELL]`](#kourou-autocomplete-shell)
|
|
138
|
+
* [`kourou collection:create INDEX COLLECTION [BODY]`](#kourou-collectioncreate-index-collection-body)
|
|
139
|
+
* [`kourou collection:export INDEX COLLECTION`](#kourou-collectionexport-index-collection)
|
|
140
|
+
* [`kourou collection:import PATH`](#kourou-collectionimport-path)
|
|
141
|
+
* [`kourou collection:migrate SCRIPT PATH`](#kourou-collectionmigrate-script-path)
|
|
142
|
+
* [`kourou config:diff FIRST SECOND`](#kourou-configdiff-first-second)
|
|
143
|
+
* [`kourou document:search INDEX COLLECTION [QUERY]`](#kourou-documentsearch-index-collection-query)
|
|
144
|
+
* [`kourou es:aliases:cat`](#kourou-esaliasescat)
|
|
145
|
+
* [`kourou es:indices:cat`](#kourou-esindicescat)
|
|
146
|
+
* [`kourou es:indices:get INDEX ID`](#kourou-esindicesget-index-id)
|
|
147
|
+
* [`kourou es:indices:insert INDEX`](#kourou-esindicesinsert-index)
|
|
148
|
+
* [`kourou es:migrate`](#kourou-esmigrate)
|
|
149
|
+
* [`kourou es:snapshot:create REPOSITORY NAME`](#kourou-essnapshotcreate-repository-name)
|
|
150
|
+
* [`kourou es:snapshot:create-repository REPOSITORY LOCATION`](#kourou-essnapshotcreate-repository-repository-location)
|
|
151
|
+
* [`kourou es:snapshot:list REPOSITORY`](#kourou-essnapshotlist-repository)
|
|
152
|
+
* [`kourou file:decrypt FILE`](#kourou-filedecrypt-file)
|
|
153
|
+
* [`kourou file:encrypt FILE`](#kourou-fileencrypt-file)
|
|
154
|
+
* [`kourou file:test FILE`](#kourou-filetest-file)
|
|
155
|
+
* [`kourou help [COMMAND]`](#kourou-help-command)
|
|
156
|
+
* [`kourou import PATH`](#kourou-import-path)
|
|
157
|
+
* [`kourou index:export INDEX`](#kourou-indexexport-index)
|
|
158
|
+
* [`kourou index:import PATH`](#kourou-indeximport-path)
|
|
159
|
+
* [`kourou instance:kill`](#kourou-instancekill)
|
|
160
|
+
* [`kourou instance:list`](#kourou-instancelist)
|
|
161
|
+
* [`kourou instance:logs`](#kourou-instancelogs)
|
|
162
|
+
* [`kourou instance:spawn`](#kourou-instancespawn)
|
|
163
|
+
* [`kourou paas:deploy ENVIRONMENT APPLICATIONID IMAGE`](#kourou-paasdeploy-environment-applicationid-image)
|
|
164
|
+
* [`kourou paas:init PROJECT`](#kourou-paasinit-project)
|
|
165
|
+
* [`kourou paas:login`](#kourou-paaslogin)
|
|
166
|
+
* [`kourou paas:logs ENVIRONMENT APPLICATION`](#kourou-paaslogs-environment-application)
|
|
167
|
+
* [`kourou paas:snapshots:cat ENVIRONMENT APPLICATIONID`](#kourou-paassnapshotscat-environment-applicationid)
|
|
168
|
+
* [`kourou paas:snapshots:dump ENVIRONMENT APPLICATIONID`](#kourou-paassnapshotsdump-environment-applicationid)
|
|
169
|
+
* [`kourou paas:snapshots:restore ENVIRONMENT APPLICATIONID SNAPSHOTID`](#kourou-paassnapshotsrestore-environment-applicationid-snapshotid)
|
|
170
|
+
* [`kourou profile:export`](#kourou-profileexport)
|
|
171
|
+
* [`kourou profile:import PATH`](#kourou-profileimport-path)
|
|
172
|
+
* [`kourou realtime:subscribe INDEX COLLECTION [FILTERS]`](#kourou-realtimesubscribe-index-collection-filters)
|
|
173
|
+
* [`kourou redis:list-keys [MATCH]`](#kourou-redislist-keys-match)
|
|
174
|
+
* [`kourou role:export`](#kourou-roleexport)
|
|
175
|
+
* [`kourou role:import PATH`](#kourou-roleimport-path)
|
|
176
|
+
* [`kourou sdk:execute [CODE]`](#kourou-sdkexecute-code)
|
|
177
|
+
* [`kourou sdk:query CONTROLLER:ACTION`](#kourou-sdkquery-controlleraction)
|
|
178
|
+
* [`kourou user:export`](#kourou-userexport)
|
|
179
|
+
* [`kourou user:export-mappings`](#kourou-userexport-mappings)
|
|
180
|
+
* [`kourou user:import PATH`](#kourou-userimport-path)
|
|
181
|
+
* [`kourou user:import-mappings PATH`](#kourou-userimport-mappings-path)
|
|
182
|
+
* [`kourou vault:add SECRETS-FILE KEY VALUE`](#kourou-vaultadd-secrets-file-key-value)
|
|
183
|
+
* [`kourou vault:decrypt FILE`](#kourou-vaultdecrypt-file)
|
|
184
|
+
* [`kourou vault:encrypt FILE`](#kourou-vaultencrypt-file)
|
|
185
|
+
* [`kourou vault:show SECRETS-FILE [KEY]`](#kourou-vaultshow-secrets-file-key)
|
|
186
|
+
* [`kourou vault:test SECRETS-FILE`](#kourou-vaulttest-secrets-file)
|
|
195
187
|
|
|
196
188
|
## `kourou api-key:check TOKEN`
|
|
197
189
|
|
|
@@ -377,9 +369,7 @@ ARGUMENTS
|
|
|
377
369
|
DESTINATION Directory to scaffold the app
|
|
378
370
|
|
|
379
371
|
OPTIONS
|
|
380
|
-
--flavor=flavor [default: generic] Template flavor ("generic", "iot
|
|
381
|
-
Those can be found here: https://github.com/kuzzleio/project-templates
|
|
382
|
-
|
|
372
|
+
--flavor=flavor [default: generic] Template flavor ("generic", "iot").
|
|
383
373
|
--help show CLI help
|
|
384
374
|
```
|
|
385
375
|
|
|
@@ -421,7 +411,7 @@ EXAMPLES
|
|
|
421
411
|
$ kourou autocomplete --refresh-cache
|
|
422
412
|
```
|
|
423
413
|
|
|
424
|
-
_See code: [@oclif/plugin-autocomplete](https://github.com/oclif/plugin-autocomplete/blob/v1.3.
|
|
414
|
+
_See code: [@oclif/plugin-autocomplete](https://github.com/oclif/plugin-autocomplete/blob/v1.3.10/src/commands/autocomplete/index.ts)_
|
|
425
415
|
|
|
426
416
|
## `kourou collection:create INDEX COLLECTION [BODY]`
|
|
427
417
|
|
|
@@ -885,7 +875,7 @@ OPTIONS
|
|
|
885
875
|
--all see all commands in CLI
|
|
886
876
|
```
|
|
887
877
|
|
|
888
|
-
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v3.2.
|
|
878
|
+
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v3.2.18/src/commands/help.ts)_
|
|
889
879
|
|
|
890
880
|
## `kourou import PATH`
|
|
891
881
|
|
|
@@ -1108,6 +1098,31 @@ OPTIONS
|
|
|
1108
1098
|
|
|
1109
1099
|
_See code: [src/commands/paas/login.ts](src/commands/paas/login.ts)_
|
|
1110
1100
|
|
|
1101
|
+
## `kourou paas:logs ENVIRONMENT APPLICATION`
|
|
1102
|
+
|
|
1103
|
+
Show logs of the targeted application
|
|
1104
|
+
|
|
1105
|
+
```
|
|
1106
|
+
USAGE
|
|
1107
|
+
$ kourou paas:logs ENVIRONMENT APPLICATION
|
|
1108
|
+
|
|
1109
|
+
ARGUMENTS
|
|
1110
|
+
ENVIRONMENT Kuzzle PaaS environment
|
|
1111
|
+
APPLICATION Kuzzle PaaS application
|
|
1112
|
+
|
|
1113
|
+
OPTIONS
|
|
1114
|
+
-f, --follow Follow log output
|
|
1115
|
+
-n, --tail=tail Number of lines to show from the end of the logs
|
|
1116
|
+
-t, --timestamp Show timestamp
|
|
1117
|
+
--help show CLI help
|
|
1118
|
+
--podName=podName Name of the pod to show logs from
|
|
1119
|
+
--project=project Current PaaS project
|
|
1120
|
+
--since=since Display logs from a specific absolute (e.g. 2022/12/02 09:41) or relative (e.g. a minute ago) time
|
|
1121
|
+
--until=until Display logs until a specific absolute (e.g. 2022/12/02 09:41) or relative (e.g. a minute ago) time
|
|
1122
|
+
```
|
|
1123
|
+
|
|
1124
|
+
_See code: [src/commands/paas/logs.ts](src/commands/paas/logs.ts)_
|
|
1125
|
+
|
|
1111
1126
|
## `kourou paas:snapshots:cat ENVIRONMENT APPLICATIONID`
|
|
1112
1127
|
|
|
1113
1128
|
List all snapshots for a given kuzzle application in a environment
|
|
@@ -1124,13 +1139,16 @@ OPTIONS
|
|
|
1124
1139
|
--help show CLI help
|
|
1125
1140
|
--project=project Current PaaS project
|
|
1126
1141
|
--token=token Authentication token
|
|
1142
|
+
|
|
1143
|
+
EXAMPLE
|
|
1144
|
+
kourou paas:snapshots:cat --project paas-project-myproject api main
|
|
1127
1145
|
```
|
|
1128
1146
|
|
|
1129
1147
|
_See code: [src/commands/paas/snapshots/cat.ts](src/commands/paas/snapshots/cat.ts)_
|
|
1130
1148
|
|
|
1131
1149
|
## `kourou paas:snapshots:dump ENVIRONMENT APPLICATIONID`
|
|
1132
1150
|
|
|
1133
|
-
|
|
1151
|
+
Create a new snapshot of the current application state
|
|
1134
1152
|
|
|
1135
1153
|
```
|
|
1136
1154
|
USAGE
|
|
@@ -1144,13 +1162,16 @@ OPTIONS
|
|
|
1144
1162
|
--help show CLI help
|
|
1145
1163
|
--project=project Current PaaS project
|
|
1146
1164
|
--token=token Authentication token
|
|
1165
|
+
|
|
1166
|
+
EXAMPLE
|
|
1167
|
+
kourou paas:snapshots:dump --project paas-project-myproject api main
|
|
1147
1168
|
```
|
|
1148
1169
|
|
|
1149
1170
|
_See code: [src/commands/paas/snapshots/dump.ts](src/commands/paas/snapshots/dump.ts)_
|
|
1150
1171
|
|
|
1151
1172
|
## `kourou paas:snapshots:restore ENVIRONMENT APPLICATIONID SNAPSHOTID`
|
|
1152
1173
|
|
|
1153
|
-
|
|
1174
|
+
Restore a snapshot of the current application state
|
|
1154
1175
|
|
|
1155
1176
|
```
|
|
1156
1177
|
USAGE
|
|
@@ -1165,6 +1186,9 @@ OPTIONS
|
|
|
1165
1186
|
--help show CLI help
|
|
1166
1187
|
--project=project Current PaaS project
|
|
1167
1188
|
--token=token Authentication token
|
|
1189
|
+
|
|
1190
|
+
EXAMPLE
|
|
1191
|
+
kourou paas:snapshots:restore --project paas-project-myproject api main snapshot-id
|
|
1168
1192
|
```
|
|
1169
1193
|
|
|
1170
1194
|
_See code: [src/commands/paas/snapshots/restore.ts](src/commands/paas/snapshots/restore.ts)_
|
|
@@ -7,6 +7,7 @@ const kuzzle_1 = require("../../support/kuzzle");
|
|
|
7
7
|
const elasticsearch_1 = require("@elastic/elasticsearch");
|
|
8
8
|
const execute_1 = require("../../support/execute");
|
|
9
9
|
const lodash_1 = (0, tslib_1.__importDefault)(require("lodash"));
|
|
10
|
+
const checkPrerequisites_1 = require("../../support/docker/checkPrerequisites");
|
|
10
11
|
class AppDoctor extends common_1.Kommand {
|
|
11
12
|
constructor() {
|
|
12
13
|
super(...arguments);
|
|
@@ -169,21 +170,11 @@ class AppDoctor extends common_1.Kommand {
|
|
|
169
170
|
suggestions.push(`Install missing libraries: sudo apt-get install ${notInstalled.join(" ")}`);
|
|
170
171
|
}
|
|
171
172
|
this.log("Docker checks");
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
if (matches === null || matches.length === 0) {
|
|
176
|
-
this.logKo("Docker Version cannot be found");
|
|
177
|
-
}
|
|
178
|
-
else {
|
|
179
|
-
this.logOk(`Docker Compose Version: ${matches[1]}`);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
catch (error) {
|
|
183
|
-
this.logKo("Docker Compose cannot be found");
|
|
184
|
-
suggestions.push("Install Docker Compose with 'npm run install:docker'");
|
|
173
|
+
const result = await (0, checkPrerequisites_1.checkPrerequisites)(this);
|
|
174
|
+
if (!result) {
|
|
175
|
+
suggestions.push("Install Docker and the Compose plugin");
|
|
185
176
|
}
|
|
186
|
-
this.log(`----------------- DoKtor
|
|
177
|
+
this.log(`----------------- DoKtor finished its job ! -----------------`);
|
|
187
178
|
this.log(`He suggest you to check the following points:`);
|
|
188
179
|
for (const suggestion of suggestions) {
|
|
189
180
|
this.logInfo(" => " + suggestion);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { flags } from "@oclif/command";
|
|
2
2
|
import { Kommand } from "../../common";
|
|
3
3
|
export default class AppScaffold extends Kommand {
|
|
4
|
+
templatesDir: string;
|
|
4
5
|
static initSdk: boolean;
|
|
5
6
|
static description: string;
|
|
6
7
|
static flags: {
|
|
@@ -13,5 +14,10 @@ export default class AppScaffold extends Kommand {
|
|
|
13
14
|
required: boolean;
|
|
14
15
|
}[];
|
|
15
16
|
runSafe(): Promise<void>;
|
|
16
|
-
|
|
17
|
+
getRepo(flavor: string): "template-kuzzle-project" | "template-kiotp-project";
|
|
18
|
+
checkDestination(destination: string): Promise<void>;
|
|
19
|
+
prepareTemplate(): Promise<void>;
|
|
20
|
+
cloneTemplate(flavor: string): Promise<void>;
|
|
21
|
+
copyTemplate(destination: string): Promise<void>;
|
|
22
|
+
cleanup(): Promise<void>;
|
|
17
23
|
}
|
|
@@ -7,25 +7,77 @@ const listr_1 = (0, tslib_1.__importDefault)(require("listr"));
|
|
|
7
7
|
const common_1 = require("../../common");
|
|
8
8
|
const execute_1 = require("../../support/execute");
|
|
9
9
|
class AppScaffold extends common_1.Kommand {
|
|
10
|
+
constructor() {
|
|
11
|
+
super(...arguments);
|
|
12
|
+
this.templatesDir = "/tmp/kuzzle-templates";
|
|
13
|
+
}
|
|
10
14
|
async runSafe() {
|
|
11
15
|
const destination = this.args.destination;
|
|
12
16
|
const flavor = this.flags.flavor;
|
|
13
17
|
const tasks = new listr_1.default([
|
|
14
18
|
{
|
|
15
|
-
title: "
|
|
16
|
-
task: async () => this.
|
|
19
|
+
title: "Checking destination",
|
|
20
|
+
task: async () => this.checkDestination(destination),
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
title: "Prepare temporary folder",
|
|
24
|
+
task: async () => this.prepareTemplate(),
|
|
17
25
|
},
|
|
26
|
+
{
|
|
27
|
+
title: "Cloning template repository",
|
|
28
|
+
task: async () => this.cloneTemplate(flavor)
|
|
29
|
+
}, {
|
|
30
|
+
title: "Copying template files",
|
|
31
|
+
task: async () => this.copyTemplate(destination)
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
title: "Cleaning up",
|
|
35
|
+
task: async () => this.cleanup()
|
|
36
|
+
}
|
|
18
37
|
]);
|
|
19
38
|
await tasks.run();
|
|
20
39
|
this.log("");
|
|
21
|
-
this.logOk(`Scaffolding complete
|
|
40
|
+
this.logOk(`Scaffolding complete!`);
|
|
41
|
+
this.logOk(`Use ${chalk_1.default.blue.bold(`cd ${destination} && docker compose up -d`)} to start your Kuzzle stack.`);
|
|
42
|
+
}
|
|
43
|
+
getRepo(flavor) {
|
|
44
|
+
console.log(flavor);
|
|
45
|
+
switch (flavor) {
|
|
46
|
+
case "generic":
|
|
47
|
+
return "template-kuzzle-project";
|
|
48
|
+
case "iot":
|
|
49
|
+
return "template-kiotp-project";
|
|
50
|
+
default:
|
|
51
|
+
return "template-kuzzle-project";
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async checkDestination(destination) {
|
|
55
|
+
let process;
|
|
56
|
+
try {
|
|
57
|
+
process = await (0, execute_1.execute)("test", "-d", destination);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (error.result.exitCode === 1) {
|
|
61
|
+
// Destination directory does not exist
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (process.exitCode === 0) {
|
|
66
|
+
throw new Error(`Destination directory ${destination} already exists.`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async prepareTemplate() {
|
|
70
|
+
await (0, execute_1.execute)("rm", "-rf", this.templatesDir);
|
|
71
|
+
}
|
|
72
|
+
async cloneTemplate(flavor) {
|
|
73
|
+
const repo = this.getRepo(flavor);
|
|
74
|
+
await (0, execute_1.execute)("git", "clone", "--depth=1", `https://github.com/kuzzleio/${repo}`, "--branch", "master", "--single-branch", this.templatesDir);
|
|
75
|
+
}
|
|
76
|
+
async copyTemplate(destination) {
|
|
77
|
+
await (0, execute_1.execute)("cp", "-r", `${this.templatesDir}/`, `${destination}/`);
|
|
22
78
|
}
|
|
23
|
-
async
|
|
24
|
-
|
|
25
|
-
await (0, execute_1.execute)("rm", "-rf", templatesDir);
|
|
26
|
-
await (0, execute_1.execute)("git", "clone", "--depth=1", "https://github.com/kuzzleio/project-templates", "--branch", flavor, "--single-branch", templatesDir);
|
|
27
|
-
await (0, execute_1.execute)("cp", "-r", `${templatesDir}/${flavor}`, `${destination}/`);
|
|
28
|
-
await (0, execute_1.execute)("rm", "-rf", templatesDir);
|
|
79
|
+
async cleanup() {
|
|
80
|
+
await (0, execute_1.execute)("rm", "-rf", this.templatesDir);
|
|
29
81
|
}
|
|
30
82
|
}
|
|
31
83
|
exports.default = AppScaffold;
|
|
@@ -35,8 +87,7 @@ AppScaffold.flags = {
|
|
|
35
87
|
help: command_1.flags.help(),
|
|
36
88
|
flavor: command_1.flags.string({
|
|
37
89
|
default: "generic",
|
|
38
|
-
description: `Template flavor ("generic", "iot
|
|
39
|
-
Those can be found here: https://github.com/kuzzleio/project-templates`,
|
|
90
|
+
description: `Template flavor ("generic", "iot").`,
|
|
40
91
|
}),
|
|
41
92
|
};
|
|
42
93
|
AppScaffold.args = [
|
|
@@ -5,11 +5,10 @@ const fs_1 = require("fs");
|
|
|
5
5
|
const path_1 = (0, tslib_1.__importDefault)(require("path"));
|
|
6
6
|
const command_1 = require("@oclif/command");
|
|
7
7
|
const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
|
|
8
|
-
const listr_1 = (0, tslib_1.__importDefault)(require("listr"));
|
|
9
8
|
const node_emoji_1 = (0, tslib_1.__importDefault)(require("node-emoji"));
|
|
10
9
|
const common_1 = require("../../common");
|
|
11
10
|
const execute_1 = require("../../support/execute");
|
|
12
|
-
const
|
|
11
|
+
const checkPrerequisites_1 = require("../../support/docker/checkPrerequisites");
|
|
13
12
|
const kuzzleServicesFile = `
|
|
14
13
|
version: '3'
|
|
15
14
|
|
|
@@ -31,7 +30,7 @@ class AppStartServices extends common_1.Kommand {
|
|
|
31
30
|
this.createKourouDir();
|
|
32
31
|
const docoFilename = path_1.default.join(this.kourouDir, "kuzzle-services.yml");
|
|
33
32
|
const successfullCheck = this.flags.check
|
|
34
|
-
? await
|
|
33
|
+
? await (0, checkPrerequisites_1.checkPrerequisites)(this)
|
|
35
34
|
: true;
|
|
36
35
|
if (this.flags.check && successfullCheck) {
|
|
37
36
|
this.log(`\n${node_emoji_1.default.get("ok_hand")} Prerequisites are ${chalk_1.default.green.bold("OK")}!`);
|
|
@@ -39,62 +38,22 @@ class AppStartServices extends common_1.Kommand {
|
|
|
39
38
|
else if (this.flags.check && !successfullCheck) {
|
|
40
39
|
throw new Error(`${node_emoji_1.default.get("shrug")} Your system doesn't satisfy all the prerequisites. Cannot run Kuzzle services.`);
|
|
41
40
|
}
|
|
42
|
-
this.log(chalk_1.default.grey(`\nWriting
|
|
41
|
+
this.log(chalk_1.default.grey(`\nWriting the Docker Compose file to ${docoFilename}...\n`));
|
|
43
42
|
(0, fs_1.writeFileSync)(docoFilename, kuzzleServicesFile);
|
|
44
43
|
// clean up
|
|
45
|
-
await (0, execute_1.execute)("docker
|
|
44
|
+
await (0, execute_1.execute)("docker", "compose", "-f", docoFilename, "down");
|
|
46
45
|
try {
|
|
47
|
-
await (0, execute_1.execute)("docker
|
|
46
|
+
await (0, execute_1.execute)("docker", "compose", "-f", docoFilename, "up", "-d");
|
|
48
47
|
this.logOk("Elasticsearch and Redis are booting in the background right now.");
|
|
49
48
|
this.log(chalk_1.default.grey("\nTo watch the logs, run"));
|
|
50
|
-
this.log(chalk_1.default.
|
|
51
|
-
this.log(
|
|
52
|
-
this.log(
|
|
49
|
+
this.log(chalk_1.default.blue.bold(` docker compose -f ${docoFilename} logs -f\n`));
|
|
50
|
+
this.log(` Elasticsearch port: ${chalk_1.default.bold("9200")}`);
|
|
51
|
+
this.log(` Redis port: ${chalk_1.default.bold("6379")}`);
|
|
53
52
|
}
|
|
54
53
|
catch (error) {
|
|
55
54
|
this.logKo(` Something went wrong: ${error.message}`);
|
|
56
55
|
this.log(chalk_1.default.grey("If you want to investigate the problem, try running"));
|
|
57
|
-
this.log(chalk_1.default.grey(` docker
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
async checkPrerequisites() {
|
|
61
|
-
this.log(chalk_1.default.grey("Checking prerequisites..."));
|
|
62
|
-
const checks = new listr_1.default([
|
|
63
|
-
{
|
|
64
|
-
title: `docker-compose exists and the version is at least ${MIN_DOCO_VERSION}`,
|
|
65
|
-
task: async () => {
|
|
66
|
-
try {
|
|
67
|
-
const docov = await (0, execute_1.execute)("docker-compose", "-v");
|
|
68
|
-
const matches = docov.stdout.match(/[^0-9.]*([0-9.]*).*/);
|
|
69
|
-
if (matches === null) {
|
|
70
|
-
throw new Error("Unable to read docker-compose verson. This is weird.");
|
|
71
|
-
}
|
|
72
|
-
const docoVersion = matches.length > 0 ? matches[1] : null;
|
|
73
|
-
if (docoVersion === null) {
|
|
74
|
-
throw new Error("Unable to read docker-compose version. This is weird.");
|
|
75
|
-
}
|
|
76
|
-
try {
|
|
77
|
-
if (docoVersion < MIN_DOCO_VERSION) {
|
|
78
|
-
throw new Error(`The detected version of docker-compose (${docoVersion}) is not recent enough (${MIN_DOCO_VERSION})`);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
catch (error) {
|
|
82
|
-
throw new Error(error);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
catch (error) {
|
|
86
|
-
throw new Error("No docker-compose found. Are you sure docker-compose is installed?");
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
|
-
]);
|
|
91
|
-
try {
|
|
92
|
-
await checks.run();
|
|
93
|
-
return true;
|
|
94
|
-
}
|
|
95
|
-
catch (error) {
|
|
96
|
-
this.logKo(error.message);
|
|
97
|
-
return false;
|
|
56
|
+
this.log(chalk_1.default.grey(` docker compose -f ${docoFilename} up\n`));
|
|
98
57
|
}
|
|
99
58
|
}
|
|
100
59
|
}
|
|
@@ -50,7 +50,8 @@ class InstanceLogs extends common_1.Kommand {
|
|
|
50
50
|
cli_ux_1.default.action.start(`${node_emoji_1.default.get("boom")} Killing Kuzzle instance ${instanceName}`, undefined, {
|
|
51
51
|
stdout: true,
|
|
52
52
|
});
|
|
53
|
-
const instanceKill = (0, child_process_1.spawn)("docker
|
|
53
|
+
const instanceKill = (0, child_process_1.spawn)("docker", [
|
|
54
|
+
"compose",
|
|
54
55
|
"-f",
|
|
55
56
|
docoFilename,
|
|
56
57
|
"-p",
|
|
@@ -8,12 +8,12 @@ const command_1 = require("@oclif/command");
|
|
|
8
8
|
const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
|
|
9
9
|
const child_process_1 = require("child_process");
|
|
10
10
|
const cli_ux_1 = (0, tslib_1.__importDefault)(require("cli-ux"));
|
|
11
|
-
const listr_1 = (0, tslib_1.__importDefault)(require("listr"));
|
|
12
11
|
const node_emoji_1 = (0, tslib_1.__importDefault)(require("node-emoji"));
|
|
13
12
|
const common_1 = require("../../common");
|
|
14
13
|
const execute_1 = require("../../support/execute");
|
|
14
|
+
const checkPrerequisites_1 = require("../../support/docker/checkPrerequisites");
|
|
15
15
|
const MIN_MAX_MAP_COUNT = 262144;
|
|
16
|
-
const MIN_DOCO_VERSION = "
|
|
16
|
+
const MIN_DOCO_VERSION = "2.0.0";
|
|
17
17
|
const kuzzleStackV1 = (increment) => `
|
|
18
18
|
version: '3'
|
|
19
19
|
|
|
@@ -89,7 +89,7 @@ class InstanceSpawn extends common_1.Kommand {
|
|
|
89
89
|
const portIndex = await this.findAvailablePort();
|
|
90
90
|
const docoFilename = path_1.default.join(this.kourouDir, `kuzzle-stack-${portIndex}.yml`);
|
|
91
91
|
const successfullCheck = this.flags.check
|
|
92
|
-
? await
|
|
92
|
+
? await (0, checkPrerequisites_1.checkPrerequisites)(this)
|
|
93
93
|
: true;
|
|
94
94
|
if (this.flags.check && successfullCheck) {
|
|
95
95
|
this.log(`\n${node_emoji_1.default.get("ok_hand")} Prerequisites are ${chalk_1.default.green.bold("OK")}!`);
|
|
@@ -97,11 +97,12 @@ class InstanceSpawn extends common_1.Kommand {
|
|
|
97
97
|
else if (this.flags.check && !successfullCheck) {
|
|
98
98
|
throw new Error(`${node_emoji_1.default.get("shrug")} Your system doesn't satisfy all the prerequisites. Cannot run Kuzzle.`);
|
|
99
99
|
}
|
|
100
|
-
this.log(chalk_1.default.grey(`\nWriting docker
|
|
100
|
+
this.log(chalk_1.default.grey(`\nWriting docker compose file to ${docoFilename}...`));
|
|
101
101
|
(0, fs_1.writeFileSync)(docoFilename, this.generateDocoFile(this.flags.version, portIndex));
|
|
102
102
|
// clean up
|
|
103
|
-
await (0, execute_1.execute)("docker
|
|
104
|
-
const doco = (0, child_process_1.spawn)("docker
|
|
103
|
+
await (0, execute_1.execute)("docker", "compose", "-f", docoFilename, "-p", `stack-${portIndex}`, "down");
|
|
104
|
+
const doco = (0, child_process_1.spawn)("docker", [
|
|
105
|
+
"compose",
|
|
105
106
|
"-f",
|
|
106
107
|
docoFilename,
|
|
107
108
|
"-p",
|
|
@@ -117,78 +118,20 @@ class InstanceSpawn extends common_1.Kommand {
|
|
|
117
118
|
cli_ux_1.default.action.stop("done");
|
|
118
119
|
this.log(`\n${node_emoji_1.default.get("thumbsup")} ${chalk_1.default.bold("Kuzzle is booting")} in the background right now.`);
|
|
119
120
|
this.log(chalk_1.default.grey("To watch the logs, run"));
|
|
120
|
-
this.log(chalk_1.default.grey(` docker
|
|
121
|
+
this.log(chalk_1.default.grey(` docker compose -f ${docoFilename} -p stack-${portIndex} logs -f\n`));
|
|
121
122
|
this.log(` Kuzzle port: ${7512 + portIndex}`);
|
|
122
123
|
this.log(` MQTT port: ${1883 + portIndex}`);
|
|
123
124
|
this.log(` Node.js debugger port: ${9229 + portIndex}`);
|
|
124
125
|
this.log(` Elasticsearch port: ${9200 + portIndex}`);
|
|
125
126
|
}
|
|
126
127
|
else {
|
|
127
|
-
cli_ux_1.default.action.stop(chalk_1.default.red(` Something went wrong: docker
|
|
128
|
+
cli_ux_1.default.action.stop(chalk_1.default.red(` Something went wrong: docker compose exited with ${docoCode}`));
|
|
128
129
|
this.log(chalk_1.default.grey("If you want to investigate the problem, try running"));
|
|
129
|
-
this.log(chalk_1.default.grey(` docker
|
|
130
|
-
throw new Error("docker
|
|
130
|
+
this.log(chalk_1.default.grey(` docker compose -f ${docoFilename} -p stack-${portIndex} up\n`));
|
|
131
|
+
throw new Error("docker compose exited with a non-zero status");
|
|
131
132
|
}
|
|
132
133
|
});
|
|
133
134
|
}
|
|
134
|
-
async checkPrerequisites() {
|
|
135
|
-
this.log(chalk_1.default.grey("Checking prerequisites..."));
|
|
136
|
-
const checks = new listr_1.default([
|
|
137
|
-
{
|
|
138
|
-
title: `docker-compose exists and the version is at least ${MIN_DOCO_VERSION}`,
|
|
139
|
-
task: async () => {
|
|
140
|
-
try {
|
|
141
|
-
const docov = await (0, execute_1.execute)("docker-compose", "-v");
|
|
142
|
-
const matches = docov.stdout.match(/[^0-9.]*([0-9.]*).*/);
|
|
143
|
-
if (matches === null) {
|
|
144
|
-
throw new Error("Unable to read docker-compose verson. This is weird.");
|
|
145
|
-
}
|
|
146
|
-
const docoVersion = matches.length > 0 ? matches[1] : null;
|
|
147
|
-
if (docoVersion === null) {
|
|
148
|
-
throw new Error("Unable to read docker-compose version. This is weird.");
|
|
149
|
-
}
|
|
150
|
-
try {
|
|
151
|
-
if (docoVersion < MIN_DOCO_VERSION) {
|
|
152
|
-
throw new Error(`The detected version of docker-compose (${docoVersion}) is not recent enough (${MIN_DOCO_VERSION})`);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
catch (error) {
|
|
156
|
-
throw new Error(error);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
catch (error) {
|
|
160
|
-
throw new Error("No docker-compose found. Are you sure docker-compose is installed?");
|
|
161
|
-
}
|
|
162
|
-
},
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
title: `vm.max_map_count is greater than ${MIN_MAX_MAP_COUNT}`,
|
|
166
|
-
task: async () => {
|
|
167
|
-
try {
|
|
168
|
-
const sysctl = await (0, execute_1.execute)("/sbin/sysctl", "-n", "vm.max_map_count");
|
|
169
|
-
if (sysctl.exitCode !== 0) {
|
|
170
|
-
throw new Error("Something went wrong checking vm.max_map_count");
|
|
171
|
-
}
|
|
172
|
-
const value = parseInt(sysctl.stdout, 10);
|
|
173
|
-
if (value < MIN_MAX_MAP_COUNT) {
|
|
174
|
-
throw new Error(`vm.max_map_count must be at least ${MIN_MAX_MAP_COUNT} (found ${value})`);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
catch (error) {
|
|
178
|
-
throw new Error(`Something went wrong checking vm.max_map_count: ${error.message}`);
|
|
179
|
-
}
|
|
180
|
-
},
|
|
181
|
-
},
|
|
182
|
-
]);
|
|
183
|
-
try {
|
|
184
|
-
await checks.run();
|
|
185
|
-
return true;
|
|
186
|
-
}
|
|
187
|
-
catch (error) {
|
|
188
|
-
this.logKo(error.message);
|
|
189
|
-
return false;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
135
|
generateDocoFile(kuzzleMajor, portIndex) {
|
|
193
136
|
if (kuzzleMajor === "1") {
|
|
194
137
|
return kuzzleStackV1(portIndex);
|
|
@@ -58,6 +58,27 @@ class PaasLogs extends PaasKommand_1.PaasKommand {
|
|
|
58
58
|
since,
|
|
59
59
|
until,
|
|
60
60
|
});
|
|
61
|
+
// Don't continue if an error occurred
|
|
62
|
+
if (incomingMessage.statusCode !== 200) {
|
|
63
|
+
return new Promise((_, reject) => {
|
|
64
|
+
// Collect the whole response body
|
|
65
|
+
let responseBody = "";
|
|
66
|
+
incomingMessage.on("data", (buffer) => {
|
|
67
|
+
responseBody += buffer.toString();
|
|
68
|
+
});
|
|
69
|
+
incomingMessage.on("end", () => {
|
|
70
|
+
let response;
|
|
71
|
+
try {
|
|
72
|
+
response = JSON.parse(responseBody);
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
reject(new Error("An error occurred while parsing the error response body from Kuzzle"));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
reject(response.error);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
}
|
|
61
82
|
// Read the response line by line
|
|
62
83
|
const lineStream = readline.createInterface({
|
|
63
84
|
input: incomingMessage,
|
|
@@ -19,7 +19,7 @@ class PaasSnapshotsDump extends PaasKommand_1.PaasKommand {
|
|
|
19
19
|
this.logOk(result.body);
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
-
PaasSnapshotsDump.description = "
|
|
22
|
+
PaasSnapshotsDump.description = "Create a new snapshot of the current application state";
|
|
23
23
|
PaasSnapshotsDump.flags = {
|
|
24
24
|
help: command_1.flags.help(),
|
|
25
25
|
token: command_1.flags.string({
|
|
@@ -42,4 +42,5 @@ PaasSnapshotsDump.args = [
|
|
|
42
42
|
required: true,
|
|
43
43
|
}
|
|
44
44
|
];
|
|
45
|
+
PaasSnapshotsDump.examples = ["kourou paas:snapshots:dump --project paas-project-myproject api main"];
|
|
45
46
|
exports.default = PaasSnapshotsDump;
|
|
@@ -22,7 +22,7 @@ class PaasSnapshotsRestore extends PaasKommand_1.PaasKommand {
|
|
|
22
22
|
this.logInfo("Ok");
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
-
PaasSnapshotsRestore.description = "
|
|
25
|
+
PaasSnapshotsRestore.description = "Restore a snapshot of the current application state";
|
|
26
26
|
PaasSnapshotsRestore.flags = {
|
|
27
27
|
help: command_1.flags.help(),
|
|
28
28
|
token: command_1.flags.string({
|
|
@@ -50,4 +50,5 @@ PaasSnapshotsRestore.args = [
|
|
|
50
50
|
required: true,
|
|
51
51
|
}
|
|
52
52
|
];
|
|
53
|
+
PaasSnapshotsRestore.examples = ["kourou paas:snapshots:restore --project paas-project-myproject api main snapshot-id"];
|
|
53
54
|
exports.default = PaasSnapshotsRestore;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkPrerequisites = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const listr_1 = (0, tslib_1.__importDefault)(require("listr"));
|
|
6
|
+
const execute_1 = require("../execute");
|
|
7
|
+
const MIN_DOCO_VERSION = "2.0.0";
|
|
8
|
+
async function checkPrerequisites(ctx) {
|
|
9
|
+
const checks = new listr_1.default([
|
|
10
|
+
{
|
|
11
|
+
title: `docker compose exists and the version is at least ${MIN_DOCO_VERSION}`,
|
|
12
|
+
task: async () => {
|
|
13
|
+
const docov = await (0, execute_1.execute)("docker", "compose", "version");
|
|
14
|
+
const matches = docov.stdout.match(/[^0-9.]*([0-9.]*).*/);
|
|
15
|
+
const docoVersion = matches ? matches[1] : null;
|
|
16
|
+
ctx.logInfo(`Found Docker Compose version: ${docoVersion}`);
|
|
17
|
+
if (!docoVersion) {
|
|
18
|
+
throw new Error("Unable to read the version of Docker Compose. Are you sure Docker and the Compose plugin are installed?");
|
|
19
|
+
}
|
|
20
|
+
if (docoVersion < MIN_DOCO_VERSION) {
|
|
21
|
+
throw new Error(`Your version of Docker Compose (${docoVersion}) is below the required version (${MIN_DOCO_VERSION}).`);
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
]);
|
|
26
|
+
try {
|
|
27
|
+
await checks.run();
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
ctx.logKo(error.message);
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.checkPrerequisites = checkPrerequisites;
|
package/lib/support/execute.js
CHANGED
|
@@ -30,9 +30,7 @@ function execute(...args) {
|
|
|
30
30
|
const process = (0, child_process_1.spawn)(command, commandArgs, options);
|
|
31
31
|
let stdout = "";
|
|
32
32
|
let stderr = "";
|
|
33
|
-
// eslint-disable-next-line
|
|
34
33
|
process.stdout.on("data", (data) => (stdout += data.toString()));
|
|
35
|
-
// eslint-disable-next-line
|
|
36
34
|
process.stderr.on("data", (data) => (stderr += data.toString()));
|
|
37
35
|
const executor = new Promise((resolve, reject) => {
|
|
38
36
|
process.on("close", (code) => {
|
package/lib/support/kuzzle.js
CHANGED
|
@@ -164,7 +164,10 @@ class KuzzleSDK {
|
|
|
164
164
|
const options = {
|
|
165
165
|
method: "POST",
|
|
166
166
|
headers: {
|
|
167
|
+
Accept: "application/json",
|
|
168
|
+
"Accept-Encoding": "identity",
|
|
167
169
|
Authorization: `Bearer ${this.sdk.jwt}`,
|
|
170
|
+
Connection: "keep-alive",
|
|
168
171
|
"Content-Length": Buffer.byteLength(body),
|
|
169
172
|
"Content-Type": "application/json",
|
|
170
173
|
},
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kourou",
|
|
3
3
|
"description": "The CLI that helps you manage your Kuzzle instances",
|
|
4
|
-
"version": "0.26.
|
|
4
|
+
"version": "0.26.2",
|
|
5
5
|
"author": "The Kuzzle Team <support@kuzzle.io>",
|
|
6
6
|
"bin": {
|
|
7
7
|
"kourou": "./bin/run"
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"ndjson": "^2.0.0",
|
|
38
38
|
"node-emoji": "^1.10.0",
|
|
39
39
|
"node-fetch": "^2.6.7",
|
|
40
|
-
"production": "0.0.2",
|
|
40
|
+
"production": "^0.0.2",
|
|
41
41
|
"strip-json-comments": "^3.1.1",
|
|
42
42
|
"tar": "^6.1.11",
|
|
43
43
|
"tmp": "^0.2.1",
|