pve 0.1.2
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 +7 -0
- data/.gitignore +2 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +70 -0
- data/README.adoc +22 -0
- data/bin/pvecli +5 -0
- data/lib/pve.rb +4 -0
- data/lib/pve/cli.rb +159 -0
- data/lib/pve/cli/base.rb +187 -0
- data/lib/pve/cli/ct.rb +115 -0
- data/lib/pve/cli/ha.rb +78 -0
- data/lib/pve/cli/node.rb +46 -0
- data/lib/pve/cli/qm.rb +32 -0
- data/lib/pve/cli/task.rb +26 -0
- data/lib/pve/helper.rb +167 -0
- data/lib/pve/proxmox.rb +597 -0
- data/lib/pve/qm.rb +32 -0
- data/lib/pve/templates.rb +154 -0
- data/lib/pve/version.rb +3 -0
- data/pve.gemspec +37 -0
- metadata +150 -0
data/lib/pve/qm.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
class PVE::Cli
|
2
|
+
def cli_qm
|
3
|
+
cli.sub :qm, "Virtual Machines", aliases: %w[v vm qemu], &lambda {|qm|
|
4
|
+
qm.cmd :list, "List VM-IDs", aliases: ['ls'], &lambda {|node=nil|
|
5
|
+
connect
|
6
|
+
nodes = Proxmox::Node.all
|
7
|
+
nodes = nodes.select {|n| node == n.name } if node
|
8
|
+
nodes.flat_map do |n|
|
9
|
+
n.qemu.map {|c| c.vmid.to_i }
|
10
|
+
end.sort.each {|c| puts c }
|
11
|
+
}
|
12
|
+
|
13
|
+
qm.cmd :status, "List VMs with status", aliases: [nil], &lambda {|node=nil|
|
14
|
+
connect
|
15
|
+
to = TablizedOutput.new %w[Status HA ID Name Host Uptime CPU Mem/MiB Disk/MiB]
|
16
|
+
nodes = Proxmox::Node.all
|
17
|
+
nodes = nodes.select {|n| node == n.name } if node
|
18
|
+
nodes.each do |n|
|
19
|
+
n.qemu.each &to.method( :virt)
|
20
|
+
end
|
21
|
+
to.print order: [3]
|
22
|
+
}
|
23
|
+
|
24
|
+
qm.cmd :exec, "Executes Command in VM via qemu-guest-agent", min: 4, &lambda {|name_or_id, *command|
|
25
|
+
connect
|
26
|
+
STDERR.puts "! #{$?.exitstatus}" unless Proxmox::Qemu.find!( name_or_id).exec *command
|
27
|
+
}
|
28
|
+
|
29
|
+
qm.cmd 'help', '', aliases: ['-h', '--help'], &lambda {|*args| help qm, *args }
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module PVE::CTTemplate
|
4
|
+
class Base
|
5
|
+
attr_reader :options
|
6
|
+
|
7
|
+
def initialize **opts
|
8
|
+
@options = OpenStruct.new opts
|
9
|
+
@virts = Proxmox::LXC.all + Proxmox::Qemu.all
|
10
|
+
end
|
11
|
+
|
12
|
+
def name() options.name end
|
13
|
+
def node() options.node end
|
14
|
+
def arch() options.arch || 'amd64' end
|
15
|
+
def vmid() options.vmid end
|
16
|
+
def ostype() options.ostype end
|
17
|
+
def cmode() options.cmode || 'shell' end
|
18
|
+
def cores() options.cores || 1 end
|
19
|
+
def description() options.description || '' end
|
20
|
+
def hostname() options.hostname || name end
|
21
|
+
def memory() options.memory || 1024 end
|
22
|
+
def swap() options.swap || 0 end
|
23
|
+
def unprivileged() options.unprivileged() || 1 end
|
24
|
+
|
25
|
+
def ssh_public_keys
|
26
|
+
options[:'ssh-public-keys'] ||
|
27
|
+
File.read( options[:'ssh-public-keys-file'] || '/root/.ssh/authorized_keys')
|
28
|
+
end
|
29
|
+
|
30
|
+
def net0()
|
31
|
+
if options.ipv4 || options.ipv6
|
32
|
+
ipv4 = IPAddress::IPv4.new options.ipv4
|
33
|
+
{
|
34
|
+
name: 'eth0',
|
35
|
+
bridge: 'vmbr1',
|
36
|
+
ip: ipv4.to_string,
|
37
|
+
gw: options.gateway || ipv4.hosts.last.to_s
|
38
|
+
}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
def net1() nil end
|
42
|
+
def net2() nil end
|
43
|
+
def net3() nil end
|
44
|
+
end
|
45
|
+
|
46
|
+
class Default < Base
|
47
|
+
def self.requirements
|
48
|
+
{
|
49
|
+
node: [:string, false, "Create CT on this node."],
|
50
|
+
name: [:string, true, "Set (uniq) name"],
|
51
|
+
arch: [:enum, false, "Architecture", %w[amd64 i386 arm64 armhf]],
|
52
|
+
vmid: [:numeric, true, "VM-ID. Proxmox internal number (100...)"],
|
53
|
+
ostype: [:string, true, "OS-Type (OS or distribution)"],
|
54
|
+
cmode: [:enum, false, "Console-mode", %w[shell console tty]],
|
55
|
+
cores: [:numeric, false, "Count of cores"],
|
56
|
+
description: [:string, false, "Description. Eg. What should this CT do?"],
|
57
|
+
hostname: [:string, false, "Hostname"],
|
58
|
+
memory: [:numeric, false, "How much memory CT could use?"],
|
59
|
+
swap: [:numeric, false, "How much CT can swap?"],
|
60
|
+
unprivileged: [:boolean, false, "Unprivileged are restricted to own UID/GID-space."],
|
61
|
+
:'ssh-public-keys' => [:string, false, "SSH-Public-Keys, which should be added to root-user in CT."],
|
62
|
+
:'ssh-public-keys-file' => [:string, false, "Read SSH-Public-Keys from file."],
|
63
|
+
ipv4: [:string, false, "IPv4-Address with net-size."],
|
64
|
+
gateway4: [:string, false, "IPv4-Address of gateway."],
|
65
|
+
ipv6: [:string, false, "IPv6-Address with net-size."],
|
66
|
+
gateway6: [:string, false, "IPv6-Address of gateway."],
|
67
|
+
storage: [:string, false, "Device will be create on this Storage (default: local"],
|
68
|
+
}
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class Datacenter < Base
|
73
|
+
def self.requirements
|
74
|
+
{
|
75
|
+
node: [:string, false, "Create CT on this node."],
|
76
|
+
name: [:string, true, "Set (uniq) name"],
|
77
|
+
arch: [:enum, false, "Architecture", %w[amd64 i386 arm64 armhf]],
|
78
|
+
vmid: [:numeric, true, "VM-ID. Proxmox internal number (100...)"],
|
79
|
+
ostype: [:string, true, "OS-Type (OS or distribution)"],
|
80
|
+
cmode: [:enum, false, "Console-mode", %w[shell console tty]],
|
81
|
+
cores: [:numeric, false, "Count of cores"],
|
82
|
+
description: [:string, false, "Description. Eg. What should this CT do?"],
|
83
|
+
hostname: [:string, false, "Hostname"],
|
84
|
+
memory: [:numeric, false, "How much memory CT could use?"],
|
85
|
+
swap: [:numeric, false, "How much CT can swap?"],
|
86
|
+
unprivileged: [:boolean, false, "Unprivileged are restricted to own UID/GID-space."],
|
87
|
+
:'ssh-public-keys' => [:string, false, "SSH-Public-Keys, which should be added to root-user in CT."],
|
88
|
+
:'ssh-public-keys-file' => [:string, false, "Read SSH-Public-Keys from file."],
|
89
|
+
:'network-id' => [:numeric, true, "Put Container to this VLAN and use a random IPv4-Address for this CT."],
|
90
|
+
ipv4: [:string, false, "IPv4-Address with net-size."],
|
91
|
+
gateway4: [:string, false, "IPv4-Address of gateway."],
|
92
|
+
ipv6: [:string, false, "IPv6-Address with net-size."],
|
93
|
+
gateway6: [:string, false, "IPv6-Address of gateway."],
|
94
|
+
storage: [:string, false, "Device will be create on this Storage (default: root)"],
|
95
|
+
}
|
96
|
+
end
|
97
|
+
|
98
|
+
def node() options.node || 'svc1' end
|
99
|
+
def ostype() options.ostype || 'debian' end
|
100
|
+
def memory() options.memory || 2048 end
|
101
|
+
def storage() options.storage || 'root' end
|
102
|
+
|
103
|
+
def network_id
|
104
|
+
return @network_id if @network_id
|
105
|
+
expect = 0..12
|
106
|
+
nid = options[:'network-id']
|
107
|
+
unless nid == nid.to_i.to_s && expect.include?( nid.to_i)
|
108
|
+
raise ArgumentError, "Network ID must be #{expect.inspect}. Given: #{nid.inspect}"
|
109
|
+
end
|
110
|
+
@network_id = nid.to_i
|
111
|
+
end
|
112
|
+
|
113
|
+
def net0
|
114
|
+
{
|
115
|
+
name: 'eth0',
|
116
|
+
bridge: 'vmbr1',
|
117
|
+
tag: 2000+network_id,
|
118
|
+
mtu: 9166,
|
119
|
+
firewall: 1,
|
120
|
+
ip: ipv4.to_string,
|
121
|
+
gw: ipv4.hosts.last.to_s,
|
122
|
+
}
|
123
|
+
end
|
124
|
+
|
125
|
+
def vmid
|
126
|
+
super || ((0...100).map {|i| "#{100*network_id+i}" } - @virts.map( &:vmid)).first
|
127
|
+
end
|
128
|
+
|
129
|
+
def network
|
130
|
+
IPAddress::IPv4.new "10.#{network_id}.255.0/24"
|
131
|
+
end
|
132
|
+
|
133
|
+
def ipv4
|
134
|
+
return options.ipv4 if options.ipv4
|
135
|
+
return @ipv4 if @ipv4
|
136
|
+
ipv4s = network.hosts
|
137
|
+
@virts.each do |v|
|
138
|
+
v.config[:network].each {|n| ipv4s.delete n[:ip] if n[:ip] }
|
139
|
+
end
|
140
|
+
@ipv4 = ipv4s.first
|
141
|
+
end
|
142
|
+
|
143
|
+
def ostemplate
|
144
|
+
@ostemplate ||=
|
145
|
+
options.ostemplate ||
|
146
|
+
case ostype
|
147
|
+
when 'debian'
|
148
|
+
'local:vztmpl/debian-10-standard_10.5-1_amd64.tar.gz'
|
149
|
+
else
|
150
|
+
raise ArgumentError, "OS-Template for ostype #{ostype} not found or ostemplate not provided."
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
data/lib/pve/version.rb
ADDED
data/pve.gemspec
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require_relative 'lib/pve/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "pve"
|
5
|
+
spec.version = PVE::VERSION
|
6
|
+
spec.authors = ["Denis Knauf"]
|
7
|
+
spec.email = ["git+pve@denkn.at"]
|
8
|
+
spec.licenses = ["LGPL-3.0"]
|
9
|
+
|
10
|
+
spec.summary = %q{Proxmox Virtual Environment higher level API }
|
11
|
+
spec.description = %q{Provides a higher level API with objects for controlling PVE}
|
12
|
+
spec.homepage = "https://git.denkn.at/deac/pve"
|
13
|
+
# Ruby3 interpret **opts in another way than before.
|
14
|
+
# 2.7.0 should work with both(?) behaviours.
|
15
|
+
# PVE based on debian, so ruby 2.5 is default.
|
16
|
+
spec.required_ruby_version = Gem::Requirement.new "~> 2.5.0"
|
17
|
+
|
18
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
19
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
20
|
+
spec.metadata["changelog_uri"] = spec.homepage
|
21
|
+
|
22
|
+
spec.add_dependency 'dencli', '~> 0.3.1'
|
23
|
+
spec.add_dependency 'rest-client', '~> 2.1'
|
24
|
+
spec.add_dependency 'ipaddress', '~> 0.8.3'
|
25
|
+
spec.add_dependency 'activesupport', '>= 2'
|
26
|
+
spec.add_dependency 'pmap', '~> 1.1'
|
27
|
+
spec.add_development_dependency "rspec", "~> 3.2"
|
28
|
+
|
29
|
+
# Specify which files should be added to the gem when it is released.
|
30
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
31
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
32
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
33
|
+
end
|
34
|
+
spec.bindir = "bin"
|
35
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
36
|
+
spec.require_paths = ["lib"]
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pve
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Denis Knauf
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-04-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: dencli
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.3.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.3.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rest-client
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.1'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: ipaddress
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.8.3
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.8.3
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activesupport
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pmap
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.1'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.1'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.2'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.2'
|
97
|
+
description: Provides a higher level API with objects for controlling PVE
|
98
|
+
email:
|
99
|
+
- git+pve@denkn.at
|
100
|
+
executables:
|
101
|
+
- pvecli
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- ".gitignore"
|
106
|
+
- Gemfile
|
107
|
+
- Gemfile.lock
|
108
|
+
- README.adoc
|
109
|
+
- bin/pvecli
|
110
|
+
- lib/pve.rb
|
111
|
+
- lib/pve/cli.rb
|
112
|
+
- lib/pve/cli/base.rb
|
113
|
+
- lib/pve/cli/ct.rb
|
114
|
+
- lib/pve/cli/ha.rb
|
115
|
+
- lib/pve/cli/node.rb
|
116
|
+
- lib/pve/cli/qm.rb
|
117
|
+
- lib/pve/cli/task.rb
|
118
|
+
- lib/pve/helper.rb
|
119
|
+
- lib/pve/proxmox.rb
|
120
|
+
- lib/pve/qm.rb
|
121
|
+
- lib/pve/templates.rb
|
122
|
+
- lib/pve/version.rb
|
123
|
+
- pve.gemspec
|
124
|
+
homepage: https://git.denkn.at/deac/pve
|
125
|
+
licenses:
|
126
|
+
- LGPL-3.0
|
127
|
+
metadata:
|
128
|
+
homepage_uri: https://git.denkn.at/deac/pve
|
129
|
+
source_code_uri: https://git.denkn.at/deac/pve
|
130
|
+
changelog_uri: https://git.denkn.at/deac/pve
|
131
|
+
post_install_message:
|
132
|
+
rdoc_options: []
|
133
|
+
require_paths:
|
134
|
+
- lib
|
135
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - "~>"
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: 2.5.0
|
140
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
requirements: []
|
146
|
+
rubygems_version: 3.1.2
|
147
|
+
signing_key:
|
148
|
+
specification_version: 4
|
149
|
+
summary: Proxmox Virtual Environment higher level API
|
150
|
+
test_files: []
|