presidium 0.16.8 → 0.16.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc.js CHANGED
@@ -52,7 +52,7 @@ module.exports = {
52
52
  'error',
53
53
  'last'
54
54
  ],
55
- 'complexity': ['error', 33],
55
+ 'complexity': ['error', 35],
56
56
  'computed-property-spacing': [
57
57
  'error',
58
58
  'never'
package/Docker.js CHANGED
@@ -995,6 +995,9 @@ const has = property => value => {
995
995
  * email?: string,
996
996
  * serveraddress?: string,
997
997
  * identitytoken?: string,
998
+ *
999
+ * // user-defined metadata
1000
+ * labels: object,
998
1001
  * }) -> Promise<HttpResponse>
999
1002
  * ```
1000
1003
  */
@@ -1010,6 +1013,7 @@ Docker.prototype.updateService = function dockerUpdateService(service, options)
1010
1013
 
1011
1014
  body: stringifyJSON(defaultsDeep(get('spec', {})(options))({
1012
1015
  Name: service,
1016
+ Labels: options.labels ?? {},
1013
1017
  TaskTemplate: {
1014
1018
  ContainerSpec: {
1015
1019
  ...options.image && { Image: options.image },
@@ -1116,6 +1120,14 @@ Docker.prototype.updateService = function dockerUpdateService(service, options)
1116
1120
  },
1117
1121
  },
1118
1122
 
1123
+ ...options.network && {
1124
+ Networks: [{
1125
+ Target: options.network,
1126
+ Aliases: [],
1127
+ DriverOpts: {},
1128
+ }],
1129
+ },
1130
+
1119
1131
  ...options.publish && {
1120
1132
  EndpointSpec: {
1121
1133
  Ports: Object.entries(options.publish).map(pipe([
@@ -1317,7 +1329,6 @@ Docker.prototype.createNetwork = function createNetwork(options) {
1317
1329
  Name: options.name,
1318
1330
  Driver: options.driver,
1319
1331
  CheckDuplicate: true,
1320
- Attachable: true,
1321
1332
  })),
1322
1333
  })
1323
1334
  }
package/DockerService.js CHANGED
@@ -193,12 +193,20 @@ DockerService.prototype.update = async function update(options) {
193
193
  ...options,
194
194
  spec: this.spec,
195
195
  version: this.version,
196
- }).then(response => {
197
- this.ready = this.synchronize()
196
+ }).then(async response => {
197
+ await this.synchronize()
198
198
  return response.json()
199
199
  })
200
200
  }
201
201
 
202
+ /**
203
+ * @name DockerService.prototype.inspect
204
+ *
205
+ * @synopsis
206
+ * ```coffeescript [specscript]
207
+ * new DockerService(...).inspect() -> Promise<{}>
208
+ * ```
209
+ */
202
210
  DockerService.prototype.inspect = async function inspect() {
203
211
  await this.ready
204
212
  return this.docker.inspectService(this.name)
@@ -6,117 +6,129 @@ const DockerService = require('./DockerService')
6
6
  const inspect = require('util').inspect
7
7
  const always = require('rubico/always')
8
8
 
9
- module.exports = Test('DockerService', DockerService)
10
- .before(async function () {
11
- this.docker = new Docker()
12
- await this.docker.leaveSwarm({ force: true })
13
- await this.docker.pruneContainers()
14
- await this.docker.pruneImages()
15
- await this.docker.initSwarm('[::1]:2377')
16
- })
17
- .case({
18
- name: 'my-service',
19
- image: 'nginx:1.19',
20
- replicas: 1,
21
- }, async function (myService) {
22
- {
23
- const info = await myService.inspect()
24
- this.serviceId = info.ID
25
- assert.equal(info.ID, this.serviceId)
26
- assert.equal(info.Spec.UpdateConfig.Parallelism, 2) // defaults
27
- assert.equal(info.Spec.UpdateConfig.Delay, 1e9)
28
- assert.equal(info.Spec.UpdateConfig.FailureAction, 'pause')
29
- assert.equal(info.Spec.UpdateConfig.Monitor, 15e9)
30
- assert.equal(info.Spec.UpdateConfig.MaxFailureRatio, 0.15)
31
- assert.equal(info.Spec.RollbackConfig.Parallelism, 1)
32
- assert.equal(info.Spec.RollbackConfig.Delay, 1e9)
33
- assert.equal(info.Spec.RollbackConfig.FailureAction, 'pause')
34
- assert.equal(info.Spec.RollbackConfig.Monitor, 15e9)
35
- assert.equal(info.Spec.RollbackConfig.MaxFailureRatio, 0.15)
36
- }
9
+ const test = new Test('DockerService', DockerService)
37
10
 
38
- {
39
- const result = await myService.update({
40
- replicas: 2,
41
- updateParallelism: 3,
42
- updateDelay: 2e9,
43
- updateFailureAction: 'continue',
44
- updateMonitor: 30e9,
45
- updateMaxFailureRatio: 0.3,
46
- rollbackParallelism: 3,
47
- rollbackDelay: 2e9,
48
- rollbackFailureAction: 'continue',
49
- rollbackMonitor: 30e9,
50
- rollbackMaxFailureRatio: 0.3,
51
- env: { FOO: 'foo' },
52
- workdir: '/opt',
53
- mounts: [{
54
- source: 'other-volume',
55
- target: '/opt/other-volume',
56
- }],
57
- publish: { 8080: 80 },
58
- healthCmd: ['curl', '0.0.0.0:80'],
59
- restart: 'on-failure:5',
60
- memory: 512e6, // bytes
61
- })
62
- }
11
+ .before(async function () {
12
+ this.docker = new Docker()
13
+ await this.docker.leaveSwarm({ force: true })
14
+ await this.docker.pruneContainers()
15
+ await this.docker.pruneImages()
16
+ await this.docker.initSwarm('[::1]:2377')
17
+ })
63
18
 
64
- {
65
- const info = await myService.inspect()
66
- assert.equal(info.ID, this.serviceId)
67
- assert.equal(info.Spec.UpdateConfig.Parallelism, 3)
68
- assert.equal(info.Spec.UpdateConfig.Delay, 2e9)
69
- assert.equal(info.Spec.UpdateConfig.FailureAction, 'continue')
70
- assert.equal(info.Spec.UpdateConfig.Monitor, 30e9)
71
- assert.equal(info.Spec.UpdateConfig.MaxFailureRatio, 0.3)
72
- assert.equal(info.Spec.RollbackConfig.Parallelism, 3)
73
- assert.equal(info.Spec.RollbackConfig.Delay, 2e9)
74
- assert.equal(info.Spec.RollbackConfig.FailureAction, 'continue')
75
- assert.equal(info.Spec.RollbackConfig.Monitor, 30e9)
76
- assert.equal(info.Spec.RollbackConfig.MaxFailureRatio, 0.3)
77
- assert.equal(info.Spec.Mode.Replicated.Replicas, 2)
78
- assert.equal(info.Spec.TaskTemplate.ContainerSpec.Env.length, 1)
79
- assert.equal(info.Spec.TaskTemplate.ContainerSpec.Env[0], 'FOO=foo')
80
- assert.equal(info.Spec.TaskTemplate.ContainerSpec.Dir, '/opt')
81
- assert.deepEqual(
82
- info.Spec.TaskTemplate.ContainerSpec.Healthcheck.Test,
83
- ['CMD', 'curl', '0.0.0.0:80'])
84
- assert.deepEqual(
85
- info.Spec.TaskTemplate.ContainerSpec.Mounts,
86
- [{ Type: 'volume', Source: 'other-volume', Target: '/opt/other-volume' }])
87
- assert.equal(info.Spec.TaskTemplate.RestartPolicy.Condition, 'on-failure')
88
- assert.equal(info.Spec.TaskTemplate.RestartPolicy.MaxAttempts, 5)
89
- assert.equal(info.Spec.TaskTemplate.Resources.Limits.MemoryBytes, 512e6)
90
- this.myServiceSpec = myService.spec
91
- }
19
+ .case({
20
+ name: 'my-service',
21
+ image: 'nginx:1.19',
22
+ replicas: 1,
23
+ }, async function (myService) {
24
+ {
25
+ const info = await myService.inspect()
26
+ this.serviceId = info.ID
27
+ assert.equal(info.ID, this.serviceId)
28
+ assert.equal(info.Spec.UpdateConfig.Parallelism, 2) // defaults
29
+ assert.equal(info.Spec.UpdateConfig.Delay, 1e9)
30
+ assert.equal(info.Spec.UpdateConfig.FailureAction, 'pause')
31
+ assert.equal(info.Spec.UpdateConfig.Monitor, 15e9)
32
+ assert.equal(info.Spec.UpdateConfig.MaxFailureRatio, 0.15)
33
+ assert.equal(info.Spec.RollbackConfig.Parallelism, 1)
34
+ assert.equal(info.Spec.RollbackConfig.Delay, 1e9)
35
+ assert.equal(info.Spec.RollbackConfig.FailureAction, 'pause')
36
+ assert.equal(info.Spec.RollbackConfig.Monitor, 15e9)
37
+ assert.equal(info.Spec.RollbackConfig.MaxFailureRatio, 0.15)
38
+ }
92
39
 
93
- {
94
- const logResponseStream = await myService.getLogs({ stdout: true, stderr: true })
95
- logResponseStream.pipe(process.stdout)
96
- await new Promise(resolve => logResponseStream.on('end', resolve))
97
- }
98
- })
99
- .case({
100
- name: 'my-service',
101
- image: 'nginx:1.19',
102
- replicas: 2,
103
- }, async function (myService) {
104
- await myService.ready
105
- // TODO test for update on construction
106
- assert.deepEqual(myService.spec, this.myServiceSpec)
107
- })
108
- .case({
109
- name: 'bad-request',
110
- image: 'nginx:1.19',
111
- replicas: 2,
112
- restart: 'always', // coulda fooled me
113
- }, async function (errorService) {
114
- assert.rejects(
115
- always(errorService.ready),
116
- new Error('{"message":"invalid RestartCondition: \\"always\\""}\n'))
117
- })
118
- .after(async function () {
119
- await this.docker.pruneContainers()
120
- await this.docker.pruneImages()
121
- await this.docker.leaveSwarm({ force: true })
122
- })
40
+ {
41
+ const result = await myService.update({
42
+ labels: { foo: 'bar' },
43
+ replicas: 2,
44
+ updateParallelism: 3,
45
+ updateDelay: 2e9,
46
+ updateFailureAction: 'continue',
47
+ updateMonitor: 30e9,
48
+ updateMaxFailureRatio: 0.3,
49
+ rollbackParallelism: 3,
50
+ rollbackDelay: 2e9,
51
+ rollbackFailureAction: 'continue',
52
+ rollbackMonitor: 30e9,
53
+ rollbackMaxFailureRatio: 0.3,
54
+ env: { FOO: 'foo' },
55
+ workdir: '/opt',
56
+ mounts: [{
57
+ source: 'other-volume',
58
+ target: '/opt/other-volume',
59
+ }],
60
+ publish: { 8080: 80 },
61
+ healthCmd: ['curl', '0.0.0.0:80'],
62
+ restart: 'on-failure:5',
63
+ memory: 512e6, // bytes
64
+ })
65
+ }
66
+
67
+ {
68
+ const info = await myService.inspect()
69
+ assert.equal(info.ID, this.serviceId)
70
+ // assert.equal(info.Spec.Labels.foo, 'bar')
71
+ assert.equal(info.Spec.UpdateConfig.Parallelism, 3)
72
+ assert.equal(info.Spec.UpdateConfig.Delay, 2e9)
73
+ assert.equal(info.Spec.UpdateConfig.FailureAction, 'continue')
74
+ assert.equal(info.Spec.UpdateConfig.Monitor, 30e9)
75
+ assert.equal(info.Spec.UpdateConfig.MaxFailureRatio, 0.3)
76
+ assert.equal(info.Spec.RollbackConfig.Parallelism, 3)
77
+ assert.equal(info.Spec.RollbackConfig.Delay, 2e9)
78
+ assert.equal(info.Spec.RollbackConfig.FailureAction, 'continue')
79
+ assert.equal(info.Spec.RollbackConfig.Monitor, 30e9)
80
+ assert.equal(info.Spec.RollbackConfig.MaxFailureRatio, 0.3)
81
+ assert.equal(info.Spec.Mode.Replicated.Replicas, 2)
82
+ assert.equal(info.Spec.TaskTemplate.ContainerSpec.Env.length, 1)
83
+ assert.equal(info.Spec.TaskTemplate.ContainerSpec.Env[0], 'FOO=foo')
84
+ assert.equal(info.Spec.TaskTemplate.ContainerSpec.Dir, '/opt')
85
+ assert.deepEqual(
86
+ info.Spec.TaskTemplate.ContainerSpec.Healthcheck.Test,
87
+ ['CMD', 'curl', '0.0.0.0:80'])
88
+ assert.deepEqual(
89
+ info.Spec.TaskTemplate.ContainerSpec.Mounts,
90
+ [{ Type: 'volume', Source: 'other-volume', Target: '/opt/other-volume' }])
91
+ assert.equal(info.Spec.TaskTemplate.RestartPolicy.Condition, 'on-failure')
92
+ assert.equal(info.Spec.TaskTemplate.RestartPolicy.MaxAttempts, 5)
93
+ assert.equal(info.Spec.TaskTemplate.Resources.Limits.MemoryBytes, 512e6)
94
+ this.myServiceSpec = myService.spec
95
+ }
96
+
97
+ {
98
+ const logResponseStream = await myService.getLogs({ stdout: true, stderr: true })
99
+ logResponseStream.pipe(process.stdout)
100
+ await new Promise(resolve => logResponseStream.on('end', resolve))
101
+ }
102
+ })
103
+
104
+ .case({
105
+ name: 'my-service',
106
+ image: 'nginx:1.19',
107
+ replicas: 2,
108
+ }, async function (myService) {
109
+ await myService.ready
110
+ // TODO test for update on construction assert.deepEqual(myService.spec, this.myServiceSpec)
111
+ })
112
+
113
+ .case({
114
+ name: 'bad-request',
115
+ image: 'nginx:1.19',
116
+ replicas: 2,
117
+ restart: 'always', // coulda fooled me
118
+ }, async function (errorService) {
119
+ assert.rejects(
120
+ always(errorService.ready),
121
+ new Error('{"message":"invalid RestartCondition: \\"always\\""}\n'))
122
+ })
123
+
124
+ .after(async function () {
125
+ await this.docker.pruneContainers()
126
+ await this.docker.pruneImages()
127
+ await this.docker.leaveSwarm({ force: true })
128
+ })
129
+
130
+ if (process.argv[1] == __filename) {
131
+ test()
132
+ }
133
+
134
+ module.exports = test
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "presidium",
3
- "version": "0.16.8",
3
+ "version": "0.16.9",
4
4
  "description": "A library for creating web services",
5
5
  "author": "Richard Tong",
6
6
  "license": "MIT",