kitchen-proxmox 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8b86aaf1627109dc3fc11a425f023a03da6601eb6ef5c19e7d426654f40a1363
4
- data.tar.gz: 71a7a993ce7729691b6887f84df0854023b32953b843fd7b0c1f29a3d07c253f
3
+ metadata.gz: 9431e030d0300d57c9fac8a20047375865cedf9f4a48b34b3039370f2d62a98a
4
+ data.tar.gz: 62e91255a7b9b2586eeef54bcd76bb7110b782ae8c948853ef0691a13e11df5e
5
5
  SHA512:
6
- metadata.gz: 5c7640ad5482862220e38d3fb3ff3cdc3d6943b4656e5bdbb9c49169f5887c82c23044abcc6361e870625fda7fa944d7f81944e70d10255b095e230fbdd777b6
7
- data.tar.gz: 9f919e44967c325720f05724b97318884719fd21b46717838d38199beebbb062c1a829c1a635092461d56fe9258c2f917e2ed97a5f18cf4af44d38b19b03c858
6
+ metadata.gz: e974ac8b7626ed1232e608073c259f5bb90c65aa47bdaf9327195a255dfbcbb7eb969a6cd88c5781c929835daa84f52a63e83aa6e291199de3d32889c244300b
7
+ data.tar.gz: 4b36857b3cfb877ff3bcf292049389cbe26cd43ab2393fb235d3236e8ad5d50ba74ed1ae55076961f97294f2df14e9a8d98d683a50afe4f37af5253ca3066f63
@@ -5,6 +5,7 @@ require 'json'
5
5
  require 'uri'
6
6
  require 'openssl'
7
7
  require 'kitchen'
8
+ require_relative 'errors'
8
9
 
9
10
  module Kitchen
10
11
  module Driver
@@ -145,7 +146,7 @@ module Kitchen
145
146
  end
146
147
 
147
148
  def handle_response(response)
148
- raise "Proxmox API error #{response.code}: #{response.body}" unless response.is_a?(Net::HTTPSuccess)
149
+ raise ProxmoxErrors::ApiError.new(response.code, response.body) unless response.is_a?(Net::HTTPSuccess)
149
150
 
150
151
  JSON.parse(response.body)['data']
151
152
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitchen
4
+ module Driver
5
+ module ProxmoxErrors
6
+ # Structured error raised by ApiClient on non-2xx responses.
7
+ class ApiError < ::StandardError
8
+ attr_reader :status_code, :response_body
9
+
10
+ def initialize(status_code, response_body)
11
+ @status_code = status_code.to_i
12
+ @response_body = response_body
13
+ super("Proxmox API error #{status_code}: #{response_body}")
14
+ end
15
+
16
+ # Returns true when the error indicates a VMID is already in use.
17
+ def vmid_conflict?
18
+ return false unless status_code == 400 || status_code == 500
19
+
20
+ response_body.match?(/already exists/i) ||
21
+ response_body.match?(/unable to create VM \d+/i)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'kitchen'
4
4
  require_relative 'proxmox_version'
5
+ require_relative 'proxmox/errors'
5
6
  require_relative 'proxmox/api_client'
6
7
 
7
8
  module Kitchen
@@ -16,6 +17,8 @@ module Kitchen
16
17
 
17
18
  plugin_version Kitchen::Driver::PROXMOX_VERSION
18
19
 
20
+ ApiError = Kitchen::Driver::ProxmoxErrors::ApiError
21
+
19
22
  required_config :proxmox_url
20
23
  required_config :proxmox_token_id
21
24
  required_config :proxmox_token_secret
@@ -32,6 +35,7 @@ module Kitchen
32
35
  default_config :clone_timeout, 300
33
36
  default_config :start_timeout, 300
34
37
  default_config :ip_wait_timeout, 120
38
+ default_config :clone_retries, 5
35
39
 
36
40
  def create(state)
37
41
  return if state[:vm_id]
@@ -65,19 +69,43 @@ module Kitchen
65
69
  def clone_and_start(state)
66
70
  info("Creating Proxmox VM from template #{config[:template_id]}...")
67
71
 
68
- vm_id = allocate_vm_id
69
- vm_name = generate_vm_name(instance.name)
72
+ vm_id, vm_name = allocate_and_clone
73
+ state[:vm_id] = vm_id
74
+ state[:vm_name] = vm_name
70
75
 
71
- clone_template(vm_id, vm_name)
72
76
  configure_hardware(vm_id)
73
77
  start_and_wait_for_ip(state, vm_id)
74
78
 
75
- state[:vm_id] = vm_id
76
- state[:vm_name] = vm_name
77
-
78
79
  info("Proxmox VM #{vm_name} (#{vm_id}) created.")
79
80
  end
80
81
 
82
+ def allocate_and_clone
83
+ retries = config[:clone_retries]
84
+ last_error = nil
85
+
86
+ retries.times do |attempt|
87
+ vm_id = allocate_vm_id
88
+ vm_name = generate_vm_name(instance.name)
89
+
90
+ begin
91
+ clone_template(vm_id, vm_name)
92
+ return [vm_id, vm_name]
93
+ rescue ApiError => e
94
+ raise unless e.vmid_conflict?
95
+
96
+ last_error = e
97
+ warn("VMID #{vm_id} conflict (attempt #{attempt + 1}/#{retries}), retrying...")
98
+ sleep backoff_delay(attempt)
99
+ end
100
+ end
101
+
102
+ raise last_error
103
+ end
104
+
105
+ def backoff_delay(attempt)
106
+ (0.5 * (2**attempt)) + rand(0.0..1.0)
107
+ end
108
+
81
109
  def allocate_vm_id
82
110
  Integer(api_client.next_vm_id)
83
111
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kitchen-proxmox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Nixon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-04-30 00:00:00.000000000 Z
11
+ date: 2026-05-03 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A Test Kitchen driver for Proxmox VE. Manages VM lifecycle (create, destroy)
14
14
  via the Proxmox REST API. Supports cloning from templates.
@@ -22,6 +22,7 @@ files:
22
22
  - README.md
23
23
  - lib/kitchen/driver/proxmox.rb
24
24
  - lib/kitchen/driver/proxmox/api_client.rb
25
+ - lib/kitchen/driver/proxmox/errors.rb
25
26
  - lib/kitchen/driver/proxmox_version.rb
26
27
  homepage: https://github.com/trickyearlobe-chef/kitchen-proxmox
27
28
  licenses: