206 lines
4.3 KiB
Ruby
206 lines
4.3 KiB
Ruby
require 'tempfile'
|
|
|
|
Puppet::Type.type(:jail).provide(:iocage) do
|
|
desc 'Manage jails using iocage(8)'
|
|
confine kernel: :freebsd
|
|
defaultfor kernel: :freebsd
|
|
|
|
commands iocage: '/usr/local/sbin/iocage'
|
|
|
|
mk_resource_methods
|
|
|
|
def self.jail_list
|
|
output = iocage(['list']).split("\n")
|
|
fields = output.shift.split.map { |i| i.downcase.to_sym }
|
|
|
|
data = []
|
|
|
|
output.each do |j|
|
|
jail_data = {}
|
|
values = j.split
|
|
|
|
iocage_jail_list_regex = %r{^(-|[0-9]+)\s+([[:xdigit:]]{8}-([[:xdigit:]]{4}-){3})[[:xdigit:]]{12}\s+(on|off)\s+(up|down)\s+.+$}
|
|
next if iocage_jail_list_regex.match(j).nil?
|
|
|
|
values.each_index do |i|
|
|
jail_data[fields[i]] = values[i]
|
|
end
|
|
data << jail_data
|
|
end
|
|
|
|
data
|
|
end
|
|
|
|
def self.prefetch(resources)
|
|
instances.each do |prov|
|
|
if (resource = resources[prov.name])
|
|
resource.provider = prov
|
|
end
|
|
end
|
|
end
|
|
|
|
def self.instances
|
|
jail_list.map do |j|
|
|
jail_properties = {
|
|
provider: :iocage,
|
|
ensure: :present,
|
|
name: j[:tag],
|
|
state: j[:state],
|
|
boot: j[:boot]
|
|
}
|
|
|
|
jail_properties[:jid] = j[:jid] if j[:jid] != '-'
|
|
|
|
all_properties = get_jail_properties(j[:tag])
|
|
|
|
extra_properties = [
|
|
:ip4_addr,
|
|
:ip6_addr,
|
|
:hostname,
|
|
:jail_zfs,
|
|
:jail_zfs_dataset
|
|
]
|
|
|
|
extra_properties.each do |p|
|
|
jail_properties[p] = all_properties[p.to_s]
|
|
end
|
|
|
|
debug jail_properties
|
|
|
|
new(jail_properties)
|
|
end
|
|
end
|
|
|
|
def initialize(value = {})
|
|
super(value)
|
|
@property_flush = {}
|
|
end
|
|
|
|
def self.get_jail_properties(jailname)
|
|
data = {}
|
|
output = iocage(['get', 'all', jailname])
|
|
output.lines.each do |l|
|
|
key, value = l.split(':', 2)
|
|
data[key] = value.chomp
|
|
end
|
|
data.reject! { |k, v| k.nil? || v.nil? }
|
|
|
|
debug data
|
|
|
|
data
|
|
end
|
|
|
|
def exists?
|
|
@property_hash[:ensure] == :present
|
|
end
|
|
|
|
def running?
|
|
@property_hash[:state] == :up
|
|
end
|
|
|
|
def create
|
|
@property_flush[:ensure] = :present
|
|
end
|
|
|
|
def destroy
|
|
@property_flush[:ensure] = :absent
|
|
end
|
|
|
|
def restart
|
|
iocage(['stop', resource[:name]])
|
|
iocage(['start', resource[:name]])
|
|
end
|
|
|
|
def set_property(property, value)
|
|
iocage(['set', "#{property}=#{value}", resource[:name]])
|
|
end
|
|
|
|
def state=(value)
|
|
@property_flush[:state] = value
|
|
end
|
|
|
|
def boot=(value)
|
|
@property_flush[:boot] = value
|
|
end
|
|
|
|
def ip4_addr=(value)
|
|
@property_flush[:ip4_addr] = value
|
|
end
|
|
|
|
def ip6_addr=(value)
|
|
@property_flush[:ip6_addr] = value
|
|
end
|
|
|
|
def hostname=(value)
|
|
@property_flush[:hostname] = value
|
|
end
|
|
|
|
def jail_zfs=(value)
|
|
@property_flush[:jail_zfs] = value
|
|
end
|
|
|
|
def jail_zfs_dataset=(value)
|
|
@property_flush[:jail_zfs_dataset] = value
|
|
end
|
|
|
|
def flush
|
|
if @property_flush
|
|
Puppet.debug "JailIocage(#flush): #{@property_flush}"
|
|
|
|
pre_start_properties = [
|
|
:boot,
|
|
:ip4_addr,
|
|
:ip6_addr,
|
|
:hostname,
|
|
:jail_zfs,
|
|
:jail_zfs_dataset
|
|
]
|
|
|
|
case resource[:ensure]
|
|
when :absent
|
|
iocage(['stop', resource[:name]])
|
|
iocage(['destroy', '-f', resource[:name]])
|
|
when :present
|
|
iocage(['create', '-c', "tag=#{resource[:name]}"])
|
|
end
|
|
|
|
if resource[:state] == :up && resource[:ensure] == :present
|
|
pre_start_properties.each do |p|
|
|
set_property(p.to_s, resource[p]) if resource[p]
|
|
end
|
|
iocage(['start', resource[:name]])
|
|
if resource[:user_data]
|
|
tmpfile = Tempfile.new('puppet-iocage')
|
|
tmpfile.write(resource[:user_data])
|
|
tmpfile.close
|
|
execute("/usr/local/sbin/iocage exec #{resource[:name]} /bin/sh",
|
|
stdinfile: tmpfile.path)
|
|
tmpfile.delete
|
|
end
|
|
end
|
|
|
|
need_restart = false
|
|
pre_start_properties.each do |p|
|
|
if @property_flush[p]
|
|
need_restart = true
|
|
set_property(p.to_s, @property_flush[p])
|
|
end
|
|
end
|
|
|
|
if @property_flush[:state]
|
|
case resource[:state]
|
|
when :up
|
|
need_restart = false
|
|
iocage(['start', resource[:name]])
|
|
when :down
|
|
need_restart = false
|
|
iocage(['stop', resource[:name]])
|
|
end
|
|
end
|
|
|
|
restart if need_restart
|
|
end
|
|
@property_hash = resource.to_hash
|
|
end
|
|
end
|