teraslice 3.2.1 → 3.3.1

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 (108) hide show
  1. package/LICENSE +202 -0
  2. package/package.json +26 -30
  3. package/dist/src/interfaces.js +0 -12
  4. package/dist/src/lib/cluster/cluster_master.js +0 -246
  5. package/dist/src/lib/cluster/node_master.js +0 -355
  6. package/dist/src/lib/cluster/services/api.js +0 -663
  7. package/dist/src/lib/cluster/services/assets.js +0 -224
  8. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/index.js +0 -192
  9. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/interfaces.js +0 -2
  10. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8s.js +0 -419
  11. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sDeploymentResource.js +0 -60
  12. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sJobResource.js +0 -55
  13. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sResource.js +0 -357
  14. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sServiceResource.js +0 -37
  15. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sState.js +0 -60
  16. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/utils.js +0 -170
  17. package/dist/src/lib/cluster/services/cluster/backends/native/dispatch.js +0 -13
  18. package/dist/src/lib/cluster/services/cluster/backends/native/index.js +0 -526
  19. package/dist/src/lib/cluster/services/cluster/backends/native/messaging.js +0 -548
  20. package/dist/src/lib/cluster/services/cluster/backends/state-utils.js +0 -26
  21. package/dist/src/lib/cluster/services/cluster/index.js +0 -13
  22. package/dist/src/lib/cluster/services/execution.js +0 -435
  23. package/dist/src/lib/cluster/services/index.js +0 -6
  24. package/dist/src/lib/cluster/services/interfaces.js +0 -2
  25. package/dist/src/lib/cluster/services/jobs.js +0 -458
  26. package/dist/src/lib/config/default-sysconfig.js +0 -25
  27. package/dist/src/lib/config/index.js +0 -20
  28. package/dist/src/lib/config/schemas/system.js +0 -360
  29. package/dist/src/lib/storage/analytics.js +0 -86
  30. package/dist/src/lib/storage/assets.js +0 -401
  31. package/dist/src/lib/storage/backends/elasticsearch_store.js +0 -496
  32. package/dist/src/lib/storage/backends/mappings/analytics.js +0 -20
  33. package/dist/src/lib/storage/backends/mappings/asset.js +0 -32
  34. package/dist/src/lib/storage/backends/mappings/ex.js +0 -53
  35. package/dist/src/lib/storage/backends/mappings/job.js +0 -42
  36. package/dist/src/lib/storage/backends/mappings/state.js +0 -16
  37. package/dist/src/lib/storage/backends/s3_store.js +0 -237
  38. package/dist/src/lib/storage/execution.js +0 -302
  39. package/dist/src/lib/storage/index.js +0 -7
  40. package/dist/src/lib/storage/jobs.js +0 -81
  41. package/dist/src/lib/storage/state.js +0 -254
  42. package/dist/src/lib/utils/api_utils.js +0 -128
  43. package/dist/src/lib/utils/asset_utils.js +0 -94
  44. package/dist/src/lib/utils/date_utils.js +0 -52
  45. package/dist/src/lib/utils/encoding_utils.js +0 -27
  46. package/dist/src/lib/utils/events.js +0 -4
  47. package/dist/src/lib/utils/file_utils.js +0 -124
  48. package/dist/src/lib/utils/id_utils.js +0 -15
  49. package/dist/src/lib/utils/port_utils.js +0 -32
  50. package/dist/src/lib/workers/assets/index.js +0 -3
  51. package/dist/src/lib/workers/assets/loader-executable.js +0 -40
  52. package/dist/src/lib/workers/assets/loader.js +0 -73
  53. package/dist/src/lib/workers/assets/spawn.js +0 -55
  54. package/dist/src/lib/workers/context/execution-context.js +0 -12
  55. package/dist/src/lib/workers/context/terafoundation-context.js +0 -8
  56. package/dist/src/lib/workers/execution-controller/execution-analytics.js +0 -188
  57. package/dist/src/lib/workers/execution-controller/index.js +0 -1024
  58. package/dist/src/lib/workers/execution-controller/recovery.js +0 -151
  59. package/dist/src/lib/workers/execution-controller/scheduler.js +0 -390
  60. package/dist/src/lib/workers/execution-controller/slice-analytics.js +0 -96
  61. package/dist/src/lib/workers/helpers/job.js +0 -80
  62. package/dist/src/lib/workers/helpers/op-analytics.js +0 -22
  63. package/dist/src/lib/workers/helpers/terafoundation.js +0 -34
  64. package/dist/src/lib/workers/helpers/worker-shutdown.js +0 -147
  65. package/dist/src/lib/workers/metrics/index.js +0 -108
  66. package/dist/src/lib/workers/worker/index.js +0 -378
  67. package/dist/src/lib/workers/worker/slice.js +0 -122
  68. package/dist/test/config/schemas/system_schema-spec.js +0 -26
  69. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/k8s-v2-spec.js +0 -458
  70. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/k8sResource-v2-spec.js +0 -818
  71. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/k8sState-multicluster-v2-spec.js +0 -67
  72. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/k8sState-v2-spec.js +0 -84
  73. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/utils-v2-spec.js +0 -320
  74. package/dist/test/lib/cluster/services/cluster/backends/state-utils-spec.js +0 -37
  75. package/dist/test/node_master-spec.js +0 -194
  76. package/dist/test/services/api-spec.js +0 -79
  77. package/dist/test/services/assets-spec.js +0 -158
  78. package/dist/test/services/messaging-spec.js +0 -440
  79. package/dist/test/storage/assets_storage-spec.js +0 -95
  80. package/dist/test/storage/s3_store-spec.js +0 -149
  81. package/dist/test/test.config.js +0 -23
  82. package/dist/test/test.setup.js +0 -6
  83. package/dist/test/utils/api_utils-spec.js +0 -25
  84. package/dist/test/utils/asset_utils-spec.js +0 -141
  85. package/dist/test/utils/elastic_utils-spec.js +0 -25
  86. package/dist/test/workers/execution-controller/execution-controller-spec.js +0 -371
  87. package/dist/test/workers/execution-controller/execution-special-test-cases-spec.js +0 -519
  88. package/dist/test/workers/execution-controller/execution-test-cases-spec.js +0 -343
  89. package/dist/test/workers/execution-controller/recovery-spec.js +0 -160
  90. package/dist/test/workers/execution-controller/scheduler-spec.js +0 -249
  91. package/dist/test/workers/execution-controller/slice-analytics-spec.js +0 -121
  92. package/dist/test/workers/fixtures/ops/example-op/processor.js +0 -20
  93. package/dist/test/workers/fixtures/ops/example-op/schema.js +0 -19
  94. package/dist/test/workers/fixtures/ops/example-reader/fetcher.js +0 -20
  95. package/dist/test/workers/fixtures/ops/example-reader/schema.js +0 -41
  96. package/dist/test/workers/fixtures/ops/example-reader/slicer.js +0 -37
  97. package/dist/test/workers/fixtures/ops/new-op/processor.js +0 -29
  98. package/dist/test/workers/fixtures/ops/new-op/schema.js +0 -18
  99. package/dist/test/workers/fixtures/ops/new-reader/fetcher.js +0 -19
  100. package/dist/test/workers/fixtures/ops/new-reader/schema.js +0 -23
  101. package/dist/test/workers/fixtures/ops/new-reader/slicer.js +0 -13
  102. package/dist/test/workers/helpers/configs.js +0 -128
  103. package/dist/test/workers/helpers/execution-controller-helper.js +0 -49
  104. package/dist/test/workers/helpers/index.js +0 -5
  105. package/dist/test/workers/helpers/test-context.js +0 -210
  106. package/dist/test/workers/helpers/zip-directory.js +0 -25
  107. package/dist/test/workers/worker/slice-spec.js +0 -333
  108. package/dist/test/workers/worker/worker-spec.js +0 -356
@@ -1,419 +0,0 @@
1
- import { TSError, get, isEmpty, pDelay, pRetry } from '@terascope/core-utils';
2
- import * as k8s from '@kubernetes/client-node';
3
- import { convertToTSResource, convertToTSResourceList, getRetryConfig, isDeployment, isJob, isPod, isReplicaSet, isService, isTSPod } from './utils.js';
4
- export class K8s {
5
- logger;
6
- apiPollDelay;
7
- defaultNamespace;
8
- shutdownTimeout;
9
- kc;
10
- k8sAppsV1Api;
11
- k8sBatchV1Api;
12
- k8sCoreV1Api;
13
- constructor(logger, clientConfig, defaultNamespace, apiPollDelay, shutdownTimeout) {
14
- this.apiPollDelay = apiPollDelay;
15
- this.defaultNamespace = defaultNamespace || 'default';
16
- this.logger = logger;
17
- this.shutdownTimeout = shutdownTimeout; // this is in milliseconds
18
- this.kc = new k8s.KubeConfig();
19
- if (clientConfig) {
20
- this.kc.loadFromOptions(clientConfig);
21
- }
22
- else if (process.env.KUBERNETES_SERVICE_HOST && process.env.KUBERNETES_SERVICE_PORT) {
23
- this.kc.loadFromCluster();
24
- }
25
- else {
26
- this.kc.loadFromDefault();
27
- }
28
- this.k8sAppsV1Api = this.kc.makeApiClient(k8s.AppsV1Api);
29
- this.k8sBatchV1Api = this.kc.makeApiClient(k8s.BatchV1Api);
30
- this.k8sCoreV1Api = this.kc.makeApiClient(k8s.CoreV1Api);
31
- }
32
- /**
33
- * Returns the k8s NamespaceList object
34
- * @return {Promise} [description]
35
- */
36
- async getNamespaces() {
37
- let namespaces;
38
- try {
39
- namespaces = await pRetry(() => this.k8sCoreV1Api.listNamespace(), getRetryConfig());
40
- }
41
- catch (err) {
42
- const error = new TSError(err, {
43
- reason: 'Failure getting in namespaces'
44
- });
45
- throw error;
46
- }
47
- return namespaces;
48
- }
49
- /**
50
- * Returns the first pod matching the provided selector after it has
51
- * entered the `Running` state.
52
- *
53
- * TODO: Make more generic to search for different statuses
54
- *
55
- * NOTE: If your selector will return multiple pods, this method probably
56
- * won't work for you.
57
- * @param {String} selector kubernetes selector, like 'controller-uid=XXX'
58
- * @param {String} ns namespace to search, this will override the default
59
- * @param {Number} timeout time, in ms, to wait for pod to start
60
- * @return {k8s.V1Pod} pod object
61
- *
62
- * TODO: Should this use the cluster state that gets polled periodically,
63
- * rather than making it's own k8s API calls
64
- */
65
- async waitForSelectedPod(selector, statusType, ns, timeout = 10000) {
66
- const namespace = ns || this.defaultNamespace;
67
- let now = Date.now();
68
- const end = now + timeout;
69
- while (true) {
70
- const podListObj = await pRetry(() => this.k8sCoreV1Api
71
- .listNamespacedPod({ namespace, labelSelector: selector }), getRetryConfig());
72
- // NOTE: This assumes the first pod returned.
73
- const pod = get(podListObj, 'items[0]');
74
- if (pod && isTSPod(pod)) {
75
- if (statusType === 'readiness-probe') {
76
- if (pod.status.conditions) {
77
- for (const condition of pod.status.conditions) {
78
- if (condition.type === 'ContainersReady'
79
- && condition.status === 'True') {
80
- return pod;
81
- }
82
- }
83
- }
84
- }
85
- else if (statusType === 'pod-status') {
86
- if (get(pod, 'status.phase') === 'Running')
87
- return pod;
88
- }
89
- }
90
- if (now > end)
91
- throw new Error(`Timeout waiting for pod matching: ${selector}`);
92
- this.logger.debug(`waiting for pod matching: ${selector}`);
93
- await pDelay(this.apiPollDelay);
94
- now = Date.now();
95
- }
96
- }
97
- /**
98
- * Waits for the number of pods to equal number.
99
- * @param {Number} number Number of pods to wait for, e.g.: 0, 10
100
- * @param {String} selector kubernetes selector, like 'controller-uid=XXX'
101
- * @param {String} ns namespace to search, this will override the default
102
- * @param {Number} timeout time, in ms, to wait for pod to start
103
- * @return {k8s.V1Pod[]} Array of pod objects
104
- *
105
- * TODO: Should this use the cluster state that gets polled periodically,
106
- * rather than making it's own k8s API calls?
107
- */
108
- async waitForNumPods(number, selector, ns, timeout = 10000) {
109
- const namespace = ns || this.defaultNamespace;
110
- let now = Date.now();
111
- const end = now + timeout;
112
- while (true) {
113
- const podListObj = await pRetry(() => this.k8sCoreV1Api
114
- .listNamespacedPod({ namespace, labelSelector: selector }), getRetryConfig());
115
- const podList = get(podListObj, 'items');
116
- if (podList.length === number)
117
- return podList;
118
- const msg = `Waiting: pods matching ${selector} is ${podList.length}/${number}`;
119
- if (now > end)
120
- throw new Error(`Timeout ${msg}`);
121
- this.logger.debug(msg);
122
- await pDelay(this.apiPollDelay);
123
- now = Date.now();
124
- }
125
- }
126
- async list(selector, objType, ns) {
127
- const namespace = ns || this.defaultNamespace;
128
- let resourceListObj;
129
- const params = {
130
- namespace,
131
- labelSelector: selector
132
- };
133
- try {
134
- if (objType === 'deployments') {
135
- resourceListObj = await pRetry(() => this.k8sAppsV1Api.listNamespacedDeployment(params), getRetryConfig());
136
- }
137
- else if (objType === 'jobs') {
138
- resourceListObj = await pRetry(() => this.k8sBatchV1Api.listNamespacedJob(params), getRetryConfig());
139
- }
140
- else if (objType === 'pods') {
141
- resourceListObj = await pRetry(() => this.k8sCoreV1Api.listNamespacedPod(params), getRetryConfig());
142
- }
143
- else if (objType === 'replicasets') {
144
- resourceListObj = await pRetry(() => this.k8sAppsV1Api.listNamespacedReplicaSet(params), getRetryConfig());
145
- }
146
- else if (objType === 'services') {
147
- resourceListObj = await pRetry(() => this.k8sCoreV1Api.listNamespacedService(params), getRetryConfig());
148
- }
149
- else {
150
- const error = new Error(`Invalid objType provided to get: ${objType}`);
151
- this.logger.error(error);
152
- return Promise.reject(error);
153
- }
154
- return convertToTSResourceList(resourceListObj);
155
- }
156
- catch (e) {
157
- const err = new Error(`Request k8s.list of ${objType} with selector ${selector} failed: ${e}`);
158
- this.logger.error(err);
159
- return Promise.reject(err);
160
- }
161
- }
162
- async nonEmptyJobList(selector) {
163
- const jobs = await this.list(selector, 'jobs');
164
- if (jobs.items.length === 1) {
165
- return jobs;
166
- }
167
- else if (jobs.items.length === 0) {
168
- const msg = `Teraslice job matching the following selector was not found: ${selector} (retriable)`;
169
- this.logger.warn(msg);
170
- throw new TSError(msg, { retryable: true });
171
- }
172
- else {
173
- throw new TSError(`Unexpected number of Teraslice jobs matching the following selector: ${selector}`, {
174
- retryable: true
175
- });
176
- }
177
- }
178
- async post(manifest) {
179
- let resourceObj;
180
- const namespace = this.defaultNamespace;
181
- try {
182
- if (isDeployment(manifest)) {
183
- resourceObj = await this.k8sAppsV1Api
184
- .createNamespacedDeployment({ namespace, body: manifest });
185
- }
186
- else if (isJob(manifest)) {
187
- resourceObj = await this.k8sBatchV1Api
188
- .createNamespacedJob({ namespace, body: manifest });
189
- }
190
- else if (isPod(manifest)) {
191
- resourceObj = await this.k8sCoreV1Api
192
- .createNamespacedPod({ namespace, body: manifest });
193
- }
194
- else if (isReplicaSet(manifest)) {
195
- resourceObj = await this.k8sAppsV1Api
196
- .createNamespacedReplicaSet({ namespace, body: manifest });
197
- }
198
- else if (isService(manifest)) {
199
- resourceObj = await this.k8sCoreV1Api
200
- .createNamespacedService({ namespace, body: manifest });
201
- }
202
- else {
203
- const error = new Error('Invalid manifest type');
204
- return Promise.reject(error);
205
- }
206
- return convertToTSResource(resourceObj);
207
- }
208
- catch (e) {
209
- const err = new Error(`Request k8s.post of ${manifest.kind} with body ${JSON.stringify(manifest)} failed: ${e}`);
210
- return Promise.reject(err);
211
- }
212
- }
213
- /**
214
- * Patches specified k8s deployment with the provided record
215
- * @param {String} record record, like 'app=teraslice'
216
- * @param {String} name Name of the deployment to patch
217
- * @return {Object} k8s V1Deployment object.
218
- */
219
- // TODO: I renamed this from patchDeployment to just patch because this is
220
- // the low level k8s api method, I expect to eventually change the interface
221
- // on this to require `objType` to support patching other things
222
- async patch(record, name) {
223
- let responseObj;
224
- try {
225
- const options = k8s.setHeaderOptions('Content-Type', k8s.PatchStrategy.JsonPatch);
226
- responseObj = await pRetry(() => this.k8sAppsV1Api.patchNamespacedDeployment({
227
- name,
228
- namespace: this.defaultNamespace,
229
- body: record
230
- }, options), getRetryConfig());
231
- return responseObj;
232
- }
233
- catch (e) {
234
- const err = new Error(`Request k8s.patch with name: ${name} failed with: ${e}`);
235
- this.logger.error(err);
236
- return Promise.reject(err);
237
- }
238
- }
239
- async delete(name, objType, force) {
240
- if (name === undefined || name.trim() === '') {
241
- throw new Error(`Name of resource to delete must be specified. Received: "${name}".`);
242
- }
243
- let responseObj;
244
- // To get a Job to remove the associated pods you have to
245
- // include a body like the one below with the delete request.
246
- // To force: setting gracePeriodSeconds to 1 will send a SIGKILL command to the resource
247
- const deleteOptions = {
248
- apiVersion: 'v1',
249
- kind: 'DeleteOptions',
250
- propagationPolicy: 'Background'
251
- };
252
- if (force) {
253
- deleteOptions.gracePeriodSeconds = 1;
254
- }
255
- const params = {
256
- name,
257
- namespace: this.defaultNamespace,
258
- body: deleteOptions
259
- };
260
- const deleteWithErrorHandling = async (deleteFn) => {
261
- try {
262
- const res = await deleteFn();
263
- return res;
264
- }
265
- catch (e) {
266
- if (e.body) {
267
- const bodyObj = JSON.parse(e.body);
268
- // 404 should be an acceptable response to a delete request, not an error
269
- if (bodyObj.code === 404) {
270
- this.logger.info(`No ${objType} with name ${name} found while attempting to delete.`);
271
- return bodyObj;
272
- }
273
- }
274
- throw e;
275
- }
276
- };
277
- try {
278
- if (objType === 'services') {
279
- responseObj = await pRetry(() => deleteWithErrorHandling(() => this.k8sCoreV1Api
280
- .deleteNamespacedService(params)), getRetryConfig());
281
- }
282
- else if (objType === 'deployments') {
283
- responseObj = await pRetry(() => deleteWithErrorHandling(() => this.k8sAppsV1Api
284
- .deleteNamespacedDeployment(params)), getRetryConfig());
285
- }
286
- else if (objType === 'jobs') {
287
- responseObj = await pRetry(() => deleteWithErrorHandling(() => this.k8sBatchV1Api
288
- .deleteNamespacedJob(params)), getRetryConfig());
289
- }
290
- else if (objType === 'pods') {
291
- responseObj = await pRetry(() => deleteWithErrorHandling(() => this.k8sCoreV1Api
292
- .deleteNamespacedPod(params)), getRetryConfig());
293
- }
294
- else if (objType === 'replicasets') {
295
- responseObj = await pRetry(() => deleteWithErrorHandling(() => this.k8sAppsV1Api
296
- .deleteNamespacedReplicaSet(params)), getRetryConfig());
297
- }
298
- else {
299
- throw new Error(`Invalid objType: ${objType}`);
300
- }
301
- return responseObj;
302
- }
303
- catch (e) {
304
- const err = new Error(`Request k8s.delete with name: ${name} failed with: ${e}`);
305
- this.logger.error(err);
306
- return Promise.reject(err);
307
- }
308
- }
309
- /**
310
- * Delete all of Kubernetes resources related to the specified exId
311
- * @param {String} exId ID of the execution
312
- * @param {Boolean} force Forcefully stop all pod, deployment,
313
- * service, replicaset and job resources
314
- * @return {Promise}
315
- */
316
- async deleteExecution(exId, force = false) {
317
- if (!exId) {
318
- throw new Error('deleteExecution requires an executionId');
319
- }
320
- if (force) {
321
- // Order matters. If we delete a parent resource before its children it
322
- // will be marked for background deletion and then can't be force deleted.
323
- await this._deleteObjByExId(exId, 'worker', 'pods', force);
324
- await this._deleteObjByExId(exId, 'worker', 'replicasets', force);
325
- await this._deleteObjByExId(exId, 'worker', 'deployments', force);
326
- await this._deleteObjByExId(exId, 'execution_controller', 'pods', force);
327
- await this._deleteObjByExId(exId, 'execution_controller', 'services', force);
328
- }
329
- await this._deleteObjByExId(exId, 'execution_controller', 'jobs', force);
330
- }
331
- async _deleteObjByExId(exId, nodeType, objType, force) {
332
- let objList;
333
- const deleteResponses = [];
334
- try {
335
- objList = await this.list(`app.kubernetes.io/component=${nodeType},teraslice.terascope.io/exId=${exId}`, objType);
336
- }
337
- catch (e) {
338
- const err = new Error(`Request ${objType} list in _deleteObjByExId with app.kubernetes.io/component: ${nodeType} and exId: ${exId} failed with: ${e}`);
339
- this.logger.error(err);
340
- return Promise.reject(err);
341
- }
342
- if (isEmpty(objList.items)) {
343
- this.logger.info(`k8s._deleteObjByExId: ${exId} ${nodeType} ${objType} has already been deleted`);
344
- return Promise.resolve();
345
- }
346
- for (const obj of objList.items) {
347
- const name = obj.metadata.name;
348
- const deletionTimestamp = obj.metadata.deletionTimestamp;
349
- // If deletionTimestamp is present then the resource is already terminating.
350
- // K8s will not change the grace period in this case, so force deletion is not possible
351
- if (force && deletionTimestamp) {
352
- this.logger.warn(`Cannot force delete ${name} for ExId: ${exId}. It will finish deleting gracefully by ${deletionTimestamp}`);
353
- return Promise.resolve();
354
- }
355
- this.logger.info(`k8s._deleteObjByExId: ${exId} ${nodeType} ${objType} ${force ? 'force' : ''} deleting: ${name}`);
356
- try {
357
- deleteResponses.push(await this.delete(name, objType, force));
358
- }
359
- catch (e) {
360
- const err = new Error(`Request k8s.delete in _deleteObjByExId with name: ${name} failed with: ${e}`);
361
- this.logger.error(err);
362
- return Promise.reject(err);
363
- }
364
- }
365
- return deleteResponses;
366
- }
367
- /**
368
- * Scales the k8s deployment for the specified exId to the desired number
369
- * of workers.
370
- * @param {String} exId exId of execution to scale
371
- * @param {number} numWorkers number of workers to scale by
372
- * @param {ScaleOp} op Scale operation: `set`, `add`, `remove`
373
- * @return {Promise<k8s.V1Deployment>} Body of patch response.
374
- */
375
- async scaleExecution(exId, numWorkers, op) {
376
- let newScale;
377
- const selector = `app.kubernetes.io/component=worker,teraslice.terascope.io/exId=${exId}`;
378
- this.logger.info(`Scaling exId: ${exId}, op: ${op}, numWorkers: ${numWorkers}`);
379
- const listResponse = await this.list(selector, 'deployments');
380
- this.logger.debug(`k8s worker query listResponse: ${JSON.stringify(listResponse)}`);
381
- // the selector provided to list above should always result in a single
382
- // deployment in the response.
383
- if (listResponse.items.length === 0) {
384
- const msg = `Teraslice deployment matching the following selector was not found: ${selector}`;
385
- this.logger.warn(msg);
386
- throw new TSError(msg);
387
- }
388
- else if (listResponse.items.length > 1) {
389
- throw new TSError(`Unexpected number of Teraslice deployments matching the following selector: ${selector}`);
390
- }
391
- const workerDeployment = listResponse.items[0];
392
- this.logger.info(`Current Scale for exId=${exId}: ${workerDeployment.spec.replicas}`);
393
- if (op === 'set') {
394
- newScale = numWorkers;
395
- }
396
- else if (op === 'add') {
397
- newScale = workerDeployment.spec.replicas + numWorkers;
398
- }
399
- else if (op === 'remove') {
400
- newScale = workerDeployment.spec.replicas - numWorkers;
401
- }
402
- else {
403
- throw new Error('scaleExecution only accepts the following operations: add, remove, set');
404
- }
405
- this.logger.info(`New Scale for exId=${exId}: ${newScale}`);
406
- const scalePatch = [
407
- {
408
- op: 'replace',
409
- path: '/spec/replicas',
410
- value: newScale
411
- }
412
- ];
413
- const patchResponseBody = await this
414
- .patch(scalePatch, workerDeployment.metadata.name);
415
- this.logger.debug(`k8s.scaleExecution patchResponseBody: ${JSON.stringify(patchResponseBody)}`);
416
- return patchResponseBody;
417
- }
418
- }
419
- //# sourceMappingURL=k8s.js.map
@@ -1,60 +0,0 @@
1
- import { V1Deployment } from '@kubernetes/client-node';
2
- import { convertToTSResource, makeTemplate } from './utils.js';
3
- import { K8sResource } from './k8sResource.js';
4
- export class K8sDeploymentResource extends K8sResource {
5
- nodeType = 'worker';
6
- nameInfix = 'wkr';
7
- templateGenerator;
8
- templateConfig;
9
- resource;
10
- exName;
11
- exUid;
12
- /**
13
- * K8sDeploymentResource allows the generation of a k8s deployment based on a template.
14
- * After creating the object, the k8s deployment is accessible on the objects
15
- * .resource property.
16
- *
17
- * @param {Object} terasliceConfig - teraslice cluster config from context
18
- * @param {Object} execution - teraslice execution
19
- * @param {Logger} logger - teraslice logger
20
- * @param {String} exName - name from execution resource
21
- * @param {String} exUid - uid from execution resource
22
- */
23
- constructor(terasliceConfig, execution, logger, exName, exUid) {
24
- super(terasliceConfig, execution, logger);
25
- this.execution = execution;
26
- this.logger = logger;
27
- this.terasliceConfig = terasliceConfig;
28
- this.exName = exName;
29
- this.exUid = exUid;
30
- this.templateGenerator = makeTemplate('deployments', this.nodeType);
31
- this.templateConfig = this._makeConfig(this.nameInfix, exName, exUid);
32
- const k8sDeployment = new V1Deployment();
33
- Object.assign(k8sDeployment, this.templateGenerator(this.templateConfig));
34
- this.resource = convertToTSResource(k8sDeployment);
35
- this._setJobLabels(this.resource);
36
- // Apply job `targets` setting as k8s nodeAffinity
37
- // We assume that multiple targets require both to match ...
38
- // NOTE: If you specify multiple `matchExpressions` associated with
39
- // `nodeSelectorTerms`, then the pod can be scheduled onto a node
40
- // only if *all* `matchExpressions` can be satisfied.
41
- this._setTargets(this.resource);
42
- this._setResources(this.resource);
43
- this._setVolumes(this.resource);
44
- if (process.env.MOUNT_LOCAL_TERASLICE !== undefined) {
45
- this._mountLocalTeraslice(this.resource);
46
- }
47
- this._setEnvVariables();
48
- this._setAssetsVolume(this.resource);
49
- this._setImagePullSecret(this.resource);
50
- this._setEphemeralStorage(this.resource);
51
- this._setExternalPorts(this.resource);
52
- this._setPriorityClassName(this.resource);
53
- this._setWorkerAntiAffinity(this.resource);
54
- // override must happen last
55
- if (this.terasliceConfig.kubernetes_overrides_enabled) {
56
- this._mergePodSpecOverlay(this.resource);
57
- }
58
- }
59
- }
60
- //# sourceMappingURL=k8sDeploymentResource.js.map
@@ -1,55 +0,0 @@
1
- import { V1Job } from '@kubernetes/client-node';
2
- import { convertToTSResource, makeTemplate } from './utils.js';
3
- import { K8sResource } from './k8sResource.js';
4
- export class K8sJobResource extends K8sResource {
5
- nodeType = 'execution_controller';
6
- nameInfix = 'exc';
7
- templateGenerator;
8
- templateConfig;
9
- resource;
10
- /**
11
- * K8sJobResource allows the generation of a k8s job based on a template.
12
- * After creating the object, the k8s job is accessible on the objects
13
- * .resource property.
14
- *
15
- * @param {Object} terasliceConfig - teraslice cluster config from context
16
- * @param {Object} execution - teraslice execution
17
- * @param {Logger} logger - teraslice logger
18
- */
19
- constructor(terasliceConfig, execution, logger) {
20
- super(terasliceConfig, execution, logger);
21
- this.templateGenerator = makeTemplate('jobs', this.nodeType);
22
- this.templateConfig = this._makeConfig(this.nameInfix);
23
- const k8sJob = new V1Job();
24
- Object.assign(k8sJob, this.templateGenerator(this.templateConfig));
25
- this.resource = convertToTSResource(k8sJob);
26
- this._setJobLabels(this.resource);
27
- // Apply job `targets` setting as k8s nodeAffinity
28
- // We assume that multiple targets require both to match ...
29
- // NOTE: If you specify multiple `matchExpressions` associated with
30
- // `nodeSelectorTerms`, then the pod can be scheduled onto a node
31
- // only if *all* `matchExpressions` can be satisfied.
32
- this._setTargets(this.resource);
33
- this._setResources(this.resource);
34
- this._setVolumes(this.resource);
35
- if (process.env.MOUNT_LOCAL_TERASLICE !== undefined) {
36
- this._mountLocalTeraslice(this.resource);
37
- }
38
- this._setEnvVariables();
39
- this._setAssetsVolume(this.resource);
40
- this._setImagePullSecret(this.resource);
41
- this._setEphemeralStorage(this.resource);
42
- this._setExternalPorts(this.resource);
43
- this._setPriorityClassName(this.resource);
44
- // Execution controller targets are required nodeAffinities, if
45
- // required job targets are also supplied, then *all* of the matches
46
- // will have to be satisfied for the job to be scheduled. This also
47
- // adds tolerations for any specified targets
48
- this._setExecutionControllerTargets(this.resource);
49
- // override must happen last
50
- if (this.terasliceConfig.kubernetes_overrides_enabled) {
51
- this._mergePodSpecOverlay(this.resource);
52
- }
53
- }
54
- }
55
- //# sourceMappingURL=k8sJobResource.js.map