@@ -16,7 +16,6 @@ import (
1616 "github.com/gitpod-io/gitpod/gitpod-cli/pkg/supervisor"
1717 "github.com/gitpod-io/gitpod/gitpod-cli/pkg/utils"
1818 "github.com/gitpod-io/gitpod/supervisor/api"
19- log "github.com/sirupsen/logrus"
2019 "github.com/spf13/cobra"
2120)
2221
@@ -48,184 +47,189 @@ func TerminateExistingContainer() error {
4847 return nil
4948}
5049
51- var buildCmd = & cobra.Command {
52- Use : "rebuild" ,
53- Short : "Re-builds the workspace image (useful to debug a workspace custom image)" ,
54- Hidden : false ,
55- Run : func (cmd * cobra.Command , args []string ) {
56- ctx := context .Background ()
50+ func runRebuild (ctx context.Context , supervisorClient * supervisor.SupervisorClient , event * utils.EventTracker ) error {
51+ wsInfo , err := supervisorClient .Info .WorkspaceInfo (ctx , & api.WorkspaceInfoRequest {})
52+ if err != nil {
53+ return err
54+ }
5755
58- client , err := supervisor . New ( ctx )
59- if err != nil {
60- utils . LogError ( ctx , err , "Could not get workspace info required to build " , client )
61- return
62- }
63- defer client . Close ( )
56+ tmpDir , err := os . MkdirTemp ( "" , "gp-rebuild-*" )
57+ if err != nil {
58+ event . Set ( "ErrorCode " , utils . SystemErrorCode_TmpDirCannotWrite )
59+ return err
60+ }
61+ defer os . RemoveAll ( tmpDir )
6462
65- wsInfo , err := client .Info .WorkspaceInfo (ctx , & api.WorkspaceInfoRequest {})
66- if err != nil {
67- utils .LogError (ctx , err , "Could not fetch the workspace info" , client )
68- return
69- }
63+ gitpodConfig , err := utils .ParseGitpodConfig (wsInfo .CheckoutLocation )
64+ if err != nil {
65+ fmt .Println ("The .gitpod.yml file cannot be parsed: please check the file and try again" )
66+ fmt .Println ("" )
67+ fmt .Println ("For help check out the reference page:" )
68+ fmt .Println ("https://www.gitpod.io/docs/references/gitpod-yml#gitpodyml" )
69+ event .Set ("ErrorCode" , utils .RebuildErrorCode_MalformedGitpodYaml )
70+ return err
71+ }
7072
71- event := utils .TrackEvent (ctx , client , & utils.TrackCommandUsageParams {
72- Command : cmd .Name (),
73- })
74- defer event .Send (ctx )
73+ if gitpodConfig == nil {
74+ fmt .Println ("To test the image build, you need to configure your project with a .gitpod.yml file" )
75+ fmt .Println ("" )
76+ fmt .Println ("For a quick start, try running:\n $ gp init -i" )
77+ fmt .Println ("" )
78+ fmt .Println ("Alternatively, check out the following docs for getting started configuring your project" )
79+ fmt .Println ("https://www.gitpod.io/docs/configure#configure-gitpod" )
80+ event .Set ("ErrorCode" , utils .RebuildErrorCode_MissingGitpodYaml )
81+ return err
82+ }
7583
76- tmpDir , err := os .MkdirTemp ("" , "gp-rebuild-*" )
77- if err != nil {
78- event .Set ("ErrorCode" , utils .SystemErrorCode_TmpDirCannotWrite )
79- log .WithError (err ).Error ("Could not create temporary directory" )
80- return
84+ var baseimage string
85+ switch img := gitpodConfig .Image .(type ) {
86+ case nil :
87+ baseimage = ""
88+ case string :
89+ baseimage = "FROM " + img
90+ case map [interface {}]interface {}:
91+ dockerfilePath := filepath .Join (wsInfo .CheckoutLocation , img ["file" ].(string ))
92+
93+ if _ , err := os .Stat (dockerfilePath ); os .IsNotExist (err ) {
94+ fmt .Println ("Your .gitpod.yml points to a Dockerfile that doesn't exist: " + dockerfilePath )
95+ event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerfileNotFound ).Send (ctx )
96+ return err
8197 }
82- defer os .RemoveAll (tmpDir )
83-
84- gitpodConfig , err := utils .ParseGitpodConfig (wsInfo .CheckoutLocation )
98+ dockerfile , err := os .ReadFile (dockerfilePath )
8599 if err != nil {
86- fmt .Println ("The .gitpod.yml file cannot be parsed: please check the file and try again" )
87- fmt .Println ("" )
88- fmt .Println ("For help check out the reference page:" )
89- fmt .Println ("https://www.gitpod.io/docs/references/gitpod-yml#gitpodyml" )
90- event .Set ("ErrorCode" , utils .RebuildErrorCode_MalformedGitpodYaml )
91- return
100+ event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerfileCannotRead )
101+ return err
92102 }
93-
94- if gitpodConfig == nil {
95- fmt .Println ("To test the image build, you need to configure your project with a .gitpod.yml file" )
103+ if string (dockerfile ) == "" {
104+ fmt .Println ("Your Gitpod's Dockerfile is empty" )
96105 fmt .Println ("" )
97- fmt .Println ("For a quick start, try running:\n $ gp init -i" )
106+ fmt .Println ("To learn how to customize your workspace, check out the following docs:" )
107+ fmt .Println ("https://www.gitpod.io/docs/configure/workspaces/workspace-image#use-a-custom-dockerfile" )
98108 fmt .Println ("" )
99- fmt .Println ("Alternatively, check out the following docs for getting started configuring your project" )
100- fmt .Println ("https://www.gitpod.io/docs/configure#configure-gitpod" )
101- event .Set ("ErrorCode" , utils .RebuildErrorCode_MissingGitpodYaml )
102- return
109+ fmt .Println ("Once you configure your Dockerfile, re-run this command to validate your changes" )
110+ event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerfileEmpty )
111+ return err
103112 }
113+ baseimage = "\n " + string (dockerfile ) + "\n "
114+ default :
115+ fmt .Println ("Check your .gitpod.yml and make sure the image property is configured correctly" )
116+ event .Set ("ErrorCode" , utils .RebuildErrorCode_MalformedGitpodYaml )
117+ return err
118+ }
104119
105- var baseimage string
106- switch img := gitpodConfig .Image .(type ) {
107- case nil :
108- baseimage = ""
109- case string :
110- baseimage = "FROM " + img
111- case map [interface {}]interface {}:
112- dockerfilePath := filepath .Join (wsInfo .CheckoutLocation , img ["file" ].(string ))
113-
114- if _ , err := os .Stat (dockerfilePath ); os .IsNotExist (err ) {
115- fmt .Println ("Your .gitpod.yml points to a Dockerfile that doesn't exist: " + dockerfilePath )
116- event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerfileNotFound ).Send (ctx )
117- return
118- }
119- dockerfile , err := os .ReadFile (dockerfilePath )
120- if err != nil {
121- event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerfileCannotRead )
122- log .WithError (err ).Error ("Could not read the Dockerfile" )
123- return
124- }
125- if string (dockerfile ) == "" {
126- fmt .Println ("Your Gitpod's Dockerfile is empty" )
127- fmt .Println ("" )
128- fmt .Println ("To learn how to customize your workspace, check out the following docs:" )
129- fmt .Println ("https://www.gitpod.io/docs/configure/workspaces/workspace-image#use-a-custom-dockerfile" )
130- fmt .Println ("" )
131- fmt .Println ("Once you configure your Dockerfile, re-run this command to validate your changes" )
132- event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerfileEmpty )
133- return
134- }
135- baseimage = "\n " + string (dockerfile ) + "\n "
136- default :
137- fmt .Println ("Check your .gitpod.yml and make sure the image property is configured correctly" )
138- event .Set ("ErrorCode" , utils .RebuildErrorCode_MalformedGitpodYaml )
139- return
140- }
120+ if baseimage == "" {
121+ fmt .Println ("Your project is not using any custom Docker image." )
122+ fmt .Println ("Check out the following docs, to know how to get started" )
123+ fmt .Println ("" )
124+ fmt .Println ("https://www.gitpod.io/docs/configure/workspaces/workspace-image#use-a-public-docker-image" )
125+ event .Set ("ErrorCode" , utils .RebuildErrorCode_NoCustomImage )
126+ return err
127+ }
141128
142- if baseimage == "" {
143- fmt .Println ("Your project is not using any custom Docker image." )
144- fmt .Println ("Check out the following docs, to know how to get started" )
145- fmt .Println ("" )
146- fmt .Println ("https://www.gitpod.io/docs/configure/workspaces/workspace-image#use-a-public-docker-image" )
147- event .Set ("ErrorCode" , utils .RebuildErrorCode_NoCustomImage )
148- return
149- }
129+ err = os .WriteFile (filepath .Join (tmpDir , "Dockerfile" ), []byte (baseimage ), 0644 )
130+ if err != nil {
131+ fmt .Println ("Could not write the temporary Dockerfile" )
132+ event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerfileCannotWirte )
133+ return err
134+ }
150135
151- err = os .WriteFile (filepath .Join (tmpDir , "Dockerfile" ), []byte (baseimage ), 0644 )
152- if err != nil {
153- fmt .Println ("Could not write the temporary Dockerfile" )
154- event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerfileCannotWirte )
155- log .WithError (err ).Error (err )
156- return
157- }
136+ dockerPath , err := exec .LookPath ("docker" )
137+ if err != nil {
138+ fmt .Println ("Docker is not installed in your workspace" )
139+ event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerNotFound )
140+ return err
141+ }
158142
159- dockerPath , err := exec .LookPath ("docker" )
160- if err != nil {
161- fmt .Println ("Docker is not installed in your workspace" )
162- event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerNotFound )
163- return
164- }
143+ tag := "gp-rebuild-temp-build"
165144
166- tag := "gp-rebuild-temp-build"
145+ dockerCmd := exec .Command (dockerPath , "build" , "-t" , tag , "--progress=tty" , "." )
146+ dockerCmd .Dir = tmpDir
147+ dockerCmd .Stdout = os .Stdout
148+ dockerCmd .Stderr = os .Stderr
167149
168- dockerCmd := exec .Command (dockerPath , "build" , "-t" , tag , "--progress=tty" , "." )
169- dockerCmd .Dir = tmpDir
170- dockerCmd .Stdout = os .Stdout
171- dockerCmd .Stderr = os .Stderr
150+ imageBuildStartTime := time .Now ()
151+ err = dockerCmd .Run ()
152+ if _ , ok := err .(* exec.ExitError ); ok {
153+ fmt .Println ("Image Build Failed" )
154+ event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerBuildFailed )
155+ return err
156+ } else if err != nil {
157+ fmt .Println ("Docker error" )
158+ event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerErr )
159+ return err
160+ }
161+ iamgeBuildDurationSeconds := time .Since (imageBuildStartTime ).Seconds ()
162+ event .Set ("ImageBuildDurationSeconds" , iamgeBuildDurationSeconds )
172163
173- imageBuildStartTime := time .Now ()
174- err = dockerCmd .Run ()
175- if _ , ok := err .(* exec.ExitError ); ok {
176- fmt .Println ("Image Build Failed" )
177- event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerBuildFailed )
178- log .WithError (err ).Error (err )
179- return
180- } else if err != nil {
181- fmt .Println ("Docker error" )
182- event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerErr )
183- log .WithError (err ).Error (err )
184- return
185- }
186- iamgeBuildDurationSeconds := time .Since (imageBuildStartTime ).Seconds ()
187- event .Set ("ImageBuildDurationSeconds" , iamgeBuildDurationSeconds )
164+ err = TerminateExistingContainer ()
165+ if err != nil {
166+ utils .LogError (ctx , err , "Failed to stop previous gp rebuild container" , supervisorClient )
167+ }
188168
189- err = TerminateExistingContainer ()
169+ messages := []string {
170+ "\n \n You are now connected to the container" ,
171+ "You can inspect the container and make sure the necessary tools & libraries are installed." ,
172+ "When you are done, just type exit to return to your Gitpod workspace\n " ,
173+ }
174+
175+ welcomeMessage := strings .Join (messages , "\n " )
176+
177+ dockerRunCmd := exec .Command (
178+ dockerPath ,
179+ "run" ,
180+ "--rm" ,
181+ "--label" , "gp-rebuild=true" ,
182+ "-it" ,
183+ tag ,
184+ "bash" ,
185+ "-c" ,
186+ fmt .Sprintf ("echo '%s'; bash" , welcomeMessage ),
187+ )
188+
189+ dockerRunCmd .Stdout = os .Stdout
190+ dockerRunCmd .Stderr = os .Stderr
191+ dockerRunCmd .Stdin = os .Stdin
192+
193+ err = dockerRunCmd .Run ()
194+ if _ , ok := err .(* exec.ExitError ); ok {
195+ fmt .Println ("Docker Run Command Failed" )
196+ event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerRunFailed )
197+ return err
198+ } else if err != nil {
199+ fmt .Println ("Docker error" )
200+ event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerErr )
201+ return err
202+ }
203+
204+ return nil
205+ }
206+
207+ var buildCmd = & cobra.Command {
208+ Use : "rebuild" ,
209+ Short : "Re-builds the workspace image (useful to debug a workspace custom image)" ,
210+ Hidden : false ,
211+ Run : func (cmd * cobra.Command , args []string ) {
212+ ctx := context .Background ()
213+ supervisorClient , err := supervisor .New (ctx )
190214 if err != nil {
191- utils .LogError (ctx , err , "Failed to stop previous gp rebuild container" , client )
215+ utils .LogError (ctx , err , "Could not get workspace info required to build" , supervisorClient )
216+ return
192217 }
218+ defer supervisorClient .Close ()
219+
220+ event := utils .TrackEvent (ctx , supervisorClient , & utils.TrackCommandUsageParams {
221+ Command : cmd .Name (),
222+ })
193223
194- messages := []string {
195- "\n \n You are now connected to the container" ,
196- "You can inspect the container and make sure the necessary tools & libraries are installed." ,
197- "When you are done, just type exit to return to your Gitpod workspace\n " ,
224+ err = runRebuild (ctx , supervisorClient , event )
225+ if err != nil && event .Data .ErrorCode == "" {
226+ event .Set ("ErrorCode" , "System" )
198227 }
228+ event .Send (ctx )
199229
200- welcomeMessage := strings .Join (messages , "\n " )
201-
202- dockerRunCmd := exec .Command (
203- dockerPath ,
204- "run" ,
205- "--rm" ,
206- "--label" , "gp-rebuild=true" ,
207- "-it" ,
208- tag ,
209- "bash" ,
210- "-c" ,
211- fmt .Sprintf ("echo '%s'; bash" , welcomeMessage ),
212- )
213-
214- dockerRunCmd .Stdout = os .Stdout
215- dockerRunCmd .Stderr = os .Stderr
216- dockerRunCmd .Stdin = os .Stdin
217-
218- err = dockerRunCmd .Run ()
219- if _ , ok := err .(* exec.ExitError ); ok {
220- fmt .Println ("Docker Run Command Failed" )
221- event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerRunFailed )
222- log .WithError (err ).Error (err )
223- return
224- } else if err != nil {
225- fmt .Println ("Docker error" )
226- event .Set ("ErrorCode" , utils .RebuildErrorCode_DockerErr )
227- log .WithError (err ).Error (err )
228- return
230+ if err != nil {
231+ utils .LogError (ctx , err , "Failed to rebuild" , supervisorClient )
232+ os .Exit (1 )
229233 }
230234 },
231235}
0 commit comments