@toa.io/operations 1.0.0-alpha.2 → 1.0.0-alpha.200

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toa.io/operations",
3
- "version": "1.0.0-alpha.2",
3
+ "version": "1.0.0-alpha.200",
4
4
  "description": "Toa Deployment",
5
5
  "homepage": "https://toa.io",
6
6
  "author": {
@@ -16,23 +16,23 @@
16
16
  "url": "https://github.com/toa-io/toa/issues"
17
17
  },
18
18
  "engines": {
19
- "node": ">= 18.0.0"
19
+ "node": ">= 20.0.0"
20
20
  },
21
21
  "publishConfig": {
22
22
  "access": "public"
23
23
  },
24
24
  "main": "src/index.js",
25
- "types": "types/index.d.ts",
25
+ "types": "types/index.ts",
26
26
  "scripts": {
27
27
  "test": "echo \"Error: run tests from root\" && exit 1"
28
28
  },
29
29
  "dependencies": {
30
- "@toa.io/filesystem": "1.0.0-alpha.2",
31
- "@toa.io/generic": "1.0.0-alpha.2",
32
- "@toa.io/norm": "1.0.0-alpha.2",
33
- "@toa.io/yaml": "1.0.0-alpha.2",
30
+ "@toa.io/filesystem": "1.0.0-alpha.173",
31
+ "@toa.io/generic": "1.0.0-alpha.173",
32
+ "@toa.io/norm": "1.0.0-alpha.200",
33
+ "@toa.io/yaml": "1.0.0-alpha.182",
34
34
  "execa": "5.1.1",
35
35
  "fs-extra": "11.1.1"
36
36
  },
37
- "gitHead": "7688e6e980a65c82ac2e459be4e355eebf406cd0"
37
+ "gitHead": "35b4adeedae2e9450ef44a74f42a53eff20ee203"
38
38
  }
@@ -1,10 +1,12 @@
1
1
  'use strict'
2
2
 
3
3
  const { addVariables } = require('./variables')
4
+ const { addMounts } = require('./mounts')
4
5
 
5
- function compositions (compositions, variables) {
6
+ function compositions (compositions, dependency) {
6
7
  for (const composition of compositions) {
7
- addVariables(composition, variables)
8
+ addVariables(composition, dependency.variables)
9
+ addMounts(composition, dependency.mounts)
8
10
  }
9
11
  }
10
12
 
@@ -0,0 +1,24 @@
1
+ 'use strict'
2
+
3
+ function addMounts (composition, mounts) {
4
+ if (mounts === undefined)
5
+ return
6
+
7
+ const used = new Set()
8
+
9
+ for (const [key, mount] of Object.entries(mounts)) {
10
+ if (key !== 'global' && !composition.components?.includes(key))
11
+ continue
12
+
13
+ for (const { name, path, claim } of mount) {
14
+ if (used.has(name))
15
+ continue
16
+
17
+ composition.mounts ??= []
18
+ composition.mounts.push({ name, path, claim })
19
+ used.add(name)
20
+ }
21
+ }
22
+ }
23
+
24
+ exports.addMounts = addMounts
@@ -1,17 +1,18 @@
1
1
  'use strict'
2
2
 
3
- function addVariables (deployment, variables) {
3
+ function addVariables (composition, variables) {
4
4
  const used = new Set()
5
5
 
6
- deployment.variables ??= []
6
+ composition.variables ??= []
7
7
 
8
8
  for (const [key, set] of Object.entries(variables)) {
9
- if (key !== 'global' && !deployment.components?.includes(key)) continue
9
+ if (key !== 'global' && !composition.components?.includes(key))
10
+ continue
10
11
 
11
12
  for (const variable of set) {
12
13
  if (used.has(variable.name)) continue
13
14
 
14
- deployment.variables.push(variable)
15
+ composition.variables.push(variable)
15
16
  used.add(variable.name)
16
17
  }
17
18
  }
@@ -1,24 +1,33 @@
1
1
  'use strict'
2
2
 
3
- const get = require('./.describe')
3
+ const desc = require('./.describe')
4
4
 
5
5
  const describe = (context, compositions, dependency) => {
6
6
  const { services } = dependency
7
7
 
8
8
  dependency.variables.global ??= []
9
- dependency.variables.global.unshift({ name: 'TOA_ENV', value: context.environment })
10
9
 
11
- const components = get.components(compositions)
10
+ dependency.variables.global.unshift(
11
+ {
12
+ name: 'TOA_CONTEXT',
13
+ value: context.name
14
+ }, {
15
+ name: 'TOA_ENV',
16
+ value: context.environment
17
+ }
18
+ )
19
+
20
+ const components = desc.components(compositions)
12
21
  const credentials = context.registry?.credentials
13
22
 
14
- get.compositions(compositions, dependency.variables, context.environment)
15
- get.services(services, dependency.variables)
23
+ desc.compositions(compositions, dependency)
24
+ desc.services(services, dependency.variables)
16
25
 
17
26
  return {
18
27
  compositions,
19
28
  components,
20
29
  services,
21
- credentials,
30
+ credentials
22
31
  }
23
32
  }
24
33
 
@@ -13,14 +13,17 @@ const merge = (dependencies) => {
13
13
  /** @type {toa.deployment.dependency.Variables} */
14
14
  const variables = {}
15
15
 
16
+ const mounts = {}
17
+
16
18
  for (const dependency of dependencies) {
17
19
  if (dependency.references !== undefined) references.push(...dependency.references)
18
20
  if (dependency.services !== undefined) services.push(...dependency.services)
19
21
  if (dependency.proxies !== undefined) proxies.push(...dependency.proxies)
20
22
  if (dependency.variables !== undefined) append(variables, dependency.variables)
23
+ if (dependency.mounts !== undefined) append(mounts, dependency.mounts)
21
24
  }
22
25
 
23
- return { references, services, proxies, variables }
26
+ return { references, services, proxies, variables, mounts }
24
27
  }
25
28
 
26
29
  const append = (merged, variables) => {
@@ -19,15 +19,49 @@ spec:
19
19
  containers:
20
20
  - name: {{ .name }}
21
21
  image: {{ .image }}
22
+ {{- if .resources }}
23
+ resources:
24
+ {{- if or .resources.cpu .resources.memory }}
25
+ requests:
26
+ {{- if .resources.cpu }}
27
+ cpu: {{ index .resources.cpu 0 }}
28
+ {{- end }}
29
+ {{- if .resources.memory }}
30
+ memory: {{ index .resources.memory 0 }}
31
+ {{- end }}
32
+ limits:
33
+ {{- if .resources.cpu }}
34
+ cpu: {{ index .resources.cpu 1 }}
35
+ {{- end }}
36
+ {{- if .resources.memory }}
37
+ memory: {{ index .resources.memory 1 }}
38
+ {{- end }}
39
+ {{- end }}
40
+ {{- end }}
22
41
  {{- if .variables }}
23
42
  env:
24
43
  {{- range .variables }}
25
44
  {{- include "env.var" . | indent 12 }}
26
45
  {{- end }}
27
46
  {{- end }}
47
+ {{- if .mounts }}
48
+ volumeMounts:
49
+ {{- range .mounts }}
50
+ - name: {{ .name }}
51
+ mountPath: {{ .path }}
52
+ {{- end }}
53
+ {{- end }}
28
54
  {{- if $.Values.credentials }}
29
55
  imagePullSecrets:
30
56
  - name: {{ $.Values.credentials }}
31
57
  {{- end }}
58
+ {{- if .mounts }}
59
+ volumes:
60
+ {{- range .mounts }}
61
+ - name: {{ .name }}
62
+ persistentVolumeClaim:
63
+ claimName: {{ .claim }}
64
+ {{- end }}
65
+ {{- end }}
32
66
  ---
33
67
  {{- end }}
@@ -16,12 +16,41 @@ spec:
16
16
  containers:
17
17
  - name: extension-{{ .name }}
18
18
  image: {{ .image }}
19
+ {{- if .resources }}
20
+ resources:
21
+ {{- if or .resources.cpu .resources.memory }}
22
+ requests:
23
+ {{- if .resources.cpu }}
24
+ cpu: {{ index .resources.cpu 0 }}
25
+ {{- end }}
26
+ {{- if .resources.memory }}
27
+ memory: {{ index .resources.memory 0 }}
28
+ {{- end }}
29
+ limits:
30
+ {{- if .resources.cpu }}
31
+ cpu: {{ index .resources.cpu 1 }}
32
+ {{- end }}
33
+ {{- if .resources.memory }}
34
+ memory: {{ index .resources.memory 1 }}
35
+ {{- end }}
36
+ {{- end }}
37
+ {{- end }}
19
38
  {{- if .variables }}
20
39
  env:
21
40
  {{- range .variables }}
22
41
  {{- include "env.var" . | indent 12 }}
23
42
  {{- end }}
24
43
  {{- end }}
44
+ {{- if .probe }}
45
+ readinessProbe:
46
+ httpGet:
47
+ path: {{ .probe.path }}
48
+ port: {{ .probe.port }}
49
+ {{- if .probe.delay }}
50
+ initialDelaySeconds: {{ .probe.delay }}
51
+ {{- end }}
52
+ {{- end }}
53
+ {{- if .port }}
25
54
  ---
26
55
  apiVersion: v1
27
56
  kind: Service
@@ -36,8 +65,10 @@ spec:
36
65
  protocol: TCP
37
66
  port: {{ .port }}
38
67
  targetPort: {{ .port }}
39
- ---
68
+ {{- end }}
40
69
  {{- if .ingress }}
70
+ {{- $service := .name }}
71
+ ---
41
72
  apiVersion: networking.k8s.io/v1
42
73
  kind: Ingress
43
74
  metadata:
@@ -51,15 +82,29 @@ spec:
51
82
  ingressClassName: {{ .ingress.class }}
52
83
  {{- end }}
53
84
  rules:
54
- - host: {{ required "ingress.host is required" .ingress.host }}
85
+ {{- range .ingress.hosts }}
86
+ - host: {{ . }}
55
87
  http:
56
88
  paths:
57
89
  - path: /
58
90
  pathType: Prefix
59
91
  backend:
60
92
  service:
61
- name: extension-{{ .name }}
93
+ name: extension-{{ $service }}
62
94
  port:
63
95
  number: 8000
96
+ {{- end }}
97
+ {{- if .ingress.default }}
98
+ - http:
99
+ paths:
100
+ - path: /
101
+ pathType: Prefix
102
+ backend:
103
+ service:
104
+ name: extension-{{ $service }}
105
+ port:
106
+ number: 8000
107
+ {{- end }}
64
108
  {{- end }}
109
+ ---
65
110
  {{- end }}
@@ -3,9 +3,16 @@ compositions:
3
3
  - name: todos
4
4
  image: localhost:5000/composition-todos:0.0.0
5
5
  replicas: 2
6
+ mounts:
7
+ - name: mount-name
8
+ path: /storage
9
+ claim: storage-pvc
6
10
  components:
7
11
  - todos-tasks
8
12
  - todos-stats
13
+ resources:
14
+ cpu: [100m, 1]
15
+ memory: [100Mi, 1Gi]
9
16
  variables:
10
17
  - name: TOA_CONFIGURATION_TODOS_TASKS
11
18
  value: foo
@@ -18,7 +25,6 @@ compositions:
18
25
  replicas: 3
19
26
  components:
20
27
  - users-users
21
- # TODO: create component services only if sync binding is being used
22
28
  components:
23
29
  - todos-tasks
24
30
  - todos-stats
@@ -28,8 +34,12 @@ services:
28
34
  image: localhost:5000/resources-gateway:0.0.0
29
35
  port: 8000
30
36
  replicas: 2
37
+ resources:
38
+ cpu: [100m, 1]
39
+ memory: [100Mi, 1Gi]
31
40
  ingress:
32
- host: dummies.toa.io
41
+ default: true
42
+ hosts: [dummies.toa.io]
33
43
  class: alb
34
44
  annotations:
35
45
  alb.ingress.kubernetes.io/scheme: internet-facing
@@ -41,6 +51,11 @@ services:
41
51
  secret:
42
52
  name: secret-name
43
53
  key: secret-key
54
+ probe:
55
+ port: 8000
56
+ path: /.ready
57
+ delay: 1
58
+
44
59
  proxies:
45
60
  - name: storage-proxy
46
61
  target: host.docker.internal
@@ -10,6 +10,7 @@ class Composition {
10
10
  this.name = composition.name
11
11
  this.image = image.reference
12
12
  this.components = composition.components.map(component)
13
+ this.resources = composition.resources
13
14
  }
14
15
  }
15
16
 
@@ -42,6 +42,7 @@ class Deployment {
42
42
 
43
43
  if (options.namespace !== undefined) args.push('-n', options.namespace)
44
44
  if (options.wait === true) args.push('--wait')
45
+ if (options.timeout !== undefined) args.push('--timeout', options.timeout)
45
46
 
46
47
  await this.#process.execute('helm', ['dependency', 'update', this.#target])
47
48
  await this.#process.execute('helm', ['upgrade', this.#chart.name, '-i', ...args, this.#target])
@@ -15,7 +15,6 @@ class Factory {
15
15
  #dependencies
16
16
  #registry
17
17
  #process
18
- #extensionComponents = []
19
18
 
20
19
  constructor (context) {
21
20
  this.#context = context
@@ -1,10 +1,11 @@
1
1
  'use strict'
2
2
 
3
3
  const { join } = require('node:path')
4
- const { hash } = require('@toa.io/generic')
5
4
  const fs = require('fs-extra')
5
+ const { createHash } = require('node:crypto')
6
6
 
7
7
  const { Image } = require('./image')
8
+ const { undef } = require('@toa.io/concise/source/expressions/undefined')
8
9
 
9
10
  class Composition extends Image {
10
11
  dockerfile = join(__dirname, 'composition.Dockerfile')
@@ -26,27 +27,43 @@ class Composition extends Image {
26
27
  }
27
28
 
28
29
  get version () {
29
- const tags = this.#components.map((component) => component.locator.id + ':' + component.version)
30
+ const hash = createHash('sha256')
30
31
 
31
- return hash(tags.join(';'))
32
+ for (const component of this.#components) {
33
+ hash.update(component.locator.id)
34
+ hash.update(component.version)
35
+ }
36
+
37
+ return hash.digest('hex').slice(0, 8)
32
38
  }
33
39
 
34
40
  get base () {
35
- if (this.#image !== undefined)
36
- return this.#image
37
-
38
- let image = null
41
+ let image = this.#image
39
42
 
40
43
  for (const component of this.#components) {
41
44
  const value = component.build?.image
42
45
 
43
- if (image !== null && image !== value)
46
+ if (image !== null && image !== value) {
44
47
  throw new Error(`Composition '${this.#name}' requires different base images for its components. Specify base image for the composition in the context.`)
48
+ }
45
49
 
46
50
  image = value
47
51
  }
48
52
 
49
- return image ?? undefined
53
+ return image
54
+ }
55
+
56
+ get run () {
57
+ const commands = []
58
+
59
+ for (const component of this.#components) {
60
+ const run = component.build?.run
61
+
62
+ if (run !== undefined)
63
+ commands.push(run)
64
+ }
65
+
66
+ return commands.join('\n')
50
67
  }
51
68
 
52
69
  async prepare (root) {
@@ -3,9 +3,6 @@
3
3
  const { Composition } = require('./composition')
4
4
  const { Service } = require('./service')
5
5
 
6
- /**
7
- * @implements {toa.deployment.images.Factory}
8
- */
9
6
  class Factory {
10
7
  /** @type {string} */
11
8
  #scope
@@ -2,9 +2,8 @@
2
2
 
3
3
  const { Image } = require('./image')
4
4
  const { generate } = require('randomstring')
5
- const { hash } = require('@toa.io/generic')
6
5
 
7
- const version = generate()
6
+ const version = '168b04ff'
8
7
  const name = generate()
9
8
 
10
9
  /**
@@ -22,17 +21,17 @@ class Class extends Image {
22
21
 
23
22
  /** @type {toa.norm.context.Runtime} */
24
23
  const runtime = {
25
- version: generate()
24
+ version: '0.0.0'
26
25
  }
27
26
 
28
27
  /** @type {toa.norm.context.Registry} */
29
28
  const registry = {
30
- base: generate()
29
+ base: 'node:alpine'
31
30
  }
32
31
 
33
32
  exports.scope = generate()
34
33
  exports.name = name
35
- exports.version = hash(runtime.version + ';' + version)
34
+ exports.version = 'ba2409fc'
36
35
  exports.Class = Class
37
36
  exports.runtime = runtime
38
37
  exports.registry = registry
@@ -1,10 +1,17 @@
1
1
  'use strict'
2
2
 
3
- const { join, posix } = require('node:path')
4
- const { readFile: read, writeFile: write } = require('node:fs/promises')
5
-
6
- const { hash, overwrite } = require('@toa.io/generic')
7
- const fs = require('fs-extra')
3
+ const {
4
+ join,
5
+ posix
6
+ } = require('node:path')
7
+ const {
8
+ readFile: read,
9
+ writeFile: write
10
+ } = require('node:fs/promises')
11
+ const { createHash } = require('node:crypto')
12
+
13
+ const { overwrite } = require('@toa.io/generic')
14
+ const { mkdir } = require('node:fs/promises')
8
15
 
9
16
  /**
10
17
  * @implements {toa.deployment.images.Image}
@@ -20,7 +27,7 @@ class Image {
20
27
  #runtime
21
28
  #values = {
22
29
  build: {
23
- image: 'node:20.9.0-alpine3.18'
30
+ image: 'node:24.12.0-alpine3.22'
24
31
  }
25
32
  }
26
33
 
@@ -31,7 +38,12 @@ class Image {
31
38
  }
32
39
 
33
40
  tag () {
34
- const tag = hash(this.#runtime?.version + ';' + this.version)
41
+ const hash = createHash('sha256')
42
+
43
+ hash.update(this.#runtime.version)
44
+ hash.update(this.version)
45
+
46
+ const tag = hash.digest('hex').slice(0, 8)
35
47
 
36
48
  this.reference = posix.join(this.#registry.base ?? '', this.#scope, `${this.name}:${tag}`)
37
49
  }
@@ -42,6 +54,8 @@ class Image {
42
54
 
43
55
  get base () {}
44
56
 
57
+ get run () {}
58
+
45
59
  async prepare (root) {
46
60
  if (this.dockerfile === undefined) throw new Error('Dockerfile isn\'t specified')
47
61
 
@@ -49,11 +63,11 @@ class Image {
49
63
 
50
64
  const path = join(root, `${this.name}.${this.version}`)
51
65
 
52
- await fs.ensureDir(path)
66
+ await mkdir(path, { recursive: true })
53
67
 
54
68
  const template = await read(this.dockerfile, 'utf-8')
55
69
  const contents = template.replace(/{{(\S{1,32})}}/g, (_, key) => this.#value(key))
56
- const ignore = 'Dockerfile'
70
+ const ignore = ['Dockerfile', '**/node_modules'].join('\r\n')
57
71
 
58
72
  await write(join(path, 'Dockerfile'), contents)
59
73
  await write(join(path, '.dockerignore'), ignore)
@@ -72,6 +86,11 @@ class Image {
72
86
  if (image !== undefined)
73
87
  this.#values.build.image = image
74
88
 
89
+ const run = this.run
90
+
91
+ if (run !== undefined)
92
+ this.#values.build.run = (this.#values.build.run === undefined ? '' : this.#values.build.run + '\n') + run
93
+
75
94
  if (this.#values.build.arguments !== undefined) this.#values.build.arguments = createArguments(this.#values.build.arguments)
76
95
  if (this.#values.build.run !== undefined) this.#values.build.run = createRunCommands(this.#values.build.run)
77
96
  }
@@ -1,4 +1,4 @@
1
- FROM node:20.9.0-alpine3.18
1
+ FROM {{build.image}}
2
2
 
3
3
  ENV NODE_ENV=production
4
4
  RUN if [ "{{runtime.registry}}" != "" ]; then npm set registry {{runtime.registry}}; fi
@@ -50,6 +50,10 @@ class Operator {
50
50
  variables () {
51
51
  return this.#deployment.variables()
52
52
  }
53
+
54
+ tags () {
55
+ return this.#registry.tags()
56
+ }
53
57
  }
54
58
 
55
59
  /** @type {toa.deployment.installation.Options} */
@@ -1,6 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  const workspace = require('./workspace')
4
+ const { newid } = require('@toa.io/generic')
4
5
 
5
6
  /**
6
7
  * @implements {toa.deployment.Registry}
@@ -39,7 +40,9 @@ class Registry {
39
40
  async build () {
40
41
  await this.prepare()
41
42
 
42
- for (const image of this.#images) await this.#build(image)
43
+ for (const image of this.#images) {
44
+ await this.#build(image)
45
+ }
43
46
  }
44
47
 
45
48
  async push () {
@@ -48,6 +51,10 @@ class Registry {
48
51
  for (const image of this.#images) await this.#push(image)
49
52
  }
50
53
 
54
+ tags () {
55
+ return this.#images.map((image) => image.reference)
56
+ }
57
+
51
58
  /**
52
59
  * @param {'composition' | 'service'} type
53
60
  * @param {...any} args
@@ -67,9 +74,18 @@ class Registry {
67
74
  * @returns {Promise<void>}
68
75
  */
69
76
  async #build (image, push = false) {
77
+ if (await this.exists(image.reference)) {
78
+ console.log('Image already exists, skipping:', image.reference)
79
+ return
80
+ }
81
+
70
82
  const args = ['--context=default', 'buildx', 'build']
71
83
 
72
- if (push) args.push('--push')
84
+ if (push) {
85
+ args.push('--push')
86
+ } else {
87
+ args.push('--load')
88
+ }
73
89
 
74
90
  args.push('--tag', image.reference, image.context)
75
91
 
@@ -81,12 +97,13 @@ class Registry {
81
97
 
82
98
  if (multiarch) {
83
99
  const platform = this.#registry.platforms.join(',')
100
+ const builder = await this.#createBuilder()
84
101
 
85
102
  args.push('--platform', platform)
86
- args.push('--builder', BUILDER)
87
-
88
- await this.#ensureBuilder()
89
- } else args.push('--builder', 'default')
103
+ args.push('--builder', builder)
104
+ } else {
105
+ args.push('--builder', 'default')
106
+ }
90
107
 
91
108
  args.push('--progress', 'plain')
92
109
 
@@ -97,20 +114,27 @@ class Registry {
97
114
  await this.#build(image, true)
98
115
  }
99
116
 
100
- async #ensureBuilder () {
101
- const ls = 'buildx ls'.split(' ')
102
- const output = await this.#process.execute('docker', ls, { silently: true })
103
- const exists = output.split('\n').findIndex((line) => line.startsWith('toa '))
117
+ async exists (tag) {
118
+ const args = ['manifest', 'inspect', tag]
119
+
120
+ try {
121
+ await this.#process.execute('docker', args, { silently: true })
122
+ } catch (error) {
123
+ console.log(error.message)
104
124
 
105
- if (exists === -1) await this.#createBuilder()
125
+ return false
126
+ }
127
+
128
+ return true
106
129
  }
107
130
 
108
131
  async #createBuilder () {
109
- const create = `buildx create --name ${BUILDER} --use`.split(' ')
110
- const bootstrap = 'buildx inspect --bootstrap'.split(' ')
132
+ const name = `toa-${newid()}`
133
+ const create = `buildx create --name ${name} --bootstrap --use`.split(' ')
111
134
 
112
135
  await this.#process.execute('docker', create)
113
- await this.#process.execute('docker', bootstrap)
136
+
137
+ return name
114
138
  }
115
139
  }
116
140
 
@@ -4,9 +4,11 @@ declare namespace toa.deployment.images {
4
4
  readonly reference: string
5
5
  readonly context: string
6
6
 
7
- tag(): void
7
+ name: string
8
8
 
9
- prepare(root: string): Promise<string>
9
+ tag (): void
10
+
11
+ prepare (root: string): Promise<string>
10
12
  }
11
13
 
12
14
  }
@@ -1,19 +1,21 @@
1
1
  import type * as _norm from '@toa.io/norm/types'
2
2
  import type * as _dependency from './dependency'
3
- import type * as _image from "./images/image"
3
+ import type * as _image from './images/image'
4
4
 
5
5
  declare namespace toa.deployment {
6
-
6
+
7
7
  interface Registry {
8
- composition(composition: _norm.Composition): _image.Image
8
+ composition (composition: _norm.Composition): _image.Image
9
+
10
+ service (path: string, service: _dependency.Service): _image.Image
9
11
 
10
- service(path: string, service: _dependency.Service): _image.Image
12
+ prepare (path: string): Promise<string>
11
13
 
12
- prepare(path: string): Promise<string>
14
+ build (): Promise<void>
13
15
 
14
- build(): Promise<void>
16
+ push (): Promise<void>
15
17
 
16
- push(): Promise<void>
18
+ tags (): string[]
17
19
  }
18
20
 
19
21
  }
@@ -0,0 +1,65 @@
1
+ import type { Manifest } from '@toa.io/norm'
2
+ import type { Locator } from '@toa.io/core'
3
+
4
+ export interface Service {
5
+ group: string
6
+ name: string
7
+ version: string
8
+ port?: number
9
+ ingress?: Ingress
10
+ resources?: Resources
11
+ variables?: Variable[]
12
+ components?: string[]
13
+ probe?: Probe
14
+ }
15
+
16
+ export interface Variable {
17
+ name: string
18
+ value?: string
19
+ secret?: {
20
+ name: string
21
+ key: string
22
+ optional?: boolean
23
+ }
24
+ }
25
+
26
+ export interface Instance<T> {
27
+ locator: Locator
28
+ manifest: T
29
+ component: Manifest
30
+ }
31
+
32
+ export type Instances<T> = Array<Instance<T>>
33
+
34
+ export type Variables = Record<'global' | string, Variable[]>
35
+ export type Mounts = Record<'global' | string, Mount[]>
36
+
37
+ export interface Dependency {
38
+ services?: Service[]
39
+ variables?: Variables
40
+ mounts?: Mounts
41
+ }
42
+
43
+ interface Ingress {
44
+ default?: boolean
45
+ hosts?: string[]
46
+ class?: string
47
+ annotations?: object
48
+ }
49
+
50
+ interface Probe {
51
+ port: number
52
+ path: string
53
+ delay?: number
54
+ }
55
+
56
+ interface Mount {
57
+ name: string
58
+ path: string
59
+ claim: string
60
+ }
61
+
62
+ export interface Resources {
63
+ cpu: string[]
64
+ memory: string[]
65
+ }
@@ -1,30 +0,0 @@
1
- export type Service = {
2
- group: string
3
- name: string
4
- version: string
5
- port: number
6
- ingress?: {
7
- host: string
8
- class?: string
9
- annotations?: object
10
- }
11
- variables: Variable[]
12
- components?: string[]
13
- }
14
-
15
- export type Variable = {
16
- name: string
17
- value?: string
18
- secret?: {
19
- name: string,
20
- key: string
21
- optional?: boolean
22
- }
23
- }
24
-
25
- export type Variables = Record<'global' | string, Variable[]>
26
-
27
- export type Dependency = {
28
- services?: Service[]
29
- variables?: Variables
30
- }
File without changes