DodoApp: Support apps exposing multiple ports

Change-Id: I9c8a47d20ffc1836cef6390c0ac6f22e977e38f2
diff --git a/charts/app-runner/templates/install.yaml b/charts/app-runner/templates/install.yaml
index b9ecdbb..00ba74e 100644
--- a/charts/app-runner/templates/install.yaml
+++ b/charts/app-runner/templates/install.yaml
@@ -16,6 +16,7 @@
   run: |
 {{ indent 4 $runCfg }}
 ---
+{{- if .Values.appPorts }}
 apiVersion: v1
 kind: Service
 metadata:
@@ -26,10 +27,13 @@
   selector:
     app: app-app
   ports:
-  - name: app
-    port: 80
-    targetPort: app
-    protocol: TCP
+  {{- range .Values.appPorts }}
+  - name: {{ .name }}
+    port: {{ .containerPort }}
+    targetPort: {{ .name }}
+    protocol: {{ .protocol }}
+  {{- end }}
+{{- end }}
 ---
 apiVersion: v1
 kind: Service
@@ -86,9 +90,9 @@
         - name: api
           containerPort: 3000
           protocol: TCP
-        - name: app
-          containerPort: {{ .Values.appPort }}
-          protocol: TCP
+        {{- if .Values.appPorts }}
+          {{ toYaml .Values.appPorts | nindent 8 }}
+        {{- end }}
         env:
         - name: SELF_IP
           valueFrom:
diff --git a/charts/app-runner/values.yaml b/charts/app-runner/values.yaml
index 88958ae..795f2c0 100644
--- a/charts/app-runner/values.yaml
+++ b/charts/app-runner/values.yaml
@@ -8,7 +8,7 @@
 appId: ""
 runCfg: ""
 appDir: /dodo-app
-appPort: 8080
+appPorts: []
 managerAddr: ""
 volumes: []
 runtimeClassName: ""
diff --git a/core/installer/app_configs/dodo_app.cue b/core/installer/app_configs/dodo_app.cue
index 6fdb412..930c74d 100644
--- a/core/installer/app_configs/dodo_app.cue
+++ b/core/installer/app_configs/dodo_app.cue
@@ -89,6 +89,14 @@
 	env: [...string] | *[]
 }
 
+#Protocol: "TCP" | "UDP"
+
+#Port: {
+	name: string
+	value: int & > 0 & < 65536
+	protocol: #Protocol | *"TCP"
+}
+
 #AppTmpl: {
 	type: string
 	cluster?: string
@@ -100,8 +108,13 @@
 	runConfiguration: [...#Command]
 	dev: #Dev | *{ enabled: false }
 	vm: #VMCustomization
+	// TODO(gio): check for duplicate values
+	ports: [...#Port]
 
 	lastCmdEnv: [
+		for p in ports {
+			"DODO_PORT_\(strings.ToUpper(p.name))=\(p.value)"
+		}
 		for v in volumes {
 			"DODO_VOLUME_\(strings.ToUpper(v.name))=/dodo-volume/\(v.name)"
 		}
@@ -129,7 +142,10 @@
 #GoAppTmpl: #AppTmpl & {
 	type: _goVer1220 | _goVer1200
 	run: string | *"main.go"
-	port: int | *8080
+	ports: [{
+		name: "web"
+		value: 8080
+	}]
 	rootDir: _appDir
 
 	lastCmdEnv: [...string]
@@ -173,7 +189,10 @@
 #HugoAppTmpl: #AppTmpl & {
 	type: _hugoLatest
 	ingress: #AppIngress
-	port: int | *8080
+	ports: [{
+		name: "web"
+		value: 1313
+	}]
 	rootDir: _appDir
 
 	lastCmdEnv: [...string]
@@ -186,7 +205,7 @@
 			"server",
 			"--watch=false",
 			"--bind=0.0.0.0",
-			"--port=\(port)",
+			"--port=1313",
 			"--baseURL=\(ingress.baseURL)",
 			"--appendPort=false",
         ]
@@ -200,7 +219,10 @@
 
 #PHPAppTmpl: #AppTmpl & {
 	type: "php:8.2-apache"
-	port: int | *80
+	ports: [{
+		name: "web"
+		value: 80
+	}]
 	rootDir: "/var/www/html"
 
 	lastCmdEnv: [...string]
@@ -217,7 +239,10 @@
 
 #NextjsDeno2AppTmpl: #AppTmpl & {
 	type: "nextjs:deno-2.0.0"
-	port: int | *8080
+	ports: [{
+		name: "web"
+		value: 8000
+	}]
 	rootDir: _appDir
 	preBuildCommands: [...#Command] | *[]
 
@@ -240,7 +265,7 @@
 		env: lastCmdEnv
 	}, {
 		bin: "/usr/bin/deno",
-		args: ["task", "start", "-p", "\(port)"]
+		args: ["task", "start", "-p", "8000"]
 		env: lastCmdEnv
 	}]
 
@@ -278,7 +303,7 @@
 					auth: _app.ingress.auth
 					service: {
 						name: "app-app"
-						port: name: "app"
+						port: name: "web"
 					}
 				}
 			}
@@ -349,7 +374,11 @@
 								}]
 						    }]
 						}
-						appPort: _app.port
+						appPorts: [for p in _app.ports {
+							name: p.name
+							containerPort: p.value
+							protocol: p.protocol
+						}]
 						appDir: _app.rootDir
 						appId: input.appId
 						repoAddr: "\(input.repoPublicAddr)/\(input.appId)"
diff --git a/core/installer/server/dodo-app/app-templates/golang-1.20.0/main.go b/core/installer/server/dodo-app/app-templates/golang-1.20.0/main.go
index 28c1368..8146613 100755
--- a/core/installer/server/dodo-app/app-templates/golang-1.20.0/main.go
+++ b/core/installer/server/dodo-app/app-templates/golang-1.20.0/main.go
@@ -1,20 +1,18 @@
 package main
 
 import (
-	"flag"
 	"fmt"
 	"log"
 	"net/http"
+	"os"
 )
 
-var port = flag.Int("port", 8080, "Port to listen on")
-
 func handler(w http.ResponseWriter, r *http.Request) {
 	fmt.Fprintln(w, "Hello from Dodo App!")
 }
 
 func main() {
-	flag.Parse()
+	port := os.Getenv("DODO_PORT_WEB")
 	http.HandleFunc("/", handler)
-	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), nil))
+	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
 }
diff --git a/core/installer/server/dodo-app/app-templates/php-8.2-apache/app.cue.gotmpl b/core/installer/server/dodo-app/app-templates/php-8.2-apache/app.json.gotmpl
similarity index 100%
rename from core/installer/server/dodo-app/app-templates/php-8.2-apache/app.cue.gotmpl
rename to core/installer/server/dodo-app/app-templates/php-8.2-apache/app.json.gotmpl