1
Puppet::Type.type(:zone).provide(:solaris) do
2
desc "Provider for Solaris Zones."
4
commands :adm => "/usr/sbin/zoneadm", :cfg => "/usr/sbin/zonecfg"
5
defaultfor :operatingsystem => :solaris
9
# Convert the output of a list into a hash
10
def self.line2hash(line)
11
fields = [:id, :name, :ensure, :path]
14
line.split(":").each_with_index { |value, index|
15
properties[fields[index]] = value
18
# Configured but not installed zones do not have IDs
19
if properties[:id] == "-"
20
properties.delete(:id)
23
properties[:ensure] = symbolize(properties[:ensure])
29
# LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
30
x = adm(:list, "-cp").split("\n").collect do |line|
35
# Perform all of our configuration steps.
37
# If the thing is entirely absent, then we need to create the config.
42
# Then perform all of our configuration steps. It's annoying
43
# that we need this much internal info on the resource.
44
@resource.send(:properties).each do |property|
45
if property.is_a? ZoneConfigProperty and ! property.insync?(properties[property.name])
46
str += property.configtext + "\n"
59
properties[:ensure] != :absent
62
# Clear out the cached values.
71
# Look up the current status.
73
if @property_hash.empty?
74
@property_hash = status || {}
75
if @property_hash.empty?
76
@property_hash[:ensure] = :absent
78
@resource.class.validproperties.each do |name|
79
@property_hash[name] ||= :absent
87
# We need a way to test whether a zone is in process. Our 'ensure'
88
# property models the static states, but we need to handle the temporary ones.
92
when "incomplete", "ready", "shutting_down"
102
# Collect the configuration of the zone.
104
output = zonecfg :info
109
output.split("\n").each do |line|
113
current = nil # reset it
114
when /^(\S+):\s*(.+)$/:
116
when /^\s+(\S+):\s*(.+)$/:
118
unless hash.include? name
124
hash[name] << current
126
current[$1.intern] = $2
128
err "Ignoring '%s'" % line
131
debug "Ignoring zone output '%s'" % line
138
# Execute a configuration string. Can't be private because it's called
141
command = "#{command(:cfg)} -z %s -f -" % @resource[:name]
142
debug "Executing '%s' in zone %s with '%s'" % [command, @resource[:name], str]
143
IO.popen(command, "w") do |pipe|
148
raise ArgumentError, "Failed to apply configuration"
153
# Check the sysidcfg stuff
154
if cfg = @resource[:sysidcfg]
155
path = File.join(@resource[:path], "root", "etc", "sysidcfg")
157
unless File.exists?(path)
159
File.open(path, "w", 0600) do |f|
164
puts detail.stacktrace
166
raise Puppet::Error, "Could not create sysidcfg: %s" % detail
174
# Return a hash of the current status of this zone.
177
output = adm "-z", @resource[:name], :list, "-p"
178
rescue Puppet::ExecutionFailure
182
main = self.class.line2hash(output.chomp)
184
# Now add in the configuration information
185
config_status.each do |name, value|
197
zonecfg :delete, "-F"
201
zoneadm :uninstall, "-F"
206
# Turn the results of getconfig into status information.
211
result[:autoboot] = config[:autoboot] ? config[:autoboot].intern : :absent
212
result[:pool] = config[:pool]
213
result[:shares] = config[:shares]
214
if dir = config["inherit-pkg-dir"]
215
result[:inherit] = dir.collect { |dirs| dirs[:dir] }
217
if net = config["net"]
218
result[:ip] = net.collect { |params| "%s:%s" % [params[:physical], params[:address]] }
226
adm("-z", @resource[:name], *cmd)
227
rescue Puppet::ExecutionFailure => detail
228
self.fail "Could not %s zone: %s" % [cmd[0], detail]
233
# You apparently can't get the configuration of the global zone
234
return "" if self.name == "global"
237
cfg("-z", self.name, *cmd)
238
rescue Puppet::ExecutionFailure => detail
239
self.fail "Could not %s zone: %s" % [cmd[0], detail]