@toa.io/operations 1.0.0-alpha.34 → 1.0.0-alpha.340

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.
Files changed (78) hide show
  1. package/CHANGELOG.md +449 -0
  2. package/image/runtime.Dockerfile +20 -0
  3. package/package.json +10 -10
  4. package/readme.md +224 -0
  5. package/src/deployment/.deployment/.describe/components.js +1 -5
  6. package/src/deployment/.deployment/.describe/compositions.js +26 -7
  7. package/src/deployment/.deployment/.describe/dependencies.js +1 -6
  8. package/src/deployment/.deployment/.describe/events.js +63 -0
  9. package/src/deployment/.deployment/.describe/fold.js +42 -0
  10. package/src/deployment/.deployment/.describe/fold.test.js +108 -0
  11. package/src/deployment/.deployment/.describe/index.js +4 -13
  12. package/src/deployment/.deployment/.describe/mounts.js +17 -0
  13. package/src/deployment/.deployment/.describe/resources.js +129 -0
  14. package/src/deployment/.deployment/.describe/resources.test.js +129 -0
  15. package/src/deployment/.deployment/.describe/services.js +32 -6
  16. package/src/deployment/.deployment/.describe/services.test.js +78 -0
  17. package/src/deployment/.deployment/.describe/variables.js +5 -9
  18. package/src/deployment/.deployment/declare.js +1 -5
  19. package/src/deployment/.deployment/describe.js +168 -10
  20. package/src/deployment/.deployment/index.js +3 -9
  21. package/src/deployment/.deployment/merge.js +66 -6
  22. package/src/deployment/.deployment/merge.test.js +133 -0
  23. package/src/deployment/chart/templates/components.configmap.yaml +13 -0
  24. package/src/deployment/chart/templates/components.yaml +4 -3
  25. package/src/deployment/chart/templates/compositions.yaml +109 -4
  26. package/src/deployment/chart/templates/mono.yaml +199 -0
  27. package/src/deployment/chart/templates/services.yaml +97 -7
  28. package/src/deployment/chart/values.yaml +23 -1
  29. package/src/deployment/composition.js +8 -6
  30. package/src/deployment/deployment.js +175 -35
  31. package/src/deployment/drain.js +70 -0
  32. package/src/deployment/drain.test.js +64 -0
  33. package/src/deployment/factory.js +178 -37
  34. package/src/deployment/images/bundle.js +93 -0
  35. package/src/deployment/images/composition.Dockerfile +9 -17
  36. package/src/deployment/images/composition.js +9 -56
  37. package/src/deployment/images/dependencies.Dockerfile +23 -0
  38. package/src/deployment/images/dependencies.js +171 -0
  39. package/src/deployment/images/dependencies.test.js +271 -0
  40. package/src/deployment/images/factory.js +31 -15
  41. package/src/deployment/images/format.js +66 -0
  42. package/src/deployment/images/format.test.js +150 -0
  43. package/src/deployment/images/image.fixtures.js +17 -19
  44. package/src/deployment/images/image.js +79 -38
  45. package/src/deployment/images/image.test.js +11 -5
  46. package/src/deployment/images/index.js +1 -5
  47. package/src/deployment/images/mono.Dockerfile +11 -0
  48. package/src/deployment/images/mono.js +15 -0
  49. package/src/deployment/images/publish.js +91 -0
  50. package/src/deployment/images/runtime-base.test.js +97 -0
  51. package/src/deployment/images/service.Dockerfile +17 -5
  52. package/src/deployment/images/service.js +63 -14
  53. package/src/deployment/index.js +1 -5
  54. package/src/deployment/operator.js +25 -16
  55. package/src/deployment/operator.test.js +98 -7
  56. package/src/deployment/registry.js +210 -46
  57. package/src/deployment/registry.test.js +539 -0
  58. package/src/deployment/secrets.js +92 -0
  59. package/src/deployment/secrets.test.js +180 -0
  60. package/src/deployment/service.js +4 -6
  61. package/src/deployment/workspace.js +13 -8
  62. package/src/index.js +3 -2
  63. package/src/process.js +51 -13
  64. package/src/process.test.js +33 -0
  65. package/types/_deployment/composition.d.ts +2 -3
  66. package/types/_deployment/dependency.d.ts +15 -7
  67. package/types/_deployment/deployment.d.ts +10 -8
  68. package/types/_deployment/factory.d.ts +2 -4
  69. package/types/_deployment/images/factory.d.ts +6 -8
  70. package/types/_deployment/images/image.d.ts +16 -1
  71. package/types/_deployment/images/registry.d.ts +8 -11
  72. package/types/_deployment/operator.d.ts +10 -9
  73. package/types/_deployment/registry.d.ts +7 -4
  74. package/types/_deployment/service.d.ts +4 -3
  75. package/types/dependency.ts +79 -0
  76. package/types/index.ts +1 -0
  77. package/types/dependency.d.ts +0 -39
  78. package/types/index.d.ts +0 -1
@@ -0,0 +1,133 @@
1
+ import { describe, it } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+
4
+ import { merge } from './merge.js'
5
+
6
+ // a service is named the way it is deployed by the time it reaches `merge`
7
+ const service = (name, extra = {}) => ({
8
+ group: 'group',
9
+ name: `group-${name}`,
10
+ version: '0',
11
+ ...extra
12
+ })
13
+
14
+ it('should merge services of all dependencies', () => {
15
+ const merged = merge([
16
+ { services: [service('one', { port: 8000 })] },
17
+ { services: [service('two', { port: 8001 })] }
18
+ ])
19
+
20
+ assert.strictEqual(merged.services.length, 2)
21
+ })
22
+
23
+ /*
24
+ * A workload that hosts services puts them in one process, so a port is claimed once
25
+ * within one. Services in separate pods share nothing.
26
+ */
27
+ describe('port reservation', () => {
28
+ const hosted = (name, extra = {}) => service(name, { workload: ['mono'], ...extra })
29
+
30
+ it('should reject two services of one workload claiming one port', () => {
31
+ const dependencies = [
32
+ { services: [hosted('one', { port: 8000 })] },
33
+ { services: [hosted('two', { port: 8000 })] }
34
+ ]
35
+
36
+ assert.throws(
37
+ () => merge(dependencies),
38
+ (error) =>
39
+ /Port 8000 is claimed by both 'group-one' and 'group-two' in 'mono'/.test(
40
+ error.message
41
+ )
42
+ )
43
+ })
44
+
45
+ it('should allow two workloads to claim one port', () => {
46
+ const dependencies = [
47
+ { services: [service('one', { port: 8000, workload: ['edge'] })] },
48
+ { services: [service('two', { port: 8000, workload: ['inner'] })] }
49
+ ]
50
+
51
+ assert.doesNotThrow(() => merge(dependencies))
52
+ })
53
+
54
+ it('should reserve the ports of a service in every workload running it', () => {
55
+ const dependencies = [
56
+ { services: [service('one', { port: 8000, workload: ['edge', 'inner'] })] },
57
+ { services: [service('two', { port: 8000, workload: ['inner'] })] }
58
+ ]
59
+
60
+ assert.throws(
61
+ () => merge(dependencies),
62
+ (error) =>
63
+ /Port 8000 is claimed by both 'group-one' and 'group-two' in 'inner'/.test(
64
+ error.message
65
+ )
66
+ )
67
+ })
68
+
69
+ it('should allow two services deployed on their own to claim one port', () => {
70
+ const dependencies = [
71
+ { services: [service('one', { port: 8000 })] },
72
+ { services: [service('two', { port: 8000 })] }
73
+ ]
74
+
75
+ assert.doesNotThrow(() => merge(dependencies))
76
+ })
77
+
78
+ it('should reject a service claiming the port of the readiness probe', () => {
79
+ const dependencies = [
80
+ { probe: { path: '/.ready', port: 8001 } },
81
+ { services: [service('one', { port: 8001 })] }
82
+ ]
83
+
84
+ assert.throws(
85
+ () => merge(dependencies),
86
+ (error) =>
87
+ /Port 8001 is claimed by both the readiness probe and 'group-one'/.test(
88
+ error.message
89
+ )
90
+ )
91
+ })
92
+
93
+ it('should reject a probe claiming the port of another service of the workload', () => {
94
+ const dependencies = [
95
+ { services: [hosted('one', { port: 8000 })] },
96
+ {
97
+ services: [hosted('two', { port: 8002, probe: { path: '/.ready', port: 8000 } })]
98
+ }
99
+ ]
100
+
101
+ assert.throws(
102
+ () => merge(dependencies),
103
+ (error) =>
104
+ /Port 8000 is claimed by both 'group-one' and the readiness probe of 'group-two' in 'mono'/.test(
105
+ error.message
106
+ )
107
+ )
108
+ })
109
+
110
+ it('should allow a service to probe its own port', () => {
111
+ const dependencies = [
112
+ {
113
+ services: [service('one', { port: 8000, probe: { path: '/.ready', port: 8000 } })]
114
+ }
115
+ ]
116
+
117
+ assert.doesNotThrow(() => merge(dependencies))
118
+ })
119
+
120
+ it('should ignore services without a port', () => {
121
+ const dependencies = [{ services: [service('one'), service('two')] }]
122
+
123
+ assert.doesNotThrow(() => merge(dependencies))
124
+ })
125
+
126
+ it('should ignore a disabled probe', () => {
127
+ const dependencies = [
128
+ { probe: false, services: [service('one', { port: 8000, probe: false })] }
129
+ ]
130
+
131
+ assert.doesNotThrow(() => merge(dependencies))
132
+ })
133
+ })
@@ -0,0 +1,13 @@
1
+ {{- if .Values.map }}
2
+ # What every component of the context provides, by the version this deployment runs of it.
3
+ # Mounted rather than rendered into a workload's environment: a variable would replace every pod
4
+ # of the context on every deployment, and a pod that came up between two of them could not be
5
+ # told. Carried gzipped, because what is read here is read by a program and a ConfigMap is capped
6
+ # at a megabyte: `kubectl exec <pod> -- zcat {{ .Values.map.directory }}/{{ .Values.map.file }}`.
7
+ apiVersion: v1
8
+ kind: ConfigMap
9
+ metadata:
10
+ name: components
11
+ binaryData:
12
+ {{ .Values.map.file }}: {{ .Values.map.gzip | quote }}
13
+ {{- end }}
@@ -6,11 +6,12 @@ metadata:
6
6
  spec:
7
7
  type: ClusterIP
8
8
  selector:
9
- {{ . }}: "1"
9
+ toa/component-{{ . }}: "1"
10
10
  ports:
11
+ # what a streamed call is dialled at; see documentation/ports.md
11
12
  - name: http-binding
12
13
  protocol: TCP
13
- port: 3000
14
- targetPort: 3000
14
+ port: 8005
15
+ targetPort: 8005
15
16
  ---
16
17
  {{- end }}
@@ -5,29 +5,134 @@ metadata:
5
5
  name: composition-{{ required "composition name is required" .name }}
6
6
  spec:
7
7
  replicas: {{ .replicas | default 2 }}
8
+ # A backstop for stuck rollouts only. Must stay above the `helm upgrade --timeout`
9
+ # the deploy runs with, so a slow but progressing rollout is not marked failed.
10
+ progressDeadlineSeconds: 900
11
+ strategy:
12
+ type: RollingUpdate
13
+ rollingUpdate:
14
+ # a replacement must pass readiness before a running replica is taken out, and every
15
+ # replacement starts at once: the rollout takes one start-up, not one per replica
16
+ maxUnavailable: 0
17
+ maxSurge: 100%
8
18
  selector:
9
19
  matchLabels:
10
- toa.io/composition: {{ .name }}
20
+ toa/composition: {{ .name }}
11
21
  template:
12
22
  metadata:
13
23
  labels:
14
- toa.io/composition: {{ .name }}
24
+ toa/composition: {{ .name }}
15
25
  {{- range .components }}
16
- {{ . }}: "1"
26
+ toa/component-{{ . }}: "1"
27
+ {{- end }}
28
+ {{- range .hosted }}
29
+ toa/service-{{ . }}: "1"
17
30
  {{- end }}
18
31
  spec:
19
32
  containers:
20
33
  - name: {{ .name }}
21
34
  image: {{ .image }}
22
- {{- if .variables }}
35
+ {{- if .resources }}
36
+ resources:
37
+ {{- if or .resources.cpu .resources.memory }}
38
+ requests:
39
+ {{- if .resources.cpu }}
40
+ cpu: {{ index .resources.cpu 0 }}
41
+ {{- end }}
42
+ {{- if .resources.memory }}
43
+ memory: {{ index .resources.memory 0 }}
44
+ {{- end }}
45
+ limits:
46
+ {{- if .resources.cpu }}
47
+ cpu: {{ index .resources.cpu 1 }}
48
+ {{- end }}
49
+ {{- if .resources.memory }}
50
+ memory: {{ index .resources.memory 1 }}
51
+ {{- end }}
52
+ {{- end }}
53
+ {{- end }}
54
+ {{- if or .variables .services }}
23
55
  env:
56
+ {{- if .services }}
57
+ - name: TOA_SERVICES
58
+ value: {{ join " " .services | quote }}
59
+ {{- end }}
24
60
  {{- range .variables }}
25
61
  {{- include "env.var" . | indent 12 }}
26
62
  {{- end }}
27
63
  {{- end }}
64
+ {{- if or .backends .probe }}
65
+ ports:
66
+ {{- range .backends }}
67
+ - containerPort: {{ .port }}
68
+ {{- end }}
69
+ {{- if .probe }}
70
+ - containerPort: {{ .probe.port }}
71
+ {{- end }}
72
+ {{- end }}
73
+ {{- if .probe }}
74
+ startupProbe:
75
+ httpGet:
76
+ path: {{ .probe.path }}
77
+ port: {{ .probe.port }}
78
+ {{- if .probe.delay }}
79
+ initialDelaySeconds: {{ .probe.delay }}
80
+ {{- end }}
81
+ periodSeconds: 2
82
+ timeoutSeconds: 3
83
+ failureThreshold: 150
84
+ readinessProbe:
85
+ httpGet:
86
+ path: {{ .probe.path }}
87
+ port: {{ .probe.port }}
88
+ # a replica is ready when it says so, not at the next tick of a slow clock
89
+ periodSeconds: 2
90
+ timeoutSeconds: 3
91
+ failureThreshold: 5
92
+ {{- end }}
93
+ {{- if or .mounts $.Values.map }}
94
+ volumeMounts:
95
+ {{- range .mounts }}
96
+ - name: {{ .name }}
97
+ mountPath: {{ .path }}
98
+ {{- end }}
99
+ {{- if $.Values.map }}
100
+ - name: components
101
+ mountPath: {{ $.Values.map.directory }}
102
+ readOnly: true
103
+ {{- end }}
104
+ {{- end }}
105
+ lifecycle:
106
+ preStop:
107
+ exec:
108
+ command: [sleep, "5"]
109
+ terminationGracePeriodSeconds: 45
28
110
  {{- if $.Values.credentials }}
29
111
  imagePullSecrets:
30
112
  - name: {{ $.Values.credentials }}
31
113
  {{- end }}
114
+ {{- if or .mounts $.Values.map }}
115
+ volumes:
116
+ {{- range .mounts }}
117
+ - name: {{ .name }}
118
+ persistentVolumeClaim:
119
+ claimName: {{ .claim }}
120
+ {{- end }}
121
+ {{- if $.Values.map }}
122
+ - name: components
123
+ configMap:
124
+ name: components
125
+ {{- end }}
126
+ {{- end }}
127
+ topologySpreadConstraints:
128
+ - maxSkew: 1
129
+ topologyKey: kubernetes.io/hostname
130
+ whenUnsatisfiable: ScheduleAnyway
131
+ labelSelector:
132
+ matchLabels:
133
+ toa/composition: {{ .name }}
134
+ # only this revision's pods: a rollout spreads the new ones, whatever the old ones occupy
135
+ matchLabelKeys:
136
+ - pod-template-hash
32
137
  ---
33
138
  {{- end }}
@@ -0,0 +1,199 @@
1
+ {{- if .Values.mono }}
2
+ {{- with .Values.mono }}
3
+ apiVersion: apps/v1
4
+ kind: Deployment
5
+ metadata:
6
+ name: mono
7
+ spec:
8
+ replicas: {{ .replicas | default 2 }}
9
+ progressDeadlineSeconds: 900
10
+ strategy:
11
+ type: RollingUpdate
12
+ rollingUpdate:
13
+ maxUnavailable: 0
14
+ maxSurge: 100%
15
+ selector:
16
+ matchLabels:
17
+ toa/composition: mono
18
+ template:
19
+ metadata:
20
+ labels:
21
+ toa/composition: mono
22
+ {{- range .components }}
23
+ toa/component-{{ . }}: "1"
24
+ {{- end }}
25
+ spec:
26
+ containers:
27
+ - name: mono
28
+ image: {{ .image }}
29
+ {{- if or .backends .probe }}
30
+ ports:
31
+ {{- range .backends }}
32
+ - containerPort: {{ .port }}
33
+ {{- end }}
34
+ {{- if .probe }}
35
+ - containerPort: {{ .probe.port }}
36
+ {{- end }}
37
+ {{- end }}
38
+ {{- if .resources }}
39
+ resources:
40
+ {{- if or .resources.cpu .resources.memory }}
41
+ requests:
42
+ {{- if .resources.cpu }}
43
+ cpu: {{ index .resources.cpu 0 }}
44
+ {{- end }}
45
+ {{- if .resources.memory }}
46
+ memory: {{ index .resources.memory 0 }}
47
+ {{- end }}
48
+ limits:
49
+ {{- if .resources.cpu }}
50
+ cpu: {{ index .resources.cpu 1 }}
51
+ {{- end }}
52
+ {{- if .resources.memory }}
53
+ memory: {{ index .resources.memory 1 }}
54
+ {{- end }}
55
+ {{- end }}
56
+ {{- end }}
57
+ {{- if or .variables .services }}
58
+ env:
59
+ {{- if .services }}
60
+ - name: TOA_SERVICES
61
+ value: {{ join " " .services | quote }}
62
+ {{- end }}
63
+ {{- range .variables }}
64
+ {{- include "env.var" . | indent 12 }}
65
+ {{- end }}
66
+ {{- end }}
67
+ {{- if .probe }}
68
+ startupProbe:
69
+ httpGet:
70
+ path: {{ .probe.path }}
71
+ port: {{ .probe.port }}
72
+ {{- if .probe.delay }}
73
+ initialDelaySeconds: {{ .probe.delay }}
74
+ {{- end }}
75
+ periodSeconds: 2
76
+ timeoutSeconds: 3
77
+ failureThreshold: 150
78
+ readinessProbe:
79
+ httpGet:
80
+ path: {{ .probe.path }}
81
+ port: {{ .probe.port }}
82
+ # a replica is ready when it says so, not at the next tick of a slow clock
83
+ periodSeconds: 2
84
+ timeoutSeconds: 3
85
+ failureThreshold: 5
86
+ {{- end }}
87
+ {{- if or .mounts $.Values.map }}
88
+ volumeMounts:
89
+ {{- range .mounts }}
90
+ - name: {{ .name }}
91
+ mountPath: {{ .path }}
92
+ {{- end }}
93
+ {{- if $.Values.map }}
94
+ - name: components
95
+ mountPath: {{ $.Values.map.directory }}
96
+ readOnly: true
97
+ {{- end }}
98
+ {{- end }}
99
+ lifecycle:
100
+ preStop:
101
+ exec:
102
+ command: [sleep, "5"]
103
+ terminationGracePeriodSeconds: 45
104
+ {{- if $.Values.credentials }}
105
+ imagePullSecrets:
106
+ - name: {{ $.Values.credentials }}
107
+ {{- end }}
108
+ {{- if or .mounts $.Values.map }}
109
+ volumes:
110
+ {{- range .mounts }}
111
+ - name: {{ .name }}
112
+ persistentVolumeClaim:
113
+ claimName: {{ .claim }}
114
+ {{- end }}
115
+ {{- if $.Values.map }}
116
+ - name: components
117
+ configMap:
118
+ name: components
119
+ {{- end }}
120
+ {{- end }}
121
+ topologySpreadConstraints:
122
+ - maxSkew: 1
123
+ topologyKey: kubernetes.io/hostname
124
+ whenUnsatisfiable: ScheduleAnyway
125
+ labelSelector:
126
+ matchLabels:
127
+ toa/composition: mono
128
+ # only this revision's pods: a rollout spreads the new ones, whatever the old ones occupy
129
+ matchLabelKeys:
130
+ - pod-template-hash
131
+ {{- if .backends }}
132
+ ---
133
+ apiVersion: v1
134
+ kind: Service
135
+ metadata:
136
+ name: mono
137
+ {{- if .annotations }}
138
+ annotations:
139
+ {{ toYaml .annotations | indent 4 }}
140
+ {{- end }}
141
+ spec:
142
+ type: ClusterIP
143
+ selector:
144
+ toa/composition: mono
145
+ ports:
146
+ {{- range .backends }}
147
+ - name: port-{{ .port }}
148
+ protocol: TCP
149
+ port: {{ .port }}
150
+ targetPort: {{ .port }}
151
+ {{- end }}
152
+ {{- end }}
153
+ {{- if .ingress }}
154
+ ---
155
+ apiVersion: networking.k8s.io/v1
156
+ kind: Ingress
157
+ metadata:
158
+ name: mono
159
+ {{- if .ingress.annotations }}
160
+ annotations:
161
+ {{ toYaml .ingress.annotations | indent 4 }}
162
+ {{- end }}
163
+ spec:
164
+ {{- if .ingress.class }}
165
+ ingressClassName: {{ .ingress.class }}
166
+ {{- end }}
167
+ {{- $backends := .backends }}
168
+ rules:
169
+ {{- range .ingress.hosts }}
170
+ - host: {{ . }}
171
+ http:
172
+ paths:
173
+ {{- range $backends }}
174
+ - path: {{ .path }}
175
+ pathType: Prefix
176
+ backend:
177
+ service:
178
+ name: mono
179
+ port:
180
+ number: {{ .port }}
181
+ {{- end }}
182
+ {{- end }}
183
+ {{- if .ingress.default }}
184
+ - http:
185
+ paths:
186
+ {{- range $backends }}
187
+ - path: {{ .path }}
188
+ pathType: Prefix
189
+ backend:
190
+ service:
191
+ name: mono
192
+ port:
193
+ number: {{ .port }}
194
+ {{- end }}
195
+ {{- end }}
196
+ {{- end }}
197
+ ---
198
+ {{- end }}
199
+ {{- end }}
@@ -1,21 +1,52 @@
1
1
  {{- range .Values.services }}
2
+ {{- if not .workload }}
2
3
  apiVersion: apps/v1
3
4
  kind: Deployment
4
5
  metadata:
5
6
  name: extension-{{ required "deployment name is required" .name }}
6
7
  spec:
7
8
  replicas: {{ .replicas | default 2 }}
9
+ # A backstop for stuck rollouts only. Must stay above the `helm upgrade --timeout`
10
+ # the deploy runs with, so a slow but progressing rollout is not marked failed.
11
+ progressDeadlineSeconds: 900
12
+ strategy:
13
+ type: RollingUpdate
14
+ rollingUpdate:
15
+ # a replacement must pass readiness before a running replica is taken out, and every
16
+ # replacement starts at once: the rollout takes one start-up, not one per replica
17
+ maxUnavailable: 0
18
+ maxSurge: 100%
8
19
  selector:
9
20
  matchLabels:
10
- toa.io/service: extension-{{ .name }}
21
+ toa/service: extension-{{ .name }}
11
22
  template:
12
23
  metadata:
13
24
  labels:
14
- toa.io/service: extension-{{ .name }}
25
+ toa/service: extension-{{ .name }}
26
+ toa/service-{{ .name }}: "1"
15
27
  spec:
16
28
  containers:
17
29
  - name: extension-{{ .name }}
18
30
  image: {{ .image }}
31
+ {{- if .resources }}
32
+ resources:
33
+ {{- if or .resources.cpu .resources.memory }}
34
+ requests:
35
+ {{- if .resources.cpu }}
36
+ cpu: {{ index .resources.cpu 0 }}
37
+ {{- end }}
38
+ {{- if .resources.memory }}
39
+ memory: {{ index .resources.memory 0 }}
40
+ {{- end }}
41
+ limits:
42
+ {{- if .resources.cpu }}
43
+ cpu: {{ index .resources.cpu 1 }}
44
+ {{- end }}
45
+ {{- if .resources.memory }}
46
+ memory: {{ index .resources.memory 1 }}
47
+ {{- end }}
48
+ {{- end }}
49
+ {{- end }}
19
50
  {{- if .variables }}
20
51
  env:
21
52
  {{- range .variables }}
@@ -23,31 +54,78 @@ spec:
23
54
  {{- end }}
24
55
  {{- end }}
25
56
  {{- if .probe }}
26
- readinessProbe:
57
+ startupProbe:
27
58
  httpGet:
28
59
  path: {{ .probe.path }}
29
60
  port: {{ .probe.port }}
30
61
  {{- if .probe.delay }}
31
62
  initialDelaySeconds: {{ .probe.delay }}
32
63
  {{- end }}
64
+ periodSeconds: 2
65
+ timeoutSeconds: 3
66
+ failureThreshold: 150
67
+ readinessProbe:
68
+ httpGet:
69
+ path: {{ .probe.path }}
70
+ port: {{ .probe.port }}
71
+ # a replica is ready when it says so, not at the next tick of a slow clock
72
+ periodSeconds: 2
73
+ timeoutSeconds: 3
74
+ failureThreshold: 5
75
+ {{- end }}
76
+ {{- if $.Values.map }}
77
+ volumeMounts:
78
+ - name: components
79
+ mountPath: {{ $.Values.map.directory }}
80
+ readOnly: true
33
81
  {{- end }}
82
+ lifecycle:
83
+ preStop:
84
+ exec:
85
+ command: [sleep, "5"]
86
+ {{- if $.Values.map }}
87
+ volumes:
88
+ - name: components
89
+ configMap:
90
+ name: components
91
+ {{- end }}
92
+ terminationGracePeriodSeconds: 45
93
+ topologySpreadConstraints:
94
+ - maxSkew: 1
95
+ topologyKey: kubernetes.io/hostname
96
+ whenUnsatisfiable: ScheduleAnyway
97
+ labelSelector:
98
+ matchLabels:
99
+ toa/service: extension-{{ .name }}
100
+ # only this revision's pods: a rollout spreads the new ones, whatever the old ones occupy
101
+ matchLabelKeys:
102
+ - pod-template-hash
103
+ {{- end }}
104
+ {{- if .port }}
34
105
  ---
35
106
  apiVersion: v1
36
107
  kind: Service
37
108
  metadata:
38
109
  name: extension-{{ .name }}
110
+ {{- if .annotations }}
111
+ annotations:
112
+ {{ toYaml .annotations | indent 4 }}
113
+ {{- end }}
39
114
  spec:
40
115
  type: ClusterIP
41
116
  selector:
42
- toa.io/service: extension-{{ .name }}
117
+ toa/service-{{ .name }}: "1"
43
118
  ports:
44
119
  - name: port-{{ .port }}
45
120
  protocol: TCP
46
121
  port: {{ .port }}
47
122
  targetPort: {{ .port }}
48
- ---
123
+ {{- end }}
49
124
  {{- if .ingress }}
50
125
  {{- $service := .name }}
126
+ {{- $port := .port }}
127
+ {{- $path := .ingress.path | default "/" }}
128
+ ---
51
129
  apiVersion: networking.k8s.io/v1
52
130
  kind: Ingress
53
131
  metadata:
@@ -65,13 +143,25 @@ spec:
65
143
  - host: {{ . }}
66
144
  http:
67
145
  paths:
68
- - path: /
146
+ - path: {{ $path }}
69
147
  pathType: Prefix
70
148
  backend:
71
149
  service:
72
150
  name: extension-{{ $service }}
73
151
  port:
74
- number: 8000
152
+ number: {{ $port }}
153
+ {{- end }}
154
+ {{- if .ingress.default }}
155
+ - http:
156
+ paths:
157
+ - path: {{ $path }}
158
+ pathType: Prefix
159
+ backend:
160
+ service:
161
+ name: extension-{{ $service }}
162
+ port:
163
+ number: {{ $port }}
75
164
  {{- end }}
76
165
  {{- end }}
166
+ ---
77
167
  {{- end }}