Class: Pvectl::Services::EditVolume

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

Overview

Orchestrates the interactive volume property editing flow.

Fetches the disk config string from VM/CT config, parses it into editable YAML (key-value pairs), opens editor, and applies changes. Size changes delegate to ResizeVolume; config changes rebuild the disk config string.

Examples:

Basic usage

service = EditVolume.new(repository: vm_repo, resource_type: :vm)
result = service.execute(id: 100, disk: "scsi0", node: "pve1")

Dry run with injected editor session

service = EditVolume.new(repository: vm_repo, resource_type: :vm,
                         editor_session: session, options: { dry_run: true })
result = service.execute(id: 100, disk: "scsi0", node: "pve1")

Instance Method Summary collapse

Constructor Details

#initialize(repository:, resource_type:, editor_session: nil, options: {}) ⇒ EditVolume

Returns a new instance of EditVolume.

Parameters:

  • repository (Repositories::Vm, Repositories::Container)

    resource repository

  • resource_type (Symbol)

    :vm or :container

  • editor_session (EditorSession, nil) (defaults to: nil)

    optional injected editor session

  • options (Hash) (defaults to: {})

    options (dry_run)



26
27
28
29
30
31
# File 'lib/pvectl/services/edit_volume.rb', line 26

def initialize(repository:, resource_type:, editor_session: nil, options: {})
  @repository = repository
  @resource_type = resource_type
  @editor_session = editor_session
  @options = options
end

Instance Method Details

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

Executes the interactive volume edit flow.

Parameters:

  • id (Integer)

    resource ID (VMID or CTID)

  • disk (String)

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

  • node (String)

    node name

Returns:



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

def execute(id:, disk:, 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

  editable = parse_disk_config(disk_value)
  yaml_content = build_yaml_content(editable, disk, id, node)

  session = @editor_session || EditorSession.new
  edited = session.edit(yaml_content)

  return nil unless edited

  edited_config = parse_edited_yaml(edited)
  changes = compute_diff(editable, edited_config)

  return nil if no_changes?(changes)

  if @options[:dry_run]
    return build_result(id, disk, node, success: true,
                        resource: { diff: changes })
  end

  apply_changes(id, disk, node, disk_value, changes)
  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