blob: d9f9a690ad2752e41f69b3844c72b6b2c0ef316b [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 }
88 if err := softClient.AddRepository("app"); err == nil {
89 repo, err := softClient.GetRepo("app")
90 if err != nil {
91 return err
92 }
93 if err := initRepo(repo); err != nil {
94 return err
95 }
96 if err := welcome.UpdateDodoApp(softClient, dodoAppFlags.namespace, string(sshKey), &env); err != nil {
97 return err
98 }
99 if err := softClient.AddWebhook("app", fmt.Sprintf("http://%s/update", dodoAppFlags.self), "--active=true", "--events=push", "--content-type=json"); err != nil {
100 return err
101 }
102 } else if !errors.Is(err, soft.ErrorAlreadyExists) {
103 return err
104 }
105 s := welcome.NewDodoAppServer(dodoAppFlags.port, string(sshKey), softClient, dodoAppFlags.namespace, env)
106 return s.Start()
107}
108
109const goMod = `module dodo.app
110
111go 1.18
112`
113
114const mainGo = `package main
115
116import (
117 "flag"
118 "fmt"
119 "log"
120 "net/http"
121)
122
123var port = flag.Int("port", 8080, "Port to listen on")
124
125func handler(w http.ResponseWriter, r *http.Request) {
126 fmt.Fprintln(w, "Hello from Dodo App!")
127}
128
129func main() {
130 flag.Parse()
131 http.HandleFunc("/", handler)
132 log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), nil))
133}
134`
135
136const appCue = `app: {
137 type: "golang:1.22.0"
138 run: "main.go"
139 ingress: {
140 network: "Private" // or Public
141 subdomain: "testapp"
142 auth: enabled: false
143 }
144}
145`
146
147func initRepo(repo soft.RepoIO) error {
148 return repo.Do(func(fs soft.RepoFS) (string, error) {
149 {
150 w, err := fs.Writer("go.mod")
151 if err != nil {
152 return "", err
153 }
154 defer w.Close()
155 fmt.Fprint(w, goMod)
156 }
157 {
158 w, err := fs.Writer("main.go")
159 if err != nil {
160 return "", err
161 }
162 defer w.Close()
163 fmt.Fprintf(w, "%s", mainGo)
164 }
165 {
166 w, err := fs.Writer("app.cue")
167 if err != nil {
168 return "", err
169 }
170 defer w.Close()
171 fmt.Fprint(w, appCue)
172 }
173 return "go web app template", nil
174 })
175}