diff --git a/cli/delete.go b/cli/delete.go index 174205afe2be2..42abca658623a 100644 --- a/cli/delete.go +++ b/cli/delete.go @@ -11,7 +11,10 @@ import ( // nolint func (r *RootCmd) deleteWorkspace() *serpent.Command { - var orphan bool + var ( + orphan bool + prov buildFlags + ) client := new(codersdk.Client) cmd := &serpent.Command{ Annotations: workspaceCommand, @@ -40,11 +43,15 @@ func (r *RootCmd) deleteWorkspace() *serpent.Command { } var state []byte - build, err := client.CreateWorkspaceBuild(inv.Context(), workspace.ID, codersdk.CreateWorkspaceBuildRequest{ + req := codersdk.CreateWorkspaceBuildRequest{ Transition: codersdk.WorkspaceTransitionDelete, ProvisionerState: state, Orphan: orphan, - }) + } + if prov.provisionerLogDebug { + req.LogLevel = codersdk.ProvisionerLogLevelDebug + } + build, err := client.CreateWorkspaceBuild(inv.Context(), workspace.ID, req) if err != nil { return err } @@ -71,5 +78,6 @@ func (r *RootCmd) deleteWorkspace() *serpent.Command { }, cliui.SkipPromptOption(), } + cmd.Options = append(cmd.Options, prov.cliOptions()...) return cmd } diff --git a/cli/parameter.go b/cli/parameter.go index e9b1ca581a5f5..2c09e9bbefc33 100644 --- a/cli/parameter.go +++ b/cli/parameter.go @@ -127,3 +127,21 @@ func parseParameterMapFile(parameterFile string) (map[string]string, error) { } return parameterMap, nil } + +// buildFlags contains options relating to troubleshooting provisioner jobs. +type buildFlags struct { + provisionerLogDebug bool +} + +func (bf *buildFlags) cliOptions() []serpent.Option { + return []serpent.Option{ + { + Flag: "provisioner-log-debug", + Description: `Sets the provisioner log level to debug. +This will print additional information about the build process. +This is useful for troubleshooting build issues.`, + Value: serpent.BoolOf(&bf.provisionerLogDebug), + Hidden: true, + }, + } +} diff --git a/cli/restart.go b/cli/restart.go index 54ce658f8f0dc..156f506105c5a 100644 --- a/cli/restart.go +++ b/cli/restart.go @@ -14,7 +14,10 @@ import ( ) func (r *RootCmd) restart() *serpent.Command { - var parameterFlags workspaceParameterFlags + var ( + parameterFlags workspaceParameterFlags + bflags buildFlags + ) client := new(codersdk.Client) cmd := &serpent.Command{ @@ -35,7 +38,7 @@ func (r *RootCmd) restart() *serpent.Command { return err } - startReq, err := buildWorkspaceStartRequest(inv, client, workspace, parameterFlags, WorkspaceRestart) + startReq, err := buildWorkspaceStartRequest(inv, client, workspace, parameterFlags, bflags, WorkspaceRestart) if err != nil { return err } @@ -48,9 +51,13 @@ func (r *RootCmd) restart() *serpent.Command { return err } - build, err := client.CreateWorkspaceBuild(ctx, workspace.ID, codersdk.CreateWorkspaceBuildRequest{ + wbr := codersdk.CreateWorkspaceBuildRequest{ Transition: codersdk.WorkspaceTransitionStop, - }) + } + if bflags.provisionerLogDebug { + wbr.LogLevel = codersdk.ProvisionerLogLevelDebug + } + build, err := client.CreateWorkspaceBuild(ctx, workspace.ID, wbr) if err != nil { return err } @@ -65,7 +72,7 @@ func (r *RootCmd) restart() *serpent.Command { // workspaces with the active version. if cerr, ok := codersdk.AsError(err); ok && cerr.StatusCode() == http.StatusForbidden { _, _ = fmt.Fprintln(inv.Stdout, "Unable to restart the workspace with the template version from the last build. Policy may require you to restart with the current active template version.") - build, err = startWorkspace(inv, client, workspace, parameterFlags, WorkspaceUpdate) + build, err = startWorkspace(inv, client, workspace, parameterFlags, bflags, WorkspaceUpdate) if err != nil { return xerrors.Errorf("start workspace with active template version: %w", err) } @@ -87,6 +94,7 @@ func (r *RootCmd) restart() *serpent.Command { } cmd.Options = append(cmd.Options, parameterFlags.allOptions()...) + cmd.Options = append(cmd.Options, bflags.cliOptions()...) return cmd } diff --git a/cli/ssh.go b/cli/ssh.go index 1d75f1015e242..7d9d2368de2f9 100644 --- a/cli/ssh.go +++ b/cli/ssh.go @@ -649,9 +649,9 @@ func getWorkspaceAndAgent(ctx context.Context, inv *serpent.Invocation, client * // It's possible for a workspace build to fail due to the template requiring starting // workspaces with the active version. _, _ = fmt.Fprintf(inv.Stderr, "Workspace was stopped, starting workspace to allow connecting to %q...\n", workspace.Name) - _, err = startWorkspace(inv, client, workspace, workspaceParameterFlags{}, WorkspaceStart) + _, err = startWorkspace(inv, client, workspace, workspaceParameterFlags{}, buildFlags{}, WorkspaceStart) if cerr, ok := codersdk.AsError(err); ok && cerr.StatusCode() == http.StatusForbidden { - _, err = startWorkspace(inv, client, workspace, workspaceParameterFlags{}, WorkspaceUpdate) + _, err = startWorkspace(inv, client, workspace, workspaceParameterFlags{}, buildFlags{}, WorkspaceUpdate) if err != nil { return codersdk.Workspace{}, codersdk.WorkspaceAgent{}, xerrors.Errorf("start workspace with active template version: %w", err) } diff --git a/cli/start.go b/cli/start.go index 89f15b95c42f3..da2d394d12846 100644 --- a/cli/start.go +++ b/cli/start.go @@ -13,7 +13,10 @@ import ( ) func (r *RootCmd) start() *serpent.Command { - var parameterFlags workspaceParameterFlags + var ( + parameterFlags workspaceParameterFlags + bflags buildFlags + ) client := new(codersdk.Client) cmd := &serpent.Command{ @@ -45,12 +48,12 @@ func (r *RootCmd) start() *serpent.Command { ) build = workspace.LatestBuild default: - build, err = startWorkspace(inv, client, workspace, parameterFlags, WorkspaceStart) + build, err = startWorkspace(inv, client, workspace, parameterFlags, bflags, WorkspaceStart) // It's possible for a workspace build to fail due to the template requiring starting // workspaces with the active version. if cerr, ok := codersdk.AsError(err); ok && cerr.StatusCode() == http.StatusForbidden { _, _ = fmt.Fprintln(inv.Stdout, "Unable to start the workspace with the template version from the last build. Policy may require you to restart with the current active template version.") - build, err = startWorkspace(inv, client, workspace, parameterFlags, WorkspaceUpdate) + build, err = startWorkspace(inv, client, workspace, parameterFlags, bflags, WorkspaceUpdate) if err != nil { return xerrors.Errorf("start workspace with active template version: %w", err) } @@ -73,11 +76,12 @@ func (r *RootCmd) start() *serpent.Command { } cmd.Options = append(cmd.Options, parameterFlags.allOptions()...) + cmd.Options = append(cmd.Options, bflags.cliOptions()...) return cmd } -func buildWorkspaceStartRequest(inv *serpent.Invocation, client *codersdk.Client, workspace codersdk.Workspace, parameterFlags workspaceParameterFlags, action WorkspaceCLIAction) (codersdk.CreateWorkspaceBuildRequest, error) { +func buildWorkspaceStartRequest(inv *serpent.Invocation, client *codersdk.Client, workspace codersdk.Workspace, parameterFlags workspaceParameterFlags, buildFlags buildFlags, action WorkspaceCLIAction) (codersdk.CreateWorkspaceBuildRequest, error) { version := workspace.LatestBuild.TemplateVersionID if workspace.AutomaticUpdates == codersdk.AutomaticUpdatesAlways || action == WorkspaceUpdate { @@ -124,14 +128,19 @@ func buildWorkspaceStartRequest(inv *serpent.Invocation, client *codersdk.Client return codersdk.CreateWorkspaceBuildRequest{}, err } - return codersdk.CreateWorkspaceBuildRequest{ + wbr := codersdk.CreateWorkspaceBuildRequest{ Transition: codersdk.WorkspaceTransitionStart, RichParameterValues: buildParameters, TemplateVersionID: version, - }, nil + } + if buildFlags.provisionerLogDebug { + wbr.LogLevel = codersdk.ProvisionerLogLevelDebug + } + + return wbr, nil } -func startWorkspace(inv *serpent.Invocation, client *codersdk.Client, workspace codersdk.Workspace, parameterFlags workspaceParameterFlags, action WorkspaceCLIAction) (codersdk.WorkspaceBuild, error) { +func startWorkspace(inv *serpent.Invocation, client *codersdk.Client, workspace codersdk.Workspace, parameterFlags workspaceParameterFlags, buildFlags buildFlags, action WorkspaceCLIAction) (codersdk.WorkspaceBuild, error) { if workspace.DormantAt != nil { _, _ = fmt.Fprintln(inv.Stdout, "Activating dormant workspace...") err := client.UpdateWorkspaceDormancy(inv.Context(), workspace.ID, codersdk.UpdateWorkspaceDormancy{ @@ -141,7 +150,7 @@ func startWorkspace(inv *serpent.Invocation, client *codersdk.Client, workspace return codersdk.WorkspaceBuild{}, xerrors.Errorf("activate workspace: %w", err) } } - req, err := buildWorkspaceStartRequest(inv, client, workspace, parameterFlags, action) + req, err := buildWorkspaceStartRequest(inv, client, workspace, parameterFlags, buildFlags, action) if err != nil { return codersdk.WorkspaceBuild{}, err } diff --git a/cli/stop.go b/cli/stop.go index 890f0275801f1..9aec5950c292b 100644 --- a/cli/stop.go +++ b/cli/stop.go @@ -10,6 +10,7 @@ import ( ) func (r *RootCmd) stop() *serpent.Command { + var bflags buildFlags client := new(codersdk.Client) cmd := &serpent.Command{ Annotations: workspaceCommand, @@ -35,9 +36,13 @@ func (r *RootCmd) stop() *serpent.Command { if err != nil { return err } - build, err := client.CreateWorkspaceBuild(inv.Context(), workspace.ID, codersdk.CreateWorkspaceBuildRequest{ + wbr := codersdk.CreateWorkspaceBuildRequest{ Transition: codersdk.WorkspaceTransitionStop, - }) + } + if bflags.provisionerLogDebug { + wbr.LogLevel = codersdk.ProvisionerLogLevelDebug + } + build, err := client.CreateWorkspaceBuild(inv.Context(), workspace.ID, wbr) if err != nil { return err } @@ -56,5 +61,7 @@ func (r *RootCmd) stop() *serpent.Command { return nil }, } + cmd.Options = append(cmd.Options, bflags.cliOptions()...) + return cmd } diff --git a/cli/update.go b/cli/update.go index 1465db716d073..cf4ec5e1b6c39 100644 --- a/cli/update.go +++ b/cli/update.go @@ -10,8 +10,10 @@ import ( ) func (r *RootCmd) update() *serpent.Command { - var parameterFlags workspaceParameterFlags - + var ( + parameterFlags workspaceParameterFlags + bflags buildFlags + ) client := new(codersdk.Client) cmd := &serpent.Command{ Annotations: workspaceCommand, @@ -32,7 +34,7 @@ func (r *RootCmd) update() *serpent.Command { return nil } - build, err := startWorkspace(inv, client, workspace, parameterFlags, WorkspaceUpdate) + build, err := startWorkspace(inv, client, workspace, parameterFlags, bflags, WorkspaceUpdate) if err != nil { return xerrors.Errorf("start workspace: %w", err) } @@ -54,5 +56,6 @@ func (r *RootCmd) update() *serpent.Command { } cmd.Options = append(cmd.Options, parameterFlags.allOptions()...) + cmd.Options = append(cmd.Options, bflags.cliOptions()...) return cmd } diff --git a/scripts/develop.sh b/scripts/develop.sh index 51f6ded4b96f5..bdaf81c7536e5 100755 --- a/scripts/develop.sh +++ b/scripts/develop.sh @@ -150,7 +150,7 @@ fatal() { trap 'fatal "Script encountered an error"' ERR cdroot - DEBUG_DELVE="${debug}" start_cmd API "" "${CODER_DEV_SHIM}" server --http-address 0.0.0.0:3000 --swagger-enable --access-url "${CODER_DEV_ACCESS_URL}" --dangerous-allow-cors-requests=true "$@" + DEBUG_DELVE="${debug}" start_cmd API "" "${CODER_DEV_SHIM}" server --http-address 0.0.0.0:3000 --swagger-enable --access-url "${CODER_DEV_ACCESS_URL}" --dangerous-allow-cors-requests=true --enable-terraform-debug-mode "$@" echo '== Waiting for Coder to become ready' # Start the timeout in the background so interrupting this script