pve 0.1.2 → 0.1.3
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/lib/pve/cli.rb +12 -7
- data/lib/pve/cli/base.rb +2 -0
- data/lib/pve/cli/ct.rb +14 -2
- data/lib/pve/helper.rb +14 -0
- data/lib/pve/proxmox.rb +8 -2
- data/lib/pve/templates.rb +55 -14
- data/lib/pve/version.rb +1 -1
- metadata +2 -3
- data/lib/pve/qm.rb +0 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a06ddcb47642c05e1741f36743dddc8549fe0a662d72246b8965d63474f437a2
|
4
|
+
data.tar.gz: 458054ab599bc236cbae0e708180778a38b4d9136d6278f4c3866047af0f4819
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e967e72848d1ca823b8ebb85737a78018116e3ac28c7bc070d1d3a8936ad6c79e9e09a2ff11344f0ce1aa62fa54634602e3993f5081126bf8f72d2b7ac841a32
|
7
|
+
data.tar.gz: 673189e3d7318103b2dad96f653c072c1cef4a1a9a329aa920b17e8f43ecc8741763379b2a2a3f07ccaaf8af8c46eac2c9cef715225f6b6faa8353edaafa1a8a
|
data/lib/pve/cli.rb
CHANGED
@@ -59,16 +59,18 @@ class PVE::Cli
|
|
59
59
|
secs ||= 0.1
|
60
60
|
spinners, spin, logn = "▖▘▝▗", 0, 0
|
61
61
|
STDERR.puts task.upid
|
62
|
+
host = task.host&.name
|
62
63
|
loop do
|
63
64
|
s = task.status
|
64
65
|
if s[:exitstatus]
|
65
|
-
STDERR.printf "\r[%s] %s %s\e[J\n",
|
66
|
-
|
66
|
+
STDERR.printf "\r[%s] %s %s %s\e[J\n",
|
67
|
+
host || s[:id],
|
67
68
|
case s[:exitstatus]
|
68
69
|
when "OK" then "\e[32;1m✓\e[0m"
|
69
70
|
else "\e[31;1m✗\e[0m"
|
70
71
|
end,
|
71
|
-
|
72
|
+
text && "#{text}:",
|
73
|
+
s[:status] == 'stopped' ? :finished : s[:status]
|
72
74
|
return task
|
73
75
|
end
|
74
76
|
log = task.log start: logn
|
@@ -78,7 +80,10 @@ class PVE::Cli
|
|
78
80
|
log.each {|l| puts l[:t] }
|
79
81
|
logn = log.last[:n]
|
80
82
|
end
|
81
|
-
STDERR.printf "\r[%s] \e[33;1m%s\e[0m %s...\e[J",
|
83
|
+
STDERR.printf "\r[%s] \e[33;1m%s\e[0m %s...\e[J",
|
84
|
+
host || s[:id],
|
85
|
+
spinners[spin = (spin + 1) % 4],
|
86
|
+
text || "Working"
|
82
87
|
sleep secs
|
83
88
|
end
|
84
89
|
end
|
@@ -112,12 +117,12 @@ class PVE::Cli
|
|
112
117
|
end
|
113
118
|
|
114
119
|
def create klass, template, timeout: nil, fire: nil, secs: nil, start: nil, **options
|
115
|
-
options[:start] =
|
120
|
+
options[:start] = fire && start
|
116
121
|
task = klass.create template, **options
|
117
122
|
return if fire
|
118
123
|
wait task, text: "Creating"
|
119
124
|
host = task.host.refresh!
|
120
|
-
start host, timeout: timeout, secs: secs
|
125
|
+
start host, timeout: timeout, secs: secs if start
|
121
126
|
end
|
122
127
|
|
123
128
|
def destroy ct, timeout: nil, fire: nil, secs: nil
|
@@ -151,7 +156,7 @@ class PVE::Cli
|
|
151
156
|
def call *argv
|
152
157
|
cli.call *argv
|
153
158
|
rescue RestClient::ExceptionWithResponse
|
154
|
-
STDERR.puts "#$! - #{$!.response} (#{$!.class})"
|
159
|
+
STDERR.puts "#$! - #{$!.response} (#{$!.class})" #, $!.backtrace.map {|b|" #{b}"}
|
155
160
|
rescue UsageError, DenCli::UsageError
|
156
161
|
STDERR.puts $!
|
157
162
|
exit 1
|
data/lib/pve/cli/base.rb
CHANGED
data/lib/pve/cli/ct.rb
CHANGED
@@ -57,13 +57,19 @@ def cli_ct
|
|
57
57
|
if %w[-h --help].include? template
|
58
58
|
STDERR.puts "Usage: ct create TEMPLATE -h # Shows template-related options"
|
59
59
|
STDERR.puts " ct create TEMPLATE [OPTIONS] # Creates a container"
|
60
|
+
STDERR.puts " ct create -l # Listing available templates"
|
60
61
|
exit 1
|
62
|
+
elsif %w[-l --list].include? template
|
63
|
+
STDERR.puts PVE::CTTemplate.constants.reject {|c|:Base==c}.map {|c|c.to_s.titlecase.dasherize.downcase}
|
64
|
+
exit 0
|
61
65
|
end
|
62
66
|
ctopts = {}
|
63
67
|
OptionParser.new do |opts|
|
68
|
+
ctt = PVE::CTTemplate.const_get template.classify
|
64
69
|
opts.banner = <<EOU
|
65
70
|
Usage: ct create #{template} [options]
|
66
71
|
|
72
|
+
#{ctt.help}
|
67
73
|
Options: (*=Required)
|
68
74
|
EOU
|
69
75
|
opts.on '-h', '--help', " Help!" do
|
@@ -75,7 +81,6 @@ EOU
|
|
75
81
|
opts.on( '-f', '--[no-]-fire', " Do not wait till running") {|v| ctopts[:start] = v }
|
76
82
|
opts.on( '-t', '--timeout=TIMEOUT', " Wait for max TIMEOUT seconds (default: endless)") {|v| ctopts[:timeout] = v }
|
77
83
|
opts.on( '-s', '--seconds=SECONDS', " Check every SECONDS for state (default: 0.2)") {|v| ctopts[:seconds] = v }
|
78
|
-
ctt = PVE::CTTemplate.const_get template.classify
|
79
84
|
ctt.requirements.each do |name, (type, req, desc, *args)|
|
80
85
|
req = req ? "*" : " "
|
81
86
|
case type
|
@@ -94,12 +99,19 @@ EOU
|
|
94
99
|
create Proxmox::LXC, template, **ctopts
|
95
100
|
})
|
96
101
|
|
97
|
-
ct_cli.cmd( :config, '', &lambda {|name_or_id|
|
102
|
+
ct_cli.cmd( :config, 'Shows current config', &lambda {|name_or_id|
|
98
103
|
connect
|
99
104
|
ct = Proxmox::LXC.find! name_or_id
|
100
105
|
STDOUT.puts ct.config.to_json
|
101
106
|
})
|
102
107
|
|
108
|
+
ct_cli.cmd( :resize, 'Resize a disk', &lambda {|name_or_id, disk, size|
|
109
|
+
connect
|
110
|
+
ct = Proxmox::LXC.find! name_or_id
|
111
|
+
task = ct.resize disk, size
|
112
|
+
wait task, text: "Resizing #{ct.sid} #{disk} to #{size}"
|
113
|
+
})
|
114
|
+
|
103
115
|
ct_cli.cmd( :destroy, '', min: 7, &lambda {|name_or_id, fire:, secs:, timeout:, i_really_want_to_destroy:|
|
104
116
|
raise UsageError, "Name/ID is not what you want to destroy" unless name_or_id == i_really_want_to_destroy
|
105
117
|
connect
|
data/lib/pve/helper.rb
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
module IPAddress::ToSWithNetmaskForNetworks
|
2
|
+
refine IPAddress::IPv6 do
|
3
|
+
def to_s
|
4
|
+
128 == prefix ? super() : to_string
|
5
|
+
end
|
6
|
+
end
|
7
|
+
refine IPAddress::IPv4 do
|
8
|
+
def to_s
|
9
|
+
32 == prefix ? super() : to_string
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
|
1
15
|
class Measured
|
2
16
|
class <<self
|
3
17
|
def bytes1 v
|
data/lib/pve/proxmox.rb
CHANGED
@@ -331,6 +331,11 @@ module Proxmox
|
|
331
331
|
r.delete :delete if r[:delete].empty?
|
332
332
|
rest_put "#{@rest_prefix}/config", r
|
333
333
|
end
|
334
|
+
|
335
|
+
def resize disk, size
|
336
|
+
upid = rest_put "#{@rest_prefix}/resize", disk: disk, size: size
|
337
|
+
Task.send :__new__, node: @node, host: self, upid: upid
|
338
|
+
end
|
334
339
|
end
|
335
340
|
|
336
341
|
class Qemu < Hosted
|
@@ -490,9 +495,10 @@ module Proxmox
|
|
490
495
|
swap: tmplt.swap,
|
491
496
|
unprivileged: tmplt.unprivileged,
|
492
497
|
}.delete_if {|k,v| v.nil? }
|
493
|
-
|
498
|
+
|
499
|
+
temp = LXC.send :__new__, node: node, vmid: options[:vmid], name: name, hostname: options[:hostname]
|
494
500
|
upid = rest_post( "/nodes/%s/lxc" % node.node, **options)
|
495
|
-
Task.send :__new__, node: node, host:
|
501
|
+
Task.send :__new__, node: node, host: temp, upid: upid
|
496
502
|
end
|
497
503
|
end
|
498
504
|
|
data/lib/pve/templates.rb
CHANGED
@@ -27,14 +27,27 @@ module PVE::CTTemplate
|
|
27
27
|
File.read( options[:'ssh-public-keys-file'] || '/root/.ssh/authorized_keys')
|
28
28
|
end
|
29
29
|
|
30
|
+
def _ipv4 ip, gw
|
31
|
+
return [ip, nil] if %w[dhcp].include? ip
|
32
|
+
ip = IPAddress::IPv4.new ip
|
33
|
+
[ip.to_string, gw || ip.hosts.last.to_s]
|
34
|
+
end
|
35
|
+
|
36
|
+
def _ipv6 ip, gw
|
37
|
+
return [ip, nil] if %w[dhcp auto].include? ip
|
38
|
+
ip = IPAddress::IPv6.new ip
|
39
|
+
[ip.to_string, gw || ip.hosts.last.to_s]
|
40
|
+
end
|
41
|
+
|
30
42
|
def net0()
|
31
43
|
if options.ipv4 || options.ipv6
|
32
|
-
ipv4 =
|
44
|
+
ipv4, gw4 = _ipv4( options.ipv4, options.gateway4)
|
45
|
+
ipv6, gw6 = _ipv6( options.ipv6, options.gateway6)
|
33
46
|
{
|
34
47
|
name: 'eth0',
|
35
48
|
bridge: 'vmbr1',
|
36
|
-
ip: ipv4
|
37
|
-
gw:
|
49
|
+
ip: ipv4, ip6: ipv6,
|
50
|
+
gw: gw4, gw6: gw6,
|
38
51
|
}
|
39
52
|
end
|
40
53
|
end
|
@@ -44,6 +57,10 @@ module PVE::CTTemplate
|
|
44
57
|
end
|
45
58
|
|
46
59
|
class Default < Base
|
60
|
+
def self.help
|
61
|
+
nil
|
62
|
+
end
|
63
|
+
|
47
64
|
def self.requirements
|
48
65
|
{
|
49
66
|
node: [:string, false, "Create CT on this node."],
|
@@ -62,7 +79,7 @@ module PVE::CTTemplate
|
|
62
79
|
:'ssh-public-keys-file' => [:string, false, "Read SSH-Public-Keys from file."],
|
63
80
|
ipv4: [:string, false, "IPv4-Address with net-size."],
|
64
81
|
gateway4: [:string, false, "IPv4-Address of gateway."],
|
65
|
-
ipv6: [:string, false, "IPv6-Address with net-size."],
|
82
|
+
ipv6: [:string, false, "IPv6-Address with net-size or auto."],
|
66
83
|
gateway6: [:string, false, "IPv6-Address of gateway."],
|
67
84
|
storage: [:string, false, "Device will be create on this Storage (default: local"],
|
68
85
|
}
|
@@ -70,12 +87,24 @@ module PVE::CTTemplate
|
|
70
87
|
end
|
71
88
|
|
72
89
|
class Datacenter < Base
|
90
|
+
def self.help
|
91
|
+
<<-EOF.gsub /^ {6}/, ''
|
92
|
+
Datacenter provides an interface for special network-settings.
|
93
|
+
Networks in Datacenters are often based on this behaviour:
|
94
|
+
A Network has an ID like 99.
|
95
|
+
This defines the VLANs: 2099 for Layer2/3099 for Layer3.
|
96
|
+
The IPv4-Range would be 10.99.0.0/16, but container will be put static in 10.99.255.0/24.
|
97
|
+
IPv6 uses RADV, so we do not need to know the IPv6-Range => auto.
|
98
|
+
VMID can be generated by Network-ID, too: smallest unused VMID in 100*ID.
|
99
|
+
EOF
|
100
|
+
end
|
101
|
+
|
73
102
|
def self.requirements
|
74
103
|
{
|
75
104
|
node: [:string, false, "Create CT on this node."],
|
76
105
|
name: [:string, true, "Set (uniq) name"],
|
77
106
|
arch: [:enum, false, "Architecture", %w[amd64 i386 arm64 armhf]],
|
78
|
-
vmid: [:numeric,
|
107
|
+
vmid: [:numeric, false, "VM-ID. Proxmox internal number (100...)"],
|
79
108
|
ostype: [:string, true, "OS-Type (OS or distribution)"],
|
80
109
|
cmode: [:enum, false, "Console-mode", %w[shell console tty]],
|
81
110
|
cores: [:numeric, false, "Count of cores"],
|
@@ -87,11 +116,12 @@ module PVE::CTTemplate
|
|
87
116
|
:'ssh-public-keys' => [:string, false, "SSH-Public-Keys, which should be added to root-user in CT."],
|
88
117
|
:'ssh-public-keys-file' => [:string, false, "Read SSH-Public-Keys from file."],
|
89
118
|
:'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."],
|
119
|
+
ipv4: [:string, false, "IPv4-Address with net-size or dhcp."],
|
91
120
|
gateway4: [:string, false, "IPv4-Address of gateway."],
|
92
|
-
ipv6: [:string, false, "IPv6-Address with net-size."],
|
121
|
+
ipv6: [:string, false, "IPv6-Address with net-size or auto|dhcp."],
|
93
122
|
gateway6: [:string, false, "IPv6-Address of gateway."],
|
94
123
|
storage: [:string, false, "Device will be create on this Storage (default: root)"],
|
124
|
+
ostemplate: [:string, false, "OS-Template eg. local:vztmpl/superlinux-1.2-amd64.tar.xz"],
|
95
125
|
}
|
96
126
|
end
|
97
127
|
|
@@ -111,15 +141,27 @@ module PVE::CTTemplate
|
|
111
141
|
end
|
112
142
|
|
113
143
|
def net0
|
144
|
+
ipv4, gw4 =
|
145
|
+
if options.ipv4
|
146
|
+
_ipv4( options.ipv4, options.gateway4)
|
147
|
+
else
|
148
|
+
self.ipv4_gw
|
149
|
+
end
|
150
|
+
ipv6, gw6 =
|
151
|
+
if options.ipv6
|
152
|
+
_ipv6( options.ipv6, options.gateway6)
|
153
|
+
else
|
154
|
+
['auto', nil]
|
155
|
+
end
|
114
156
|
{
|
115
157
|
name: 'eth0',
|
116
158
|
bridge: 'vmbr1',
|
117
159
|
tag: 2000+network_id,
|
118
160
|
mtu: 9166,
|
119
161
|
firewall: 1,
|
120
|
-
ip: ipv4
|
121
|
-
|
122
|
-
}
|
162
|
+
ip: ipv4, gw: gw4,
|
163
|
+
ip6: ipv6, gw6: gw6,
|
164
|
+
}.delete_if {|k,v| v.nil? }
|
123
165
|
end
|
124
166
|
|
125
167
|
def vmid
|
@@ -130,14 +172,13 @@ module PVE::CTTemplate
|
|
130
172
|
IPAddress::IPv4.new "10.#{network_id}.255.0/24"
|
131
173
|
end
|
132
174
|
|
133
|
-
def
|
134
|
-
return
|
135
|
-
return @ipv4 if @ipv4
|
175
|
+
def ipv4_gw
|
176
|
+
return @ipv4_gw if @ipv4_gw
|
136
177
|
ipv4s = network.hosts
|
137
178
|
@virts.each do |v|
|
138
179
|
v.config[:network].each {|n| ipv4s.delete n[:ip] if n[:ip] }
|
139
180
|
end
|
140
|
-
@
|
181
|
+
@ipv4_gw = [ipv4s.first.to_string, network.last.to_s]
|
141
182
|
end
|
142
183
|
|
143
184
|
def ostemplate
|
data/lib/pve/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pve
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Denis Knauf
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-06-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dencli
|
@@ -117,7 +117,6 @@ files:
|
|
117
117
|
- lib/pve/cli/task.rb
|
118
118
|
- lib/pve/helper.rb
|
119
119
|
- lib/pve/proxmox.rb
|
120
|
-
- lib/pve/qm.rb
|
121
120
|
- lib/pve/templates.rb
|
122
121
|
- lib/pve/version.rb
|
123
122
|
- pve.gemspec
|
data/lib/pve/qm.rb
DELETED
@@ -1,32 +0,0 @@
|
|
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
|