From 31935231f434c60df692b6013bcf0af0baf92825 Mon Sep 17 00:00:00 2001 From: James Strachan Date: Sat, 7 Jan 2017 15:31:23 +0000 Subject: [PATCH] first spike of debugging support --- cmd/debug.go | 88 ++++++++++++++++++++++++++++++++++++++++++++++------ cmd/log.go | 4 +-- glide.lock | 27 ++++++++-------- glide.yaml | 2 ++ 4 files changed, 95 insertions(+), 26 deletions(-) diff --git a/cmd/debug.go b/cmd/debug.go index 3533ee0..f894aee 100644 --- a/cmd/debug.go +++ b/cmd/debug.go @@ -15,21 +15,27 @@ package cmd import ( + "bufio" "fmt" "os" "os/exec" + "path/filepath" + "strconv" + "strings" + "github.com/pkg/browser" "github.com/funktionio/funktion/pkg/k8sutil" + "github.com/funktionio/funktion/pkg/funktion" "github.com/spf13/cobra" "k8s.io/client-go/1.5/kubernetes" "k8s.io/client-go/1.5/pkg/api" "k8s.io/client-go/1.5/pkg/api/v1" "k8s.io/client-go/1.5/pkg/apis/extensions/v1beta1" - "strings" - "path/filepath" - "github.com/funktionio/funktion/pkg/funktion" - "strconv" +) + +const ( + chromeDevToolsURLPrefix = "chrome-devtools:" ) type debugCmd struct { @@ -149,10 +155,26 @@ func (p *debugCmd) createPortText(kindText, name string) (string, error) { debugPort := 0 if kind == functionKind { + // ensure debug mode is enabled on the function + if found.Data == nil { + found.Data = map[string]string{} + } + data := found.Data + debugMode := data[funktion.DebugProperty] + if strings.ToLower(debugMode) != "true" { + data[funktion.DebugProperty] = "true" + _, err = cms.Update(found) + if err != nil { + return "", fmt.Errorf("Failed to update Function %s to enable debug mode %v", name, err) + } + fmt.Printf("Enabled debug mode for Function %s\n", name) + } + + // lets use the debug port on the runtime runtime := "" - data := found.Labels - if data != nil { - runtime = data[funktion.RuntimeLabel] + labels := found.Labels + if labels != nil { + runtime = labels[funktion.RuntimeLabel] } if len(runtime) > 0 { return p.createPortText(runtimeKind, runtime) @@ -227,14 +249,60 @@ func (p *debugCmd) viewLog(pod *v1.Pod) error { } if p.chromeDevTools { - return p.openChromeDevTools(pod) + return p.openChromeDevTools(pod, binaryFile) } } return nil } -func (p *debugCmd) openChromeDevTools(pod *v1.Pod) error { - // TODO +func (p *debugCmd) openChromeDevTools(pod *v1.Pod, binaryFile string) error { + name := pod.Name + + args := []string{"logs", "-f", name} + cmd := exec.Command(binaryFile, args...) + + cmdReader, err := cmd.StdoutPipe() + if err != nil { + return fmt.Errorf("failed to get stdout for command %s %s: %v", filepath.Base(binaryFile), strings.Join(args, " "), err) + } + + scanner := bufio.NewScanner(cmdReader) + line := 0 + go func() { + for scanner.Scan() { + if line++; line > 50 { + fmt.Printf("No log line found starting with `%s` in the first %d lines. Maybe debug is not really enabled in this pod?\n", chromeDevToolsURLPrefix, line) + cmdReader.Close() + killCmd(cmd) + } + text := strings.TrimSpace(scanner.Text()) + if strings.HasPrefix(text, chromeDevToolsURLPrefix) { + fmt.Printf("\nTo Debug open: %s\n\n", text) + cmdReader.Close() + killCmd(cmd) + browser.OpenURL(text) + } + } + }() + + if err := cmd.Start(); err != nil { + killCmd(cmd) + return fmt.Errorf("failed to start command %s %s: %v", filepath.Base(binaryFile), strings.Join(args, " "), err) + } + + err = cmd.Wait() + if err != nil { + killCmd(cmd) + return fmt.Errorf("failed to wait for command %s %s: %v", filepath.Base(binaryFile), strings.Join(args, " "), err) + } return nil } +func killCmd(cmd *exec.Cmd) { + if cmd != nil { + p := cmd.Process + if p != nil { + p.Kill() + } + } +} diff --git a/cmd/log.go b/cmd/log.go index 46e9d42..f284297 100644 --- a/cmd/log.go +++ b/cmd/log.go @@ -18,6 +18,8 @@ import ( "fmt" "os" "os/exec" + "path/filepath" + "strings" "github.com/funktionio/funktion/pkg/k8sutil" "github.com/spf13/cobra" @@ -26,8 +28,6 @@ import ( "k8s.io/client-go/1.5/pkg/api" "k8s.io/client-go/1.5/pkg/api/v1" "k8s.io/client-go/1.5/pkg/apis/extensions/v1beta1" - "strings" - "path/filepath" ) type logCmd struct { diff --git a/glide.lock b/glide.lock index 812b43d..3b42d73 100644 --- a/glide.lock +++ b/glide.lock @@ -1,15 +1,15 @@ -hash: 9879602b6120f2a2b47fa84c635e0f4eeeb9137765ac7a415b4c0749a8b36bc3 -updated: 2017-01-06T17:20:39.156391257Z +hash: 600c89061f0709ab9caa4bc0be1f08a75e0dec8851c0447470da782b1bd178a9 +updated: 2017-01-07T11:54:43.923587976Z imports: - name: cloud.google.com/go - version: 641b1469e744485a8e6235bffc3b7bf366758a85 + version: c96c4486674a140772b9788370fa29898577bc0c subpackages: - compute/metadata - internal - name: github.com/blang/semver version: 3a37c301dda64cbe17f16f661b4c976803c0e2d2 - name: github.com/coreos/go-oidc - version: 9e117111587506b9dc83b7b38263268bf48352ea + version: 2b5d73091ea4b7ddb15e3ac00077f153120b5b61 subpackages: - jose - oauth2 @@ -27,10 +27,9 @@ imports: subpackages: - spew - name: github.com/docker/distribution - version: 534b155cc89a8787a192dd95bf293e4dde19335d + version: 7dba427612198a11b161a27f9d40bb2dca1ccd20 subpackages: - reference - - digest - name: github.com/emicklei/go-restful version: d916db217751a3fef55337f799c31fde4b8efcf1 subpackages: @@ -97,8 +96,12 @@ imports: - buffer - name: github.com/mitchellh/mapstructure version: bfdb1a85537d60bc7e954e600c250219ea497417 +- name: github.com/opencontainers/go-digest + version: a6d0ee40d4207ea02364bd3b9e8e77b9159ba1eb - name: github.com/pborman/uuid version: 5007efa264d92316c43112bc573e754bc889b7b1 +- name: github.com/pkg/browser + version: 9302be274faad99162b9d48ec97b24306872ebb0 - name: github.com/PuerkitoBio/purell version: 0bcb03f4b4d0a9428594752bd2a3b9aa0a9d4bd4 - name: github.com/PuerkitoBio/urlesc @@ -112,11 +115,11 @@ imports: subpackages: - codec - name: golang.org/x/crypto - version: 5b4074c2c416448b5d06e287167144493aabda43 + version: cb497ae8f18e3c55f81bc9f3876c8f4c3d8a2813 subpackages: - ssh/terminal - name: golang.org/x/net - version: 905989bd20b7c354fd28a61074eed1c8f49ebc89 + version: ae05321a78c1401cec22ba7bc203b597ea372496 subpackages: - context - http2 @@ -146,7 +149,7 @@ imports: - transform - unicode/bidi - name: google.golang.org/appengine - version: 08a149cfaee099e6ce4be01c0113a78c85ee1dee + version: 8758a385849434ba5eac8aeedcf5192c5a0f5f10 subpackages: - urlfetch - internal @@ -191,6 +194,7 @@ imports: - 1.5/tools/cache - 1.5/pkg/api/errors - 1.5/pkg/conversion + - 1.5/pkg/util/homedir - 1.5/pkg/api/unversioned - 1.5/discovery - 1.5/kubernetes/typed/apps/v1alpha1 @@ -241,7 +245,6 @@ imports: - 1.5/pkg/conversion/queryparams - 1.5/pkg/util/errors - 1.5/pkg/util/json - - 1.5/pkg/util/homedir - 1.5/pkg/util/validation - 1.5/tools/auth - 1.5/tools/clientcmd/api @@ -285,8 +288,4 @@ imports: - 1.5/tools/clientcmd/api/v1 - 1.5/pkg/util/framer - 1.5/pkg/util/yaml -- name: k8s.io/kubernetes - version: 9ce93ed50a7822d0fecd167211942cc18e6d965a - subpackages: - - pkg/util/homedir devImports: [] diff --git a/glide.yaml b/glide.yaml index 021940f..95beb15 100644 --- a/glide.yaml +++ b/glide.yaml @@ -22,3 +22,5 @@ import: - package: github.com/magiconair/properties - package: github.com/fsnotify/fsnotify - package: github.com/kardianos/osext +- package: github.com/pkg/browser +