├── .github └── workflows │ └── npm.yml ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── docs ├── assets │ ├── css │ │ ├── main.css │ │ └── main.css.map │ ├── images │ │ ├── icons.png │ │ ├── icons@2x.png │ │ ├── widgets.png │ │ └── widgets@2x.png │ └── js │ │ ├── main.js │ │ └── search.js ├── classes │ ├── _container_.container.html │ ├── _container_.containerfs.html │ ├── _container_.default.html │ ├── _container_.exec.html │ ├── _container_.execmanager.html │ ├── _docker_.docker.html │ ├── _image_.default.html │ ├── _image_.image.html │ ├── _network_.default.html │ ├── _network_.network.html │ ├── _node_.default.html │ ├── _node_.node.html │ ├── _plugin_.plugin.html │ ├── _secret_.default.html │ ├── _secret_.secret.html │ ├── _service_.default.html │ ├── _service_.service.html │ ├── _swarm_.swarm.html │ ├── _task_.default.html │ ├── _task_.task.html │ ├── _volume_.default.html │ └── _volume_.volume.html ├── globals.html ├── index.html └── modules │ ├── _container_.html │ ├── _docker_.html │ ├── _image_.html │ ├── _network_.html │ ├── _node_.html │ ├── _plugin_.html │ ├── _secret_.html │ ├── _service_.html │ ├── _swarm_.html │ ├── _task_.html │ └── _volume_.html ├── examples ├── commands_and_kill.js ├── export_container.js ├── fetch_events.js ├── file_system.js ├── list_containers.js ├── logs_container.js ├── manage_containers.js ├── manage_images.js ├── pull_and_check_image.js └── top_containers.js ├── install_docker.sh ├── jsdoc.json ├── package-lock.json ├── package.json ├── src ├── container.ts ├── docker.ts ├── image.ts ├── network.ts ├── node.ts ├── plugin.ts ├── secret.ts ├── service.ts ├── swarm.ts ├── task.ts ├── types │ └── container.ts └── volume.ts ├── test.sh ├── test ├── container.js ├── docker.js ├── image.js ├── network.js ├── swarm.js ├── test-load.tar ├── test.tar └── volume.js ├── tsconfig.json ├── tslint.json └── yarn.lock /.github/workflows/npm.yml: -------------------------------------------------------------------------------- 1 | name: Publish Package to npmjs 2 | 3 | on: 4 | release: 5 | types: [created] 6 | 7 | jobs: 8 | publish: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | - uses: actions/setup-node@v3 13 | with: 14 | node-version: '16.x' 15 | registry-url: 'https://registry.npmjs.org' 16 | - run: npm ci 17 | - run: npm run build 18 | - run: npm publish 19 | env: 20 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | lib 29 | 30 | # Dependency directories 31 | node_modules 32 | jspm_packages 33 | 34 | # Optional npm cache directory 35 | .npm 36 | 37 | # Optional REPL history 38 | .node_repl_history 39 | 40 | *.swp 41 | 42 | test_folder 43 | 44 | # Editor 45 | .vscode 46 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: "6" 3 | dist: trusty 4 | sudo: required 5 | group: deprecated-2017Q2 6 | env: 7 | - DOCKER_VERSION=17.06.0 8 | before_script: 9 | - chmod +x install_docker.sh 10 | - sudo ./install_docker.sh ${DOCKER_VERSION} 11 | - npm run build 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # docker-api 2 | [![travis-ci](https://travis-ci.org/AgustinCB/docker-api.png?branch=master)](https://travis-ci.org/AgustinCB/docker-api) 3 | 4 | Docker Remote API driver for node.js. It uses the same modem than [dockerode](https://github.com/apocas/dockerode), but the interface is promisified and with a different syntax. 5 | 6 | Support for: 7 | 8 | * **streams** 9 | * **stream demux** 10 | * **entities** 11 | * **run** 12 | * **tests** 13 | * **promises** 14 | * **full es6 support** 15 | 16 | The current status of the package is in beta state. This module covers the full [API reference](https://docs.docker.com/engine/api/v1.30), including experimental stuff such as plugins. 17 | 18 | Check the [reference](https://agustincb.github.io/docker-api/) and the [tests](https://github.com/AgustinCB/docker-api/tree/master/test) for full examples. 19 | 20 | ## Installation 21 | ```console 22 | $ npm install node-docker-api 23 | ``` 24 | 25 | ## Usage 26 | 27 | You can find more into the [examples folder](https://github.com/AgustinCB/docker-api/tree/master/examples) 28 | 29 | ### Create, start, stop, restart and remove a container 30 | 31 | ``` js 32 | 'use strict'; 33 | const {Docker} = require('node-docker-api'); 34 | 35 | const docker = new Docker({ socketPath: '/var/run/docker.sock' }); 36 | 37 | docker.container.create({ 38 | Image: 'ubuntu', 39 | name: 'test' 40 | }) 41 | .then(container => container.start()) 42 | .then(container => container.stop()) 43 | .then(container => container.restart()) 44 | .then(container => container.delete({ force: true })) 45 | .catch(error => console.log(error)); 46 | ``` 47 | 48 | ### List, inspect and top containers 49 | 50 | ``` js 51 | 'use strict'; 52 | const {Docker} = require('node-docker-api'); 53 | 54 | const docker = new Docker({ socketPath: '/var/run/docker.sock' }); 55 | 56 | // List 57 | docker.container.list() 58 | // Inspect 59 | .then(containers => containers[0].status()) 60 | .then(container => container.top()) 61 | .then(processes => console.log(processes)) 62 | .catch(error => console.log(error)); 63 | ``` 64 | 65 | ### List, inspect and stat containers 66 | 67 | ``` js 68 | 'use strict'; 69 | const {Docker} = require('node-docker-api'); 70 | 71 | const docker = new Docker({ socketPath: '/var/run/docker.sock' }); 72 | 73 | // List 74 | docker.container.list() 75 | // Inspect 76 | .then(containers => containers[0].status()) 77 | .then(container => container.stats()) 78 | .then(stats => { 79 | stats.on('data', stat => console.log('Stats: ', stat.toString())) 80 | stats.on('error', err => console.log('Error: ', err)) 81 | }) 82 | .catch(error => console.log(error)); 83 | ``` 84 | 85 | ### Get logs of a container 86 | 87 | ```js 88 | 'use strict'; 89 | const {Docker} = require('node-docker-api'); 90 | 91 | const docker = new Docker({ socketPath: '/var/run/docker.sock' }); 92 | let container; 93 | 94 | docker.container.create({ 95 | Image: 'ubuntu', 96 | name: 'test' 97 | }) 98 | .then(container => container.logs({ 99 | follow: true, 100 | stdout: true, 101 | stderr: true 102 | })) 103 | .then(stream => { 104 | stream.on('data', info => console.log(info)) 105 | stream.on('error', err => console.log(err)) 106 | }) 107 | .catch(error => console.log(error)); 108 | ``` 109 | 110 | ### Export a container 111 | 112 | ``` js 113 | const {Docker} = require('node-docker-api'); 114 | const fs = require('fs'); 115 | 116 | const docker = new Docker({ socketPath: '/var/run/docker.sock' }); 117 | let container; 118 | 119 | docker.container.create({ 120 | Image: 'ubuntu', 121 | name: 'test' 122 | }) 123 | .then(container => container.start()) 124 | .then(container => container.export()) 125 | .then(content => { 126 | const file = fs.createWriteStream("container.tar"); 127 | file.end(content) 128 | }) 129 | .catch(error => console.log(error)); 130 | ``` 131 | 132 | ### Manipulate file system in a container 133 | 134 | ``` js 135 | 'use strict'; 136 | const fs = require('fs'); 137 | const {Docker} = require('node-docker-api'); 138 | 139 | const promisifyStream = stream => new Promise((resolve, reject) => { 140 | stream.on('data', data => console.log(data.toString())) 141 | stream.on('end', resolve) 142 | stream.on('error', reject) 143 | }); 144 | 145 | const docker = new Docker({ socketPath: '/var/run/docker.sock' }); 146 | let container; 147 | 148 | docker.container.create({ 149 | Image: 'ubuntu', 150 | Cmd: [ '/bin/bash', '-c', 'tail -f /var/log/dmesg' ], 151 | name: 'test' 152 | }) 153 | .then(container => container.start()) 154 | .then(_container => { 155 | container = _container 156 | return _container.fs.put('./file.tar', { 157 | path: 'root' 158 | }) 159 | }) 160 | .then(stream => promisifyStream(stream)) 161 | .then(() => container.fs.get({ path: '/var/log/dmesg' })) 162 | .then(stream => { 163 | const file = fs.createWriteStream("file.jpg"); 164 | stream.pipe(file); 165 | return promisifyStream(stream); 166 | }) 167 | .then(() => container.status()) 168 | .then(container => container.stop()) 169 | .catch(error => console.log(error)); 170 | ``` 171 | 172 | ### Execute commands and kill containers 173 | 174 | ``` js 175 | 'use strict'; 176 | const {Docker} = require('node-docker-api'); 177 | 178 | const promisifyStream = stream => new Promise((resolve, reject) => { 179 | stream.on('data', data => console.log(data.toString())) 180 | stream.on('end', resolve) 181 | stream.on('error', reject) 182 | }); 183 | 184 | const docker = new Docker({ socketPath: '/var/run/docker.sock' }); 185 | let _container; 186 | 187 | docker.container.create({ 188 | Image: 'ubuntu', 189 | Cmd: [ '/bin/bash', '-c', 'tail -f /var/log/dmesg' ], 190 | name: 'test' 191 | }) 192 | .then(container => container.start()) 193 | .then(container => { 194 | _container = container 195 | return container.exec.create({ 196 | AttachStdout: true, 197 | AttachStderr: true, 198 | Cmd: [ 'echo', 'test' ] 199 | }) 200 | }) 201 | .then(exec => { 202 | return exec.start({ Detach: false }) 203 | }) 204 | .then(stream => promisifyStream(stream)) 205 | .then(() => _container.kill()) 206 | .catch(error => console.log(error)); 207 | ``` 208 | 209 | ### Build, inspect and remove an image 210 | 211 | ``` js 212 | 'use strict'; 213 | const {Docker} = require('node-docker-api'); 214 | const tar = require('tar-fs'); 215 | 216 | const promisifyStream = stream => new Promise((resolve, reject) => { 217 | stream.on('data', data => console.log(data.toString())) 218 | stream.on('end', resolve) 219 | stream.on('error', reject) 220 | }); 221 | 222 | const docker = new Docker({ socketPath: '/var/run/docker.sock' }); 223 | 224 | var tarStream = tar.pack('/path/to/Dockerfile') 225 | docker.image.build(tarStream, { 226 | t: 'testimg' 227 | }) 228 | .then(stream => promisifyStream(stream)) 229 | .then(() => docker.image.get('testimg').status()) 230 | .then(image => image.remove()) 231 | .catch(error => console.log(error)); 232 | ``` 233 | 234 | ### Pull and check history of an image 235 | 236 | ``` js 237 | 'use strict'; 238 | const {Docker} = require('node-docker-api'); 239 | 240 | const promisifyStream = (stream) => new Promise((resolve, reject) => { 241 | stream.on('data', (d) => console.log(d.toString())) 242 | stream.on('end', resolve) 243 | stream.on('error', reject) 244 | }) 245 | 246 | const docker = new Docker({ socketPath: '/var/run/docker.sock' }) 247 | 248 | return docker.image.create({}, { fromImage: 'ubuntu', tag: 'latest' }) 249 | .then(stream => promisifyStream(stream)) 250 | .then(() => docker.image.get('ubuntu').status()) 251 | .then(image => image.history()) 252 | .then(events => console.log(events)) 253 | .catch(error => console.log(error)) 254 | ``` 255 | 256 | ### Fetch events from docker 257 | 258 | ``` js 259 | 'use strict' 260 | const fs = require('fs'); 261 | const {Docker} = require('node-docker-api'); 262 | 263 | const promisifyStream = stream => new Promise((resolve, reject) => { 264 | stream.on('data', data => console.log(data.toString())) 265 | stream.on('end', resolve) 266 | stream.on('error', reject) 267 | }) 268 | 269 | const docker = new Docker({ socketPath: '/var/run/docker.sock' }) 270 | 271 | docker.events({ 272 | since: ((new Date().getTime() / 1000) - 60).toFixed(0) 273 | }) 274 | .then(stream => promisifyStream(stream)) 275 | .catch(error => console.log(error)) 276 | ``` 277 | -------------------------------------------------------------------------------- /docs/assets/images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgustinCB/docker-api/2098bd424e71ccdde8f379edac6acc2b47b317b2/docs/assets/images/icons.png -------------------------------------------------------------------------------- /docs/assets/images/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgustinCB/docker-api/2098bd424e71ccdde8f379edac6acc2b47b317b2/docs/assets/images/icons@2x.png -------------------------------------------------------------------------------- /docs/assets/images/widgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgustinCB/docker-api/2098bd424e71ccdde8f379edac6acc2b47b317b2/docs/assets/images/widgets.png -------------------------------------------------------------------------------- /docs/assets/images/widgets@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgustinCB/docker-api/2098bd424e71ccdde8f379edac6acc2b47b317b2/docs/assets/images/widgets@2x.png -------------------------------------------------------------------------------- /docs/globals.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | node-docker-api 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 59 |

node-docker-api

60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |

Index

68 |
69 |
70 |
71 |

External modules

72 | 85 |
86 |
87 |
88 |
89 |
90 | 136 |
137 |
138 | 197 |
198 |

Generated using TypeDoc

199 |
200 |
201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /docs/modules/_container_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "container" | node-docker-api 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "container"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Classes

75 | 82 |
83 |
84 |
85 |
86 |
87 | 148 |
149 |
150 | 209 |
210 |

Generated using TypeDoc

211 |
212 |
213 | 214 | 215 | 216 | -------------------------------------------------------------------------------- /docs/modules/_docker_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "docker" | node-docker-api 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "docker"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Classes

75 | 78 |
79 |
80 |
81 |
82 |
83 | 132 |
133 |
134 | 193 |
194 |

Generated using TypeDoc

195 |
196 |
197 | 198 | 199 | 200 | -------------------------------------------------------------------------------- /docs/modules/_image_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "image" | node-docker-api 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "image"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Classes

75 | 79 |
80 |
81 |
82 |
83 |
84 | 136 |
137 |
138 | 197 |
198 |

Generated using TypeDoc

199 |
200 |
201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /docs/modules/_network_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "network" | node-docker-api 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "network"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Classes

75 | 79 |
80 |
81 |
82 |
83 |
84 | 136 |
137 |
138 | 197 |
198 |

Generated using TypeDoc

199 |
200 |
201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /docs/modules/_node_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "node" | node-docker-api 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "node"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Classes

75 | 79 |
80 |
81 |
82 |
83 |
84 | 136 |
137 |
138 | 197 |
198 |

Generated using TypeDoc

199 |
200 |
201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /docs/modules/_plugin_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "plugin" | node-docker-api 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "plugin"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Classes

75 | 78 |
79 |
80 |
81 |
82 |
83 | 132 |
133 |
134 | 193 |
194 |

Generated using TypeDoc

195 |
196 |
197 | 198 | 199 | 200 | -------------------------------------------------------------------------------- /docs/modules/_secret_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "secret" | node-docker-api 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "secret"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Classes

75 | 79 |
80 |
81 |
82 |
83 |
84 | 136 |
137 |
138 | 197 |
198 |

Generated using TypeDoc

199 |
200 |
201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /docs/modules/_service_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "service" | node-docker-api 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "service"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Classes

75 | 79 |
80 |
81 |
82 |
83 |
84 | 136 |
137 |
138 | 197 |
198 |

Generated using TypeDoc

199 |
200 |
201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /docs/modules/_swarm_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "swarm" | node-docker-api 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "swarm"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Classes

75 | 78 |
79 |
80 |
81 |
82 |
83 | 132 |
133 |
134 | 193 |
194 |

Generated using TypeDoc

195 |
196 |
197 | 198 | 199 | 200 | -------------------------------------------------------------------------------- /docs/modules/_task_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "task" | node-docker-api 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "task"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Classes

75 | 79 |
80 |
81 |
82 |
83 |
84 | 136 |
137 |
138 | 197 |
198 |

Generated using TypeDoc

199 |
200 |
201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /docs/modules/_volume_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "volume" | node-docker-api 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "volume"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Classes

75 | 79 |
80 |
81 |
82 |
83 |
84 | 136 |
137 |
138 | 197 |
198 |

Generated using TypeDoc

199 |
200 |
201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /examples/commands_and_kill.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const Docker = require('node-docker-api').Docker 3 | 4 | const promisifyStream = (stream) => new Promise((resolve, reject) => { 5 | stream.on('data', (d) => console.log(d.toString())) 6 | stream.on('end', resolve) 7 | stream.on('error', reject) 8 | }) 9 | 10 | const docker = new Docker({ socketPath: '/var/run/docker.sock' }) 11 | let _container 12 | 13 | docker.container.create({ 14 | Image: 'ubuntu', 15 | Cmd: [ '/bin/bash', '-c', 'tail -f /var/log/dmesg' ], 16 | name: 'test' 17 | }) 18 | .then((container) => container.start()) 19 | .then((container) => { 20 | _container = container 21 | return container.exec.create({ 22 | AttachStdout: true, 23 | AttachStderr: true, 24 | Cmd: [ 'echo', 'test' ] 25 | }) 26 | }) 27 | .then((exec) => { 28 | return exec.start({ Detach: false }) 29 | }) 30 | .then((stream) => promisifyStream(stream)) 31 | .then(() => _container.kill()) 32 | .catch((error) => console.log(error)) 33 | -------------------------------------------------------------------------------- /examples/export_container.js: -------------------------------------------------------------------------------- 1 | const Docker = require('node-docker-api').Docker, 2 | fs = require('fs') 3 | 4 | const docker = new Docker({ socketPath: '/var/run/docker.sock' }) 5 | let container 6 | 7 | docker.container.create({ 8 | Image: 'ubuntu', 9 | name: 'test' 10 | }) 11 | .then((container) => container.start()) 12 | .then((container) => container.export()) 13 | .then((content) => { 14 | const file = fs.createWriteStream("container.tar"); 15 | file.end(content) 16 | }) 17 | .catch((error) => console.log(error)) 18 | -------------------------------------------------------------------------------- /examples/fetch_events.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const Docker = require('node-docker-api').Docker, 4 | fs = require('fs') 5 | 6 | const promisifyStream = (stream) => new Promise((resolve, reject) => { 7 | stream.on('data', (d) => console.log(d.toString())) 8 | stream.on('end', resolve) 9 | stream.on('error', reject) 10 | }) 11 | 12 | const docker = new Docker({ socketPath: '/var/run/docker.sock' }) 13 | 14 | docker.events({ 15 | since: ((new Date().getTime() / 1000) - 60).toFixed(0) 16 | }) 17 | .then((stream) => promisifyStream(stream)) 18 | .catch((error) => console.log(error)) 19 | -------------------------------------------------------------------------------- /examples/file_system.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const Docker = require('node-docker-api').Docker, 3 | fs = require('fs') 4 | 5 | const promisifyStream = (stream) => new Promise((resolve, reject) => { 6 | stream.on('data', (d) => console.log(d.toString())) 7 | stream.on('end', resolve) 8 | stream.on('error', reject) 9 | }) 10 | 11 | const docker = new Docker({ socketPath: '/var/run/docker.sock' }) 12 | let container 13 | 14 | docker.container.create({ 15 | Image: 'ubuntu', 16 | Cmd: [ '/bin/bash', '-c', 'tail -f /var/log/dmesg' ], 17 | name: 'test' 18 | }) 19 | .then((container) => container.start()) 20 | .then((_container) => { 21 | container = _container 22 | return _container.fs.put('./file.tar', { 23 | path: 'root' 24 | }) 25 | }) 26 | .then((stream) => promisifyStream(stream)) 27 | .then(() => container.fs.get({ path: '/var/log/dmesg' })) 28 | .then((stream) => { 29 | const file = fs.createWriteStream("file.jpg"); 30 | stream.pipe(file) 31 | return promisifyStream(stream) 32 | }) 33 | .then(() => container.status()) 34 | .then((container) => container.stop()) 35 | .catch((error) => console.log(error)) 36 | -------------------------------------------------------------------------------- /examples/list_containers.js: -------------------------------------------------------------------------------- 1 | const Docker = require('node-docker-api').Docker 2 | 3 | const docker = new Docker({ socketPath: '/var/run/docker.sock' }) 4 | 5 | // List 6 | docker.container.list() 7 | // Inspect 8 | .then((containers) => containers[0].status()) 9 | .then((container) => container.stats()) 10 | .then((stats) => { 11 | stats.on('data', (stat) => console.log('Stats: ', stat.toString())) 12 | stats.on('error', (err) => console.log('Error: ', err)) 13 | }) 14 | .catch((error) => console.log(error)) 15 | -------------------------------------------------------------------------------- /examples/logs_container.js: -------------------------------------------------------------------------------- 1 | const Docker = require('node-docker-api').Docker 2 | 3 | const docker = new Docker({ socketPath: '/var/run/docker.sock' }) 4 | let container 5 | 6 | docker.container.create({ 7 | Image: 'ubuntu', 8 | name: 'test' 9 | }) 10 | .then((container) => container.logs({ 11 | follow: true, 12 | stdout: true, 13 | stderr: true 14 | })) 15 | .then((stream) => { 16 | stream.on('data', (info) => console.log(info)) 17 | stream.on('error', (err) => console.log(err)) 18 | }) 19 | .catch((error) => console.log(error)) 20 | -------------------------------------------------------------------------------- /examples/manage_containers.js: -------------------------------------------------------------------------------- 1 | const Docker = require('node-docker-api').Docker 2 | 3 | const docker = new Docker({ socketPath: '/var/run/docker.sock' }) 4 | 5 | docker.container.create({ 6 | Image: 'ubuntu', 7 | name: 'test' 8 | }) 9 | .then((container) => container.start()) 10 | .then((container) => container.stop()) 11 | .then((container) => container.restart()) 12 | .then((container) => container.delete({ force: true })) 13 | .catch((error) => console.log(error)) 14 | -------------------------------------------------------------------------------- /examples/manage_images.js: -------------------------------------------------------------------------------- 1 | const Docker = require('node-docker-api').Docker, 2 | tar = require('tar-fs') 3 | 4 | const promisifyStream = (stream) => new Promise((resolve, reject) => { 5 | stream.on('data', (d) => console.log(d.toString())) 6 | stream.on('end', resolve) 7 | stream.on('error', reject) 8 | }) 9 | 10 | const docker = new Docker({ socketPath: '/var/run/docker.sock' }) 11 | 12 | var tarStream = tar.pack('/path/to/Dockerfile') 13 | docker.image.build(tarStream, { 14 | t: 'testimg' 15 | }) 16 | .then((stream) => promisifyStream(stream)) 17 | .then(() => docker.image.get('testimg').status()) 18 | .then((image) => image.remove()) 19 | .catch((error) => console.log(error)) 20 | -------------------------------------------------------------------------------- /examples/pull_and_check_image.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const Docker = require('node-docker-api').Docker 4 | 5 | const promisifyStream = (stream) => new Promise((resolve, reject) => { 6 | stream.on('data', (d) => console.log(d.toString())) 7 | stream.on('end', resolve) 8 | stream.on('error', reject) 9 | }) 10 | 11 | const docker = new Docker({ socketPath: '/var/run/docker.sock' }) 12 | 13 | return docker.image.create({}, { fromImage: 'ubuntu', tag: 'latest' }) 14 | .then((stream) => promisifyStream(stream)) 15 | .then(() => docker.image.get('ubuntu').status()) 16 | .then((image) => image.history()) 17 | .then((events) => console.log(events)) 18 | .catch((error) => console.log(error)) 19 | -------------------------------------------------------------------------------- /examples/top_containers.js: -------------------------------------------------------------------------------- 1 | const Docker = require('node-docker-api').Docker 2 | 3 | const docker = new Docker({ socketPath: '/var/run/docker.sock' }) 4 | 5 | // List 6 | docker.container.list() 7 | // Inspect 8 | .then((containers) => containers[0].status()) 9 | .then((container) => container.top()) 10 | .then((processes) => console.log(processes)) 11 | .catch((error) => console.log(error)) 12 | -------------------------------------------------------------------------------- /install_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | # argv[0] 5 | DOCKER_VERSION=$1 6 | 7 | service docker stop 8 | apt-get -y --purge remove docker docker-engine docker.io 9 | 10 | apt-get update 11 | apt-get install -y apt-transport-https ca-certificates curl software-properties-common 12 | 13 | # install gpg key for docker rpo 14 | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - 15 | apt-key fingerprint 0EBFCD88 16 | 17 | # enable docker repo 18 | add-apt-repository \ 19 | "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ 20 | $(lsb_release -cs) \ 21 | stable" 22 | apt-get update 23 | apt-cache gencaches 24 | 25 | # install package 26 | apt-cache policy docker-ce 27 | apt-get -y --force-yes install docker-ce=${DOCKER_VERSION}~ce-0~ubuntu 28 | echo 'DOCKER_OPTS="-H unix:///var/run/docker.sock --pidfile=/var/run/docker.pid --experimental=true"' > /etc/default/docker 29 | #cat /etc/default/docker 30 | 31 | #service docker stop 32 | 33 | #/usr/bin/dockerd -H unix:///var/run/docker.sock --pidfile=/var/run/docker.pid --experimental=true & 34 | 35 | docker --version 36 | -------------------------------------------------------------------------------- /jsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": { 3 | "allowUnknownTags": true, 4 | "dictionaries": [ "jsdoc", "closure" ] 5 | }, 6 | "source": { 7 | "includePattern": ".+\\.js(doc|x)?$", 8 | "excludePattern": "(^|\\/|\\\\)_" 9 | }, 10 | "plugins": [], 11 | "templates": { 12 | "cleverLinks": false, 13 | "monospaceLinks": false 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-docker-api", 3 | "version": "1.1.23", 4 | "description": "Docker Remote API driver for node", 5 | "main": "./lib/docker", 6 | "typings": "./lib/docker", 7 | "scripts": { 8 | "watch-test": "nodemon --watch build --watch test --exec 'npm run test'", 9 | "lint": "./node_modules/tslint/bin/tslint -c tslint.json 'src/**/*.ts'", 10 | "test": "chmod +x test.sh; ./test.sh", 11 | "gendoc": "typedoc --out docs src", 12 | "build": "tsc --outDir lib" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/AgustinCB/docker-api.git" 17 | }, 18 | "keywords": [ 19 | "docker", 20 | "api", 21 | "node" 22 | ], 23 | "author": "AgustinCB", 24 | "license": "\tGPL-2.0", 25 | "bugs": { 26 | "url": "https://github.com/AgustinCB/docker-api/issues" 27 | }, 28 | "homepage": "https://github.com/AgustinCB/docker-api#readme", 29 | "devDependencies": { 30 | "@types/node": "10.5.1", 31 | "ava": "^0.17.0", 32 | "brace-expansion": "^1.1.7", 33 | "chai": "^3.5.0", 34 | "jsdox": "^0.4.10", 35 | "marked": "4.0.10", 36 | "mocha": "^2.5.3", 37 | "mustache": "2.2.1", 38 | "nodemon": "^1.11.0", 39 | "tslint": "^4.4.2", 40 | "typedoc": "^0.6.0", 41 | "typescript": "^2.1.6" 42 | }, 43 | "dependencies": { 44 | "docker-modem": "^0.3.1", 45 | "memorystream": "^0.3.1" 46 | } 47 | } -------------------------------------------------------------------------------- /src/docker.ts: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | import Modem = require('docker-modem') 4 | import ContainerManager from './container' 5 | import ImageManager from './image' 6 | import VolumeManager from './volume' 7 | import NetworkManager from './network' 8 | import NodeManager from './node' 9 | import PluginManager from './plugin' 10 | import SecretManager from './secret' 11 | import ServiceManager from './service' 12 | import SwarmManager from './swarm' 13 | import TaskManager from './task' 14 | 15 | /** 16 | * Docker class with all methods 17 | */ 18 | export class Docker { 19 | modem: Modem 20 | container: ContainerManager 21 | image: ImageManager 22 | volume: VolumeManager 23 | network: NetworkManager 24 | node: NodeManager 25 | plugin: PluginManager 26 | secret: SecretManager 27 | service: ServiceManager 28 | swarm: SwarmManager 29 | task: TaskManager 30 | 31 | /** 32 | * Creates the Docker Object 33 | * @param {Object} opts Docker options 34 | */ 35 | constructor (opts) { 36 | this.modem = new Modem(opts) 37 | 38 | this.container = new ContainerManager(this.modem) 39 | this.image = new ImageManager(this.modem) 40 | this.volume = new VolumeManager(this.modem) 41 | this.network = new NetworkManager(this.modem) 42 | this.node = new NodeManager(this.modem) 43 | this.plugin = new PluginManager(this.modem) 44 | this.secret = new SecretManager(this.modem) 45 | this.service = new ServiceManager(this.modem) 46 | this.swarm = new SwarmManager(this.modem) 47 | this.task = new TaskManager(this.modem) 48 | } 49 | 50 | /** 51 | * Validate credentials for a registry and get identity token, 52 | * if available, for accessing the registry without password 53 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/check-auth-configuration 54 | * @param {Object} opts Auth options 55 | * @return {Promise} Promise returning the result 56 | */ 57 | auth (opts: Object): Promise { 58 | const call = { 59 | path: '/auth?', 60 | method: 'POST', 61 | options: opts, 62 | statusCodes: { 63 | 200: true, 64 | 204: true, 65 | 500: 'server error' 66 | } 67 | } 68 | 69 | return new Promise((resolve, reject) => { 70 | this.modem.dial(call, (err, data: Object) => { 71 | if (err) return reject(err) 72 | resolve(data) 73 | }) 74 | }) 75 | } 76 | 77 | /** 78 | * Get system wide information about docker 79 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/display-system-wide-information 80 | * @return {Promise} Promise returning the result 81 | */ 82 | info (): Promise { 83 | const call = { 84 | path: '/info?', 85 | method: 'GET', 86 | statusCodes: { 87 | 200: true, 88 | 500: 'server error' 89 | } 90 | } 91 | 92 | return new Promise((resolve, reject) => { 93 | this.modem.dial(call, (err, data: Object) => { 94 | if (err) return reject(err) 95 | resolve(data) 96 | }) 97 | }) 98 | } 99 | 100 | /** 101 | * Get docker version information of server 102 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/show-the-docker-version-information 103 | * @return {Promise} Promise returning the result 104 | */ 105 | version (): Promise { 106 | const call = { 107 | path: '/version?', 108 | method: 'GET', 109 | statusCodes: { 110 | 200: true, 111 | 500: 'server error' 112 | } 113 | } 114 | 115 | return new Promise((resolve, reject) => { 116 | this.modem.dial(call, (err, data) => { 117 | if (err) return reject(err) 118 | resolve(data) 119 | }) 120 | }) 121 | } 122 | 123 | /** 124 | * Ping the docker server 125 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/ping-the-docker-server 126 | * @return {Promise} Promise returning the result 127 | */ 128 | ping (): Promise { 129 | const call = { 130 | path: '/_ping?', 131 | method: 'GET', 132 | statusCodes: { 133 | 200: true, 134 | 500: 'server error' 135 | } 136 | } 137 | 138 | return new Promise((resolve, reject) => { 139 | this.modem.dial(call, (err, data: string) => { 140 | if (err) return reject(err) 141 | resolve(data) 142 | }) 143 | }) 144 | } 145 | 146 | /** 147 | * Get container events from docker, can be in real time via streaming or via polling (with since) 148 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/monitor-docker-s-events 149 | * @param {Object} opts Options to send with the request (optional) 150 | * @return {Promise} Promise returning the result 151 | */ 152 | events (opts: Object = {}): Promise { 153 | const call = { 154 | path: '/events?', 155 | method: 'GET', 156 | options: opts, 157 | isStream: true, 158 | statusCodes: { 159 | 200: true, 160 | 500: 'server error' 161 | } 162 | } 163 | 164 | return new Promise((resolve, reject) => { 165 | this.modem.dial(call, (err, data: Object) => { 166 | if (err) return reject(err) 167 | resolve(data) 168 | }) 169 | }) 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /src/network.ts: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | import Modem = require('docker-modem') 4 | 5 | /** 6 | * Class reprensenting a network 7 | */ 8 | export class Network { 9 | modem: Modem 10 | id: string 11 | data: Object = {} 12 | 13 | /** 14 | * Creates a new network 15 | * @param {Modem} modem Modem to connect to the remote service 16 | * @param {string} id Id of the network (optional) 17 | */ 18 | constructor (modem: Modem, id: string) { 19 | this.modem = modem 20 | this.id = id 21 | } 22 | 23 | /** 24 | * Get low-level information on a network 25 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/inspect-network 26 | * The reason why this module isn't called inspect is because that interferes with the inspect utility of node. 27 | * @param {Object} opts Query params in the request (optional) 28 | * @return {Promise} Promise return the network 29 | */ 30 | status (opts?: Object) { 31 | const call = { 32 | path: `/networks/${this.id}?`, 33 | method: 'GET', 34 | options: opts, 35 | statusCodes: { 36 | 200: true, 37 | 404: 'no such network', 38 | 500: 'server error' 39 | } 40 | } 41 | 42 | return new Promise((resolve, reject) => { 43 | this.modem.dial(call, (err, conf) => { 44 | if (err) return reject(err) 45 | const network = new Network(this.modem, this.id) 46 | network.data = conf 47 | resolve(network) 48 | }) 49 | }) 50 | } 51 | 52 | /** 53 | * Remove a network 54 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/remove-a-network 55 | * @param {Object} opts Query params in the request (optional) 56 | * @return {Promise} Promise return the result 57 | */ 58 | remove (opts?: Object): Promise<{}> { 59 | const call = { 60 | path: `/networks/${this.id}?`, 61 | method: 'DELETE', 62 | options: opts, 63 | statusCodes: { 64 | 204: true, 65 | 404: 'no such network', 66 | 500: 'server error' 67 | } 68 | } 69 | 70 | return new Promise((resolve, reject) => { 71 | this.modem.dial(call, (err) => { 72 | if (err) return reject(err) 73 | resolve() 74 | }) 75 | }) 76 | } 77 | 78 | /** 79 | * Connect a container into the network 80 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/connect-a-container-to-a-network 81 | * @param {Object} opts Query params in the request (optional) 82 | * @return {Promise} Promise return the network 83 | */ 84 | connect (opts?: Object) { 85 | const call = { 86 | path: `/networks/${this.id}/connect?`, 87 | method: 'POST', 88 | options: opts, 89 | statusCodes: { 90 | 200: true, 91 | 403: 'operation not supported for swarm scoped network', 92 | 404: 'network or container not found', 93 | 500: 'server error' 94 | } 95 | } 96 | 97 | return new Promise((resolve, reject) => { 98 | this.modem.dial(call, (err, conf) => { 99 | if (err) return reject(err) 100 | const network = new Network(this.modem, this.id) 101 | network.data = conf 102 | resolve(network) 103 | }) 104 | }) 105 | } 106 | 107 | /** 108 | * Disonnect a container into the network 109 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/disconnect-a-container-from-a-network 110 | * @param {Object} opts Query params in the request (optional) 111 | * @return {Promise} Promise return the network 112 | */ 113 | disconnect (opts?: Object): Promise { 114 | const call = { 115 | path: `/networks/${this.id}/disconnect?`, 116 | method: 'POST', 117 | options: opts, 118 | statusCodes: { 119 | 200: true, 120 | 403: 'operation not supported for swarm scoped network', 121 | 404: 'network or container not found', 122 | 500: 'server error' 123 | } 124 | } 125 | 126 | return new Promise((resolve, reject) => { 127 | this.modem.dial(call, (err, conf) => { 128 | if (err) return reject(err) 129 | const network = new Network(this.modem, this.id) 130 | network.data = conf 131 | resolve(network) 132 | }) 133 | }) 134 | } 135 | } 136 | 137 | export default class { 138 | modem: Modem 139 | 140 | constructor (modem: Modem) { 141 | this.modem = modem 142 | } 143 | 144 | /** 145 | * Get a Network Object 146 | * @param {id} string ID of the secret 147 | * @return {Network} 148 | */ 149 | get (id: string): Network { 150 | return new Network(this.modem, id) 151 | } 152 | 153 | /** 154 | * Get the list of networks 155 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/list-networks 156 | * @param {Object} opts Query params in the request (optional) 157 | * @return {Promise} Promise returning the result as a list of networks 158 | */ 159 | list (opts?: Object): Promise> { 160 | const call = { 161 | path: '/networks?', 162 | method: 'GET', 163 | options: opts, 164 | statusCodes: { 165 | 200: true, 166 | 500: 'server error' 167 | } 168 | } 169 | 170 | return new Promise((resolve, reject) => { 171 | this.modem.dial(call, (err, networks) => { 172 | if (err) return reject(err) 173 | if (!networks || !networks.length) return resolve([]) 174 | resolve(networks.map((conf) => { 175 | const network = new Network(this.modem, conf.Id) 176 | network.data = conf 177 | return network 178 | })) 179 | }) 180 | }) 181 | } 182 | 183 | /** 184 | * Create a network 185 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/create-a-network 186 | * @param {Object} opts Query params in the request (optional) 187 | * @return {Promise} Promise return the new network 188 | */ 189 | create (opts?: Object): Promise { 190 | const call = { 191 | path: '/networks/create?', 192 | method: 'POST', 193 | options: opts, 194 | statusCodes: { 195 | 201: true, 196 | 404: 'plugin not found', 197 | 500: 'server error' 198 | } 199 | } 200 | 201 | return new Promise((resolve, reject) => { 202 | this.modem.dial(call, (err, conf) => { 203 | if (err) return reject(err) 204 | const network = new Network(this.modem, conf.Id) 205 | network.data = conf 206 | resolve(network) 207 | }) 208 | }) 209 | } 210 | 211 | /** 212 | * Prune network 213 | * https://docs.docker.com/engine/api/v1.25/#operation/NetworkPrune 214 | * @param {Object} opts Query params in the request (optional) 215 | * @return {Promise} Promise returning the container 216 | */ 217 | prune (opts?: Object): Promise { 218 | const call = { 219 | path: `/networks/prune`, 220 | method: 'POST', 221 | options: opts, 222 | statusCodes: { 223 | 200: true, 224 | 500: 'server error' 225 | } 226 | } 227 | 228 | return new Promise((resolve, reject) => { 229 | this.modem.dial(call, (err, res: Object) => { 230 | if (err) return reject(err) 231 | resolve(res) 232 | }) 233 | }) 234 | } 235 | } 236 | -------------------------------------------------------------------------------- /src/node.ts: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | import Modem = require('docker-modem') 4 | 5 | /** 6 | * Class representing a node 7 | */ 8 | export class Node { 9 | modem: Modem 10 | id: string 11 | data: Object = {} 12 | 13 | /** 14 | * Create a node 15 | * @param {Modem} modem Modem to connect to the remote service 16 | * @param {string} id Id of the node (optional) 17 | */ 18 | constructor (modem: Modem, id: string) { 19 | this.modem = modem 20 | this.id = id 21 | } 22 | 23 | /** 24 | * Update a node 25 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/update-a-node 26 | * @param {Object} opts Query params in the request (optional) 27 | * @return {Promise} Promise return the new node 28 | */ 29 | update (opts?: Object): Promise { 30 | const call = { 31 | path: `/nodes/${this.id}/update?`, 32 | method: 'POST', 33 | options: opts, 34 | statusCodes: { 35 | 200: true, 36 | 404: 'no such node', 37 | 500: 'server error' 38 | } 39 | } 40 | 41 | return new Promise((resolve, reject) => { 42 | this.modem.dial(call, (err, conf) => { 43 | if (err) return reject(err) 44 | const node = new Node(this.modem, this.id) 45 | node.data = conf 46 | resolve(node) 47 | }) 48 | }) 49 | } 50 | 51 | /** 52 | * Get low-level information on a node 53 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/inspect-a-node 54 | * The reason why this module isn't called inspect is because that interferes with the inspect utility of node. 55 | * @param {Object} opts Query params in the request (optional) 56 | * @return {Promise} Promise return the node 57 | */ 58 | status (opts?: Object) { 59 | const call = { 60 | path: `/nodes/${this.id}?`, 61 | method: 'GET', 62 | options: opts, 63 | statusCodes: { 64 | 200: true, 65 | 404: 'no such node', 66 | 500: 'server error' 67 | } 68 | } 69 | 70 | return new Promise((resolve, reject) => { 71 | this.modem.dial(call, (err, conf) => { 72 | if (err) return reject(err) 73 | const node = new Node(this.modem, this.id) 74 | node.data = conf 75 | resolve(node) 76 | }) 77 | }) 78 | } 79 | 80 | /** 81 | * Remove a node 82 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/remove-a-node 83 | * @param {Object} opts Query params in the request (optional) 84 | * @return {Promise} Promise return the result 85 | */ 86 | remove (opts: Object): Promise<{}> { 87 | const call = { 88 | path: `/nodes/${this.id}?`, 89 | method: 'DELETE', 90 | options: opts, 91 | statusCodes: { 92 | 204: true, 93 | 404: 'no such node', 94 | 500: 'server error' 95 | } 96 | } 97 | 98 | return new Promise((resolve, reject) => { 99 | this.modem.dial(call, (err) => { 100 | if (err) return reject(err) 101 | resolve() 102 | }) 103 | }) 104 | } 105 | } 106 | 107 | export default class { 108 | modem: Modem 109 | 110 | /** 111 | * Create a node 112 | * @param {Modem} modem Modem to connect to the remote service 113 | */ 114 | constructor (modem: Modem) { 115 | this.modem = modem 116 | } 117 | 118 | /** 119 | * Get a Node Object 120 | * @param {id} string ID of the secret 121 | * @return {Node} 122 | */ 123 | get (id: string): Node { 124 | return new Node(this.modem, id) 125 | } 126 | 127 | /** 128 | * Get the list of nodes 129 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/list-nodes 130 | * @param {Object} opts Query params in the request (optional) 131 | * @return {Promise} Promise returning the result as a list of nodes 132 | */ 133 | list (opts?: Object): Promise> { 134 | const call = { 135 | path: '/nodes?', 136 | method: 'GET', 137 | options: opts, 138 | statusCodes: { 139 | 200: true, 140 | 500: 'server error' 141 | } 142 | } 143 | 144 | return new Promise((resolve, reject) => { 145 | this.modem.dial(call, (err, result) => { 146 | if (err) return reject(err) 147 | if (!result || !result.length) return resolve([]) 148 | resolve(result.map((conf) => { 149 | const node = new Node(this.modem, conf.ID) 150 | node.data = conf 151 | return node 152 | })) 153 | }) 154 | }) 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /src/plugin.ts: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | /** 4 | * Class reprensenting a plugin 5 | */ 6 | class Plugin { 7 | 8 | modem: any 9 | id: any 10 | 11 | /** 12 | * Creates a new plugin 13 | * @param {Modem} modem Modem to connect to the remote service 14 | * @param {string} id Id of the plugin (optional) 15 | */ 16 | constructor (modem, id?) { 17 | this.modem = modem 18 | this.id = id 19 | } 20 | 21 | /** 22 | * Get the list of plugins 23 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/list-plugins 24 | * @param {Object} opts Query params in the request (optional) 25 | * @return {Promise} Promise returning the result as a list of plugins 26 | */ 27 | list (opts) { 28 | const call = { 29 | path: '/plugins?', 30 | method: 'GET', 31 | options: opts, 32 | statusCodes: { 33 | 200: true, 34 | 500: 'server error' 35 | } 36 | } 37 | 38 | return new Promise((resolve, reject) => { 39 | this.modem.dial(call, (err, plugins) => { 40 | if (err) return reject(err) 41 | if (!plugins || !plugins.length) return resolve([]) 42 | resolve(plugins.map((conf) => { 43 | const plugin = new Plugin(this.modem, conf.Id) 44 | return Object.assign(plugin, conf) 45 | })) 46 | }) 47 | }) 48 | } 49 | 50 | /** 51 | * upgrade a plugin 52 | * https://docs.docker.com/engine/api/v1.26/#operation/PluginUpgrade 53 | * @param {Object} opts Query params in the request (optional) 54 | * @return {Promise} Promise return the new plugin 55 | */ 56 | upgrade (opts) { 57 | let id 58 | [ opts, id ] = this.__processArguments(opts) 59 | 60 | const call = { 61 | path: `/plugins/${id}/upgrade?`, 62 | method: 'POST', 63 | options: opts, 64 | statusCodes: { 65 | 204: true, 66 | 404: 'plugin not installed', 67 | 500: 'server error' 68 | } 69 | } 70 | 71 | return new Promise((resolve, reject) => { 72 | this.modem.dial(call, (err, conf) => { 73 | if (err) return reject(err) 74 | const plugin = new Plugin(this.modem, opts.name) 75 | resolve(plugin) 76 | }) 77 | }) 78 | } 79 | 80 | /** 81 | * Create a plugin 82 | * https://docs.docker.com/engine/api/v1.25/#operation/PluginCreate 83 | * @param {Object} opts Query params in the request (optional) 84 | * @return {Promise} Promise return the new plugin 85 | */ 86 | create (opts) { 87 | const call = { 88 | path: '/plugins/create?', 89 | method: 'POST', 90 | options: opts, 91 | statusCodes: { 92 | 204: true, 93 | 500: 'server error' 94 | } 95 | } 96 | 97 | return new Promise((resolve, reject) => { 98 | this.modem.dial(call, (err, conf) => { 99 | if (err) return reject(err) 100 | const plugin = new Plugin(this.modem, opts.name) 101 | resolve(plugin) 102 | }) 103 | }) 104 | } 105 | 106 | /** 107 | * install a plugin 108 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/install-a-plugin 109 | * @param {Object} opts Query params in the request (optional) 110 | * @return {Promise} Promise return the new plugin 111 | */ 112 | install (opts) { 113 | const call = { 114 | path: '/plugins/pull?', 115 | method: 'POST', 116 | options: opts, 117 | statusCodes: { 118 | 200: true, 119 | 500: 'server error' 120 | } 121 | } 122 | 123 | return new Promise((resolve, reject) => { 124 | this.modem.dial(call, (err, conf) => { 125 | if (err) return reject(err) 126 | const plugin = new Plugin(this.modem, opts.name) 127 | resolve(plugin) 128 | }) 129 | }) 130 | } 131 | 132 | /** 133 | * Get low-level information on a plugin 134 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/inspect-a-plugin 135 | * The reason why this module isn't called inspect is because that interferes with the inspect utility of node. 136 | * @param {Object} opts Query params in the request (optional) 137 | * @param {String} id ID of the plugin to inspect, if it's not set, use the id of the Object (optional) 138 | * @return {Promise} Promise return the plugin 139 | */ 140 | status (opts, id) { 141 | [ opts, id ] = this.__processArguments(opts, id) 142 | 143 | const call = { 144 | path: `/plugins/${id}?`, 145 | method: 'GET', 146 | options: opts, 147 | statusCodes: { 148 | 200: true, 149 | 404: 'no such plugin', 150 | 500: 'server error' 151 | } 152 | } 153 | 154 | return new Promise((resolve, reject) => { 155 | this.modem.dial(call, (err, conf) => { 156 | if (err) return reject(err) 157 | const plugin = new Plugin(this.modem, id) 158 | resolve(Object.assign(plugin, conf)) 159 | }) 160 | }) 161 | } 162 | 163 | /** 164 | * Remove a plugin 165 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/remove-a-plugin 166 | * @param {Object} opts Query params in the request (optional) 167 | * @param {String} id ID of the plugin to inspect, if it's not set, use the id of the Object (optional) 168 | * @return {Promise} Promise return the result 169 | */ 170 | remove (opts, id) { 171 | [ opts, id ] = this.__processArguments(opts, id) 172 | const call = { 173 | path: `/plugins/${id}?`, 174 | method: 'DELETE', 175 | options: opts, 176 | statusCodes: { 177 | 200: true, 178 | 404: 'no such plugin', 179 | 500: 'server error' 180 | } 181 | } 182 | 183 | return new Promise((resolve, reject) => { 184 | this.modem.dial(call, (err, res) => { 185 | if (err) return reject(err) 186 | resolve(res) 187 | }) 188 | }) 189 | } 190 | 191 | /** 192 | * push a plugin 193 | * https://docs.docker.com/engine/api/v1.26/#operation/PluginPush 194 | * @param {Object} opts Query params in the request (optional) 195 | * @param {String} id ID of the plugin, if it's not set, use the id of the Object (optional) 196 | * @return {Promise} Promise return the plugin 197 | */ 198 | push (opts, id) { 199 | [ opts, id ] = this.__processArguments(opts, id) 200 | 201 | const call = { 202 | path: `/plugins/${id}/push?`, 203 | method: 'POST', 204 | options: opts, 205 | statusCodes: { 206 | 200: true, 207 | 404: 'plugin not found', 208 | 500: 'server error' 209 | } 210 | } 211 | 212 | return new Promise((resolve, reject) => { 213 | this.modem.dial(call, (err, conf) => { 214 | if (err) return reject(err) 215 | const plugin = new Plugin(this.modem, id) 216 | resolve(plugin) 217 | }) 218 | }) 219 | } 220 | 221 | /** 222 | * Set a plugin configuration 223 | * https://docs.docker.com/engine/api/v1.25/#operation/PluginSet 224 | * @param {Object} opts Query params in the request (optional) 225 | * @param {String} id ID of the plugin, if it's not set, use the id of the Object (optional) 226 | * @return {Promise} Promise return the plugin 227 | */ 228 | set (opts, id) { 229 | [ opts, id ] = this.__processArguments(opts, id) 230 | 231 | const call = { 232 | path: `/plugins/${id}/set?`, 233 | method: 'POST', 234 | options: opts, 235 | statusCodes: { 236 | 204: true, 237 | 404: 'plugin not found', 238 | 500: 'server error' 239 | } 240 | } 241 | 242 | return new Promise((resolve, reject) => { 243 | this.modem.dial(call, (err, conf) => { 244 | if (err) return reject(err) 245 | const plugin = new Plugin(this.modem, id) 246 | resolve(plugin) 247 | }) 248 | }) 249 | } 250 | 251 | /** 252 | * Enable a plugin 253 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/enable-a-plugin 254 | * @param {Object} opts Query params in the request (optional) 255 | * @param {String} id ID of the plugin, if it's not set, use the id of the Object (optional) 256 | * @return {Promise} Promise return the plugin 257 | */ 258 | enable (opts, id) { 259 | [ opts, id ] = this.__processArguments(opts, id) 260 | 261 | const call = { 262 | path: `/plugins/${id}/enable?`, 263 | method: 'POST', 264 | options: opts, 265 | statusCodes: { 266 | 200: true, 267 | 500: 'server error' 268 | } 269 | } 270 | 271 | return new Promise((resolve, reject) => { 272 | this.modem.dial(call, (err, conf) => { 273 | if (err) return reject(err) 274 | const plugin = new Plugin(this.modem, id) 275 | resolve(plugin) 276 | }) 277 | }) 278 | } 279 | 280 | /** 281 | * Disable a plugin 282 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/disable-a-plugin 283 | * @param {Object} opts Query params in the request (optional) 284 | * @param {String} id ID of the plugin, if it's not set, use the id of the Object (optional) 285 | * @return {Promise} Promise return the plugin 286 | */ 287 | disable (opts, id) { 288 | [ opts, id ] = this.__processArguments(opts, id) 289 | 290 | const call = { 291 | path: `/plugins/${id}/disable?`, 292 | method: 'POST', 293 | options: opts, 294 | statusCodes: { 295 | 200: true, 296 | 500: 'server error' 297 | } 298 | } 299 | 300 | return new Promise((resolve, reject) => { 301 | this.modem.dial(call, (err, conf) => { 302 | if (err) return reject(err) 303 | const plugin = new Plugin(this.modem, id) 304 | resolve(plugin) 305 | }) 306 | }) 307 | } 308 | 309 | __processArguments (opts, id?) { 310 | if (typeof opts === 'string' && !id) { 311 | id = opts 312 | } 313 | if (!id && this.id) { 314 | id = this.id 315 | } 316 | if (!opts) opts = {} 317 | return [ opts, id ] 318 | } 319 | } 320 | 321 | export default Plugin 322 | -------------------------------------------------------------------------------- /src/secret.ts: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | import Modem = require('docker-modem') 4 | 5 | /** 6 | * Class representing a secret 7 | */ 8 | export class Secret { 9 | modem: Modem 10 | id: string 11 | data: Object = {} 12 | 13 | /** 14 | * Create a secret 15 | * @param {Modem} modem Modem to connect to the remote service 16 | * @param {string} id Id of the secret (optional) 17 | */ 18 | constructor (modem: Modem, id: string) { 19 | this.modem = modem 20 | this.id = id 21 | } 22 | 23 | /** 24 | * Get low-level information on a secret 25 | * https://docs.docker.com/engine/api/v1.25/#operation/SecretInspect 26 | * The reason why this module isn't called inspect is because that interferes with the inspect utility of node. 27 | * @param {Object} opts Query params in the request (optional) 28 | * @return {Promise} Promise return the secret 29 | */ 30 | status (opts?: Object): Promise { 31 | const call = { 32 | path: `/secrets/${this.id}?`, 33 | method: 'GET', 34 | options: opts, 35 | statusCodes: { 36 | 200: true, 37 | 404: 'no such secret', 38 | 406: '406 node is not part of a swarm', 39 | 500: 'server error' 40 | } 41 | } 42 | 43 | return new Promise((resolve, reject) => { 44 | this.modem.dial(call, (err, conf) => { 45 | if (err) return reject(err) 46 | const secret = new Secret(this.modem, this.id) 47 | secret.data = conf 48 | resolve(secret) 49 | }) 50 | }) 51 | } 52 | 53 | /** 54 | * Remove a secret 55 | * https://docs.docker.com/engine/api/v1.25/#operation/SecretDelete 56 | * @param {Object} opts Query params in the request (optional) 57 | * @return {Promise} Promise return the result 58 | */ 59 | remove (opts?: Object): Promise<{}> { 60 | const call = { 61 | path: `/secrets/${this.id}?`, 62 | method: 'DELETE', 63 | options: opts, 64 | statusCodes: { 65 | 204: true, 66 | 404: 'no such secret', 67 | 500: 'server error' 68 | } 69 | } 70 | 71 | return new Promise((resolve, reject) => { 72 | this.modem.dial(call, (err) => { 73 | if (err) return reject(err) 74 | resolve() 75 | }) 76 | }) 77 | } 78 | } 79 | 80 | export default class { 81 | modem: Modem 82 | 83 | /** 84 | * Create a secret 85 | * @param {Modem} modem Modem to connect to the remote service 86 | */ 87 | constructor (modem: Modem) { 88 | this.modem = modem 89 | } 90 | 91 | /** 92 | * Get a Secret Object 93 | * @param {id} string ID of the secret 94 | * @return {Secret} 95 | */ 96 | get (id: string): Secret { 97 | return new Secret(this.modem, id) 98 | } 99 | 100 | /** 101 | * Get the list of secrets 102 | * https://docs.docker.com/engine/api/v1.25/#operation/SecretList 103 | * @param {Object} opts Query params in the request (optional) 104 | * @return {Promise} Promise returning the result as a list of secrets 105 | */ 106 | list (opts?: Object): Promise> { 107 | const call = { 108 | path: '/secrets', 109 | method: 'GET', 110 | options: opts, 111 | statusCodes: { 112 | 200: true, 113 | 500: 'server error' 114 | } 115 | } 116 | 117 | return new Promise((resolve, reject) => { 118 | this.modem.dial(call, (err, result) => { 119 | if (err) return reject(err) 120 | if (!result.length) return resolve([]) 121 | resolve(result.map((conf) => { 122 | const secret = new Secret(this.modem, conf.Name) 123 | secret.data = conf 124 | return secret 125 | })) 126 | }) 127 | }) 128 | } 129 | 130 | /** 131 | * Create a secret 132 | * https://docs.docker.com/engine/api/v1.25/#operation/SecretCreate 133 | * @param {Object} opts Query params in the request (optional) 134 | * @return {Promise} Promise return the new secret 135 | */ 136 | create (opts?: Object): Promise { 137 | const call = { 138 | path: '/secrets/create?', 139 | method: 'POST', 140 | options: opts, 141 | statusCodes: { 142 | 201: true, 143 | 406: 'server error or node is not part of a swarm', 144 | 409: '409 name conflicts with an existing Object', 145 | 500: 'server error' 146 | } 147 | } 148 | 149 | return new Promise((resolve, reject) => { 150 | this.modem.dial(call, (err, conf) => { 151 | if (err) return reject(err) 152 | const secret = new Secret(this.modem, conf.ID) 153 | secret.data = conf 154 | resolve(secret) 155 | }) 156 | }) 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /src/service.ts: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | import Modem = require('docker-modem') 4 | 5 | /** 6 | * Class representing a service 7 | */ 8 | export class Service { 9 | modem: Modem 10 | id: string 11 | data: Object = {} 12 | 13 | /** 14 | * Create a service 15 | * @param {Modem} modem Modem to connect to the remote service 16 | * @param {string} id Id of the service (optional) 17 | */ 18 | constructor (modem: Modem, id: string) { 19 | this.modem = modem 20 | this.id = id 21 | } 22 | 23 | /** 24 | * Update a service 25 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/update-a-service 26 | * @param {Object} opts Query params in the request (optional) 27 | * @param {Object} auth Authentication (optional) 28 | * @return {Promise} Promise return the new service 29 | */ 30 | update (opts?: Object, auth?: Object): Promise { 31 | const call = { 32 | path: `/services/${this.id}/update?`, 33 | method: 'POST', 34 | options: opts, 35 | authconfig: auth, 36 | statusCodes: { 37 | 200: true, 38 | 404: 'no such service', 39 | 500: 'server error' 40 | } 41 | } 42 | 43 | return new Promise((resolve, reject) => { 44 | this.modem.dial(call, (err, conf) => { 45 | if (err) return reject(err) 46 | const service = new Service(this.modem, this.id) 47 | service.data = conf 48 | resolve(service) 49 | }) 50 | }) 51 | } 52 | 53 | /** 54 | * Get low-level information on a service 55 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/inspect-one-or-more-services 56 | * The reason why this module isn't called inspect is because that interferes with the inspect utility of service. 57 | * @param {Object} opts Query params in the request (optional) 58 | * @return {Promise} Promise return the service 59 | */ 60 | status (opts?: Object): Promise { 61 | const call = { 62 | path: `/services/${this.id}?`, 63 | method: 'GET', 64 | options: opts, 65 | statusCodes: { 66 | 200: true, 67 | 404: 'no such service', 68 | 500: 'server error' 69 | } 70 | } 71 | 72 | return new Promise((resolve, reject) => { 73 | this.modem.dial(call, (err, conf) => { 74 | if (err) return reject(err) 75 | const service = new Service(this.modem, this.id) 76 | service.data = conf 77 | resolve(service) 78 | }) 79 | }) 80 | } 81 | 82 | /** 83 | * Remove a service 84 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/remove-a-service 85 | * @param {Object} opts Query params in the request (optional) 86 | * @return {Promise} Promise return the result 87 | */ 88 | remove (opts?: Object): Promise { 89 | const call = { 90 | path: `/services/${this.id}?`, 91 | method: 'DELETE', 92 | options: opts, 93 | statusCodes: { 94 | 200: true, 95 | 404: 'no such service', 96 | 500: 'server error' 97 | } 98 | } 99 | 100 | return new Promise((resolve, reject) => { 101 | this.modem.dial(call, (err, res: string) => { 102 | if (err) return reject(err) 103 | resolve(res) 104 | }) 105 | }) 106 | } 107 | 108 | /** 109 | * Logs of a service 110 | * https://docs.docker.com/engine/api/v1.27/#operation/ServiceLogs 111 | * @param {Object} opts Query params in the request (optional) 112 | * @return {Promise} Promise return the result 113 | */ 114 | logs (opts?: Object): Promise { 115 | const call = { 116 | path: `/services/${this.id}/logs?`, 117 | method: 'GET', 118 | options: opts, 119 | isStream: true, 120 | statusCodes: { 121 | 101: true, 122 | 200: true, 123 | 404: 'no such service', 124 | 500: 'server error', 125 | 501: 'use --experimental to see this', 126 | 503: 'node is not part of a swarm' 127 | } 128 | } 129 | 130 | return new Promise((resolve, reject) => { 131 | this.modem.dial(call, (err, logs) => { 132 | if (err) return reject(err) 133 | resolve(logs) 134 | }) 135 | }) 136 | } 137 | } 138 | 139 | export default class { 140 | modem: Modem 141 | 142 | /** 143 | * Create a service 144 | * @param {Modem} modem Modem to connect to the remote service 145 | */ 146 | constructor (modem: Modem) { 147 | this.modem = modem 148 | } 149 | 150 | /** 151 | * Get a Service Object 152 | * @param {id} string ID of the secret 153 | * @return {Network} 154 | */ 155 | get (id: string): Service { 156 | return new Service(this.modem, id) 157 | } 158 | 159 | /** 160 | * Create a service 161 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/create-a-service 162 | * @param {Object} opts Query params in the request (optional) 163 | * @param {Object} auth Authentication (optional) 164 | * @return {Promise} Promise return the new service 165 | */ 166 | create (opts?: Object, auth?: Object): Promise { 167 | const call = { 168 | path: '/services/create?', 169 | method: 'POST', 170 | options: opts, 171 | authconfig: auth, 172 | statusCodes: { 173 | 201: true, 174 | 406: 'node is not part of a swarm', 175 | 409: 'name conflicts' 176 | } 177 | } 178 | 179 | return new Promise((resolve, reject) => { 180 | this.modem.dial(call, (err, conf) => { 181 | if (err) return reject(err) 182 | const service = new Service(this.modem, conf.ID) 183 | service.data = conf 184 | resolve(service) 185 | }) 186 | }) 187 | } 188 | 189 | /** 190 | * Get the list of services 191 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/list-services 192 | * @param {Object} opts Query params in the request (optional) 193 | * @return {Promise} Promise returning the result as a list of services 194 | */ 195 | list (opts?: Object): Promise> { 196 | const call = { 197 | path: '/services?', 198 | method: 'GET', 199 | options: opts, 200 | statusCodes: { 201 | 200: true, 202 | 500: 'server error' 203 | } 204 | } 205 | 206 | return new Promise((resolve, reject) => { 207 | this.modem.dial(call, (err, result) => { 208 | if (err) return reject(err) 209 | resolve(result.map((conf) => { 210 | const service = new Service(this.modem, conf.ID) 211 | service.data = conf 212 | return service 213 | })) 214 | }) 215 | }) 216 | } 217 | } 218 | -------------------------------------------------------------------------------- /src/swarm.ts: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | import Modem = require('docker-modem') 4 | import { Node } from './node' 5 | 6 | /** 7 | * Class reprensenting a swarm 8 | */ 9 | export default class Swarm { 10 | modem: Modem 11 | data: Object = {} 12 | 13 | /** 14 | * Creates a new swarm 15 | * @param {Modem} modem Modem to connect to the remote service 16 | */ 17 | constructor (modem: Modem) { 18 | this.modem = modem 19 | } 20 | 21 | /** 22 | * Initialize a new swarm 23 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/initialize-a-new-swarm 24 | * @param {Object} opts Query params in the request (optional) 25 | * @return {Promise} Promise return the new node 26 | */ 27 | init (opts?: Object): Promise { 28 | const call = { 29 | path: '/swarm/init?', 30 | method: 'POST', 31 | options: opts, 32 | statusCodes: { 33 | 200: true, 34 | 400: 'bad parameter', 35 | 406: 'node is already part of a swarm' 36 | } 37 | } 38 | 39 | return new Promise((resolve, reject) => { 40 | this.modem.dial(call, (err, nodeId) => { 41 | if (err) return reject(err) 42 | const node = new Node(this.modem, nodeId) 43 | resolve(node) 44 | }) 45 | }) 46 | } 47 | 48 | /** 49 | * Get low-level information on a swarm 50 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/inspect-swarm 51 | * The reason why this module isn't called inspect is because that interferes with the inspect utility of node. 52 | * @param {Object} opts Query params in the request (optional) 53 | * @return {Promise} Promise return the swarm 54 | */ 55 | status (opts?: Object): Promise { 56 | const call = { 57 | path: `/swarm?`, 58 | method: 'GET', 59 | options: opts, 60 | statusCodes: { 61 | 200: true, 62 | 404: 'no such swarm', 63 | 500: 'server error' 64 | } 65 | } 66 | 67 | return new Promise((resolve, reject) => { 68 | this.modem.dial(call, (err, conf) => { 69 | if (err) return reject(err) 70 | const swarm = new Swarm(this.modem) 71 | swarm.data = conf 72 | resolve(swarm) 73 | }) 74 | }) 75 | } 76 | 77 | /** 78 | * Join a swarm 79 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/join-an-existing-swarm 80 | * @param {Object} opts Query params in the request (optional) 81 | * @return {Promise} Promise return the result 82 | */ 83 | join (opts?: Object): Promise { 84 | const call = { 85 | path: `/swarm/join?`, 86 | method: 'POST', 87 | options: opts, 88 | statusCodes: { 89 | 200: true, 90 | 400: 'bad parameter', 91 | 406: 'node is already part of a swarm' 92 | } 93 | } 94 | 95 | return new Promise((resolve, reject) => { 96 | this.modem.dial(call, (err, id: string) => { 97 | if (err) return reject(err) 98 | resolve(id) 99 | }) 100 | }) 101 | } 102 | 103 | /** 104 | * Leave a swarm 105 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/leave-a-swarm 106 | * @param {Object} opts Query params in the request (optional) 107 | * @return {Promise} Promise return the swarm 108 | */ 109 | leave (opts?: Object): Promise { 110 | const call = { 111 | path: `/swarm/leave?`, 112 | method: 'POST', 113 | options: opts, 114 | statusCodes: { 115 | 200: true, 116 | 406: 'node is not part of a swarm' 117 | } 118 | } 119 | 120 | return new Promise((resolve, reject) => { 121 | this.modem.dial(call, (err, res: string) => { 122 | if (err) return reject(err) 123 | resolve(res) 124 | }) 125 | }) 126 | } 127 | 128 | /** 129 | * Update a swarm 130 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/update-a-swarm 131 | * @param {Object} opts Query params in the request (optional) 132 | * @return {Promise} Promise return the swarm 133 | */ 134 | update (opts?: Object): Promise { 135 | const call = { 136 | path: `/swarm/update?`, 137 | method: 'POST', 138 | options: opts, 139 | statusCodes: { 140 | 200: true, 141 | 400: 'bad parameter', 142 | 406: 'node is already part of a swarm' 143 | } 144 | } 145 | 146 | return new Promise((resolve, reject) => { 147 | this.modem.dial(call, (err, res: string) => { 148 | if (err) return reject(err) 149 | resolve(res) 150 | }) 151 | }) 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /src/task.ts: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | import Modem = require('docker-modem') 4 | 5 | /** 6 | * Class representing a task 7 | */ 8 | export class Task { 9 | modem: Modem 10 | id: string 11 | data: Object = {} 12 | 13 | /** 14 | * Create a task 15 | * @param {Modem} modem Modem to connect to the remote service 16 | * @param {string} id Id of the task (optional) 17 | */ 18 | constructor (modem: Modem, id: string) { 19 | this.modem = modem 20 | this.id = id 21 | } 22 | 23 | /** 24 | * Get low-level information on a task 25 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/inspect-a-task 26 | * The reason why this module isn't called inspect is because that interferes with the inspect utility of task. 27 | * @param {Object} opts Query params in the request (optional) 28 | * @param {String} id ID of the task to inspect, if it's not set, use the id of the Object (optional) 29 | * @return {Promise} Promise return the task 30 | */ 31 | status (opts?: Object) { 32 | const call = { 33 | path: `/tasks/${this.id}?`, 34 | method: 'GET', 35 | options: opts, 36 | statusCodes: { 37 | 200: true, 38 | 404: 'no such task', 39 | 500: 'server error' 40 | } 41 | } 42 | 43 | return new Promise((resolve, reject) => { 44 | this.modem.dial(call, (err, conf) => { 45 | if (err) return reject(err) 46 | const task = new Task(this.modem, this.id) 47 | task.data = conf 48 | resolve(task) 49 | }) 50 | }) 51 | } 52 | } 53 | 54 | export default class { 55 | modem: Modem 56 | 57 | /** 58 | * Create a task 59 | * @param {Modem} modem Modem to connect to the remote service 60 | * @param {string} id Id of the task (optional) 61 | */ 62 | constructor (modem: Modem) { 63 | this.modem = modem 64 | } 65 | 66 | /** 67 | * Get a Task Object 68 | * @param {id} string ID of the secret 69 | * @return {Task} 70 | */ 71 | get (id: string): Task { 72 | return new Task(this.modem, id) 73 | } 74 | 75 | /** 76 | * Get the list of tasks 77 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/list-tasks 78 | * @param {Object} opts Query params in the request (optional) 79 | * @return {Promise} Promise returning the result as a list of tasks 80 | */ 81 | list (opts?: Object): Promise> { 82 | const call = { 83 | path: '/tasks?', 84 | method: 'GET', 85 | options: opts, 86 | statusCodes: { 87 | 200: true, 88 | 500: 'server error' 89 | } 90 | } 91 | 92 | return new Promise((resolve, reject) => { 93 | this.modem.dial(call, (err, result) => { 94 | if (err) return reject(err) 95 | if (!result || !result.length) return resolve([]) 96 | resolve(result.map((conf) => { 97 | const task = new Task(this.modem, conf.ID) 98 | task.data = conf 99 | return task 100 | })) 101 | }) 102 | }) 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/types/container.ts: -------------------------------------------------------------------------------- 1 | export interface ContainerData { 2 | Id: string; 3 | Names: string[]; 4 | Image: string; 5 | ImageID: string; 6 | Command: string; 7 | Created: number; 8 | Ports: number[]; 9 | Labels: any; 10 | State: 'running' | 'exited'; 11 | Status: string; 12 | HostConfig: any; 13 | NetworkSettings: any; 14 | Mounts: any[]; 15 | } 16 | -------------------------------------------------------------------------------- /src/volume.ts: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | import Modem = require('docker-modem') 4 | 5 | /** 6 | * Class representing a volume 7 | */ 8 | export class Volume { 9 | modem: Modem 10 | id: string 11 | data: Object = {} 12 | 13 | /** 14 | * Create a volume 15 | * @param {Modem} modem Modem to connect to the remote service 16 | * @param {string} id Id of the volume (optional) 17 | */ 18 | constructor (modem: Modem, id: string) { 19 | this.modem = modem 20 | this.id = id 21 | } 22 | 23 | /** 24 | * Get low-level information on a volume 25 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/inspect-a-volume 26 | * The reason why this module isn't called inspect is because that interferes with the inspect utility of node. 27 | * @param {Object} opts Query params in the request (optional) 28 | * @param {String} id ID of the volume to inspect, if it's not set, use the id of the Object (optional) 29 | * @return {Promise} Promise return the volume 30 | */ 31 | status (opts?: Object): Promise { 32 | const call = { 33 | path: `/volumes/${this.id}?`, 34 | method: 'GET', 35 | options: opts, 36 | statusCodes: { 37 | 200: true, 38 | 404: 'no such volume', 39 | 500: 'server error' 40 | } 41 | } 42 | 43 | return new Promise((resolve, reject) => { 44 | this.modem.dial(call, (err, conf) => { 45 | if (err) return reject(err) 46 | const volume = new Volume(this.modem, this.id) 47 | volume.data = conf 48 | resolve(volume) 49 | }) 50 | }) 51 | } 52 | 53 | /** 54 | * Remove a volume from the filesystem 55 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/remove-a-volume 56 | * @param {Object} opts Query params in the request (optional) 57 | * @param {String} id ID of the volume to inspect, if it's not set, use the id of the Object (optional) 58 | * @return {Promise} Promise return the result 59 | */ 60 | remove (opts?: Object): Promise<{}> { 61 | const call = { 62 | path: `/volumes/${this.id}?`, 63 | method: 'DELETE', 64 | options: opts, 65 | statusCodes: { 66 | 204: true, 67 | 404: 'no such volume', 68 | 409: 'conflict', 69 | 500: 'server error' 70 | } 71 | } 72 | 73 | return new Promise((resolve, reject) => { 74 | this.modem.dial(call, (err) => { 75 | if (err) return reject(err) 76 | resolve() 77 | }) 78 | }) 79 | } 80 | } 81 | 82 | export default class { 83 | modem: Modem 84 | 85 | /** 86 | * Create a volume 87 | * @param {Modem} modem Modem to connect to the remote service 88 | * @param {string} id Id of the volume (optional) 89 | */ 90 | constructor (modem: Modem) { 91 | this.modem = modem 92 | } 93 | 94 | /** 95 | * Get a Volume Object 96 | * @param {id} String ID of the secret 97 | * @return {Volume} 98 | */ 99 | get (id: string): Volume { 100 | return new Volume(this.modem, id) 101 | } 102 | 103 | /** 104 | * Get the list of volumes 105 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/list-volumes 106 | * @param {Object} opts Query params in the request (optional) 107 | * @return {Promise} Promise returning the result as a list of volumes 108 | */ 109 | list (opts?: Object): Promise> { 110 | const call = { 111 | path: '/volumes', 112 | method: 'GET', 113 | options: opts, 114 | statusCodes: { 115 | 200: true, 116 | 500: 'server error' 117 | } 118 | } 119 | 120 | return new Promise((resolve, reject) => { 121 | this.modem.dial(call, (err, result) => { 122 | if (err) return reject(err) 123 | if (!result.Volumes || !result.Volumes.length) return resolve([]) 124 | resolve(result.Volumes.map((conf) => { 125 | const volume = new Volume(this.modem, conf.Name) 126 | volume.data = conf 127 | return volume 128 | })) 129 | }) 130 | }) 131 | } 132 | 133 | /** 134 | * Create a volume 135 | * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/create-a-volume 136 | * @param {Object} opts Query params in the request (optional) 137 | * @return {Promise} Promise return the new volume 138 | */ 139 | create (opts?: Object): Promise { 140 | const call = { 141 | path: '/volumes/create?', 142 | method: 'POST', 143 | options: opts, 144 | statusCodes: { 145 | 201: true, 146 | 500: 'server error' 147 | } 148 | } 149 | 150 | return new Promise((resolve, reject) => { 151 | this.modem.dial(call, (err, conf) => { 152 | if (err) return reject(err) 153 | const volume = new Volume(this.modem, conf.Name) 154 | volume.data 155 | resolve(volume) 156 | }) 157 | }) 158 | } 159 | 160 | /** 161 | * Prune volumes 162 | * https://docs.docker.com/engine/api/v1.25/#operation/VolumePrune 163 | * @param {Object} opts Query params in the request (optional) 164 | * @return {Promise} Promise returning the container 165 | */ 166 | prune (opts?: Object): Promise { 167 | const call = { 168 | path: `/volumes/prune`, 169 | method: 'POST', 170 | options: opts, 171 | statusCodes: { 172 | 200: true, 173 | 500: 'server error' 174 | } 175 | } 176 | 177 | return new Promise((resolve, reject) => { 178 | this.modem.dial(call, (err, res: Object) => { 179 | if (err) return reject(err) 180 | resolve(res) 181 | }) 182 | }) 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | set -euo pipefail 4 | 5 | docker pull ubuntu:latest 6 | npm run lint 7 | ./node_modules/.bin/ava --timeout 30000 test 8 | -------------------------------------------------------------------------------- /test/container.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import fs from 'fs' 3 | import { Container } from '../src/container' 4 | import { Image } from '../src/image' 5 | import { Docker } from '../src/docker' 6 | 7 | const socket = process.env.DOCKER_SOCKET || '/var/run/docker.sock' 8 | const isSocket = fs.existsSync(socket) ? fs.statSync(socket).isSocket() : false 9 | const docker = isSocket 10 | ? new Docker() 11 | : new Docker({ socketPath: socket }) 12 | 13 | const createContainer = (name, extra) => 14 | docker.container.create(Object.assign({ Image: 'ubuntu', name: containerNames.get(name) }, extra)) 15 | const containerNames = new Map([ 16 | [ 'create', 'docker_api_test_create' ], 17 | [ 'inspect', 'docker_api_test_inspect' ], 18 | [ 'top', 'docker_api_test_top' ], 19 | [ 'logs', 'docker_api_test_logs' ], 20 | [ 'changes', 'docker_api_test_changes' ], 21 | [ 'export', 'docker_api_test_export' ], 22 | [ 'stats', 'docker_api_test_stats' ], 23 | [ 'resize', 'docker_api_test_resize' ], 24 | [ 'prune', 'docker_api_test_prune' ], 25 | [ 'start', 'docker_api_test_start' ], 26 | [ 'stop', 'docker_api_test_stop' ], 27 | [ 'restart', 'docker_api_test_restart' ], 28 | [ 'kill', 'docker_api_test_kill' ], 29 | [ 'update', 'docker_api_test_update' ], 30 | [ 'rename', 'docker_api_test_rename' ], 31 | [ 'rename_prev', 'docker_api_test_rename_prev' ], 32 | [ 'pause', 'docker_api_test_pause' ], 33 | [ 'attach', 'docker_api_test_attach' ], 34 | [ 'commit', 'docker_api_test_commit' ], 35 | [ 'exec', 'docker_api_test_exec' ], 36 | [ 'inspect_exec', 'docker_api_test_inspect_exec' ], 37 | [ 'get_archive', 'docker_api_test_get_archive' ], 38 | [ 'put_archive', 'docker_api_test_put_archive' ], 39 | [ 'info_archive', 'docker_api_test_info_archive' ] 40 | ]) 41 | 42 | test('list', async t => { 43 | const containers = await docker.container.list() 44 | t.is(containers.constructor, Array) 45 | }) 46 | 47 | test('should create a container', async t => { 48 | const container = await createContainer('create') 49 | t.is(container.constructor, Container) 50 | }) 51 | 52 | test('inspect', async t => { 53 | const container = await createContainer('inspect') 54 | const containerStatus = await container.status() 55 | t.is(containerStatus.constructor, Container) 56 | }) 57 | 58 | test('top', async t => { 59 | const container = await createContainer('top', { 60 | Cmd: [ '/bin/bash', '-c', 'tail -f /var/log/dmesg' ], 61 | }) 62 | await container.start() 63 | const processes = await container.top() 64 | t.is(processes.Processes.constructor, Array) 65 | }) 66 | 67 | test('log', async t => { 68 | const container = await createContainer('logs', { 69 | Cmd: [ '/bin/bash', '-c', 'tail -f /var/log/dmesg' ], 70 | }) 71 | await container.start() 72 | const logs = await container.logs({ stdout: 1, follow: true }) 73 | t.truthy(logs.pipe) 74 | }) 75 | 76 | test('changes', async t => { 77 | const container = await createContainer('changes', { 78 | Cmd: [ '/bin/bash', '-c', 'echo "xfoo" > foo.txt' ], 79 | }) 80 | await container.start() 81 | const changes = await container.changes() 82 | t.is(changes.constructor, Array) 83 | }) 84 | 85 | test('export', async t => { 86 | const container = await createContainer('export') 87 | const result = container.export({ stream: false }) 88 | t.truthy(result) 89 | }) 90 | 91 | test('stats', async t => { 92 | const container = await createContainer('stats', { 93 | Cmd: [ '/bin/bash', '-c', 'tail -f /var/log/dmesg' ], 94 | }) 95 | await container.start() 96 | const stats = await container.stats() 97 | t.truthy(stats.pipe) 98 | }) 99 | 100 | test('resize', async t => { 101 | const container = await createContainer('resize', { 102 | Cmd: [ '/bin/bash', '-c', 'tail -f /var/log/dmesg' ], 103 | }) 104 | await container.start() 105 | const result = await container.stats({ 106 | h: process.stdout.rows, 107 | w: process.stdout.columns 108 | }) 109 | t.truthy(result.pipe) 110 | }) 111 | 112 | test('prune', async t => { 113 | const container = await createContainer('prune') 114 | t.notThrows(docker.container.prune()) 115 | }) 116 | 117 | test('start', async t => { 118 | const container = await createContainer('start', { 119 | Cmd: [ '/bin/bash', '-c', 'tail -f /var/log/dmesg' ], 120 | }) 121 | const result = await container.start() 122 | t.is(result.constructor, Container) 123 | }) 124 | 125 | test('stop', async t => { 126 | const container = await createContainer('stop', { 127 | Cmd: [ '/bin/bash', '-c', 'tail -f /var/log/dmesg' ], 128 | }) 129 | await container.start() 130 | await container.stop() 131 | const containerStatus = await container.status() 132 | t.is(containerStatus.data.State.Status, 'exited') 133 | }) 134 | 135 | test('restart', async t => { 136 | const container = await createContainer('restart', { 137 | Cmd: [ '/bin/bash', '-c', 'tail -f /var/log/dmesg' ], 138 | }) 139 | await container.start() 140 | await container.restart() 141 | const containerStatus = await container.status() 142 | t.is(containerStatus.data.State.Status, 'running') 143 | }) 144 | 145 | test('kill', async t => { 146 | const container = await createContainer('kill', { 147 | Cmd: [ '/bin/bash', '-c', 'tail -f /var/log/dmesg' ], 148 | }) 149 | await container.start() 150 | await container.kill() 151 | const containerStatus = await container.status() 152 | t.is(containerStatus.data.State.Status, 'exited') 153 | }) 154 | 155 | test('update', async t => { 156 | const container = await createContainer('update', { 157 | Cmd: [ '/bin/bash', '-c', 'tail -f /var/log/dmesg' ], 158 | }) 159 | await container.update({ 'CpuShares': 512 }) 160 | const containerStatus = await container.status() 161 | t.is(containerStatus.data.HostConfig.CpuShares, 512) 162 | }) 163 | 164 | test('rename', async t => { 165 | const container = await createContainer('rename_prev', { 166 | Cmd: [ '/bin/bash', '-c', 'tail -f /var/log/dmesg' ], 167 | }) 168 | await container.rename({ 'name': containerNames.get('rename') }) 169 | const containerStatus = await container.status() 170 | t.is(containerStatus.data.Name, '/' + containerNames.get('rename')) 171 | }) 172 | 173 | test('pause', async t => { 174 | const container = await createContainer('pause', { 175 | Cmd: [ '/bin/bash', '-c', 'tail -f /var/log/dmesg' ], 176 | }) 177 | await container.start() 178 | await container.pause() 179 | const containerStatus = await container.status() 180 | t.is(containerStatus.data.State.Status, 'paused') 181 | await container.unpause() 182 | const containerStatus2 = await container.status() 183 | t.is(containerStatus2.data.State.Status, 'running') 184 | }) 185 | 186 | test('commit', async t => { 187 | const container = await createContainer('commit', { 188 | Cmd: [ '/bin/bash', '-c', 'tail -f /var/log/dmesg' ], 189 | }) 190 | await container.start() 191 | const image = await container.commit({ comment: 'commit test' }) 192 | t.is(image.constructor, Image) 193 | }) 194 | 195 | test('exec', async t => { 196 | const container = await createContainer('exec', { 197 | Cmd: [ '/bin/bash', '-c', 'tail -f /var/log/dmesg' ], 198 | }) 199 | await container.start() 200 | const exec = await container.exec.create({ 201 | Cmd: [ "top" ] 202 | }) 203 | const stream = await exec.start() 204 | t.truthy(stream.pipe) 205 | }) 206 | 207 | test('exec-status', async t => { 208 | const container = await createContainer('inspect_exec', { 209 | Cmd: [ '/bin/bash', '-c', 'tail -f /var/log/dmesg' ], 210 | }) 211 | await container.start() 212 | const exec = await container.exec.create({ 213 | Cmd: [ "top" ] 214 | }) 215 | const execStatus = await exec.status() 216 | t.is(exec.constructor, execStatus.constructor) 217 | }) 218 | 219 | test('attach', async t => { 220 | const container = await createContainer('attach', { 221 | 'AttachStdin': false, 222 | 'AttachStdout': true, 223 | 'AttachStderr': true, 224 | 'Tty': false, 225 | 'OpenStdin': false, 226 | 'StdinOnce': false, 227 | 'Env': null, 228 | 'Cmd': ['/bin/bash', '-c', 'uptime'], 229 | 'Dns': ['8.8.8.8', '8.8.4.4'], 230 | 'Image': 'ubuntu', 231 | }) 232 | const result = await container.attach({ 233 | stream: true, 234 | stdout: true, 235 | stderr: true 236 | }) 237 | const stream = result[0] 238 | t.truthy(stream) 239 | 240 | await container.start() 241 | const code = await container.wait() 242 | t.is(code.StatusCode.constructor, Number) 243 | }) 244 | 245 | test('get-archive', async t => { 246 | const container = await createContainer('get_archive', { 247 | Cmd: [ '/bin/bash', '-c', 'tail -f /var/log/dmesg' ], 248 | }) 249 | const data = await container.fs.get({ path: '/var/log/dmesg' }) 250 | t.truthy(data) 251 | }) 252 | 253 | test('put-archive', async t => { 254 | const container = await createContainer('put_archive', { 255 | Cmd: [ '/bin/bash', '-c', 'tail -f /var/log/dmesg' ], 256 | }) 257 | const data = await container.fs.put('./test/test.tar', { 258 | path: '/root' 259 | }) 260 | t.truthy(data) 261 | }) 262 | 263 | test('inspect-archive', async t => { 264 | const container = await createContainer('info_archive', { 265 | Cmd: [ '/bin/bash', '-c', 'tail -f /var/log/dmesg' ], 266 | }) 267 | const data = await container.fs.info({ path: '/var/log/dmesg' }) 268 | t.truthy(data) 269 | }) 270 | 271 | test.after.always('cleanup', async t => { 272 | const promises = Array.from(containerNames.values()).map((name) => 273 | docker.container.get(name).stop() 274 | .then((container) => { 275 | return container.delete({ force: true }) 276 | }) 277 | .catch((err) => console.log(err)) 278 | ) 279 | t.notThrows(Promise.all(promises)) 280 | }) 281 | -------------------------------------------------------------------------------- /test/docker.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import fs from 'fs' 3 | import { Docker } from '../src/docker' 4 | 5 | const socket = process.env.DOCKER_SOCKET || '/var/run/docker.sock' 6 | const isSocket = fs.existsSync(socket) ? fs.statSync(socket).isSocket() : false 7 | const docker = isSocket 8 | ? new Docker() 9 | : new Docker({ socketPath: socket }) 10 | 11 | test('ping', async t => { 12 | t.is(await docker.ping(), "OK") 13 | }) 14 | 15 | test('version', async t => { 16 | const data = await docker.version() 17 | t.truthy(data) 18 | t.is(data.Version.constructor, String) 19 | }) 20 | 21 | test('info', async t => { 22 | const data = await docker.info() 23 | t.truthy(data) 24 | t.is(data.ServerVersion.constructor, String) 25 | }) 26 | 27 | test('auth', async t => { 28 | t.throws(docker.auth({ 29 | username: "AgustinCB", 30 | password: "AgustinIsAwesome" 31 | })) 32 | }) 33 | 34 | test('events', async t => { 35 | const data = await docker.events({ 36 | since: ((new Date().getTime() / 1000) - 60).toFixed(0) 37 | }) 38 | t.truthy(data) 39 | }) 40 | -------------------------------------------------------------------------------- /test/image.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import fs from 'fs' 3 | import { Image } from '../src/image' 4 | import { Docker } from '../src/docker' 5 | 6 | const socket = process.env.DOCKER_SOCKET || '/var/run/docker.sock' 7 | const isSocket = fs.existsSync(socket) ? fs.statSync(socket).isSocket() : false 8 | const docker = isSocket 9 | ? new Docker() 10 | : new Docker({ socketPath: socket }) 11 | const testImage = 'ubuntu:latest' 12 | 13 | test('list', async t => { 14 | const images = await docker.image.list() 15 | t.is(images.constructor, Array) 16 | }) 17 | 18 | test('create', async t => { 19 | const stream = await docker.image.create({}, { fromImage: 'ubuntu' }) 20 | t.truthy(stream.pipe) 21 | }) 22 | 23 | test('status', async t => { 24 | const image = await docker.image.get(testImage).status() 25 | t.is(image.constructor, Image) 26 | }) 27 | 28 | test('history', async t => { 29 | const history = await docker.image.get(testImage).history() 30 | t.is(history.constructor, Array) 31 | }) 32 | 33 | test('tag', async t => { 34 | const image = await docker.image.get(testImage).tag({ tag: 'test', repo: 'root' }) 35 | t.is(image.constructor, Image) 36 | t.not(image.data.RepoTags.indexOf('root:test'), -1) 37 | }) 38 | 39 | test('search', async t => { 40 | const images = await docker.image.search({ term: 'ubuntu' }) 41 | t.is(images.constructor, Array) 42 | }) 43 | 44 | test('load', async t => { 45 | const stream = await docker.image.build(fs.createReadStream('./test/test.tar')) 46 | t.truthy(stream.pipe) 47 | }) 48 | 49 | test('build', async t => { 50 | const result = await docker.image.build('./test/test.tar', { t: 'test' }) 51 | .then((stream) => { 52 | t.truthy(stream.pipe) 53 | 54 | return new Promise((resolve, reject) => { 55 | const res = [] 56 | stream.on('end',() => resolve(Buffer.concat(res).toString())) 57 | stream.on('data', (d) => res.push(d)) 58 | stream.on('error', reject) 59 | }) 60 | }) 61 | const image = await docker.image.get('test').status() 62 | t.notThrows(image.remove()) 63 | }) 64 | 65 | test.after('prune', async t => { 66 | async function tryPrune(attempt = 5) { 67 | if (attempt > 0) { 68 | try { 69 | await docker.image.prune() 70 | } catch (e) { 71 | tryPrune(attempt - 1) 72 | } 73 | } else { 74 | t.truthy(await docker.image.prune()) 75 | } 76 | } 77 | await tryPrune() 78 | }) 79 | -------------------------------------------------------------------------------- /test/network.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import fs from 'fs' 3 | import { Network } from '../src/network' 4 | import { Docker } from '../src/docker' 5 | 6 | const socket = process.env.DOCKER_SOCKET || '/var/run/docker.sock' 7 | const isSocket = fs.existsSync(socket) ? fs.statSync(socket).isSocket() : false 8 | const docker = isSocket 9 | ? new Docker() 10 | : new Docker({ socketPath: socket }) 11 | 12 | test('list', async t => { 13 | const networks = await docker.network.list() 14 | t.is(networks.constructor, Array) 15 | }) 16 | 17 | test('create', async t => { 18 | const network = await docker.network.create({ 19 | "Name": "test", 20 | "Driver": "bridge", 21 | }) 22 | t.is(network.constructor, Network) 23 | t.notThrows(network.remove()) 24 | }) 25 | 26 | test('status', async t => { 27 | const network = await docker.network.create({ 28 | "Name": "test", 29 | "Driver": "bridge", 30 | }) 31 | t.is(network.constructor, Network) 32 | const networkStatus = await network.status() 33 | t.is(networkStatus.constructor, Network) 34 | t.notThrows(network.remove()) 35 | }) 36 | 37 | test.after('prune', async t => { 38 | async function tryPrune(attempt = 5) { 39 | if (attempt > 0) { 40 | try { 41 | await docker.network.prune() 42 | } catch (e) { 43 | tryPrune(attempt - 1) 44 | } 45 | } else { 46 | t.truthy(await docker.network.prune()) 47 | } 48 | } 49 | await tryPrune() 50 | }) 51 | -------------------------------------------------------------------------------- /test/swarm.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import fs from 'fs' 3 | import { Node } from '../src/node' 4 | import { Secret } from '../src/secret' 5 | import { Service } from '../src/service' 6 | import Swarm from '../src/swarm' 7 | import { Docker } from '../src/docker' 8 | 9 | const socket = process.env.DOCKER_SOCKET || '/var/run/docker.sock' 10 | const isSocket = fs.existsSync(socket) ? fs.statSync(socket).isSocket() : false 11 | const docker = isSocket 12 | ? new Docker() 13 | : new Docker({ socketPath: socket }) 14 | 15 | const createService = _ => 16 | docker.service.create({ 17 | "Name": "redis-" + Date.now(), 18 | "TaskTemplate": { 19 | "ContainerSpec": { 20 | "Image": "redis" 21 | }, 22 | "Resources": { 23 | "Limits": {}, 24 | "Reservations": {} 25 | }, 26 | "RestartPolicy": {}, 27 | "Placement": {} 28 | }, 29 | "Mode": { 30 | "Replicated": { 31 | "Replicas": 1 32 | } 33 | }, 34 | "UpdateConfig": { 35 | "Parallelism": 1 36 | }, 37 | "EndpointSpec": { 38 | "ExposedPorts": [{ 39 | "Protocol": "tcp", 40 | "Port": 6379 41 | }] 42 | } 43 | }) 44 | 45 | test.before(async t => { 46 | const node = await docker.swarm.init({ 47 | "ListenAddr": "127.0.0.1:4500", 48 | "AdvertiseAddr": "127.0.0.1:4500", 49 | "ForceNewCluster": true, 50 | "Spec": { 51 | "AcceptancePolicy": { 52 | "Policies": [{ 53 | "Role": "MANAGER", 54 | "Autoaccept": false 55 | }, { 56 | "Role": "WORKER", 57 | "Autoaccept": true 58 | }] 59 | }, 60 | "Orchestration": {}, 61 | "Raft": {}, 62 | "Dispatcher": {}, 63 | "CAConfig": {} 64 | } 65 | }) 66 | t.is(node.constructor, Node) 67 | }) 68 | 69 | test.after('cleanup', t => { 70 | docker.swarm.leave({ 'force': true }) 71 | }) 72 | 73 | test('inspect', async t => { 74 | const swarm = await docker.swarm.status() 75 | t.is(swarm.constructor, Swarm) 76 | }) 77 | 78 | test('create-service', async t => { 79 | const service = await createService() 80 | t.is(service.constructor, Service) 81 | }) 82 | 83 | test('list-services', async t => { 84 | const service = await createService() 85 | const services = await docker.service.list() 86 | t.is(services.constructor, Array) 87 | t.not(services.length, 0) 88 | }) 89 | 90 | test('inspect-service', async t => { 91 | const service = await (await createService()).status() 92 | t.is(service.constructor, Service) 93 | }) 94 | 95 | test('update-service', async t => { 96 | const service = await (await createService()).status() 97 | const data = service.data.Spec 98 | data.version = service.data.Version.Index 99 | const res = await service.update(data) 100 | t.is(res.constructor, Service) 101 | }) 102 | 103 | test('delete-service', async t => { 104 | const service = await (await createService()).status() 105 | t.notThrows(service.remove()) 106 | }) 107 | 108 | test('logs-service', async t => { 109 | const res = await (await createService()).logs({stdout: true}) 110 | t.truthy(res.pipe) 111 | }) 112 | 113 | 114 | test('list-tasks', async t => { 115 | const tasks = await docker.task.list() 116 | t.is(tasks.constructor, Array) 117 | }) 118 | 119 | test('list-nodes', async t => { 120 | const nodes = await docker.node.list() 121 | t.is(nodes.constructor, Array) 122 | t.is(nodes[0].constructor, Node) 123 | }) 124 | 125 | test('inspect-node', async t => { 126 | const nodes = await docker.node.list() 127 | const node = await nodes[0].status() 128 | t.is(node.constructor, Node) 129 | }) 130 | 131 | test('remove-node', async t => { 132 | const nodes = await docker.node.list() 133 | const node = await nodes[0].status() 134 | t.throws(node.remove()) 135 | }) 136 | 137 | test('list-secret', async t => { 138 | const secrets = await docker.secret.list() 139 | t.is(secrets.constructor, Array) 140 | }) 141 | 142 | test('create-secret', async t => { 143 | const secret = await docker.secret.create({ 144 | "Name": "app-key.crt", 145 | "Labels": { 146 | "foo": "bar" 147 | }, 148 | "Data": "VEhJUyBJUyBOT1QgQSBSRUFMIENFUlRJRklDQVRFCg==" 149 | }) 150 | 151 | t.is(secret.constructor, Secret) 152 | t.notThrows(secret.remove()) 153 | }) 154 | 155 | test('status-secret', async t => { 156 | const secret = await docker.secret.create({ 157 | "Name": "app-key1.crt", 158 | "Data": "VEhJUyBJUyBOT1QgQSBSRUFMIENFUlRJRklDQVRFCg==" 159 | }) 160 | const secretStatus = await secret.status() 161 | 162 | t.is(secretStatus.constructor, Secret) 163 | t.notThrows(secret.remove()) 164 | }) 165 | -------------------------------------------------------------------------------- /test/test-load.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgustinCB/docker-api/2098bd424e71ccdde8f379edac6acc2b47b317b2/test/test-load.tar -------------------------------------------------------------------------------- /test/test.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgustinCB/docker-api/2098bd424e71ccdde8f379edac6acc2b47b317b2/test/test.tar -------------------------------------------------------------------------------- /test/volume.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import fs from 'fs' 3 | import { Docker } from '../src/docker' 4 | import { Volume } from '../src/volume' 5 | 6 | const socket = process.env.DOCKER_SOCKET || '/var/run/docker.sock' 7 | const isSocket = fs.existsSync(socket) ? fs.statSync(socket).isSocket() : false 8 | const docker = isSocket 9 | ? new Docker() 10 | : new Docker({ socketPath: socket }) 11 | 12 | test('list', async t => { 13 | const volumes = await docker.volume.list() 14 | t.is(volumes.constructor, Array) 15 | }) 16 | 17 | test('create', async t => { 18 | const volume = await docker.volume.create({ 19 | "Name": "tardis1", 20 | "Labels": { 21 | "com.example.some-label": "some-value", 22 | "com.example.some-other-label": "some-other-value" 23 | }, 24 | "Driver": "local" 25 | }) 26 | 27 | t.is(volume.constructor, Volume) 28 | t.notThrows(volume.remove()) 29 | }) 30 | 31 | test('status', async t => { 32 | const volume = await docker.volume.create({ 33 | "Name": "tardis2", 34 | "Labels": { 35 | "com.example.some-label": "some-value", 36 | "com.example.some-other-label": "some-other-value" 37 | }, 38 | "Driver": "local" 39 | }) 40 | const volumeStatus = await volume.status() 41 | t.is(volumeStatus.constructor, Volume) 42 | t.notThrows(volume.remove()) 43 | }) 44 | 45 | test.after('prune', async t => { 46 | t.truthy(await docker.volume.prune()) 47 | }) 48 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true, 6 | "declaration": true, 7 | "types": ["node"], 8 | "removeComments": false 9 | }, 10 | "include": ["src/**/*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "jsRules": { 3 | "class-name": true, 4 | "comment-format": [ 5 | true, 6 | "check-space" 7 | ], 8 | "indent": [ 9 | true, 10 | "spaces" 11 | ], 12 | "no-duplicate-variable": true, 13 | "no-eval": true, 14 | "no-trailing-whitespace": true, 15 | "no-unsafe-finally": true, 16 | "one-line": [ 17 | true, 18 | "check-open-brace", 19 | "check-whitespace" 20 | ], 21 | "quotemark": [ 22 | true, 23 | "single" 24 | ], 25 | "semicolon": [ 26 | true, 27 | "never" 28 | ], 29 | "triple-equals": [ 30 | true, 31 | "allow-null-check" 32 | ], 33 | "variable-name": [ 34 | true, 35 | "ban-keywords" 36 | ], 37 | "whitespace": [ 38 | true, 39 | "check-branch", 40 | "check-decl", 41 | "check-operator", 42 | "check-separator", 43 | "check-type" 44 | ] 45 | }, 46 | "rules": { 47 | "class-name": true, 48 | "comment-format": [ 49 | true, 50 | "check-space" 51 | ], 52 | "indent": [ 53 | true, 54 | "tab" 55 | ], 56 | "no-eval": true, 57 | "no-internal-module": true, 58 | "no-trailing-whitespace": true, 59 | "no-unsafe-finally": true, 60 | "no-var-keyword": true, 61 | "one-line": [ 62 | true, 63 | "check-open-brace", 64 | "check-whitespace" 65 | ], 66 | "quotemark": [ 67 | true, 68 | "single" 69 | ], 70 | "semicolon": [ 71 | true, 72 | "never" 73 | ], 74 | "triple-equals": [ 75 | true, 76 | "allow-null-check" 77 | ], 78 | "typedef-whitespace": [ 79 | true, 80 | { 81 | "call-signature": "nospace", 82 | "index-signature": "nospace", 83 | "parameter": "nospace", 84 | "property-declaration": "nospace", 85 | "variable-declaration": "nospace" 86 | } 87 | ], 88 | "variable-name": [ 89 | true, 90 | "ban-keywords" 91 | ], 92 | "whitespace": [ 93 | true, 94 | "check-branch", 95 | "check-decl", 96 | "check-operator", 97 | "check-separator", 98 | "check-type" 99 | ] 100 | } 101 | } 102 | --------------------------------------------------------------------------------