Class: Pvectl::Services::SetVolume

Inherits:
Object
  • Object
show all
Defined in:
lib/pvectl/services/set_volume.rb

Overview

Orchestrates non-interactive volume property updates.

Handles two types of changes:

  1. Size changes — delegates to ResizeVolume service (irreversible)

  2. Config changes (cache, discard, ssd, etc.) — rebuilds volume config string

Examples:

Resize only

service = SetVolume.new(repository: vm_repo, resource_type: :vm)
result = service.execute(id: 100, disk: "scsi0", params: { "size" => "+10G" }, node: "pve1")

Config change

service.execute(id: 100, disk: "scsi0", params: { "cache" => "writeback" }, node: "pve1")

Mixed (size + config)

service.execute(id: 100, disk: "scsi0",
  params: { "size" => "+10G", "cache" => "writeback" }, node: "pve1")

Instance Method Summary collapse

Constructor Details

#initialize(repository:, resource_type:) ⇒ SetVolume

Returns a new instance of SetVolume.

Parameters:



25
26
27
28
# File 'lib/pvectl/services/set_volume.rb', line 25

def initialize(repository:, resource_type:)
  @repository = repository
  @resource_type = resource_type
end

Instance Method Details

#execute(id:, disk:, params:, node:) ⇒ Models::VolumeOperationResult

Executes the volume property update.

Separates size param (delegated to ResizeVolume) from config params (rebuilt into the disk config string). Both can be applied in a single call.

Parameters:

  • id (Integer)

    resource ID (VMID or CTID)

  • disk (String)

    disk name (e.g., “scsi0”, “rootfs”)

  • params (Hash)

    key-value pairs to set

  • node (String)

    node name

Returns:



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
# File 'lib/pvectl/services/set_volume.rb', line 40

def execute(id:, disk:, params:, node:)
  config = @repository.fetch_config(node, id)
  disk_value = config[disk.to_sym]

  unless disk_value
    return build_result(id, disk, node, success: false,
                        error: "Volume '#{disk}' not found in config for resource #{id}")
  end

  # Separate size from config params (dup to avoid mutating caller's hash)
  params = params.dup
  size_param = params.delete("size") || params.delete(:size)
  config_params = params

  # Handle size change (resize)
  if size_param
    parsed_size = ResizeVolume.parse_size(size_param)
    resize_service = ResizeVolume.new(repository: @repository)
    resize_service.preflight(id, disk, parsed_size, node: node)
    resize_service.perform(id, disk, parsed_size.raw, node: node)
  end

  # Handle config changes (cache, discard, ssd, iothread, backup)
  unless config_params.empty?
    new_disk_value = rebuild_disk_config(disk_value, config_params)
    @repository.update(id, node, { disk.to_sym => new_disk_value })
  end

  build_result(id, disk, node, success: true)
rescue ResizeVolume::VolumeNotFoundError, ResizeVolume::SizeTooSmallError, ArgumentError => e
  build_result(id, disk, node, success: false, error: e.message)
rescue StandardError => e
  build_result(id, disk, node, success: false, error: e.message)
end