blob: d9f9a690ad2752e41f69b3844c72b6b2c0ef316b [file] [log] [blame]
package main
import (
"encoding/json"
"errors"
"fmt"
"log"
"os"
"github.com/giolekva/pcloud/core/installer"
"github.com/giolekva/pcloud/core/installer/soft"
"github.com/giolekva/pcloud/core/installer/welcome"
"github.com/spf13/cobra"
)
var dodoAppFlags struct {
port int
sshKey string
repoAddr string
self string
namespace string
envConfig string
}
func dodoAppCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "dodo-app",
RunE: dodoAppCmdRun,
}
cmd.Flags().IntVar(
&dodoAppFlags.port,
"port",
8080,
"",
)
cmd.Flags().StringVar(
&dodoAppFlags.repoAddr,
"repo-addr",
"",
"",
)
cmd.Flags().StringVar(
&dodoAppFlags.sshKey,
"ssh-key",
"",
"",
)
cmd.Flags().StringVar(
&dodoAppFlags.self,
"self",
"",
"",
)
cmd.Flags().StringVar(
&dodoAppFlags.namespace,
"namespace",
"",
"",
)
cmd.Flags().StringVar(
&dodoAppFlags.envConfig,
"env-config",
"",
"",
)
return cmd
}
func dodoAppCmdRun(cmd *cobra.Command, args []string) error {
envConfig, err := os.Open(dodoAppFlags.envConfig)
if err != nil {
return err
}
defer envConfig.Close()
var env installer.EnvConfig
if err := json.NewDecoder(envConfig).Decode(&env); err != nil {
return err
}
sshKey, err := os.ReadFile(dodoAppFlags.sshKey)
if err != nil {
return err
}
softClient, err := soft.NewClient(dodoAppFlags.repoAddr, sshKey, log.Default())
if err != nil {
return err
}
if err := softClient.AddRepository("app"); err == nil {
repo, err := softClient.GetRepo("app")
if err != nil {
return err
}
if err := initRepo(repo); err != nil {
return err
}
if err := welcome.UpdateDodoApp(softClient, dodoAppFlags.namespace, string(sshKey), &env); err != nil {
return err
}
if err := softClient.AddWebhook("app", fmt.Sprintf("http://%s/update", dodoAppFlags.self), "--active=true", "--events=push", "--content-type=json"); err != nil {
return err
}
} else if !errors.Is(err, soft.ErrorAlreadyExists) {
return err
}
s := welcome.NewDodoAppServer(dodoAppFlags.port, string(sshKey), softClient, dodoAppFlags.namespace, env)
return s.Start()
}
const goMod = `module dodo.app
go 1.18
`
const mainGo = `package main
import (
"flag"
"fmt"
"log"
"net/http"
)
var port = flag.Int("port", 8080, "Port to listen on")
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello from Dodo App!")
}
func main() {
flag.Parse()
http.HandleFunc("/", handler)
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), nil))
}
`
const appCue = `app: {
type: "golang:1.22.0"
run: "main.go"
ingress: {
network: "Private" // or Public
subdomain: "testapp"
auth: enabled: false
}
}
`
func initRepo(repo soft.RepoIO) error {
return repo.Do(func(fs soft.RepoFS) (string, error) {
{
w, err := fs.Writer("go.mod")
if err != nil {
return "", err
}
defer w.Close()
fmt.Fprint(w, goMod)
}
{
w, err := fs.Writer("main.go")
if err != nil {
return "", err
}
defer w.Close()
fmt.Fprintf(w, "%s", mainGo)
}
{
w, err := fs.Writer("app.cue")
if err != nil {
return "", err
}
defer w.Close()
fmt.Fprint(w, appCue)
}
return "go web app template", nil
})
}