blob: 5eb2f58d68d987b4a349613fb4c6bcdf0ca75ed7 [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
21 workers map[string]struct{}
22}
23
24func NewDodoAppServer(
25 port int,
26 sshKey string,
27 client soft.Client,
28 namespace string,
29 env installer.EnvConfig,
30) *DodoAppServer {
31 return &DodoAppServer{
32 port,
33 sshKey,
34 client,
35 namespace,
36 env,
37 map[string]struct{}{},
38 }
39}
40
41func (s *DodoAppServer) Start() error {
42 http.HandleFunc("/update", s.handleUpdate)
43 http.HandleFunc("/register-worker", s.handleRegisterWorker)
44 return http.ListenAndServe(fmt.Sprintf(":%d", s.port), nil)
45}
46
47type updateReq struct {
48 Ref string `json:"ref"`
49}
50
51func (s *DodoAppServer) handleUpdate(w http.ResponseWriter, r *http.Request) {
52 fmt.Println("update")
53 var req updateReq
54 var contents strings.Builder
55 io.Copy(&contents, r.Body)
56 c := contents.String()
57 fmt.Println(c)
58 if err := json.NewDecoder(strings.NewReader(c)).Decode(&req); err != nil {
59 fmt.Println(err)
60 return
61 }
62 if req.Ref != "refs/heads/master" {
63 return
64 }
65 go func() {
66 time.Sleep(20 * time.Second)
67 if err := UpdateDodoApp(s.client, s.namespace, s.sshKey, &s.env); err != nil {
68 fmt.Println(err)
69 }
70 }()
71 for addr, _ := range s.workers {
72 go func() {
73 // TODO(gio): make port configurable
74 http.Get(fmt.Sprintf("http://%s:3000/update", addr))
75 }()
76 }
77}
78
79type registerWorkerReq struct {
80 Address string `json:"address"`
81}
82
83func (s *DodoAppServer) handleRegisterWorker(w http.ResponseWriter, r *http.Request) {
84 var req registerWorkerReq
85 if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
86 http.Error(w, err.Error(), http.StatusInternalServerError)
87 return
88 }
89 s.workers[req.Address] = struct{}{}
90 fmt.Printf("registered worker: %s\n", req.Address)
91}
92
93func UpdateDodoApp(client soft.Client, namespace string, sshKey string, env *installer.EnvConfig) error {
94 repo, err := client.GetRepo("app")
95 if err != nil {
96 return err
97 }
98 nsCreator := installer.NewNoOpNamespaceCreator()
99 if err != nil {
100 return err
101 }
102 m, err := installer.NewAppManager(repo, nsCreator, "/.dodo")
103 if err != nil {
104 return err
105 }
106 appCfg, err := soft.ReadFile(repo, "app.cue")
107 fmt.Println(string(appCfg))
108 if err != nil {
109 return err
110 }
111 app, err := installer.NewDodoApp(appCfg)
112 if err != nil {
113 return err
114 }
115 if _, err := m.Install(app, "app", "/.dodo/app", namespace, map[string]any{
116 "repoAddr": repo.FullAddress(),
117 "sshPrivateKey": sshKey,
118 }, installer.WithConfig(env), installer.WithBranch("dodo")); err != nil {
119 return err
120 }
121 return nil
122}