Skip to content

Commit

Permalink
debug: run interactive shell on error
Browse files Browse the repository at this point in the history
Launch interactive shell in context of failed action for issues
investigation and debug.

Add options to debos:
--debug-shell -- to start a shell in case of any failure
--shell <path> -- use selected shell instead of default bash

Fixes #30

Signed-off-by: Denis Pynkin <denis.pynkin@collabora.com>
  • Loading branch information
d4s committed Oct 25, 2017
1 parent d8a6fe1 commit ffa6447
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 9 deletions.
1 change: 1 addition & 0 deletions action.go
Expand Up @@ -17,6 +17,7 @@ type DebosContext struct {
ImageKernelRoot string // Kernel cmdline root= snippet for the / of the image
RecipeDir string
Architecture string
DebugShell string
Origins map[string]string
}

Expand Down
33 changes: 24 additions & 9 deletions cmd/debos/debos.go
Expand Up @@ -13,12 +13,14 @@ import (
"github.com/sjoerdsimons/fakemachine"
)

func bailOnError(err error, a debos.Action, stage string) {
func bailOnError(context debos.DebosContext, err error, a debos.Action, stage string) {
if err == nil {
return
}

log.Fatalf("Action `%s` failed at stage %s, error: %s", a, stage, err)
log.Printf("Action `%s` failed at stage %s, error: %s", a, stage, err)
debos.DebugShell(context)
os.Exit(1)
}

func main() {
Expand All @@ -27,6 +29,8 @@ func main() {
ArtifactDir string `long:"artifactdir"`
InternalImage string `long:"internal-image" hidden:"true"`
TemplateVars map[string]string `short:"t" long:"template-var" description:"Template variables"`
DebugShell bool `long:"debug-shell" description:"Fall into interactive shell on error"`
Shell string `short:"s" long:"shell" description:"Redefine interactive shell binary (default: bash)" optionsl:"" default:"/bin/bash"`
}

var exitcode int = 0
Expand Down Expand Up @@ -55,6 +59,11 @@ func main() {
return
}

// Set interactive shell binary only if '--debug-shell' options passed
if options.DebugShell {
context.DebugShell = options.Shell
}

file := args[0]
file = debos.CleanPath(file)

Expand Down Expand Up @@ -95,7 +104,7 @@ func main() {

for _, a := range r.Actions {
err = a.Verify(&context)
bailOnError(err, a, "Verify")
bailOnError(context, err, a, "Verify")
}

if !fakemachine.InMachine() && fakemachine.Supported() {
Expand All @@ -112,9 +121,14 @@ func main() {
m.AddVolume(context.RecipeDir)
args = append(args, file)

if options.DebugShell {
args = append(args, "--debug-shell")
args = append(args, "--shell", fmt.Sprintf("%s", options.Shell))
}

for _, a := range r.Actions {
err = a.PreMachine(&context, m, &args)
bailOnError(err, a, "PreMachine")
bailOnError(context, err, a, "PreMachine")
}

exitcode = m.RunInMachineWithArgs(args)
Expand All @@ -125,7 +139,7 @@ func main() {

for _, a := range r.Actions {
err = a.PostMachine(context)
bailOnError(err, a, "Postmachine")
bailOnError(context, err, a, "Postmachine")
}

log.Printf("==== Recipe done ====")
Expand All @@ -135,24 +149,25 @@ func main() {
if !fakemachine.InMachine() {
for _, a := range r.Actions {
err = a.PreNoMachine(&context)
bailOnError(err, a, "PreNoMachine")
bailOnError(context, err, a, "PreNoMachine")
}
}

for _, a := range r.Actions {
err = a.Run(&context)
bailOnError(err, a, "Run")

bailOnError(context, err, a, "Run")
}

for _, a := range r.Actions {
err = a.Cleanup(context)
bailOnError(err, a, "Cleanup")
bailOnError(context, err, a, "Cleanup")
}

if !fakemachine.InMachine() {
for _, a := range r.Actions {
err = a.PostMachine(context)
bailOnError(err, a, "PostMachine")
bailOnError(context, err, a, "PostMachine")
}
log.Printf("==== Recipe done ====")
}
Expand Down
31 changes: 31 additions & 0 deletions debug.go
@@ -0,0 +1,31 @@
package debos

import (
"fmt"
"log"
"os"
)

/*
DebugShell function launches an interactive shell for
debug and problems investigation.
*/
func DebugShell(context DebosContext) {

if len(context.DebugShell) == 0 {
return
}

pa := os.ProcAttr{
Files: []*os.File{os.Stdin, os.Stdout, os.Stderr},
Dir: context.Scratchdir,
}

// Start an interactive shell for debug.
log.Printf(">>> Starting a debug shell")
if proc, err := os.StartProcess(context.DebugShell, []string{}, &pa); err != nil {
fmt.Printf("Failed: %s\n", err)
} else {
proc.Wait()
}
}

0 comments on commit ffa6447

Please sign in to comment.