blob: 39d3a0331c474f6b065ed1e3ef24110e81e4f6ed [file] [log] [blame]
gio0eaf2712024-04-14 13:08:46 +04001package welcome
2
3import (
4 "encoding/json"
5 "fmt"
6 "io"
7 "net/http"
8 "strings"
9 "time"
10
11 "github.com/giolekva/pcloud/core/installer"
12 "github.com/giolekva/pcloud/core/installer/soft"
13)
14
15type DodoAppServer struct {
16 port int
17 sshKey string
18 client soft.Client
19 namespace string
20 env installer.EnvConfig
giof8843412024-05-22 16:38:05 +040021 jc installer.JobCreator
gio0eaf2712024-04-14 13:08:46 +040022 workers map[string]struct{}
23}
24
25func NewDodoAppServer(
26 port int,
27 sshKey string,
28 client soft.Client,
29 namespace string,
giof8843412024-05-22 16:38:05 +040030 jc installer.JobCreator,
gio0eaf2712024-04-14 13:08:46 +040031 env installer.EnvConfig,
32) *DodoAppServer {
33 return &DodoAppServer{
34 port,
35 sshKey,
36 client,
37 namespace,
38 env,
giof8843412024-05-22 16:38:05 +040039 jc,
gio0eaf2712024-04-14 13:08:46 +040040 map[string]struct{}{},
41 }
42}
43
44func (s *DodoAppServer) Start() error {
45 http.HandleFunc("/update", s.handleUpdate)
46 http.HandleFunc("/register-worker", s.handleRegisterWorker)
gio70be3e52024-06-26 18:27:19 +040047 http.HandleFunc("/api/add-admin-key", s.handleAddAdminKey)
gio0eaf2712024-04-14 13:08:46 +040048 return http.ListenAndServe(fmt.Sprintf(":%d", s.port), nil)
49}
50
51type updateReq struct {
52 Ref string `json:"ref"`
53}
54
55func (s *DodoAppServer) handleUpdate(w http.ResponseWriter, r *http.Request) {
56 fmt.Println("update")
57 var req updateReq
58 var contents strings.Builder
59 io.Copy(&contents, r.Body)
60 c := contents.String()
61 fmt.Println(c)
62 if err := json.NewDecoder(strings.NewReader(c)).Decode(&req); err != nil {
63 fmt.Println(err)
64 return
65 }
66 if req.Ref != "refs/heads/master" {
67 return
68 }
69 go func() {
70 time.Sleep(20 * time.Second)
giof8843412024-05-22 16:38:05 +040071 if err := UpdateDodoApp(s.client, s.namespace, s.sshKey, s.jc, &s.env); err != nil {
gio0eaf2712024-04-14 13:08:46 +040072 fmt.Println(err)
73 }
74 }()
75 for addr, _ := range s.workers {
76 go func() {
77 // TODO(gio): make port configurable
78 http.Get(fmt.Sprintf("http://%s:3000/update", addr))
79 }()
80 }
81}
82
83type registerWorkerReq struct {
84 Address string `json:"address"`
85}
86
87func (s *DodoAppServer) handleRegisterWorker(w http.ResponseWriter, r *http.Request) {
88 var req registerWorkerReq
89 if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
90 http.Error(w, err.Error(), http.StatusInternalServerError)
91 return
92 }
93 s.workers[req.Address] = struct{}{}
94 fmt.Printf("registered worker: %s\n", req.Address)
95}
96
gio70be3e52024-06-26 18:27:19 +040097type addAdminKeyReq struct {
98 Public string `json:"public"`
99}
100
101func (s *DodoAppServer) handleAddAdminKey(w http.ResponseWriter, r *http.Request) {
102 var req addAdminKeyReq
103 if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
104 http.Error(w, err.Error(), http.StatusBadRequest)
105 return
106 }
107 if err := s.client.AddPublicKey("admin", req.Public); err != nil {
108 http.Error(w, err.Error(), http.StatusInternalServerError)
109 return
110 }
111}
112
giof8843412024-05-22 16:38:05 +0400113func UpdateDodoApp(client soft.Client, namespace string, sshKey string, jc installer.JobCreator, env *installer.EnvConfig) error {
gio0eaf2712024-04-14 13:08:46 +0400114 repo, err := client.GetRepo("app")
115 if err != nil {
116 return err
117 }
giof8843412024-05-22 16:38:05 +0400118 nsc := installer.NewNoOpNamespaceCreator()
gio0eaf2712024-04-14 13:08:46 +0400119 if err != nil {
120 return err
121 }
giof8843412024-05-22 16:38:05 +0400122 hf := installer.NewGitHelmFetcher()
123 m, err := installer.NewAppManager(repo, nsc, jc, hf, "/.dodo")
gio0eaf2712024-04-14 13:08:46 +0400124 if err != nil {
125 return err
126 }
127 appCfg, err := soft.ReadFile(repo, "app.cue")
128 fmt.Println(string(appCfg))
129 if err != nil {
130 return err
131 }
132 app, err := installer.NewDodoApp(appCfg)
133 if err != nil {
134 return err
135 }
giof8843412024-05-22 16:38:05 +0400136 lg := installer.GitRepositoryLocalChartGenerator{"app", namespace}
giof71a0832024-06-27 14:45:45 +0400137 if _, err := m.Install(
138 app,
139 "app",
140 "/.dodo/app",
141 namespace,
142 map[string]any{
143 "repoAddr": repo.FullAddress(),
144 "sshPrivateKey": sshKey,
145 },
146 installer.WithConfig(env),
147 installer.WithLocalChartGenerator(lg),
148 installer.WithBranch("dodo"),
149 installer.WithForce(),
150 ); err != nil {
gio0eaf2712024-04-14 13:08:46 +0400151 return err
152 }
153 return nil
154}