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:**
|
**Environment:**
|
||||||
|
|
||||||
- Ark version (use `ark version`):
|
- Ark version (use `ark version`):
|
||||||
- Kubernetes version (use `kubectl version`):
|
- Kubernetes version (use `kubectl version`):
|
||||||
- Kubernetes installer & version:
|
- Kubernetes installer & version:
|
||||||
- Cloud provider or hardware configuration:
|
- Cloud provider or hardware configuration:
|
||||||
|
|
|
@ -31,6 +31,7 @@ operations can also be performed as 'ark backup get' and 'ark schedule create'.
|
||||||
|
|
||||||
### SEE ALSO
|
### SEE ALSO
|
||||||
* [ark backup](ark_backup.md) - Work with backups
|
* [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 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 completion](ark_completion.md) - Output shell completion code for the specified shell (bash or zsh)
|
||||||
* [ark create](ark_create.md) - Create ark resources
|
* [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.
|
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:
|
Some general commands for troubleshooting that may be helpful:
|
||||||
|
|
||||||
* `ark backup describe <backupName>` - describe the details of a backup
|
* `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/client"
|
||||||
"github.com/heptio/ark/pkg/cmd/cli/backup"
|
"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"
|
cliclient "github.com/heptio/ark/pkg/cmd/cli/client"
|
||||||
"github.com/heptio/ark/pkg/cmd/cli/completion"
|
"github.com/heptio/ark/pkg/cmd/cli/completion"
|
||||||
"github.com/heptio/ark/pkg/cmd/cli/create"
|
"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(),
|
cliclient.NewCommand(),
|
||||||
completion.NewCommand(),
|
completion.NewCommand(),
|
||||||
restic.NewCommand(f),
|
restic.NewCommand(f),
|
||||||
|
bug.NewCommand(),
|
||||||
)
|
)
|
||||||
|
|
||||||
// add the glog flags
|
// 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