add an ark bug command
Signed-off-by: Dave Parfitt <diparfitt@gmail.com>pull/774/head
parent
652069b5e6
commit
342a1c6437
|
@ -27,7 +27,7 @@ about: Tell us about a problem you are experiencing
|
|||
|
||||
**Environment:**
|
||||
|
||||
- Ark version (use `ark version`):
|
||||
- Ark version (use `ark version`):
|
||||
- Kubernetes version (use `kubectl version`):
|
||||
- Kubernetes installer & version:
|
||||
- Cloud provider or hardware configuration:
|
||||
|
|
|
@ -31,6 +31,7 @@ operations can also be performed as 'ark backup get' and 'ark schedule create'.
|
|||
|
||||
### SEE ALSO
|
||||
* [ark backup](ark_backup.md) - Work with backups
|
||||
* [ark bug](ark_bug.md) - Report an Ark bug
|
||||
* [ark client](ark_client.md) - Ark client related commands
|
||||
* [ark completion](ark_completion.md) - Output shell completion code for the specified shell (bash or zsh)
|
||||
* [ark create](ark_create.md) - Create ark resources
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
## ark bug
|
||||
|
||||
Report an Ark bug
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
Open a browser window to report an Ark bug
|
||||
|
||||
```
|
||||
ark bug [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for bug
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--alsologtostderr log to standard error as well as files
|
||||
--kubeconfig string Path to the kubeconfig file to use to talk to the Kubernetes apiserver. If unset, try the environment variable KUBECONFIG, as well as in-cluster configuration
|
||||
--kubecontext string The context to use to talk to the Kubernetes apiserver. If unset defaults to whatever your current-context is (kubectl config current-context)
|
||||
--log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0)
|
||||
--log_dir string If non-empty, write log files in this directory
|
||||
--logtostderr log to standard error instead of files
|
||||
-n, --namespace string The namespace in which Ark should operate (default "heptio-ark")
|
||||
--stderrthreshold severity logs at or above this threshold go to stderr (default 2)
|
||||
-v, --v Level log level for V logs
|
||||
--vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
* [ark](ark.md) - Back up and restore Kubernetes cluster resources.
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
Copyright 2018 the Heptio Ark contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This code renders the IssueTemplate string in pkg/cmd/cli/bug/bug.go to
|
||||
// .github/ISSUE_TEMPLATE/bug_report.md via the hack/update-generated-issue-template.sh script.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"text/template"
|
||||
|
||||
"github.com/heptio/ark/pkg/cmd/cli/bug"
|
||||
)
|
||||
|
||||
func main() {
|
||||
outTemplateFilename := os.Args[1]
|
||||
outFile, err := os.OpenFile(outTemplateFilename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer outFile.Close()
|
||||
tmpl, err := template.New("ghissue").Parse(bug.IssueTemplate)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err = tmpl.Execute(outFile, bug.ArkBugInfo{})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
These tips can help you troubleshoot known issues. If they don't help, you can [file an issue][4], or talk to us on the [#ark-dr channel][25] on the Kubernetes Slack server.
|
||||
|
||||
In `ark` version >= `0.1.0`, you can use the `ark bug` command to open a [Github issue][4] by launching a browser window with some prepopulated values. Values included are OS, CPU architecture, `kubectl` client and server versions (if available) and the `ark` client version. This information isn't submitted to Github until you click the `Submit new issue` button in the Github UI, so feel free to add, remove or update whatever information you like.
|
||||
|
||||
Some general commands for troubleshooting that may be helpful:
|
||||
|
||||
* `ark backup describe <backupName>` - describe the details of a backup
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
#!/bin/bash -e
|
||||
#
|
||||
# Copyright 2018 the Heptio Ark contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
ARK_ROOT=$(dirname ${BASH_SOURCE})/..
|
||||
BIN=${ARK_ROOT}/_output/bin
|
||||
|
||||
mkdir -p ${BIN}
|
||||
|
||||
echo "Updating generated Github issue template"
|
||||
go build -o ${BIN}/issue-tmpl-gen ./docs/issue-template-gen/main.go
|
||||
|
||||
if [[ $# -gt 1 ]]; then
|
||||
echo "usage: ${BASH_SOURCE} [OUTPUT_FILE]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
OUTPUT_ISSUE_FILE="$1"
|
||||
if [[ -z "${OUTPUT_ISSUE_FILE}" ]]; then
|
||||
OUTPUT_ISSUE_FILE=${ARK_ROOT}/.github/ISSUE_TEMPLATE/bug_report.md
|
||||
fi
|
||||
|
||||
${BIN}/issue-tmpl-gen ${OUTPUT_ISSUE_FILE}
|
||||
echo "Success!"
|
|
@ -0,0 +1,39 @@
|
|||
#!/bin/bash -e
|
||||
#
|
||||
# Copyright 2018 the Heptio Ark contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
ARK_ROOT=$(dirname ${BASH_SOURCE})/..
|
||||
HACK_DIR=$(dirname "${BASH_SOURCE}")
|
||||
ISSUE_TEMPLATE_FILE=${ARK_ROOT}/.github/ISSUE_TEMPLATE/bug_report.md
|
||||
OUT_TMP_FILE="$(mktemp -d)"/bug_report.md
|
||||
|
||||
|
||||
trap cleanup INT TERM HUP EXIT
|
||||
|
||||
cleanup() {
|
||||
rm -rf ${TMP_DIR}
|
||||
}
|
||||
|
||||
echo "Verifying generated Github issue template"
|
||||
${HACK_DIR}/update-generated-issue-template.sh ${OUT_TMP_FILE} > /dev/null
|
||||
output=$(echo "`diff ${ISSUE_TEMPLATE_FILE} ${OUT_TMP_FILE}`")
|
||||
|
||||
if [[ -n "${output}" ]] ; then
|
||||
echo "FAILURE: verification of generated template failed:"
|
||||
echo "${output}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Success!"
|
|
@ -23,6 +23,7 @@ import (
|
|||
|
||||
"github.com/heptio/ark/pkg/client"
|
||||
"github.com/heptio/ark/pkg/cmd/cli/backup"
|
||||
"github.com/heptio/ark/pkg/cmd/cli/bug"
|
||||
cliclient "github.com/heptio/ark/pkg/cmd/cli/client"
|
||||
"github.com/heptio/ark/pkg/cmd/cli/completion"
|
||||
"github.com/heptio/ark/pkg/cmd/cli/create"
|
||||
|
@ -69,6 +70,7 @@ operations can also be performed as 'ark backup get' and 'ark schedule create'.`
|
|||
cliclient.NewCommand(),
|
||||
completion.NewCommand(),
|
||||
restic.NewCommand(f),
|
||||
bug.NewCommand(),
|
||||
)
|
||||
|
||||
// add the glog flags
|
||||
|
|
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
Copyright 2018 the Heptio Ark contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package bug
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/heptio/ark/pkg/buildinfo"
|
||||
"github.com/heptio/ark/pkg/cmd"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
const (
|
||||
// kubectlTimeout is how long we wait in seconds for `kubectl version`
|
||||
// before killing the process
|
||||
kubectlTimeout = 5 * time.Second
|
||||
issueURL = "https://github.com/heptio/ark/issues/new"
|
||||
// IssueTemplate is used to generate .github/ISSUE_TEMPLATE/bug_report.md
|
||||
// as well as the initial text that's place in a new Github issue as
|
||||
// the result of running `ark bug`.
|
||||
IssueTemplate = `---
|
||||
name: Bug report
|
||||
about: Tell us about a problem you are experiencing
|
||||
|
||||
---
|
||||
|
||||
**What steps did you take and what happened:**
|
||||
[A clear and concise description of what the bug is, and what commands you ran.)
|
||||
|
||||
|
||||
**What did you expect to happen:**
|
||||
|
||||
|
||||
**The output of the following commands will help us better understand what's going on**:
|
||||
(Pasting long output into a [GitHub gist](https://gist.github.com) or other pastebin is fine.)
|
||||
|
||||
* ` + "`kubectl logs deployment/ark -n heptio-ark`" + `
|
||||
* ` + "`ark backup describe <backupname>` or `kubectl get backup/<backupname> -n heptio-ark -o yaml`" + `
|
||||
* ` + "`ark backup logs <backupname>`" + `
|
||||
* ` + "`ark restore describe <restorename>` or `kubectl get restore/<restorename> -n heptio-ark -o yaml`" + `
|
||||
* ` + "`ark restore logs <restorename>`" + `
|
||||
|
||||
|
||||
**Anything else you would like to add:**
|
||||
[Miscellaneous information that will assist in solving the issue.]
|
||||
|
||||
|
||||
**Environment:**
|
||||
|
||||
- Ark version (use ` + "`ark version`" + `):{{.ArkVersion}} {{.GitCommit}} {{.GitTreeState}}
|
||||
- Kubernetes version (use ` + "`kubectl version`" + `):
|
||||
{{- if .KubectlVersion}}
|
||||
` + "```" + `
|
||||
{{.KubectlVersion}}
|
||||
` + "```" + `
|
||||
{{end}}
|
||||
- Kubernetes installer & version:
|
||||
- Cloud provider or hardware configuration:
|
||||
- OS (e.g. from ` + "`/etc/os-release`" + `):
|
||||
{{if .RuntimeOS}} - RuntimeOS: {{.RuntimeOS}}{{end -}}
|
||||
{{if .RuntimeArch}} - RuntimeArch: {{.RuntimeArch}}{{end -}}
|
||||
`
|
||||
)
|
||||
|
||||
func NewCommand() *cobra.Command {
|
||||
c := &cobra.Command{
|
||||
Use: "bug",
|
||||
Short: "Report an Ark bug",
|
||||
Long: "Open a browser window to report an Ark bug",
|
||||
Run: func(c *cobra.Command, args []string) {
|
||||
kubectlVersion, err := getKubectlVersion()
|
||||
if err != nil {
|
||||
// we don't want to prevent the user from submitting a bug
|
||||
// if we can't get the kubectl version, so just display a warning
|
||||
fmt.Fprintf(os.Stderr, "WARNING: can't get kubectl version: %v\n", err)
|
||||
}
|
||||
body, err := renderToString(newBugInfo(kubectlVersion))
|
||||
cmd.CheckError(err)
|
||||
cmd.CheckError(showIssueInBrowser(body))
|
||||
},
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
type ArkBugInfo struct {
|
||||
ArkVersion string
|
||||
GitCommit string
|
||||
GitTreeState string
|
||||
RuntimeOS string
|
||||
RuntimeArch string
|
||||
KubectlVersion string
|
||||
}
|
||||
|
||||
// cmdExistsOnPath checks to see if an executable is available on the current PATH
|
||||
func cmdExistsOnPath(name string) bool {
|
||||
if _, err := exec.LookPath(name); err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// getKubectlVersion makes a best-effort to run `kubectl version`
|
||||
// and return it's output. This func will timeout and return an empty
|
||||
// string after kubectlTimeout if we're not connected to a cluster.
|
||||
func getKubectlVersion() (string, error) {
|
||||
if !cmdExistsOnPath("kubectl") {
|
||||
return "", errors.New("kubectl not found on PATH")
|
||||
}
|
||||
|
||||
kubectlCmd := exec.Command("kubectl", "version")
|
||||
var outbuf bytes.Buffer
|
||||
kubectlCmd.Stdout = &outbuf
|
||||
if err := kubectlCmd.Start(); err != nil {
|
||||
return "", errors.New("can't start kubectl")
|
||||
}
|
||||
|
||||
done := make(chan error, 1)
|
||||
go func() {
|
||||
done <- kubectlCmd.Wait()
|
||||
}()
|
||||
select {
|
||||
case <-time.After(kubectlTimeout):
|
||||
// we don't care about the possible error returned from Kill() here,
|
||||
// just return an empty string
|
||||
kubectlCmd.Process.Kill()
|
||||
return "", errors.New("timeout waiting for kubectl version")
|
||||
|
||||
case err := <-done:
|
||||
if err != nil {
|
||||
return "", errors.New("error waiting for kubectl process")
|
||||
}
|
||||
}
|
||||
versionOut := outbuf.String()
|
||||
kubectlVersion := strings.TrimSpace(string(versionOut))
|
||||
return kubectlVersion, nil
|
||||
}
|
||||
|
||||
func newBugInfo(kubectlVersion string) *ArkBugInfo {
|
||||
return &ArkBugInfo{
|
||||
ArkVersion: buildinfo.Version,
|
||||
GitCommit: buildinfo.GitSHA,
|
||||
GitTreeState: buildinfo.GitTreeState,
|
||||
RuntimeOS: runtime.GOOS,
|
||||
RuntimeArch: runtime.GOARCH,
|
||||
KubectlVersion: kubectlVersion}
|
||||
}
|
||||
|
||||
// renderToString renders IssueTemplate to a string using the
|
||||
// supplied *ArkBugInfo
|
||||
func renderToString(bugInfo *ArkBugInfo) (string, error) {
|
||||
outputTemplate, err := template.New("ghissue").Parse(IssueTemplate)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
err = outputTemplate.Execute(&buf, bugInfo)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
||||
// showIssueInBrowser opens a browser window to submit a Github issue using
|
||||
// a platform specific binary.
|
||||
func showIssueInBrowser(body string) error {
|
||||
url := issueURL + "?body=" + url.QueryEscape(body)
|
||||
switch runtime.GOOS {
|
||||
case "darwin":
|
||||
return exec.Command("open", url).Start()
|
||||
case "linux":
|
||||
if cmdExistsOnPath("xdg-open") {
|
||||
return exec.Command("xdg-open", url).Start()
|
||||
}
|
||||
return fmt.Errorf("ark can't open a browser window using the command '%s'", "xdg-open")
|
||||
case "windows":
|
||||
return exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start()
|
||||
default:
|
||||
return fmt.Errorf("ark can't open a browser window on platform %s", runtime.GOOS)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue