Compare commits
59 Commits
Author | SHA1 | Date | |
---|---|---|---|
23266ca459 | |||
a91e69b6db | |||
015ccfad48 | |||
06d2fcb750 | |||
f3e4bc0350 | |||
6de3abe3bf | |||
eaa4140f2f | |||
b21fe80109 | |||
96a2992432 | |||
870b5f2c07 | |||
212edf1db7 | |||
46dbd81bcc | |||
8f5678502d | |||
959d7aaed1 | |||
5aa10653b6 | |||
e120d6527e | |||
c80da05fbb | |||
b9c3475b86 | |||
de2d7e647b | |||
d9348bd016 | |||
034fbc3994 | |||
a33a6a1f7f | |||
9dd403821b | |||
601d82ea74 | |||
784bb22511 | |||
71c89ac9bc | |||
0b3e3b68c9 | |||
f3779faaaf | |||
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 |
4
.gitignore
vendored
4
.gitignore
vendored
@ -15,8 +15,6 @@ node_modules/
|
|||||||
|
|
||||||
# builds
|
# builds
|
||||||
dist/
|
dist/
|
||||||
dist_web/
|
dist_*/
|
||||||
dist_serve/
|
|
||||||
dist_ts_web/
|
|
||||||
|
|
||||||
# custom
|
# custom
|
@ -3,14 +3,14 @@ image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
|
|||||||
|
|
||||||
cache:
|
cache:
|
||||||
paths:
|
paths:
|
||||||
- .npmci_cache/
|
- .npmci_cache/
|
||||||
key: "$CI_BUILD_STAGE"
|
key: '$CI_BUILD_STAGE'
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- security
|
- security
|
||||||
- test
|
- test
|
||||||
- release
|
- release
|
||||||
- metadata
|
- metadata
|
||||||
|
|
||||||
# ====================
|
# ====================
|
||||||
# security stage
|
# security stage
|
||||||
@ -18,62 +18,66 @@ stages:
|
|||||||
mirror:
|
mirror:
|
||||||
stage: security
|
stage: security
|
||||||
script:
|
script:
|
||||||
- npmci git mirror
|
- npmci git mirror
|
||||||
tags:
|
tags:
|
||||||
- docker
|
- lossless
|
||||||
- notpriv
|
- docker
|
||||||
|
- notpriv
|
||||||
|
|
||||||
snyk:
|
audit:
|
||||||
|
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
|
||||||
stage: security
|
stage: security
|
||||||
script:
|
script:
|
||||||
- npmci npm prepare
|
- npmci npm prepare
|
||||||
- npmci command npm install -g snyk
|
|
||||||
- npmci command npm install --ignore-scripts
|
- npmci command npm install --ignore-scripts
|
||||||
- npmci command snyk test
|
- npmci command npm config set registry https://registry.npmjs.org
|
||||||
|
- npmci command npm audit --audit-level=high
|
||||||
tags:
|
tags:
|
||||||
- docker
|
- lossless
|
||||||
- notpriv
|
- docker
|
||||||
|
- notpriv
|
||||||
|
|
||||||
# ====================
|
# ====================
|
||||||
# test stage
|
# test stage
|
||||||
# ====================
|
# ====================
|
||||||
|
|
||||||
testLTS:
|
testStable:
|
||||||
services:
|
|
||||||
- docker:18-dind
|
|
||||||
stage: test
|
stage: test
|
||||||
script:
|
script:
|
||||||
- npmci npm prepare
|
- npmci npm prepare
|
||||||
- npmci node install lts
|
- npmci node install stable
|
||||||
- npmci npm install
|
- npmci npm install
|
||||||
- npmci npm test
|
- npmci npm test
|
||||||
coverage: /\d+.?\d+?\%\s*coverage/
|
coverage: /\d+.?\d+?\%\s*coverage/
|
||||||
tags:
|
tags:
|
||||||
- docker
|
- lossless
|
||||||
- priv
|
- docker
|
||||||
|
- priv
|
||||||
|
|
||||||
testBuild:
|
testBuild:
|
||||||
stage: test
|
stage: test
|
||||||
script:
|
script:
|
||||||
- npmci npm prepare
|
- npmci npm prepare
|
||||||
- npmci node install lts
|
- npmci node install stable
|
||||||
- npmci npm install
|
- npmci npm install
|
||||||
- npmci command npm run build
|
- npmci command npm run build
|
||||||
coverage: /\d+.?\d+?\%\s*coverage/
|
coverage: /\d+.?\d+?\%\s*coverage/
|
||||||
tags:
|
tags:
|
||||||
- docker
|
- lossless
|
||||||
- notpriv
|
- docker
|
||||||
|
- notpriv
|
||||||
|
|
||||||
release:
|
release:
|
||||||
stage: release
|
stage: release
|
||||||
script:
|
script:
|
||||||
- npmci node install lts
|
- npmci node install stable
|
||||||
- npmci npm publish
|
- npmci npm publish
|
||||||
only:
|
only:
|
||||||
- tags
|
- tags
|
||||||
tags:
|
tags:
|
||||||
- docker
|
- lossless
|
||||||
- notpriv
|
- docker
|
||||||
|
- notpriv
|
||||||
|
|
||||||
# ====================
|
# ====================
|
||||||
# metadata stage
|
# metadata stage
|
||||||
@ -83,33 +87,35 @@ codequality:
|
|||||||
allow_failure: true
|
allow_failure: true
|
||||||
script:
|
script:
|
||||||
- npmci command npm install -g tslint typescript
|
- npmci command npm install -g tslint typescript
|
||||||
|
- npmci npm prepare
|
||||||
- npmci npm install
|
- npmci npm install
|
||||||
- npmci command "tslint -c tslint.json ./ts/**/*.ts"
|
- npmci command "tslint -c tslint.json ./ts/**/*.ts"
|
||||||
tags:
|
tags:
|
||||||
- docker
|
- lossless
|
||||||
- priv
|
- docker
|
||||||
|
- priv
|
||||||
|
|
||||||
trigger:
|
trigger:
|
||||||
stage: metadata
|
stage: metadata
|
||||||
script:
|
script:
|
||||||
- npmci trigger
|
- npmci trigger
|
||||||
only:
|
only:
|
||||||
- tags
|
- tags
|
||||||
tags:
|
tags:
|
||||||
- docker
|
- lossless
|
||||||
- notpriv
|
- docker
|
||||||
|
- notpriv
|
||||||
|
|
||||||
pages:
|
pages:
|
||||||
image: hosttoday/ht-docker-dbase:npmci
|
|
||||||
services:
|
|
||||||
- docker:18-dind
|
|
||||||
stage: metadata
|
stage: metadata
|
||||||
script:
|
script:
|
||||||
|
- npmci node install lts
|
||||||
- npmci command npm install -g @gitzone/tsdoc
|
- npmci command npm install -g @gitzone/tsdoc
|
||||||
- npmci npm prepare
|
- npmci npm prepare
|
||||||
- npmci npm install
|
- npmci npm install
|
||||||
- npmci command tsdoc
|
- npmci command tsdoc
|
||||||
tags:
|
tags:
|
||||||
|
- lossless
|
||||||
- docker
|
- docker
|
||||||
- notpriv
|
- notpriv
|
||||||
only:
|
only:
|
||||||
@ -117,5 +123,5 @@ pages:
|
|||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 1 week
|
expire_in: 1 week
|
||||||
paths:
|
paths:
|
||||||
- public
|
- public
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
9
.snyk
Normal file
9
.snyk
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
|
||||||
|
version: v1.13.5
|
||||||
|
# ignores vulnerabilities until expiry date; change duration by modifying expiry date
|
||||||
|
ignore:
|
||||||
|
SNYK-JS-HTTPSPROXYAGENT-469131:
|
||||||
|
- '@pushrocks/smartnetwork > speedtest-net > https-proxy-agent':
|
||||||
|
reason: None given
|
||||||
|
expires: '2019-11-04T13:59:28.695Z'
|
||||||
|
patch: {}
|
26
.vscode/settings.json
vendored
Normal file
26
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"json.schemas": [
|
||||||
|
{
|
||||||
|
"fileMatch": ["/npmextra.json"],
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"npmci": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "settings for npmci"
|
||||||
|
},
|
||||||
|
"gitzone": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "settings for gitzone",
|
||||||
|
"properties": {
|
||||||
|
"projectType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["website", "element", "service", "npm"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -10,6 +10,7 @@
|
|||||||
"npmRegistryUrl": "registry.npmjs.org"
|
"npmRegistryUrl": "registry.npmjs.org"
|
||||||
},
|
},
|
||||||
"gitzone": {
|
"gitzone": {
|
||||||
|
"projectType": "npm",
|
||||||
"module": {
|
"module": {
|
||||||
"githost": "gitlab.com",
|
"githost": "gitlab.com",
|
||||||
"gitscope": "mojoio",
|
"gitscope": "mojoio",
|
||||||
|
1732
package-lock.json
generated
1732
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
48
package.json
48
package.json
@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "@mojoio/docker",
|
"name": "@mojoio/docker",
|
||||||
"version": "1.0.63",
|
"version": "1.0.93",
|
||||||
"description": "easy communication with docker remote api from node, TypeScript ready",
|
"description": "easy communication with docker remote api from node, TypeScript ready",
|
||||||
"private": false,
|
"private": false,
|
||||||
"main": "dist/index.js",
|
"main": "dist_ts/index.js",
|
||||||
"typings": "dist/index.d.ts",
|
"typings": "dist_ts/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "tstest test/",
|
"test": "tstest test/",
|
||||||
"build": "tsbuild"
|
"build": "tsbuild"
|
||||||
@ -27,34 +27,36 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://gitlab.com/pushrocks/dockersock#README",
|
"homepage": "https://gitlab.com/pushrocks/dockersock#README",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@pushrocks/lik": "^3.0.11",
|
"@pushrocks/lik": "^3.0.19",
|
||||||
"@pushrocks/smartfile": "^7.0.4",
|
"@pushrocks/smartfile": "^7.0.11",
|
||||||
"@pushrocks/smartjson": "^3.0.8",
|
"@pushrocks/smartjson": "^3.0.10",
|
||||||
"@pushrocks/smartlog": "^2.0.19",
|
"@pushrocks/smartlog": "^2.0.21",
|
||||||
"@pushrocks/smartnetwork": "^1.1.14",
|
"@pushrocks/smartnetwork": "^1.1.18",
|
||||||
"@pushrocks/smartpath": "^4.0.1",
|
"@pushrocks/smartpath": "^4.0.1",
|
||||||
"@pushrocks/smartpromise": "^3.0.2",
|
"@pushrocks/smartpromise": "^3.0.6",
|
||||||
"@pushrocks/smartrequest": "^1.1.26",
|
"@pushrocks/smartrequest": "^1.1.47",
|
||||||
"@pushrocks/smartstring": "^3.0.10",
|
"@pushrocks/smartstring": "^3.0.18",
|
||||||
"@pushrocks/smartversion": "^2.0.4",
|
"@pushrocks/smartversion": "^2.0.4",
|
||||||
"rxjs": "^6.5.3"
|
"@tsclass/tsclass": "^3.0.13",
|
||||||
|
"rxjs": "^6.5.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@gitzone/tsbuild": "^2.1.17",
|
"@gitzone/tsbuild": "^2.1.22",
|
||||||
"@gitzone/tsrun": "^1.2.8",
|
"@gitzone/tsrun": "^1.2.8",
|
||||||
"@gitzone/tstest": "^1.0.24",
|
"@gitzone/tstest": "^1.0.28",
|
||||||
"@pushrocks/tapbundle": "^3.0.13",
|
"@pushrocks/tapbundle": "^3.2.1",
|
||||||
"@types/node": "^12.7.4",
|
"@types/node": "^13.9.3",
|
||||||
"tslint": "^5.19.0",
|
"tslint": "^6.1.0",
|
||||||
"tslint-config-prettier": "^1.18.0"
|
"tslint-config-prettier": "^1.18.0"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"ts/*",
|
"ts/**/*",
|
||||||
"ts_web/*",
|
"ts_web/**/*",
|
||||||
"dist/*",
|
"dist/**/*",
|
||||||
"dist_web/*",
|
"dist_*/**/*",
|
||||||
"dist_ts_web/*",
|
"dist_ts/**/*",
|
||||||
"assets/*",
|
"dist_ts_web/**/*",
|
||||||
|
"assets/**/*",
|
||||||
"cli.js",
|
"cli.js",
|
||||||
"npmextra.json",
|
"npmextra.json",
|
||||||
"readme.md"
|
"readme.md"
|
||||||
|
@ -8,7 +8,7 @@ unofficial docker engine api abstraction package written in TypeScript
|
|||||||
* [docs (typedoc)](https://mojoio.gitlab.io/docker/)
|
* [docs (typedoc)](https://mojoio.gitlab.io/docker/)
|
||||||
|
|
||||||
## Status for master
|
## Status for master
|
||||||
[](https://gitlab.com/mojoio/docker/commits/master)
|
[](https://gitlab.com/mojoio/docker/commits/master)
|
||||||
[](https://gitlab.com/mojoio/docker/commits/master)
|
[](https://gitlab.com/mojoio/docker/commits/master)
|
||||||
[](https://www.npmjs.com/package/@mojoio/docker)
|
[](https://www.npmjs.com/package/@mojoio/docker)
|
||||||
[](https://snyk.io/test/npm/@mojoio/docker)
|
[](https://snyk.io/test/npm/@mojoio/docker)
|
||||||
@ -30,6 +30,10 @@ const run = async () => {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Contribution
|
||||||
|
|
||||||
|
We are always happy for code contributions. If you are not the code contributing type that is ok. Still, maintaining Open Source repositories takes considerable time and thought. If you like the quality of what we do and our modules are useful to you we would appreciate a little monthly contribution: You can [contribute one time](https://lossless.link/contribute-onetime) or [contribute monthly](https://lossless.link/contribute). :)
|
||||||
|
|
||||||
For further information read the linked docs at the top of this readme.
|
For further information read the linked docs at the top of this readme.
|
||||||
|
|
||||||
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh)
|
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh)
|
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();
|
15
test/test.ts
15
test/test.ts
@ -72,7 +72,6 @@ tap.test('should remove a secret by name', async () => {
|
|||||||
await mySecret.remove();
|
await mySecret.remove();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// SERVICES
|
// SERVICES
|
||||||
tap.test('should activate swarm mode', async () => {
|
tap.test('should activate swarm mode', async () => {
|
||||||
await testDockerHost.activateSwarm();
|
await testDockerHost.activateSwarm();
|
||||||
@ -88,28 +87,24 @@ tap.test('should create a service', async () => {
|
|||||||
Name: 'testNetwork'
|
Name: 'testNetwork'
|
||||||
});
|
});
|
||||||
const testSecret = await docker.DockerSecret.createSecret(testDockerHost, {
|
const testSecret = await docker.DockerSecret.createSecret(testDockerHost, {
|
||||||
name: 'serviceSecret',
|
name: 'testSecret',
|
||||||
version: '0.0.1',
|
version: '0.0.1',
|
||||||
labels: {},
|
labels: {},
|
||||||
contentArg: '{"hi": "wow"}'
|
contentArg: '{"hi": "wow"}'
|
||||||
});
|
});
|
||||||
const testImage = await docker.DockerImage.createFromRegistry(testDockerHost, {
|
const testImage = await docker.DockerImage.createFromRegistry(testDockerHost, {
|
||||||
imageUrl: 'nginx:latest'
|
imageUrl: 'registry.gitlab.com/hosttoday/ht-docker-static'
|
||||||
});
|
});
|
||||||
const testService = await docker.DockerService.createService(testDockerHost, {
|
const testService = await docker.DockerService.createService(testDockerHost, {
|
||||||
image: testImage,
|
image: testImage,
|
||||||
labels: {
|
labels: {},
|
||||||
'testlabel': 'hi'
|
|
||||||
},
|
|
||||||
name: 'testService',
|
name: 'testService',
|
||||||
networks: [testNetwork],
|
networks: [testNetwork],
|
||||||
networkAlias: 'testService',
|
networkAlias: 'testService',
|
||||||
secrets: [testSecret]
|
secrets: [testSecret],
|
||||||
|
ports: ['3000:80']
|
||||||
});
|
});
|
||||||
|
|
||||||
await testSecret.update(`{"updated": "socool"}`);
|
|
||||||
await testService.update();
|
|
||||||
|
|
||||||
await testService.remove();
|
await testService.remove();
|
||||||
await testNetwork.remove();
|
await testNetwork.remove();
|
||||||
await testSecret.remove();
|
await testSecret.remove();
|
||||||
|
@ -3,6 +3,12 @@ import { DockerContainer } from './docker.classes.container';
|
|||||||
import { DockerNetwork } from './docker.classes.network';
|
import { DockerNetwork } from './docker.classes.network';
|
||||||
import { DockerService } from './docker.classes.service';
|
import { DockerService } from './docker.classes.service';
|
||||||
|
|
||||||
|
export interface IAuthData {
|
||||||
|
serveraddress: string;
|
||||||
|
username: string;
|
||||||
|
password: string;
|
||||||
|
}
|
||||||
|
|
||||||
export class DockerHost {
|
export class DockerHost {
|
||||||
/**
|
/**
|
||||||
* the path where the docker sock can be found
|
* the path where the docker sock can be found
|
||||||
@ -31,26 +37,16 @@ export class DockerHost {
|
|||||||
* @param userArg
|
* @param userArg
|
||||||
* @param passArg
|
* @param passArg
|
||||||
*/
|
*/
|
||||||
public async auth(registryUrl: string, userArg: string, passArg: string) {
|
public async auth(authData: IAuthData) {
|
||||||
const response = await this.request('POST', '/auth', {
|
const response = await this.request('POST', '/auth', authData);
|
||||||
serveraddress: registryUrl,
|
|
||||||
username: userArg,
|
|
||||||
password: passArg
|
|
||||||
});
|
|
||||||
if (response.body.Status !== 'Login Succeeded') {
|
if (response.body.Status !== 'Login Succeeded') {
|
||||||
console.log(`Login failed with ${response.body.Status}`);
|
console.log(`Login failed with ${response.body.Status}`);
|
||||||
throw new Error(response.body.Status);
|
throw new Error(response.body.Status);
|
||||||
}
|
}
|
||||||
console.log(response.body.Status);
|
console.log(response.body.Status);
|
||||||
this.registryToken = plugins.smartstring.base64.encode(response.body.IdentityToken);
|
this.registryToken = plugins.smartstring.base64.encode(
|
||||||
}
|
plugins.smartjson.Smartjson.stringify(authData, {})
|
||||||
|
);
|
||||||
/**
|
|
||||||
* sets an auth token
|
|
||||||
* @param authToken
|
|
||||||
*/
|
|
||||||
public setAuthToken(authToken: string) {
|
|
||||||
this.registryToken = authToken;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,7 +55,14 @@ export class DockerHost {
|
|||||||
public async getGitlabComTokenFromDockerConfig() {
|
public async getGitlabComTokenFromDockerConfig() {
|
||||||
const dockerConfigPath = plugins.smartpath.get.home('~/.docker/config.json');
|
const dockerConfigPath = plugins.smartpath.get.home('~/.docker/config.json');
|
||||||
const configObject = plugins.smartfile.fs.toObjectSync(dockerConfigPath);
|
const configObject = plugins.smartfile.fs.toObjectSync(dockerConfigPath);
|
||||||
this.registryToken = configObject.auths['registry.gitlab.com'].auth;
|
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'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -73,7 +76,6 @@ export class DockerHost {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gets all containers
|
* gets all containers
|
||||||
*/
|
*/
|
||||||
@ -171,6 +173,7 @@ export class DockerHost {
|
|||||||
method: methodArg,
|
method: methodArg,
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
'X-Registry-Auth': this.registryToken,
|
||||||
Host: 'docker.sock'
|
Host: 'docker.sock'
|
||||||
},
|
},
|
||||||
requestBody: null,
|
requestBody: null,
|
||||||
|
@ -21,7 +21,6 @@ export class DockerImage {
|
|||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -30,7 +29,6 @@ export class DockerImage {
|
|||||||
dockerHostArg: DockerHost,
|
dockerHostArg: DockerHost,
|
||||||
creationObject: interfaces.IImageCreationDescriptor
|
creationObject: interfaces.IImageCreationDescriptor
|
||||||
): Promise<DockerImage> {
|
): Promise<DockerImage> {
|
||||||
|
|
||||||
// lets create a sanatized imageUrlObject
|
// lets create a sanatized imageUrlObject
|
||||||
const imageUrlObject: {
|
const imageUrlObject: {
|
||||||
imageUrl: string;
|
imageUrl: string;
|
||||||
@ -46,9 +44,7 @@ export class DockerImage {
|
|||||||
const imageTag = imageUrlObject.imageUrl.split(':')[1];
|
const imageTag = imageUrlObject.imageUrl.split(':')[1];
|
||||||
if (imageUrlObject.imageTag) {
|
if (imageUrlObject.imageTag) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`imageUrl ${imageUrlObject.imageUrl} can't be tagged with ${
|
`imageUrl ${imageUrlObject.imageUrl} can't be tagged with ${imageUrlObject.imageTag} because it is already tagged with ${imageTag}`
|
||||||
imageUrlObject.imageTag
|
|
||||||
} because it is already tagged with ${imageTag}`
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
imageUrlObject.imageUrl = imageUrl;
|
imageUrlObject.imageUrl = imageUrl;
|
||||||
@ -141,6 +137,10 @@ export class DockerImage {
|
|||||||
|
|
||||||
// get stuff
|
// get stuff
|
||||||
public async getVersion() {
|
public async getVersion() {
|
||||||
return this.Labels.version;
|
if (this.Labels && this.Labels.version) {
|
||||||
|
return this.Labels.version;
|
||||||
|
} else {
|
||||||
|
return '0.0.0';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import * as plugins from './docker.plugins';
|
|||||||
import * as interfaces from './interfaces';
|
import * as interfaces from './interfaces';
|
||||||
|
|
||||||
import { DockerHost } from './docker.classes.host';
|
import { DockerHost } from './docker.classes.host';
|
||||||
|
import { DockerService } from './docker.classes.service';
|
||||||
|
|
||||||
export class DockerNetwork {
|
export class DockerNetwork {
|
||||||
public static async getNetworks(dockerHost: DockerHost): Promise<DockerNetwork[]> {
|
public static async getNetworks(dockerHost: DockerHost): Promise<DockerNetwork[]> {
|
||||||
@ -29,17 +30,17 @@ export class DockerNetwork {
|
|||||||
CheckDuplicate: true,
|
CheckDuplicate: true,
|
||||||
Driver: 'overlay',
|
Driver: 'overlay',
|
||||||
EnableIPv6: false,
|
EnableIPv6: false,
|
||||||
IPAM: {
|
/* IPAM: {
|
||||||
Driver: 'default',
|
Driver: 'default',
|
||||||
Config: [
|
Config: [
|
||||||
{
|
{
|
||||||
Subnet: '172.20.10.0/16',
|
Subnet: `172.20.${networkCreationDescriptor.NetworkNumber}.0/16`,
|
||||||
IPRange: '172.20.10.0/24',
|
IPRange: `172.20.${networkCreationDescriptor.NetworkNumber}.0/24`,
|
||||||
Gateway: '172.20.10.11'
|
Gateway: `172.20.${networkCreationDescriptor.NetworkNumber}.11`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
}, */
|
||||||
Internal: true,
|
Internal: false,
|
||||||
Attachable: true,
|
Attachable: true,
|
||||||
Ingress: false
|
Ingress: false
|
||||||
});
|
});
|
||||||
@ -90,4 +91,30 @@ export class DockerNetwork {
|
|||||||
public async remove() {
|
public async remove() {
|
||||||
const response = await this.dockerHost.request('DELETE', `/networks/${this.Id}`);
|
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,17 +17,20 @@ export class DockerSecret {
|
|||||||
return secrets;
|
return secrets;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async getSecretByID (dockerHostArg: DockerHost, idArg: string) {
|
public static async getSecretByID(dockerHostArg: DockerHost, idArg: string) {
|
||||||
const secrets = await this.getSecrets(dockerHostArg);
|
const secrets = await this.getSecrets(dockerHostArg);
|
||||||
return secrets.find(secret => secret.ID === idArg);
|
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);
|
const secrets = await this.getSecrets(dockerHostArg);
|
||||||
return secrets.find(secret => secret.Spec.Name === nameArg);
|
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 = {
|
const labels: interfaces.TLabels = {
|
||||||
...secretDescriptor.labels,
|
...secretDescriptor.labels,
|
||||||
version: secretDescriptor.version
|
version: secretDescriptor.version
|
||||||
@ -40,7 +43,10 @@ export class DockerSecret {
|
|||||||
|
|
||||||
const newSecretInstance = new DockerSecret(dockerHostArg);
|
const newSecretInstance = new DockerSecret(dockerHostArg);
|
||||||
Object.assign(newSecretInstance, response.body);
|
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;
|
return newSecretInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +57,7 @@ export class DockerSecret {
|
|||||||
Labels: interfaces.TLabels;
|
Labels: interfaces.TLabels;
|
||||||
};
|
};
|
||||||
public Version: {
|
public Version: {
|
||||||
Index:string;
|
Index: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
public dockerHost: DockerHost;
|
public dockerHost: DockerHost;
|
||||||
@ -62,20 +68,23 @@ export class DockerSecret {
|
|||||||
/**
|
/**
|
||||||
* updates a secret
|
* updates a secret
|
||||||
*/
|
*/
|
||||||
public async update (contentArg: string) {
|
public async update(contentArg: string) {
|
||||||
const route = `/secrets/${this.ID}/update?=version=${this.Version.Index}`;
|
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}`, {
|
const response = await this.dockerHost.request(
|
||||||
Name: this.Spec.Name,
|
'POST',
|
||||||
Labels: this.Spec.Labels,
|
`/secrets/${this.ID}/update?version=${this.Version.Index}`,
|
||||||
Data: plugins.smartstring.base64.encode(contentArg)
|
{
|
||||||
});
|
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}`);
|
await this.dockerHost.request('DELETE', `/secrets/${this.ID}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// get things
|
// get things
|
||||||
public async getVersion() {
|
public async getVersion() {
|
||||||
return this.Spec.Labels.version;
|
return this.Spec.Labels.version;
|
||||||
|
@ -50,7 +50,46 @@ export class DockerService {
|
|||||||
version: serviceVersion
|
version: serviceVersion
|
||||||
};
|
};
|
||||||
|
|
||||||
const networkArray: any[] = [];
|
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'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serviceCreationDescriptor.resources && serviceCreationDescriptor.resources.volumeMounts) {
|
||||||
|
for(const volumeMount of serviceCreationDescriptor.resources.volumeMounts) {
|
||||||
|
mounts.push({
|
||||||
|
Target: volumeMount.containerFsPath,
|
||||||
|
Source: volumeMount.hostFsPath,
|
||||||
|
Consistency: 'default',
|
||||||
|
ReadOnly: false,
|
||||||
|
Type: 'bind'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const networkArray: Array<{
|
||||||
|
Target: string;
|
||||||
|
Aliases: string[];
|
||||||
|
}> = [];
|
||||||
|
|
||||||
for (const network of serviceCreationDescriptor.networks) {
|
for (const network of serviceCreationDescriptor.networks) {
|
||||||
networkArray.push({
|
networkArray.push({
|
||||||
Target: network.Name,
|
Target: network.Name,
|
||||||
@ -58,11 +97,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[] = [];
|
const secretArray: any[] = [];
|
||||||
for (const secret of serviceCreationDescriptor.secrets) {
|
for (const secret of serviceCreationDescriptor.secrets) {
|
||||||
secretArray.push({
|
secretArray.push({
|
||||||
File: {
|
File: {
|
||||||
Name: 'secret.json',
|
Name: 'secret.json', // TODO: make sure that works with multiple secrets
|
||||||
UID: '33',
|
UID: '33',
|
||||||
GID: '33',
|
GID: '33',
|
||||||
Mode: 384
|
Mode: 384
|
||||||
@ -72,13 +124,32 @@ export class DockerService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// lets configure limits
|
||||||
|
|
||||||
|
const memoryLimitMB =
|
||||||
|
serviceCreationDescriptor.resources && serviceCreationDescriptor.resources.memorySizeMB
|
||||||
|
? serviceCreationDescriptor.resources.memorySizeMB
|
||||||
|
: 1000;
|
||||||
|
|
||||||
|
const limits = {
|
||||||
|
MemoryBytes: memoryLimitMB * 1000000
|
||||||
|
};
|
||||||
|
|
||||||
|
if (serviceCreationDescriptor.resources) {
|
||||||
|
limits.MemoryBytes = serviceCreationDescriptor.resources.memorySizeMB * 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
const response = await dockerHost.request('POST', '/services/create', {
|
const response = await dockerHost.request('POST', '/services/create', {
|
||||||
Name: serviceCreationDescriptor.name,
|
Name: serviceCreationDescriptor.name,
|
||||||
TaskTemplate: {
|
TaskTemplate: {
|
||||||
ContainerSpec: {
|
ContainerSpec: {
|
||||||
Image: serviceCreationDescriptor.image.RepoTags[0],
|
Image: serviceCreationDescriptor.image.RepoTags[0],
|
||||||
Labels: labels,
|
Labels: labels,
|
||||||
Secrets: secretArray
|
Secrets: secretArray,
|
||||||
|
Mounts: mounts
|
||||||
|
/* DNSConfig: {
|
||||||
|
Nameservers: ['1.1.1.1']
|
||||||
|
} */
|
||||||
},
|
},
|
||||||
UpdateConfig: {
|
UpdateConfig: {
|
||||||
Parallelism: 0,
|
Parallelism: 0,
|
||||||
@ -87,10 +158,23 @@ export class DockerService {
|
|||||||
Monitor: 15000000000,
|
Monitor: 15000000000,
|
||||||
MaxFailureRatio: 0.15
|
MaxFailureRatio: 0.15
|
||||||
},
|
},
|
||||||
ForceUpdate: 1
|
ForceUpdate: 1,
|
||||||
|
Resources: {
|
||||||
|
Limits: limits
|
||||||
|
},
|
||||||
|
LogDriver: {
|
||||||
|
Name: 'json-file',
|
||||||
|
Options: {
|
||||||
|
'max-file': '3',
|
||||||
|
'max-size': '10M'
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Labels: serviceCreationDescriptor.labels,
|
Labels: labels,
|
||||||
Networks: networkArray
|
Networks: networkArray,
|
||||||
|
EndpointSpec: {
|
||||||
|
Ports: ports
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const createdService = await DockerService.getServiceByName(
|
const createdService = await DockerService.getServiceByName(
|
||||||
@ -136,32 +220,13 @@ export class DockerService {
|
|||||||
this.dockerHostRef = dockerHostArg;
|
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() {
|
public async remove() {
|
||||||
await this.dockerHostRef.request('DELETE', `/services/${this.ID}`);
|
await this.dockerHostRef.request('DELETE', `/services/${this.ID}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async reReadFromDockerEngine() {
|
public async reReadFromDockerEngine() {
|
||||||
const dockerData = await this.dockerHostRef.request('GET', `/services/${this.ID}`);
|
const dockerData = await this.dockerHostRef.request('GET', `/services/${this.ID}`);
|
||||||
Object.assign(this, dockerData);
|
// TODO: Better assign: Object.assign(this, dockerData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async needsUpdate(): Promise<boolean> {
|
public async needsUpdate(): Promise<boolean> {
|
||||||
@ -181,10 +246,4 @@ export class DockerService {
|
|||||||
console.log(`service ${this.Spec.Name} is up to date.`);
|
console.log(`service ${this.Spec.Name} is up to date.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updateFromRegistry() {
|
|
||||||
if (await this.needsUpdate()) {
|
|
||||||
this.update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
// node native path
|
// node native path
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
export {
|
export { path };
|
||||||
path
|
|
||||||
};
|
|
||||||
|
|
||||||
// @pushrocks scope
|
// @pushrocks scope
|
||||||
import * as lik from '@pushrocks/lik';
|
import * as lik from '@pushrocks/lik';
|
||||||
@ -19,7 +17,25 @@ import * as smartversion from '@pushrocks/smartversion';
|
|||||||
|
|
||||||
smartlog.defaultLogger.enableConsole();
|
smartlog.defaultLogger.enableConsole();
|
||||||
|
|
||||||
export { lik, smartfile, smartjson, smartlog, smartnetwork, smartpath, smartpromise, smartrequest, smartstring, smartversion };
|
export {
|
||||||
|
lik,
|
||||||
|
smartfile,
|
||||||
|
smartjson,
|
||||||
|
smartlog,
|
||||||
|
smartnetwork,
|
||||||
|
smartpath,
|
||||||
|
smartpromise,
|
||||||
|
smartrequest,
|
||||||
|
smartstring,
|
||||||
|
smartversion
|
||||||
|
};
|
||||||
|
|
||||||
|
// @tsclass scope
|
||||||
|
import * as tsclass from '@tsclass/tsclass';
|
||||||
|
|
||||||
|
export {
|
||||||
|
tsclass
|
||||||
|
};
|
||||||
|
|
||||||
// third party
|
// third party
|
||||||
import * as rxjs from 'rxjs';
|
import * as rxjs from 'rxjs';
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import * as plugins from '../docker.plugins';
|
||||||
|
|
||||||
import * as interfaces from './';
|
import * as interfaces from './';
|
||||||
import { DockerNetwork } from '../docker.classes.network';
|
import { DockerNetwork } from '../docker.classes.network';
|
||||||
import { DockerSecret } from '../docker.classes.secret';
|
import { DockerSecret } from '../docker.classes.secret';
|
||||||
@ -10,4 +12,10 @@ export interface IServiceCreationDescriptor {
|
|||||||
networks: DockerNetwork[];
|
networks: DockerNetwork[];
|
||||||
networkAlias: string;
|
networkAlias: string;
|
||||||
secrets: DockerSecret[];
|
secrets: DockerSecret[];
|
||||||
|
ports: string[];
|
||||||
|
accessHostDockerSock?: boolean;
|
||||||
|
resources?: {
|
||||||
|
memorySizeMB?: number;
|
||||||
|
volumeMounts: plugins.tsclass.container.IVolumeMount[]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user