DodoApp: Support volume requests

Users can define volumes section under app, and for each volume
corresponding env variable will be passed down to the application.

Change-Id: I8da9d5e1ca652cdb2f0196fcba1b6242064d057f
diff --git a/core/installer/app_configs/dodo_app.cue b/core/installer/app_configs/dodo_app.cue
index b4878b3..c721863 100644
--- a/core/installer/app_configs/dodo_app.cue
+++ b/core/installer/app_configs/dodo_app.cue
@@ -18,16 +18,24 @@
 	baseURL: "https://\(subdomain).\(_network.domain)"
 }
 
-#AppTmpl: {
-	type: string
-	ingress: #AppIngress
-	runConfiguration: [...#Command]
+#Volumes: {
 	...
 }
 
+app: {
+	volumes: {
+		for key, value in volumes {
+			"\(key)": #volume & value & {
+				name: key
+			}
+		}
+	}
+}
+
 #Command: {
 	bin: string
 	args: [...string] | *[]
+	env: [...string] | *[]
 }
 
 // Go app
@@ -39,6 +47,7 @@
 	type: _goVer1220 | _goVer1200
 	run: string
 	ingress: #AppIngress
+	volumes: #Volumes
 
 	runConfiguration: [{
 		bin: "/usr/local/go/bin/go",
@@ -48,7 +57,12 @@
 		args: ["build", "-o", ".app", run]
 	}, {
 		bin: ".app",
-		args: []
+		args: [],
+		env: [
+			for k, v in volumes {
+				"DODO_VOLUME_\(strings.ToUpper(k))=/dodo-volume/\(v.name)"
+			}
+	    ]
 	}]
 }
 
@@ -69,6 +83,7 @@
 #HugoAppTmpl: {
 	type: _hugoLatest
 	ingress: #AppIngress
+	volumes: {}
 
 	runConfiguration: [{
 		bin: "/usr/bin/hugo",
@@ -125,6 +140,8 @@
 	}
 }
 
+volumes: app.volumes
+
 helm: {
 	app: {
 		chart: charts.app
@@ -140,6 +157,12 @@
 			sshPrivateKey: base64.Encode(null, input.sshPrivateKey)
 			runCfg: base64.Encode(null, json.Marshal(_app.runConfiguration))
 			manager: "http://dodo-app.\(release.namespace).svc.cluster.local/register-worker"
+			volumes: [
+				for key, value in _app.volumes {
+					name: value.name
+					mountPath: "/dodo-volume/\(key)"
+				}
+            ]
 		}
 	}
 }
diff --git a/core/installer/app_configs/testapp.cue b/core/installer/app_configs/testapp.cue
index 2573c5c..8201ff6 100644
--- a/core/installer/app_configs/testapp.cue
+++ b/core/installer/app_configs/testapp.cue
@@ -6,6 +6,7 @@
 		subdomain: "testapp"
 		auth: enabled: false
 	}
+	volumes: data: size: "1Gi"
 }
 
 // do create app --type=go[1.22.0] [--run-cmd=(*default main.go)]
diff --git a/core/installer/app_test.go b/core/installer/app_test.go
index ef5a8ef..559de31 100644
--- a/core/installer/app_test.go
+++ b/core/installer/app_test.go
@@ -304,7 +304,20 @@
 var testAppCue []byte
 
 func TestPCloudApp(t *testing.T) {
-	_, err := NewDodoApp(testAppCue)
+	app, err := NewDodoApp(testAppCue)
+	if err != nil {
+		t.Fatal(err)
+	}
+	release := Release{
+		Namespace:     "foo",
+		AppInstanceId: "foo-bar",
+		RepoAddr:      "ssh://192.168.100.210:22/config",
+		AppDir:        "/foo/bar",
+	}
+	_, err = app.Render(release, env, map[string]any{
+		"repoAddr":      "",
+		"sshPrivateKey": "",
+	}, nil)
 	if err != nil {
 		t.Fatal(err)
 	}