Class: Pvectl::Services::Sendkey

Inherits:
Object
  • Object
show all
Defined in:
lib/pvectl/services/sendkey.rb,
sig/pvectl/services/sendkey.rbs

Overview

Orchestrates QEMU monitor key-send operations for a single VM.

Resolves the VM (and its node) via the repository, validates that the target VM is running, and forwards the key sequence verbatim to the Proxmox API. The key string is passed through unmodified — interpretation is delegated to QEMU's qcode parser.

Examples:

Sending Ctrl+Alt+Delete to a running VM

service = Sendkey.new(vm_repository: vm_repo)
result = service.execute(vmid: 100, key: "ctrl-alt-delete")
result.successful? #=> true

Instance Method Summary collapse

Constructor Details

#initialize(vm_repository:) ⇒ Sendkey

Creates a new Sendkey service.

Parameters:

  • vm_repository (Repositories::Vm)

    VM repository for lookup and key send

  • vm_repository: (Object)


21
22
23
# File 'lib/pvectl/services/sendkey.rb', line 21

def initialize(vm_repository:)
  @vm_repository = vm_repository
end

Instance Method Details

#execute(vmid:, key:, node: nil) ⇒ Models::VmOperationResult

Sends a QEMU key sequence to a VM.

Looks up the VM (the node kwarg is honored when provided, otherwise the node is taken from the resolved VM). Returns a failed VmOperationResult when the VM cannot be found, is not running, or the underlying API call raises.

Parameters:

  • vmid (Integer, String)

    VM identifier

  • key (String)

    QEMU qcode key sequence (e.g., "ctrl-alt-delete")

  • node (String, nil) (defaults to: nil)

    optional node override

  • vmid: (Integer, String)
  • key: (String)
  • node: (String, nil) (defaults to: nil)

Returns:



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/pvectl/services/sendkey.rb', line 36

def execute(vmid:, key:, node: nil)
  vmid_int = vmid.to_i

  vm = @vm_repository.get(vmid_int)
  return not_found_result(vmid_int) unless vm

  target_node = node || vm.node
  return not_running_result(vm, target_node, key) unless vm.status == "running"

  @vm_repository.sendkey(vmid_int, target_node, key)

  success_result(vm, target_node, key)
rescue StandardError => e
  failure_result(vm, target_node || vm&.node, key, e.message)
end

#failure_result(vm, node, key, message) ⇒ Models::VmOperationResult

Parameters:

  • vm (Models::Vm, nil)
  • node (String, nil)
  • key (String)
  • message (String)

Returns:



97
98
99
100
101
102
103
104
105
# File 'lib/pvectl/services/sendkey.rb', line 97

def failure_result(vm, node, key, message)
  Models::VmOperationResult.new(
    vm: vm,
    operation: :sendkey,
    success: false,
    error: message,
    resource: { vmid: vm&.vmid, node: node, key: key }
  )
end

#not_found_result(vmid) ⇒ Models::VmOperationResult

Parameters:

  • vmid (Integer)

Returns:



56
57
58
59
60
61
62
63
# File 'lib/pvectl/services/sendkey.rb', line 56

def not_found_result(vmid)
  Models::VmOperationResult.new(
    operation: :sendkey,
    success: false,
    error: "VM #{vmid} not found",
    resource: { vmid: vmid }
  )
end

#not_running_result(vm, node, key) ⇒ Models::VmOperationResult

Parameters:

Returns:



69
70
71
72
73
74
75
76
77
# File 'lib/pvectl/services/sendkey.rb', line 69

def not_running_result(vm, node, key)
  Models::VmOperationResult.new(
    vm: vm,
    operation: :sendkey,
    success: false,
    error: "VM #{vm.vmid} is not running (status: #{vm.status})",
    resource: { vmid: vm.vmid, node: node, key: key }
  )
end

#success_result(vm, node, key) ⇒ Models::VmOperationResult

Parameters:

Returns:



83
84
85
86
87
88
89
90
# File 'lib/pvectl/services/sendkey.rb', line 83

def success_result(vm, node, key)
  Models::VmOperationResult.new(
    vm: vm,
    operation: :sendkey,
    success: true,
    resource: { vmid: vm.vmid, node: node, key: key }
  )
end