Skip to content

Commit

Permalink
feat: adds support bundles (runfinch#210)
Browse files Browse the repository at this point in the history
Signed-off-by: Sam Berning <[email protected]>

Issue #, if available:

*Description of changes:*

Allow users to generate a support bundle, a collection of Finch-related
logs and configs that will help debug issues.

*Testing done:*

Unit & manual testing


- [x] I've reviewed the guidance in CONTRIBUTING.md


#### License Acceptance

By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 license.

Signed-off-by: Sam Berning <[email protected]>
  • Loading branch information
sam-berning authored Mar 29, 2023
1 parent 05227ce commit cc6be65
Show file tree
Hide file tree
Showing 18 changed files with 1,914 additions and 4 deletions.
3 changes: 3 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,6 @@ If applicable, add screenshots or logs to help explain your problem.

**Additional context**
Add any other context about the problem here.


_To help debug the issue as quickly as possible, we recommend generating a support bundle with `finch support-bundle-generate` and attaching it to this issue. This packages all Finch-related configs and logs into one file._
12 changes: 10 additions & 2 deletions cmd/finch/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ import (
"io"
"os"

"github.com/runfinch/finch/pkg/disk"

"github.com/runfinch/finch/pkg/command"
"github.com/runfinch/finch/pkg/config"
"github.com/runfinch/finch/pkg/dependency"
"github.com/runfinch/finch/pkg/dependency/vmnet"
"github.com/runfinch/finch/pkg/disk"
"github.com/runfinch/finch/pkg/flog"
"github.com/runfinch/finch/pkg/fmemory"
"github.com/runfinch/finch/pkg/fssh"
"github.com/runfinch/finch/pkg/path"
"github.com/runfinch/finch/pkg/support"
"github.com/runfinch/finch/pkg/system"
"github.com/runfinch/finch/pkg/version"

Expand Down Expand Up @@ -88,13 +88,21 @@ var newApp = func(logger flog.Logger, fp path.Finch, fs afero.Fs, fc *config.Fin
fp.QEMUBinDir(),
system.NewStdLib(),
)
supportBundleBuilder := support.NewBundleBuilder(
logger,
fs,
support.NewBundleConfig(fp, system.NewStdLib().Env("HOME")),
fp,
ecc,
)

// append nerdctl commands
allCommands := initializeNerdctlCommands(lcc, logger, fs)
// append finch specific commands
allCommands = append(allCommands,
newVersionCommand(lcc, logger, stdOut),
virtualMachineCommands(logger, fp, lcc, ecc, fs, fc),
newSupportBundleCommand(logger, supportBundleBuilder, lcc),
)

rootCmd.AddCommand(allCommands...)
Expand Down
4 changes: 2 additions & 2 deletions cmd/finch/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@ func TestNewApp(t *testing.T) {
assert.Equal(t, cmd.Version, version.Version)
assert.Equal(t, cmd.SilenceUsage, true)
assert.Equal(t, cmd.SilenceErrors, true)
// confirm the number of command, comprised of nerdctl commands + finch commands (version, vm)
assert.Equal(t, len(cmd.Commands()), len(nerdctlCmds)+2)
// confirm the number of command, comprised of nerdctl commands + finch commands (version, vm, support-bundle)
assert.Equal(t, len(cmd.Commands()), len(nerdctlCmds)+3)

// PersistentPreRunE should set logger level to debug if the debug flag exists.
mockCmd := &cobra.Command{}
Expand Down
104 changes: 104 additions & 0 deletions cmd/finch/support_bundle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package main

import (
"fmt"

"github.com/spf13/cobra"

"github.com/runfinch/finch/pkg/command"
"github.com/runfinch/finch/pkg/flog"
"github.com/runfinch/finch/pkg/lima"
"github.com/runfinch/finch/pkg/support"
)

func newSupportBundleCommand(logger flog.Logger, builder support.BundleBuilder, lcc command.LimaCmdCreator) *cobra.Command {
supportBundleCommand := &cobra.Command{
Use: "support-bundle",
Short: "Support bundle management",
}
supportBundleCommand.AddCommand(
newSupportBundleGenerateCommand(logger, builder, lcc),
)
return supportBundleCommand
}

func newSupportBundleGenerateCommand(logger flog.Logger, builder support.BundleBuilder, lcc command.LimaCmdCreator) *cobra.Command {
supportBundleGenerateCommand := &cobra.Command{
Use: "generate",
Args: cobra.NoArgs,
Short: "Generate support bundle",
Long: "Generates a collection of logs and configs that can be uploaded to a Github issue to help debug issues.",
RunE: newGenerateSupportBundleAction(logger, builder, lcc).runAdapter,
}

supportBundleGenerateCommand.Flags().StringArray("include", []string{},
"additional files to include in the support bundle, specified by absolute or relative path")
supportBundleGenerateCommand.Flags().StringArray("exclude", []string{},
//nolint:lll // usage string
"files to exclude from the support bundle. if you specify a base name, all files matching that base name will be excluded. if you specify an absolute or relative path, only exact matches will be excluded")
return supportBundleGenerateCommand
}

type generateSupportBundleAction struct {
logger flog.Logger
builder support.BundleBuilder
lcc command.LimaCmdCreator
}

func newGenerateSupportBundleAction(
logger flog.Logger,
builder support.BundleBuilder,
lcc command.LimaCmdCreator,
) *generateSupportBundleAction {
return &generateSupportBundleAction{
logger: logger,
builder: builder,
lcc: lcc,
}
}

func (gsa *generateSupportBundleAction) runAdapter(cmd *cobra.Command, args []string) error {
additionalFiles, err := cmd.Flags().GetStringArray("include")
if err != nil {
return err
}
excludeFiles, err := cmd.Flags().GetStringArray("exclude")
if err != nil {
return err
}
return gsa.run(additionalFiles, excludeFiles)
}

func (gsa *generateSupportBundleAction) run(additionalFiles []string, excludeFiles []string) error {
err := gsa.assertVMExists()
if err != nil {
return err
}
gsa.logger.Info("Generating support bundle...")
bundleFile, err := gsa.builder.GenerateSupportBundle(additionalFiles, excludeFiles)
if err != nil {
return err
}
gsa.logger.Infof("Bundle created: %s", bundleFile)
gsa.logger.Info("Files posted on a Github issue can be read by anyone.")
gsa.logger.Info("Please ensure there is no sensitive information in the bundle before uploading.")
gsa.logger.Info("By default, this bundle contains basic logs and configs for Finch.")
return nil
}

func (gsa *generateSupportBundleAction) assertVMExists() error {
status, err := lima.GetVMStatus(gsa.lcc, gsa.logger, limaInstanceName)
if err != nil {
return err
}
switch status {
case lima.Nonexistent:
return fmt.Errorf("cannot create support bundle for nonexistent VM, run `finch %s init` to create a new instance",
virtualMachineRootCmd)
default:
return nil
}
}
Loading

0 comments on commit cc6be65

Please sign in to comment.