RoadSign/pkg/cmd/rds/deploy/commands.go

144 lines
3.8 KiB
Go
Raw Normal View History

2023-12-10 06:52:00 +00:00
package deploy
import (
"context"
"fmt"
2023-12-10 10:55:13 +00:00
"io"
2023-12-10 06:52:00 +00:00
"os"
"path/filepath"
2023-12-10 09:56:17 +00:00
"strings"
2023-12-10 06:52:00 +00:00
"code.smartsheep.studio/goatworks/roadsign/pkg/cmd/rds/conn"
2023-12-10 10:55:13 +00:00
"code.smartsheep.studio/goatworks/roadsign/pkg/sign"
2023-12-10 06:52:00 +00:00
"github.com/gofiber/fiber/v2"
"github.com/google/uuid"
"github.com/rs/zerolog/log"
"github.com/samber/lo"
2023-12-10 11:19:40 +00:00
"github.com/saracen/fastzip"
2023-12-10 06:52:00 +00:00
"github.com/urfave/cli/v2"
2023-12-10 10:55:13 +00:00
"gopkg.in/yaml.v2"
2023-12-10 06:52:00 +00:00
)
var DeployCommands = []*cli.Command{
{
Name: "deploy",
Aliases: []string{"dp"},
ArgsUsage: "<server> <site> <upstream> [path]",
Action: func(ctx *cli.Context) error {
if ctx.Args().Len() < 3 {
return fmt.Errorf("must have three arguments: <server> <site> <upstream> [path]")
}
server, ok := conn.GetConnection(ctx.Args().Get(0))
if !ok {
return fmt.Errorf("server was not found, use \"rds connect\" add one first")
}
// Prepare file to upload
cleanup := true
2023-12-10 09:56:17 +00:00
workdir, _ := os.Getwd()
var filename string
if ctx.Args().Len() < 3 || !strings.HasSuffix(ctx.Args().Get(3), ".zip") {
log.Info().Msg("Preparing file to upload, please stand by...")
2023-12-10 06:52:00 +00:00
2023-12-10 11:19:40 +00:00
dest := lo.Ternary(ctx.Args().Len() > 3, ctx.Args().Get(3), workdir)
2023-12-10 09:56:17 +00:00
filename = filepath.Join(workdir, fmt.Sprintf("rds-deploy-cache-%s.zip", uuid.NewString()))
out, err := os.Create(filename)
if err != nil {
return fmt.Errorf("failed to prepare file: %q", err)
}
defer out.Close()
2023-12-10 06:52:00 +00:00
2023-12-10 11:19:40 +00:00
arc, err := fastzip.NewArchiver(out, dest)
if err != nil {
return err
}
defer arc.Close()
filelist := make(map[string]os.FileInfo)
if err := filepath.Walk(dest, func(pathname string, info os.FileInfo, err error) error {
filelist[pathname] = info
return nil
}); err != nil {
return err
}
if err := arc.Archive(context.Background(), filelist); err != nil {
return err
2023-12-10 09:56:17 +00:00
}
} else if ctx.Args().Len() > 3 {
cleanup = false
2023-12-10 09:56:17 +00:00
filename = ctx.Args().Get(3)
2023-12-10 06:52:00 +00:00
}
// Send request
log.Info().Msg("Now publishing to remote server...")
url := fmt.Sprintf("/webhooks/publish/%s/%s?mimetype=%s", ctx.Args().Get(1), ctx.Args().Get(2), "application/zip")
client := fiber.Put(server.Url+url).
SendFile(filename, "attachments").
MultipartForm(nil).
BasicAuth("RoadSign CLI", server.Credential)
var mistake error
2023-12-10 10:26:04 +00:00
if status, data, err := client.Bytes(); len(err) > 0 {
2023-12-10 06:52:00 +00:00
mistake = fmt.Errorf("failed to publish to remote: %q", err)
} else if status != 200 {
2023-12-10 10:26:04 +00:00
mistake = fmt.Errorf("server rejected request, status code %d, response %s", status, string(data))
2023-12-10 06:52:00 +00:00
}
// Cleanup
if cleanup {
log.Info().Msg("Cleaning up...")
os.Remove(filename)
}
2023-12-10 06:52:00 +00:00
if mistake != nil {
return mistake
}
log.Info().Msg("Well done! Your site is successfully published! 🎉")
2023-12-10 10:55:13 +00:00
return nil
},
},
{
Name: "sync",
Aliases: []string{"sc"},
ArgsUsage: "<server> <site> <configuration path>",
Action: func(ctx *cli.Context) error {
if ctx.Args().Len() < 3 {
return fmt.Errorf("must have three arguments: <server> <site> <configuration path>")
}
server, ok := conn.GetConnection(ctx.Args().Get(0))
if !ok {
return fmt.Errorf("server was not found, use \"rds connect\" add one first")
}
var site sign.SiteConfig
if file, err := os.Open(ctx.Args().Get(2)); err != nil {
return err
} else {
raw, _ := io.ReadAll(file)
yaml.Unmarshal(raw, &site)
}
url := fmt.Sprintf("/webhooks/sync/%s", ctx.Args().Get(1))
client := fiber.Put(server.Url+url).
2023-12-10 11:04:43 +00:00
JSON(site).
2023-12-10 10:55:13 +00:00
BasicAuth("RoadSign CLI", server.Credential)
if status, data, err := client.Bytes(); len(err) > 0 {
return fmt.Errorf("failed to sync to remote: %q", err)
} else if status != 200 {
return fmt.Errorf("server rejected request, status code %d, response %s", status, string(data))
}
log.Info().Msg("Well done! Your site configuration is up-to-date! 🎉")
2023-12-10 06:52:00 +00:00
return nil
},
},
}