@@ -4,9 +4,10 @@ import (
44 "context"
55 "errors"
66 "fmt"
7- "time "
7+ "net/http "
88
99 "github.com/stainless-sdks/gitpod-go"
10+ "github.com/stainless-sdks/gitpod-go/internal/apierror"
1011)
1112
1213type EnvironmentSandbox struct {
@@ -19,84 +20,190 @@ func NewEnvironmentSandbox(client *gitpod.Client) *EnvironmentSandbox {
1920 }
2021}
2122
22- type CreateEnvironmentParams struct {
23+ type CreateEnvironmentOptions struct {
2324 ProjectID string
2425 ContextURL string
2526 EnvironmentClass string
2627}
2728
28- func (s * EnvironmentSandbox ) Create (ctx context.Context , params * CreateEnvironmentParams ) (res * gitpod.EnvironmentGetResponseEnvironment , err error ) {
29- envID , err := s .create (ctx , params )
29+ func (s * EnvironmentSandbox ) Create (ctx context.Context , options * CreateEnvironmentOptions ) (res * gitpod.EnvironmentGetResponseEnvironment , err error ) {
30+ envID , err := s .create (ctx , options )
3031 if err != nil {
3132 return nil , err
3233 }
3334 return s .waitForRunning (ctx , envID )
3435}
3536
37+ type StartEnvironmentOptions struct {
38+ EnvironmentID string
39+ }
40+
41+ func (s * EnvironmentSandbox ) Start (ctx context.Context , options * StartEnvironmentOptions ) (res * gitpod.EnvironmentGetResponseEnvironment , err error ) {
42+ _ , err = s .Client .Environments .Start (ctx , gitpod.EnvironmentStartParams {
43+ EnvironmentID : gitpod .String (options .EnvironmentID ),
44+ })
45+ if err != nil {
46+ return nil , err
47+ }
48+ return s .waitForRunning (ctx , options .EnvironmentID )
49+ }
50+
51+ type StopEnvironmentOptions struct {
52+ EnvironmentID string
53+ }
54+
55+ func (s * EnvironmentSandbox ) Stop (ctx context.Context , options * StopEnvironmentOptions ) (res * gitpod.EnvironmentGetResponseEnvironment , err error ) {
56+ _ , err = s .Client .Environments .Stop (ctx , gitpod.EnvironmentStopParams {
57+ EnvironmentID : gitpod .String (options .EnvironmentID ),
58+ })
59+ if err != nil {
60+ return nil , err
61+ }
62+ return s .waitForStopped (ctx , options .EnvironmentID )
63+ }
64+
65+ type DeleteEnvironmentOptions struct {
66+ EnvironmentID string
67+ }
68+
69+ func (s * EnvironmentSandbox ) Delete (ctx context.Context , options * DeleteEnvironmentOptions ) error {
70+ _ , err := s .Client .Environments .Delete (ctx , gitpod.EnvironmentDeleteParams {
71+ EnvironmentID : gitpod .String (options .EnvironmentID ),
72+ })
73+ if err != nil {
74+ apierr , ok := err .(* apierror.Error )
75+ if ok && apierr .StatusCode == http .StatusNotFound {
76+ return nil
77+ }
78+ return err
79+ }
80+ return s .waitForDeleted (ctx , options .EnvironmentID )
81+ }
82+
83+ func (s * EnvironmentSandbox ) waitForDeleted (ctx context.Context , envID string ) error {
84+ _ , err := s .waitFor (ctx , envID , func () (* gitpod.EnvironmentGetResponseEnvironment , bool , error ) {
85+ resp , err := s .Client .Environments .Get (ctx , gitpod.EnvironmentGetParams {
86+ EnvironmentID : gitpod .String (envID ),
87+ })
88+ if err != nil {
89+ apierr , ok := err .(* apierror.Error )
90+ if ok && apierr .StatusCode == http .StatusNotFound {
91+ return nil , true , nil
92+ }
93+ return nil , false , err
94+ }
95+ return nil , resp .Environment .Status .Phase == gitpod .EnvironmentGetResponseEnvironmentStatusPhaseEnvironmentPhaseDeleted , nil
96+ })
97+ return err
98+ }
99+
100+ func (s * EnvironmentSandbox ) waitForStopped (ctx context.Context , envID string ) (* gitpod.EnvironmentGetResponseEnvironment , error ) {
101+ return s .waitFor (ctx , envID , func () (* gitpod.EnvironmentGetResponseEnvironment , bool , error ) {
102+ resp , err := s .Client .Environments .Get (ctx , gitpod.EnvironmentGetParams {
103+ EnvironmentID : gitpod .String (envID ),
104+ })
105+ if err != nil {
106+ return nil , false , err
107+ }
108+ if resp .Environment .Status .Phase == gitpod .EnvironmentGetResponseEnvironmentStatusPhaseEnvironmentPhaseStopped ||
109+ resp .Environment .Status .Phase == gitpod .EnvironmentGetResponseEnvironmentStatusPhaseEnvironmentPhaseDeleting ||
110+ resp .Environment .Status .Phase == gitpod .EnvironmentGetResponseEnvironmentStatusPhaseEnvironmentPhaseDeleted {
111+ return & resp .Environment , true , nil
112+ }
113+ return nil , false , nil
114+ })
115+ }
116+
36117func (s * EnvironmentSandbox ) waitForRunning (ctx context.Context , envID string ) (* gitpod.EnvironmentGetResponseEnvironment , error ) {
37- tick := time .NewTicker (500 * time .Microsecond )
38- defer tick .Stop ()
39- for {
40- select {
41- case <- ctx .Done ():
42- return nil , ctx .Err ()
43- case <- tick .C :
44- resp , err := s .Client .Environments .Get (ctx , gitpod.EnvironmentGetParams {
45- EnvironmentID : gitpod .String (envID ),
46- })
118+ return s .waitFor (ctx , envID , func () (* gitpod.EnvironmentGetResponseEnvironment , bool , error ) {
119+ resp , err := s .Client .Environments .Get (ctx , gitpod.EnvironmentGetParams {
120+ EnvironmentID : gitpod .String (envID ),
121+ })
122+ if err != nil {
123+ return nil , false , err
124+ }
125+
126+ if fm := resp .Environment .Status .FailureMessage ; len (fm ) > 0 {
127+ return nil , false , fmt .Errorf ("environment creation failed: %s" , fm )
128+ }
129+ if resp .Environment .Status .Phase == gitpod .EnvironmentGetResponseEnvironmentStatusPhaseEnvironmentPhaseRunning {
130+ return & resp .Environment , true , nil
131+ }
132+ if resp .Environment .Status .Phase == gitpod .EnvironmentGetResponseEnvironmentStatusPhaseEnvironmentPhaseStopping {
133+ return nil , false , errors .New ("environment creation failed: environment is stopping" )
134+ }
135+ if resp .Environment .Status .Phase == gitpod .EnvironmentGetResponseEnvironmentStatusPhaseEnvironmentPhaseStopped {
136+ return nil , false , errors .New ("environment creation failed: environment is stopped" )
137+ }
138+ if resp .Environment .Status .Phase == gitpod .EnvironmentGetResponseEnvironmentStatusPhaseEnvironmentPhaseDeleting {
139+ return nil , false , errors .New ("environment creation failed: environment is deleting" )
140+ }
141+ if resp .Environment .Status .Phase == gitpod .EnvironmentGetResponseEnvironmentStatusPhaseEnvironmentPhaseDeleted {
142+ return nil , false , errors .New ("environment creation failed: environment is deleted" )
143+ }
144+ return nil , false , nil
145+ })
146+ }
147+
148+ func (s * EnvironmentSandbox ) waitFor (ctx context.Context , envID string , fetch func () (* gitpod.EnvironmentGetResponseEnvironment , bool , error )) (* gitpod.EnvironmentGetResponseEnvironment , error ) {
149+ env , ok , err := fetch ()
150+ if err != nil {
151+ return nil , err
152+ }
153+ if ok {
154+ return env , nil
155+ }
156+
157+ stream := s .Client .Events .WatchStreaming (ctx , gitpod.EventWatchParams {
158+ Body : gitpod.EventWatchParamsBodyEnvironmentScopeProducesEventsForTheEnvironmentItselfAllTasksTaskExecutionsAndServicesAssociatedWithThatEnvironment {
159+ EnvironmentID : gitpod .String (envID ),
160+ },
161+ })
162+ defer stream .Close ()
163+
164+ for stream .Next () {
165+ resp := stream .Current ()
166+ if resp .ResourceType == gitpod .EventWatchResponseResourceTypeResourceTypeEnvironment && resp .ResourceID == envID {
167+ env , ok , err := fetch ()
47168 if err != nil {
48169 // TODO: if transient we should retry?
49170 return nil , err
50171 }
51-
52- if fm := resp .Environment .Status .FailureMessage ; len (fm ) > 0 {
53- return nil , fmt .Errorf ("environment creation failed: %s" , fm )
54- }
55- if resp .Environment .Status .Phase == gitpod .EnvironmentGetResponseEnvironmentStatusPhaseEnvironmentPhaseRunning {
56- return & resp .Environment , nil
57- }
58- if resp .Environment .Status .Phase == gitpod .EnvironmentGetResponseEnvironmentStatusPhaseEnvironmentPhaseStopping {
59- return nil , errors .New ("environment creation failed: environment is stopping" )
60- }
61- if resp .Environment .Status .Phase == gitpod .EnvironmentGetResponseEnvironmentStatusPhaseEnvironmentPhaseStopped {
62- return nil , errors .New ("environment creation failed: environment is stopped" )
63- }
64- if resp .Environment .Status .Phase == gitpod .EnvironmentGetResponseEnvironmentStatusPhaseEnvironmentPhaseDeleting {
65- return nil , errors .New ("environment creation failed: environment is deleting" )
66- }
67- if resp .Environment .Status .Phase == gitpod .EnvironmentGetResponseEnvironmentStatusPhaseEnvironmentPhaseDeleted {
68- return nil , errors .New ("environment creation failed: environment is deleted" )
172+ if ok {
173+ return env , nil
69174 }
70175 }
71176 }
177+
178+ return nil , stream .Err ()
72179}
73180
74- func (s * EnvironmentSandbox ) create (ctx context.Context , params * CreateEnvironmentParams ) (string , error ) {
75- if params .ProjectID != "" {
181+ func (s * EnvironmentSandbox ) create (ctx context.Context , options * CreateEnvironmentOptions ) (string , error ) {
182+ if options .ProjectID != "" {
76183 resp , err := s .Client .Environments .NewFromProject (ctx , gitpod.EnvironmentNewFromProjectParams {
77- ProjectID : gitpod .String (params .ProjectID ),
184+ ProjectID : gitpod .String (options .ProjectID ),
78185 })
79186 if err != nil {
80187 return "" , err
81188 }
82189 return resp .Environment .ID , nil
83190 }
84- if params .ContextURL != "" {
85- if params .EnvironmentClass == "" {
191+ if options .ContextURL != "" {
192+ if options .EnvironmentClass == "" {
86193 return "" , errors .New ("environmentClass must be provided when contextURL is provided" )
87194 }
88195 resp , err := s .Client .Environments .New (ctx , gitpod.EnvironmentNewParams {
89196 Spec : gitpod .F (gitpod.EnvironmentNewParamsSpec {
90197 DesiredPhase : gitpod .F (gitpod .EnvironmentNewParamsSpecDesiredPhaseEnvironmentPhaseRunning ),
91198 Machine : gitpod .F (gitpod.EnvironmentNewParamsSpecMachine {
92- Class : gitpod .String (params .EnvironmentClass ),
199+ Class : gitpod .String (options .EnvironmentClass ),
93200 }),
94201 Content : gitpod .F (gitpod.EnvironmentNewParamsSpecContent {
95202 Initializer : gitpod .F (gitpod.EnvironmentNewParamsSpecContentInitializer {
96203 Specs : gitpod .F ([]gitpod.EnvironmentNewParamsSpecContentInitializerSpecUnion {
97204 gitpod.EnvironmentNewParamsSpecContentInitializerSpecsContextURL {
98205 ContextURL : gitpod .F (gitpod.EnvironmentNewParamsSpecContentInitializerSpecsContextURLContextURL {
99- URL : gitpod .String (params .ContextURL ),
206+ URL : gitpod .String (options .ContextURL ),
100207 }),
101208 },
102209 }),
0 commit comments