Skip to content

feat(cli): retrieve virtual machine instance description#602

Merged
skevetter merged 1 commit intoskevetter:mainfrom
dubinsky:machine-describe
Mar 10, 2026
Merged

feat(cli): retrieve virtual machine instance description#602
skevetter merged 1 commit intoskevetter:mainfrom
dubinsky:machine-describe

Conversation

@dubinsky
Copy link

@dubinsky dubinsky commented Mar 9, 2026

Summary by CodeRabbit

  • New Features

    • Added a new "describe" command to retrieve and display machine descriptions.
    • Client and backend now surface machine descriptions to the CLI.
  • Bug Fixes

    • Corrected multiple command help/description strings that incorrectly referenced "destroy".
  • Chores

    • Clarified status command help to indicate output format options (plain or json).

@coderabbitai
Copy link

coderabbitai bot commented Mar 9, 2026

📝 Walkthrough

Walkthrough

Adds a new machine "describe" CLI command and corresponding client API/implementations that run provider describe commands and return their output; extends provider config with a describe command array; and fixes several machine command docstrings. No existing public API signatures were removed.

Changes

Cohort / File(s) Summary
New Describe CLI
cmd/machine/describe.go, cmd/machine/machine.go
Add DescribeCmd and NewDescribeCmd; register the new describe subcommand and wire it into the machine command tree.
Client API & Types
pkg/client/client.go
Add Client.Describe(ctx context.Context) (string, error) and top-level constant DescriptionNotFound = "{}".
Client Implementations
pkg/client/clientimplementation/machine_client.go, pkg/client/clientimplementation/workspace_client.go
Implement Describe on machineClient to execute provider describe command and return trimmed stdout or DescriptionNotFound on error; add workspaceClient.Describe delegating to machineClient when a machine provider and command configured.
Provider Configuration
pkg/provider/provider.go
Add Describe types.StrArray field to ProviderCommands (json:"describe,omitempty").
Docstring Corrections
cmd/machine/delete.go, cmd/machine/list.go, cmd/machine/ssh.go, cmd/machine/start.go, cmd/machine/stop.go, cmd/machine/status.go
Fix constructor/doc comments and clarify status flag help text; no behavioral changes.

Sequence Diagram

sequenceDiagram
    participant CLI as CLI
    participant Config as Config Loader
    participant Workspace as Workspace Client
    participant Machine as Machine Client
    participant Executor as Command Executor
    participant Output as Stdout/Stderr

    CLI->>Config: Load config
    Config-->>CLI: config
    CLI->>Workspace: GetMachine(config, args)
    Workspace-->>CLI: machine client
    CLI->>Machine: Describe(ctx)
    Machine->>Executor: Run provider describe command
    Executor->>Output: Capture stdout/stderr
    Executor-->>Machine: result
    alt success
        Machine-->>CLI: Description (stdout)
    else failure
        Machine-->>CLI: DescriptionNotFound (combined stdout/stderr)
    end
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the primary change: adding a new CLI feature to retrieve virtual machine instance descriptions. The changeset introduces a Describe command across multiple files (cmd/machine/describe.go), updates the machine command registry, adds the necessary client interface methods, and extends the provider configuration to support descriptions.
Docstring Coverage ✅ Passed Docstring coverage is 88.89% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added the size/m label Mar 9, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
cmd/machine/describe.go (1)

28-29: Use the cobra command's context instead of context.Background().

Using context.Background() ignores any context set on the cobra command, which can affect signal handling and cancellation propagation.

♻️ Proposed fix
 describeCmd := &cobra.Command{
 	Use:   "describe [name]",
 	Short: "Retrieves the description of an existing machine",
-	RunE: func(_ *cobra.Command, args []string) error {
-		return cmd.Run(context.Background(), args)
+	RunE: func(cobraCmd *cobra.Command, args []string) error {
+		return cmd.Run(cobraCmd.Context(), args)
 	},
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/machine/describe.go` around lines 28 - 29, The RunE handler uses
context.Background() which ignores the cobra command's context; change the
handler signature to accept the cobra command (e.g. func(c *cobra.Command, args
[]string) error) and pass c.Context() into the existing cmd.Run call (replace
context.Background() with c.Context()), ensuring you don't shadow the
package-level cmd variable while updating the parameter name.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@cmd/machine/describe.go`:
- Around line 28-29: The RunE handler uses context.Background() which ignores
the cobra command's context; change the handler signature to accept the cobra
command (e.g. func(c *cobra.Command, args []string) error) and pass c.Context()
into the existing cmd.Run call (replace context.Background() with c.Context()),
ensuring you don't shadow the package-level cmd variable while updating the
parameter name.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0f3771ea-ec44-454f-8950-09c5a7d88749

📥 Commits

Reviewing files that changed from the base of the PR and between 8f26dc9 and ca535f8.

📒 Files selected for processing (12)
  • cmd/machine/delete.go
  • cmd/machine/describe.go
  • cmd/machine/list.go
  • cmd/machine/machine.go
  • cmd/machine/ssh.go
  • cmd/machine/start.go
  • cmd/machine/status.go
  • cmd/machine/stop.go
  • pkg/client/client.go
  • pkg/client/clientimplementation/machine_client.go
  • pkg/client/clientimplementation/workspace_client.go
  • pkg/provider/provider.go

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
cmd/machine/describe.go (1)

26-31: Consider using cobra command's context for signal propagation.

Using context.Background() in the RunE handler ignores any context that cobra may provide (e.g., for handling cancellation signals like SIGINT). Consider using the command's context:

♻️ Suggested improvement
 	describeCmd := &cobra.Command{
 		Use:   "describe [name]",
 		Short: "Retrieves the description of an existing machine",
-		RunE: func(_ *cobra.Command, args []string) error {
-			return cmd.Run(context.Background(), args)
+		RunE: func(cobraCmd *cobra.Command, args []string) error {
+			return cmd.Run(cobraCmd.Context(), args)
 		},
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/machine/describe.go` around lines 26 - 31, The handler currently calls
cmd.Run with context.Background(), which ignores cobra's command context and
signal cancellation; change the RunE signature to accept the command (e.g.,
func(c *cobra.Command, args []string) error) and call cmd.Run(c.Context(), args)
so describeCmd uses the cobra-provided context for cancellation/propagation
(also remove the now-unused context.Background() usage/import).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@cmd/machine/describe.go`:
- Around line 26-31: The handler currently calls cmd.Run with
context.Background(), which ignores cobra's command context and signal
cancellation; change the RunE signature to accept the command (e.g., func(c
*cobra.Command, args []string) error) and call cmd.Run(c.Context(), args) so
describeCmd uses the cobra-provided context for cancellation/propagation (also
remove the now-unused context.Background() usage/import).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e86024f1-73b0-485b-b016-cb6cb0d0f1f4

📥 Commits

Reviewing files that changed from the base of the PR and between ca535f8 and 844152d.

📒 Files selected for processing (11)
  • cmd/machine/delete.go
  • cmd/machine/describe.go
  • cmd/machine/list.go
  • cmd/machine/machine.go
  • cmd/machine/ssh.go
  • cmd/machine/start.go
  • cmd/machine/status.go
  • cmd/machine/stop.go
  • pkg/client/client.go
  • pkg/client/clientimplementation/machine_client.go
  • pkg/client/clientimplementation/workspace_client.go
✅ Files skipped from review due to trivial changes (3)
  • cmd/machine/ssh.go
  • cmd/machine/list.go
  • cmd/machine/start.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • cmd/machine/status.go
  • cmd/machine/stop.go
  • cmd/machine/delete.go
  • pkg/client/clientimplementation/machine_client.go

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
cmd/machine/describe.go (1)

26-32: Consider adding argument validation to the command.

The Use: "describe [name]" suggests an optional single argument, but without explicit Args validation, extra arguments are silently ignored (per GetMachine behavior in pkg/workspace/machine.go:147-170). Adding validation improves CLI UX by providing clear error messages for invalid invocations.

Proposed fix
 	describeCmd := &cobra.Command{
 		Use:   "describe [name]",
 		Short: "Retrieves the description of an existing machine",
+		Args:  cobra.MaximumNArgs(1),
 		RunE: func(_ *cobra.Command, args []string) error {
 			return cmd.Run(context.Background(), args)
 		},
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/machine/describe.go` around lines 26 - 32, The describe command lacks
argument validation: add an Args validator on the describeCmd (the cobra.Command
created in cmd/machine/describe.go) to enforce exactly one positional argument
(or adjust to zero/one if intended) so extra arguments are rejected; update the
command declaration near describeCmd and ensure RunE (which calls cmd.Run) only
runs when the Args check passes so GetMachine is not called with unexpected
extra args.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@cmd/machine/describe.go`:
- Around line 26-32: The describe command lacks argument validation: add an Args
validator on the describeCmd (the cobra.Command created in
cmd/machine/describe.go) to enforce exactly one positional argument (or adjust
to zero/one if intended) so extra arguments are rejected; update the command
declaration near describeCmd and ensure RunE (which calls cmd.Run) only runs
when the Args check passes so GetMachine is not called with unexpected extra
args.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 31ceca32-a908-4a0d-915e-ecc6ac3c2e1d

📥 Commits

Reviewing files that changed from the base of the PR and between 844152d and e6fd2be.

📒 Files selected for processing (12)
  • cmd/machine/delete.go
  • cmd/machine/describe.go
  • cmd/machine/list.go
  • cmd/machine/machine.go
  • cmd/machine/ssh.go
  • cmd/machine/start.go
  • cmd/machine/status.go
  • cmd/machine/stop.go
  • pkg/client/client.go
  • pkg/client/clientimplementation/machine_client.go
  • pkg/client/clientimplementation/workspace_client.go
  • pkg/provider/provider.go
✅ Files skipped from review due to trivial changes (3)
  • cmd/machine/start.go
  • cmd/machine/delete.go
  • cmd/machine/stop.go
🚧 Files skipped from review as they are similar to previous changes (7)
  • cmd/machine/ssh.go
  • cmd/machine/status.go
  • cmd/machine/list.go
  • pkg/provider/provider.go
  • pkg/client/client.go
  • pkg/client/clientimplementation/workspace_client.go
  • cmd/machine/machine.go

@dubinsky
Copy link
Author

dubinsky commented Mar 9, 2026

@skevetter I probably shouldn't be able to merge pull requests without approval; you may want to tweak the repository settings a bit ;)

@skevetter
Copy link
Owner

@skevetter I probably shouldn't be able to merge pull requests without approval; you may want to tweak the repository settings a bit ;)

I'm still figuring out the settings. Are you able to merge with bypass with your current permissions?

@dubinsky
Copy link
Author

dubinsky commented Mar 9, 2026

Are you able to merge with bypass with your current permissions?

No. Everything seems to be as it should now. Thanks!

Copy link
Owner

@skevetter skevetter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will review the gcloud provider changes next, merge those changes, and update the provider.

Use: "describe [name]",
Short: "Retrieves the description of an existing machine",
RunE: func(_ *cobra.Command, args []string) error {
return cmd.Run(context.Background(), args)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is inconsistency throughout the commands. Some use context.Background(); others use cobraCmd.Context(). I'll let you decide if you want to update this here; otherwise, I can follow up and update all the commands at once.

Suggested change
return cmd.Run(context.Background(), args)
RunE: func(cobraCmd *cobra.Command, args []string) error {
return cmd.Run(cobraCmd.Context(), args)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I'll leave this one to you: I do not understand the difference sufficiently...

@skevetter skevetter changed the title feat(cli): retrieve virtual machine instance description; feat(cli): retrieve virtual machine instance description Mar 10, 2026
Signed-off-by: Leonid Dubinsky <dub@podval.org>
@dubinsky dubinsky requested a review from skevetter March 10, 2026 03:48
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/client/clientimplementation/machine_client.go`:
- Around line 245-264: The Describe method must short-circuit when there is no
describe command configured: check if len(s.config.Exec.Describe) == 0 at the
start of machineClient.Describe and, if so, return client.DescriptionNotFound
(and nil error) instead of calling s.executor.execute; this avoids treating an
empty command slice as a successful no-op from RunCommand and ensures callers
get DescriptionNotFound for providers that don't support describe.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 638a6887-576e-48a0-b973-9a66976e5a94

📥 Commits

Reviewing files that changed from the base of the PR and between e6fd2be and 85066db.

📒 Files selected for processing (12)
  • cmd/machine/delete.go
  • cmd/machine/describe.go
  • cmd/machine/list.go
  • cmd/machine/machine.go
  • cmd/machine/ssh.go
  • cmd/machine/start.go
  • cmd/machine/status.go
  • cmd/machine/stop.go
  • pkg/client/client.go
  • pkg/client/clientimplementation/machine_client.go
  • pkg/client/clientimplementation/workspace_client.go
  • pkg/provider/provider.go
✅ Files skipped from review due to trivial changes (2)
  • cmd/machine/stop.go
  • cmd/machine/start.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • cmd/machine/delete.go
  • cmd/machine/describe.go
  • pkg/provider/provider.go
  • cmd/machine/machine.go

Comment on lines +245 to +264
func (s *machineClient) Describe(ctx context.Context) (string, error) {
stdout := &bytes.Buffer{}
stderr := &bytes.Buffer{}

err := s.executor.execute(ctx, execConfig{
name: "describe",
command: s.config.Exec.Describe,
stdout: stdout,
stderr: io.MultiWriter(stderr, s.log.Writer(logrus.InfoLevel, true)),
})
if err != nil {
return client.DescriptionNotFound, fmt.Errorf(
"describe: %s%s",
strings.TrimSpace(stdout.String()),
strings.TrimSpace(stderr.String()),
)
}

return strings.TrimSpace(stdout.String()), nil
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Handle providers with no describe command before executing.

execute() eventually reaches RunCommand, which treats an empty command slice as success. Because this method does not guard len(s.config.Exec.Describe) == 0, direct machine-client callers can get "", nil for unsupported providers and the new machine describe flow will look like a successful no-op instead of returning DescriptionNotFound or failing.

Suggested fix
 func (s *machineClient) Describe(ctx context.Context) (string, error) {
+	if len(s.config.Exec.Describe) == 0 {
+		return client.DescriptionNotFound, nil
+	}
+
 	stdout := &bytes.Buffer{}
 	stderr := &bytes.Buffer{}

 	err := s.executor.execute(ctx, execConfig{
 		name:    "describe",
 		command: s.config.Exec.Describe,
 		stdout:  stdout,
 		stderr:  io.MultiWriter(stderr, s.log.Writer(logrus.InfoLevel, true)),
 	})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/client/clientimplementation/machine_client.go` around lines 245 - 264,
The Describe method must short-circuit when there is no describe command
configured: check if len(s.config.Exec.Describe) == 0 at the start of
machineClient.Describe and, if so, return client.DescriptionNotFound (and nil
error) instead of calling s.executor.execute; this avoids treating an empty
command slice as a successful no-op from RunCommand and ensures callers get
DescriptionNotFound for providers that don't support describe.

@dubinsky
Copy link
Author

Will review the gcloud provider changes next, merge those changes, and update the provider.

Thank you!

@skevetter skevetter merged commit 1451fa1 into skevetter:main Mar 10, 2026
41 checks passed
@dubinsky dubinsky deleted the machine-describe branch March 10, 2026 05:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants