fog-proxmox 0.16.2 → 1.1.0
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 +4 -4
- data/CHANGELOG.md +34 -0
- data/README.md +4 -4
- data/lib/fog/proxmox/compute/models/multipart_body.rb +91 -0
- data/lib/fog/proxmox/compute/models/multipart_iso_upload.rb +64 -0
- data/lib/fog/proxmox/compute/models/rng.rb +35 -0
- data/lib/fog/proxmox/compute/models/server_config.rb +14 -1
- data/lib/fog/proxmox/compute/models/storage.rb +6 -0
- data/lib/fog/proxmox/compute.rb +1 -0
- data/lib/fog/proxmox/core.rb +3 -2
- data/lib/fog/proxmox/helpers/agent_helper.rb +50 -0
- data/lib/fog/proxmox/helpers/hotplug_helper.rb +41 -0
- data/lib/fog/proxmox/helpers/rng_helper.rb +61 -0
- data/lib/fog/proxmox/storage/models/iso_upload.rb +34 -0
- data/lib/fog/proxmox/storage/requests/upload_iso.rb +46 -0
- data/lib/fog/proxmox/storage.rb +61 -3
- data/lib/fog/proxmox/version.rb +1 -1
- data/spec/fog/proxmox/compute/models/multipart_body_spec.rb +46 -0
- data/spec/fog/proxmox/storage/real_upload_iso_spec.rb +162 -0
- data/spec/fog/proxmox/storage/storage_upload_iso_spec.rb +129 -0
- data/spec/helpers/agent_helper_spec.rb +66 -0
- data/spec/helpers/hotplug_helper_spec.rb +67 -0
- data/spec/helpers/rng_helper_spec.rb +108 -0
- data/spec/proxmox_vcr.rb +2 -2
- metadata +15 -15
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d571150b56652b8f22fc3172ac26caf7918bdc167c5202b9f0809f138693da0f
|
|
4
|
+
data.tar.gz: f26c7b0f98d625306b573bdc2c848974438b03260ac7814b796d055e9967c88a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: df89614d08202bce01cc9f9be6d0fe3bd03a763672016ef363a0666a70e08625c6babed6d5969344496334d1aa5f59ef9584bf4e10b1b8f1b39a60d648d8b3b0
|
|
7
|
+
data.tar.gz: 4fea613dea946a99e5376f6b691eaf6112c1f21d8116497a44e0cc67aba0ddb081a766941b9a1fb8922e40160e451791984a2c06176670fce9f979556fc730bd
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.1.0](https://github.com/fog/fog-proxmox/compare/v1.0.0...v1.1.0) (2026-10-21)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* Add hotplug support ([#158](https://github.com/fog/fog-proxmox/issues/158)) ([0745f60](https://github.com/fog/fog-proxmox/commit/0745f6013003af9d0b1ec7304749a5c52038fa62))
|
|
9
|
+
* Add VirtIO RNG device support ([#160](https://github.com/fog/fog-proxmox/issues/160)) ([a31b9d3](https://github.com/fog/fog-proxmox/commit/a31b9d39927d82b2db9da6c1889b9fd556905b5c))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
* ISO upload task polling ([3dc3c31](https://github.com/fog/fog-proxmox/commit/3dc3c31fe8cd72fc719954917dad39afa6b08ebd))
|
|
15
|
+
|
|
16
|
+
## [1.0.0](https://github.com/fog/fog-proxmox/compare/v0.16.2...v1.0.0) (2026-09-14)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### ⚠ BREAKING CHANGES
|
|
20
|
+
|
|
21
|
+
* Add support for ISO uploads via Proxmox API ([#148](https://github.com/fog/fog-proxmox/issues/148))
|
|
22
|
+
|
|
23
|
+
### Features
|
|
24
|
+
|
|
25
|
+
* Add support for ISO uploads via Proxmox API ([#148](https://github.com/fog/fog-proxmox/issues/148)) ([396d08c](https://github.com/fog/fog-proxmox/commit/396d08c573feceda8443072d2c76cffd3c2a4918))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Bug Fixes
|
|
29
|
+
|
|
30
|
+
* RuboCop extra spacing offenses ([#149](https://github.com/fog/fog-proxmox/issues/149)) ([9a303bc](https://github.com/fog/fog-proxmox/commit/9a303bc03a3d5049ded43d3ad1fa6ea79febd43e))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
### Miscellaneous Chores
|
|
34
|
+
|
|
35
|
+
* allow major releases before 1.0 ([#156](https://github.com/fog/fog-proxmox/issues/156)) ([0752d55](https://github.com/fog/fog-proxmox/commit/0752d55fcfa0628c452c3bc7d7a137e341c8da4a))
|
|
36
|
+
|
|
3
37
|
## [0.16.2](https://github.com/fog/fog-proxmox/compare/v0.16.1...v0.16.2) (2026-08-12)
|
|
4
38
|
|
|
5
39
|
|
data/README.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
# Fog::Proxmox
|
|
4
4
|
|
|
5
|
-
](https://github.com/fog/fog-proxmox/actions/workflows/ci.yml)
|
|
6
6
|
[](https://codeclimate.com/github/fog/fog-proxmox/maintainability)
|
|
7
7
|
[](https://codeclimate.com/github/fog/fog-proxmox/test_coverage)
|
|
8
8
|
[](https://badge.fury.io/rb/fog-proxmox)
|
|
9
9
|
|
|
10
|
-
This is a [FOG](
|
|
10
|
+
This is a [FOG](https://fog.github.io/) (>= 2.1) module gem to support [Proxmox VE](https://www.proxmox.com/en/proxmox-ve)
|
|
11
11
|
|
|
12
|
-
It is intended to satisfy this [feature](https://github.com/fog/fog/issues/3644), but Proxmox provider only, and above all this [Foreman](
|
|
12
|
+
It is intended to satisfy this [feature](https://github.com/fog/fog/issues/3644), but Proxmox provider only, and above all this [Foreman](https://www.theforeman.org) [feature](https://projects.theforeman.org/issues/2186).
|
|
13
13
|
|
|
14
14
|
It is inspired by the great [fog-openstack](https://github.com/fog/fog-openstack) module.
|
|
15
15
|
|
|
@@ -102,7 +102,7 @@ bundle exec rake --tasks
|
|
|
102
102
|
## Contributing
|
|
103
103
|
|
|
104
104
|
You can reach the [contributors](.github/CONTRIBUTORS.md).
|
|
105
|
-
Bug reports and pull requests are welcome on GitHub at [Fog-Proxmox](https://github.com/fog/fog-proxmox/issues). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](
|
|
105
|
+
Bug reports and pull requests are welcome on GitHub at [Fog-Proxmox](https://github.com/fog/fog-proxmox/issues). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](https://www.contributor-covenant.org) code of conduct.
|
|
106
106
|
|
|
107
107
|
Please read [how to contribute](.github/CONTRIBUTING.md).
|
|
108
108
|
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file is part of Fog::Proxmox.
|
|
4
|
+
|
|
5
|
+
# Fog::Proxmox is free software: you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
# (at your option) any later version.
|
|
9
|
+
|
|
10
|
+
# Fog::Proxmox is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
# GNU General Public License for more details.
|
|
14
|
+
|
|
15
|
+
# You should have received a copy of the GNU General Public License
|
|
16
|
+
# along with Fog::Proxmox. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
module Fog
|
|
19
|
+
module Proxmox
|
|
20
|
+
# An IO-like multipart body that streams a file between a prefix and suffix.
|
|
21
|
+
class MultipartBody
|
|
22
|
+
attr_reader :size
|
|
23
|
+
|
|
24
|
+
def initialize(prefix, file, suffix)
|
|
25
|
+
@prefix = prefix
|
|
26
|
+
@file = file
|
|
27
|
+
@suffix = suffix
|
|
28
|
+
@size = prefix.bytesize + file_size + suffix.bytesize
|
|
29
|
+
rewind
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def read(length = nil, outbuf = nil)
|
|
33
|
+
length = @size - @position if length.nil?
|
|
34
|
+
raise ArgumentError, 'negative length' if length.negative?
|
|
35
|
+
|
|
36
|
+
result = ::String.new(encoding: Encoding::BINARY)
|
|
37
|
+
read_into(result, length)
|
|
38
|
+
result = nil if result.empty? && length.positive? && @part > 2
|
|
39
|
+
|
|
40
|
+
return result unless outbuf
|
|
41
|
+
|
|
42
|
+
outbuf.replace(result || '')
|
|
43
|
+
result && outbuf
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def rewind
|
|
47
|
+
@file.rewind
|
|
48
|
+
@part = 0
|
|
49
|
+
@offset = 0
|
|
50
|
+
@position = 0
|
|
51
|
+
0
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def binmode
|
|
55
|
+
@file.binmode if @file.respond_to?(:binmode)
|
|
56
|
+
self
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
def file_size
|
|
62
|
+
return @file.size if @file.respond_to?(:size)
|
|
63
|
+
return @file.stat.size if @file.respond_to?(:stat)
|
|
64
|
+
|
|
65
|
+
raise ArgumentError, 'Upload file size cannot be determined'
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def read_into(result, length)
|
|
69
|
+
while result.bytesize < length && @part <= 2
|
|
70
|
+
remaining = length - result.bytesize
|
|
71
|
+
chunk = @part == 1 ? @file.read(remaining) : read_string_part(remaining)
|
|
72
|
+
|
|
73
|
+
if chunk.nil? || chunk.empty?
|
|
74
|
+
@part += 1
|
|
75
|
+
@offset = 0
|
|
76
|
+
else
|
|
77
|
+
result << chunk
|
|
78
|
+
@position += chunk.bytesize
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def read_string_part(length)
|
|
84
|
+
string = @part.zero? ? @prefix : @suffix
|
|
85
|
+
chunk = string.byteslice(@offset, length)
|
|
86
|
+
@offset += chunk.bytesize if chunk
|
|
87
|
+
chunk
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file is part of Fog::Proxmox.
|
|
4
|
+
|
|
5
|
+
# Fog::Proxmox is free software: you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
# (at your option) any later version.
|
|
9
|
+
|
|
10
|
+
# Fog::Proxmox is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
# GNU General Public License for more details.
|
|
14
|
+
|
|
15
|
+
# You should have received a copy of the GNU General Public License
|
|
16
|
+
# along with Fog::Proxmox. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
require 'securerandom'
|
|
19
|
+
require 'excon'
|
|
20
|
+
require 'fog/proxmox/compute/models/multipart_body'
|
|
21
|
+
|
|
22
|
+
module Fog
|
|
23
|
+
module Proxmox
|
|
24
|
+
# Prepares a streamed multipart ISO upload and its content type.
|
|
25
|
+
class MultipartIsoUpload
|
|
26
|
+
attr_reader :body, :content_type
|
|
27
|
+
|
|
28
|
+
def initialize(body_params)
|
|
29
|
+
filename = body_params.fetch(:filename)
|
|
30
|
+
raise ArgumentError, "Invalid ISO filename: #{filename}" unless filename.match?(/\A[a-zA-Z0-9][a-zA-Z0-9._-]*\.iso\z/i)
|
|
31
|
+
|
|
32
|
+
file = body_params.fetch(:file)
|
|
33
|
+
|
|
34
|
+
boundary = '-' * 30 + SecureRandom.hex(15)
|
|
35
|
+
prefix = build_multipart_content(boundary, 'content', 'iso')
|
|
36
|
+
prefix << build_multipart_header(boundary, 'filename', filename: filename)
|
|
37
|
+
@body = MultipartBody.new(prefix, file, build_multipart_closing(boundary))
|
|
38
|
+
|
|
39
|
+
@content_type = "multipart/form-data; boundary=#{boundary}"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def build_multipart_header(boundary, name, filename: nil)
|
|
45
|
+
newline = Excon::CR_NL
|
|
46
|
+
header = ::String.new(encoding: Encoding::BINARY)
|
|
47
|
+
header << "--#{boundary}#{newline}"
|
|
48
|
+
header << %(Content-Disposition: form-data; name="#{name}")
|
|
49
|
+
header << %(; filename="#{filename}") if filename
|
|
50
|
+
header << newline
|
|
51
|
+
header << "Content-Type: application/octet-stream#{newline}" if filename
|
|
52
|
+
header << newline
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def build_multipart_content(boundary, name, value)
|
|
56
|
+
build_multipart_header(boundary, name) << value << Excon::CR_NL
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def build_multipart_closing(boundary)
|
|
60
|
+
"#{Excon::CR_NL}--#{boundary}--#{Excon::CR_NL}".b
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file is part of Fog::Proxmox.
|
|
4
|
+
|
|
5
|
+
# Fog::Proxmox is free software: you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
# (at your option) any later version.
|
|
9
|
+
|
|
10
|
+
# Fog::Proxmox is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
# GNU General Public License for more details.
|
|
14
|
+
|
|
15
|
+
# You should have received a copy of the GNU General Public License
|
|
16
|
+
# along with Fog::Proxmox. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
require 'fog/proxmox/helpers/rng_helper'
|
|
19
|
+
|
|
20
|
+
module Fog
|
|
21
|
+
module Proxmox
|
|
22
|
+
class Compute
|
|
23
|
+
# VirtIO RNG device; period is in milliseconds and max_bytes is in bytes.
|
|
24
|
+
class Rng < Fog::Model
|
|
25
|
+
attribute :max_bytes
|
|
26
|
+
attribute :period
|
|
27
|
+
attribute :source
|
|
28
|
+
|
|
29
|
+
def flatten
|
|
30
|
+
Fog::Proxmox::RngHelper.flatten(attributes)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -21,6 +21,7 @@ require 'fog/proxmox/attributes'
|
|
|
21
21
|
require 'fog/proxmox/helpers/nic_helper'
|
|
22
22
|
require 'fog/proxmox/helpers/controller_helper'
|
|
23
23
|
require 'fog/proxmox/helpers/efidisk_helper'
|
|
24
|
+
require 'fog/proxmox/helpers/rng_helper'
|
|
24
25
|
|
|
25
26
|
module Fog
|
|
26
27
|
module Proxmox
|
|
@@ -41,6 +42,7 @@ module Fog
|
|
|
41
42
|
attribute :onboot
|
|
42
43
|
attribute :boot
|
|
43
44
|
attribute :agent
|
|
45
|
+
attribute :hotplug
|
|
44
46
|
attribute :scsihw
|
|
45
47
|
attribute :sockets
|
|
46
48
|
attribute :memory
|
|
@@ -80,6 +82,7 @@ module Fog
|
|
|
80
82
|
attribute :searchdomain
|
|
81
83
|
attribute :nameserver
|
|
82
84
|
attribute :efidisk
|
|
85
|
+
attribute :rng
|
|
83
86
|
|
|
84
87
|
def initialize(new_attributes = {})
|
|
85
88
|
prepare_service_value(new_attributes)
|
|
@@ -88,6 +91,7 @@ module Fog
|
|
|
88
91
|
initialize_interfaces(new_attributes)
|
|
89
92
|
initialize_disks(new_attributes)
|
|
90
93
|
initialize_efidisk(new_attributes)
|
|
94
|
+
initialize_rng(new_attributes)
|
|
91
95
|
super(new_attributes)
|
|
92
96
|
end
|
|
93
97
|
|
|
@@ -103,9 +107,10 @@ module Fog
|
|
|
103
107
|
end
|
|
104
108
|
|
|
105
109
|
def flatten
|
|
106
|
-
flat_hash = attributes.reject { |attribute| %i[node_id type vmid disks interfaces].include? attribute }
|
|
110
|
+
flat_hash = attributes.reject { |attribute| %i[node_id type vmid disks interfaces rng].include? attribute }
|
|
107
111
|
flat_hash.merge(interfaces_flatten)
|
|
108
112
|
flat_hash.merge(disks_flatten)
|
|
113
|
+
flat_hash.merge!(rng.flatten) unless rng.nil?
|
|
109
114
|
flat_hash
|
|
110
115
|
end
|
|
111
116
|
|
|
@@ -166,6 +171,14 @@ module Fog
|
|
|
166
171
|
efidisk_hash = Fog::Proxmox::EfidiskHelper.extract(efidisk)
|
|
167
172
|
attributes[:efidisk] = Fog::Proxmox::Compute::Efidisk.new(efidisk_hash)
|
|
168
173
|
end
|
|
174
|
+
|
|
175
|
+
def initialize_rng(new_attributes)
|
|
176
|
+
rng = new_attributes[:rng0] || new_attributes['rng0']
|
|
177
|
+
return if rng.nil?
|
|
178
|
+
|
|
179
|
+
rng_hash = Fog::Proxmox::RngHelper.extract(rng)
|
|
180
|
+
attributes[:rng] = Fog::Proxmox::Compute::Rng.new(rng_hash)
|
|
181
|
+
end
|
|
169
182
|
end
|
|
170
183
|
end
|
|
171
184
|
end
|
|
@@ -26,6 +26,8 @@
|
|
|
26
26
|
|
|
27
27
|
# frozen_string_literal: true
|
|
28
28
|
|
|
29
|
+
require 'fog/proxmox/storage/models/iso_upload'
|
|
30
|
+
|
|
29
31
|
module Fog
|
|
30
32
|
module Proxmox
|
|
31
33
|
class Compute
|
|
@@ -53,6 +55,10 @@ module Fog
|
|
|
53
55
|
super(new_attributes)
|
|
54
56
|
end
|
|
55
57
|
|
|
58
|
+
def upload_iso(path)
|
|
59
|
+
Fog::Proxmox::Storage::IsoUpload.new(service: service, node_id: node_id, storage_id: identity, path: path).upload
|
|
60
|
+
end
|
|
61
|
+
|
|
56
62
|
private
|
|
57
63
|
|
|
58
64
|
def initialize_volumes
|
data/lib/fog/proxmox/compute.rb
CHANGED
data/lib/fog/proxmox/core.rb
CHANGED
|
@@ -93,8 +93,8 @@ module Fog
|
|
|
93
93
|
begin
|
|
94
94
|
authenticate! if expired?
|
|
95
95
|
request_options = params.merge(path: "#{@path}/#{params[:path]}",
|
|
96
|
-
headers:
|
|
97
|
-
params[:method],
|
|
96
|
+
headers: (params[:headers] || {}).merge(
|
|
97
|
+
@auth_token.headers(params[:method], {}, {})
|
|
98
98
|
))
|
|
99
99
|
response = @connection.request(request_options)
|
|
100
100
|
rescue Excon::Errors::Unauthorized => e
|
|
@@ -102,6 +102,7 @@ module Fog
|
|
|
102
102
|
if !%w[Bad username or password, invalid token
|
|
103
103
|
value!].include?(e.response.body) && @proxmox_can_reauthenticate && !retried
|
|
104
104
|
authenticate!
|
|
105
|
+
params[:body].rewind if params[:body].respond_to?(:rewind)
|
|
105
106
|
retried = true
|
|
106
107
|
retry
|
|
107
108
|
# bad credentials or token renewal not possible
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file is part of Fog::Proxmox.
|
|
4
|
+
|
|
5
|
+
# Fog::Proxmox is free software: you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
# (at your option) any later version.
|
|
9
|
+
|
|
10
|
+
# Fog::Proxmox is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
# GNU General Public License for more details.
|
|
14
|
+
|
|
15
|
+
# You should have received a copy of the GNU General Public License
|
|
16
|
+
# along with Fog::Proxmox. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
module Fog
|
|
19
|
+
module Proxmox
|
|
20
|
+
# Convert guest agent settings to and from Proxmox configuration strings.
|
|
21
|
+
module AgentHelper
|
|
22
|
+
DEFAULTS = {
|
|
23
|
+
'enabled' => '0',
|
|
24
|
+
'freeze-fs-on-backup' => '1',
|
|
25
|
+
'fstrim_cloned_disks' => '0',
|
|
26
|
+
'type' => 'virtio'
|
|
27
|
+
}.freeze
|
|
28
|
+
|
|
29
|
+
def self.extract(agent)
|
|
30
|
+
settings = DEFAULTS.dup
|
|
31
|
+
agent.to_s.split(',').each do |option|
|
|
32
|
+
key, value = option.split('=', 2)
|
|
33
|
+
if value.nil?
|
|
34
|
+
settings['enabled'] = key
|
|
35
|
+
else
|
|
36
|
+
settings[key] = value
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
settings['freeze-fs-on-backup'] = settings.fetch('freeze-fs', settings['freeze-fs-on-backup'])
|
|
41
|
+
settings
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def self.flatten(settings)
|
|
45
|
+
"enabled=#{settings['enabled']},freeze-fs-on-backup=#{settings['freeze-fs-on-backup']}," \
|
|
46
|
+
"fstrim_cloned_disks=#{settings['fstrim_cloned_disks']},type=#{settings['type']}"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file is part of Fog::Proxmox.
|
|
4
|
+
|
|
5
|
+
# Fog::Proxmox is free software: you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
# (at your option) any later version.
|
|
9
|
+
|
|
10
|
+
# Fog::Proxmox is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
# GNU General Public License for more details.
|
|
14
|
+
|
|
15
|
+
# You should have received a copy of the GNU General Public License
|
|
16
|
+
# along with Fog::Proxmox. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
module Fog
|
|
19
|
+
module Proxmox
|
|
20
|
+
# Convert hotplug settings to and from Proxmox configuration strings.
|
|
21
|
+
module HotplugHelper
|
|
22
|
+
DEVICES = %w[disk network usb cpu memory].freeze
|
|
23
|
+
DEFAULTS = %w[disk network usb].freeze
|
|
24
|
+
|
|
25
|
+
def self.extract(hotplug)
|
|
26
|
+
hotplug = hotplug.to_s
|
|
27
|
+
{
|
|
28
|
+
enabled: hotplug != '0',
|
|
29
|
+
devices: hotplug.empty? || hotplug == '1' ? DEFAULTS.dup : hotplug.split(',')
|
|
30
|
+
}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.flatten(settings)
|
|
34
|
+
return '0' unless settings[:enabled]
|
|
35
|
+
|
|
36
|
+
devices = DEVICES.select { |device| settings[:devices].include?(device) }
|
|
37
|
+
devices.empty? ? '0' : devices.join(',')
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file is part of Fog::Proxmox.
|
|
4
|
+
|
|
5
|
+
# Fog::Proxmox is free software: you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
# (at your option) any later version.
|
|
9
|
+
|
|
10
|
+
# Fog::Proxmox is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
# GNU General Public License for more details.
|
|
14
|
+
|
|
15
|
+
# You should have received a copy of the GNU General Public License
|
|
16
|
+
# along with Fog::Proxmox. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
require 'fog/proxmox/hash'
|
|
19
|
+
|
|
20
|
+
module Fog
|
|
21
|
+
module Proxmox
|
|
22
|
+
# Convert RNG devices to and from Proxmox configuration strings
|
|
23
|
+
module RngHelper
|
|
24
|
+
RNG_SOURCES = %w[/dev/urandom /dev/random /dev/hwrng].freeze
|
|
25
|
+
|
|
26
|
+
def self.flatten(rng)
|
|
27
|
+
return {} if rng.nil?
|
|
28
|
+
|
|
29
|
+
options = rng.select do |key, value|
|
|
30
|
+
%i[max_bytes period source].include?(key) && !value.nil? && value != ''
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
validate(options)
|
|
34
|
+
|
|
35
|
+
{ rng0: Fog::Proxmox::Hash.stringify(options) }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.validate(rng)
|
|
39
|
+
raise ArgumentError, 'RNG source is required and must be /dev/urandom, /dev/random, or /dev/hwrng' unless RNG_SOURCES.include?(rng[:source].to_s)
|
|
40
|
+
|
|
41
|
+
%i[max_bytes period].each do |key|
|
|
42
|
+
next if rng[key].nil? || rng[key] == ''
|
|
43
|
+
next if rng[key].to_s.match?(/\A[0-9]+\z/)
|
|
44
|
+
|
|
45
|
+
raise ArgumentError, "RNG #{key} must be a non-negative integer"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
true
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def self.extract(rng)
|
|
52
|
+
options = rng.split(',').each_with_object({}) do |option, values|
|
|
53
|
+
key, value = option.split('=', 2)
|
|
54
|
+
values[key.to_sym] = value&.sub(/\A"(.*)"\z/, '\1')
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
options.slice(:max_bytes, :period, :source)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Fog
|
|
4
|
+
module Proxmox
|
|
5
|
+
class Storage
|
|
6
|
+
# Uploads a local ISO and waits for the Proxmox task to finish.
|
|
7
|
+
class IsoUpload < Fog::Model
|
|
8
|
+
attribute :node_id
|
|
9
|
+
attribute :storage_id
|
|
10
|
+
attribute :path
|
|
11
|
+
|
|
12
|
+
def upload
|
|
13
|
+
requires :node_id, :storage_id, :path
|
|
14
|
+
|
|
15
|
+
filename = File.basename(path)
|
|
16
|
+
size = File.size(path)
|
|
17
|
+
Fog::Logger.debug("Starting Proxmox ISO upload filename=#{filename} size=#{size} bytes node=#{node_id} storage=#{storage_id}")
|
|
18
|
+
response = File.open(path, 'rb') do |file|
|
|
19
|
+
Fog::Proxmox::Storage.new(service.config).upload_iso(
|
|
20
|
+
{ node: node_id, storage: storage_id },
|
|
21
|
+
{ filename: filename, file: file }
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
Fog::Logger.debug("Upload response: #{response.inspect}")
|
|
25
|
+
task_node = response.to_s[/\AUPID:([^:]+):/, 1]
|
|
26
|
+
raise Fog::Errors::Error, "Unexpected upload response: #{response.inspect}" unless task_node
|
|
27
|
+
|
|
28
|
+
service.nodes.get(task_node).tasks.wait_for(response)
|
|
29
|
+
response
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file is part of Fog::Proxmox.
|
|
4
|
+
|
|
5
|
+
# Fog::Proxmox is free software: you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
# (at your option) any later version.
|
|
9
|
+
|
|
10
|
+
# Fog::Proxmox is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
# GNU General Public License for more details.
|
|
14
|
+
|
|
15
|
+
# You should have received a copy of the GNU General Public License
|
|
16
|
+
# along with Fog::Proxmox. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
require 'fog/proxmox/compute/models/multipart_iso_upload'
|
|
19
|
+
|
|
20
|
+
module Fog
|
|
21
|
+
module Proxmox
|
|
22
|
+
class Storage
|
|
23
|
+
# class Real upload_iso request
|
|
24
|
+
class Real
|
|
25
|
+
def upload_iso(path_params, body_params)
|
|
26
|
+
node = path_params[:node]
|
|
27
|
+
storage = path_params[:storage]
|
|
28
|
+
upload = MultipartIsoUpload.new(body_params)
|
|
29
|
+
|
|
30
|
+
request(
|
|
31
|
+
expects: [200],
|
|
32
|
+
method: 'POST',
|
|
33
|
+
path: "nodes/#{node}/storage/#{storage}/upload",
|
|
34
|
+
body: upload.body,
|
|
35
|
+
headers: { 'Content-Type' => upload.content_type }
|
|
36
|
+
)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# class Mock upload_iso request
|
|
41
|
+
class Mock
|
|
42
|
+
def upload_iso(_path_params, _body_params); end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|