summaryrefslogtreecommitdiffstats
path: root/lib/puppet/provider/zone
diff options
context:
space:
mode:
authorluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-12-29 00:05:03 +0000
committerluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-12-29 00:05:03 +0000
commit7ae62a5dd2323c38b2dd5ba662d8c140b0f9345c (patch)
tree72e33fc20ac6d796b3a4e5fec7219c71b8db89d1 /lib/puppet/provider/zone
parentc4c3d77c58ae07560eafe838abbbf8271d923e57 (diff)
downloadpuppet-7ae62a5dd2323c38b2dd5ba662d8c140b0f9345c.tar.gz
puppet-7ae62a5dd2323c38b2dd5ba662d8c140b0f9345c.tar.xz
puppet-7ae62a5dd2323c38b2dd5ba662d8c140b0f9345c.zip
A couple of small bug fixes
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@1982 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'lib/puppet/provider/zone')
-rw-r--r--lib/puppet/provider/zone/solaris.rb208
1 files changed, 208 insertions, 0 deletions
diff --git a/lib/puppet/provider/zone/solaris.rb b/lib/puppet/provider/zone/solaris.rb
new file mode 100644
index 000000000..e4871f812
--- /dev/null
+++ b/lib/puppet/provider/zone/solaris.rb
@@ -0,0 +1,208 @@
+Puppet::Type.type(:zone).provide(:solaris) do
+ desc "Provider for Solaris Zones."
+
+ commands :adm => "/usr/sbin/zoneadm", :cfg => "/usr/sbin/zonecfg"
+ defaultfor :operatingsystem => :solaris
+
+ # Convert the output of a list into a hash
+ def self.line2hash(line)
+ fields = [:id, :name, :ensure, :path]
+
+ hash = {}
+ line.split(":").each_with_index { |value, index|
+ hash[fields[index]] = value
+ }
+
+ # Configured but not installed zones do not have IDs
+ if hash[:id] == "-"
+ hash.delete(:id)
+ end
+
+ return hash
+ end
+
+ def self.list
+ adm(:list, "-cp").split("\n").collect do |line|
+ hash = line2hash(line)
+
+ obj = nil
+ unless obj = @model[hash[:name]]
+ obj = @model.create(:name => hash[:name])
+ end
+
+ obj.setstatus(hash)
+
+ obj
+ end
+ end
+
+ # Perform all of our configuration steps.
+ def configure
+ # If the thing is entirely absent, then we need to create the config.
+ str = %{create -b
+set zonepath=%s
+} % @model[:path]
+
+ # Then perform all of our configuration steps. It's annoying
+ # that we need this much internal info on the model.
+ @model.send(:states).each do |state|
+ if state.is_a? ZoneConfigState and ! state.insync?
+ str += state.configtext + "\n"
+ end
+ end
+
+ str += "commit\n"
+ setconfig(str)
+ end
+
+ def destroy
+ zonecfg :delete, "-F"
+ end
+
+ def install
+ zoneadm :install
+ end
+
+ # We need a way to test whether a zone is in process. Our 'ensure'
+ # state models the static states, but we need to handle the temporary ones.
+ def processing?
+ if hash = statushash()
+ case hash[:ensure]
+ when "incomplete", "ready", "shutting_down"
+ true
+ else
+ false
+ end
+ else
+ false
+ end
+ end
+
+ # Collect the configuration of the zone.
+ def getconfig
+ output = zonecfg :info
+
+ name = nil
+ current = nil
+ hash = {}
+ output.split("\n").each do |line|
+ case line
+ when /^(\S+):\s*$/:
+ name = $1
+ current = nil # reset it
+ when /^(\S+):\s*(.+)$/:
+ hash[$1.intern] = $2
+ #self.is = [$1.intern, $2]
+ when /^\s+(\S+):\s*(.+)$/:
+ if name
+ unless hash.include? name
+ hash[name] = []
+ end
+
+ unless current
+ current = {}
+ hash[name] << current
+ end
+ current[$1.intern] = $2
+ else
+ err "Ignoring '%s'" % line
+ end
+ else
+ debug "Ignoring zone output '%s'" % line
+ end
+ end
+ return hash
+ end
+
+ def retrieve
+ if hash = statushash()
+ setstatus(hash)
+
+ # Now retrieve the configuration itself and set appropriately.
+ getconfig()
+ else
+ @states.each do |name, state|
+ state.is = :absent
+ end
+ end
+ end
+
+ # Execute a configuration string. Can't be private because it's called
+ # by the states.
+ def setconfig(str)
+ command = "#{command(:cfg)} -z %s -f -" % @model[:name]
+ debug "Executing '%s' in zone %s with '%s'" % [command, @model[:name], str]
+ IO.popen(command, "w") do |pipe|
+ pipe.puts str
+ end
+
+ unless $? == 0
+ raise ArgumentError, "Failed to apply configuration"
+ end
+ end
+
+ def start
+ # Check the sysidcfg stuff
+ if cfg = @model[:sysidcfg]
+ path = File.join(@model[:path], "root", "etc", "sysidcfg")
+
+ unless File.exists?(path)
+ begin
+ File.open(path, "w", 0600) do |f|
+ f.puts cfg
+ end
+ rescue => detail
+ if Puppet[:debug]
+ puts detail.stacktrace
+ end
+ raise Puppet::Error, "Could not create sysidcfg: %s" % detail
+ end
+ end
+ end
+
+ zoneadm :boot
+ end
+
+ # Return a hash of the current status of this zone.
+ def statushash
+ begin
+ output = adm "-z", @model[:name], :list, "-p"
+ rescue Puppet::ExecutionFailure
+ return nil
+ end
+
+ return self.class.line2hash(output.chomp)
+ end
+
+ def stop
+ zoneadm :halt
+ end
+
+ def unconfigure
+ zonecfg :delete, "-F"
+ end
+
+ def uninstall
+ zoneadm :uninstall, "-F"
+ end
+
+ private
+
+ def zoneadm(*cmd)
+ begin
+ adm("-z", @model[:name], *cmd)
+ rescue Puppet::ExecutionFailure => detail
+ self.fail "Could not %s zone: %s" % [cmd[0], detail]
+ end
+ end
+
+ def zonecfg(*cmd)
+ begin
+ cfg("-z", @model[:name], *cmd)
+ rescue Puppet::ExecutionFailure => detail
+ self.fail "Could not %s zone: %s" % [cmd[0], detail]
+ end
+ end
+end
+
+# $Id$