Class: Pvectl::Commands::UnlinkDiskVm

Inherits:
Object
  • Object
show all
Defined in:
lib/pvectl/commands/unlink_disk_vm.rb

Overview

Handler for the ‘pvectl unlink disk vm` command.

Removes one or more disks from a VM configuration. By default, the disk entry is converted to ‘unused` (the underlying volume is preserved). With `–force`, the underlying volume is physically deleted.

Examples:

Soft unlink (keeps volume as unused0)

pvectl unlink disk vm 100 scsi1

Unlink multiple disks

pvectl unlink disk vm 100 scsi1,virtio0

Hard delete the underlying volume

pvectl unlink disk vm 100 scsi1 --force --yes

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args, options, global_options) ⇒ UnlinkDiskVm

Returns a new instance of UnlinkDiskVm.

Parameters:

  • args (Array<String>)

    command arguments

  • options (Hash)

    command options

  • global_options (Hash)

    global CLI options



105
106
107
108
109
# File 'lib/pvectl/commands/unlink_disk_vm.rb', line 105

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

Class Method Details

.execute(args, options, global_options) ⇒ Integer

Executes the unlink disk vm command.

Parameters:

  • args (Array<String>)

    command arguments (VMID, DISK_LIST)

  • options (Hash)

    command options

  • global_options (Hash)

    global CLI options

Returns:

  • (Integer)

    exit code



98
99
100
# File 'lib/pvectl/commands/unlink_disk_vm.rb', line 98

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

.register(cli) ⇒ void

This method returns an undefined value.

Registers the unlink command with the CLI.

Parameters:

  • cli (GLI::App)

    the CLI application object



26
27
28
29
30
31
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
# File 'lib/pvectl/commands/unlink_disk_vm.rb', line 26

def self.register(cli)
  cli.desc "Unlink a disk from a resource"
  cli.long_desc <<~HELP
    DESCRIPTION
      Remove one or more disks from a VM configuration.

      By default, the disk entry is moved to `unused[n]` in the VM
      config — the underlying volume is preserved so it can be
      re-attached or inspected later. With --force, the underlying
      volume is physically deleted and cannot be recovered.

      Multiple disks may be removed in a single call by passing a
      comma-separated list (e.g. "scsi1,virtio0").

    EXAMPLES
      Soft unlink (keeps the volume as unused0):
        $ pvectl unlink disk vm 100 scsi1

      Unlink multiple disks at once:
        $ pvectl unlink disk vm 100 scsi1,virtio0

      Permanently delete the underlying volume:
        $ pvectl unlink disk vm 100 scsi1 --force --yes

      Skip confirmation prompt:
        $ pvectl unlink disk vm 100 scsi1 -y

    NOTES
      --force is destructive: the underlying volume is removed and
      cannot be recovered. Without --force, the volume can be
      re-attached later (e.g. via `pvectl set vm`).

      The command operates only on QEMU virtual machines; LXC
      containers are not supported by the Proxmox /unlink endpoint.

    SEE ALSO
      pvectl help describe vm     Show VM configuration including disks
      pvectl help edit volume     Edit volume properties interactively
      pvectl help set vm          Modify VM configuration (re-attach unused)
  HELP
  cli.arg_name "RESOURCE_TYPE ID DISK_LIST"
  cli.command :unlink do |c|
    c.desc "Skip confirmation prompt"
    c.switch [:yes, :y], negatable: false

    c.desc "Physically delete the underlying volume(s)"
    c.switch [:force], negatable: false

    c.action do |global_options, options, args|
      resource_type = args.shift
      scope = args.shift

      exit_code = case [resource_type, scope]
      when %w[disk vm]
        Commands::UnlinkDiskVm.execute(args, options, global_options)
      else
        $stderr.puts "Error: Unknown unlink target: #{resource_type} #{scope}".strip
        $stderr.puts "Valid form: unlink disk vm <id> <disk_list>"
        ExitCodes::USAGE_ERROR
      end

      exit exit_code if exit_code != 0
    end
  end
end

Instance Method Details

#executeInteger

Executes the unlink disk vm command.

Returns:

  • (Integer)

    exit code



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

def execute
  vmid_arg = @args[0]
  disk_list = @args[1]

  return usage_error("VMID required") if vmid_arg.nil? || vmid_arg.to_s.empty?
  return usage_error("Disk list required (e.g., scsi1 or scsi1,virtio0)") if disk_list.nil? || disk_list.to_s.empty?
  return usage_error("Invalid VMID: #{vmid_arg}") unless vmid_arg.to_s.match?(/\A\d+\z/)

  vmid = vmid_arg.to_i
  load_config
  node = resolve_node(vmid)
  return ExitCodes::NOT_FOUND if node.nil?

  return ExitCodes::SUCCESS unless confirm_operation(vmid, disk_list)

  repo = build_repository
  service = Pvectl::Services::UnlinkDisk.new(repository: repo)
  result = service.execute(
    vmid: vmid,
    node: node,
    disk_ids: disk_list,
    force: @options[:force] == true
  )

  output_result(result)
  result.failed? ? ExitCodes::GENERAL_ERROR : ExitCodes::SUCCESS
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