From ba5d4b8cac0b852c1aa1b925034613cb9ce0e55e Mon Sep 17 00:00:00 2001 From: Garrett Delfosse Date: Fri, 4 Sep 2020 09:23:47 +0000 Subject: [PATCH 1/3] Add ws dials for resource load and ide status --- coder-sdk/env.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/coder-sdk/env.go b/coder-sdk/env.go index 5113dee2..952d1e78 100644 --- a/coder-sdk/env.go +++ b/coder-sdk/env.go @@ -78,14 +78,14 @@ type CreateEnvironmentRequest struct { // CreateEnvironment sends a request to create an environment. func (c Client) CreateEnvironment(ctx context.Context, orgID string, req CreateEnvironmentRequest) (*Environment, error) { - var env *Environment + var env Environment err := c.requestBody( ctx, http.MethodPost, "/api/orgs/"+orgID+"/environments", req, - env, + &env, ) - return env, err + return &env, err } // EnvironmentsByOrganization gets the list of environments owned by the given user. @@ -116,6 +116,11 @@ func (c Client) DialWsep(ctx context.Context, env *Environment) (*websocket.Conn return c.dialWs(ctx, "/proxy/environments/"+env.ID+"/wsep") } +// DialIDEStatus opens a websocket connection for cpu load metrics on the environment +func (c Client) DialIDEStatus(ctx context.Context, envID string) (*websocket.Conn, error) { + return c.dialWs(ctx, "/proxy/environments/"+envID+"/ide/api/status") +} + // DialEnvironmentBuildLog opens a websocket connection for the environment build log messages func (c Client) DialEnvironmentBuildLog(ctx context.Context, envID string) (*websocket.Conn, error) { return c.dialWs(ctx, "/api/environments/"+envID+"/watch-update") @@ -125,3 +130,8 @@ func (c Client) DialEnvironmentBuildLog(ctx context.Context, envID string) (*web func (c Client) DialEnvironmentStats(ctx context.Context, envID string) (*websocket.Conn, error) { return c.dialWs(ctx, "/api/environments/"+envID+"/watch-stats") } + +// DialResourceLoad opens a websocket connection for cpu load metrics on the environment +func (c Client) DialResourceLoad(ctx context.Context, envID string) (*websocket.Conn, error) { + return c.dialWs(ctx, "/api/environments/"+envID+"/watch-resource-load") +} From 77d3e643dbbf13a31cf59a52343a3a73f895f231 Mon Sep 17 00:00:00 2001 From: Garrett Delfosse Date: Fri, 4 Sep 2020 16:26:10 +0000 Subject: [PATCH 2/3] Add WaitForEnvironmentReady utility --- coder-sdk/env.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/coder-sdk/env.go b/coder-sdk/env.go index 952d1e78..22d7f591 100644 --- a/coder-sdk/env.go +++ b/coder-sdk/env.go @@ -2,11 +2,13 @@ package coder import ( "context" + "fmt" "net/http" "time" "cdr.dev/coder-cli/internal/x/xjson" "nhooyr.io/websocket" + "nhooyr.io/websocket/wsjson" ) // Environment describes a Coder environment @@ -135,3 +137,27 @@ func (c Client) DialEnvironmentStats(ctx context.Context, envID string) (*websoc func (c Client) DialResourceLoad(ctx context.Context, envID string) (*websocket.Conn, error) { return c.dialWs(ctx, "/api/environments/"+envID+"/watch-resource-load") } + +type buildLogMsg struct { + Type string `json:"type"` +} + +// WaitForEnvironmentReady will watch the build log and return when done +func (c Client) WaitForEnvironmentReady(ctx context.Context, env *Environment) error { + conn, err := c.DialEnvironmentBuildLog(ctx, env.ID) + if err != nil { + return fmt.Errorf("%s: dial build log: %w", env.Name, err) + } + + for { + msg := buildLogMsg{} + err := wsjson.Read(ctx, conn, &msg) + if err != nil { + return fmt.Errorf("%s: reading build log msg: %w", env.Name, err) + } + + if msg.Type == "done" { + return nil + } + } +} From 89752dff12db022ccd13e0968c77a435892d47b5 Mon Sep 17 00:00:00 2001 From: Garrett Delfosse Date: Fri, 4 Sep 2020 17:11:44 +0000 Subject: [PATCH 3/3] Add build log types --- coder-sdk/env.go | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/coder-sdk/env.go b/coder-sdk/env.go index 22d7f591..8984e944 100644 --- a/coder-sdk/env.go +++ b/coder-sdk/env.go @@ -2,11 +2,11 @@ package coder import ( "context" - "fmt" "net/http" "time" "cdr.dev/coder-cli/internal/x/xjson" + "golang.org/x/xerrors" "nhooyr.io/websocket" "nhooyr.io/websocket/wsjson" ) @@ -138,25 +138,45 @@ func (c Client) DialResourceLoad(ctx context.Context, envID string) (*websocket. return c.dialWs(ctx, "/api/environments/"+envID+"/watch-resource-load") } +// BuildLogType describes the type of an event. +type BuildLogType string + +const ( + // BuildLogTypeStart signals that a new build log has begun. + BuildLogTypeStart BuildLogType = "start" + // BuildLogTypeStage is a stage-level event for an environment. + // It can be thought of as a major step in the environment's + // lifecycle. + BuildLogTypeStage BuildLogType = "stage" + // BuildLogTypeError describes an error that has occurred. + BuildLogTypeError BuildLogType = "error" + // BuildLogTypeSubstage describes a subevent that occurs as + // part of a stage. This can be the output from a user's + // personalization script, or a long running command. + BuildLogTypeSubstage BuildLogType = "substage" + // BuildLogTypeDone signals that the build has completed. + BuildLogTypeDone BuildLogType = "done" +) + type buildLogMsg struct { - Type string `json:"type"` + Type BuildLogType `json:"type"` } // WaitForEnvironmentReady will watch the build log and return when done func (c Client) WaitForEnvironmentReady(ctx context.Context, env *Environment) error { conn, err := c.DialEnvironmentBuildLog(ctx, env.ID) if err != nil { - return fmt.Errorf("%s: dial build log: %w", env.Name, err) + return xerrors.Errorf("%s: dial build log: %w", env.Name, err) } for { msg := buildLogMsg{} err := wsjson.Read(ctx, conn, &msg) if err != nil { - return fmt.Errorf("%s: reading build log msg: %w", env.Name, err) + return xerrors.Errorf("%s: reading build log msg: %w", env.Name, err) } - if msg.Type == "done" { + if msg.Type == BuildLogTypeDone { return nil } }