@@ -9,8 +9,10 @@ import (
99 "fmt"
1010 "os"
1111 "os/exec"
12+ "os/signal"
1213 "path/filepath"
1314 "strings"
15+ "syscall"
1416 "time"
1517
1618 "github.com/gitpod-io/gitpod/gitpod-cli/pkg/supervisor"
@@ -19,8 +21,8 @@ import (
1921 "github.com/spf13/cobra"
2022)
2123
22- func TerminateExistingContainer () error {
23- cmd := exec .Command ( "docker" , "ps" , "-q" , "-f" , "label=gp-rebuild" )
24+ func TerminateExistingContainer (ctx context. Context ) error {
25+ cmd := exec .CommandContext ( ctx , "docker" , "ps" , "-q" , "-f" , "label=gp-rebuild" )
2426 containerIds , err := cmd .Output ()
2527 if err != nil {
2628 return err
@@ -31,13 +33,13 @@ func TerminateExistingContainer() error {
3133 continue
3234 }
3335
34- cmd = exec .Command ( "docker" , "stop" , id )
36+ cmd = exec .CommandContext ( ctx , "docker" , "stop" , id )
3537 err := cmd .Run ()
3638 if err != nil {
3739 return err
3840 }
3941
40- cmd = exec .Command ( "docker" , "rm" , "-f" , id )
42+ cmd = exec .CommandContext ( ctx , "docker" , "rm" , "-f" , id )
4143 err = cmd .Run ()
4244 if err != nil {
4345 return err
@@ -47,17 +49,15 @@ func TerminateExistingContainer() error {
4749 return nil
4850}
4951
50- func runRebuild (ctx context.Context , supervisorClient * supervisor.SupervisorClient , event * utils.EventTracker ) error {
52+ func runRebuild (ctx context.Context , supervisorClient * supervisor.SupervisorClient , event * utils.EventTracker ) ( string , error ) {
5153 wsInfo , err := supervisorClient .Info .WorkspaceInfo (ctx , & api.WorkspaceInfoRequest {})
5254 if err != nil {
53- event .Set ("ErrorCode" , utils .SystemErrorCode )
54- return err
55+ return utils .Outcome_SystemErr , err
5556 }
5657
5758 tmpDir , err := os .MkdirTemp ("" , "gp-rebuild-*" )
5859 if err != nil {
59- event .Set ("ErrorCode" , utils .SystemErrorCode )
60- return err
60+ return utils .Outcome_SystemErr , err
6161 }
6262 defer os .RemoveAll (tmpDir )
6363
@@ -68,7 +68,7 @@ func runRebuild(ctx context.Context, supervisorClient *supervisor.SupervisorClie
6868 fmt .Println ("For help check out the reference page:" )
6969 fmt .Println ("https://www.gitpod.io/docs/references/gitpod-yml#gitpodyml" )
7070 event .Set ("ErrorCode" , utils .RebuildErrorCode_MalformedGitpodYaml )
71- return err
71+ return utils . Outcome_UserErr , err
7272 }
7373
7474 if gitpodConfig == nil {
@@ -79,7 +79,7 @@ func runRebuild(ctx context.Context, supervisorClient *supervisor.SupervisorClie
7979 fmt .Println ("Alternatively, check out the following docs for getting started configuring your project" )
8080 fmt .Println ("https://www.gitpod.io/docs/configure#configure-gitpod" )
8181 event .Set ("ErrorCode" , utils .RebuildErrorCode_MissingGitpodYaml )
82- return err
82+ return utils . Outcome_UserErr , nil
8383 }
8484
8585 var baseimage string
@@ -93,13 +93,11 @@ func runRebuild(ctx context.Context, supervisorClient *supervisor.SupervisorClie
9393
9494 if _ , err := os .Stat (dockerfilePath ); os .IsNotExist (err ) {
9595 fmt .Println ("Your .gitpod.yml points to a Dockerfile that doesn't exist: " + dockerfilePath )
96- event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerfileNotFound ).Send (ctx )
97- return err
96+ return utils .Outcome_UserErr , err
9897 }
9998 dockerfile , err := os .ReadFile (dockerfilePath )
10099 if err != nil {
101- event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerfileCannotRead )
102- return err
100+ return utils .Outcome_SystemErr , err
103101 }
104102 if string (dockerfile ) == "" {
105103 fmt .Println ("Your Gitpod's Dockerfile is empty" )
@@ -108,14 +106,13 @@ func runRebuild(ctx context.Context, supervisorClient *supervisor.SupervisorClie
108106 fmt .Println ("https://www.gitpod.io/docs/configure/workspaces/workspace-image#use-a-custom-dockerfile" )
109107 fmt .Println ("" )
110108 fmt .Println ("Once you configure your Dockerfile, re-run this command to validate your changes" )
111- event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerfileEmpty )
112- return err
109+ return utils .Outcome_UserErr , nil
113110 }
114111 baseimage = "\n " + string (dockerfile ) + "\n "
115112 default :
116113 fmt .Println ("Check your .gitpod.yml and make sure the image property is configured correctly" )
117114 event .Set ("ErrorCode" , utils .RebuildErrorCode_MalformedGitpodYaml )
118- return err
115+ return utils . Outcome_UserErr , nil
119116 }
120117
121118 if baseimage == "" {
@@ -124,94 +121,107 @@ func runRebuild(ctx context.Context, supervisorClient *supervisor.SupervisorClie
124121 fmt .Println ("" )
125122 fmt .Println ("https://www.gitpod.io/docs/configure/workspaces/workspace-image#use-a-public-docker-image" )
126123 event .Set ("ErrorCode" , utils .RebuildErrorCode_NoCustomImage )
127- return err
124+ return utils . Outcome_UserErr , nil
128125 }
129126
130- err = os .WriteFile (filepath .Join (tmpDir , "Dockerfile" ), []byte (baseimage ), 0644 )
127+ tmpDockerfile := filepath .Join (tmpDir , "Dockerfile" )
128+
129+ err = os .WriteFile (tmpDockerfile , []byte (baseimage ), 0644 )
131130 if err != nil {
132131 fmt .Println ("Could not write the temporary Dockerfile" )
133- event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerfileCannotWirte )
134- return err
132+ return utils .Outcome_SystemErr , err
135133 }
136134
137135 dockerPath , err := exec .LookPath ("docker" )
138136 if err != nil {
139137 fmt .Println ("Docker is not installed in your workspace" )
140138 event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerNotFound )
141- return err
139+ return utils . Outcome_SystemErr , err
142140 }
143141
144142 tag := "gp-rebuild-temp-build"
145143
146- dockerCmd := exec .Command (dockerPath , "build" , "-t" , tag , "--progress=tty" , "." )
147- dockerCmd .Dir = tmpDir
144+ dockerCmd := exec .CommandContext (ctx , dockerPath , "build" , "-f" , tmpDockerfile , "-t" , tag , wsInfo .CheckoutLocation )
148145 dockerCmd .Stdout = os .Stdout
149146 dockerCmd .Stderr = os .Stderr
150147
151148 imageBuildStartTime := time .Now ()
152149 err = dockerCmd .Run ()
153150 if _ , ok := err .(* exec.ExitError ); ok {
154151 fmt .Println ("Image Build Failed" )
155- event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerBuildFailed )
156- return err
152+ event .Set ("ErrorCode" , utils .RebuildErrorCode_ImageBuildFailed )
153+ return utils . Outcome_UserErr , nil
157154 } else if err != nil {
158155 fmt .Println ("Docker error" )
159156 event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerErr )
160- return err
157+ return utils . Outcome_SystemErr , err
161158 }
162159 ImageBuildDuration := time .Since (imageBuildStartTime ).Milliseconds ()
163160 event .Set ("ImageBuildDuration" , ImageBuildDuration )
164161
165- err = TerminateExistingContainer ()
162+ err = TerminateExistingContainer (ctx )
166163 if err != nil {
167- event .Set ("ErrorCode" , utils .SystemErrorCode )
168- return err
169- }
170-
171- messages := []string {
172- "\n \n You are now connected to the container" ,
173- "You can inspect the container and make sure the necessary tools & libraries are installed." ,
174- "When you are done, just type exit to return to your Gitpod workspace\n " ,
164+ return utils .Outcome_SystemErr , err
175165 }
176166
177- welcomeMessage := strings .Join (messages , "\n " )
167+ welcomeMessage := strings .Join ([]string {
168+ "\n \n You are now connected to the container." ,
169+ "Check if all tools and libraries you need are properly installed." ,
170+ "When you are done, type \" exit\" to return to your Gitpod workspace.\n " ,
171+ }, "\n " )
178172
179- dockerRunCmd := exec .Command (
173+ dockerRunCmd := exec .CommandContext ( ctx ,
180174 dockerPath ,
181175 "run" ,
182176 "--rm" ,
177+ "-v" , "/workspace:/workspace" ,
183178 "--label" , "gp-rebuild=true" ,
184- "-it" ,
185- tag ,
186- "bash" ,
179+ "-it" , tag ,
180+ "sh" ,
187181 "-c" ,
188- fmt .Sprintf ("echo '%s'; bash" , welcomeMessage ),
182+ fmt .Sprintf (`
183+ echo "%s";
184+ cd "%s";
185+ if [ -x "$(command -v $SHELL)" ]; then
186+ $SHELL;
187+ else
188+ if [ -x "$(command -v bash)" ]; then
189+ bash;
190+ else
191+ sh;
192+ fi;
193+ fi;
194+ ` , welcomeMessage , wsInfo .CheckoutLocation ),
189195 )
190196
191197 dockerRunCmd .Stdout = os .Stdout
192198 dockerRunCmd .Stderr = os .Stderr
193199 dockerRunCmd .Stdin = os .Stdin
194200
195- err = dockerRunCmd .Run ()
196- if _ , ok := err .( * exec. ExitError ); ok {
197- fmt .Println ("Docker Run Command Failed " )
201+ err = dockerRunCmd .Start ()
202+ if err != nil {
203+ fmt .Println ("Failed to run docker container " )
198204 event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerRunFailed )
199- return err
200- } else if err != nil {
201- fmt .Println ("Docker error" )
202- event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerErr )
203- return err
205+ return utils .Outcome_UserErr , err
204206 }
205207
206- return nil
208+ _ = dockerRunCmd .Wait ()
209+
210+ return utils .Outcome_Success , nil
207211}
208212
209213var buildCmd = & cobra.Command {
210214 Use : "rebuild" ,
211215 Short : "Re-builds the workspace image (useful to debug a workspace custom image)" ,
212216 Hidden : false ,
213217 Run : func (cmd * cobra.Command , args []string ) {
214- ctx := context .Background ()
218+ ctx , cancel := context .WithCancel (context .Background ())
219+ sigChan := make (chan os.Signal , 1 )
220+ signal .Notify (sigChan , os .Interrupt , syscall .SIGTERM , syscall .SIGHUP )
221+ go func () {
222+ <- sigChan
223+ cancel ()
224+ }()
215225 supervisorClient , err := supervisor .New (ctx )
216226 if err != nil {
217227 utils .LogError (ctx , err , "Could not get workspace info required to build" , supervisorClient )
@@ -223,10 +233,18 @@ var buildCmd = &cobra.Command{
223233 Command : cmd .Name (),
224234 })
225235
226- err = runRebuild (ctx , supervisorClient , event )
227- if err != nil && event .Data .ErrorCode == "" {
228- event .Set ("ErrorCode" , utils .SystemErrorCode )
236+ outcome , err := runRebuild (ctx , supervisorClient , event )
237+ event .Set ("Outcome" , outcome )
238+
239+ if outcome != utils .Outcome_Success && event .Data .ErrorCode == "" {
240+ switch outcome {
241+ case utils .Outcome_UserErr :
242+ event .Set ("ErrorCode" , utils .UserErrorCode )
243+ case utils .Outcome_SystemErr :
244+ event .Set ("ErrorCode" , utils .SystemErrorCode )
245+ }
229246 }
247+
230248 event .Send (ctx )
231249
232250 if err != nil {
0 commit comments