Dodo APP: infrastructure to deploy app by pusing to Git repo
Change-Id: I4034c6893255581b014ddb207c844261cb34202b
diff --git a/core/installer/welcome/dodo_app.go b/core/installer/welcome/dodo_app.go
new file mode 100644
index 0000000..5eb2f58
--- /dev/null
+++ b/core/installer/welcome/dodo_app.go
@@ -0,0 +1,122 @@
+package welcome
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "strings"
+ "time"
+
+ "github.com/giolekva/pcloud/core/installer"
+ "github.com/giolekva/pcloud/core/installer/soft"
+)
+
+type DodoAppServer struct {
+ port int
+ sshKey string
+ client soft.Client
+ namespace string
+ env installer.EnvConfig
+ workers map[string]struct{}
+}
+
+func NewDodoAppServer(
+ port int,
+ sshKey string,
+ client soft.Client,
+ namespace string,
+ env installer.EnvConfig,
+) *DodoAppServer {
+ return &DodoAppServer{
+ port,
+ sshKey,
+ client,
+ namespace,
+ env,
+ map[string]struct{}{},
+ }
+}
+
+func (s *DodoAppServer) Start() error {
+ http.HandleFunc("/update", s.handleUpdate)
+ http.HandleFunc("/register-worker", s.handleRegisterWorker)
+ return http.ListenAndServe(fmt.Sprintf(":%d", s.port), nil)
+}
+
+type updateReq struct {
+ Ref string `json:"ref"`
+}
+
+func (s *DodoAppServer) handleUpdate(w http.ResponseWriter, r *http.Request) {
+ fmt.Println("update")
+ var req updateReq
+ var contents strings.Builder
+ io.Copy(&contents, r.Body)
+ c := contents.String()
+ fmt.Println(c)
+ if err := json.NewDecoder(strings.NewReader(c)).Decode(&req); err != nil {
+ fmt.Println(err)
+ return
+ }
+ if req.Ref != "refs/heads/master" {
+ return
+ }
+ go func() {
+ time.Sleep(20 * time.Second)
+ if err := UpdateDodoApp(s.client, s.namespace, s.sshKey, &s.env); err != nil {
+ fmt.Println(err)
+ }
+ }()
+ for addr, _ := range s.workers {
+ go func() {
+ // TODO(gio): make port configurable
+ http.Get(fmt.Sprintf("http://%s:3000/update", addr))
+ }()
+ }
+}
+
+type registerWorkerReq struct {
+ Address string `json:"address"`
+}
+
+func (s *DodoAppServer) handleRegisterWorker(w http.ResponseWriter, r *http.Request) {
+ var req registerWorkerReq
+ if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ s.workers[req.Address] = struct{}{}
+ fmt.Printf("registered worker: %s\n", req.Address)
+}
+
+func UpdateDodoApp(client soft.Client, namespace string, sshKey string, env *installer.EnvConfig) error {
+ repo, err := client.GetRepo("app")
+ if err != nil {
+ return err
+ }
+ nsCreator := installer.NewNoOpNamespaceCreator()
+ if err != nil {
+ return err
+ }
+ m, err := installer.NewAppManager(repo, nsCreator, "/.dodo")
+ if err != nil {
+ return err
+ }
+ appCfg, err := soft.ReadFile(repo, "app.cue")
+ fmt.Println(string(appCfg))
+ if err != nil {
+ return err
+ }
+ app, err := installer.NewDodoApp(appCfg)
+ if err != nil {
+ return err
+ }
+ if _, err := m.Install(app, "app", "/.dodo/app", namespace, map[string]any{
+ "repoAddr": repo.FullAddress(),
+ "sshPrivateKey": sshKey,
+ }, installer.WithConfig(env), installer.WithBranch("dodo")); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/core/installer/welcome/env_test.go b/core/installer/welcome/env_test.go
index e4cee83..0803e64 100644
--- a/core/installer/welcome/env_test.go
+++ b/core/installer/welcome/env_test.go
@@ -59,7 +59,7 @@
return nil
}
-func (r mockRepoIO) CommitAndPush(message string) error {
+func (r mockRepoIO) CommitAndPush(message string, opts ...soft.PushOption) error {
r.t.Logf("Commit and push: %s", message)
return nil
}
@@ -128,6 +128,10 @@
return nil
}
+func (f fakeSoftServeClient) AddWebhook(repo, url string, opts ...string) error {
+ return nil
+}
+
type fakeClientGetter struct {
t *testing.T
envFS billy.Filesystem