Class: Pvectl::Commands::EditVolume

Inherits:
Object
  • Object
show all
Extended by:
ClassMethods
Defined in:
lib/pvectl/commands/edit_volume.rb,
sig/pvectl/commands/edit_volume.rbs

Overview

Handler for the pvectl edit volume command.

Does NOT use EditResourceCommand template — has custom flow due to different argument structure (resource_type + id + disk).

Examples:

Edit volume properties

pvectl edit volume vm 100 scsi0

With custom editor

pvectl edit volume vm 100 scsi0 --editor nano

Dry-run mode

pvectl edit volume vm 100 scsi0 --dry-run

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args, options, global_options) ⇒ EditVolume



38
39
40
41
42
# File 'lib/pvectl/commands/edit_volume.rb', line 38

def initialize(args, options, global_options)
  @args = args
  @options = options
  @global_options = global_options
end

Class Method Details

.executeInteger

extend ClassMethods — RBS cannot represent extend, list class methods directly



9
# File 'sig/pvectl/commands/edit_volume.rbs', line 9

def self.execute: (Array[String] args, Hash[Symbol, untyped] options, Hash[Symbol, untyped] global_options) -> Integer

Instance Method Details

#build_editor_sessionEditorSession?

Builds an editor session from the --editor option.



152
153
154
155
156
157
158
159
# File 'lib/pvectl/commands/edit_volume.rb', line 152

def build_editor_session
  editor_cmd = @options[:editor]
  return nil unless editor_cmd

  Pvectl::EditorSession.new(
    editor: ->(path) { system(editor_cmd, path) }
  )
end

#build_repository(connection, resource_type) ⇒ Repositories::Vm, Repositories::Container

Builds repository for resource type.



126
127
128
129
130
131
132
133
134
135
# File 'lib/pvectl/commands/edit_volume.rb', line 126

def build_repository(connection, resource_type)
  case resource_type
  when "vm"
    Pvectl::Repositories::Vm.new(connection)
  when "container", "ct"
    Pvectl::Repositories::Container.new(connection)
  else
    raise ArgumentError, "Unknown resource type: #{resource_type}"
  end
end

#executeInteger

Executes the edit volume command.



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
# File 'lib/pvectl/commands/edit_volume.rb', line 47

def execute
  resource_type = @args[0]
  resource_id = @args[1]
  disk = @args[2]

  return usage_error("Resource type required (vm, container)") unless resource_type
  return usage_error("Resource ID is required") unless resource_id
  return usage_error("Volume name is required (e.g., scsi0, rootfs)") unless disk

  load_config
  connection = Pvectl::Connection.new(@config)

  node = resolve_node(resource_id.to_i, connection, resource_type)
  return ExitCodes::NOT_FOUND unless node

  repo = build_repository(connection, resource_type)
  service = Pvectl::Services::EditVolume.new(
    repository: repo,
    resource_type: resource_type_symbol(resource_type),
    editor_session: build_editor_session,
    options: service_options
  )
  result = service.execute(id: resource_id.to_i, disk: disk, node: node)

  if result.nil?
    $stdout.puts "Edit cancelled, no changes made."
    return ExitCodes::SUCCESS
  end

  if result.successful?
    if @options[:"dry-run"]
      $stdout.puts "(dry-run mode — no changes applied)"
    else
      $stdout.puts "Volume #{disk} on #{resource_type} #{resource_id} updated successfully."
    end
    ExitCodes::SUCCESS
  else
    $stderr.puts "Error: #{result.error}"
    ExitCodes::GENERAL_ERROR
  end
rescue Pvectl::Config::ConfigNotFoundError,
       Pvectl::Config::InvalidConfigError,
       Pvectl::Config::ContextNotFoundError,
       Pvectl::Config::ClusterNotFoundError,
       Pvectl::Config::UserNotFoundError
  raise
rescue StandardError => e
  $stderr.puts "Error: #{e.message}"
  ExitCodes::GENERAL_ERROR
end

#load_configvoid

This method returns an undefined value.

Loads configuration.



173
174
175
176
177
# File 'lib/pvectl/commands/edit_volume.rb', line 173

def load_config
  service = Pvectl::Config::Service.new
  service.load(config: @global_options[:config])
  @config = service.current_config
end

#resolve_node(resource_id, connection, resource_type) ⇒ String?

Resolves node for a resource.



106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/pvectl/commands/edit_volume.rb', line 106

def resolve_node(resource_id, connection, resource_type)
  return @options[:node] if @options[:node]

  resolver = Pvectl::Utils::ResourceResolver.new(connection)
  resolved = resolver.resolve(resource_id)

  unless resolved
    label = resource_type == "vm" ? "VM" : "container"
    $stderr.puts "Error: #{label} #{resource_id} not found"
    return nil
  end

  resolved[:node]
end

#resource_type_symbol(resource_type) ⇒ Symbol

Converts string resource type to symbol.



141
142
143
144
145
146
147
# File 'lib/pvectl/commands/edit_volume.rb', line 141

def resource_type_symbol(resource_type)
  case resource_type
  when "vm" then :vm
  when "container", "ct" then :container
  else :vm
  end
end

#service_optionsHash

Builds service options from command options.



164
165
166
167
168
# File 'lib/pvectl/commands/edit_volume.rb', line 164

def service_options
  opts = {}
  opts[:dry_run] = true if @options[:"dry-run"]
  opts
end

#usage_error(message) ⇒ Integer

Outputs usage error.



183
184
185
186
# File 'lib/pvectl/commands/edit_volume.rb', line 183

def usage_error(message)
  $stderr.puts "Error: #{message}"
  ExitCodes::USAGE_ERROR
end