@steedos/service-package-registry 2.2.54-beta.1 → 2.2.54-beta.10
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/package.json +8 -8
- package/package.service.js +13 -675
- package/project.package.service.js +716 -0
|
@@ -0,0 +1,716 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
"use strict";
|
|
4
|
+
const loader = require('./main/default/manager/loader');
|
|
5
|
+
const packages = require('./main/default/manager/packages');
|
|
6
|
+
const registry = require('./main/default/manager/registry');
|
|
7
|
+
const metadata = require('@steedos/metadata-core')
|
|
8
|
+
const packageLicense = require('@steedos/service-package-license');
|
|
9
|
+
const axios = require('axios');
|
|
10
|
+
const _ = require(`lodash`);
|
|
11
|
+
const path = require(`path`);
|
|
12
|
+
const metadataApi = require('@steedos/metadata-api');
|
|
13
|
+
const util = require('./main/default/manager/util');
|
|
14
|
+
const fetch = require('node-fetch');
|
|
15
|
+
const fs = require('fs');
|
|
16
|
+
const { MoleculerError } = require("moleculer").Errors;
|
|
17
|
+
const validator = require('validator');
|
|
18
|
+
const npa = require("npm-package-arg");
|
|
19
|
+
const login = require('./main/default/manager/login');
|
|
20
|
+
|
|
21
|
+
const HEADER_AUTH = 'Authorization';
|
|
22
|
+
const AUTH_TYPE = 'Bearer';
|
|
23
|
+
|
|
24
|
+
const getPackageMetadata = async (packagePath)=>{
|
|
25
|
+
const packageMetadata = [];
|
|
26
|
+
const result = await metadataApi.loadFileToJson(packagePath, {
|
|
27
|
+
CustomApplication: '*',
|
|
28
|
+
CustomPermissionset: '*',
|
|
29
|
+
CustomProfile: '*',
|
|
30
|
+
CustomObject: '*',
|
|
31
|
+
Layout: '*',
|
|
32
|
+
CustomReport: '*',
|
|
33
|
+
Workflow: '*',
|
|
34
|
+
Flow: '*',
|
|
35
|
+
ApprovalProcess: '*',
|
|
36
|
+
Role: '*',
|
|
37
|
+
FlowRole: '*',
|
|
38
|
+
Query: '*',
|
|
39
|
+
Chart: '*',
|
|
40
|
+
Page: '*',
|
|
41
|
+
Tab: '*',
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
_.each(result, (metadataItems, metadataType)=>{
|
|
45
|
+
_.each(metadataItems, (metadata, apiName)=>{
|
|
46
|
+
packageMetadata.push({
|
|
47
|
+
label: metadata.label || metadata.name,
|
|
48
|
+
type: metadataType,
|
|
49
|
+
api_name: apiName
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
return packageMetadata;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @typedef {import('moleculer').Context} Context Moleculer's Context
|
|
58
|
+
* 软件包服务启动后也需要抛出事件。
|
|
59
|
+
*/
|
|
60
|
+
module.exports = {
|
|
61
|
+
name: '~packages-project-server',
|
|
62
|
+
namespace: "steedos",
|
|
63
|
+
/**
|
|
64
|
+
* Settings
|
|
65
|
+
*/
|
|
66
|
+
settings: {
|
|
67
|
+
packageInfo: {
|
|
68
|
+
path: __dirname,
|
|
69
|
+
name: this.name,
|
|
70
|
+
isPackage: false
|
|
71
|
+
},
|
|
72
|
+
STEEDOS_CLOUD_URL: process.env.STEEDOS_CLOUD_URL ? process.env.STEEDOS_CLOUD_URL : 'https://console.steedos.cn',
|
|
73
|
+
STEEDOS_CLOUD_SPACE_ID: process.env.STEEDOS_CLOUD_SPACE_ID,
|
|
74
|
+
STEEDOS_CLOUD_API_KEY: process.env.STEEDOS_CLOUD_API_KEY,
|
|
75
|
+
STEEDOS_REGISTRY_URL: process.env.STEEDOS_REGISTRY_URL ? process.env.STEEDOS_REGISTRY_URL : 'https://registry.steedos.cn/',
|
|
76
|
+
STEEDOS_CLOUD_SYNC_PACKAGES: validator.toBoolean(process.env.STEEDOS_CLOUD_SYNC_PACKAGES || 'false', true),
|
|
77
|
+
STEEDOS_INITIAL_PACKAGES: process.env.STEEDOS_INITIAL_PACKAGES
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Dependencies
|
|
82
|
+
*/
|
|
83
|
+
dependencies: ['~packages-standard-objects', '@steedos/service-package-license'],
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Actions
|
|
87
|
+
*/
|
|
88
|
+
actions: {
|
|
89
|
+
getProjectNodes: {
|
|
90
|
+
rest: {
|
|
91
|
+
method: "GET",
|
|
92
|
+
path: "/getProjectNodes"
|
|
93
|
+
},
|
|
94
|
+
async handler(ctx) {
|
|
95
|
+
const data = await ctx.broker.call('metadata.filter', {key: `#package_install_node.*`}, {meta: ctx.meta})
|
|
96
|
+
const nodes = [];
|
|
97
|
+
_.each(data,(item)=>{
|
|
98
|
+
nodes.push(item.metadata.nodeID)
|
|
99
|
+
})
|
|
100
|
+
let installNodes = _.uniq(_.compact(nodes));
|
|
101
|
+
|
|
102
|
+
if(installNodes.length === 0){
|
|
103
|
+
installNodes = [ctx.broker.nodeID]
|
|
104
|
+
}
|
|
105
|
+
return installNodes;
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
installPackage:{
|
|
109
|
+
async handler(ctx) {
|
|
110
|
+
const { module, version, label, description} = ctx.params
|
|
111
|
+
return await this.installPackage(module, version, label, description, true, ctx.broker);
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
uninstallPackage:{
|
|
115
|
+
async handler(ctx) {
|
|
116
|
+
const { module } = ctx.params
|
|
117
|
+
await loader.removePackage(module);
|
|
118
|
+
await registry.uninstallModule(module)
|
|
119
|
+
await ctx.broker.call(`@steedos/service-packages.uninstall`, {
|
|
120
|
+
serviceInfo: {
|
|
121
|
+
name: module,
|
|
122
|
+
nodeID: ctx.broker.nodeID,
|
|
123
|
+
instanceID: ctx.broker.instanceID,
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
return {};
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
reloadPackage:{
|
|
130
|
+
async handler(ctx) {
|
|
131
|
+
const { module } = ctx.params
|
|
132
|
+
const packages = loader.loadPackagesConfig();
|
|
133
|
+
const packageConfig = _.find(packages, (_p, pname) => {
|
|
134
|
+
return pname === module;
|
|
135
|
+
})
|
|
136
|
+
if (packageConfig) {
|
|
137
|
+
if (packageConfig.enable) {
|
|
138
|
+
if (packageConfig.local) {
|
|
139
|
+
let packagePath = packageConfig.path;
|
|
140
|
+
if(!path.isAbsolute(packagePath)){
|
|
141
|
+
packagePath = path.resolve(process.cwd(), packagePath)
|
|
142
|
+
}
|
|
143
|
+
await loader.loadPackage(module, packagePath);
|
|
144
|
+
const metadata = await getPackageMetadata(util.getPackageRelativePath(process.cwd(), packageConfig.path));
|
|
145
|
+
await ctx.broker.call(`@steedos/service-packages.install`, {
|
|
146
|
+
serviceInfo: Object.assign({}, Object.assign({}, packageConfig, { name: module }), {
|
|
147
|
+
nodeID: ctx.broker.nodeID,
|
|
148
|
+
instanceID: ctx.broker.instanceID,
|
|
149
|
+
metadata: metadata
|
|
150
|
+
})
|
|
151
|
+
})
|
|
152
|
+
}else{
|
|
153
|
+
await loader.loadPackage(module);
|
|
154
|
+
}
|
|
155
|
+
}else{
|
|
156
|
+
throw new Error('package is disable: ' + module )
|
|
157
|
+
}
|
|
158
|
+
}else{
|
|
159
|
+
throw new Error('not find package: ' + module)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return {}
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
disablePackage:{
|
|
166
|
+
async handler(ctx) {
|
|
167
|
+
const { module } = ctx.params
|
|
168
|
+
const packageConfig = await loader.disablePackage(module);
|
|
169
|
+
if(packageConfig.path){
|
|
170
|
+
const metadata = await getPackageMetadata(util.getPackageRelativePath(process.cwd(), packageConfig.path));
|
|
171
|
+
await ctx.broker.call(`@steedos/service-packages.install`, {
|
|
172
|
+
serviceInfo: Object.assign({}, packageConfig, {
|
|
173
|
+
nodeID: ctx.broker.nodeID,
|
|
174
|
+
instanceID: ctx.broker.instanceID,
|
|
175
|
+
metadata: metadata
|
|
176
|
+
})
|
|
177
|
+
})
|
|
178
|
+
}
|
|
179
|
+
return {}
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
enablePackage:{
|
|
183
|
+
async handler(ctx) {
|
|
184
|
+
const { module } = ctx.params
|
|
185
|
+
const packageConfig = await loader.enablePackage(module);
|
|
186
|
+
const metadata = await getPackageMetadata(util.getPackageRelativePath(process.cwd(), packageConfig.path));
|
|
187
|
+
await ctx.broker.call(`@steedos/service-packages.install`, {
|
|
188
|
+
serviceInfo: Object.assign({}, packageConfig, {
|
|
189
|
+
nodeID: ctx.broker.nodeID,
|
|
190
|
+
instanceID: ctx.broker.instanceID,
|
|
191
|
+
metadata: metadata
|
|
192
|
+
})
|
|
193
|
+
})
|
|
194
|
+
return {}
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
getCloudSaasPurchasedPackages:{
|
|
198
|
+
rest: {
|
|
199
|
+
method: "GET",
|
|
200
|
+
path: "/cloud/saas/packages/purchased"
|
|
201
|
+
},
|
|
202
|
+
async handler(ctx) {
|
|
203
|
+
try {
|
|
204
|
+
|
|
205
|
+
const user = ctx.meta.user;
|
|
206
|
+
if(!user.is_space_admin){
|
|
207
|
+
throw new Error('not permission!');
|
|
208
|
+
}
|
|
209
|
+
return await this.getCloudSaasPurchasedPackages();
|
|
210
|
+
} catch (error) {
|
|
211
|
+
throw new MoleculerError(error.message, 500, "ERR_SOMETHING");
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
installPurchasedPackages: {
|
|
216
|
+
rest: {
|
|
217
|
+
method: "POST",
|
|
218
|
+
path: "/cloud/saas/packages/purchased"
|
|
219
|
+
},
|
|
220
|
+
async handler(ctx){
|
|
221
|
+
const installErrors = {};
|
|
222
|
+
const installPackages = [];
|
|
223
|
+
try {
|
|
224
|
+
const user = ctx.meta.user;
|
|
225
|
+
if(!user.is_space_admin){
|
|
226
|
+
throw new Error('not permission!');
|
|
227
|
+
}
|
|
228
|
+
try {
|
|
229
|
+
await this.loginSteedosRegistry();
|
|
230
|
+
console.info(`login steedos registry success`);
|
|
231
|
+
} catch (error) {
|
|
232
|
+
console.error(`login steedos registry fail: `, error.message);
|
|
233
|
+
}
|
|
234
|
+
const settings = this.settings;
|
|
235
|
+
const syncCloudPackages = settings.STEEDOS_CLOUD_SYNC_PACKAGES;
|
|
236
|
+
let result = null;
|
|
237
|
+
if(syncCloudPackages){
|
|
238
|
+
result = await this.getCloudSaasPurchasedPackages();
|
|
239
|
+
}
|
|
240
|
+
//同步软件包许可证
|
|
241
|
+
await this.broker.call(`@steedos/service-package-license.syncPackagesLicense`);
|
|
242
|
+
if(result){
|
|
243
|
+
for (const _package of result.packages) {
|
|
244
|
+
try {
|
|
245
|
+
const { name, version, label, description } = _package
|
|
246
|
+
let enable = true; //安装已购买的软件包时先默认启用
|
|
247
|
+
//TODO 处理 registry_url
|
|
248
|
+
// 安装最新版
|
|
249
|
+
const packageInfo = await this.installPackage(name, null, label, description, enable, ctx.broker);
|
|
250
|
+
installPackages.push(packageInfo)
|
|
251
|
+
} catch (error) {
|
|
252
|
+
if(error.stderr){
|
|
253
|
+
installErrors[_package.name] = error.stderr
|
|
254
|
+
}else{
|
|
255
|
+
installErrors[_package.name] = error.message
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return {
|
|
261
|
+
installPackages: installPackages,
|
|
262
|
+
installErrors: installErrors
|
|
263
|
+
}
|
|
264
|
+
} catch (error) {
|
|
265
|
+
throw new MoleculerError(error.message, 500, "ERR_SOMETHING");
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
getPackageVersions: {
|
|
270
|
+
async handler(ctx) {
|
|
271
|
+
const { module } = ctx.params
|
|
272
|
+
return await this.getPackageVersions(module);
|
|
273
|
+
}
|
|
274
|
+
},
|
|
275
|
+
upgradePackage: {
|
|
276
|
+
async handler(ctx) {
|
|
277
|
+
const { module, version } = ctx.params
|
|
278
|
+
//同步软件包许可证
|
|
279
|
+
await this.broker.call(`@steedos/service-package-license.syncPackagesLicense`);
|
|
280
|
+
return await this.upgradePackage(module, version);
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
installPackageFromUrl: {
|
|
284
|
+
rest: {
|
|
285
|
+
method: "POST",
|
|
286
|
+
path: "/cloud/saas/packages/url"
|
|
287
|
+
},
|
|
288
|
+
async handler(ctx){
|
|
289
|
+
try {
|
|
290
|
+
const user = ctx.meta.user;
|
|
291
|
+
if(!user.is_space_admin){
|
|
292
|
+
throw new Error('not permission!');
|
|
293
|
+
}
|
|
294
|
+
try {
|
|
295
|
+
await this.loginSteedosRegistry();
|
|
296
|
+
console.info(`login steedos registry success`);
|
|
297
|
+
} catch (error) {
|
|
298
|
+
console.error(`login steedos registry fail: `, error.message);
|
|
299
|
+
}
|
|
300
|
+
let { module, version, url, auth, registry_url } = ctx.params
|
|
301
|
+
const enable = true;
|
|
302
|
+
//同步软件包许可证
|
|
303
|
+
await this.broker.call(`@steedos/service-package-license.syncPackagesLicense`);
|
|
304
|
+
return await this.installPackageFromUrl(module, version, url, auth, enable, registry_url, ctx.broker)
|
|
305
|
+
} catch (error) {
|
|
306
|
+
let errorInfo = error.message || '';
|
|
307
|
+
if (error.stderr) {
|
|
308
|
+
const errors = error.stderr.split('\n');
|
|
309
|
+
errors.forEach(element => {
|
|
310
|
+
if (element) {
|
|
311
|
+
try {
|
|
312
|
+
const item = JSON.parse(element);
|
|
313
|
+
if (item.type === 'error') {
|
|
314
|
+
errorInfo = errorInfo + item.data + '\n'
|
|
315
|
+
}
|
|
316
|
+
} catch (error) {
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
throw new MoleculerError(errorInfo, 500, "ERR_SOMETHING");
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
},
|
|
325
|
+
initialPackages: {
|
|
326
|
+
async handler(ctx) {
|
|
327
|
+
return await this.initialPackages();
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
},
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Events
|
|
334
|
+
*/
|
|
335
|
+
events: {
|
|
336
|
+
|
|
337
|
+
},
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Methods
|
|
341
|
+
*/
|
|
342
|
+
methods: {
|
|
343
|
+
installPackage: {
|
|
344
|
+
async handler(module, version, label, description, enable, broker) {
|
|
345
|
+
const packagePath = await registry.installModule(module, version)
|
|
346
|
+
if(enable){
|
|
347
|
+
const packageInfo = await loader.loadPackage(module, packagePath);
|
|
348
|
+
}else{
|
|
349
|
+
enable = false;
|
|
350
|
+
}
|
|
351
|
+
const packageConfig = {
|
|
352
|
+
label: label,
|
|
353
|
+
version: version,
|
|
354
|
+
description: description || '',
|
|
355
|
+
local: false,
|
|
356
|
+
enable: enable,
|
|
357
|
+
path: util.getPackageRelativePath(process.cwd(), packagePath)
|
|
358
|
+
}
|
|
359
|
+
loader.appendToPackagesConfig(module, packageConfig);
|
|
360
|
+
const metadata = await getPackageMetadata(util.getPackageRelativePath(process.cwd(), packagePath));
|
|
361
|
+
await broker.call(`@steedos/service-packages.install`, {
|
|
362
|
+
serviceInfo: Object.assign({}, packageConfig, {
|
|
363
|
+
name: module,
|
|
364
|
+
enable: enable,
|
|
365
|
+
nodeID: broker.nodeID,
|
|
366
|
+
instanceID: broker.instanceID,
|
|
367
|
+
metadata: metadata
|
|
368
|
+
})
|
|
369
|
+
})
|
|
370
|
+
return packageConfig;
|
|
371
|
+
}
|
|
372
|
+
},
|
|
373
|
+
getCloudSaasPurchasedPackages:{
|
|
374
|
+
async handler() {
|
|
375
|
+
const settings = this.settings;
|
|
376
|
+
const apiKey = settings.STEEDOS_CLOUD_API_KEY || process.env.STEEDOS_CLOUD_API_KEY
|
|
377
|
+
const spaceId = settings.STEEDOS_CLOUD_SPACE_ID || process.env.STEEDOS_CLOUD_SPACE_ID
|
|
378
|
+
const url = settings.STEEDOS_CLOUD_URL
|
|
379
|
+
|
|
380
|
+
if(!apiKey || !spaceId || !url){
|
|
381
|
+
throw new Error(`请配置STEEDOS_CLOUD参数`);
|
|
382
|
+
}
|
|
383
|
+
const headers = Object.assign({}, {'Content-Type': 'application/json'}, { [HEADER_AUTH]: `${AUTH_TYPE} apikey,${apiKey}`});
|
|
384
|
+
const response = await fetch(`${url}/api/shop/product_subscriptions/steedos-packages`, {
|
|
385
|
+
method: 'GET', headers: headers
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
const result = await response.json();
|
|
389
|
+
|
|
390
|
+
if(result.status === 'error'){
|
|
391
|
+
throw new Error(`${url}: ${result.message}`)
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
const packages = [];
|
|
395
|
+
|
|
396
|
+
_.each(result.data, (item)=>{
|
|
397
|
+
if(item.product){
|
|
398
|
+
let isExist = _.find(packages, (_package)=>{
|
|
399
|
+
return _package.name === item.product.sku
|
|
400
|
+
})
|
|
401
|
+
if(!isExist){
|
|
402
|
+
packages.push({
|
|
403
|
+
name: item.product.sku,
|
|
404
|
+
version: null, //始终安装latest最新版
|
|
405
|
+
label: item.product.name,
|
|
406
|
+
description: item.product.description || ''
|
|
407
|
+
})
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
})
|
|
411
|
+
return { packages : packages}
|
|
412
|
+
}
|
|
413
|
+
},
|
|
414
|
+
getPackageVersions: {
|
|
415
|
+
async handler(module) {
|
|
416
|
+
return packages.getPackageVersions(module);
|
|
417
|
+
}
|
|
418
|
+
},
|
|
419
|
+
upgradePackage: {
|
|
420
|
+
async handler(module, version) {
|
|
421
|
+
//TODO 处理 registry_url
|
|
422
|
+
const packagePath = await registry.installModule(module, version);
|
|
423
|
+
const enable = true;
|
|
424
|
+
if(enable){
|
|
425
|
+
await loader.loadPackage(module, packagePath);
|
|
426
|
+
}else{
|
|
427
|
+
enable = false;
|
|
428
|
+
}
|
|
429
|
+
const packageConfig = {
|
|
430
|
+
version: version,
|
|
431
|
+
enable: enable,
|
|
432
|
+
path: util.getPackageRelativePath(process.cwd(), packagePath)
|
|
433
|
+
}
|
|
434
|
+
const newConfig = loader.appendToPackagesConfig(module, packageConfig);
|
|
435
|
+
const metadata = await getPackageMetadata(util.getPackageRelativePath(process.cwd(), packagePath));
|
|
436
|
+
await this.broker.call(`@steedos/service-packages.install`, {
|
|
437
|
+
serviceInfo: Object.assign({}, newConfig, {
|
|
438
|
+
name: module,
|
|
439
|
+
enable: enable,
|
|
440
|
+
nodeID: this.broker.nodeID,
|
|
441
|
+
instanceID: this.broker.instanceID,
|
|
442
|
+
metadata: metadata
|
|
443
|
+
})
|
|
444
|
+
})
|
|
445
|
+
return packageConfig;
|
|
446
|
+
}
|
|
447
|
+
},
|
|
448
|
+
installPackageFromUrl: {
|
|
449
|
+
async handler(module, version, url, auth, enable, registry_url, broker) {
|
|
450
|
+
if(!module || !_.isString(module) || !module.trim()){
|
|
451
|
+
throw new Error(`无效的软件包名称`);
|
|
452
|
+
} else {
|
|
453
|
+
module = module.trim();
|
|
454
|
+
}
|
|
455
|
+
if (url && !registry.isPackageUrl(url)) {
|
|
456
|
+
throw new Error(`无效的软件包地址`);
|
|
457
|
+
}
|
|
458
|
+
if (url) {
|
|
459
|
+
url = url.trim();
|
|
460
|
+
version = null;
|
|
461
|
+
} else {
|
|
462
|
+
url = null;
|
|
463
|
+
if (!version) {
|
|
464
|
+
version = 'latest'
|
|
465
|
+
} else {
|
|
466
|
+
version = version.trim();
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
const settings = this.settings;
|
|
471
|
+
if (url && url.startsWith(settings.STEEDOS_CLOUD_URL + '/api/pkg/download')) {
|
|
472
|
+
const apiKey = settings.STEEDOS_CLOUD_API_KEY || process.env.STEEDOS_CLOUD_API_KEY
|
|
473
|
+
const spaceId = settings.STEEDOS_CLOUD_SPACE_ID || process.env.STEEDOS_CLOUD_SPACE_ID
|
|
474
|
+
const cloudUrl = settings.STEEDOS_CLOUD_URL
|
|
475
|
+
|
|
476
|
+
if (!apiKey || !spaceId || !cloudUrl) {
|
|
477
|
+
throw new Error(`请配置STEEDOS_CLOUD参数`);
|
|
478
|
+
}
|
|
479
|
+
const headers = Object.assign({}, { 'Content-Type': 'application/json' }, { [HEADER_AUTH]: `${AUTH_TYPE} apikey,${apiKey}` });
|
|
480
|
+
const response = await fetch(url, {
|
|
481
|
+
method: 'POST', headers: headers, body: JSON.stringify({ _authToken: auth })
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
const result = await response.json();
|
|
485
|
+
|
|
486
|
+
if (result.error) {
|
|
487
|
+
throw new Error(`安装失败,软件包URL或认证信息错误`)
|
|
488
|
+
}
|
|
489
|
+
url = `${url}/${result.token}`
|
|
490
|
+
console.log(`url`, url);
|
|
491
|
+
}
|
|
492
|
+
const packagePath = await registry.installModule(module, version, url, registry_url);
|
|
493
|
+
const packageInfo = loader.getPackageInfo(null, packagePath);
|
|
494
|
+
const packageName = packageInfo.name;
|
|
495
|
+
if(enable){
|
|
496
|
+
await loader.loadPackage(packageName, packagePath);
|
|
497
|
+
}else{
|
|
498
|
+
enable = false;
|
|
499
|
+
}
|
|
500
|
+
const packageConfig = {
|
|
501
|
+
label: packageInfo.name,
|
|
502
|
+
version: packageInfo.version,
|
|
503
|
+
description: packageInfo.description || '',
|
|
504
|
+
local: false,
|
|
505
|
+
enable: enable,
|
|
506
|
+
url: url,
|
|
507
|
+
// registry_url: registry_url,
|
|
508
|
+
path: util.getPackageRelativePath(process.cwd(), packagePath)
|
|
509
|
+
}
|
|
510
|
+
loader.appendToPackagesConfig(packageName, packageConfig);
|
|
511
|
+
const metadata = await getPackageMetadata(util.getPackageRelativePath(process.cwd(), packagePath));
|
|
512
|
+
await broker.call(`@steedos/service-packages.install`, {
|
|
513
|
+
serviceInfo: Object.assign({}, packageConfig, {
|
|
514
|
+
name: packageName,
|
|
515
|
+
enable: enable,
|
|
516
|
+
nodeID: broker.nodeID,
|
|
517
|
+
instanceID: broker.instanceID,
|
|
518
|
+
metadata: metadata
|
|
519
|
+
})
|
|
520
|
+
})
|
|
521
|
+
return packageConfig;
|
|
522
|
+
}
|
|
523
|
+
},
|
|
524
|
+
getSafeScopes: {
|
|
525
|
+
async handler(spaceId, apiKey, consoleUrl) {
|
|
526
|
+
let result = await axios({
|
|
527
|
+
url: `${consoleUrl}/api/npm-scopes/safe`,
|
|
528
|
+
method: 'post',
|
|
529
|
+
data: {
|
|
530
|
+
cloudSpaceId: spaceId
|
|
531
|
+
},
|
|
532
|
+
timeout: 5 * 1000,
|
|
533
|
+
headers: { "Content-Type": "application/json", "Authorization": `Bearer apikey,${apiKey}` }
|
|
534
|
+
})
|
|
535
|
+
if (!result.data.success) {
|
|
536
|
+
throw new Error(result.data.error);
|
|
537
|
+
}
|
|
538
|
+
return result.data;
|
|
539
|
+
}
|
|
540
|
+
},
|
|
541
|
+
loginSteedosRegistry: {
|
|
542
|
+
async handler() {
|
|
543
|
+
const settings = this.settings;
|
|
544
|
+
// 配置主控地址
|
|
545
|
+
const consoleUrl = settings.STEEDOS_CLOUD_URL;
|
|
546
|
+
if (!consoleUrl) {
|
|
547
|
+
throw new Error('请配置主控地址');
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
// 初始化工作区数据
|
|
551
|
+
// 获取环境变量中工作区信息
|
|
552
|
+
const spaceId = settings.STEEDOS_CLOUD_SPACE_ID || process.env.STEEDOS_CLOUD_SPACE_ID;
|
|
553
|
+
const apiKey = settings.STEEDOS_CLOUD_API_KEY || process.env.STEEDOS_CLOUD_API_KEY;
|
|
554
|
+
|
|
555
|
+
if (!spaceId || !apiKey) {
|
|
556
|
+
throw new Error('请配置环境变量STEEDOS_CLOUD_SPACE_ID和STEEDOS_CLOUD_API_KEY。');
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
const registryUrl = settings.STEEDOS_REGISTRY_URL
|
|
560
|
+
|
|
561
|
+
// 调用接口获取初始化信息
|
|
562
|
+
const { info, scopes } = await this.getSafeScopes(spaceId, apiKey, consoleUrl);
|
|
563
|
+
const { adminPhone } = info;
|
|
564
|
+
if (!adminPhone) {
|
|
565
|
+
throw new Error('缺少工作区信息 工作区名称、管理员姓名、管理员手机号,请检查');
|
|
566
|
+
}
|
|
567
|
+
// let scope = '';
|
|
568
|
+
// if (scopes && scopes.length > 0) {
|
|
569
|
+
// scope = scopes[0];
|
|
570
|
+
// }
|
|
571
|
+
await login.loginToRegistry(adminPhone, apiKey, `${adminPhone}@steedos.com`, registryUrl, undefined);
|
|
572
|
+
login.setYarnrcScopes(scopes, registryUrl);
|
|
573
|
+
}
|
|
574
|
+
},
|
|
575
|
+
initialPackages: {
|
|
576
|
+
async handler(){
|
|
577
|
+
const settings = this.settings;
|
|
578
|
+
const packages = settings.STEEDOS_INITIAL_PACKAGES;
|
|
579
|
+
if(_.isString(packages)){
|
|
580
|
+
for (const packageName of packages.split(',')) {
|
|
581
|
+
try {
|
|
582
|
+
const parsed = npa(packageName);
|
|
583
|
+
const installProps = {
|
|
584
|
+
url: null,
|
|
585
|
+
name: null,
|
|
586
|
+
version: null
|
|
587
|
+
};
|
|
588
|
+
switch (parsed.type) {
|
|
589
|
+
case "tag":
|
|
590
|
+
installProps.name = parsed.name;
|
|
591
|
+
installProps.version = parsed.rawSpec;
|
|
592
|
+
break;
|
|
593
|
+
case "version":
|
|
594
|
+
installProps.name = parsed.name;
|
|
595
|
+
installProps.version = parsed.rawSpec;
|
|
596
|
+
break;
|
|
597
|
+
case "range":
|
|
598
|
+
installProps.name = parsed.name;
|
|
599
|
+
installProps.version = parsed.rawSpec;
|
|
600
|
+
break;
|
|
601
|
+
case "directory":
|
|
602
|
+
case "remote":
|
|
603
|
+
case "file":
|
|
604
|
+
case "git":
|
|
605
|
+
installProps.url = parsed.rawSpec;
|
|
606
|
+
break;
|
|
607
|
+
case "alias":
|
|
608
|
+
throw new Error(`not support ${parsed.type}`);
|
|
609
|
+
}
|
|
610
|
+
if(installProps.url){
|
|
611
|
+
//module, version, url, auth, enable, registry_url, broker
|
|
612
|
+
await this.installPackageFromUrl(installProps.url, installProps.version, installProps.url, null, true, null, this.broker);
|
|
613
|
+
}else{
|
|
614
|
+
//module, version, label, description, enable, broker
|
|
615
|
+
await this.installPackage(installProps.name, installProps.version, null, null, true, this.broker);
|
|
616
|
+
}
|
|
617
|
+
} catch (error) {
|
|
618
|
+
this.broker.logger.error(`initialPackages: ${packageName}. ${error.message}`);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
},
|
|
625
|
+
|
|
626
|
+
/**
|
|
627
|
+
* Service created lifecycle event handler
|
|
628
|
+
*/
|
|
629
|
+
async created() {
|
|
630
|
+
this.broker.createService(packageLicense);
|
|
631
|
+
},
|
|
632
|
+
|
|
633
|
+
/**
|
|
634
|
+
* Service started lifecycle event handler
|
|
635
|
+
*/
|
|
636
|
+
async started() {
|
|
637
|
+
try {
|
|
638
|
+
await this.loginSteedosRegistry();
|
|
639
|
+
console.info(`login steedos registry success`);
|
|
640
|
+
} catch (error) {
|
|
641
|
+
// console.error(`login steedos registry fail: `, error.message);
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
await this.broker.call(`@steedos/service-package-license.syncPackagesLicense`);
|
|
645
|
+
|
|
646
|
+
const PACKAGE_INSTALL_NODE = process.env.PACKAGE_INSTALL_NODE
|
|
647
|
+
if(PACKAGE_INSTALL_NODE){
|
|
648
|
+
await this.broker.call('metadata.add', {key: `#package_install_node.${this.broker.nodeID}`, data: {nodeID: PACKAGE_INSTALL_NODE}}, {meta: {}})
|
|
649
|
+
}
|
|
650
|
+
packages.maintainSystemFiles()
|
|
651
|
+
try {
|
|
652
|
+
const packagePath = path.join(process.cwd(), 'steedos-app');
|
|
653
|
+
if(fs.existsSync(packagePath)){
|
|
654
|
+
const packageInfo = require(path.join(packagePath, 'package.json'));
|
|
655
|
+
loader.appendToPackagesConfig(`${packageInfo.name}`, {version: packageInfo.version, description: packageInfo.description, local: true, path: util.getPackageRelativePath(process.cwd(), packagePath)});
|
|
656
|
+
}
|
|
657
|
+
} catch (error) {
|
|
658
|
+
console.log(`started error`, error)
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
await metadata.uncompressPackages(process.cwd());
|
|
662
|
+
const mPackages = metadata.getAllPackages(process.cwd());
|
|
663
|
+
_.each(mPackages, (packagePath)=>{
|
|
664
|
+
try {
|
|
665
|
+
const packageInfo = require(path.join(packagePath, 'package.json'));
|
|
666
|
+
loader.appendToPackagesConfig(packageInfo.name, {version: packageInfo.version, description: packageInfo.description, local: true, path: util.getPackageRelativePath(process.cwd(), packagePath)});
|
|
667
|
+
} catch (error) {
|
|
668
|
+
console.log(`started error`, error)
|
|
669
|
+
}
|
|
670
|
+
})
|
|
671
|
+
await loader.loadPackages();
|
|
672
|
+
|
|
673
|
+
//注册本地已安装的steedos packages
|
|
674
|
+
const installPackages = loader.loadPackagesConfig();
|
|
675
|
+
for (const name in installPackages) {
|
|
676
|
+
if (Object.hasOwnProperty.call(installPackages, name)) {
|
|
677
|
+
const _packageInfo = installPackages[name];
|
|
678
|
+
const metadata = await getPackageMetadata(_packageInfo.path);
|
|
679
|
+
await this.broker.call(`@steedos/service-packages.install`, {
|
|
680
|
+
serviceInfo: {
|
|
681
|
+
name: name,
|
|
682
|
+
nodeID: this.broker.nodeID,
|
|
683
|
+
instanceID: this.broker.instanceID,
|
|
684
|
+
path: _packageInfo.path,
|
|
685
|
+
local: _packageInfo.local,
|
|
686
|
+
enable: _packageInfo.enable,
|
|
687
|
+
version: _packageInfo.version,
|
|
688
|
+
description: _packageInfo.description,
|
|
689
|
+
metadata: metadata
|
|
690
|
+
}
|
|
691
|
+
})
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
},
|
|
696
|
+
|
|
697
|
+
/**
|
|
698
|
+
* Service stopped lifecycle event handler
|
|
699
|
+
*/
|
|
700
|
+
async stopped() {
|
|
701
|
+
const PACKAGE_INSTALL_NODE = process.env.PACKAGE_INSTALL_NODE
|
|
702
|
+
if(PACKAGE_INSTALL_NODE){
|
|
703
|
+
this.broker.call('metadata.delete', {key: `#package_install_node.${this.broker.nodeID}`}, {meta: {}})
|
|
704
|
+
}
|
|
705
|
+
const installPackages = loader.loadPackagesConfig();
|
|
706
|
+
for (const name in installPackages) {
|
|
707
|
+
this.broker.call(`@steedos/service-packages.uninstall`, {
|
|
708
|
+
serviceInfo: {
|
|
709
|
+
name: name,
|
|
710
|
+
nodeID: this.broker.nodeID,
|
|
711
|
+
instanceID: this.broker.instanceID,
|
|
712
|
+
}
|
|
713
|
+
})
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
};
|