DodoApp: Abstract away service definition
TODO(gio): There seems to be a performance degradation evaluating cue files.
Change-Id: Ib157dfaa1c108f06f3026032e8fad79c06f42d3a
diff --git a/apps/canvas/front/src/components/actions.tsx b/apps/canvas/front/src/components/actions.tsx
index 58598ca..0f39e4e 100644
--- a/apps/canvas/front/src/components/actions.tsx
+++ b/apps/canvas/front/src/components/actions.tsx
@@ -8,6 +8,8 @@
function toNodeType(t: string): string {
if (t === "ingress") {
return "gateway-https";
+ } else if (t === "service") {
+ return "app";
} else {
return t;
}
diff --git a/core/installer/app_configs/app_base.cue b/core/installer/app_configs/app_base.cue
index 1a60440..d61bfb3 100644
--- a/core/installer/app_configs/app_base.cue
+++ b/core/installer/app_configs/app_base.cue
@@ -2,6 +2,7 @@
"crypto/sha256"
"encoding/base64"
"encoding/json"
+ "strconv"
"list"
"net"
"strings"
@@ -11,6 +12,16 @@
cluster?: #Cluster @name(Cluster)
}
+_uuidData: json.Marshal([
+ input,
+ release,
+ global,
+ localCharts,
+ ])
+// TODO(gio): revisit this logic
+_uuidSorted: strings.Join(list.Sort([for x in strings.Runes(_uuidData) {strconv.QuoteRune(x)}], list.Ascending), "")
+uuid: base64.Encode(null, sha256.Sum256(_uuidSorted))
+
name: string | *""
description: string | *""
readme: string | *""
@@ -78,9 +89,9 @@
size: string
accessMode: string
- _cluster: cluster
- _name: name
- _size: size
+ _cluster: cluster
+ _name: name
+ _size: size
_accessMode: accessMode
charts: {
@@ -98,15 +109,15 @@
if _cluster != _|_ {
cluster: _cluster
}
- info: "Creating disk for \(name)"
+ info: "Creating disk for \(name)"
annotations: {
"dodo.cloud/resource-type": "volume"
"dodo.cloud/resource.volume.name": name
"dodo.cloud/resource.volume.size": size
}
values: {
- name: _name
- size: _size
+ name: _name
+ size: _size
accessMode: _accessMode
}
}
@@ -115,14 +126,17 @@
#WithOut: {
cluster?: #Cluster
- _cluster: cluster
+ _cc: #Cluster | null | *null
+ if cluster != _|_ {
+ _cc: cluster
+ }
volume: {...}
volume: {
for k, v in volume {
"\(k)": #Volume & v & {
name: k
- if _cluster != _|_ {
- cluster: _cluster
+ if _cc != null {
+ cluster: _cc
}
}
}
@@ -530,13 +544,16 @@
#WithOut: {
cluster?: #Cluster
- _cluster: cluster
+ _cc: #Cluster | null | *null
+ if cluster != _|_ {
+ _cc: cluster
+ }
mongodb: {...}
mongodb: {
for k, v in mongodb {
"\(k)": #MongoDB & v & {
- if _cluster != _|_ {
- cluster: _cluster
+ if _cc != null {
+ cluster: _cc
}
}
}
@@ -708,17 +725,7 @@
targetNamespace?: string
values: {...} | *{}
- id: base64.Encode(null, sha256.Sum256(json.Marshal([
- name,
- values,
- dependsOn,
- if cluster != _|_ {
- cluster
- },
- if targetNamespace != _|_ {
- targetNamespace
- },
- ])))
+ id: uuid
...
}
@@ -831,17 +838,20 @@
if input.cluster != _|_ {
cluster: #Cluster | *input.cluster
}
- _cluster: cluster
+ _cc: #Cluster | null | *null
+ if cluster != _|_ {
+ _cc: cluster
+ }
images: {...}
charts: {...}
helm: {...}
openPort: [...#PortForward] | *[]
openPortMap: {
"_self": list.FlattenN([for i, e in openPort {
- if cluster == _|_ {
+ if _cc == null {
e
}
- if cluster != _|_ {
+ if _cc != null {
if strings.ToLower(e.network.name) == "private" {
[{
name: "\(e.name)_cluster"
@@ -849,16 +859,16 @@
name: "cluster_\(cluster.name)"
ingressClass: "default"
domain: ""
- allocatePortAddr: "http://port-allocator.\(global.id)-cluster-\(cluster.name)-network.svc.cluster.local/api/allocate"
- reservePortAddr: "http://port-allocator.\(global.id)-cluster-\(cluster.name)-network.svc.cluster.local/api/reserve"
- deallocatePortAddr: "http://port-allocator.\(global.id)-cluster-\(cluster.name)-network.svc.cluster.local/api/remmove"
+ allocatePortAddr: "http://port-allocator.\(global.id)-cluster-\(_cc.name)-network.svc.cluster.local/api/allocate"
+ reservePortAddr: "http://port-allocator.\(global.id)-cluster-\(_cc.name)-network.svc.cluster.local/api/reserve"
+ deallocatePortAddr: "http://port-allocator.\(global.id)-cluster-\(_cc.name)-network.svc.cluster.local/api/remmove"
}
port: input[name]
protocol: e.protocol
service: e.service
}, {
name: e.name
- clusterName: _cluster.name
+ clusterName: _cc.name
network: e.network
port: input[e.name]
protocol: e.protocol
@@ -872,12 +882,12 @@
[{
name: "\(e.name)_cluster"
network: #Network & {
- name: "cluster_\(cluster.name)"
+ name: "cluster_\(_cc.name)"
ingressClass: "default"
domain: ""
- allocatePortAddr: "http://port-allocator.\(global.id)-cluster-\(cluster.name)-network.svc.cluster.local/api/allocate"
- reservePortAddr: "http://port-allocator.\(global.id)-cluster-\(cluster.name)-network.svc.cluster.local/api/reserve"
- deallocatePortAddr: "http://port-allocator.\(global.id)-cluster-\(cluster.name)-network.svc.cluster.local/api/remmove"
+ allocatePortAddr: "http://port-allocator.\(global.id)-cluster-\(_cc.name)-network.svc.cluster.local/api/allocate"
+ reservePortAddr: "http://port-allocator.\(global.id)-cluster-\(_cc.name)-network.svc.cluster.local/api/reserve"
+ deallocatePortAddr: "http://port-allocator.\(global.id)-cluster-\(_cc.name)-network.svc.cluster.local/api/remmove"
}
port: input[name]
protocol: "TCP"
@@ -885,7 +895,7 @@
}, {
name: "\(e.name)_private"
network: networks.private // TODO(gio): take corresponding private network
- clusterName: _cluster.name
+ clusterName: _cc.name
port: input[name]
protocol: "TCP"
service: {
@@ -936,8 +946,8 @@
helmR: {
for k, v in helm {
"\(k)": v & {
- if v.cluster == _|_ && _cluster != _|_ {
- cluster: _cluster
+ if v.cluster == _|_ && _cc != null {
+ cluster: _cc
}
}
}
@@ -980,8 +990,6 @@
}
#WithOut: {
- cluster?: #Cluster
- _cluster: cluster
charts: {
secret: {
kind: "GitRepository"
@@ -995,13 +1003,16 @@
#WithOut: {
cluster?: #Cluster
- _cluster: cluster
+ _cc: #Cluster | null | *null
+ if cluster != _|_ {
+ _cc: cluster
+ }
postgresql: {...}
postgresql: {
for k, v in postgresql {
"\(k)": #PostgreSQL & v & {
- if _cluster != _|_ {
- cluster: _cluster
+ if _cc != null {
+ cluster: _cc
}
}
}
@@ -1040,14 +1051,17 @@
#WithOut: {
cluster?: #Cluster
- _cluster: cluster
+ _cc: #Cluster | null | *null
+ if cluster != _|_ {
+ _cc: cluster
+ }
vm: {...}
vm: {
for k, v in vm {
"\(k)": #VirtualMachine & v & {
name: k
- if _cluster != _|_ {
- cluster: _cluster
+ if _cc != null {
+ cluster: _cc
}
}
}
diff --git a/core/installer/app_configs/app_global_env.cue b/core/installer/app_configs/app_global_env.cue
index cd98be0..e9e5332 100644
--- a/core/installer/app_configs/app_global_env.cue
+++ b/core/installer/app_configs/app_global_env.cue
@@ -211,15 +211,18 @@
#WithOut: {
cluster?: #Cluster
- _cluster: cluster
+ _cc: #Cluster | null | *null
+ if cluster != _|_ {
+ _cc: cluster
+ }
ingress: {...}
ingress: {
for k, v in ingress {
"\(k)": #Ingress & v & {
name: k
g: global
- if _cluster != _|_ {
- cluster: _cluster
+ if _cc != null {
+ cluster: _cc
}
}
}
diff --git a/core/installer/app_configs/dodo_app.cue b/core/installer/app_configs/dodo_app.cue
index 9f41805..bc465b5 100644
--- a/core/installer/app_configs/dodo_app.cue
+++ b/core/installer/app_configs/dodo_app.cue
@@ -9,7 +9,12 @@
namespace: "dodo-app"
cluster?: string
-_cluster: cluster
+_cluster: string | null | *null
+if cluster != _|_ {
+ if cluster != "default" {
+ _cluster: cluster
+ }
+}
input: {
// VM uses this endpoint to load env variables from dodo-app server.
@@ -21,7 +26,7 @@
key: #SSHKey
// TODO(gio): this should not be necessary as app.dev.username is autogenerated
username?: string
- if _cluster != _|_ {
+ if _cluster != null {
cluster: clusterMap[strings.ToLower(_cluster)]
}
@@ -76,6 +81,7 @@
_volume: volume
_postgresql: postgresql
_mongodb: mongodb
+_service: service
envVars: [
for v in _volume {
@@ -452,233 +458,300 @@
service: [...#App]
-outs: {
- for svc in service {
- _namedPorts: {
- for p in svc.ports {
- "\(p.name)": p.value
- }
+#ServiceDevDisabled: #WithOut & {
+ cluster?: #Cluster
+ _cc: #Cluster | null | *null
+ if cluster != _|_ {
+ _cc: cluster
+ }
+ svc: #App & {
+ dev: {
+ enabled: false
}
- "service_\(svc.name)": #WithOut & {
- envProfile: strings.Join(list.Concat([
- svc.vm.env,
- [for e in svc.lastCmdEnv {"export \(e)"}],
- ]), "\n")
- if !svc.dev.enabled {
- {
- // TODO(gio): support vm open ports
- openPort: list.Concat([
- [for i, e in svc.expose if e.port.name != _|_ {
- for p in svc.ports if e.port.name == p.name {
- name: "port_service_\(svc.name)_\(i)"
- network: networks[strings.ToLower(e.network)]
- port: input[name]
- protocol: p.protocol
- service: {
- name: "app-app"
- port: p.value
- }
- }
- }],
- [for i, e in svc.expose if e.port.value != _|_ {
- for p in svc.ports if e.port.value == p.value {
- name: "port_service_\(svc.name)_\(i)"
- network: networks[strings.ToLower(e.network)]
- port: input[name]
- protocol: p.protocol
- service: {
- name: "app-app"
- port: p.value
- }
- }
- }],
- ])
- ingress: {
- if svc.ingress != _|_ {
- {for i, ingress in svc.ingress {
- "\(svc.name)-\(i)": {
- label: svc.name
- network: networks[strings.ToLower(ingress.network)]
- subdomain: ingress.subdomain
- auth: ingress.auth
- if input.cluster != _|_ {
- cluster: input.cluster
- }
- service: {
- name: "\(svc.name)-app"
- if ingress.port.value != _|_ {
- port: ingress.port.value
- }
- if ingress.port.value == _|_ {
- port: _namedPorts[ingress.port.name]
- }
- }
- }
- }}
- }
- }
- images: {
- app: {
- repository: "giolekva"
- name: "app-runner"
- tag: strings.Replace(svc.type, ":", "-", -1)
- pullPolicy: "Always"
- }
- "tailscale-proxy": {
- repository: "tailscale"
- name: "tailscale"
- tag: "v1.82.0"
- pullPolicy: "IfNotPresent"
- }
- }
- charts: {
- "access-secrets": {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/access-secrets"
- }
- app: {
- kind: "GitRepository"
- address: "https://code.v1.dodo.cloud/helm-charts"
- branch: "main"
- path: "charts/app-runner"
- }
- }
- helm: {
- if input.cluster != _|_ {
- {
- "access-secrets": {
- chart: charts["access-secrets"]
- values: {
- serviceAccountName: "default"
- }
- }
- }
- }
- "\(svc.name)": {
- chart: charts.app
- annotations: {
- "dodo.cloud/resource-type": "service"
- "dodo.cloud/resource.service.name": svc.name
- }
- values: {
- image: {
- repository: images.app.fullName
- tag: images.app.tag
- pullPolicy: images.app.pullPolicy
- }
- // TODO(gio): install gvisor runtime during new remote cluster init
- if input.cluster == _|_ {
- runtimeClassName: "untrusted-external" // TODO(gio): make this part of the infra config
- }
- name: svc.name
- apiPort: svc.apiPort
- appPorts: [for p in svc.ports {
- name: p.name
- containerPort: p.value
- protocol: p.protocol
- }]
- appDir: svc.rootDir
- appId: input.appId
- repoAddr: svc.source.repository
- branch: svc.source.branch
- rootDir: svc.source.rootDir
- sshPrivateKey: base64.Encode(null, input.key.private)
- runCfg: base64.Encode(null, json.Marshal(svc.runConfiguration))
- managerAddr: input.managerAddr
- volumes: [
- for v in svc.volume {
- name: v.name
- mountPath: "/dodo/volume/\(v)"
- },
- ]
- }
- }
- }
- }
- }
- }
+ }
- if svc.dev.enabled {
- // TODO(gio): reuse envProfile from above
- _envProfile: strings.Join(list.Concat([
- svc.vm.env,
- [for e in svc.lastCmdEnv {"export \(e)"}],
- ]), "\n")
- {
- "\(svc.name)": #WithOut & {
- ingress: {
- if svc.ingress != _|_ {
- {for i, ingress in svc.ingress {
- "\(svc.name)-\(i)": {
- label: svc.name
- network: networks[strings.ToLower(ingress.network)]
- subdomain: ingress.subdomain
- auth: ingress.auth
- service: {
- name: svc.name
- if ingress.port.value != _|_ {
- port: ingress.port.value
- }
- if ingress.port.name != _|_ {
- port: _namedPorts[ingress.port.name]
- }
- }
- }
- // TODO(gio): code should work even without svc ingress
- "\(svc.name)-\(i)-code": {
- label: "VS Code"
- home: "/?folder=/home/\(svc.dev.username)/code"
- network: networks[strings.ToLower(ingress.network)]
- subdomain: "code-\(ingress.subdomain)"
- auth: enabled: false
- service: {
- name: svc.name
- port: _codeServerPort
- }
- }
- }}
- }
+ _namedPorts: {
+ for p in svc.ports {
+ "\(p.name)": p.value
+ }
+ }
+
+ openPort: list.Concat([
+ [for i, e in svc.expose if e.port.name != _|_ {
+ for p in svc.ports if e.port.name == p.name {
+ name: "port_service_\(svc.name)_\(i)"
+ network: networks[strings.ToLower(e.network)]
+ port: input[name]
+ protocol: p.protocol
+ service: {
+ name: "app-app"
+ port: p.value
+ }
+ }
+ }],
+ [for i, e in svc.expose if e.port.value != _|_ {
+ for p in svc.ports if e.port.value == p.value {
+ name: "port_service_\(svc.name)_\(i)"
+ network: networks[strings.ToLower(e.network)]
+ port: input[name]
+ protocol: p.protocol
+ service: {
+ name: "app-app"
+ port: p.value
+ }
+ }
+ }],
+ ])
+
+ images: {
+ app: {
+ repository: "giolekva"
+ name: "app-runner"
+ tag: strings.Replace(svc.type, ":", "-", -1)
+ pullPolicy: "Always"
+ }
+ "tailscale-proxy": {
+ repository: "tailscale"
+ name: "tailscale"
+ tag: "v1.82.0"
+ pullPolicy: "IfNotPresent"
+ }
+ }
+
+ charts: {
+ "access-secrets": {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/access-secrets"
+ }
+ app: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/app-runner"
+ }
+ }
+
+ ingress: {
+ if svc.ingress != _|_ {
+ {for i, ingress in svc.ingress {
+ "\(svc.name)-\(i)": {
+ label: svc.name
+ network: networks[strings.ToLower(ingress.network)]
+ subdomain: ingress.subdomain
+ auth: ingress.auth
+ if _cc != null {
+ cluster: _cc
}
- vm: {
- "\(svc.name)": {
- username: svc.dev.username
- domain: global.domain
- vpn: {
- enabled: true
- loginServer: "https://headscale.\(global.domain)"
- authKey: input.vpnAuthKey
- }
- codeServerEnabled: true
- cpuCores: 2
- memory: "3Gi"
- ports: svc.ports
- configFiles: {
- "env.sh": _envProfile
- }
- cloudInit: {
- writeFiles: [{
- path: "/home/\(username)/.bash_profile"
- content: "source /home/\(username)/.dodo/env.sh"
- owner: "\(username):\(username)"
- permissions: "0700"
- }]
- runCmd: list.Concat([[
- ["sh", "-c", "chown \(username):\(username) /home/\(username)/.cache"],
- ["sh", "-c", "GIT_SSH_COMMAND='ssh -i /home/\(username)/.ssh/id_ed25519 -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new' git clone --branch \(svc.source.branch) \(svc.source.repository) /home/\(username)/code"],
- ["sh", "-c", "chown -R \(username):\(username) /home/\(username)/code"],
- ["sh", "-c", "chown -R \(username):\(username) /home/\(username)"],
- ], svc.vm.cloudInit.runCmd])
- }
+ service: {
+ name: "\(svc.name)-app"
+ if ingress.port.value != _|_ {
+ port: ingress.port.value
+ }
+ if ingress.port.value == _|_ {
+ port: _namedPorts[ingress.port.name]
}
}
}
+ }}
+ }
+ }
+
+ helm: {
+ if _cc != null {
+ {
+ "access-secrets": {
+ chart: charts["access-secrets"]
+ values: {
+ serviceAccountName: "default"
+ }
+ }
+ }
+ }
+ "\(svc.name)": {
+ chart: charts.app
+ annotations: {
+ "dodo.cloud/resource-type": "service"
+ "dodo.cloud/resource.service.name": svc.name
+ }
+ values: {
+ image: {
+ repository: images.app.fullName
+ tag: images.app.tag
+ pullPolicy: images.app.pullPolicy
+ }
+ // TODO(gio): install gvisor runtime during new remote cluster init
+ if cluster == _|_ {
+ runtimeClassName: "untrusted-external" // TODO(gio): make this part of the infra config
+ }
+ name: svc.name
+ apiPort: svc.apiPort
+ appPorts: [for p in svc.ports {
+ name: p.name
+ containerPort: p.value
+ protocol: p.protocol
+ }]
+ appDir: svc.rootDir
+ appId: input.appId
+ repoAddr: svc.source.repository
+ branch: svc.source.branch
+ rootDir: svc.source.rootDir
+ sshPrivateKey: base64.Encode(null, input.key.private)
+ runCfg: base64.Encode(null, json.Marshal(svc.runConfiguration))
+ managerAddr: input.managerAddr
+ volumes: [
+ for v in svc.volume {
+ name: v.name
+ mountPath: "/dodo/volume/\(v)"
+ },
+ ]
}
}
}
}
+// TODO(gio): Support remote clusters.
+#ServiceDevEnabled: #WithOut & {
+ cluster?: #Cluster
+ _cc: #Cluster | null | *null
+ if cluster != _|_ {
+ _cc: cluster
+ }
+ svc: #App & {
+ dev: {
+ enabled: true
+ }
+ }
+
+ _namedPorts: {
+ for p in svc.ports {
+ "\(p.name)": p.value
+ }
+ }
+
+ // TODO(gio): reuse envProfile from above
+ _envProfile: strings.Join(list.Concat([
+ svc.vm.env,
+ [for e in svc.lastCmdEnv {"export \(e)"}],
+ ]), "\n")
+ ingress: {
+ if svc.ingress != _|_ {
+ {for i, ingress in svc.ingress {
+ "\(svc.name)-\(i)": {
+ label: svc.name
+ network: networks[strings.ToLower(ingress.network)]
+ subdomain: ingress.subdomain
+ auth: ingress.auth
+ service: {
+ name: svc.name
+ if ingress.port.value != _|_ {
+ port: ingress.port.value
+ }
+ if ingress.port.name != _|_ {
+ port: _namedPorts[ingress.port.name]
+ }
+ }
+ }
+ // TODO(gio): code should work even without svc ingress
+ "\(svc.name)-\(i)-code": {
+ label: "VS Code"
+ home: "/?folder=/home/\(svc.dev.username)/code"
+ network: networks[strings.ToLower(ingress.network)]
+ subdomain: "code-\(ingress.subdomain)"
+ auth: enabled: false
+ service: {
+ name: svc.name
+ port: _codeServerPort
+ }
+ }
+ }}
+ }
+ }
+ vm: {
+ "\(svc.name)": {
+ username: svc.dev.username
+ domain: global.domain
+ vpn: {
+ enabled: true
+ loginServer: "https://headscale.\(global.domain)"
+ authKey: input.vpnAuthKey
+ }
+ codeServerEnabled: true
+ cpuCores: 2
+ memory: "3Gi"
+ ports: svc.ports
+ configFiles: {
+ "env.sh": _envProfile
+ }
+ cloudInit: {
+ writeFiles: [{
+ path: "/home/\(username)/.bash_profile"
+ content: "source /home/\(username)/.dodo/env.sh"
+ owner: "\(username):\(username)"
+ permissions: "0700"
+ }]
+ runCmd: list.Concat([[
+ ["sh", "-c", "chown \(username):\(username) /home/\(username)/.cache"],
+ ["sh", "-c", "GIT_SSH_COMMAND='ssh -i /home/\(username)/.ssh/id_ed25519 -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new' git clone --branch \(svc.source.branch) \(svc.source.repository) /home/\(username)/code"],
+ ["sh", "-c", "chown -R \(username):\(username) /home/\(username)/code"],
+ ["sh", "-c", "chown -R \(username):\(username) /home/\(username)"],
+ ], svc.vm.cloudInit.runCmd])
+ }
+ }
+ }
+}
+
+#Service: #ServiceDevEnabled | #ServiceDevDisabled
+
+#WithOut: {
+ cluster?: #Cluster
+ _cc: #Cluster | null | *null
+ if cluster != _|_ {
+ _cc: cluster
+ }
+ services: {...}
+ services: {
+ for k, v in services {
+ "\(k)": #Service & v & {
+ if _cc != null {
+ cluster: _cc
+ }
+ }
+ }
+ ...
+ }
+ openPortMap: {
+ for k, v in services {
+ "service-\(k)": v.openPortMap
+ }
+ ...
+ }
+ images: {
+ for k, v in services {
+ for x, y in v.images {
+ "\(x)": y
+ }
+ }
+ }
+ charts: {
+ for k, v in services {
+ for x, y in v.charts {
+ "\(x)": y
+ }
+ }
+ }
+ helmR: {
+ for k, v in services {
+ for x, y in v.helmR {
+ "\(x)": y
+ }
+ }
+ ...
+ }
+ ...
+}
+
out: {
if input.cluster != _|_ {
cluster: input.cluster
@@ -698,6 +771,14 @@
"\(v.name)": v
}
}
+ services: {
+ for v in _service {
+ "\(v.name)": #Service & {
+ name: v.name
+ svc: v
+ }
+ }
+ }
}
_appDir: "/dodo-app"
diff --git a/core/installer/samples/blog.rest b/core/installer/samples/blog.rest
index 2a0b95c..f0116b7 100644
--- a/core/installer/samples/blog.rest
+++ b/core/installer/samples/blog.rest
@@ -1,4 +1,4 @@
-PUT http://appmanager.hgrz-appmanager.svc.cluster.local/api/dodo-app/dodo-app-snd
+POST http://appmanager.hgrz-appmanager.svc.cluster.local/api/dodo-app
Content-Type: application/json
{
@@ -20,7 +20,7 @@
"groups": "pr"
},
"network": "Private",
- "subdomain": "blog"
+ "subdomain": "test-blog"
}],
"type": "nextjs:deno-2.0.0",
"preBuildCommands": [
@@ -43,4 +43,4 @@
}
]
}
-}
\ No newline at end of file
+}
diff --git a/core/installer/status/instance.go b/core/installer/status/instance.go
index c88e5e5..9ad2ff0 100644
--- a/core/installer/status/instance.go
+++ b/core/installer/status/instance.go
@@ -93,6 +93,13 @@
s = mergeStatus(status, s)
}
}
+ for _, i := range out.Services {
+ if s, err := m.monitor(namespace, DodoResource{"service", i.Name}, i, ret); err != nil {
+ return StatusNoStatus, err
+ } else {
+ s = mergeStatus(status, s)
+ }
+ }
ret[resource] = status
return status, nil
}
@@ -116,6 +123,7 @@
PostgreSQL map[string]ResourceOut `json:"postgresql"`
MongoDB map[string]ResourceOut `json:"mongodb"`
Ingress map[string]resourceIngress `json:"ingress"`
+ Services map[string]ResourceOut `json:"services"`
Helm map[string]resourceHelm `json:"helmR"`
}