Skip to content

Commit

Permalink
Provide a nicer image build failed message (#20281)
Browse files Browse the repository at this point in the history
* Provide a nicer image build failed message

* an error message that actually shows up

* Tweak error message

* Make env retrieval consistent in supervisor config

* Fix broken docs link in dashboard
  • Loading branch information
filiptronicek authored Oct 15, 2024
1 parent 30b3c27 commit b1b2214
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ export const PrebuildDetailPage: FC = () => {
<div className="py-4 px-6 flex flex-col gap-1">
<PrebuildStatus prebuild={prebuild} />
{prebuild?.status?.message && (
<div className="text-pk-content-secondary truncate">
<div className="text-pk-content-secondary line-clamp-2">
{prebuild?.status.message}
</div>
)}
Expand Down
2 changes: 1 addition & 1 deletion components/dashboard/src/start/StartWorkspace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -822,7 +822,7 @@ function ImageBuildView(props: ImageBuildViewProps) {
💡 You can use the <code>gp validate</code> command to validate the workspace configuration
from the editor terminal. &nbsp;
<a
href="https://www.gitpod.io/docs/configure/workspaces/workspace-image#trying-out-changes-to-your-dockerfile"
href="https://www.gitpod.io/docs/configure/workspaces#validate-your-gitpod-configuration"
target="_blank"
rel="noopener noreferrer"
className="gp-link"
Expand Down
7 changes: 5 additions & 2 deletions components/server/src/workspace/workspace-starter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ export class WorkspaceStarter {

/**
* failInstanceStart properly fails a workspace instance if something goes wrong before the instance ever reaches
* workspace manager. In this case we need to make sure we also fulfil the tasks of the bridge (e.g. for prebulds).
* workspace manager. In this case we need to make sure we also fulfil the tasks of the bridge (e.g. for prebuilds).
*/
private async failInstanceStart(ctx: TraceContext, err: any, workspace: Workspace, instance: WorkspaceInstance) {
if (ctxIsAborted()) {
Expand Down Expand Up @@ -1344,7 +1344,10 @@ export class WorkspaceStarter {
`workspace image build failed: ${message}`,
{ looksLikeUserError: true },
);
err = new StartInstanceError("imageBuildFailedUser", err);
err = new StartInstanceError(
"imageBuildFailedUser",
`workspace image build failed: ${message}. For further logs, try executing \`gp validate\` inside of a workspace`,
);
// Don't report this as "failed" to our metrics as it would trigger an alert
} else {
log.error(
Expand Down
8 changes: 8 additions & 0 deletions components/supervisor/pkg/supervisor/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,9 @@ type WorkspaceConfig struct {
// GitpodHeadless controls whether the workspace is running headless
GitpodHeadless string `env:"GITPOD_HEADLESS"`

// BobDockerfilePath is the path to the Dockerfile image builder will attempt to build
BobDockerfilePath string `env:"BOB_DOCKERFILE_PATH"`

// DebugEnabled controls whether the supervisor debugging facilities (pprof, grpc tracing) should be enabled
DebugEnable bool `env:"SUPERVISOR_DEBUG_ENABLE"`

Expand Down Expand Up @@ -468,6 +471,11 @@ func (c WorkspaceConfig) isDebugWorkspace() bool {
return c.DebugWorkspaceType != api.DebugWorkspaceType_noDebug
}

// isImageBuild returns true if the workspace is an image build.
func (c WorkspaceConfig) isImageBuild() bool {
return c.BobDockerfilePath != ""
}

var contentSources = map[api.ContentSource]csapi.WorkspaceInitSource{
api.ContentSource_from_other: csapi.WorkspaceInitFromOther,
api.ContentSource_from_backup: csapi.WorkspaceInitFromBackup,
Expand Down
13 changes: 9 additions & 4 deletions components/supervisor/pkg/supervisor/supervisor.go
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ func Run(options ...RunOption) {

if cfg.isHeadless() {
wg.Add(1)
go stopWhenTasksAreDone(ctx, &wg, shutdown, tasksSuccessChan)
go stopWhenTasksAreDone(&wg, cfg, shutdown, tasksSuccessChan)
} else if !opts.RunGP {
wg.Add(1)
go portMgmt.Run(ctx, &wg)
Expand Down Expand Up @@ -1593,15 +1593,20 @@ func tunnelOverSSH(ctx context.Context, tunneled *ports.TunneledPortsService, ne
<-ctx.Done()
}

func stopWhenTasksAreDone(ctx context.Context, wg *sync.WaitGroup, shutdown chan ShutdownReason, successChan <-chan taskSuccess) {
func stopWhenTasksAreDone(wg *sync.WaitGroup, cfg *Config, shutdown chan ShutdownReason, successChan <-chan taskSuccess) {
defer wg.Done()
defer close(shutdown)

success := <-successChan
if success.Failed() {
var msg []byte
if cfg.isImageBuild() {
msg = []byte("image build failed (" + string(success) + "). This is likely due to a misconfiguration in your Dockerfile. Debug this using `gp validate` (visit https://www.gitpod.io/docs/configure/workspaces#validate-your-gitpod-configuration) to learn more")
} else {
msg = []byte("headless task failed: " + string(success))
}
// we signal task failure via kubernetes termination log
msg := []byte("headless task failed: " + string(success))
err := ioutil.WriteFile("/dev/termination-log", msg, 0o644)
err := os.WriteFile("/dev/termination-log", msg, 0o644)
if err != nil {
log.WithError(err).Error("err while writing termination log")
}
Expand Down

0 comments on commit b1b2214

Please sign in to comment.