@leverege/build-tools 2.89.0 → 2.89.2

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 (31) hide show
  1. package/package.json +6 -6
  2. package/src/Utils.mjs +3 -2
  3. package/src/build-cnpg-image.mjs +2 -1
  4. package/src/clone-cnpg-from-snapshot.mjs +3 -1
  5. package/src/count-lines-of-code.mjs +1 -0
  6. package/src/custom-images/bitnami-audits/bitnami-audit.mjs +2 -1
  7. package/src/docker-to-registry-py.mjs +1 -1
  8. package/src/docker-to-registry.mjs +0 -1
  9. package/src/fetch-awesome-alerts.mjs +1 -0
  10. package/src/getjson.mjs +1 -0
  11. package/src/helm-audit.mjs +1 -0
  12. package/src/helm-charts/prom-operator/rules/cadvisor-rules.yaml +1 -1
  13. package/src/helm-charts/prom-operator/rules/kubestate-rules.yaml +20 -3
  14. package/src/helm-charts/prom-operator/rules/prometheus-rules.yaml +3 -3
  15. package/src/helm-charts/prom-operator/rules/velero-rules.yaml +1 -1
  16. package/src/hook-and-release/Config.mjs +10 -4
  17. package/src/hook-and-release.mjs +0 -1
  18. package/src/init-my-chart/Chart.yaml +5 -0
  19. package/src/init-my-chart/templates/NOTES.txt +5 -0
  20. package/src/init-my-chart/templates/_helpers.tpl +135 -0
  21. package/src/init-my-chart/templates/configmap.yaml +10 -0
  22. package/src/init-my-chart/templates/deployment.yaml +125 -0
  23. package/src/init-my-chart/templates/hpa.yaml +26 -0
  24. package/src/init-my-chart/templates/ingressroute.yaml +18 -0
  25. package/src/init-my-chart/templates/pdb.yaml +22 -0
  26. package/src/init-my-chart/templates/service.yaml +15 -0
  27. package/src/init-my-chart/templates/serviceaccount.yaml +13 -0
  28. package/src/init-my-chart/templates/servicemonitor.yaml +23 -0
  29. package/src/init-my-chart/values.yaml +152 -0
  30. package/src/k8x.sh +4 -0
  31. package/src/modify-gcs-access.mjs +1 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leverege/build-tools",
3
- "version": "2.89.0",
3
+ "version": "2.89.2",
4
4
  "description": "A collection of build / support tools for Leverege developers",
5
5
  "main": "index.js",
6
6
  "repository": {
@@ -69,20 +69,20 @@
69
69
  "chalk": "^5.6.2",
70
70
  "command-line-args": "^6.0.1",
71
71
  "command-line-usage": "^7.0.3",
72
- "commander": "^14.0.1",
72
+ "commander": "^14.0.2",
73
73
  "deepmerge": "^4.3.1",
74
74
  "enquirer": "^2.4.1",
75
75
  "execa": "^9.6.0",
76
76
  "glob": "^11.0.3",
77
77
  "handlebars": "^4.7.8",
78
78
  "ignore": "^7.0.5",
79
- "inquirer": "^12.9.6",
79
+ "inquirer": "^12.10.0",
80
80
  "js-yaml": "^4.1.0",
81
81
  "jsdoc": "^4.0.5",
82
82
  "ms": "^2.1.3",
83
83
  "npm-registry-fetch": "^19.0.0",
84
84
  "ora": "^9.0.0",
85
- "p-limit": "^7.1.1",
85
+ "p-limit": "^7.2.0",
86
86
  "package-up": "^5.0.0",
87
87
  "readline-sync": "^1.4.10",
88
88
  "semver": "^7.7.3",
@@ -90,10 +90,10 @@
90
90
  "simple-git": "^3.28.0",
91
91
  "sloc": "^0.3.2",
92
92
  "toml": "^3.0.0",
93
- "zx": "^8.8.4"
93
+ "zx": "^8.8.5"
94
94
  },
95
95
  "devDependencies": {
96
- "@leverege/eslint-config-leverege": "^5.1.0",
96
+ "@leverege/eslint-config-leverege": "^5.1.1",
97
97
  "npm": "^11.6.2"
98
98
  }
99
99
  }
package/src/Utils.mjs CHANGED
@@ -39,9 +39,10 @@ export const warning = ( warningText ) => {
39
39
  console.error( `\n${chalk.yellow.bold( fullWarning )}` )
40
40
  }
41
41
 
42
- export const errorExit = ( error, opts = { errorCode : 1 } ) => {
42
+ export const errorExit = ( error, opts = {} ) => {
43
+ const { errorCode = 1 } = opts
43
44
  console.error( `\n${chalk.red.bold( error )}\n` )
44
- if ( opts?.errorCode ) { process.exit( opts.errorCode ) }
45
+ process.exit( errorCode )
45
46
  }
46
47
  /* eslint-enable no-console */
47
48
 
@@ -102,7 +102,8 @@ RUN set -xe; \\
102
102
  apt-get update; \\
103
103
  apt-get install -y --no-install-recommends \\
104
104
  "postgresql-\${PG_MAJOR}-jsquery" \\
105
- "postgresql-\${PG_MAJOR}-repack"; \\
105
+ "postgresql-\${PG_MAJOR}-repack" \\
106
+ "postgresql-\${PG_MAJOR}-squeeze"; \\
106
107
  ln -s /usr/lib/postgresql/\${PG_MAJOR}/bin/pg_repack /usr/local/bin/pg_repack || true; \\
107
108
  rm -fr /tmp/*; \\
108
109
  rm -rf /var/lib/apt/lists/*;
@@ -4,11 +4,12 @@
4
4
 
5
5
  import fs from 'node:fs/promises'
6
6
  import path from 'node:path'
7
- import ora from 'ora'
8
7
 
8
+ import ora from 'ora'
9
9
  import { program } from 'commander'
10
10
  import chalk from 'chalk'
11
11
  import YAML from 'js-yaml'
12
+
12
13
  import {
13
14
  // condir,
14
15
  debug,
@@ -88,6 +89,7 @@ const writeApplyScript = async ( dir ) => {
88
89
  #
89
90
  # Apply VolumeSnapshot resources prior to deploying the CNPG cluster
90
91
  #
92
+ overwhelm
91
93
  kubectl apply -f ${dir}/volumesnapshotclass.yaml
92
94
  kubectl apply -f ${dir}/volumesnapshotcontent.yaml
93
95
  kubectl apply -f ${dir}/volumesnapshot.yaml
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import path from 'node:path'
3
+
3
4
  import { $, fs, chalk, argv } from 'zx'
4
5
 
5
6
  import { log } from './Utils.mjs'
@@ -6,6 +6,7 @@
6
6
  // the BitnamiImageRegistry gsheet to show progess on the migration effort.
7
7
  //
8
8
  import fs from 'node:fs'
9
+
9
10
  import chalk from 'chalk'
10
11
  import semver from 'semver'
11
12
 
@@ -13,7 +14,7 @@ import {
13
14
  debug,
14
15
  log,
15
16
  shellCmd,
16
- } from '../Utils.mjs'
17
+ } from '../../Utils.mjs'
17
18
 
18
19
  const auditProjects = [
19
20
  'dev-controltek',
@@ -3,6 +3,7 @@
3
3
  * DEPRECATED - DO NOT MODIFY
4
4
  */
5
5
  import fs from 'node:fs'
6
+
6
7
  import toml from 'toml'
7
8
  import chalk from 'chalk'
8
9
 
@@ -14,7 +15,6 @@ import {
14
15
  parseHelmChart,
15
16
  proceed,
16
17
  shellCmd } from './Utils.mjs'
17
-
18
18
  import Docker from './DockerPy.mjs'
19
19
 
20
20
  // refresh-npm-token does not throw so no need to try, but it emits in debug
@@ -18,7 +18,6 @@ import {
18
18
  shellCmd,
19
19
  warning,
20
20
  } from './Utils.mjs'
21
-
22
21
  import docker from './Docker.mjs'
23
22
 
24
23
  const minimumBuildToolsVersion = '2.68.0'
@@ -2,6 +2,7 @@
2
2
 
3
3
  import fs from 'node:fs'
4
4
  import path from 'node:path'
5
+
5
6
  import yaml from 'js-yaml'
6
7
  import { Command } from 'commander'
7
8
  import chalk from 'chalk'
package/src/getjson.mjs CHANGED
@@ -19,6 +19,7 @@
19
19
  * Get a command line switch parser.
20
20
  */
21
21
  import fs from 'node:fs'
22
+
22
23
  import cliArgs from 'command-line-args'
23
24
  import cliHelp from 'command-line-usage'
24
25
 
@@ -6,6 +6,7 @@
6
6
  import ora from 'ora'
7
7
  import pLimit from 'p-limit'
8
8
  import chalk from 'chalk'
9
+
9
10
  import { shellCmd, log, errorExit } from './Utils.mjs'
10
11
 
11
12
  const spinner = ora( 'Gathering Helm release info...' ).start()
@@ -76,7 +76,7 @@ spec:
76
76
  time() - kube_pod_start_time > 60
77
77
  )
78
78
  ) > 0.3
79
- for: 5m
79
+ for: 10m # awesome was 5m
80
80
  labels:
81
81
  severity: warning
82
82
  namespace: '{{ $labels.namespace }}'
@@ -165,7 +165,7 @@ spec:
165
165
  LABELS = {{ $labels }}
166
166
  - alert: KubernetesHpaScaleInability
167
167
  expr: (kube_horizontalpodautoscaler_spec_max_replicas - kube_horizontalpodautoscaler_status_desired_replicas) * on (horizontalpodautoscaler,namespace) (kube_horizontalpodautoscaler_status_condition{condition="ScalingLimited", status="true"} == 1) == 0
168
- for: 5m # awesome was => 2m
168
+ for: 15m # awesome was => 2m
169
169
  labels:
170
170
  severity: warning
171
171
  annotations:
@@ -295,7 +295,7 @@ spec:
295
295
  LABELS = {{ $labels }}
296
296
  - alert: KubernetesDaemonsetRolloutStuck
297
297
  expr: kube_daemonset_status_number_ready / kube_daemonset_status_desired_number_scheduled * 100 < 100 or kube_daemonset_status_desired_number_scheduled - kube_daemonset_status_current_number_scheduled > 0
298
- for: 10m
298
+ for: 15m # awesome was 10m
299
299
  labels:
300
300
  severity: warning
301
301
  annotations:
@@ -349,7 +349,24 @@ spec:
349
349
  VALUE = {{ $value }}
350
350
  LABELS = {{ $labels }}
351
351
  - alert: KubernetesApiClientErrors
352
- expr: (sum(rate(rest_client_requests_total{code=~"(4|5).."}[1m])) by (instance, job) / sum(rate(rest_client_requests_total[1m])) by (instance, job)) * 100 > 1
352
+ # awesome expr: (sum(rate(rest_client_requests_total{code=~"(4|5).."}[1m])) by (instance, job) / sum(rate(rest_client_requests_total[1m])) by (instance, job)) * 100 > 1
353
+ expr: |
354
+ (
355
+ (
356
+ sum by (instance, job) (
357
+ rate(
358
+ rest_client_requests_total{
359
+ code=~"(4|5)..",
360
+ code!~"403|404|409"
361
+ }[5m]
362
+ )
363
+ )
364
+ /
365
+ sum by (instance, job) (
366
+ rate(rest_client_requests_total[5m])
367
+ )
368
+ ) * 100
369
+ ) > 1
353
370
  for: 5m
354
371
  labels:
355
372
  severity: critical
@@ -130,10 +130,10 @@ spec:
130
130
  VALUE = {{ $value }}
131
131
  LABELS = {{ $labels }}
132
132
  - alert: PrometheusRuleEvaluationFailures
133
- expr: increase(prometheus_rule_evaluation_failures_total[5m]) > 0 # awesome was 3m
134
- for: 5m # awesome was 0m
133
+ expr: increase(prometheus_rule_evaluation_failures_total[5m]) > 5
134
+ for: 10m # awesome was 0m
135
135
  labels:
136
- severity: critical
136
+ severity: warning # awesome was critical
137
137
  annotations:
138
138
  summary: Prometheus rule evaluation failures (instance {{ $labels.instance }})
139
139
  description: |-
@@ -9,7 +9,7 @@ spec:
9
9
  - name: Velero
10
10
  rules:
11
11
  - alert: VeleroBackupFailure
12
- expr: (time() - velero_backup_last_successful_timestamp{schedule_version=~"2.[0]"} > 108000) and (velero_backup_success_total{schedule!=""} != 0)
12
+ expr: (time() - velero_backup_last_successful_timestamp > 108000) and (velero_backup_success_total{schedule!=""} != 0)
13
13
  for: 5m
14
14
  labels:
15
15
  severity: warning
@@ -6,6 +6,7 @@ import {
6
6
  debug,
7
7
  enableDebug,
8
8
  errorExit,
9
+ getGitRootDirectory,
9
10
  getRepositoryDescr,
10
11
  log,
11
12
  parseJsonFile,
@@ -127,16 +128,21 @@ export default class Config {
127
128
  }
128
129
 
129
130
  async bootstrapHookAndRelease() {
130
- const repoDescr = await getRepositoryDescr()
131
- if ( !repoDescr.isGitRepo ) {
131
+ const gitRootDirectory = await getGitRootDirectory()
132
+ if ( gitRootDirectory === undefined ) {
132
133
  const notGitRepo = `
134
+
133
135
  The hook-and-release script only works with git repositories. Try running:
134
136
 
135
137
  git init && hook-and-release --init
136
138
 
137
- to initialize git and hook-and-release.`
138
- errorExit( notGitRepo )
139
+ to initialize git and hook up hook-and-release.`
140
+ warning( notGitRepo )
141
+ process.exit( 0 )
139
142
  }
143
+
144
+ const repoDescr = await getRepositoryDescr()
145
+
140
146
  this.gitRoot = repoDescr.gitRoot
141
147
  this.gitBranch = repoDescr.gitBranch
142
148
  this.gitHooksPath = repoDescr.gitHooksPath
@@ -3,7 +3,6 @@
3
3
  import path from 'node:path'
4
4
 
5
5
  import { debug, getGitDiff, } from './Utils.mjs'
6
-
7
6
  import Config from './hook-and-release/index.mjs'
8
7
 
9
8
  const harConfig = await Config.create()
@@ -0,0 +1,5 @@
1
+ name: {{appChartName}}
2
+ version: 0.1.0
3
+ appVersion: v0.1.0
4
+ apiVersion: v2
5
+ icon: https://raw.githubusercontent.com/kubernetes/kubernetes/master/logo/logo.svg
@@ -0,0 +1,5 @@
1
+ -------------------------------------------------------------------------------
2
+
3
+ Deploying => {{ .Chart.Name }}
4
+
5
+ -------------------------------------------------------------------------------
@@ -0,0 +1,135 @@
1
+ {{/*
2
+ Expand the name of the chart.
3
+ */}}
4
+ {{- define "leverege.name" -}}
5
+ {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
6
+ {{- end }}
7
+
8
+ {{/*
9
+ Create a default fully qualified app name.
10
+ We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
11
+ If release name contains chart name it will be used as a full name.
12
+ */}}
13
+ {{- define "leverege.fullname" -}}
14
+ {{- if .Values.fullnameOverride }}
15
+ {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
16
+ {{- else }}
17
+ {{- $name := default .Chart.Name .Values.nameOverride }}
18
+ {{- if contains $name .Release.Name }}
19
+ {{- .Release.Name | trunc 63 | trimSuffix "-" }}
20
+ {{- else }}
21
+ {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
22
+ {{- end }}
23
+ {{- end }}
24
+ {{- end }}
25
+
26
+ {{/*
27
+ Create chart name and version as used by the chart label.
28
+ */}}
29
+ {{- define "leverege.chart" -}}
30
+ {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
31
+ {{- end }}
32
+
33
+ {{/*
34
+ Common labels
35
+ */}}
36
+ {{- define "leverege.labels" -}}
37
+ helm.sh/chart: {{ include "leverege.chart" . }}
38
+ {{ include "leverege.selectorLabels" . }}
39
+ {{- if .Chart.AppVersion }}
40
+ app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
41
+ {{- end }}
42
+ app.kubernetes.io/managed-by: {{ .Release.Service }}
43
+ {{- if .Values.partOf }}
44
+ app.kubernetes.io/part-of: {{ .Values.partOf }}
45
+ {{- end }}
46
+ {{- end }}
47
+
48
+ {{/*
49
+ Selector labels
50
+ */}}
51
+ {{- define "leverege.selectorLabels" -}}
52
+ app.kubernetes.io/name: {{ include "leverege.name" . }}
53
+ app.kubernetes.io/instance: {{ .Release.Name }}
54
+ {{- end }}
55
+
56
+ {{/*
57
+ Create the name of the service account to use
58
+ */}}
59
+ {{- define "leverege.serviceAccountName" -}}
60
+ {{- if .Values.serviceAccount.create }}
61
+ {{- default (include "leverege.fullname" .) .Values.serviceAccount.name }}
62
+ {{- else }}
63
+ {{- default "default" .Values.serviceAccount.name }}
64
+ {{- end }}
65
+ {{- end }}
66
+
67
+ {{/*
68
+ Define reusable container ports configuration for deployments.
69
+ */}}
70
+ {{- define "leverege.deploymentPorts" -}}
71
+ - name: http
72
+ containerPort: {{ .Values.config.HTTP_SERVER_PORT }}
73
+ protocol: TCP
74
+ - name: node-metrics
75
+ containerPort: {{ .Values.config.METRICS_PORT }}
76
+ protocol: TCP
77
+ {{- end }}
78
+
79
+ {{/*
80
+ Define reusable service ports configuration for services.
81
+ */}}
82
+ {{- define "leverege.servicePorts" -}}
83
+ - name: http
84
+ port: {{ .Values.config.HTTP_SERVER_PORT }}
85
+ targetPort: http
86
+ protocol: TCP
87
+ - name: node-metrics
88
+ port: {{ .Values.config.METRICS_PORT }}
89
+ targetPort: node-metrics
90
+ protocol: TCP
91
+ {{- end }}
92
+
93
+ {{/*
94
+ Define reusable service monitors for the prometheus operator.
95
+ */}}
96
+ {{- define "leverege.serviceMonitorEndpoints" -}}
97
+ - port: node-metrics
98
+ interval: {{ default "60s" .Values.serviceMonitor.interval }}
99
+ honorLabels: true # prom-operator config setting
100
+ relabelings:
101
+ - action: labelmap
102
+ regex: __meta_kubernetes_pod_label_(.+)
103
+ - action: labelmap
104
+ regex: __meta_kubernetes_service_label_(.+)
105
+ {{- end }}
106
+
107
+ {{/*
108
+ Reusable initContainers block, currently supports modelInit pattern.
109
+ */}}
110
+ {{- define "leverege.initContainers" -}}
111
+ {{- if .Values.modelInit.enabled }}
112
+ - name: {{ .Values.modelInit.name | default "fetch-models" }}
113
+ image: {{ .Values.modelInit.image }}
114
+ securityContext:
115
+ runAsUser: {{ .Values.modelInit.runAsUser }}
116
+ runAsGroup: {{ .Values.modelInit.runAsGroup }}
117
+ command: ["/bin/bash", "-c"]
118
+ args:
119
+ {{- if .Values.modelInit.args }}
120
+ {{- toYaml .Values.modelInit.args | nindent 4 }}
121
+ {{- else }}
122
+ - >-
123
+ exec > /proc/1/fd/1 2>&1; set -ex;
124
+ {{- range $name, $uri := .Values.modelInit.sources }}
125
+ echo "Syncing {{$name}} from {{$uri}}...";
126
+ mkdir -p {{ $.Values.modelInit.targetDir }}/{{$name}};
127
+ gsutil -m rsync -r {{$uri}} {{ $.Values.modelInit.targetDir }}/{{$name}};
128
+ {{- end }}
129
+ {{- end }}
130
+ volumeMounts:
131
+ - name: model-volume
132
+ mountPath: {{ .Values.modelInit.targetDir }}
133
+ {{- end }}
134
+ {{- end }}
135
+
@@ -0,0 +1,10 @@
1
+ apiVersion: v1
2
+ kind: ConfigMap
3
+ metadata:
4
+ name: {{ include "leverege.fullname" . }}-configs
5
+ labels:
6
+ {{- include "leverege.labels" . | nindent 4 }}
7
+ data:
8
+ {{- with .Values.config }}
9
+ {{- toYaml . | nindent 2 }}
10
+ {{- end }}
@@ -0,0 +1,125 @@
1
+ apiVersion: apps/v1
2
+ kind: Deployment
3
+ metadata:
4
+ name: {{ include "leverege.fullname" . }}
5
+ labels:
6
+ {{- include "leverege.labels" . | nindent 4 }}
7
+ app: {{ include "leverege.fullname" . }}
8
+ redis-client: {{ .Values.redis.enabled | quote }}
9
+ spec:
10
+ replicas: {{ default 1 .Values.staticscaling.replicas }}
11
+ selector:
12
+ matchLabels:
13
+ {{- include "leverege.selectorLabels" . | nindent 6 }}
14
+ template:
15
+ metadata:
16
+ labels:
17
+ {{- include "leverege.selectorLabels" . | nindent 8 }}
18
+ app: {{ include "leverege.fullname" . }}
19
+ redis-client: {{ .Values.redis.enabled | quote }}
20
+ annotations:
21
+ checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
22
+ prometheus.io/port: '{{ default "5111" .Values.config.METRICS_PORT }}'
23
+ prometheus.io/scrape: "true"
24
+ configmap.reloader.stakater.com/reload: "default-configs"
25
+ {{- if .Values.service.preemptible }}
26
+ cluster-autoscaler.kubernetes.io/safe-to-evict: "true"
27
+ {{- end }}
28
+ spec:
29
+ serviceAccountName: {{ include "leverege.fullname" . }}
30
+ volumes:
31
+ - name: tmpfs
32
+ emptyDir: {}
33
+ {{- if .Values.workloadIdentity.disabled }}
34
+ - name: google-cloud-key
35
+ secret:
36
+ secretName: {{ .Chart.Name }}-sa-key
37
+ {{- end }}
38
+ affinity:
39
+ podAntiAffinity:
40
+ preferredDuringSchedulingIgnoredDuringExecution:
41
+ - weight: 100
42
+ podAffinityTerm:
43
+ labelSelector:
44
+ matchExpressions:
45
+ - key: app.kubernetes.io/name
46
+ operator: In
47
+ values:
48
+ - {{ include "leverege.fullname" . }}
49
+ topologyKey: "kubernetes.io/hostname"
50
+ {{- if .Values.service.preemptible }}
51
+ nodeAffinity:
52
+ requiredDuringSchedulingIgnoredDuringExecution:
53
+ nodeSelectorTerms:
54
+ - matchExpressions:
55
+ - key: target-env
56
+ operator: In
57
+ values:
58
+ - preemptible
59
+ tolerations:
60
+ - key: "preemptible"
61
+ operator: "Equal"
62
+ value: "true"
63
+ effect: "NoSchedule"
64
+ {{- end }}
65
+ {{- if .Values.modelInit.enabled }}
66
+ initContainers:
67
+ - name: {{ default "fetch-models" .Values.modelInit.name }}
68
+ image: {{ .Values.modelInit.image }}
69
+ securityContext:
70
+ runAsUser: {{ .Values.modelInit.runAsUser }}
71
+ runAsGroup: {{ .Values.modelInit.runAsGroup }}
72
+ command: ["/bin/sh","-c"]
73
+ args:
74
+ {{- if .Values.modelInit.args }}
75
+ {{- toYaml .Values.modelInit.args | nindent 6 }}
76
+ {{- else }}
77
+ - |
78
+ exec > /proc/1/fd/1 2>&1 # Send both stdout and stderr to container's stdout
79
+ set -ex
80
+ {{- range $name, $uri := .Values.modelInit.sources }}
81
+ echo "Syncing {{$name}} from {{$uri}}..."
82
+ mkdir -p {{ $.Values.modelInit.targetDir }}/{{$name}}
83
+ gsutil -m rsync -r {{$uri}} {{ $.Values.modelInit.targetDir }}/{{$name}}
84
+ {{- end }}
85
+ {{- end }}
86
+ volumeMounts:
87
+ - name: model-volume
88
+ mountPath: {{ .Values.modelInit.targetDir }}
89
+ {{- end }}
90
+ containers:
91
+ - name: {{ include "leverege.fullname" . }}
92
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
93
+ image: {{ .Values.image.registry }}/{{ .Chart.Name }}:{{ default .Chart.AppVersion .Values.image.tag }}
94
+ securityContext:
95
+ readOnlyRootFilesystem: {{ .Values.securityContext.readOnlyRootFs }}
96
+ runAsNonRoot: true
97
+ runAsUser: 1000
98
+ allowPrivilegeEscalation: false
99
+ {{ if .Values.probes.enabled }}
100
+ livenessProbe:
101
+ {{- toYaml .Values.probes.livenessProbe | nindent 10 }}
102
+ readinessProbe:
103
+ {{- toYaml .Values.probes.readinessProbe | nindent 10 }}
104
+ {{- end }}
105
+ resources:
106
+ {{- toYaml .Values.resources | nindent 10 }}
107
+ ports:
108
+ {{- include "leverege.deploymentPorts" . | nindent 8 }}
109
+ volumeMounts:
110
+ - name: tmpfs
111
+ mountPath: "/tmp"
112
+ {{- if .Values.workloadIdentity.disabled }}
113
+ - name: google-cloud-key
114
+ mountPath: /var/secrets/google
115
+ {{- end }}
116
+ envFrom:
117
+ - configMapRef:
118
+ name: default-configs
119
+ - configMapRef:
120
+ name: {{ include "leverege.fullname" . }}-configs
121
+ env:
122
+ {{- if .Values.workloadIdentity.disabled }}
123
+ - name: GOOGLE_APPLICATION_CREDENTIALS
124
+ value: /var/secrets/google/key.json
125
+ {{- end }}
@@ -0,0 +1,26 @@
1
+ {{- if .Values.autoscaling.enabled }}
2
+ {{ if lt .Capabilities.KubeVersion.Minor "23" }}
3
+ apiVersion: autoscaling/v2beta2
4
+ {{ else }}
5
+ apiVersion: autoscaling/v2
6
+ {{ end }}
7
+ kind: HorizontalPodAutoscaler
8
+ metadata:
9
+ name: {{ include "leverege.fullname" . }}
10
+ labels:
11
+ {{- include "leverege.labels" . | nindent 4 }}
12
+ spec:
13
+ scaleTargetRef:
14
+ apiVersion: apps/v1
15
+ kind: Deployment
16
+ name: {{ include "leverege.fullname" . }}
17
+ minReplicas: {{ .Values.autoscaling.minReplicas }}
18
+ maxReplicas: {{ .Values.autoscaling.maxReplicas }}
19
+ metrics: # https://cloud.google.com/kubernetes-engine/docs/how-to/horizontal-pod-autoscaling#multiple-metrics
20
+ - type: Resource
21
+ resource:
22
+ name: cpu
23
+ target:
24
+ type: Utilization
25
+ averageUtilization: {{ .Values.autoscaling.averageCPU }}
26
+ {{- end }}
@@ -0,0 +1,18 @@
1
+ {{- if .Values.ingressRoute.host }}
2
+ {{- $fullName := include "leverege.fullname" . -}}
3
+ {{- $svcPort := .Values.config.HTTP_SERVER_PORT -}}
4
+ apiVersion: traefik.io/v1alpha1
5
+ kind: IngressRoute
6
+ metadata:
7
+ name: {{ $fullName }}
8
+ namespace: default
9
+ spec:
10
+ entryPoints:
11
+ - websecure
12
+ routes:
13
+ - match: Host(`{{ .Values.ingressRoute.host }}`)
14
+ kind: Rule
15
+ services:
16
+ - name: {{ $fullName }}
17
+ port: {{ $svcPort }}
18
+ {{- end }}
@@ -0,0 +1,22 @@
1
+ {{- if .Values.pdb.create }}
2
+ {{ if lt .Capabilities.KubeVersion.Minor "21" }}
3
+ apiVersion: policy/v1beta1
4
+ {{ else }}
5
+ apiVersion: policy/v1
6
+ {{ end }}
7
+ kind: PodDisruptionBudget
8
+ metadata:
9
+ name: {{ include "leverege.fullname" . }}
10
+ labels:
11
+ {{- include "leverege.labels" . | nindent 4 }}
12
+ spec:
13
+ {{- if .Values.pdb.minAvailable }}
14
+ minAvailable: {{ .Values.pdb.minAvailable }}
15
+ {{- end }}
16
+ {{- if .Values.pdb.maxUnavailable }}
17
+ maxUnavailable: {{ .Values.pdb.maxUnavailable }}
18
+ {{- end }}
19
+ selector:
20
+ matchLabels:
21
+ {{ include "leverege.selectorLabels" . | nindent 6 }}
22
+ {{- end }}
@@ -0,0 +1,15 @@
1
+ apiVersion: v1
2
+ kind: Service
3
+ metadata:
4
+ name: {{ include "leverege.fullname" . }}
5
+ labels:
6
+ {{- include "leverege.labels" . | nindent 4 }}
7
+ spec:
8
+ type: {{ .Values.service.type }}
9
+ {{- if .Values.loadbalancer.ip }}
10
+ loadBalancerIP: {{ .Values.loadbalancer.ip }}
11
+ {{- end }}
12
+ ports:
13
+ {{- include "leverege.servicePorts" . | nindent 6 }}
14
+ selector:
15
+ {{- include "leverege.selectorLabels" . | nindent 4 }}
@@ -0,0 +1,13 @@
1
+ {{- if .Values.serviceAccount.create -}}
2
+ apiVersion: v1
3
+ kind: ServiceAccount
4
+ metadata:
5
+ name: {{ include "leverege.serviceAccountName" . }}
6
+ labels:
7
+ {{- include "leverege.labels" . | nindent 4 }}
8
+ annotations:
9
+ iam.gke.io/gcp-service-account: {{ .Chart.Name }}@{{ .Values.service.project_id }}.iam.gserviceaccount.com
10
+ {{- with .Values.serviceAccount.annotations }}
11
+ {{- toYaml . | nindent 4 }}
12
+ {{- end }}
13
+ {{- end }}
@@ -0,0 +1,23 @@
1
+ # plugs us into the prometheus operator
2
+ {{- if .Values.serviceMonitor.enabled }}
3
+ apiVersion: monitoring.coreos.com/v1
4
+ kind: ServiceMonitor
5
+ metadata:
6
+ {{- if .Values.partOf }}
7
+ name: {{ .Values.partOf }}-{{ include "leverege.fullname" . }}
8
+ {{ else }}
9
+ name: {{ include "leverege.fullname" . }}
10
+ {{- end }}
11
+ labels:
12
+ {{- include "leverege.labels" . | nindent 4 }}
13
+ namespace: prometheus
14
+ spec:
15
+ selector:
16
+ matchLabels:
17
+ {{ include "leverege.selectorLabels" . | nindent 6 }}
18
+ namespaceSelector:
19
+ matchNames:
20
+ - {{ default "default" .Values.serviceMonitor.namespace }}
21
+ endpoints:
22
+ {{- include "leverege.serviceMonitorEndpoints" . | nindent 4 }}
23
+ {{- end }}
@@ -0,0 +1,152 @@
1
+ # Default values for the Chart.
2
+ # This is a YAML-formatted file.
3
+ # Declare variables to be passed into your templates.
4
+ image:
5
+ pullPolicy: IfNotPresent
6
+ # Replace <FOLDER> with the artifact-registry folder for this image
7
+ registry: us-docker.pkg.dev/leverege-registry/<FOLDER>/images
8
+ # Overrides the image tag whose default is the chart appVersion.
9
+ tag: ""
10
+
11
+ # define all config values as quoted strings
12
+ config:
13
+
14
+ # node options see nodejs docs section on Command-line options
15
+ # example => "--max-old-space-size=400"
16
+ NODE_OPTIONS: ""
17
+
18
+ # server configs
19
+ LOG_CONFIG: '{"type":"pino","level":"warn"}'
20
+ HTTP_SERVER_PORT: "8080"
21
+ METRICS_PORT: "5111"
22
+
23
+ # imagine configs
24
+ IMAGINE_API_URL : "http://api-server:8181"
25
+
26
+ # INTERNAL_PORT: '8998'
27
+ # INTERNAL_CORS_ORIGIN: '*'
28
+
29
+ nameOverride: ""
30
+ fullnameOverride: ""
31
+
32
+ # When multiple charts or pieces of software are used together to make one
33
+ # application. For example, application software and a database to produce
34
+ # a website. This can be set to the top level application being supported.
35
+ partOf: # leverege-stack or project-x - OPTIONAL
36
+
37
+ # The project_id, host and ingress will be auto injected by overwhelm. The
38
+ # service port definition will use config.HTTP_SERVER_PORT for listening to
39
+ # health checks and any other routes associated with the default setup.
40
+ service:
41
+ # port: see config.HTTP_SERVER_PORT
42
+ preemptible: true
43
+ type: ClusterIP
44
+
45
+ serviceAccount:
46
+ # Specifies whether a service account should be created
47
+ create: true
48
+ # Annotations to add to the service account
49
+ annotations: {}
50
+ # The name of the service account to use.
51
+ # If not set and create is true, a name is generated using the fullname template
52
+ name: ""
53
+
54
+ # enable the service monitor for providing metrics to the prometheus operator
55
+ serviceMonitor:
56
+ enabled: false
57
+ interval: "60s"
58
+ namespace: "default"
59
+
60
+ # typically handled by traefik, but not always
61
+ ingressRoute:
62
+ host: "" # set-me-in-values-local
63
+
64
+ # can be used to set load balancer to registered static IP
65
+ loadbalancer:
66
+ ip: {}
67
+
68
+ # liveness and readiness probe to prove k8s health
69
+ probes:
70
+ enabled: true
71
+ livenessProbe:
72
+ httpGet:
73
+ path: /livenessProbe
74
+ port: http
75
+ initialDelaySeconds: 30
76
+ periodSeconds: 60
77
+ readinessProbe:
78
+ httpGet:
79
+ path: /healthz
80
+ port: http
81
+ initialDelaySeconds: 30
82
+ periodSeconds: 10
83
+
84
+ # this tells calico that redis access is needed
85
+ redis:
86
+ enabled: true
87
+
88
+ # setting to false will allow pod disk to mount read/write
89
+ # setting this to false should only be done for debugging
90
+ securityContext:
91
+ readOnlyRootFs: true
92
+
93
+ resources:
94
+ # We usually recommend not to specify default resources and to leave this as a conscious
95
+ # choice for the user. This also increases chances charts run on environments with little
96
+ # resources, such as Minikube. If you do want to specify resources, uncomment the following
97
+ # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
98
+ # limits:
99
+ # cpu: 100m
100
+ # memory: 512Mi
101
+ requests:
102
+ cpu: 150m
103
+ memory: 256Mi
104
+
105
+ # use auto scaling for dynamically sized workloads
106
+ autoscaling:
107
+ enabled: true # set to false for static scaling
108
+ minReplicas: 2
109
+ maxReplicas: 8
110
+ averageCPU: 75
111
+
112
+ # use static scaling for fixed size workloads
113
+ staticscaling:
114
+ replicas: 1 # only relevant when autoscaling is disabled
115
+
116
+ pdb:
117
+ # Specifies whether a PodDisruptionBudget should be created
118
+ create: true
119
+ # Min number of pods that must still be available after the eviction
120
+ minAvailable: 1
121
+ # Max number of pods that can be unavailable after the eviction
122
+ maxUnavailable: ""
123
+
124
+ # Uses an initContainer to build models volume from GCS (tailorable)
125
+ modelInit:
126
+ enabled: true
127
+ # If 'args' is omitted, a default block that loops over 'sources' is used
128
+ # args:
129
+ # - |
130
+ # set -ex
131
+ # echo "Custom model fetch logic here..."
132
+
133
+ # Default model sync behavior (only used if args is omitted)
134
+ sources:
135
+ sam: gs://leverege-registry-ml-models/sam
136
+ yolo: gs://leverege-registry-ml-models/yolo
137
+ targetDir: /usr/src/app/models
138
+
139
+ # Optional defaults for the initContainer specification
140
+ image: gcr.io/google.com/cloudsdktool/cloud-sdk:slim
141
+ runAsUser: 1000
142
+ runAsGroup: 1000
143
+
144
+ affinity: {}
145
+
146
+ nodeSelector: {}
147
+
148
+ podAnnotations: {}
149
+
150
+ tolerations: []
151
+
152
+ workloadIdentity: {}
package/src/k8x.sh CHANGED
@@ -63,6 +63,10 @@ K8X_HELP
63
63
  FZFQ="--query=redis" && cmd='redis-cli'
64
64
  ;;
65
65
 
66
+ "valkey"|"valkey-cli")
67
+ FZFQ="--query=valkey" && cmd='valkey-cli'
68
+ ;;
69
+
66
70
  *)
67
71
  FZFQ="--query=$cmd" && cmd='bash'
68
72
  ;;
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { Command } from 'commander'
4
+
4
5
  import { shellCmd, log, warning, errorExit } from './Utils.mjs'
5
6
 
6
7
  const program = new Command()