Skip to content

Commit 2e468a0

Browse files
author
Andrea Falzetti
committed
refactor
1 parent c61d095 commit 2e468a0

File tree

2 files changed

+169
-167
lines changed

2 files changed

+169
-167
lines changed

components/gitpod-cli/cmd/rebuild.go

Lines changed: 160 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -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\nYou 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\nYou 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

Comments
 (0)