Compare commits
45 Commits
Author | SHA1 | Date | |
---|---|---|---|
73476c2c39 | |||
942f65268d | |||
a965647c1f | |||
db88c7f86c | |||
3f18cb68bf | |||
dae3b59e3b | |||
53062e70d4 | |||
3e70dc465b | |||
49445d93c6 | |||
4f838837f8 | |||
c76968bbe8 | |||
6c5e5644b1 | |||
5cf80944fe | |||
cdb69c5f17 | |||
178c1d2df1 | |||
43d9da808b | |||
15f5c38eb0 | |||
225c1be14c | |||
44f2aab2f6 | |||
b69315f1d3 | |||
7d20804986 | |||
0aab639fbd | |||
794bb60dfc | |||
b182a379af | |||
5c6c06dee6 | |||
a48e1e035e | |||
8836c06b56 | |||
7af8e0739b | |||
684185e951 | |||
21e6fff3fb | |||
83c49a6234 | |||
ad67849d45 | |||
0e4e07a912 | |||
1fbc09f557 | |||
d6201b864c | |||
ea5e552192 | |||
1afe5c6e16 | |||
eb0dc96dbd | |||
55f45b1c3a | |||
87ff0f01bb | |||
dd1939d7b2 | |||
5a2a5f1248 | |||
9767b8767a | |||
546e139b46 | |||
28d70bb49f |
@ -38,13 +38,11 @@ snyk:
|
||||
# test stage
|
||||
# ====================
|
||||
|
||||
testLTS:
|
||||
services:
|
||||
- docker:18-dind
|
||||
testStable:
|
||||
stage: test
|
||||
script:
|
||||
- npmci npm prepare
|
||||
- npmci node install lts
|
||||
- npmci node install stable
|
||||
- npmci npm install
|
||||
- npmci npm test
|
||||
coverage: /\d+.?\d+?\%\s*coverage/
|
||||
@ -56,7 +54,7 @@ testBuild:
|
||||
stage: test
|
||||
script:
|
||||
- npmci npm prepare
|
||||
- npmci node install lts
|
||||
- npmci node install stable
|
||||
- npmci npm install
|
||||
- npmci command npm run build
|
||||
coverage: /\d+.?\d+?\%\s*coverage/
|
||||
@ -67,7 +65,7 @@ testBuild:
|
||||
release:
|
||||
stage: release
|
||||
script:
|
||||
- npmci node install lts
|
||||
- npmci node install stable
|
||||
- npmci npm publish
|
||||
only:
|
||||
- tags
|
||||
@ -102,7 +100,7 @@ trigger:
|
||||
pages:
|
||||
image: hosttoday/ht-docker-dbase:npmci
|
||||
services:
|
||||
- docker:18-dind
|
||||
- docker:stable-dind
|
||||
stage: metadata
|
||||
script:
|
||||
- npmci command npm install -g @gitzone/tsdoc
|
||||
|
120
package-lock.json
generated
120
package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@mojoio/docker",
|
||||
"version": "1.0.56",
|
||||
"version": "1.0.79",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@ -167,7 +167,6 @@
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://verdaccio.lossless.one/@pushrocks%2fsmartfile/-/smartfile-7.0.4.tgz",
|
||||
"integrity": "sha512-ym8eigWJAQhwgmuVLew3GLrk4WhV03ajapwuMWytxKSzfIW9ZqceJBX2QzOkmhFGA2bp+gc4Q2wOBy3Ffnlj+A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@pushrocks/smartpath": "^4.0.1",
|
||||
"@pushrocks/smartpromise": "^3.0.2",
|
||||
@ -250,8 +249,7 @@
|
||||
"@pushrocks/smartpath": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://verdaccio.lossless.one/@pushrocks%2fsmartpath/-/smartpath-4.0.1.tgz",
|
||||
"integrity": "sha512-MaI0+uLQPCr2V3WGnbdgb0pWa9xkWyrP4qYcbsHIjeismGLbn9s3jmP/HIXU8LkgzRgaVb+BJxmZJHOwl32DyA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-MaI0+uLQPCr2V3WGnbdgb0pWa9xkWyrP4qYcbsHIjeismGLbn9s3jmP/HIXU8LkgzRgaVb+BJxmZJHOwl32DyA=="
|
||||
},
|
||||
"@pushrocks/smartpromise": {
|
||||
"version": "3.0.2",
|
||||
@ -415,7 +413,6 @@
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://verdaccio.lossless.one/@types%2ffs-extra/-/fs-extra-5.1.0.tgz",
|
||||
"integrity": "sha512-AInn5+UBFIK9FK5xc9yP5e3TQSPNNgjHByqYcj9g5elVBnDQcQL7PlO1CIRy2gWlbwK7UPYqi7vRvFA44dCmYQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
@ -449,7 +446,6 @@
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://verdaccio.lossless.one/@types%2fvinyl/-/vinyl-2.0.3.tgz",
|
||||
"integrity": "sha512-hrT6xg16CWSmndZqOTJ6BGIn2abKyTw0B58bI+7ioUoj3Sma6u8ftZ1DTI2yCaJamOVGLOnQWiPH3a74+EaqTA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
@ -504,7 +500,6 @@
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"sprintf-js": "~1.0.2"
|
||||
}
|
||||
@ -634,26 +629,22 @@
|
||||
"clone": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://verdaccio.lossless.one/clone/-/clone-2.1.2.tgz",
|
||||
"integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
|
||||
"dev": true
|
||||
"integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18="
|
||||
},
|
||||
"clone-buffer": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
|
||||
"integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=",
|
||||
"dev": true
|
||||
"resolved": "https://verdaccio.lossless.one/clone-buffer/-/clone-buffer-1.0.0.tgz",
|
||||
"integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg="
|
||||
},
|
||||
"clone-stats": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
|
||||
"integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=",
|
||||
"dev": true
|
||||
"resolved": "https://verdaccio.lossless.one/clone-stats/-/clone-stats-1.0.0.tgz",
|
||||
"integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA="
|
||||
},
|
||||
"cloneable-readable": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://verdaccio.lossless.one/cloneable-readable/-/cloneable-readable-1.1.3.tgz",
|
||||
"integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"inherits": "^2.0.1",
|
||||
"process-nextick-args": "^2.0.0",
|
||||
@ -700,9 +691,8 @@
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
|
||||
"dev": true
|
||||
"resolved": "https://verdaccio.lossless.one/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
},
|
||||
"cron": {
|
||||
"version": "1.7.1",
|
||||
@ -914,8 +904,7 @@
|
||||
"esprima": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
||||
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
|
||||
"dev": true
|
||||
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
|
||||
},
|
||||
"esutils": {
|
||||
"version": "2.0.3",
|
||||
@ -963,9 +952,8 @@
|
||||
},
|
||||
"first-chunk-stream": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz",
|
||||
"resolved": "https://verdaccio.lossless.one/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz",
|
||||
"integrity": "sha1-G97NuOCDwGZLkZRVgVd6Q6nzHXA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"readable-stream": "^2.0.2"
|
||||
}
|
||||
@ -984,7 +972,6 @@
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://verdaccio.lossless.one/fs-extra/-/fs-extra-7.0.1.tgz",
|
||||
"integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.2",
|
||||
"jsonfile": "^4.0.0",
|
||||
@ -994,8 +981,7 @@
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"dev": true
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
||||
},
|
||||
"function-bind": {
|
||||
"version": "1.1.1",
|
||||
@ -1027,7 +1013,6 @@
|
||||
"version": "7.1.4",
|
||||
"resolved": "https://verdaccio.lossless.one/glob/-/glob-7.1.4.tgz",
|
||||
"integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
@ -1040,8 +1025,7 @@
|
||||
"graceful-fs": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://verdaccio.lossless.one/graceful-fs/-/graceful-fs-4.2.2.tgz",
|
||||
"integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==",
|
||||
"dev": true
|
||||
"integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q=="
|
||||
},
|
||||
"has": {
|
||||
"version": "1.0.3",
|
||||
@ -1083,7 +1067,6 @@
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
@ -1092,8 +1075,7 @@
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://verdaccio.lossless.one/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"invert-kv": {
|
||||
"version": "2.0.0",
|
||||
@ -1160,15 +1142,13 @@
|
||||
},
|
||||
"is-utf8": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
|
||||
"integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
|
||||
"dev": true
|
||||
"resolved": "https://verdaccio.lossless.one/is-utf8/-/is-utf8-0.2.1.tgz",
|
||||
"integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI="
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
|
||||
"dev": true
|
||||
"resolved": "https://verdaccio.lossless.one/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"isexe": {
|
||||
"version": "2.0.0",
|
||||
@ -1190,7 +1170,6 @@
|
||||
"version": "3.13.1",
|
||||
"resolved": "https://verdaccio.lossless.one/js-yaml/-/js-yaml-3.13.1.tgz",
|
||||
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
"esprima": "^4.0.0"
|
||||
@ -1198,9 +1177,8 @@
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||
"resolved": "https://verdaccio.lossless.one/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
@ -1515,8 +1493,7 @@
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"dev": true
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
|
||||
},
|
||||
"path-key": {
|
||||
"version": "2.0.1",
|
||||
@ -1537,9 +1514,8 @@
|
||||
},
|
||||
"pify": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
||||
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
|
||||
"dev": true
|
||||
"resolved": "https://verdaccio.lossless.one/pify/-/pify-2.3.0.tgz",
|
||||
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
|
||||
},
|
||||
"portscanner": {
|
||||
"version": "2.2.0",
|
||||
@ -1553,8 +1529,7 @@
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://verdaccio.lossless.one/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
|
||||
"dev": true
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
||||
},
|
||||
"pump": {
|
||||
"version": "3.0.0",
|
||||
@ -1577,9 +1552,8 @@
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "https://verdaccio.lossless.one/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
@ -1592,15 +1566,13 @@
|
||||
},
|
||||
"remove-trailing-separator": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
|
||||
"integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
|
||||
"dev": true
|
||||
"resolved": "https://verdaccio.lossless.one/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
|
||||
"integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8="
|
||||
},
|
||||
"replace-ext": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
|
||||
"integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=",
|
||||
"dev": true
|
||||
"resolved": "https://verdaccio.lossless.one/replace-ext/-/replace-ext-1.0.0.tgz",
|
||||
"integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs="
|
||||
},
|
||||
"require-directory": {
|
||||
"version": "2.1.1",
|
||||
@ -1643,9 +1615,8 @@
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||
"dev": true
|
||||
"resolved": "https://verdaccio.lossless.one/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"sax": {
|
||||
"version": "1.2.4",
|
||||
@ -1726,8 +1697,7 @@
|
||||
"sprintf-js": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
|
||||
"dev": true
|
||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
|
||||
},
|
||||
"string-width": {
|
||||
"version": "2.1.1",
|
||||
@ -1759,9 +1729,8 @@
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"resolved": "https://verdaccio.lossless.one/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
@ -1777,27 +1746,24 @@
|
||||
},
|
||||
"strip-bom": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
|
||||
"resolved": "https://verdaccio.lossless.one/strip-bom/-/strip-bom-2.0.0.tgz",
|
||||
"integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-utf8": "^0.2.0"
|
||||
}
|
||||
},
|
||||
"strip-bom-buf": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz",
|
||||
"resolved": "https://verdaccio.lossless.one/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz",
|
||||
"integrity": "sha1-HLRar1dTD0yvhsf3UXnSyaUd1XI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-utf8": "^0.2.1"
|
||||
}
|
||||
},
|
||||
"strip-bom-stream": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz",
|
||||
"resolved": "https://verdaccio.lossless.one/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz",
|
||||
"integrity": "sha1-+H217yYT9paKpUWr/h7HKLaoKco=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"first-chunk-stream": "^2.0.0",
|
||||
"strip-bom": "^2.0.0"
|
||||
@ -1913,15 +1879,13 @@
|
||||
},
|
||||
"universalify": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
||||
"dev": true
|
||||
"resolved": "https://verdaccio.lossless.one/universalify/-/universalify-0.1.2.tgz",
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
||||
"dev": true
|
||||
"resolved": "https://verdaccio.lossless.one/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
},
|
||||
"util.promisify": {
|
||||
"version": "1.0.0",
|
||||
@ -1934,9 +1898,8 @@
|
||||
},
|
||||
"vinyl": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz",
|
||||
"resolved": "https://verdaccio.lossless.one/vinyl/-/vinyl-2.2.0.tgz",
|
||||
"integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"clone": "^2.1.1",
|
||||
"clone-buffer": "^1.0.0",
|
||||
@ -1948,9 +1911,8 @@
|
||||
},
|
||||
"vinyl-file": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vinyl-file/-/vinyl-file-3.0.0.tgz",
|
||||
"resolved": "https://verdaccio.lossless.one/vinyl-file/-/vinyl-file-3.0.0.tgz",
|
||||
"integrity": "sha1-sQTZ5ECf+jJfqt1SBkLQo7SIs2U=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.2",
|
||||
"pify": "^2.3.0",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@mojoio/docker",
|
||||
"version": "1.0.56",
|
||||
"version": "1.0.79",
|
||||
"description": "easy communication with docker remote api from node, TypeScript ready",
|
||||
"private": false,
|
||||
"main": "dist/index.js",
|
||||
@ -28,9 +28,11 @@
|
||||
"homepage": "https://gitlab.com/pushrocks/dockersock#README",
|
||||
"dependencies": {
|
||||
"@pushrocks/lik": "^3.0.11",
|
||||
"@pushrocks/smartfile": "^7.0.4",
|
||||
"@pushrocks/smartjson": "^3.0.8",
|
||||
"@pushrocks/smartlog": "^2.0.19",
|
||||
"@pushrocks/smartnetwork": "^1.1.14",
|
||||
"@pushrocks/smartpath": "^4.0.1",
|
||||
"@pushrocks/smartpromise": "^3.0.2",
|
||||
"@pushrocks/smartrequest": "^1.1.26",
|
||||
"@pushrocks/smartstring": "^3.0.10",
|
||||
|
11
scripts/testauth.ts
Normal file
11
scripts/testauth.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import * as docker from '../ts';
|
||||
import * as smartstring from '@pushrocks/smartstring';
|
||||
|
||||
const run = async () => {
|
||||
const dockerHost = new docker.DockerHost();
|
||||
await docker.DockerImage.createFromRegistry(dockerHost, {
|
||||
imageUrl: 'registry.gitlab.com/servezone/private/cloudly:latest'
|
||||
});
|
||||
};
|
||||
|
||||
run();
|
25
test/test.ts
25
test/test.ts
@ -1,6 +1,5 @@
|
||||
import { expect, tap } from '@pushrocks/tapbundle';
|
||||
import * as docker from '../ts/index';
|
||||
import { DockerService } from '../ts/index';
|
||||
|
||||
let testDockerHost: docker.DockerHost;
|
||||
|
||||
@ -61,6 +60,7 @@ tap.test('should return a change Observable', async tools => {
|
||||
tap.test('should create a secret', async () => {
|
||||
const mySecret = await docker.DockerSecret.createSecret(testDockerHost, {
|
||||
name: 'testSecret',
|
||||
version: '1.0.3',
|
||||
contentArg: `{ "hi": "wow"}`,
|
||||
labels: {}
|
||||
});
|
||||
@ -72,7 +72,6 @@ tap.test('should remove a secret by name', async () => {
|
||||
await mySecret.remove();
|
||||
});
|
||||
|
||||
|
||||
// SERVICES
|
||||
tap.test('should activate swarm mode', async () => {
|
||||
await testDockerHost.activateSwarm();
|
||||
@ -88,24 +87,24 @@ tap.test('should create a service', async () => {
|
||||
Name: 'testNetwork'
|
||||
});
|
||||
const testSecret = await docker.DockerSecret.createSecret(testDockerHost, {
|
||||
name: 'serviceSecret',
|
||||
name: 'testSecret',
|
||||
version: '0.0.1',
|
||||
labels: {},
|
||||
contentArg: '{"hi": "wow"}'
|
||||
});
|
||||
const testService = await DockerService.createService(testDockerHost, {
|
||||
Image: 'nginx:latest',
|
||||
Labels: {
|
||||
'testlabel': 'hi'
|
||||
},
|
||||
Name: 'testService',
|
||||
const testImage = await docker.DockerImage.createFromRegistry(testDockerHost, {
|
||||
imageUrl: 'registry.gitlab.com/hosttoday/ht-docker-static'
|
||||
});
|
||||
const testService = await docker.DockerService.createService(testDockerHost, {
|
||||
image: testImage,
|
||||
labels: {},
|
||||
name: 'testService',
|
||||
networks: [testNetwork],
|
||||
networkAlias: 'testService',
|
||||
secrets: [testSecret]
|
||||
secrets: [testSecret],
|
||||
ports: ['3000:80']
|
||||
});
|
||||
|
||||
await testSecret.update(`{"updated": "socool"}`);
|
||||
await testService.update();
|
||||
|
||||
await testService.remove();
|
||||
await testNetwork.remove();
|
||||
await testSecret.remove();
|
||||
|
@ -3,11 +3,18 @@ import { DockerContainer } from './docker.classes.container';
|
||||
import { DockerNetwork } from './docker.classes.network';
|
||||
import { DockerService } from './docker.classes.service';
|
||||
|
||||
export interface IAuthData {
|
||||
serveraddress: string;
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export class DockerHost {
|
||||
/**
|
||||
* the path where the docker sock can be found
|
||||
*/
|
||||
public socketPath: string;
|
||||
private registryToken: string = '';
|
||||
|
||||
/**
|
||||
* the constructor to instantiate a new docker sock instance
|
||||
@ -30,11 +37,31 @@ export class DockerHost {
|
||||
* @param userArg
|
||||
* @param passArg
|
||||
*/
|
||||
public async auth(registryUrl: string, userArg: string, passArg: string) {
|
||||
const response = await this.request('POST', '/auth', {
|
||||
serveraddress: registryUrl,
|
||||
username: userArg,
|
||||
password: passArg,
|
||||
public async auth(authData: IAuthData) {
|
||||
const response = await this.request('POST', '/auth', authData);
|
||||
if (response.body.Status !== 'Login Succeeded') {
|
||||
console.log(`Login failed with ${response.body.Status}`);
|
||||
throw new Error(response.body.Status);
|
||||
}
|
||||
console.log(response.body.Status);
|
||||
this.registryToken = plugins.smartstring.base64.encode(
|
||||
plugins.smartjson.Smartjson.stringify(authData, {})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the token from the .docker/config.json file for GitLab registry
|
||||
*/
|
||||
public async getGitlabComTokenFromDockerConfig() {
|
||||
const dockerConfigPath = plugins.smartpath.get.home('~/.docker/config.json');
|
||||
const configObject = plugins.smartfile.fs.toObjectSync(dockerConfigPath);
|
||||
const gitlabAuthBase64 = configObject.auths['registry.gitlab.com'].auth;
|
||||
const gitlabAuth: string = plugins.smartstring.base64.decode(gitlabAuthBase64);
|
||||
const gitlabAuthArray = gitlabAuth.split(':');
|
||||
await this.auth({
|
||||
username: gitlabAuthArray[0],
|
||||
password: gitlabAuthArray[1],
|
||||
serveraddress: 'registry.gitlab.com'
|
||||
});
|
||||
}
|
||||
|
||||
@ -45,6 +72,10 @@ export class DockerHost {
|
||||
return await DockerNetwork.getNetworks(this);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* gets all containers
|
||||
*/
|
||||
@ -122,6 +153,7 @@ export class DockerHost {
|
||||
method: methodArg,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Registry-Auth': this.registryToken,
|
||||
Host: 'docker.sock'
|
||||
},
|
||||
requestBody: dataArg,
|
||||
@ -141,6 +173,7 @@ export class DockerHost {
|
||||
method: methodArg,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Registry-Auth': this.registryToken,
|
||||
Host: 'docker.sock'
|
||||
},
|
||||
requestBody: null,
|
||||
|
@ -15,16 +15,20 @@ export class DockerImage {
|
||||
|
||||
public static async findImageByName(dockerHost: DockerHost, imageNameArg: string) {
|
||||
const images = await this.getImages(dockerHost);
|
||||
return images.find(image => {
|
||||
return image.RepoTags.includes(imageNameArg);
|
||||
const result = images.find(image => {
|
||||
if (image.RepoTags) {
|
||||
return image.RepoTags.includes(imageNameArg);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async createFromRegistry(
|
||||
dockerHostArg: DockerHost,
|
||||
creationObject: interfaces.IImageCreationDescriptor
|
||||
): Promise<DockerImage> {
|
||||
|
||||
// lets create a sanatized imageUrlObject
|
||||
const imageUrlObject: {
|
||||
imageUrl: string;
|
||||
@ -40,9 +44,7 @@ export class DockerImage {
|
||||
const imageTag = imageUrlObject.imageUrl.split(':')[1];
|
||||
if (imageUrlObject.imageTag) {
|
||||
throw new Error(
|
||||
`imageUrl ${imageUrlObject.imageUrl} can't be tagged with ${
|
||||
imageUrlObject.imageTag
|
||||
} because it is already tagged with ${imageTag}`
|
||||
`imageUrl ${imageUrlObject.imageUrl} can't be tagged with ${imageUrlObject.imageTag} because it is already tagged with ${imageTag}`
|
||||
);
|
||||
} else {
|
||||
imageUrlObject.imageUrl = imageUrl;
|
||||
@ -113,7 +115,13 @@ export class DockerImage {
|
||||
});
|
||||
}
|
||||
|
||||
public tagImage(newTag) {}
|
||||
/**
|
||||
* tag an image
|
||||
* @param newTag
|
||||
*/
|
||||
public async tagImage(newTag) {
|
||||
throw new Error('.tagImage is not yet implemented');
|
||||
}
|
||||
|
||||
/**
|
||||
* pulls the latest version from the registry
|
||||
@ -126,4 +134,13 @@ export class DockerImage {
|
||||
// TODO: Compare image digists before and after
|
||||
return true;
|
||||
}
|
||||
|
||||
// get stuff
|
||||
public async getVersion() {
|
||||
if (this.Labels && this.Labels.version) {
|
||||
return this.Labels.version;
|
||||
} else {
|
||||
return 'x.x.x';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import * as plugins from './docker.plugins';
|
||||
import * as interfaces from './interfaces';
|
||||
|
||||
import { DockerHost } from './docker.classes.host';
|
||||
import { DockerService } from './docker.classes.service';
|
||||
|
||||
export class DockerNetwork {
|
||||
public static async getNetworks(dockerHost: DockerHost): Promise<DockerNetwork[]> {
|
||||
@ -29,16 +30,6 @@ export class DockerNetwork {
|
||||
CheckDuplicate: true,
|
||||
Driver: 'overlay',
|
||||
EnableIPv6: false,
|
||||
IPAM: {
|
||||
Driver: 'default',
|
||||
Config: [
|
||||
{
|
||||
Subnet: '172.20.10.0/16',
|
||||
IPRange: '172.20.10.0/24',
|
||||
Gateway: '172.20.10.11'
|
||||
}
|
||||
]
|
||||
},
|
||||
Internal: true,
|
||||
Attachable: true,
|
||||
Ingress: false
|
||||
@ -90,4 +81,29 @@ export class DockerNetwork {
|
||||
public async remove() {
|
||||
const response = await this.dockerHost.request('DELETE', `/networks/${this.Id}`);
|
||||
}
|
||||
|
||||
public async getContainersOnNetwork(): Promise<Array<{
|
||||
Name: string;
|
||||
EndpointID: string;
|
||||
MacAddress: string;
|
||||
IPv4Address: string;
|
||||
IPv6Address: string;
|
||||
}>> {
|
||||
const returnArray = [];
|
||||
const response = await this.dockerHost.request('GET', `/networks/${this.Id}`);
|
||||
for (const key of Object.keys(response.body.Containers)) {
|
||||
returnArray.push(response.body.Containers[key]);
|
||||
}
|
||||
|
||||
return returnArray;
|
||||
|
||||
}
|
||||
|
||||
public async getContainersOnNetworkForService(serviceArg: DockerService) {
|
||||
const containersOnNetwork = await this.getContainersOnNetwork();
|
||||
const containersOfService = containersOnNetwork.filter(container => {
|
||||
return container.Name.startsWith(serviceArg.Spec.Name);
|
||||
});
|
||||
return containersOfService;
|
||||
}
|
||||
}
|
||||
|
@ -17,26 +17,36 @@ export class DockerSecret {
|
||||
return secrets;
|
||||
}
|
||||
|
||||
public static async getSecretByID (dockerHostArg: DockerHost, idArg: string) {
|
||||
public static async getSecretByID(dockerHostArg: DockerHost, idArg: string) {
|
||||
const secrets = await this.getSecrets(dockerHostArg);
|
||||
return secrets.find(secret => secret.ID === idArg);
|
||||
}
|
||||
|
||||
public static async getSecretByName (dockerHostArg: DockerHost, nameArg: string) {
|
||||
public static async getSecretByName(dockerHostArg: DockerHost, nameArg: string) {
|
||||
const secrets = await this.getSecrets(dockerHostArg);
|
||||
return secrets.find(secret => secret.Spec.Name === nameArg);
|
||||
}
|
||||
|
||||
public static async createSecret(dockerHostArg: DockerHost, secretDescriptor: interfaces.ISecretCreationDescriptor) {
|
||||
public static async createSecret(
|
||||
dockerHostArg: DockerHost,
|
||||
secretDescriptor: interfaces.ISecretCreationDescriptor
|
||||
) {
|
||||
const labels: interfaces.TLabels = {
|
||||
...secretDescriptor.labels,
|
||||
version: secretDescriptor.version
|
||||
};
|
||||
const response = await dockerHostArg.request('POST', '/secrets/create', {
|
||||
Name: secretDescriptor.name,
|
||||
Labels: secretDescriptor.labels,
|
||||
Labels: labels,
|
||||
Data: plugins.smartstring.base64.encode(secretDescriptor.contentArg)
|
||||
});
|
||||
|
||||
|
||||
const newSecretInstance = new DockerSecret(dockerHostArg);
|
||||
Object.assign(newSecretInstance, response.body);
|
||||
Object.assign (newSecretInstance, await DockerSecret.getSecretByID(dockerHostArg, newSecretInstance.ID));
|
||||
Object.assign(
|
||||
newSecretInstance,
|
||||
await DockerSecret.getSecretByID(dockerHostArg, newSecretInstance.ID)
|
||||
);
|
||||
return newSecretInstance;
|
||||
}
|
||||
|
||||
@ -46,9 +56,9 @@ export class DockerSecret {
|
||||
Name: string;
|
||||
Labels: interfaces.TLabels;
|
||||
};
|
||||
Version: {
|
||||
Index:string;
|
||||
}
|
||||
public Version: {
|
||||
Index: string;
|
||||
};
|
||||
|
||||
public dockerHost: DockerHost;
|
||||
constructor(dockerHostArg: DockerHost) {
|
||||
@ -58,16 +68,25 @@ export class DockerSecret {
|
||||
/**
|
||||
* updates a secret
|
||||
*/
|
||||
public async update (contentArg: string) {
|
||||
public async update(contentArg: string) {
|
||||
const route = `/secrets/${this.ID}/update?=version=${this.Version.Index}`;
|
||||
const response = await this.dockerHost.request('POST', `/secrets/${this.ID}/update?version=${this.Version.Index}`, {
|
||||
Name: this.Spec.Name,
|
||||
Labels: this.Spec.Labels,
|
||||
Data: plugins.smartstring.base64.encode(contentArg)
|
||||
});
|
||||
const response = await this.dockerHost.request(
|
||||
'POST',
|
||||
`/secrets/${this.ID}/update?version=${this.Version.Index}`,
|
||||
{
|
||||
Name: this.Spec.Name,
|
||||
Labels: this.Spec.Labels,
|
||||
Data: plugins.smartstring.base64.encode(contentArg)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public async remove () {
|
||||
public async remove() {
|
||||
await this.dockerHost.request('DELETE', `/secrets/${this.ID}`);
|
||||
}
|
||||
}
|
||||
|
||||
// get things
|
||||
public async getVersion() {
|
||||
return this.Spec.Labels.version;
|
||||
}
|
||||
}
|
||||
|
@ -39,16 +39,45 @@ export class DockerService {
|
||||
// lets get the image
|
||||
plugins.smartlog.defaultLogger.log(
|
||||
'info',
|
||||
`downloading image for service ${serviceCreationDescriptor.Name}`
|
||||
`now creating service ${serviceCreationDescriptor.name}`
|
||||
);
|
||||
const serviceImage = await DockerImage.createFromRegistry(dockerHost, {
|
||||
imageUrl: serviceCreationDescriptor.Image
|
||||
});
|
||||
|
||||
const serviceVersion = serviceImage.Labels.version;
|
||||
serviceCreationDescriptor.Labels.version = serviceVersion;
|
||||
// await serviceCreationDescriptor.image.pullLatestImageFromRegistry();
|
||||
const serviceVersion = await serviceCreationDescriptor.image.getVersion();
|
||||
|
||||
const labels: interfaces.TLabels = {
|
||||
...serviceCreationDescriptor.labels,
|
||||
version: serviceVersion
|
||||
};
|
||||
|
||||
const mounts: Array<{
|
||||
/**
|
||||
* the target inside the container
|
||||
*/
|
||||
Target: string;
|
||||
/**
|
||||
* The Source from which to mount the data (Volume or host path)
|
||||
*/
|
||||
Source: string;
|
||||
Type: 'bind' | 'volume' | 'tmpfs' | 'npipe';
|
||||
ReadOnly: boolean;
|
||||
Consistency: 'default' | 'consistent' | 'cached' | 'delegated';
|
||||
}> = [];
|
||||
if (serviceCreationDescriptor.accessHostDockerSock) {
|
||||
mounts.push({
|
||||
Target: '/var/run/docker.sock',
|
||||
Source: '/var/run/docker.sock',
|
||||
Consistency: 'default',
|
||||
ReadOnly: false,
|
||||
Type: 'bind'
|
||||
});
|
||||
}
|
||||
|
||||
const networkArray: Array<{
|
||||
Target: string;
|
||||
Aliases: string[];
|
||||
}> = [];
|
||||
|
||||
const networkArray: any[] = [];
|
||||
for (const network of serviceCreationDescriptor.networks) {
|
||||
networkArray.push({
|
||||
Target: network.Name,
|
||||
@ -56,11 +85,24 @@ export class DockerService {
|
||||
});
|
||||
}
|
||||
|
||||
const ports = [];
|
||||
for (const port of serviceCreationDescriptor.ports) {
|
||||
const portArray = port.split(':');
|
||||
const hostPort = portArray[0];
|
||||
const containerPort = portArray[1];
|
||||
ports.push({
|
||||
Protocol: 'tcp',
|
||||
PublishedPort: parseInt(hostPort, 10),
|
||||
TargetPort: parseInt(containerPort, 10)
|
||||
});
|
||||
}
|
||||
|
||||
// lets configure secrets
|
||||
const secretArray: any[] = [];
|
||||
for (const secret of serviceCreationDescriptor.secrets) {
|
||||
secretArray.push({
|
||||
File: {
|
||||
Name: 'secret.json',
|
||||
Name: 'secret.json', // TODO: make sure that works with multiple secrets
|
||||
UID: '33',
|
||||
GID: '33',
|
||||
Mode: 384
|
||||
@ -70,13 +112,23 @@ export class DockerService {
|
||||
});
|
||||
}
|
||||
|
||||
// lets configure limits
|
||||
const limits = {
|
||||
MemoryBytes: 1000 * 1000000
|
||||
};
|
||||
|
||||
if (serviceCreationDescriptor.resources) {
|
||||
limits.MemoryBytes = serviceCreationDescriptor.resources.memorySizeMB * 1000000;
|
||||
}
|
||||
|
||||
const response = await dockerHost.request('POST', '/services/create', {
|
||||
Name: serviceCreationDescriptor.Name,
|
||||
Name: serviceCreationDescriptor.name,
|
||||
TaskTemplate: {
|
||||
ContainerSpec: {
|
||||
Image: serviceCreationDescriptor.Image,
|
||||
Labels: serviceCreationDescriptor.Labels,
|
||||
Secrets: secretArray
|
||||
Image: serviceCreationDescriptor.image.RepoTags[0],
|
||||
Labels: labels,
|
||||
Secrets: secretArray,
|
||||
Mounts: mounts
|
||||
},
|
||||
UpdateConfig: {
|
||||
Parallelism: 0,
|
||||
@ -85,15 +137,21 @@ export class DockerService {
|
||||
Monitor: 15000000000,
|
||||
MaxFailureRatio: 0.15
|
||||
},
|
||||
ForceUpdate: 1
|
||||
ForceUpdate: 1,
|
||||
Resources: {
|
||||
Limits: limits
|
||||
}
|
||||
},
|
||||
Labels: serviceCreationDescriptor.Labels,
|
||||
Networks: networkArray
|
||||
Labels: labels,
|
||||
Networks: networkArray,
|
||||
EndpointSpec: {
|
||||
Ports: ports
|
||||
}
|
||||
});
|
||||
|
||||
const createdService = await DockerService.getServiceByName(
|
||||
dockerHost,
|
||||
serviceCreationDescriptor.Name
|
||||
serviceCreationDescriptor.name
|
||||
);
|
||||
return createdService;
|
||||
}
|
||||
@ -107,7 +165,7 @@ export class DockerService {
|
||||
public UpdatedAt: string;
|
||||
public Spec: {
|
||||
Name: string;
|
||||
Labels: interfaces.TLabels; // ZBD
|
||||
Labels: interfaces.TLabels;
|
||||
TaskTemplate: {
|
||||
ContainerSpec: {
|
||||
Image: string;
|
||||
@ -134,35 +192,16 @@ export class DockerService {
|
||||
this.dockerHostRef = dockerHostArg;
|
||||
}
|
||||
|
||||
public async update() {
|
||||
const labels: interfaces.TLabels = {
|
||||
...this.Spec.Labels,
|
||||
version: 'x.x.x'
|
||||
};
|
||||
|
||||
const dockerData = await this.dockerHostRef.request(
|
||||
'POST',
|
||||
`/services/${this.ID}/update?version=${this.Version.Index}`,
|
||||
{
|
||||
Name: this.Spec.Name,
|
||||
TaskTemplate: this.Spec.TaskTemplate,
|
||||
Labels: labels,
|
||||
Networks: this.Spec.Networks
|
||||
}
|
||||
);
|
||||
Object.assign(this, dockerData);
|
||||
}
|
||||
|
||||
public async remove() {
|
||||
await this.dockerHostRef.request('DELETE', `/services/${this.ID}`);
|
||||
}
|
||||
|
||||
public async reReadFromDockerEngine() {
|
||||
const dockerData = await this.dockerHostRef.request('GET', `/services/${this.ID}`);
|
||||
Object.assign(this, dockerData);
|
||||
// TODO: Better assign: Object.assign(this, dockerData);
|
||||
}
|
||||
|
||||
public async updateFromRegistry() {
|
||||
public async needsUpdate(): Promise<boolean> {
|
||||
// TODO: implement digest based update recognition
|
||||
|
||||
await this.reReadFromDockerEngine();
|
||||
@ -173,8 +212,10 @@ export class DockerService {
|
||||
const imageVersion = new plugins.smartversion.SmartVersion(dockerImage.Labels.version);
|
||||
const serviceVersion = new plugins.smartversion.SmartVersion(this.Spec.Labels.version);
|
||||
if (imageVersion.greaterThan(serviceVersion)) {
|
||||
console.log('service needs to be updated');
|
||||
this.update();
|
||||
console.log(`service ${this.Spec.Name} needs to be updated`);
|
||||
return true;
|
||||
} else {
|
||||
console.log(`service ${this.Spec.Name} is up to date.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,34 @@
|
||||
// node native path
|
||||
import * as path from 'path';
|
||||
|
||||
export { path };
|
||||
|
||||
// @pushrocks scope
|
||||
import * as lik from '@pushrocks/lik';
|
||||
import * as smartfile from '@pushrocks/smartfile';
|
||||
import * as smartjson from '@pushrocks/smartjson';
|
||||
import * as smartlog from '@pushrocks/smartlog';
|
||||
import * as smartnetwork from '@pushrocks/smartnetwork';
|
||||
import * as smartpath from '@pushrocks/smartpath';
|
||||
import * as smartpromise from '@pushrocks/smartpromise';
|
||||
import * as smartrequest from '@pushrocks/smartrequest';
|
||||
import * as smartstring from '@pushrocks/smartstring'
|
||||
import * as smartstring from '@pushrocks/smartstring';
|
||||
import * as smartversion from '@pushrocks/smartversion';
|
||||
|
||||
smartlog.defaultLogger.enableConsole();
|
||||
|
||||
export { lik, smartjson, smartlog, smartnetwork, smartpromise, smartrequest, smartstring, smartversion };
|
||||
export {
|
||||
lik,
|
||||
smartfile,
|
||||
smartjson,
|
||||
smartlog,
|
||||
smartnetwork,
|
||||
smartpath,
|
||||
smartpromise,
|
||||
smartrequest,
|
||||
smartstring,
|
||||
smartversion
|
||||
};
|
||||
|
||||
// third party
|
||||
import * as rxjs from 'rxjs';
|
||||
|
@ -2,6 +2,7 @@ import * as interfaces from './';
|
||||
|
||||
export interface ISecretCreationDescriptor {
|
||||
name: string;
|
||||
version: string;
|
||||
contentArg: any;
|
||||
labels: interfaces.TLabels;
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,18 @@
|
||||
import * as interfaces from './';
|
||||
import { DockerNetwork } from '../docker.classes.network';
|
||||
import { DockerSecret } from '../docker.classes.secret';
|
||||
import { DockerImage } from '../docker.classes.image';
|
||||
|
||||
export interface IServiceCreationDescriptor {
|
||||
Name: string;
|
||||
Image: string;
|
||||
Labels: interfaces.TLabels;
|
||||
name: string;
|
||||
image: DockerImage;
|
||||
labels: interfaces.TLabels;
|
||||
networks: DockerNetwork[];
|
||||
networkAlias: string;
|
||||
secrets: DockerSecret[];
|
||||
ports: string[];
|
||||
accessHostDockerSock?: boolean;
|
||||
resources?: {
|
||||
memorySizeMB: number
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user