AppManager: Unify regular and dodo app installation logic

Change-Id: I4c18bbebc6499e8dfe38eb8ac18536bc6017f673
diff --git a/apps/app-runner/main.go b/apps/app-runner/main.go
index 2f4f5a8..b560c6c 100644
--- a/apps/app-runner/main.go
+++ b/apps/app-runner/main.go
@@ -7,6 +7,7 @@
 	"log"
 	"net"
 	"os"
+	"strings"
 
 	"golang.org/x/crypto/ssh"
 
@@ -91,7 +92,8 @@
 		panic("no SELF_IP")
 	}
 	var signer ssh.Signer
-	if *sshKey != "" {
+	// TODO(gio): revisit this logic
+	if *sshKey != "" && !(strings.HasPrefix(*repoAddr, "http://") || strings.HasPrefix(*repoAddr, "https://")) {
 		key, err := os.ReadFile(*sshKey)
 		if err != nil {
 			panic(err)
diff --git a/core/installer/app_configs/dodo_app.cue b/core/installer/app_configs/dodo_app.cue
index 19cb06a..28eedd1 100644
--- a/core/installer/app_configs/dodo_app.cue
+++ b/core/installer/app_configs/dodo_app.cue
@@ -5,6 +5,9 @@
 	"strings"
 )
 
+name:        "dodo-app"
+namespace:   "dodo-app"
+
 cluster?: string
 _cluster: cluster
 
diff --git a/core/installer/server/appmanager/server.go b/core/installer/server/appmanager/server.go
index f4b543b..91594ce 100644
--- a/core/installer/server/appmanager/server.go
+++ b/core/installer/server/appmanager/server.go
@@ -10,7 +10,6 @@
 	"html/template"
 	"net"
 	"net/http"
-	"path/filepath"
 	"strconv"
 	"strings"
 	"sync"
@@ -188,14 +187,11 @@
 		http.Error(w, err.Error(), http.StatusBadRequest)
 		return
 	}
-	appDir := filepath.Join("/dodo-app", req.Id)
-	namespace := "dodo-app-testttt" // TODO(gio)
-	if _, err := s.m.Install(app, req.Id, appDir, namespace, map[string]any{
-		"managerAddr": "", // TODO(gio)
-		"appId":       req.Id,
-	}); err != nil {
+	if instanceId, err := s.install(app, map[string]any{}); err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
+	} else {
+		fmt.Fprintf(w, "/tasks/%s", instanceId)
 	}
 }
 
@@ -330,6 +326,36 @@
 	}
 }
 
+func (s *Server) install(app installer.EnvApp, values map[string]any) (string, error) {
+	env, err := s.m.Config()
+	if err != nil {
+		return "", err
+	}
+	suffixGen := installer.NewFixedLengthRandomSuffixGenerator(3)
+	suffix, err := suffixGen.Generate()
+	if err != nil {
+		return "", err
+	}
+	instanceId := app.Slug() + suffix
+	appDir := fmt.Sprintf("/apps/%s", instanceId)
+	namespace := fmt.Sprintf("%s%s%s", env.NamespacePrefix, app.Namespace(), suffix)
+	t := tasks.NewInstallTask(s.h, func() (installer.ReleaseResources, error) {
+		rr, err := s.m.Install(app, instanceId, appDir, namespace, values)
+		if err == nil {
+			ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
+			go s.reconciler.Reconcile(ctx)
+		}
+		return rr, err
+	})
+	if _, ok := s.tasks[instanceId]; ok {
+		panic("MUST NOT REACH!")
+	}
+	s.tasks[instanceId] = &taskForward{t, fmt.Sprintf("/instance/%s", instanceId), 0}
+	t.OnDone(s.cleanTask(instanceId, 0))
+	go t.Start()
+	return instanceId, nil
+}
+
 func (s *Server) handleAppInstall(w http.ResponseWriter, r *http.Request) {
 	s.l.Lock()
 	defer s.l.Unlock()
@@ -343,42 +369,16 @@
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
-	a, err := installer.FindEnvApp(s.r, slug)
+	app, err := installer.FindEnvApp(s.r, slug)
 	if err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
-	env, err := s.m.Config()
-	if err != nil {
+	if instanceId, err := s.install(app, values); err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
-	}
-	suffixGen := installer.NewFixedLengthRandomSuffixGenerator(3)
-	suffix, err := suffixGen.Generate()
-	if err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-		return
-	}
-	instanceId := a.Slug() + suffix
-	appDir := fmt.Sprintf("/apps/%s", instanceId)
-	namespace := fmt.Sprintf("%s%s%s", env.NamespacePrefix, a.Namespace(), suffix)
-	t := tasks.NewInstallTask(s.h, func() (installer.ReleaseResources, error) {
-		rr, err := s.m.Install(a, instanceId, appDir, namespace, values)
-		if err == nil {
-			ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
-			go s.reconciler.Reconcile(ctx)
-		}
-		return rr, err
-	})
-	if _, ok := s.tasks[instanceId]; ok {
-		panic("MUST NOT REACH!")
-	}
-	s.tasks[instanceId] = &taskForward{t, fmt.Sprintf("/instance/%s", instanceId), 0}
-	t.OnDone(s.cleanTask(instanceId, 0))
-	go t.Start()
-	if _, err := fmt.Fprintf(w, "/tasks/%s", instanceId); err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-		return
+	} else {
+		fmt.Fprintf(w, "/tasks/%s", instanceId)
 	}
 }