cli + daemon: move test seams off package globals onto injected structs
CLI: introduce internal/cli.deps which owns every RPC/SSH/host-command seam the tree used to reach through mutable package vars. Command builders, orchestrators, and the completion helpers become methods on *deps. Tests construct their own deps per case, so fakes no longer leak across cases and tests are free to run in parallel. Daemon: move workspaceInspectRepoFunc + workspaceImportFunc onto the Daemon struct (workspaceInspectRepo / workspaceImport), mirroring the existing guestWaitForSSH / guestDial pattern. Workspace-prepare tests drop t.Parallel() guards now that they no longer mutate process-wide state. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d38f580e00
commit
c42fcbe012
19 changed files with 664 additions and 733 deletions
|
|
@ -22,35 +22,35 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newVMCommand() *cobra.Command {
|
||||
func (d *deps) newVMCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "vm",
|
||||
Short: "Manage virtual machines",
|
||||
RunE: helpNoArgs,
|
||||
}
|
||||
cmd.AddCommand(
|
||||
newVMCreateCommand(),
|
||||
newVMRunCommand(),
|
||||
newVMListCommand(),
|
||||
newVMShowCommand(),
|
||||
newVMActionCommand("start", "Start a VM", "vm.start"),
|
||||
newVMActionCommand("stop", "Stop a VM", "vm.stop"),
|
||||
newVMKillCommand(),
|
||||
newVMActionCommand("restart", "Restart a VM", "vm.restart"),
|
||||
newVMActionCommand("delete", "Delete a VM", "vm.delete", "rm"),
|
||||
newVMPruneCommand(),
|
||||
newVMSetCommand(),
|
||||
newVMSSHCommand(),
|
||||
newVMWorkspaceCommand(),
|
||||
newVMSessionCommand(),
|
||||
newVMLogsCommand(),
|
||||
newVMStatsCommand(),
|
||||
newVMPortsCommand(),
|
||||
d.newVMCreateCommand(),
|
||||
d.newVMRunCommand(),
|
||||
d.newVMListCommand(),
|
||||
d.newVMShowCommand(),
|
||||
d.newVMActionCommand("start", "Start a VM", "vm.start"),
|
||||
d.newVMActionCommand("stop", "Stop a VM", "vm.stop"),
|
||||
d.newVMKillCommand(),
|
||||
d.newVMActionCommand("restart", "Restart a VM", "vm.restart"),
|
||||
d.newVMActionCommand("delete", "Delete a VM", "vm.delete", "rm"),
|
||||
d.newVMPruneCommand(),
|
||||
d.newVMSetCommand(),
|
||||
d.newVMSSHCommand(),
|
||||
d.newVMWorkspaceCommand(),
|
||||
d.newVMSessionCommand(),
|
||||
d.newVMLogsCommand(),
|
||||
d.newVMStatsCommand(),
|
||||
d.newVMPortsCommand(),
|
||||
)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newVMRunCommand() *cobra.Command {
|
||||
func (d *deps) newVMRunCommand() *cobra.Command {
|
||||
defaults := effectiveVMDefaults()
|
||||
var (
|
||||
name string
|
||||
|
|
@ -104,7 +104,7 @@ Three modes:
|
|||
|
||||
var repoPtr *vmRunRepo
|
||||
if sourcePath != "" {
|
||||
resolved, err := vmRunPreflightRepo(cmd.Context(), sourcePath)
|
||||
resolved, err := d.vmRunPreflightRepo(cmd.Context(), sourcePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -135,11 +135,11 @@ Three modes:
|
|||
if err := system.EnsureSudo(cmd.Context()); err != nil {
|
||||
return err
|
||||
}
|
||||
layout, cfg, err = ensureDaemon(cmd.Context())
|
||||
layout, cfg, err = d.ensureDaemon(cmd.Context())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return runVMRun(cmd.Context(), layout.SocketPath, cfg, cmd.InOrStdin(), cmd.OutOrStdout(), cmd.ErrOrStderr(), params, repoPtr, commandArgs, removeOnExit)
|
||||
return d.runVMRun(cmd.Context(), layout.SocketPath, cfg, cmd.InOrStdin(), cmd.OutOrStdout(), cmd.ErrOrStderr(), params, repoPtr, commandArgs, removeOnExit)
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringVar(&name, "name", "", "vm name")
|
||||
|
|
@ -152,22 +152,22 @@ Three modes:
|
|||
cmd.Flags().StringVar(&branchName, "branch", "", "create and switch to a new guest branch")
|
||||
cmd.Flags().StringVar(&fromRef, "from", "HEAD", "base ref for --branch")
|
||||
cmd.Flags().BoolVar(&removeOnExit, "rm", false, "delete the VM after the ssh session / command exits")
|
||||
_ = cmd.RegisterFlagCompletionFunc("image", completeImageNames)
|
||||
_ = cmd.RegisterFlagCompletionFunc("image", d.completeImageNames)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newVMKillCommand() *cobra.Command {
|
||||
func (d *deps) newVMKillCommand() *cobra.Command {
|
||||
var signal string
|
||||
cmd := &cobra.Command{
|
||||
Use: "kill <id-or-name>...",
|
||||
Short: "Send a signal to a VM process",
|
||||
Args: minArgsUsage(1, "usage: banger vm kill [--signal SIGTERM|SIGKILL|...] <id-or-name>..."),
|
||||
ValidArgsFunction: completeVMNames,
|
||||
ValidArgsFunction: d.completeVMNames,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := system.EnsureSudo(cmd.Context()); err != nil {
|
||||
return err
|
||||
}
|
||||
layout, _, err := ensureDaemon(cmd.Context())
|
||||
layout, _, err := d.ensureDaemon(cmd.Context())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -201,7 +201,7 @@ func newVMKillCommand() *cobra.Command {
|
|||
return cmd
|
||||
}
|
||||
|
||||
func newVMPruneCommand() *cobra.Command {
|
||||
func (d *deps) newVMPruneCommand() *cobra.Command {
|
||||
var force bool
|
||||
cmd := &cobra.Command{
|
||||
Use: "prune",
|
||||
|
|
@ -212,23 +212,23 @@ func newVMPruneCommand() *cobra.Command {
|
|||
if err := system.EnsureSudo(cmd.Context()); err != nil {
|
||||
return err
|
||||
}
|
||||
layout, _, err := ensureDaemon(cmd.Context())
|
||||
layout, _, err := d.ensureDaemon(cmd.Context())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return runVMPrune(cmd, layout.SocketPath, force)
|
||||
return d.runVMPrune(cmd, layout.SocketPath, force)
|
||||
},
|
||||
}
|
||||
cmd.Flags().BoolVarP(&force, "force", "f", false, "skip the confirmation prompt")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func runVMPrune(cmd *cobra.Command, socketPath string, force bool) error {
|
||||
func (d *deps) runVMPrune(cmd *cobra.Command, socketPath string, force bool) error {
|
||||
ctx := cmd.Context()
|
||||
stdout := cmd.OutOrStdout()
|
||||
stderr := cmd.ErrOrStderr()
|
||||
|
||||
list, err := vmListFunc(ctx, socketPath)
|
||||
list, err := d.vmList(ctx, socketPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -270,7 +270,7 @@ func runVMPrune(cmd *cobra.Command, socketPath string, force bool) error {
|
|||
if ref == "" {
|
||||
ref = shortID(vm.ID)
|
||||
}
|
||||
if err := vmDeleteFunc(ctx, socketPath, vm.ID); err != nil {
|
||||
if err := d.vmDelete(ctx, socketPath, vm.ID); err != nil {
|
||||
fmt.Fprintf(stderr, "delete %s: %v\n", ref, err)
|
||||
failed++
|
||||
continue
|
||||
|
|
@ -299,7 +299,7 @@ func promptYesNo(in io.Reader, out io.Writer, prompt string) (bool, error) {
|
|||
return answer == "y" || answer == "yes", nil
|
||||
}
|
||||
|
||||
func newVMCreateCommand() *cobra.Command {
|
||||
func (d *deps) newVMCreateCommand() *cobra.Command {
|
||||
defaults := effectiveVMDefaults()
|
||||
var (
|
||||
name string
|
||||
|
|
@ -323,11 +323,11 @@ func newVMCreateCommand() *cobra.Command {
|
|||
if err := system.EnsureSudo(cmd.Context()); err != nil {
|
||||
return err
|
||||
}
|
||||
layout, _, err := ensureDaemon(cmd.Context())
|
||||
layout, _, err := d.ensureDaemon(cmd.Context())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
vm, err := runVMCreate(cmd.Context(), layout.SocketPath, cmd.ErrOrStderr(), params)
|
||||
vm, err := d.runVMCreate(cmd.Context(), layout.SocketPath, cmd.ErrOrStderr(), params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -342,7 +342,7 @@ func newVMCreateCommand() *cobra.Command {
|
|||
cmd.Flags().StringVar(&workDiskSize, "disk-size", model.FormatSizeBytes(defaults.WorkDiskSizeBytes), "work disk size")
|
||||
cmd.Flags().BoolVar(&natEnabled, "nat", false, "enable NAT")
|
||||
cmd.Flags().BoolVar(&noStart, "no-start", false, "create without starting")
|
||||
_ = cmd.RegisterFlagCompletionFunc("image", completeImageNames)
|
||||
_ = cmd.RegisterFlagCompletionFunc("image", d.completeImageNames)
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
|
@ -352,15 +352,15 @@ type vmListOptions struct {
|
|||
quiet bool
|
||||
}
|
||||
|
||||
func newPSCommand() *cobra.Command {
|
||||
return newVMListLikeCommand("ps", nil, "usage: banger ps")
|
||||
func (d *deps) newPSCommand() *cobra.Command {
|
||||
return d.newVMListLikeCommand("ps", nil, "usage: banger ps")
|
||||
}
|
||||
|
||||
func newVMListCommand() *cobra.Command {
|
||||
return newVMListLikeCommand("list", []string{"ls", "ps"}, "usage: banger vm list")
|
||||
func (d *deps) newVMListCommand() *cobra.Command {
|
||||
return d.newVMListLikeCommand("list", []string{"ls", "ps"}, "usage: banger vm list")
|
||||
}
|
||||
|
||||
func newVMListLikeCommand(use string, aliases []string, usage string) *cobra.Command {
|
||||
func (d *deps) newVMListLikeCommand(use string, aliases []string, usage string) *cobra.Command {
|
||||
var opts vmListOptions
|
||||
cmd := &cobra.Command{
|
||||
Use: use,
|
||||
|
|
@ -368,7 +368,7 @@ func newVMListLikeCommand(use string, aliases []string, usage string) *cobra.Com
|
|||
Short: "List VMs",
|
||||
Args: noArgsUsage(usage),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return runVMList(cmd, opts)
|
||||
return d.runVMList(cmd, opts)
|
||||
},
|
||||
}
|
||||
cmd.Flags().BoolVarP(&opts.showAll, "all", "a", false, "show all VMs")
|
||||
|
|
@ -377,8 +377,8 @@ func newVMListLikeCommand(use string, aliases []string, usage string) *cobra.Com
|
|||
return cmd
|
||||
}
|
||||
|
||||
func runVMList(cmd *cobra.Command, opts vmListOptions) error {
|
||||
layout, _, err := ensureDaemon(cmd.Context())
|
||||
func (d *deps) runVMList(cmd *cobra.Command, opts vmListOptions) error {
|
||||
layout, _, err := d.ensureDaemon(cmd.Context())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -421,14 +421,14 @@ func selectVMListVMs(vms []model.VMRecord, showAll, latest bool) []model.VMRecor
|
|||
return []model.VMRecord{latestVM}
|
||||
}
|
||||
|
||||
func newVMShowCommand() *cobra.Command {
|
||||
func (d *deps) newVMShowCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "show <id-or-name>",
|
||||
Short: "Show VM details",
|
||||
Args: exactArgsUsage(1, "usage: banger vm show <id-or-name>"),
|
||||
ValidArgsFunction: completeVMNameOnlyAtPos0,
|
||||
ValidArgsFunction: d.completeVMNameOnlyAtPos0,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
layout, _, err := ensureDaemon(cmd.Context())
|
||||
layout, _, err := d.ensureDaemon(cmd.Context())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -441,18 +441,18 @@ func newVMShowCommand() *cobra.Command {
|
|||
}
|
||||
}
|
||||
|
||||
func newVMActionCommand(use, short, method string, aliases ...string) *cobra.Command {
|
||||
func (d *deps) newVMActionCommand(use, short, method string, aliases ...string) *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: use + " <id-or-name>...",
|
||||
Aliases: aliases,
|
||||
Short: short,
|
||||
Args: minArgsUsage(1, fmt.Sprintf("usage: banger vm %s <id-or-name>...", use)),
|
||||
ValidArgsFunction: completeVMNames,
|
||||
ValidArgsFunction: d.completeVMNames,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := system.EnsureSudo(cmd.Context()); err != nil {
|
||||
return err
|
||||
}
|
||||
layout, _, err := ensureDaemon(cmd.Context())
|
||||
layout, _, err := d.ensureDaemon(cmd.Context())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -474,7 +474,7 @@ func newVMActionCommand(use, short, method string, aliases ...string) *cobra.Com
|
|||
}
|
||||
}
|
||||
|
||||
func newVMSetCommand() *cobra.Command {
|
||||
func (d *deps) newVMSetCommand() *cobra.Command {
|
||||
var (
|
||||
vcpu int
|
||||
memory int
|
||||
|
|
@ -486,7 +486,7 @@ func newVMSetCommand() *cobra.Command {
|
|||
Use: "set <id-or-name>...",
|
||||
Short: "Update stopped VM settings",
|
||||
Args: minArgsUsage(1, "usage: banger vm set [--vcpu N] [--memory MiB] [--disk-size SIZE] [--nat|--no-nat] <id-or-name>..."),
|
||||
ValidArgsFunction: completeVMNames,
|
||||
ValidArgsFunction: d.completeVMNames,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
params, err := vmSetParamsFromFlags(args[0], vcpu, memory, diskSize, nat, noNat)
|
||||
if err != nil {
|
||||
|
|
@ -495,7 +495,7 @@ func newVMSetCommand() *cobra.Command {
|
|||
if err := system.EnsureSudo(cmd.Context()); err != nil {
|
||||
return err
|
||||
}
|
||||
layout, _, err := ensureDaemon(cmd.Context())
|
||||
layout, _, err := d.ensureDaemon(cmd.Context())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -525,21 +525,21 @@ func newVMSetCommand() *cobra.Command {
|
|||
return cmd
|
||||
}
|
||||
|
||||
func newVMSSHCommand() *cobra.Command {
|
||||
func (d *deps) newVMSSHCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "ssh <id-or-name> [ssh args...]",
|
||||
Short: "SSH into a running VM",
|
||||
Args: minArgsUsage(1, "usage: banger vm ssh <id-or-name> [ssh args...]"),
|
||||
ValidArgsFunction: completeVMNameOnlyAtPos0,
|
||||
ValidArgsFunction: d.completeVMNameOnlyAtPos0,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
layout, cfg, err := ensureDaemon(cmd.Context())
|
||||
layout, cfg, err := d.ensureDaemon(cmd.Context())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := validateSSHPrereqs(cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := vmSSHFunc(cmd.Context(), layout.SocketPath, args[0])
|
||||
result, err := d.vmSSH(cmd.Context(), layout.SocketPath, args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -547,25 +547,25 @@ func newVMSSHCommand() *cobra.Command {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return runSSHSession(cmd.Context(), layout.SocketPath, result.Name, cmd.InOrStdin(), cmd.OutOrStdout(), cmd.ErrOrStderr(), sshArgs, false)
|
||||
return d.runSSHSession(cmd.Context(), layout.SocketPath, result.Name, cmd.InOrStdin(), cmd.OutOrStdout(), cmd.ErrOrStderr(), sshArgs, false)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func newVMWorkspaceCommand() *cobra.Command {
|
||||
func (d *deps) newVMWorkspaceCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "workspace",
|
||||
Short: "Manage repository workspaces inside a running VM",
|
||||
RunE: helpNoArgs,
|
||||
}
|
||||
cmd.AddCommand(
|
||||
newVMWorkspacePrepareCommand(),
|
||||
newVMWorkspaceExportCommand(),
|
||||
d.newVMWorkspacePrepareCommand(),
|
||||
d.newVMWorkspaceExportCommand(),
|
||||
)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newVMWorkspacePrepareCommand() *cobra.Command {
|
||||
func (d *deps) newVMWorkspacePrepareCommand() *cobra.Command {
|
||||
var guestPath string
|
||||
var branchName string
|
||||
var fromRef string
|
||||
|
|
@ -576,14 +576,14 @@ func newVMWorkspacePrepareCommand() *cobra.Command {
|
|||
Short: "Copy a local repo into a running VM",
|
||||
Long: "Prepare a repository workspace from a local git checkout into a running VM. The default guest path is /root/repo and the default mode is shallow_overlay. Repositories with git submodules must use --mode full_copy.",
|
||||
Args: minArgsUsage(1, "usage: banger vm workspace prepare <id-or-name> [path]"),
|
||||
ValidArgsFunction: completeVMNameOnlyAtPos0,
|
||||
ValidArgsFunction: d.completeVMNameOnlyAtPos0,
|
||||
Example: strings.TrimSpace(`
|
||||
banger vm workspace prepare devbox
|
||||
banger vm workspace prepare devbox ../repo --guest-path /root/repo --readonly
|
||||
banger vm workspace prepare devbox ../repo --mode full_copy
|
||||
`),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
layout, _, err := ensureDaemon(cmd.Context())
|
||||
layout, _, err := d.ensureDaemon(cmd.Context())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -592,7 +592,7 @@ func newVMWorkspacePrepareCommand() *cobra.Command {
|
|||
sourcePath = args[1]
|
||||
}
|
||||
if strings.TrimSpace(sourcePath) == "" {
|
||||
wd, err := cwdFunc()
|
||||
wd, err := d.cwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -606,7 +606,7 @@ func newVMWorkspacePrepareCommand() *cobra.Command {
|
|||
if strings.TrimSpace(branchName) != "" {
|
||||
prepareFrom = fromRef
|
||||
}
|
||||
result, err := vmWorkspacePrepareFunc(cmd.Context(), layout.SocketPath, api.VMWorkspacePrepareParams{
|
||||
result, err := d.vmWorkspacePrepare(cmd.Context(), layout.SocketPath, api.VMWorkspacePrepareParams{
|
||||
IDOrName: args[0],
|
||||
SourcePath: resolvedPath,
|
||||
GuestPath: guestPath,
|
||||
|
|
@ -629,7 +629,7 @@ func newVMWorkspacePrepareCommand() *cobra.Command {
|
|||
return cmd
|
||||
}
|
||||
|
||||
func newVMWorkspaceExportCommand() *cobra.Command {
|
||||
func (d *deps) newVMWorkspaceExportCommand() *cobra.Command {
|
||||
var guestPath string
|
||||
var outputPath string
|
||||
var baseCommit string
|
||||
|
|
@ -638,7 +638,7 @@ func newVMWorkspaceExportCommand() *cobra.Command {
|
|||
Short: "Pull changes from a guest workspace back to the host as a patch",
|
||||
Long: "Emit a binary-safe unified diff of every change inside the guest workspace (committed since base + uncommitted + untracked, minus .gitignore). Non-mutating — the guest's index and working tree are untouched. Pass --base-commit with the head_commit from workspace prepare to capture changes even when the worker ran git commit inside the VM. Without --base-commit the diff is against the current guest HEAD, which misses committed changes.",
|
||||
Args: exactArgsUsage(1, "usage: banger vm workspace export <id-or-name>"),
|
||||
ValidArgsFunction: completeVMNameOnlyAtPos0,
|
||||
ValidArgsFunction: d.completeVMNameOnlyAtPos0,
|
||||
Example: strings.TrimSpace(`
|
||||
banger vm workspace export devbox | git apply
|
||||
banger vm workspace export devbox --base-commit abc1234 | git apply
|
||||
|
|
@ -646,11 +646,11 @@ func newVMWorkspaceExportCommand() *cobra.Command {
|
|||
banger vm workspace export devbox --guest-path /root/project --output changes.diff
|
||||
`),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
layout, _, err := ensureDaemon(cmd.Context())
|
||||
layout, _, err := d.ensureDaemon(cmd.Context())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := vmWorkspaceExportFunc(cmd.Context(), layout.SocketPath, api.WorkspaceExportParams{
|
||||
result, err := d.vmWorkspaceExport(cmd.Context(), layout.SocketPath, api.WorkspaceExportParams{
|
||||
IDOrName: args[0],
|
||||
GuestPath: guestPath,
|
||||
BaseCommit: baseCommit,
|
||||
|
|
@ -680,15 +680,15 @@ func newVMWorkspaceExportCommand() *cobra.Command {
|
|||
return cmd
|
||||
}
|
||||
|
||||
func newVMLogsCommand() *cobra.Command {
|
||||
func (d *deps) newVMLogsCommand() *cobra.Command {
|
||||
var follow bool
|
||||
cmd := &cobra.Command{
|
||||
Use: "logs <id-or-name>",
|
||||
Short: "Show VM logs",
|
||||
Args: exactArgsUsage(1, "usage: banger vm logs [-f] <id-or-name>"),
|
||||
ValidArgsFunction: completeVMNameOnlyAtPos0,
|
||||
ValidArgsFunction: d.completeVMNameOnlyAtPos0,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
layout, _, err := ensureDaemon(cmd.Context())
|
||||
layout, _, err := d.ensureDaemon(cmd.Context())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -706,14 +706,14 @@ func newVMLogsCommand() *cobra.Command {
|
|||
return cmd
|
||||
}
|
||||
|
||||
func newVMStatsCommand() *cobra.Command {
|
||||
func (d *deps) newVMStatsCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "stats <id-or-name>",
|
||||
Short: "Show VM stats",
|
||||
Args: exactArgsUsage(1, "usage: banger vm stats <id-or-name>"),
|
||||
ValidArgsFunction: completeVMNameOnlyAtPos0,
|
||||
ValidArgsFunction: d.completeVMNameOnlyAtPos0,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
layout, _, err := ensureDaemon(cmd.Context())
|
||||
layout, _, err := d.ensureDaemon(cmd.Context())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -726,18 +726,18 @@ func newVMStatsCommand() *cobra.Command {
|
|||
}
|
||||
}
|
||||
|
||||
func newVMPortsCommand() *cobra.Command {
|
||||
func (d *deps) newVMPortsCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "ports <id-or-name>",
|
||||
Short: "Show host-reachable listening guest ports",
|
||||
Args: exactArgsUsage(1, "usage: banger vm ports <id-or-name>"),
|
||||
ValidArgsFunction: completeVMNameOnlyAtPos0,
|
||||
ValidArgsFunction: d.completeVMNameOnlyAtPos0,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
layout, _, err := ensureDaemon(cmd.Context())
|
||||
layout, _, err := d.ensureDaemon(cmd.Context())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := vmPortsFunc(cmd.Context(), layout.SocketPath, args[0])
|
||||
result, err := d.vmPorts(cmd.Context(), layout.SocketPath, args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue