Class: Pvectl::Services::CreateVm

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

Overview

Orchestrates VM creation operations.

Handles auto-VMID allocation, parameter building (mapping disk/net/cloud-init configs to Proxmox API format), sync/async modes, and optional auto-start.

Examples:

Basic VM creation

service = CreateVm.new(vm_repository: vm_repo, task_repository: task_repo)
result = service.execute(name: "web-server", node: "pve1",
                         cores: 4, memory: 4096,
                         disks: [{ storage: "local-lvm", size: "32G" }])

Async creation with auto-start

service = CreateVm.new(vm_repository: vm_repo, task_repository: task_repo,
                       options: { async: true, start: true })
result = service.execute(vmid: 200, name: "db-server", node: "pve1",
                         cores: 8, memory: 16384)

Constant Summary collapse

DEFAULT_TIMEOUT =
300
START_TIMEOUT =
60

Instance Method Summary collapse

Constructor Details

#initialize(vm_repository:, task_repository:, options: {}) ⇒ CreateVm

Creates a new CreateVm service.



34
35
36
37
38
# File 'lib/pvectl/services/create_vm.rb', line 34

def initialize(vm_repository:, task_repository:, options: {})
  @vm_repository = vm_repository
  @task_repository = task_repository
  @options = options
end

Instance Method Details

#add_disk_params(params, disks) ⇒ void

This method returns an undefined value.

Adds disk parameters mapped to scsi0, scsi1, etc.



138
139
140
141
142
# File 'lib/pvectl/services/create_vm.rb', line 138

def add_disk_params(params, disks)
  disks.each_with_index do |disk, index|
    params[:"scsi#{index}"] = Parsers::DiskConfig.to_proxmox(disk)
  end
end

#add_net_params(params, nets) ⇒ void

This method returns an undefined value.

Adds network parameters mapped to net0, net1, etc.



149
150
151
152
153
# File 'lib/pvectl/services/create_vm.rb', line 149

def add_net_params(params, nets)
  nets.each_with_index do |net, index|
    params[:"net#{index}"] = Parsers::NetConfig.to_proxmox(net)
  end
end

#build_params(name:, cores:, sockets:, cpu_type:, numa:, memory:, balloon:, disks:, scsihw:, cdrom:, nets:, bios:, boot_order:, machine:, efidisk:, cloud_init:, agent:, ostype:, description:, tags:, pool:) ⇒ Hash

Builds Proxmox API parameters from user-friendly options.

Maps disk configs through Parsers::DiskConfig.to_proxmox and network configs through Parsers::NetConfig.to_proxmox.



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/pvectl/services/create_vm.rb', line 105

def build_params(name:, cores:, sockets:, cpu_type:, numa:, memory:,
                 balloon:, disks:, scsihw:, cdrom:, nets:, bios:,
                 boot_order:, machine:, efidisk:, cloud_init:, agent:,
                 ostype:, description:, tags:, pool:)
  params = { name: name }
  params[:cores] = cores if cores
  params[:sockets] = sockets if sockets
  params[:cpu] = cpu_type if cpu_type
  params[:numa] = numa ? 1 : 0 unless numa.nil?
  params[:memory] = memory if memory
  params[:balloon] = balloon if balloon
  add_disk_params(params, disks) if disks
  params[:scsihw] = scsihw if scsihw
  params[:cdrom] = cdrom if cdrom
  add_net_params(params, nets) if nets
  params[:bios] = bios if bios
  params[:boot] = "order=#{boot_order}" if boot_order
  params[:machine] = machine if machine
  params[:efidisk0] = efidisk if efidisk
  params.merge!(cloud_init) if cloud_init
  params[:agent] = agent ? "1" : "0" unless agent.nil?
  params[:ostype] = ostype if ostype
  params[:description] = description if description
  params[:tags] = tags if tags
  params[:pool] = pool if pool
  params
end

#build_result(resource_info, **attrs) ⇒ Models::VmOperationResult

Builds a VmOperationResult with the :create operation.

Creates a minimal Vm model for presenter compatibility.



179
180
181
182
183
184
185
186
187
188
# File 'lib/pvectl/services/create_vm.rb', line 179

def build_result(resource_info, **attrs)
  vm = Models::Vm.new(
    vmid: resource_info[:vmid],
    name: resource_info[:name],
    node: resource_info[:node]
  )
  Models::VmOperationResult.new(
    operation: :create, vm: vm, resource: resource_info, **attrs
  )
end

#execute(vmid: nil, name:, node:, cores: nil, sockets: nil, cpu_type: nil, numa: nil, memory: nil, balloon: nil, disks: nil, scsihw: nil, cdrom: nil, nets: nil, bios: nil, boot_order: nil, machine: nil, efidisk: nil, cloud_init: nil, agent: nil, ostype: nil, description: nil, tags: nil, pool: nil) ⇒ Models::VmOperationResult

Executes VM creation operation.



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

def execute(vmid: nil, name:, node:, cores: nil, sockets: nil, cpu_type: nil,
            numa: nil, memory: nil, balloon: nil, disks: nil, scsihw: nil,
            cdrom: nil, nets: nil, bios: nil, boot_order: nil, machine: nil,
            efidisk: nil, cloud_init: nil, agent: nil, ostype: nil,
            description: nil, tags: nil, pool: nil)
  vmid ||= @vm_repository.next_available_vmid

  params = build_params(
    name: name, cores: cores, sockets: sockets, cpu_type: cpu_type,
    numa: numa, memory: memory, balloon: balloon, disks: disks,
    scsihw: scsihw, cdrom: cdrom, nets: nets, bios: bios,
    boot_order: boot_order, machine: machine, efidisk: efidisk,
    cloud_init: cloud_init, agent: agent, ostype: ostype,
    description: description, tags: tags, pool: pool
  )

  upid = @vm_repository.create(node, vmid, params)
  resource_info = { vmid: vmid, name: name, node: node }

  if @options[:async]
    build_result(resource_info, task_upid: upid, success: :pending)
  else
    task = @task_repository.wait(upid, timeout: timeout)
    start_vm(vmid, node) if task.successful? && @options[:start]
    build_result(resource_info, task: task, success: task.successful?)
  end
rescue StandardError => e
  build_result({ vmid: vmid, name: name, node: node },
               success: false, error: e.message)
end

#start_vm(vmid, node) ⇒ void

This method returns an undefined value.

Starts a VM after successful creation.



160
161
162
163
# File 'lib/pvectl/services/create_vm.rb', line 160

def start_vm(vmid, node)
  upid = @vm_repository.start(vmid, node)
  @task_repository.wait(upid, timeout: START_TIMEOUT)
end

#timeoutInteger

Returns configured timeout.



168
169
170
# File 'lib/pvectl/services/create_vm.rb', line 168

def timeout
  @options[:timeout] || DEFAULT_TIMEOUT
end