@cyklang/cli 0.7.1 → 0.7.4

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/build/Cmd.d.ts CHANGED
@@ -35,6 +35,13 @@ export declare function runShellCommand(command: string, args: string[]): Promis
35
35
  * @returns
36
36
  */
37
37
  export declare function spawnCommand(command: string, args: string[]): Promise<void>;
38
+ /**
39
+ * function spawnCommandData
40
+ * @param command
41
+ * @param args
42
+ * @returns
43
+ */
44
+ export declare function spawnCommandData(command: string, args: string[]): Promise<string>;
38
45
  /**
39
46
  * function readPackageJson
40
47
  * @returns
package/build/Cmd.js CHANGED
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.readPackageJson = exports.spawnCommand = exports.runShellCommand = exports.Cmd = void 0;
29
+ exports.readPackageJson = exports.spawnCommandData = exports.spawnCommand = exports.runShellCommand = exports.Cmd = void 0;
30
30
  const core_1 = require("@cyklang/core");
31
31
  const commander_1 = require("commander");
32
32
  const dotenv_1 = __importDefault(require("dotenv"));
@@ -168,6 +168,31 @@ function spawnCommand(command, args) {
168
168
  });
169
169
  }
170
170
  exports.spawnCommand = spawnCommand;
171
+ /**
172
+ * function spawnCommandData
173
+ * @param command
174
+ * @param args
175
+ * @returns
176
+ */
177
+ function spawnCommandData(command, args) {
178
+ let result = '';
179
+ const child_process = (0, child_process_1.spawn)(command, args);
180
+ return new Promise((resolve, reject) => {
181
+ child_process.stdout.on('data', (data) => {
182
+ result += String(data);
183
+ });
184
+ child_process.on('close', (code) => {
185
+ if (code === 0) {
186
+ // console.log(green('*') + ' ' + [command, ...args].join(' '))
187
+ resolve(result);
188
+ }
189
+ else {
190
+ reject(new Error([command, ...args].join(' ') + ' --> Error ' + code));
191
+ }
192
+ });
193
+ });
194
+ }
195
+ exports.spawnCommandData = spawnCommandData;
171
196
  /**
172
197
  * function readPackageJson
173
198
  * @returns
package/build/index.js CHANGED
@@ -71,16 +71,42 @@ async function startServer() {
71
71
  await (0, Cmd_1.spawnCommand)('docker', ['compose', 'up', '-d']);
72
72
  }
73
73
  if (orchestrator === 'kubernetes') {
74
+ // apply resource files
75
+ await (0, Cmd_1.spawnCommand)('kubectl', ['apply', '-f', path_1.default.join(process.cwd(), 'k8s')]);
76
+ // port-forward
74
77
  const portForwardPath = path_1.default.join(process.cwd(), 'k8s', 'port-forward');
75
78
  if (!fs.existsSync(portForwardPath) || !fs.statSync(portForwardPath).isFile())
76
79
  throw portForwardPath + ' file not found';
77
- const config = JSON.parse(fs.readFileSync(portForwardPath).toString());
78
- if (!config.postgres || !config.nodejs)
79
- throw portForwardPath + ' : file format incorrect';
80
- (0, Cmd_1.spawnCommand)('kubectl', ['port-forward', 'svc/postgres', config.postgres + ':5432']);
81
- logger.info('Postgresql proxy at localhost:' + config.postgres);
82
- (0, Cmd_1.spawnCommand)('kubectl', ['port-forward', 'svc/nodejs', config.nodejs + ':3000']);
83
- logger.info('Nodejs proxy at localhost:' + config.nodejs);
80
+ const portForwardContent = JSON.parse(fs.readFileSync(portForwardPath).toString());
81
+ // wait for the services to be available
82
+ while (true) {
83
+ const declared_services = await (0, Cmd_1.spawnCommandData)('kubectl', ['get', 'svc', '-o', 'name']);
84
+ let ok = true;
85
+ for (const service in portForwardContent) {
86
+ if (!Object.prototype.hasOwnProperty.call(portForwardContent, service))
87
+ continue;
88
+ if (!declared_services.includes(`service/${service}`)) {
89
+ ok = false;
90
+ break;
91
+ }
92
+ const avail = await serviceAvailable(service);
93
+ if (!avail) {
94
+ ok = false;
95
+ break;
96
+ }
97
+ }
98
+ if (ok)
99
+ break;
100
+ // wait for 1 second
101
+ logger.info('Wait for nodejs and postgres services...');
102
+ await new Promise((resolve) => setTimeout(() => {
103
+ resolve();
104
+ }, 1000));
105
+ }
106
+ for (const service in portForwardContent) {
107
+ (0, Cmd_1.spawnCommand)('kubectl', ['port-forward', `svc/${service}`, portForwardContent[service]]);
108
+ logger.info(`${service} proxy via localhost ${portForwardContent[service].split(':')[0]}`);
109
+ }
84
110
  }
85
111
  if (!orchestrator) {
86
112
  logger.error('No cyk server is defined in current folder ' + process.cwd());
@@ -90,6 +116,21 @@ async function startServer() {
90
116
  console.error(err);
91
117
  }
92
118
  }
119
+ /**
120
+ * function serviceAvailable
121
+ * @param service
122
+ * @returns
123
+ */
124
+ async function serviceAvailable(service) {
125
+ const descNodejs = await (0, Cmd_1.spawnCommandData)('kubectl', ['describe', 'service', service]);
126
+ const lines = descNodejs.split('\n');
127
+ for (const line of lines) {
128
+ if (line.includes('Endpoints')) {
129
+ return !line.includes('<none>');
130
+ }
131
+ }
132
+ return false;
133
+ }
93
134
  /**
94
135
  * function stopServer
95
136
  */
@@ -140,7 +181,7 @@ class StopCommand extends commander_1.Command {
140
181
  */
141
182
  const program = new commander_1.Command();
142
183
  program.name('cyk').description('cyklang CLI')
143
- .version('0.7.1');
184
+ .version('0.7.4');
144
185
  program.addCommand(new StartCommand('start'));
145
186
  program.addCommand(new StopCommand('stop'));
146
187
  program.addCommand(new InstallCommand_1.InstallCommand('install'));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cyklang/cli",
3
- "version": "0.7.1",
3
+ "version": "0.7.4",
4
4
  "description": "cyklang CLI",
5
5
  "main": "build/index.js",
6
6
  "scripts": {
package/src/Cmd.ts CHANGED
@@ -115,9 +115,6 @@ export class Cmd extends Command {
115
115
  });
116
116
  });
117
117
  }
118
-
119
-
120
-
121
118
  }
122
119
 
123
120
 
@@ -162,6 +159,31 @@ export function spawnCommand(command: string, args: string[]): Promise<void> {
162
159
  })
163
160
  }
164
161
 
162
+ /**
163
+ * function spawnCommandData
164
+ * @param command
165
+ * @param args
166
+ * @returns
167
+ */
168
+ export function spawnCommandData(command: string, args: string[]): Promise<string> {
169
+ let result = ''
170
+ const child_process = spawn(command, args)
171
+ return new Promise((resolve, reject) => {
172
+ child_process.stdout.on('data', (data) => {
173
+ result += String(data)
174
+ })
175
+ child_process.on('close', (code) => {
176
+ if (code === 0) {
177
+ // console.log(green('*') + ' ' + [command, ...args].join(' '))
178
+ resolve(result)
179
+ }
180
+ else {
181
+ reject(new Error([command, ...args].join(' ') + ' --> Error ' + code))
182
+ }
183
+ })
184
+ })
185
+ }
186
+
165
187
  /**
166
188
  * function readPackageJson
167
189
  * @returns
package/src/index.ts CHANGED
@@ -4,7 +4,7 @@ import * as fs from 'fs'
4
4
  import loglevel from 'loglevel'
5
5
  import path from 'path'
6
6
  import { AssetCommand } from './AssetCommand'
7
- import { Cmd, spawnCommand } from './Cmd'
7
+ import { Cmd, spawnCommand, spawnCommandData } from './Cmd'
8
8
  import { InstallCommand } from './InstallCommand'
9
9
  import { ModuleCommand } from "./ModuleCommand"
10
10
  import { OpenCommand } from './OpenCommand'
@@ -48,16 +48,53 @@ async function startServer() {
48
48
  await spawnCommand('docker', ['compose', 'up', '-d'])
49
49
  }
50
50
  if (orchestrator === 'kubernetes') {
51
+
52
+ // apply resource files
53
+ await spawnCommand('kubectl', ['apply', '-f', path.join(process.cwd(), 'k8s')])
54
+
55
+ // port-forward
51
56
  const portForwardPath = path.join(process.cwd(), 'k8s', 'port-forward')
52
57
  if (!fs.existsSync(portForwardPath) || !fs.statSync(portForwardPath).isFile())
53
58
  throw portForwardPath + ' file not found'
54
- const config = JSON.parse(fs.readFileSync(portForwardPath).toString())
55
- if (! config.postgres || ! config.nodejs)
56
- throw portForwardPath + ' : file format incorrect'
57
- spawnCommand('kubectl', ['port-forward', 'svc/postgres', config.postgres + ':5432'])
58
- logger.info('Postgresql proxy at localhost:' + config.postgres)
59
- spawnCommand('kubectl', ['port-forward', 'svc/nodejs', config.nodejs + ':3000'])
60
- logger.info('Nodejs proxy at localhost:' + config.nodejs)
59
+ const portForwardContent = JSON.parse(fs.readFileSync(portForwardPath).toString())
60
+
61
+ // wait for the services to be available
62
+
63
+ while (true) {
64
+
65
+ const declared_services = await spawnCommandData('kubectl', ['get', 'svc', '-o', 'name'])
66
+
67
+ let ok = true
68
+
69
+ for(const service in portForwardContent) {
70
+ if (! Object.prototype.hasOwnProperty.call(portForwardContent, service)) continue
71
+ if (! declared_services.includes(`service/${service}`)) {
72
+ ok = false
73
+ break
74
+ }
75
+ const avail = await serviceAvailable(service)
76
+ if (! avail) {
77
+ ok = false
78
+ break
79
+ }
80
+ }
81
+
82
+ if (ok) break
83
+
84
+ // wait for 1 second
85
+ logger.info('Wait for nodejs and postgres services...')
86
+ await new Promise<void>((resolve) =>
87
+ setTimeout(() => {
88
+ resolve();
89
+ }, 1000)
90
+ );
91
+ }
92
+
93
+ for(const service in portForwardContent) {
94
+ spawnCommand('kubectl', ['port-forward', `svc/${service}`, portForwardContent[service]])
95
+ logger.info(`${service} proxy via localhost ${portForwardContent[service].split(':')[0]}`)
96
+ }
97
+
61
98
  }
62
99
  if (!orchestrator) {
63
100
  logger.error('No cyk server is defined in current folder ' + process.cwd())
@@ -68,6 +105,23 @@ async function startServer() {
68
105
  }
69
106
  }
70
107
 
108
+ /**
109
+ * function serviceAvailable
110
+ * @param service
111
+ * @returns
112
+ */
113
+ async function serviceAvailable(service: string): Promise<boolean> {
114
+
115
+ const descNodejs = await spawnCommandData('kubectl', ['describe', 'service', service])
116
+ const lines = descNodejs.split('\n')
117
+ for (const line of lines) {
118
+ if (line.includes('Endpoints')) {
119
+ return !line.includes('<none>')
120
+ }
121
+ }
122
+ return false
123
+ }
124
+
71
125
  /**
72
126
  * function stopServer
73
127
  */
@@ -121,7 +175,7 @@ class StopCommand extends Command {
121
175
  */
122
176
  const program = new Command()
123
177
  program.name('cyk').description('cyklang CLI')
124
- .version('0.7.1')
178
+ .version('0.7.4')
125
179
  program.addCommand(new StartCommand('start'))
126
180
  program.addCommand(new StopCommand('stop'))
127
181
  program.addCommand(new InstallCommand('install'))