Compare commits

..

85 Commits

Author SHA1 Message Date
440eb07afb 1.0.107 2024-02-02 16:54:08 +01:00
8d74712a97 fix(core): update 2024-02-02 16:54:07 +01:00
bbdf61e0a9 1.0.106 2024-02-02 16:40:39 +01:00
6f5ed697cb fix(core): update 2024-02-02 16:40:38 +01:00
cc93c296c6 1.0.105 2022-10-17 11:00:42 +02:00
07a4d024a8 fix(core): update 2022-10-17 11:00:42 +02:00
192216c7ec 1.0.104 2022-10-17 09:36:36 +02:00
daa97c68d9 fix(core): update 2022-10-17 09:36:35 +02:00
4569bffc37 1.0.103 2020-10-05 15:08:38 +00:00
ad4e6ad206 fix(core): update 2020-10-05 15:08:38 +00:00
ddfa701391 1.0.102 2020-10-01 14:59:38 +00:00
3d2d1e3b1d fix(core): update 2020-10-01 14:59:37 +00:00
01e79b8cd6 1.0.101 2020-09-30 17:06:27 +00:00
8b6021ff66 fix(core): update 2020-09-30 17:06:26 +00:00
5e5bb3032c 1.0.100 2020-09-30 17:01:55 +00:00
855e18a74f fix(core): update 2020-09-30 17:01:55 +00:00
b808a93e46 1.0.99 2020-09-30 17:01:30 +00:00
a18166260e fix(core): update 2020-09-30 17:01:30 +00:00
cba8de348d 1.0.98 2020-09-30 16:56:40 +00:00
30d4a7bd24 fix(core): update 2020-09-30 16:56:39 +00:00
4ea99426fd 1.0.97 2020-09-30 16:51:04 +00:00
19309f7f45 fix(core): update 2020-09-30 16:51:03 +00:00
4e7d2fd637 1.0.96 2020-09-30 16:35:24 +00:00
1675c0c4c9 fix(core): update 2020-09-30 16:35:24 +00:00
3a4f59ef9e 1.0.95 2020-09-30 16:27:43 +00:00
90eac3e50a fix(core): update 2020-09-30 16:27:43 +00:00
edec48529d 1.0.94 2020-03-23 00:17:15 +00:00
e622b97097 fix(core): update 2020-03-23 00:17:15 +00:00
23266ca459 1.0.93 2020-03-23 00:01:46 +00:00
a91e69b6db fix(core): update 2020-03-23 00:01:45 +00:00
015ccfad48 1.0.92 2020-03-22 23:53:32 +00:00
06d2fcb750 fix(core): update 2020-03-22 23:53:31 +00:00
f3e4bc0350 1.0.91 2019-11-20 13:36:36 +00:00
6de3abe3bf fix(readme): update 2019-11-20 13:36:36 +00:00
eaa4140f2f 1.0.90 2019-11-20 13:36:04 +00:00
b21fe80109 fix(structure): formatted, ci updates and new readme 2019-11-20 13:36:03 +00:00
96a2992432 1.0.89 2019-11-20 13:27:18 +00:00
870b5f2c07 fix(dependencies): update smartnetwork 2019-11-20 13:27:17 +00:00
212edf1db7 1.0.88 2019-11-19 18:45:10 +00:00
46dbd81bcc fix(dependencies): update 2019-11-19 18:45:09 +00:00
8f5678502d 1.0.87 2019-11-19 18:42:16 +00:00
959d7aaed1 fix(core): update 2019-11-19 18:42:15 +00:00
5aa10653b6 1.0.86 2019-10-05 15:59:37 +02:00
e120d6527e fix(core): update 2019-10-05 15:59:36 +02:00
c80da05fbb 1.0.85 2019-10-05 15:56:49 +02:00
b9c3475b86 fix(core): update 2019-10-05 15:56:46 +02:00
de2d7e647b 1.0.84 2019-09-24 20:20:37 +02:00
d9348bd016 fix(Image().getVersion()): now returns 0.0.0 for unavailable versions to make SemVer work later on 2019-09-24 20:20:37 +02:00
034fbc3994 1.0.83 2019-09-23 13:52:52 +02:00
a33a6a1f7f fix(core): update 2019-09-23 13:52:52 +02:00
9dd403821b 1.0.82 2019-09-23 13:41:06 +02:00
601d82ea74 fix(core): update 2019-09-23 13:41:06 +02:00
784bb22511 1.0.81 2019-09-22 23:42:30 +02:00
71c89ac9bc fix(core): update 2019-09-22 23:42:29 +02:00
0b3e3b68c9 1.0.80 2019-09-22 17:42:29 +02:00
f3779faaaf fix(core): update 2019-09-22 17:42:28 +02:00
73476c2c39 1.0.79 2019-09-22 17:03:53 +02:00
942f65268d fix(core): update 2019-09-22 17:03:53 +02:00
a965647c1f 1.0.78 2019-09-22 15:11:57 +02:00
db88c7f86c fix(core): update 2019-09-22 15:11:57 +02:00
3f18cb68bf 1.0.77 2019-09-22 15:02:29 +02:00
dae3b59e3b fix(core): update 2019-09-22 15:02:29 +02:00
53062e70d4 1.0.76 2019-09-22 14:32:48 +02:00
3e70dc465b fix(core): update 2019-09-22 14:32:48 +02:00
49445d93c6 1.0.75 2019-09-21 21:57:57 +02:00
4f838837f8 fix(core): update 2019-09-21 21:57:57 +02:00
c76968bbe8 1.0.74 2019-09-20 16:29:44 +02:00
6c5e5644b1 fix(core): update 2019-09-20 16:29:43 +02:00
5cf80944fe 1.0.73 2019-09-19 20:05:57 +02:00
cdb69c5f17 fix(core): update 2019-09-19 20:05:56 +02:00
178c1d2df1 1.0.72 2019-09-18 17:29:43 +02:00
43d9da808b fix(core): update 2019-09-18 17:29:43 +02:00
15f5c38eb0 1.0.71 2019-09-15 15:08:48 +02:00
225c1be14c fix(core): update 2019-09-15 15:08:48 +02:00
44f2aab2f6 1.0.70 2019-09-13 23:08:17 +02:00
b69315f1d3 1.0.69 2019-09-13 23:05:56 +02:00
7d20804986 fix(core): update 2019-09-13 23:05:55 +02:00
0aab639fbd 1.0.68 2019-09-13 22:43:30 +02:00
794bb60dfc fix(core): update 2019-09-13 22:43:29 +02:00
b182a379af 1.0.67 2019-09-13 22:37:38 +02:00
5c6c06dee6 fix(core): update 2019-09-13 22:37:38 +02:00
a48e1e035e 1.0.66 2019-09-13 22:31:03 +02:00
8836c06b56 fix(core): update 2019-09-13 22:31:03 +02:00
7af8e0739b 1.0.65 2019-09-13 22:09:35 +02:00
684185e951 fix(core): update 2019-09-13 22:09:35 +02:00
30 changed files with 6251 additions and 2473 deletions

View File

@ -0,0 +1,66 @@
name: Default (not tags)
on:
push:
tags-ignore:
- '**'
env:
IMAGE: registry.gitlab.com/hosttoday/ht-docker-node:npmci
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@gitea.lossless.digital/${{gitea.repository}}.git
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
NPMCI_URL_CLOUDLY: ${{secrets.NPMCI_URL_CLOUDLY}}
jobs:
security:
runs-on: ubuntu-latest
continue-on-error: true
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Install pnpm and npmci
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
- name: Run npm prepare
run: npmci npm prepare
- name: Audit production dependencies
run: |
npmci command npm config set registry https://registry.npmjs.org
npmci command pnpm audit --audit-level=high --prod
continue-on-error: true
- name: Audit development dependencies
run: |
npmci command npm config set registry https://registry.npmjs.org
npmci command pnpm audit --audit-level=high --dev
continue-on-error: true
test:
if: ${{ always() }}
needs: security
runs-on: ubuntu-latest
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Test stable
run: |
npmci node install stable
npmci npm install
npmci npm test
- name: Test build
run: |
npmci node install stable
npmci npm install
npmci npm build

View File

@ -0,0 +1,124 @@
name: Default (tags)
on:
push:
tags:
- '*'
env:
IMAGE: registry.gitlab.com/hosttoday/ht-docker-node:npmci
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@gitea.lossless.digital/${{gitea.repository}}.git
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
NPMCI_URL_CLOUDLY: ${{secrets.NPMCI_URL_CLOUDLY}}
jobs:
security:
runs-on: ubuntu-latest
continue-on-error: true
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
npmci npm prepare
- name: Audit production dependencies
run: |
npmci command npm config set registry https://registry.npmjs.org
npmci command pnpm audit --audit-level=high --prod
continue-on-error: true
- name: Audit development dependencies
run: |
npmci command npm config set registry https://registry.npmjs.org
npmci command pnpm audit --audit-level=high --dev
continue-on-error: true
test:
if: ${{ always() }}
needs: security
runs-on: ubuntu-latest
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
npmci npm prepare
- name: Test stable
run: |
npmci node install stable
npmci npm install
npmci npm test
- name: Test build
run: |
npmci node install stable
npmci npm install
npmci npm build
release:
needs: test
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
npmci npm prepare
- name: Release
run: |
npmci node install stable
npmci npm publish
metadata:
needs: test
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
container:
image: ${{ env.IMAGE }}
continue-on-error: true
steps:
- uses: actions/checkout@v3
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
npmci npm prepare
- name: Code quality
run: |
npmci command npm install -g typescript
npmci npm install
- name: Trigger
run: npmci trigger
- name: Build docs and upload artifacts
run: |
npmci node install stable
npmci npm install
pnpm install -g @git.zone/tsdoc
npmci command tsdoc
continue-on-error: true

4
.gitignore vendored
View File

@ -15,8 +15,6 @@ node_modules/
# builds # builds
dist/ dist/
dist_web/ dist_*/
dist_serve/
dist_ts_web/
# custom # custom

View File

@ -1,119 +0,0 @@
# gitzone ci_default
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
cache:
paths:
- .npmci_cache/
key: "$CI_BUILD_STAGE"
stages:
- security
- test
- release
- metadata
# ====================
# security stage
# ====================
mirror:
stage: security
script:
- npmci git mirror
tags:
- docker
- notpriv
snyk:
stage: security
script:
- npmci npm prepare
- npmci command npm install -g snyk
- npmci command npm install --ignore-scripts
- npmci command snyk test
tags:
- docker
- notpriv
# ====================
# test stage
# ====================
testStable:
stage: test
script:
- npmci npm prepare
- npmci node install stable
- npmci npm install
- npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
- priv
testBuild:
stage: test
script:
- npmci npm prepare
- npmci node install stable
- npmci npm install
- npmci command npm run build
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
- notpriv
release:
stage: release
script:
- npmci node install stable
- npmci npm publish
only:
- tags
tags:
- docker
- notpriv
# ====================
# metadata stage
# ====================
codequality:
stage: metadata
allow_failure: true
script:
- npmci command npm install -g tslint typescript
- npmci npm install
- npmci command "tslint -c tslint.json ./ts/**/*.ts"
tags:
- docker
- priv
trigger:
stage: metadata
script:
- npmci trigger
only:
- tags
tags:
- docker
- notpriv
pages:
image: hosttoday/ht-docker-dbase:npmci
services:
- docker:stable-dind
stage: metadata
script:
- npmci command npm install -g @gitzone/tsdoc
- npmci npm prepare
- npmci npm install
- npmci command tsdoc
tags:
- docker
- notpriv
only:
- tags
artifacts:
expire_in: 1 week
paths:
- public
allow_failure: true

24
.vscode/launch.json vendored
View File

@ -2,28 +2,10 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "current file", "command": "npm test",
"type": "node", "name": "Run npm test",
"request": "launch", "request": "launch",
"args": [ "type": "node-terminal"
"${relativeFile}"
],
"runtimeArgs": ["-r", "@gitzone/tsrun"],
"cwd": "${workspaceRoot}",
"protocol": "inspector",
"internalConsoleOptions": "openOnSessionStart"
},
{
"name": "test.ts",
"type": "node",
"request": "launch",
"args": [
"test/test.ts"
],
"runtimeArgs": ["-r", "@gitzone/tsrun"],
"cwd": "${workspaceRoot}",
"protocol": "inspector",
"internalConsoleOptions": "openOnSessionStart"
} }
] ]
} }

26
.vscode/settings.json vendored Normal file
View 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", "wcc"]
}
}
}
}
}
}
]
}

View File

@ -1,38 +0,0 @@
# @mojoio/docker
unofficial docker engine api abstraction package written in TypeScript
## Availabililty and Links
* [npmjs.org (npm package)](https://www.npmjs.com/package/@mojoio/docker)
* [gitlab.com (source)](https://gitlab.com/mojoio/docker)
* [github.com (source mirror)](https://github.com/mojoio/docker)
* [docs (typedoc)](https://mojoio.gitlab.io/docker/)
## Status for master
[![build status](https://gitlab.com/mojoio/docker/badges/master/build.svg)](https://gitlab.com/mojoio/docker/commits/master)
[![coverage report](https://gitlab.com/mojoio/docker/badges/master/coverage.svg)](https://gitlab.com/mojoio/docker/commits/master)
[![npm downloads per month](https://img.shields.io/npm/dm/@mojoio/docker.svg)](https://www.npmjs.com/package/@mojoio/docker)
[![Known Vulnerabilities](https://snyk.io/test/npm/@mojoio/docker/badge.svg)](https://snyk.io/test/npm/@mojoio/docker)
[![TypeScript](https://img.shields.io/badge/TypeScript->=%203.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
[![node](https://img.shields.io/badge/node->=%2010.x.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-prettier-ff69b4.svg)](https://prettier.io/)
## Usage
Use TypeScript for best in class instellisense.
```typescript
import { DockerHost } from '@mojoio/docker'; // require Dockersock class
const run = async () => {
const myDockerHost = new DockerHost(); // optional: you can pass a domain to the contructor, defaults to /var/run/docker.sock
const containers = await myDockerHost.getContainers(); // promise, resolve with an array of DockerContainers
};
```
For further information read the linked docs at the top of this readme.
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh)
| By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy)
[![repo-footer](https://lossless.gitlab.io/publicrelations/repofooter.svg)](https://maintainedby.lossless.com)

View File

@ -10,11 +10,12 @@
"npmRegistryUrl": "registry.npmjs.org" "npmRegistryUrl": "registry.npmjs.org"
}, },
"gitzone": { "gitzone": {
"projectType": "npm",
"module": { "module": {
"githost": "gitlab.com", "githost": "gitlab.com",
"gitscope": "mojoio", "gitscope": "mojoio",
"gitrepo": "docker", "gitrepo": "docker",
"shortDescription": "unofficial docker engine api abstraction package written in TypeScript", "description": "unofficial docker engine api abstraction package written in TypeScript",
"npmPackagename": "@mojoio/docker", "npmPackagename": "@mojoio/docker",
"license": "MIT" "license": "MIT"
} }

2057
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +1,19 @@
{ {
"name": "@mojoio/docker", "name": "@apiclient.xyz/docker",
"version": "1.0.64", "version": "1.0.107",
"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",
"type": "module",
"scripts": { "scripts": {
"test": "tstest test/", "test": "(tstest test/ --web)",
"build": "tsbuild" "build": "(tsbuild --web --allowimplicitany)",
"buildDocs": "tsdoc"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+ssh://git@gitlab.com/pushrocks/dockersock.git" "url": "git+https://gitlab.com/mojoio/docker.git"
}, },
"keywords": [ "keywords": [
"docker", "docker",
@ -23,40 +25,43 @@
"author": "Lossless GmbH", "author": "Lossless GmbH",
"license": "MIT", "license": "MIT",
"bugs": { "bugs": {
"url": "https://gitlab.com/pushrocks/dockersock/issues" "url": "https://gitlab.com/mojoio/docker/issues"
}, },
"homepage": "https://gitlab.com/pushrocks/dockersock#README", "homepage": "https://gitlab.com/mojoio/docker#readme",
"dependencies": { "dependencies": {
"@pushrocks/lik": "^3.0.11", "@push.rocks/lik": "^6.0.0",
"@pushrocks/smartfile": "^7.0.4", "@push.rocks/smartfile": "^11.0.4",
"@pushrocks/smartjson": "^3.0.8", "@push.rocks/smartjson": "^5.0.2",
"@pushrocks/smartlog": "^2.0.19", "@push.rocks/smartlog": "^3.0.1",
"@pushrocks/smartnetwork": "^1.1.14", "@push.rocks/smartnetwork": "^3.0.0",
"@pushrocks/smartpath": "^4.0.1", "@push.rocks/smartpath": "^5.0.5",
"@pushrocks/smartpromise": "^3.0.2", "@push.rocks/smartpromise": "^4.0.3",
"@pushrocks/smartrequest": "^1.1.26", "@push.rocks/smartrequest": "^2.0.11",
"@pushrocks/smartstring": "^3.0.10", "@push.rocks/smartstring": "^4.0.5",
"@pushrocks/smartversion": "^2.0.4", "@push.rocks/smartversion": "^3.0.2",
"rxjs": "^6.5.3" "@tsclass/tsclass": "^4.0.24",
"rxjs": "^7.5.7"
}, },
"devDependencies": { "devDependencies": {
"@gitzone/tsbuild": "^2.1.17", "@git.zone/tsbuild": "^2.1.25",
"@gitzone/tsrun": "^1.2.8", "@git.zone/tsrun": "^1.2.12",
"@gitzone/tstest": "^1.0.24", "@git.zone/tstest": "^1.0.52",
"@pushrocks/tapbundle": "^3.0.13", "@push.rocks/tapbundle": "^5.0.4",
"@types/node": "^12.7.4", "@types/node": "^20.11.16"
"tslint": "^5.19.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"
],
"browserslist": [
"last 1 chrome versions"
] ]
} }

5623
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

49
readme.md Normal file
View File

@ -0,0 +1,49 @@
# @mojoio/docker
unofficial docker engine api abstraction package written in TypeScript
## Availabililty and Links
* [npmjs.org (npm package)](https://www.npmjs.com/package/@mojoio/docker)
* [gitlab.com (source)](https://gitlab.com/mojoio/docker)
* [github.com (source mirror)](https://github.com/mojoio/docker)
* [docs (typedoc)](https://mojoio.gitlab.io/docker/)
## Status for master
Status Category | Status Badge
-- | --
GitLab Pipelines | [![pipeline status](https://gitlab.com/mojoio/docker/badges/master/pipeline.svg)](https://lossless.cloud)
GitLab Pipline Test Coverage | [![coverage report](https://gitlab.com/mojoio/docker/badges/master/coverage.svg)](https://lossless.cloud)
npm | [![npm downloads per month](https://badgen.net/npm/dy/@mojoio/docker)](https://lossless.cloud)
Snyk | [![Known Vulnerabilities](https://badgen.net/snyk/mojoio/docker)](https://lossless.cloud)
TypeScript Support | [![TypeScript](https://badgen.net/badge/TypeScript/>=%203.x/blue?icon=typescript)](https://lossless.cloud)
node Support | [![node](https://img.shields.io/badge/node->=%2010.x.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
Code Style | [![Code Style](https://badgen.net/badge/style/prettier/purple)](https://lossless.cloud)
PackagePhobia (total standalone install weight) | [![PackagePhobia](https://badgen.net/packagephobia/install/@mojoio/docker)](https://lossless.cloud)
PackagePhobia (package size on registry) | [![PackagePhobia](https://badgen.net/packagephobia/publish/@mojoio/docker)](https://lossless.cloud)
BundlePhobia (total size when bundled) | [![BundlePhobia](https://badgen.net/bundlephobia/minzip/@mojoio/docker)](https://lossless.cloud)
Platform support | [![Supports Windows 10](https://badgen.net/badge/supports%20Windows%2010/yes/green?icon=windows)](https://lossless.cloud) [![Supports Mac OS X](https://badgen.net/badge/supports%20Mac%20OS%20X/yes/green?icon=apple)](https://lossless.cloud)
## Usage
Use TypeScript for best in class instellisense.
```typescript
import { DockerHost } from '@mojoio/docker'; // require Dockersock class
const run = async () => {
const myDockerHost = new DockerHost(); // optional: you can pass a domain to the contructor, defaults to /var/run/docker.sock
const containers = await myDockerHost.getContainers(); // promise, resolve with an array of DockerContainers
};
```
## 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.
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh)
| By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy)
[![repo-footer](https://lossless.gitlab.io/publicrelations/repofooter.svg)](https://maintainedby.lossless.com)

11
scripts/testauth.ts Normal file
View File

@ -0,0 +1,11 @@
import * as docker from '../ts';
import * as smartstring from '@push.rocks/smartstring';
const run = async () => {
const dockerHost = new docker.DockerHost();
await docker.DockerImage.createFromRegistry(dockerHost, {
imageUrl: 'registry.gitlab.com/servezone/private/cloudly:latest'
});
};
run();

View File

@ -1,11 +1,11 @@
import { expect, tap } from '@pushrocks/tapbundle'; import { expect, tap } from '@push.rocks/tapbundle';
import * as docker from '../ts/index'; import * as docker from '../ts/index.js';
let testDockerHost: docker.DockerHost; let testDockerHost: docker.DockerHost;
tap.test('should create a new Dockersock instance', async () => { tap.test('should create a new Dockersock instance', async () => {
testDockerHost = new docker.DockerHost('http://unix:/var/run/docker.sock:'); testDockerHost = new docker.DockerHost();
return expect(testDockerHost).to.be.instanceof(docker.DockerHost); return expect(testDockerHost).toBeInstanceOf(docker.DockerHost);
}); });
tap.test('should create a docker swarm', async () => { tap.test('should create a docker swarm', async () => {
@ -26,10 +26,10 @@ tap.test('should list networks', async () => {
tap.test('should create a network', async () => { tap.test('should create a network', async () => {
const newNetwork = await docker.DockerNetwork.createNetwork(testDockerHost, { const newNetwork = await docker.DockerNetwork.createNetwork(testDockerHost, {
Name: 'webgateway' Name: 'webgateway',
}); });
expect(newNetwork).to.be.instanceOf(docker.DockerNetwork); expect(newNetwork).toBeInstanceOf(docker.DockerNetwork);
expect(newNetwork.Name).to.equal('webgateway'); expect(newNetwork.Name).toEqual('webgateway');
}); });
tap.test('should remove a network', async () => { tap.test('should remove a network', async () => {
@ -41,15 +41,15 @@ tap.test('should remove a network', async () => {
tap.test('should pull an image from imagetag', async () => { tap.test('should pull an image from imagetag', async () => {
const image = await docker.DockerImage.createFromRegistry(testDockerHost, { const image = await docker.DockerImage.createFromRegistry(testDockerHost, {
imageUrl: 'hosttoday/ht-docker-node', imageUrl: 'hosttoday/ht-docker-node',
imageTag: 'alpine' imageTag: 'alpine',
}); });
expect(image).to.be.instanceOf(docker.DockerImage); expect(image).toBeInstanceOf(docker.DockerImage);
console.log(image); console.log(image);
}); });
tap.test('should return a change Observable', async tools => { tap.test('should return a change Observable', async (tools) => {
const testObservable = await testDockerHost.getEventObservable(); const testObservable = await testDockerHost.getEventObservable();
const subscription = testObservable.subscribe(changeObject => { const subscription = testObservable.subscribe((changeObject) => {
console.log(changeObject); console.log(changeObject);
}); });
await tools.delayFor(2000); await tools.delayFor(2000);
@ -62,7 +62,7 @@ tap.test('should create a secret', async () => {
name: 'testSecret', name: 'testSecret',
version: '1.0.3', version: '1.0.3',
contentArg: `{ "hi": "wow"}`, contentArg: `{ "hi": "wow"}`,
labels: {} labels: {},
}); });
console.log(mySecret); console.log(mySecret);
}); });
@ -77,38 +77,34 @@ tap.test('should activate swarm mode', async () => {
await testDockerHost.activateSwarm(); await testDockerHost.activateSwarm();
}); });
tap.test('should list all services', async tools => { tap.test('should list all services', async (tools) => {
const services = await testDockerHost.getServices(); const services = await testDockerHost.getServices();
console.log(services); console.log(services);
}); });
tap.test('should create a service', async () => { tap.test('should create a service', async () => {
const testNetwork = await docker.DockerNetwork.createNetwork(testDockerHost, { const testNetwork = await docker.DockerNetwork.createNetwork(testDockerHost, {
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();

8
ts/00_commitinfo_data.ts Normal file
View File

@ -0,0 +1,8 @@
/**
* autocreated commitinfo by @pushrocks/commitinfo
*/
export const commitinfo = {
name: '@apiclient.xyz/docker',
version: '1.0.107',
description: 'easy communication with docker remote api from node, TypeScript ready'
}

View File

@ -1,7 +1,8 @@
import * as plugins from './docker.plugins'; import * as plugins from './docker.plugins.js';
import * as interfaces from './interfaces'; import * as interfaces from './interfaces/index.js';
import { DockerHost } from './docker.classes.host'; import { DockerHost } from './docker.classes.host.js';
import { logger } from './docker.logging.js';
export class DockerContainer { export class DockerContainer {
// STATIC // STATIC
@ -37,22 +38,19 @@ export class DockerContainer {
) { ) {
// check for unique hostname // check for unique hostname
const existingContainers = await DockerContainer.getContainers(dockerHost); const existingContainers = await DockerContainer.getContainers(dockerHost);
const sameHostNameContainer = existingContainers.find(container => { const sameHostNameContainer = existingContainers.find((container) => {
// TODO implement HostName Detection; // TODO implement HostName Detection;
return false; return false;
}); });
const response = await dockerHost.request('POST', '/containers/create', { const response = await dockerHost.request('POST', '/containers/create', {
Hostname: containerCreationDescriptor.Hostname, Hostname: containerCreationDescriptor.Hostname,
Domainname: containerCreationDescriptor.Domainname, Domainname: containerCreationDescriptor.Domainname,
User: 'root' User: 'root',
}); });
if (response.statusCode < 300) { if (response.statusCode < 300) {
plugins.smartlog.defaultLogger.log('info', 'Container created successfully'); logger.log('info', 'Container created successfully');
} else { } else {
plugins.smartlog.defaultLogger.log( logger.log('error', 'There has been a problem when creating the container');
'error',
'There has been a problem when creating the container'
);
} }
} }
@ -94,7 +92,7 @@ export class DockerContainer {
public Mounts: any; public Mounts: any;
constructor(dockerHostArg: DockerHost, dockerContainerObjectArg: any) { constructor(dockerHostArg: DockerHost, dockerContainerObjectArg: any) {
this.dockerHost = dockerHostArg; this.dockerHost = dockerHostArg;
Object.keys(dockerContainerObjectArg).forEach(keyArg => { Object.keys(dockerContainerObjectArg).forEach((keyArg) => {
this[keyArg] = dockerContainerObjectArg[keyArg]; this[keyArg] = dockerContainerObjectArg[keyArg];
}); });
} }

View File

@ -1,7 +1,15 @@
import * as plugins from './docker.plugins'; import * as plugins from './docker.plugins.js';
import { DockerContainer } from './docker.classes.container'; import { DockerContainer } from './docker.classes.container.js';
import { DockerNetwork } from './docker.classes.network'; import { DockerNetwork } from './docker.classes.network.js';
import { DockerService } from './docker.classes.service'; import { DockerService } from './docker.classes.service.js';
import { logger } from './docker.logging.js';
import path from 'path';
export interface IAuthData {
serveraddress: string;
username: string;
password: string;
}
export class DockerHost { export class DockerHost {
/** /**
@ -18,11 +26,17 @@ export class DockerHost {
let pathToUse: string; let pathToUse: string;
if (pathArg) { if (pathArg) {
pathToUse = pathArg; pathToUse = pathArg;
} else if (process.env.DOCKER_HOST) {
pathToUse = process.env.DOCKER_HOST;
} else if (process.env.CI) { } else if (process.env.CI) {
pathToUse = 'http://docker:2375/'; pathToUse = 'http://docker:2375/';
} else { } else {
pathToUse = 'http://unix:/var/run/docker.sock:'; pathToUse = 'http://unix:/var/run/docker.sock:';
} }
if (pathToUse.startsWith('unix:///')) {
pathToUse = pathToUse.replace('unix://', 'http://unix:') + ':';
}
console.log(`using docker sock at ${pathToUse}`);
this.socketPath = pathToUse; this.socketPath = pathToUse;
} }
@ -31,26 +45,14 @@ 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.stringify(authData));
}
/**
* sets an auth token
* @param authToken
*/
public setAuthToken(authToken: string) {
this.registryToken = authToken;
} }
/** /**
@ -59,7 +61,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',
});
} }
/** /**
@ -94,8 +103,8 @@ export class DockerHost {
*/ */
public async getEventObservable(): Promise<plugins.rxjs.Observable<any>> { public async getEventObservable(): Promise<plugins.rxjs.Observable<any>> {
const response = await this.requestStreaming('GET', '/events'); const response = await this.requestStreaming('GET', '/events');
return plugins.rxjs.Observable.create(observer => { return plugins.rxjs.Observable.create((observer) => {
response.on('data', data => { response.on('data', (data) => {
const eventString = data.toString(); const eventString = data.toString();
try { try {
const eventObject = JSON.parse(eventString); const eventObject = JSON.parse(eventString);
@ -132,12 +141,12 @@ export class DockerHost {
DataPathPort: 4789, DataPathPort: 4789,
DefaultAddrPool: ['10.10.0.0/8', '20.20.0.0/8'], DefaultAddrPool: ['10.10.0.0/8', '20.20.0.0/8'],
SubnetSize: 24, SubnetSize: 24,
ForceNewCluster: false ForceNewCluster: false,
}); });
if (response.statusCode === 200) { if (response.statusCode === 200) {
plugins.smartlog.defaultLogger.log('info', 'created Swam succesfully'); logger.log('info', 'created Swam succesfully');
} else { } else {
plugins.smartlog.defaultLogger.log('error', 'could not initiate swarm'); logger.log('error', 'could not initiate swarm');
} }
} }
@ -151,10 +160,10 @@ export class DockerHost {
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'X-Registry-Auth': this.registryToken, 'X-Registry-Auth': this.registryToken,
Host: 'docker.sock' Host: 'docker.sock',
}, },
requestBody: dataArg, requestBody: dataArg,
keepAlive: false keepAlive: false,
}); });
if (response.statusCode !== 200) { if (response.statusCode !== 200) {
console.log(response.body); console.log(response.body);
@ -170,10 +179,11 @@ export class DockerHost {
method: methodArg, method: methodArg,
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
Host: 'docker.sock' 'X-Registry-Auth': this.registryToken,
Host: 'docker.sock',
}, },
requestBody: null, requestBody: null,
keepAlive: false keepAlive: false,
}, },
true true
); );

View File

@ -1,6 +1,7 @@
import * as plugins from './docker.plugins'; import * as plugins from './docker.plugins.js';
import * as interfaces from './interfaces'; import * as interfaces from './interfaces/index.js';
import { DockerHost } from './docker.classes.host'; import { DockerHost } from './docker.classes.host.js';
import { logger } from './docker.logging.js';
export class DockerImage { export class DockerImage {
// STATIC // STATIC
@ -15,7 +16,7 @@ export class DockerImage {
public static async findImageByName(dockerHost: DockerHost, imageNameArg: string) { public static async findImageByName(dockerHost: DockerHost, imageNameArg: string) {
const images = await this.getImages(dockerHost); const images = await this.getImages(dockerHost);
const result = images.find(image => { const result = images.find((image) => {
if (image.RepoTags) { if (image.RepoTags) {
return image.RepoTags.includes(imageNameArg); return image.RepoTags.includes(imageNameArg);
} else { } else {
@ -37,7 +38,7 @@ export class DockerImage {
} = { } = {
imageUrl: creationObject.imageUrl, imageUrl: creationObject.imageUrl,
imageTag: creationObject.imageTag, imageTag: creationObject.imageTag,
imageOriginTag: null imageOriginTag: null,
}; };
if (imageUrlObject.imageUrl.includes(':')) { if (imageUrlObject.imageUrl.includes(':')) {
const imageUrl = imageUrlObject.imageUrl.split(':')[0]; const imageUrl = imageUrlObject.imageUrl.split(':')[0];
@ -63,14 +64,11 @@ export class DockerImage {
)}&tag=${encodeURIComponent(imageUrlObject.imageTag)}` )}&tag=${encodeURIComponent(imageUrlObject.imageTag)}`
); );
if (response.statusCode < 300) { if (response.statusCode < 300) {
plugins.smartlog.defaultLogger.log( logger.log('info', `Successfully pulled image ${imageUrlObject.imageUrl} from the registry`);
'info',
`Successfully pulled image ${imageUrlObject.imageUrl} from the registry`
);
const image = await DockerImage.findImageByName(dockerHostArg, imageUrlObject.imageOriginTag); const image = await DockerImage.findImageByName(dockerHostArg, imageUrlObject.imageOriginTag);
return image; return image;
} else { } else {
plugins.smartlog.defaultLogger.log('error', `Failed at the attempt of creating a new image`); logger.log('error', `Failed at the attempt of creating a new image`);
} }
} }
@ -110,7 +108,7 @@ export class DockerImage {
constructor(dockerHostArg, dockerImageObjectArg: any) { constructor(dockerHostArg, dockerImageObjectArg: any) {
this.dockerHost = dockerHostArg; this.dockerHost = dockerHostArg;
Object.keys(dockerImageObjectArg).forEach(keyArg => { Object.keys(dockerImageObjectArg).forEach((keyArg) => {
this[keyArg] = dockerImageObjectArg[keyArg]; this[keyArg] = dockerImageObjectArg[keyArg];
}); });
} }
@ -128,7 +126,7 @@ export class DockerImage {
*/ */
public async pullLatestImageFromRegistry(): Promise<boolean> { public async pullLatestImageFromRegistry(): Promise<boolean> {
const updatedImage = await DockerImage.createFromRegistry(this.dockerHost, { const updatedImage = await DockerImage.createFromRegistry(this.dockerHost, {
imageUrl: this.RepoTags[0] imageUrl: this.RepoTags[0],
}); });
Object.assign(this, updatedImage); Object.assign(this, updatedImage);
// TODO: Compare image digists before and after // TODO: Compare image digists before and after
@ -137,6 +135,10 @@ export class DockerImage {
// get stuff // get stuff
public async getVersion() { public async getVersion() {
if (this.Labels && this.Labels.version) {
return this.Labels.version; return this.Labels.version;
} else {
return '0.0.0';
}
} }
} }

View File

@ -1,7 +1,9 @@
import * as plugins from './docker.plugins'; import * as plugins from './docker.plugins.js';
import * as interfaces from './interfaces'; import * as interfaces from './interfaces/index.js';
import { DockerHost } from './docker.classes.host'; import { DockerHost } from './docker.classes.host.js';
import { DockerService } from './docker.classes.service.js';
import { logger } from './docker.logging.js';
export class DockerNetwork { export class DockerNetwork {
public static async getNetworks(dockerHost: DockerHost): Promise<DockerNetwork[]> { public static async getNetworks(dockerHost: DockerHost): Promise<DockerNetwork[]> {
@ -17,7 +19,7 @@ export class DockerNetwork {
public static async getNetworkByName(dockerHost: DockerHost, dockerNetworkNameArg: string) { public static async getNetworkByName(dockerHost: DockerHost, dockerNetworkNameArg: string) {
const networks = await DockerNetwork.getNetworks(dockerHost); const networks = await DockerNetwork.getNetworks(dockerHost);
return networks.find(dockerNetwork => dockerNetwork.Name === dockerNetworkNameArg); return networks.find((dockerNetwork) => dockerNetwork.Name === dockerNetworkNameArg);
} }
public static async createNetwork( public static async createNetwork(
@ -29,28 +31,25 @@ 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,
}); });
if (response.statusCode < 300) { if (response.statusCode < 300) {
plugins.smartlog.defaultLogger.log('info', 'Created network successfully'); logger.log('info', 'Created network successfully');
return await DockerNetwork.getNetworkByName(dockerHost, networkCreationDescriptor.Name); return await DockerNetwork.getNetworkByName(dockerHost, networkCreationDescriptor.Name);
} else { } else {
plugins.smartlog.defaultLogger.log( logger.log('error', 'There has been an error creating the wanted network');
'error',
'There has been an error creating the wanted network'
);
return null; return null;
} }
} }
@ -90,4 +89,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;
}
} }

View File

@ -1,8 +1,8 @@
import * as plugins from './docker.plugins'; import * as plugins from './docker.plugins.js';
import { DockerHost } from './docker.classes.host'; import { DockerHost } from './docker.classes.host.js';
// interfaces // interfaces
import * as interfaces from './interfaces'; import * as interfaces from './interfaces/index.js';
export class DockerSecret { export class DockerSecret {
// STATIC // STATIC
@ -19,12 +19,12 @@ export class DockerSecret {
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( public static async createSecret(
@ -33,12 +33,12 @@ export class DockerSecret {
) { ) {
const labels: interfaces.TLabels = { const labels: interfaces.TLabels = {
...secretDescriptor.labels, ...secretDescriptor.labels,
version: secretDescriptor.version version: secretDescriptor.version,
}; };
const response = await dockerHostArg.request('POST', '/secrets/create', { const response = await dockerHostArg.request('POST', '/secrets/create', {
Name: secretDescriptor.name, Name: secretDescriptor.name,
Labels: labels, Labels: labels,
Data: plugins.smartstring.base64.encode(secretDescriptor.contentArg) Data: plugins.smartstring.base64.encode(secretDescriptor.contentArg),
}); });
const newSecretInstance = new DockerSecret(dockerHostArg); const newSecretInstance = new DockerSecret(dockerHostArg);
@ -76,7 +76,7 @@ export class DockerSecret {
{ {
Name: this.Spec.Name, Name: this.Spec.Name,
Labels: this.Spec.Labels, Labels: this.Spec.Labels,
Data: plugins.smartstring.base64.encode(contentArg) Data: plugins.smartstring.base64.encode(contentArg),
} }
); );
} }

View File

@ -1,9 +1,10 @@
import * as plugins from './docker.plugins'; import * as plugins from './docker.plugins.js';
import * as interfaces from './interfaces'; import * as interfaces from './interfaces/index.js';
import { DockerHost } from './docker.classes.host'; import { DockerHost } from './docker.classes.host.js';
import { DockerImage } from './docker.classes.image'; import { DockerImage } from './docker.classes.image.js';
import { DockerSecret } from './docker.classes.secret'; import { DockerSecret } from './docker.classes.secret.js';
import { logger } from './docker.logging.js';
export class DockerService { export class DockerService {
// STATIC // STATIC
@ -23,7 +24,7 @@ export class DockerService {
networkName: string networkName: string
): Promise<DockerService> { ): Promise<DockerService> {
const allServices = await DockerService.getServices(dockerHost); const allServices = await DockerService.getServices(dockerHost);
const wantedService = allServices.find(service => { const wantedService = allServices.find((service) => {
return service.Spec.Name === networkName; return service.Spec.Name === networkName;
}); });
return wantedService; return wantedService;
@ -37,60 +38,141 @@ export class DockerService {
serviceCreationDescriptor: interfaces.IServiceCreationDescriptor serviceCreationDescriptor: interfaces.IServiceCreationDescriptor
): Promise<DockerService> { ): Promise<DockerService> {
// lets get the image // lets get the image
plugins.smartlog.defaultLogger.log( logger.log('info', `now creating service ${serviceCreationDescriptor.name}`);
'info',
`now creating service ${serviceCreationDescriptor.name}`
);
// await serviceCreationDescriptor.image.pullLatestImageFromRegistry(); // await serviceCreationDescriptor.image.pullLatestImageFromRegistry();
const serviceVersion = await serviceCreationDescriptor.image.getVersion(); const serviceVersion = await serviceCreationDescriptor.image.getVersion();
const labels: interfaces.TLabels = { const labels: interfaces.TLabels = {
...serviceCreationDescriptor.labels, ...serviceCreationDescriptor.labels,
version: serviceVersion version: serviceVersion,
}; };
const networkArray: any[] = []; const mounts: Array<{
for (const network of serviceCreationDescriptor.networks) { /**
networkArray.push({ * the target inside the container
Target: network.Name, */
Aliases: [serviceCreationDescriptor.networkAlias] 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) {
networkArray.push({
Target: network.Name,
Aliases: [serviceCreationDescriptor.networkAlias],
});
}
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,
}, },
SecretID: secret.ID, SecretID: secret.ID,
SecretName: secret.Spec.Name SecretName: secret.Spec.Name,
}); });
} }
// 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,
Delay: 0, Delay: 0,
FailureAction: 'pause', FailureAction: 'pause',
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: labels,
Networks: networkArray,
EndpointSpec: {
Ports: ports,
}, },
Labels: serviceCreationDescriptor.labels,
Networks: networkArray
}); });
const createdService = await DockerService.getServiceByName( const createdService = await DockerService.getServiceByName(
@ -136,32 +218,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> {
@ -169,7 +232,7 @@ export class DockerService {
await this.reReadFromDockerEngine(); await this.reReadFromDockerEngine();
const dockerImage = await DockerImage.createFromRegistry(this.dockerHostRef, { const dockerImage = await DockerImage.createFromRegistry(this.dockerHostRef, {
imageUrl: this.Spec.TaskTemplate.ContainerSpec.Image imageUrl: this.Spec.TaskTemplate.ContainerSpec.Image,
}); });
const imageVersion = new plugins.smartversion.SmartVersion(dockerImage.Labels.version); const imageVersion = new plugins.smartversion.SmartVersion(dockerImage.Labels.version);
@ -181,10 +244,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();
}
}
} }

3
ts/docker.logging.ts Normal file
View File

@ -0,0 +1,3 @@
import * as plugins from './docker.plugins.js';
export const logger = new plugins.smartlog.ConsoleLog();

View File

@ -4,18 +4,16 @@ import * as path from 'path';
export { path }; export { path };
// @pushrocks scope // @pushrocks scope
import * as lik from '@pushrocks/lik'; import * as lik from '@push.rocks/lik';
import * as smartfile from '@pushrocks/smartfile'; import * as smartfile from '@push.rocks/smartfile';
import * as smartjson from '@pushrocks/smartjson'; import * as smartjson from '@push.rocks/smartjson';
import * as smartlog from '@pushrocks/smartlog'; import * as smartlog from '@push.rocks/smartlog';
import * as smartnetwork from '@pushrocks/smartnetwork'; import * as smartnetwork from '@push.rocks/smartnetwork';
import * as smartpath from '@pushrocks/smartpath'; import * as smartpath from '@push.rocks/smartpath';
import * as smartpromise from '@pushrocks/smartpromise'; import * as smartpromise from '@push.rocks/smartpromise';
import * as smartrequest from '@pushrocks/smartrequest'; import * as smartrequest from '@push.rocks/smartrequest';
import * as smartstring from '@pushrocks/smartstring'; import * as smartstring from '@push.rocks/smartstring';
import * as smartversion from '@pushrocks/smartversion'; import * as smartversion from '@push.rocks/smartversion';
smartlog.defaultLogger.enableConsole();
export { export {
lik, lik,
@ -27,9 +25,14 @@ export {
smartpromise, smartpromise,
smartrequest, smartrequest,
smartstring, smartstring,
smartversion 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';

View File

@ -1,6 +1,6 @@
export * from './docker.classes.host'; export * from './docker.classes.host.js';
export * from './docker.classes.container'; export * from './docker.classes.container.js';
export * from './docker.classes.image'; export * from './docker.classes.image.js';
export * from './docker.classes.network'; export * from './docker.classes.network.js';
export * from './docker.classes.secret'; export * from './docker.classes.secret.js';
export * from './docker.classes.service'; export * from './docker.classes.service.js';

View File

@ -1,4 +1,4 @@
import { DockerNetwork } from '../docker.classes.network'; import { DockerNetwork } from '../docker.classes.network.js';
export interface IContainerCreationDescriptor { export interface IContainerCreationDescriptor {
Hostname: string; Hostname: string;

View File

@ -1,7 +1,7 @@
export * from './container'; export * from './container.js';
export * from './image'; export * from './image.js';
export * from './label'; export * from './label.js';
export * from './network'; export * from './network.js';
export * from './port'; export * from './port.js';
export * from './secret'; export * from './secret.js';
export * from './service'; export * from './service.js';

View File

@ -1,4 +1,4 @@
import * as interfaces from './'; import * as interfaces from './index.js';
export interface ISecretCreationDescriptor { export interface ISecretCreationDescriptor {
name: string; name: string;

View File

@ -1,7 +1,9 @@
import * as interfaces from './'; import * as plugins from '../docker.plugins.js';
import { DockerNetwork } from '../docker.classes.network';
import { DockerSecret } from '../docker.classes.secret'; import * as interfaces from './index.js';
import { DockerImage } from '../docker.classes.image'; import { DockerNetwork } from '../docker.classes.network.js';
import { DockerSecret } from '../docker.classes.secret.js';
import { DockerImage } from '../docker.classes.image.js';
export interface IServiceCreationDescriptor { export interface IServiceCreationDescriptor {
name: string; name: string;
@ -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[];
};
} }

14
tsconfig.json Normal file
View File

@ -0,0 +1,14 @@
{
"compilerOptions": {
"experimentalDecorators": true,
"useDefineForClassFields": false,
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"esModuleInterop": true,
"verbatimModuleSyntax": true
},
"exclude": [
"dist_*/**/*.d.ts"
]
}

View File

@ -1,17 +0,0 @@
{
"extends": ["tslint:latest", "tslint-config-prettier"],
"rules": {
"semicolon": [true, "always"],
"no-console": false,
"ordered-imports": false,
"object-literal-sort-keys": false,
"member-ordering": {
"options":{
"order": [
"static-method"
]
}
}
},
"defaultSeverity": "warning"
}