pve/lib/pve/templates.rb

155 lines
6.2 KiB
Ruby

require 'ostruct'
module PVE::CTTemplate
class Base
attr_reader :options
def initialize **opts
@options = OpenStruct.new opts
@virts = Proxmox::LXC.all + Proxmox::Qemu.all
end
def name() options.name end
def node() options.node end
def arch() options.arch || 'amd64' end
def vmid() options.vmid end
def ostype() options.ostype end
def cmode() options.cmode || 'shell' end
def cores() options.cores || 1 end
def description() options.description || '' end
def hostname() options.hostname || name end
def memory() options.memory || 1024 end
def swap() options.swap || 0 end
def unprivileged() options.unprivileged() || 1 end
def ssh_public_keys
options[:'ssh-public-keys'] ||
File.read( options[:'ssh-public-keys-file'] || '/root/.ssh/authorized_keys')
end
def net0()
if options.ipv4 || options.ipv6
ipv4 = IPAddress::IPv4.new options.ipv4
{
name: 'eth0',
bridge: 'vmbr1',
ip: ipv4.to_string,
gw: options.gateway || ipv4.hosts.last.to_s
}
end
end
def net1() nil end
def net2() nil end
def net3() nil end
end
class Default < Base
def self.requirements
{
node: [:string, false, "Create CT on this node."],
name: [:string, true, "Set (uniq) name"],
arch: [:enum, false, "Architecture", %w[amd64 i386 arm64 armhf]],
vmid: [:numeric, true, "VM-ID. Proxmox internal number (100...)"],
ostype: [:string, true, "OS-Type (OS or distribution)"],
cmode: [:enum, false, "Console-mode", %w[shell console tty]],
cores: [:numeric, false, "Count of cores"],
description: [:string, false, "Description. Eg. What should this CT do?"],
hostname: [:string, false, "Hostname"],
memory: [:numeric, false, "How much memory CT could use?"],
swap: [:numeric, false, "How much CT can swap?"],
unprivileged: [:boolean, false, "Unprivileged are restricted to own UID/GID-space."],
:'ssh-public-keys' => [:string, false, "SSH-Public-Keys, which should be added to root-user in CT."],
:'ssh-public-keys-file' => [:string, false, "Read SSH-Public-Keys from file."],
ipv4: [:string, false, "IPv4-Address with net-size."],
gateway4: [:string, false, "IPv4-Address of gateway."],
ipv6: [:string, false, "IPv6-Address with net-size."],
gateway6: [:string, false, "IPv6-Address of gateway."],
storage: [:string, false, "Device will be create on this Storage (default: local"],
}
end
end
class Datacenter < Base
def self.requirements
{
node: [:string, false, "Create CT on this node."],
name: [:string, true, "Set (uniq) name"],
arch: [:enum, false, "Architecture", %w[amd64 i386 arm64 armhf]],
vmid: [:numeric, true, "VM-ID. Proxmox internal number (100...)"],
ostype: [:string, true, "OS-Type (OS or distribution)"],
cmode: [:enum, false, "Console-mode", %w[shell console tty]],
cores: [:numeric, false, "Count of cores"],
description: [:string, false, "Description. Eg. What should this CT do?"],
hostname: [:string, false, "Hostname"],
memory: [:numeric, false, "How much memory CT could use?"],
swap: [:numeric, false, "How much CT can swap?"],
unprivileged: [:boolean, false, "Unprivileged are restricted to own UID/GID-space."],
:'ssh-public-keys' => [:string, false, "SSH-Public-Keys, which should be added to root-user in CT."],
:'ssh-public-keys-file' => [:string, false, "Read SSH-Public-Keys from file."],
:'network-id' => [:numeric, true, "Put Container to this VLAN and use a random IPv4-Address for this CT."],
ipv4: [:string, false, "IPv4-Address with net-size."],
gateway4: [:string, false, "IPv4-Address of gateway."],
ipv6: [:string, false, "IPv6-Address with net-size."],
gateway6: [:string, false, "IPv6-Address of gateway."],
storage: [:string, false, "Device will be create on this Storage (default: root)"],
}
end
def node() options.node || 'svc1' end
def ostype() options.ostype || 'debian' end
def memory() options.memory || 2048 end
def storage() options.storage || 'root' end
def network_id
return @network_id if @network_id
expect = 0..12
nid = options[:'network-id']
unless nid == nid.to_i.to_s && expect.include?( nid.to_i)
raise ArgumentError, "Network ID must be #{expect.inspect}. Given: #{nid.inspect}"
end
@network_id = nid.to_i
end
def net0
{
name: 'eth0',
bridge: 'vmbr1',
tag: 2000+network_id,
mtu: 9166,
firewall: 1,
ip: ipv4.to_string,
gw: ipv4.hosts.last.to_s,
}
end
def vmid
super || ((0...100).map {|i| "#{100*network_id+i}" } - @virts.map( &:vmid)).first
end
def network
IPAddress::IPv4.new "10.#{network_id}.255.0/24"
end
def ipv4
return options.ipv4 if options.ipv4
return @ipv4 if @ipv4
ipv4s = network.hosts
@virts.each do |v|
v.config[:network].each {|n| ipv4s.delete n[:ip] if n[:ip] }
end
@ipv4 = ipv4s.first
end
def ostemplate
@ostemplate ||=
options.ostemplate ||
case ostype
when 'debian'
'local:vztmpl/debian-10-standard_10.5-1_amd64.tar.gz'
else
raise ArgumentError, "OS-Template for ostype #{ostype} not found or ostemplate not provided."
end
end
end
end