Skip to content

Commit

Permalink
new cli and api
Browse files Browse the repository at this point in the history
  • Loading branch information
anthdm committed Jan 8, 2024
1 parent 8404ccd commit ab1fe4b
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 159 deletions.
3 changes: 1 addition & 2 deletions cmd/api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ func seedEndpoint(store storage.Store, cache storage.ModCacher) {

deploy := types.NewDeployment(endpoint, b)
endpoint.ActiveDeploymentID = deploy.ID
endpoint.URL = config.GetWasmUrl() + "/" + endpoint.ID.String()
endpoint.DeploymentHistory = append(endpoint.DeploymentHistory, &types.DeploymentHistory{
ID: deploy.ID,
CreatedAT: deploy.CreatedAT,
Expand All @@ -82,7 +81,7 @@ func seedEndpoint(store storage.Store, cache storage.ModCacher) {
if err != nil {
log.Fatal(err)
}
fmt.Printf("endpoint seeded: %s\n", endpoint.URL)
fmt.Printf("endpoint seeded: %s/live/%s\n", config.GetWasmUrl(), endpoint.ID)
}

func compile(ctx context.Context, cache wazero.CompilationCache, blob []byte) {
Expand Down
173 changes: 52 additions & 121 deletions cmd/cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,15 @@ import (

func printUsage() {
fmt.Printf(`
Usage: raptor [OPTIONS] COMMAND
Raptor cli v0.0.1
Options:
--env Set and environment variable [--env foo=bar]
--config Set the configuration path [--config path/to/config.toml]
--runtime Set the runtime of your application [--runtime go or js]
Usage: raptor COMMAND
Commands:
endpoint Create a new endpoint [options... endpoint "myendpoint"]
test Test your application [options... test "path/to/app.wasm(js)"]
Subcommands:
create Create a new endpoint [options... endpoint create "myendpoint"]
list List current endpoints
deploy Deploy an app to the cloud [deploy <endpointID path/to/app.wasm>]
help Show usage
endpoint Create a new endpoint
publish Publish a specific deployment to your applications endpoint
deploy Create a new deployment
help Show usage
`)
os.Exit(0)
Expand All @@ -51,23 +43,13 @@ func (l *stringList) String() string {
return strings.Join(*l, ":")
}

var (
env stringList
endpointID string
configFile string
runtime string
addr string
)

func main() {
flagset := flag.NewFlagSet("cli", flag.ExitOnError)
flagset.Usage = printUsage
flagset.StringVar(&endpointID, "endpoint", "", "")
flagset.StringVar(&configFile, "config", "config.toml", "")
flagset.StringVar(&addr, "addr", ":3000", "")
flagset.StringVar(&runtime, "runtime", "", "")

flagset.Var(&env, "env", "")
var configFile string
flagset.StringVar(&configFile, "config", "config.toml", "The location of your raptor config file")

flagset.Usage = printUsage
flagset.Parse(os.Args[1:])

if err := config.Parse(configFile); err != nil {
Expand All @@ -85,24 +67,11 @@ func main() {
}

switch args[0] {
case "publish":
command.handlePublish(args[1:])
case "endpoint":
if len(args) < 2 {
printUsage()
}
switch args[1] {
case "rollback":
command.handleRollback(args)
case "create":
command.handleCreateEndpoint(args)
case "list":
command.handleListEndpoints(args)
default:
printUsage()
}
command.handleEndpoint(args[1:])
case "deploy":
if len(args) < 2 {
printUsage()
}
command.handleDeploy(args[1:])
case "serve":
if len(args) < 2 {
Expand All @@ -120,21 +89,20 @@ type command struct {
client *client.Client
}

// endpoint rollback <endpointID> <deployID>
func (c command) handleRollback(args []string) {
if len(args) != 4 {
printUsage()
}
endpointID, err := uuid.Parse(args[2])
if err != nil {
printErrorAndExit(err)
}
deployID, err := uuid.Parse(args[3])
func (c command) handlePublish(args []string) {
flagset := flag.NewFlagSet("endpoint", flag.ExitOnError)

var deployID string
flagset.StringVar(&deployID, "deploy", "", "The id of the deployment that you want to publish LIVE")
_ = flagset.Parse(args)

id, err := uuid.Parse(deployID)
if err != nil {
printErrorAndExit(err)
}
params := api.CreateRollbackParams{DeployID: deployID}
resp, err := c.client.RollbackEndpoint(endpointID, params)

params := api.PublishParams{DeploymentID: id}
resp, err := c.client.Publish(params)
if err != nil {
printErrorAndExit(err)
}
Expand All @@ -145,28 +113,28 @@ func (c command) handleRollback(args []string) {
fmt.Println(string(b))
}

func (c command) handleListEndpoints(args []string) {
endpoints, err := c.client.ListEndpoints()
if err != nil {
printErrorAndExit(err)
}
b, err := json.MarshalIndent(endpoints, "", " ")
if err != nil {
printErrorAndExit(err)
}
fmt.Println(string(b))
}
func (c command) handleEndpoint(args []string) {
flagset := flag.NewFlagSet("endpoint", flag.ExitOnError)

var name string
flagset.StringVar(&name, "name", "", "The name of your endpoint")
var runtime string
flagset.StringVar(&runtime, "runtime", "", "The runtime of your endpoint (go or js)")
var env stringList
flagset.Var(&env, "env", "Environment variables for this endpoint")
_ = flagset.Parse(args)

func (c command) handleCreateEndpoint(args []string) {
if len(args) != 3 {
printUsage()
}
if !types.ValidRuntime(runtime) {
printUsage()
fmt.Printf("invalid runtime %s, only go and js are currently supported\n", runtime)
os.Exit(1)
}
if len(name) == 0 {
fmt.Println("The name of the endpoint is not provided. --name <name>")
os.Exit(1)
}
params := api.CreateEndpointParams{
Runtime: runtime,
Name: args[2],
Name: name,
Environment: makeEnvMap(env),
}
endpoint, err := c.client.CreateEndpoint(params)
Expand All @@ -181,14 +149,19 @@ func (c command) handleCreateEndpoint(args []string) {
}

func (c command) handleDeploy(args []string) {
if len(args) != 2 {
printUsage()
}
id, err := uuid.Parse(args[0])
flagset := flag.NewFlagSet("deploy", flag.ExitOnError)

var endpointID string
flagset.StringVar(&endpointID, "endpoint", "", "The id of the endpoint to where you want to deploy")
var file string
flagset.StringVar(&file, "file", "", "The file location of your code that you want to deploy")
_ = flagset.Parse(args)

id, err := uuid.Parse(endpointID)
if err != nil {
printErrorAndExit(fmt.Errorf("invalid endpoint id given: %s", args[0]))
}
b, err := os.ReadFile(args[1])
b, err := os.ReadFile(file)
if err != nil {
printErrorAndExit(err)
}
Expand All @@ -202,53 +175,11 @@ func (c command) handleDeploy(args []string) {
}
fmt.Println(string(b))
fmt.Println()
fmt.Printf("deploy is live on: %s/%s\n", config.GetWasmUrl(), deploy.EndpointID)
fmt.Printf("deploy preview: %s/preview/%s\n", config.GetWasmUrl(), deploy.ID)
}

func (c command) handleServeEndpoint(args []string) {
fmt.Println("TODO")
// b, err := os.ReadFile(args[0])
// if err != nil {
// printErrorAndExit(err)
// }

// out := &bytes.Buffer{}

// http.ListenAndServe(addr, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// if r.URL.Path == "/favicon.ico" {
// return
// }
// preq, err := shared.MakeProtoRequest(uuid.NewString(), r)
// if err != nil {
// w.Write([]byte(err.Error()))
// return
// }
// fmt.Println(preq)
// reqb, err := proto.Marshal(preq)
// if err != nil {
// w.Write([]byte(err.Error()))
// return
// }

// invokeArgs := run.InvokeArgs{
// Blob: b,
// Out: out,
// In: bytes.NewBuffer(reqb),
// }

// if err := run.Invoke(r.Context(), invokeArgs); err != nil {
// w.Write([]byte(err.Error()))
// return
// }

// resp, status, err := shared.ParseRuntimeHTTPResponse(out.String())
// if err != nil {
// w.Write([]byte(err.Error()))
// return
// }
// w.WriteHeader(status)
// w.Write([]byte(resp))
// }))
}

func makeEnvMap(list []string) map[string]string {
Expand Down
2 changes: 1 addition & 1 deletion pkg/actrs/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (r *Runtime) handleHTTPRequest(ctx *actor.Context, msg *proto.HTTPRequest)
r.deployID = uuid.MustParse(msg.DeploymentID)
deploy, err := r.store.GetDeployment(r.deployID)
if err != nil {
slog.Warn("runtime could not find the endpoint's active deploy from store", "err", err)
slog.Warn("runtime could not find deploy from store", "err", err, "id", r.deployID)
respondError(ctx, http.StatusInternalServerError, "internal server error", msg.ID)
return
}
Expand Down
5 changes: 4 additions & 1 deletion pkg/actrs/wasmserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ func (s *WasmServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
req.Runtime = endpoint.Runtime
req.EndpointID = endpointID.String()
// When serving LIVE endpoints we use the active deployment id.
req.DeploymentID = endpoint.ActiveDeploymentID.String()
req.Env = endpoint.Environment
req.Preview = false
Expand All @@ -151,7 +152,9 @@ func (s *WasmServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
req.Runtime = endpoint.Runtime
req.EndpointID = endpoint.ID.String()
req.DeploymentID = endpoint.ActiveDeploymentID.String()
// When serving PREVIEW endpoints, we just use the deployment id from the
// request.
req.DeploymentID = deploy.ID.String()
req.Env = endpoint.Environment
req.Preview = true
}
Expand Down
44 changes: 23 additions & 21 deletions pkg/api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func (s *Server) initRouter() {
s.router.Get("/endpoint/{id}/metrics", makeAPIHandler(s.handleGetEndpointMetrics))
s.router.Post("/endpoint", makeAPIHandler(s.handleCreateEndpoint))
s.router.Post("/endpoint/{id}/deployment", makeAPIHandler(s.handleCreateDeployment))
s.router.Post("/endpoint/{id}/rollback", makeAPIHandler(s.handleCreateRollback))
s.router.Post("/publish/{id}", makeAPIHandler(s.handlePublish))
}

func handleStatus(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -96,7 +96,6 @@ func (s *Server) handleCreateEndpoint(w http.ResponseWriter, r *http.Request) er
}

endpoint := types.NewEndpoint(params.Name, params.Runtime, params.Environment)
endpoint.URL = config.GetWasmUrl() + "/" + endpoint.ID.String()
if err := s.store.CreateEndpoint(endpoint); err != nil {
return writeJSON(w, http.StatusBadRequest, ErrorResponse(err))
}
Expand Down Expand Up @@ -147,53 +146,56 @@ func (s *Server) handleGetEndpoints(w http.ResponseWriter, r *http.Request) erro
return writeJSON(w, http.StatusOK, endpoints)
}

// CreateRollbackParams holds all the necessary fields to rollback your application
// to a specific deploy id (version).
type CreateRollbackParams struct {
DeployID uuid.UUID `json:"deploy_id"`
// PublishParams holds all the necessary fields to publish a specific
// deployment to your application.
type PublishParams struct {
DeploymentID uuid.UUID `json:"deployment_id"`
}

type CreateRollbackResponse struct {
DeployID uuid.UUID `json:"deploy_id"`
type PublishResponse struct {
DeploymentID uuid.UUID `json:"deployment_id"`
URL string `json:"url"`
}

func (s *Server) handleCreateRollback(w http.ResponseWriter, r *http.Request) error {
endpointID, err := uuid.Parse(chi.URLParam(r, "id"))
func (s *Server) handlePublish(w http.ResponseWriter, r *http.Request) error {
deployID, err := uuid.Parse(chi.URLParam(r, "id"))
if err != nil {
return writeJSON(w, http.StatusBadRequest, ErrorResponse(err))
}
endpoint, err := s.store.GetEndpoint(endpointID)
deploy, err := s.store.GetDeployment(deployID)
if err != nil {
return writeJSON(w, http.StatusBadRequest, ErrorResponse(err))
}
endpoint, err := s.store.GetEndpoint(deploy.EndpointID)
if err != nil {
return writeJSON(w, http.StatusBadRequest, ErrorResponse(err))
}

currentDeploymentID := endpoint.ActiveDeploymentID

var params CreateRollbackParams
var params PublishParams
if err := json.NewDecoder(r.Body).Decode(&params); err != nil {
return writeJSON(w, http.StatusBadRequest, ErrorResponse(err))
}

if currentDeploymentID.String() == params.DeployID.String() {
err := fmt.Errorf("deploy %s already active", params.DeployID)
if currentDeploymentID.String() == params.DeploymentID.String() {
err := fmt.Errorf("deploy %s already active", params.DeploymentID)
return writeJSON(w, http.StatusBadRequest, ErrorResponse(err))
}

deploy, err := s.store.GetDeployment(params.DeployID)
if err != nil {
return writeJSON(w, http.StatusNotFound, ErrorResponse(err))
}

updateParams := storage.UpdateEndpointParams{
ActiveDeployID: deploy.ID,
}
if err := s.store.UpdateEndpoint(endpointID, updateParams); err != nil {
if err := s.store.UpdateEndpoint(deploy.EndpointID, updateParams); err != nil {
return writeJSON(w, http.StatusBadRequest, ErrorResponse(err))
}

s.cache.Delete(currentDeploymentID)

resp := CreateRollbackResponse{DeployID: deploy.ID}
resp := PublishResponse{
DeploymentID: deploy.ID,
URL: fmt.Sprintf("%s/live/%s", config.GetWasmUrl(), endpoint.ID),
}
return writeJSON(w, http.StatusOK, resp)
}

Expand Down
Loading

0 comments on commit ab1fe4b

Please sign in to comment.