Class: Pvectl::Commands::Get::Command

Inherits:
Object
  • Object
show all
Defined in:
lib/pvectl/commands/get/command.rb,
sig/pvectl/commands/get/command.rbs

Overview

Dispatcher for the pvectl get <resource_type> command.

Routes requests to appropriate resource handlers based on the resource type argument. Supports watch mode for continuous monitoring and node filtering.

Responsibilities:

  • Control flow (watch vs single execution)
  • Handler lookup via ResourceRegistry
  • Error handling for unknown resources and handler exceptions

Delegates to:

  • Services::Get::ResourceService for data fetching and formatting

Examples:

Basic usage

Commands::Get::Command.execute("nodes", nil, options, global_options)

With watch mode

options = { watch: true, :"watch-interval" => 5 }
Commands::Get::Command.execute("vms", nil, options, global_options)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(resource_type, args, options, global_options, registry: ResourceRegistry) ⇒ Command

Creates a new Get command instance.



194
195
196
197
198
199
200
201
# File 'lib/pvectl/commands/get/command.rb', line 194

def initialize(resource_type, args, options, global_options,
               registry: ResourceRegistry)
  @resource_type = resource_type
  @args = normalize_args(args)
  @options = options
  @global_options = global_options
  @registry = registry
end

Instance Attribute Details

#argsArray[String] (readonly)

Returns the value of attribute args.



235
236
237
# File 'lib/pvectl/commands/get/command.rb', line 235

def args
  @args
end

#global_optionsHash[Symbol, untyped] (readonly)

Returns the value of attribute global_options.



235
236
237
# File 'lib/pvectl/commands/get/command.rb', line 235

def global_options
  @global_options
end

#optionsHash[Symbol, untyped] (readonly)

Returns the value of attribute options.



235
236
237
# File 'lib/pvectl/commands/get/command.rb', line 235

def options
  @options
end

#resource_typeString? (readonly)

Returns the value of attribute resource_type.



235
236
237
# File 'lib/pvectl/commands/get/command.rb', line 235

def resource_type
  @resource_type
end

Class Method Details

.execute(resource_type, args, options, global_options) ⇒ Integer

Executes the get command.



183
184
185
# File 'lib/pvectl/commands/get/command.rb', line 183

def self.execute(resource_type, args, options, global_options)
  new(resource_type, args, options, global_options).execute
end

.register(cli) ⇒ void

This method returns an undefined value.

Registers the get command with the CLI.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/pvectl/commands/get/command.rb', line 32

def self.register(cli)
  cli.desc "List resources in cluster"
  cli.long_desc <<~HELP
    List resources across the Proxmox cluster. Supports multiple resource
    types including nodes, VMs, containers, storage, snapshots, backups,
    templates, and tasks.

    Results can be filtered by node (--node), formatted in different output
    modes (-o), and auto-refreshed with watch mode (-w).

    RESOURCE TYPES
      nodes (node)              Cluster nodes
      vms (vm)                  Virtual machines
      containers (ct, cts)      LXC containers
      storage (stor)            Storage pools
      snapshots (snap)          VM/CT snapshots
      backups (backup)          Backup volumes
      templates (template)      VM and container templates
      tasks (task)              Task history
      disks (disk)              Physical disks (block devices)
      volumes (volume, vol)     Virtual disks attached to VMs/containers
      time                      Node time and timezone settings
      node-capabilities (caps)  Supported QEMU CPU models and machine types
      subscription (sub)        Proxmox subscription status per node

    EXAMPLES
      List all VMs in table format:
        $ pvectl get vms

      List containers on a specific node as JSON:
        $ pvectl get containers --node pve1 -o json

      List snapshots for specific VMs:
        $ pvectl get snapshots --vmid 100 --vmid 101

      Watch cluster nodes with 5-second refresh:
        $ pvectl get nodes -w --watch-interval 5

      Filter tasks by type and date:
        $ pvectl get tasks --type vzdump --since 2026-01-01

      Wide output with extra columns:
        $ pvectl get vms -o wide

      Filter VMs by status (shortcut):
        $ pvectl get vms --status running

      Filter VMs by selector (supports status, name, tags, pool):
        $ pvectl get vms -l status=running
        $ pvectl get vms -l status=running,tags=prod
        $ pvectl get vms -l name=~web-*

      List VM volumes:
        $ pvectl get volume vm 100

      List volumes from storage:
        $ pvectl get volume --storage local-lvm

      List volumes with filtering:
        $ pvectl get volume vm 100 -l format=raw

      Show node time and timezone for a single node:
        $ pvectl get time --node pve1

      Show time and timezone for all online nodes:
        $ pvectl get time

      List supported CPU models / machine types for a node:
        $ pvectl get node-capabilities --node pve1
        $ pvectl get caps --node pve1 -o json

      List subscription status across the cluster:
        $ pvectl get subscription

      Show full license key for one node (key is masked by default):
        $ pvectl get subscription --node pve1 -o wide

    NOTES
      Use selectors (-l) to filter VMs/containers by status, name, tags, or
      pool. Multiple selectors use AND logic. The --status flag is a shortcut
      for -l status=VALUE and can be combined with other selectors.

      Task listing defaults to 50 entries; use --limit to change.

      Watch mode clears the screen on each refresh. Press Ctrl+C to stop.

    SEE ALSO
      pvectl help describe    Show detailed info about a single resource
      pvectl help top         Display real-time resource usage metrics
      pvectl help logs        Show logs and task history
  HELP
  cli.command :get do |c|
    c.desc "Filter by node name"
    c.flag [:node], arg_name: "NODE"

    c.desc "Filter by VM/CT ID (repeatable)"
    c.flag [:vmid], arg_name: "VMID", multiple: true

    c.desc "Filter by storage (for backups)"
    c.flag [:storage], arg_name: "STORAGE"

    c.desc "Watch for changes with auto-refresh"
    c.switch [:watch, :w], negatable: false

    c.desc "Watch refresh interval in seconds (default: 2, minimum: 1)"
    c.default_value 2
    c.flag [:"watch-interval"], arg_name: "SECONDS", type: Integer

    c.desc "Maximum number of entries to show (for tasks)"
    c.default_value 50
    c.flag [:limit], type: Integer, arg_name: "N"

    c.desc "Show entries since timestamp (YYYY-MM-DD or epoch, for tasks)"
    c.flag [:since], arg_name: "TIMESTAMP"

    c.desc "Show entries until timestamp (YYYY-MM-DD or epoch, for tasks)"
    c.flag [:until], arg_name: "TIMESTAMP"

    c.desc "Filter by task type (e.g., qmstart, qmstop, vzdump)"
    c.flag [:type], arg_name: "TYPE"

    c.desc "Filter by status (running, stopped for VMs/CTs; running, ok, error for tasks)"
    c.flag [:status], arg_name: "STATUS"

    c.desc "Filter by selector (e.g., status=running,tags=prod)"
    c.flag [:l, :selector], arg_name: "SELECTOR", multiple: true

    c.desc "Search across all cluster nodes (default for tasks)"
    c.switch [:"all-nodes"], negatable: false

    c.action do |global_options, options, args|
      resource_type = args[0]
      resource_args = args[1..] || []
      exit_code = execute(resource_type, resource_args, options, global_options)
      exit exit_code if exit_code != 0
    end
  end
end

Instance Method Details

#build_selector(handler) ⇒ Selectors::Base?

Builds a selector from -l and --status flags for client-side filtering.

For handlers that declare a selector_class (VMs, Containers), --status is translated into a selector condition. For handlers without selector support (e.g., tasks), --status is passed through as status_filter.



324
325
326
327
328
329
330
331
332
333
334
# File 'lib/pvectl/commands/get/command.rb', line 324

def build_selector(handler)
  selector_class = handler.selector_class
  return nil unless selector_class

  selector_strings = Array(options[:selector])
  selector_strings << "status=#{options[:status]}" if options[:status]

  return nil if selector_strings.empty?

  selector_class.parse_all(selector_strings)
end

#build_service(handler) ⇒ Services::Get::ResourceService

Builds the service for the given handler.



340
341
342
343
344
345
346
# File 'lib/pvectl/commands/get/command.rb', line 340

def build_service(handler)
  Services::Get::ResourceService.new(
    handler: handler,
    format: global_options[:output] || "table",
    color_enabled: determine_color_enabled
  )
end

#determine_color_enabledBoolean

Determines if color output should be enabled.



351
352
353
354
355
356
# File 'lib/pvectl/commands/get/command.rb', line 351

def determine_color_enabled
  explicit = global_options[:color]
  return explicit unless explicit.nil?

  $stdout.tty?
end

#executeInteger

Executes the get operation.



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/pvectl/commands/get/command.rb', line 206

def execute
  return missing_resource_type_error if @resource_type.nil?

  handler = @registry.for(@resource_type)
  return unknown_resource_error unless handler

  if @options[:watch]
    run_watch_mode(handler)
  else
    run_once(handler)
  end

  ExitCodes::SUCCESS
rescue Timeout::Error => e
  output_connection_error(e.message)
  ExitCodes::CONNECTION_ERROR
rescue Errno::ECONNREFUSED => e
  output_connection_error(e.message)
  ExitCodes::CONNECTION_ERROR
rescue SocketError => e
  output_connection_error(e.message)
  ExitCodes::CONNECTION_ERROR
rescue ArgumentError => e
  output_usage_error(e.message)
  ExitCodes::USAGE_ERROR
end

#missing_resource_type_errorInteger

Outputs error for missing resource type argument.



252
253
254
255
256
# File 'lib/pvectl/commands/get/command.rb', line 252

def missing_resource_type_error
  $stderr.puts "Error: resource type is required"
  $stderr.puts "Usage: pvectl get RESOURCE_TYPE [NAME] [options]"
  ExitCodes::USAGE_ERROR
end

#normalize_args(args) ⇒ Array<String>

Normalizes args to an array.



241
242
243
244
245
246
247
# File 'lib/pvectl/commands/get/command.rb', line 241

def normalize_args(args)
  case args
  when nil then []
  when Array then args
  else [args.to_s]
  end
end

#output_connection_error(message) ⇒ void

This method returns an undefined value.

Outputs connection error message.



270
271
272
# File 'lib/pvectl/commands/get/command.rb', line 270

def output_connection_error(message)
  $stderr.puts "Error: #{message}"
end

#output_usage_error(message) ⇒ void

This method returns an undefined value.

Outputs usage error message.



278
279
280
# File 'lib/pvectl/commands/get/command.rb', line 278

def output_usage_error(message)
  $stderr.puts "Error: #{message}"
end

#run_once(handler) ⇒ void

This method returns an undefined value.

Executes a single fetch and display operation.



286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
# File 'lib/pvectl/commands/get/command.rb', line 286

def run_once(handler)
  service = build_service(handler)
  selector = build_selector(handler)
  output = service.list(
    node: options[:node],
    name: nil,
    args: args,
    storage: options[:storage],
    vmid: options[:vmid],
    limit: options[:limit],
    since: options[:since],
    until_time: options[:until],
    type_filter: options[:type],
    status_filter: options[:status],
    all_nodes: options[:"all-nodes"] || false,
    selector: selector
  )
  puts output
end

#run_watch_mode(handler) ⇒ void

This method returns an undefined value.

Executes watch mode with continuous refresh.



310
311
312
313
314
# File 'lib/pvectl/commands/get/command.rb', line 310

def run_watch_mode(handler)
  interval = options[:"watch-interval"] || WatchLoop::DEFAULT_INTERVAL
  watch_loop = WatchLoop.new(interval: interval)
  watch_loop.run { run_once(handler) }
end

#unknown_resource_errorInteger

Outputs error for unknown resource type.



261
262
263
264
# File 'lib/pvectl/commands/get/command.rb', line 261

def unknown_resource_error
  $stderr.puts "Unknown resource type: #{@resource_type}"
  ExitCodes::USAGE_ERROR
end