pve 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,3 @@
1
+ module PVE
2
+ VERSION = '0.1.2'
3
+ end
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: []