blob: c45cd3590583afe4cd7d10db3a868d068c097c27 [file] [log] [blame]
gio0eaf2712024-04-14 13:08:46 +04001package main
2
3import (
4 "encoding/json"
5 "errors"
6 "fmt"
7 "log"
8 "os"
9
10 "github.com/giolekva/pcloud/core/installer"
11 "github.com/giolekva/pcloud/core/installer/soft"
12 "github.com/giolekva/pcloud/core/installer/welcome"
13
14 "github.com/spf13/cobra"
15)
16
17var dodoAppFlags struct {
18 port int
19 sshKey string
20 repoAddr string
21 self string
22 namespace string
23 envConfig string
24}
25
26func dodoAppCmd() *cobra.Command {
27 cmd := &cobra.Command{
28 Use: "dodo-app",
29 RunE: dodoAppCmdRun,
30 }
31 cmd.Flags().IntVar(
32 &dodoAppFlags.port,
33 "port",
34 8080,
35 "",
36 )
37 cmd.Flags().StringVar(
38 &dodoAppFlags.repoAddr,
39 "repo-addr",
40 "",
41 "",
42 )
43 cmd.Flags().StringVar(
44 &dodoAppFlags.sshKey,
45 "ssh-key",
46 "",
47 "",
48 )
49 cmd.Flags().StringVar(
50 &dodoAppFlags.self,
51 "self",
52 "",
53 "",
54 )
55 cmd.Flags().StringVar(
56 &dodoAppFlags.namespace,
57 "namespace",
58 "",
59 "",
60 )
61 cmd.Flags().StringVar(
62 &dodoAppFlags.envConfig,
63 "env-config",
64 "",
65 "",
66 )
67 return cmd
68}
69
70func dodoAppCmdRun(cmd *cobra.Command, args []string) error {
71 envConfig, err := os.Open(dodoAppFlags.envConfig)
72 if err != nil {
73 return err
74 }
75 defer envConfig.Close()
76 var env installer.EnvConfig
77 if err := json.NewDecoder(envConfig).Decode(&env); err != nil {
78 return err
79 }
80 sshKey, err := os.ReadFile(dodoAppFlags.sshKey)
81 if err != nil {
82 return err
83 }
84 softClient, err := soft.NewClient(dodoAppFlags.repoAddr, sshKey, log.Default())
85 if err != nil {
86 return err
87 }
giof8843412024-05-22 16:38:05 +040088 jc, err := newJobCreator()
89 if err != nil {
90 return err
91 }
gio0eaf2712024-04-14 13:08:46 +040092 if err := softClient.AddRepository("app"); err == nil {
93 repo, err := softClient.GetRepo("app")
94 if err != nil {
95 return err
96 }
97 if err := initRepo(repo); err != nil {
98 return err
99 }
giof8843412024-05-22 16:38:05 +0400100 if err := welcome.UpdateDodoApp(softClient, dodoAppFlags.namespace, string(sshKey), jc, &env); err != nil {
gio0eaf2712024-04-14 13:08:46 +0400101 return err
102 }
103 if err := softClient.AddWebhook("app", fmt.Sprintf("http://%s/update", dodoAppFlags.self), "--active=true", "--events=push", "--content-type=json"); err != nil {
104 return err
105 }
106 } else if !errors.Is(err, soft.ErrorAlreadyExists) {
107 return err
108 }
giof8843412024-05-22 16:38:05 +0400109 s := welcome.NewDodoAppServer(dodoAppFlags.port, string(sshKey), softClient, dodoAppFlags.namespace, jc, env)
gio0eaf2712024-04-14 13:08:46 +0400110 return s.Start()
111}
112
113const goMod = `module dodo.app
114
115go 1.18
116`
117
118const mainGo = `package main
119
120import (
121 "flag"
122 "fmt"
123 "log"
124 "net/http"
125)
126
127var port = flag.Int("port", 8080, "Port to listen on")
128
129func handler(w http.ResponseWriter, r *http.Request) {
130 fmt.Fprintln(w, "Hello from Dodo App!")
131}
132
133func main() {
134 flag.Parse()
135 http.HandleFunc("/", handler)
136 log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), nil))
137}
138`
139
140const appCue = `app: {
141 type: "golang:1.22.0"
142 run: "main.go"
143 ingress: {
144 network: "Private" // or Public
145 subdomain: "testapp"
146 auth: enabled: false
147 }
148}
149`
150
151func initRepo(repo soft.RepoIO) error {
152 return repo.Do(func(fs soft.RepoFS) (string, error) {
153 {
154 w, err := fs.Writer("go.mod")
155 if err != nil {
156 return "", err
157 }
158 defer w.Close()
159 fmt.Fprint(w, goMod)
160 }
161 {
162 w, err := fs.Writer("main.go")
163 if err != nil {
164 return "", err
165 }
166 defer w.Close()
167 fmt.Fprintf(w, "%s", mainGo)
168 }
169 {
170 w, err := fs.Writer("app.cue")
171 if err != nil {
172 return "", err
173 }
174 defer w.Close()
175 fmt.Fprint(w, appCue)
176 }
177 return "go web app template", nil
178 })
179}