Skip to content

[Gitpod CLI] gp rebuild #15638

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 13, 2023
Merged

[Gitpod CLI] gp rebuild #15638

merged 1 commit into from
Jan 13, 2023

Conversation

andreafalzetti
Copy link
Contributor

@andreafalzetti andreafalzetti commented Jan 9, 2023

Description

We're introducing a new command to gp cli, to facilitate users in testing the the build and run of custom Docker workspace images.

Note: if the user closes the terminal via the IDE once they are inside the debug container, the event won't be sent.

Related Issue(s)

Relates to #7671

How to test

  1. Start a workspace https://ide-gp-build.preview.gitpod-dev.com/#https://github.com/gitpod-io/empty
  2. Run gp rebuild and observe error message
  3. Specify a custom dockerfile (both using image: xxx or image.file
  4. If you specify a non-existing file, and re-run, observe the error
  5. Check in Segment Staging Trusted that gp_command is being sent with the following fields:
    • errorCode
  6. Configure a real image and re-run, exit the container
  7. Check in Segment Staging Trusted that gp_command is being sent with the following fields:
    • durationMs
    • dockerBuildDurationSeconds

Release Notes

new command: `gp rebuild`

Documentation

Werft options:

  • /werft with-local-preview
    If enabled this will build install/preview
  • /werft with-preview
  • /werft with-large-vm
  • /werft with-integration-tests=all
    Valid options are all, workspace, webapp, ide, jetbrains, vscode, ssh
  • /werft analytics=segment

@werft-gitpod-dev-com

This comment was marked as resolved.

@werft-gitpod-dev-com

This comment was marked as resolved.

@andreafalzetti

This comment was marked as resolved.

@werft-gitpod-dev-com

This comment was marked as resolved.

@andreafalzetti

This comment was marked as resolved.

@andreafalzetti andreafalzetti force-pushed the ide/gp-build branch 2 times, most recently from 96499a9 to 755b956 Compare January 10, 2023 16:25
@werft-gitpod-dev-com

This comment was marked as resolved.

@andreafalzetti

This comment was marked as resolved.

@andreafalzetti andreafalzetti force-pushed the ide/gp-build branch 5 times, most recently from 227f8b6 to 70ed53b Compare January 12, 2023 12:19
event.Set("ErrorCode", utils.RebuildErrorCode_DockerfileNotFound).Send(ctx)
return
}
dockerfile, err := os.ReadFile(dockerfilePath)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

err is swallowed, we should give a root cause to the user

return
}

tmpDir, err := os.MkdirTemp("", "gp-rebuild-*")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

err is swallowed, we should give a root cause to the user

}
dockerfile, err := os.ReadFile(dockerfilePath)
if err != nil {
log.Fatal("Could not read the Dockerfile")
Copy link
Member

@akosyakov akosyakov Jan 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andreafalzetti I don't think the flow here can work. Maybe I'm missing something. Fatal calls os.Exit and it interrupts the program immediately, defer are not called and events are not sent.

I'm asking can we restructure top level routine to something like (pseudo code):

ctx := context.Background()
event := utils.TrackEvent(ctx, ...)
err := doRebuild(ctx, event)
if err != nil && event.ErrorCode == "" {
    err.ErrorCode = "system"
}
event.Send()
if err != nil {
    utils.LogError(..) // log to a user and GCP
    os.Exit(1)
}

It looks also we swallow errors here and there, we should always propagate given errors to users.

WorkspaceId string `json:"workspaceId,omitempty"`
InstanceId string `json:"instanceId,omitempty"`
Timestamp int64 `json:"timestamp,omitempty"`
DockerBuildDurationSeconds float64 `json:"dockerBuildDurationSeconds,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let’s call it imageBuildDurationSeconds. We are likely go away from docker next week to build the image.

@akosyakov
Copy link
Member

akosyakov commented Jan 13, 2023

Is there a reason why don’t we measure everything in milliseconds and drop suffix for unit, ie just duration and imageBuildDuration. We do it the same for other events?

@andreafalzetti
Copy link
Contributor Author

andreafalzetti commented Jan 13, 2023

Is there a reason why don’t we measure everything in milliseconds and drop suffix for unit, ie just duration and imageBuildDuration. We do it the same for other events?

The thought process is that image build will most likely take seconds so it would be more convinent to have it already in seconds.

About the suffix, I think it's a nice to have, in general, because it easily indicates the unit from the Segmenet/Mixpanel without having to access the code or remember what unit it was.

Happy to make it all ms and drop the suffix, no hard opinions

Co-authored-by: Victor Nogueira <[email protected]>
@andreafalzetti
Copy link
Contributor Author

andreafalzetti commented Jan 13, 2023

I've updated the PR with the suggestions from @akosyakov

I've tested almost all scenarios, but feel free to test again @felladrin 🙏

Copy link
Member

@akosyakov akosyakov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good, I have not tried, rely on Andrea and Victor for it

/hold

pease unhold when comfortable

@felladrin
Copy link
Contributor

I'm running a quick test on it now.

@akosyakov
Copy link
Member

@andreafalzetti follow up are to update docs and then contribute how to troubleshoot link to the image build screen? Maybe makes sense to talk to @gtsiolis where to add it, we will speak about it again next design meeting

Copy link
Contributor

@felladrin felladrin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested! ✅

@andreafalzetti
Copy link
Contributor Author

/unhold

@roboquat roboquat merged commit 1e24370 into main Jan 13, 2023
@roboquat roboquat deleted the ide/gp-build branch January 13, 2023 13:48
@gtsiolis
Copy link
Contributor

gtsiolis commented Jan 13, 2023

Exciting changes! ➰


@akosyakov I've added your comment above in #15638 (comment) in the next 🍳 IDE / Design Check-in on next Wed (Jan 18), see relevant discussion point (internal).

return err
}

err = os.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(baseimage), 0644)
Copy link
Member

@akosyakov akosyakov Jan 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andreafalzetti @felladrin is not it bogus? 🤔

We should build in the context of /workspace because Dockerfile can make usage of COPY statements?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can use the current working direction to run docker command but then pass -f which pints to the temp dockerfile?

fmt.Println("")
fmt.Println("Once you configure your Dockerfile, re-run this command to validate your changes")
event.Set("ErrorCode", utils.RebuildErrorCode_DockerfileEmpty)
return err
Copy link
Member

@akosyakov akosyakov Jan 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andreafalzetti @felladrin for me this branch is hanging 🤔

I think the problem is that it returns nil here. It should return some real error. We need to double check all places, where we return without having err object in advance.

Update hanging actually because of my branch, but I think we should return an error here to exit with 1 properly or another value like ok if we don't want to print an error

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i.e. something like:

ok, err = runRebuild(ctx, supervisorClient, event)
if event.Data.ErrorCode == "" {
	if err != nil {
		event.Set("ErrorCode", utils.SystemErrorCode)
	} else if !ok {
		event.Set("ErrorCode", utils.UserErrorCode)
	}
}
event.Send(ctx)

if err != nil {
	utils.LogError(ctx, err, "Failed to rebuild", supervisorClient)
}
var exitCode int
if err != nil || !ok {
	exitCode = 1
}
os.Exit(exitCode)

Copy link
Contributor Author

@andreafalzetti andreafalzetti Jan 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, I wonder how I missed this :(

will send a follow-up PR!

Update: ok, it's not hanging then.. I will look into this anyway

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is also the default branch of the switch having the same issue, I will check them all

@andreafalzetti
Copy link
Contributor Author

andreafalzetti commented Jan 13, 2023

@akosyakov I will double check that branch. About Dockerfile location it's a good pont, maybe the tmp file should be located in the root of the project 🤔

@akosyakov
Copy link
Member

@andreafalzetti I think it does not matter, you can do docker build . -f /tmp/gp-rebuild/Dockerfile and don't set dockerCmd.Dir -> it will build then in the context of a current directory but with a temp Dockerfile

@andreafalzetti
Copy link
Contributor Author

andreafalzetti commented Jan 13, 2023

@akosyakov there are 2 other things I've noticed now:

  1. if bash is not installed in the image, it fails (this is also true atm when we suggest launching bash from the docs, but it's a user action so it's revertable) in rebuild maybe we should consider using sh as there are higher changes it will work 🤔 WDYT?
  2. if the user generates a non-zero exit code from within the container, it gets propagated outside (e.g. type exit 1)

@andreafalzetti
Copy link
Contributor Author

andreafalzetti commented Jan 14, 2023

I've opened a follow-up PR: #15740

Let's discuss improvements over there 🙏

@roboquat roboquat added deployed: IDE IDE change is running in production deployed Change is completely running in production labels Jan 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: gp cli deployed: IDE IDE change is running in production deployed Change is completely running in production release-note size/XL team: IDE
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

6 participants