diff options
| author | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2006-06-01 20:39:13 +0000 |
|---|---|---|
| committer | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2006-06-01 20:39:13 +0000 |
| commit | 011e811f6e9096eedc1b500bb00841292897258b (patch) | |
| tree | bf816804a73c1111e31f436e2a3b649b2abd71e3 /lib | |
| parent | add6b805e84feb2636335b1b3a87ef1b11db60a5 (diff) | |
| download | puppet-011e811f6e9096eedc1b500bb00841292897258b.tar.gz puppet-011e811f6e9096eedc1b500bb00841292897258b.tar.xz puppet-011e811f6e9096eedc1b500bb00841292897258b.zip | |
temporary commit so i can transfer my testing to a faster, sparc box
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@1231 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/puppet/type/zone.rb | 174 |
1 files changed, 148 insertions, 26 deletions
diff --git a/lib/puppet/type/zone.rb b/lib/puppet/type/zone.rb index 86b84272a..b866ffcfd 100644 --- a/lib/puppet/type/zone.rb +++ b/lib/puppet/type/zone.rb @@ -1,6 +1,65 @@ Puppet::Type.newtype(:zone) do @doc = "Solaris zones." + # We should have a special state type for those states that modify + # the zone's configuration. + def self.newstate(name, &block) do + super + + @states[name].class_eval do + def cfgstate + @cfgstate = true + end + + def cfgstate? + if defined? @cfgstate + @cfgstate + else + false + end + end + end + end + + ensurable do + desc "The running state of the zone. The valid states directly reflect + the states that ``zoneadm`` provides. The states are linear, + in that a zone must be ``configured`` then ``installed``, and + only then can be ``running``. Note also that ``halt`` is currently + used to stop zones." + + @@list = [:absent, :configured, :installed, :running] + + newvalue(:absent) do + end + + newvalue(:configured) do + @parent.configure + # Um, don't do anything for now... + end + + newvalue(:installed) do + begin + execute("/usr/sbin/zlogin #{@parent[:name]} shutdown") + rescue ExecutionFailure + self.fail "Could not stop zone: %s" % output + end + end + + newvalue(:running) do + begin + execute("/usr/sbin/zoneadm #{@parent[:name]} boot") + rescue ExecutionFailure + self.fail "Could not stop zone: %s" % output + end + + return :zone_booted + end + + def perform(value) + end + end + newparam(:name) do desc "The name of the zone." @@ -12,52 +71,61 @@ Puppet::Type.newtype(:zone) do and cannot be changed." end - newparam(:ip) do + newstate(:ip) do desc "The IP address of the zone." # We need a generic IP address validation mechanism, and this library # needs to use it. + + cfgstate + end + + newstate(:pool) do + desc "The resource pool for this zone." + + cfgstate end - newstate(:inherited) do + newstate(:inherits) do desc "The list of directories that the zone inherits from the global zone. All directories must be fully qualified." + cfgstate + validate do |value| unless value =~ /^\// raise ArgumentError, "The zone base must be fully qualified" end end - def insync? + # Add a directory to our list of inherited directories. + def adddir(dir) + @parent.cfg "add inherit-pkg-dir + set dir=#{dir} + end" end - def sync + # We want all specified directories to be included. + def insync? + @is == @should end - end - - newstate(:status) do - desc "The running state of the zone." - newvalue(:running) do - begin - execute("/usr/sbin/zoneadm #{@parent[:name]} boot") - rescue ExecutionFailure - self.fail "Could not stop zone: %s" % output - end - - return :zone_booted + def rmdir(dir) + @parent.cfg "remove inherit-pkg-dir{dir=#{dir}}" end - newvalue(:stopped) do - begin - execute("/usr/sbin/zoneadm #{@parent[:name]} shutdown") - rescue ExecutionFailure - self.fail "Could not stop zone: %s" % output - end + def sync + [@is, @should].sort.uniq.each do |dir| + # Skip directories that are configured and should be + next if @is.include?(dir) and @should.include?(dir) - return :zone_stopped + if @is.include?(dir) + rmdir(dir) + else + adddir(dir) + end + end end end @@ -94,18 +162,23 @@ Puppet::Type.newtype(:zone) do # Convert the output of a list into a hash def self.line2hash(line) - fields = [:id, :name, :status, :root] + fields = [:id, :name, :status, :base] 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 - %x{/usr/sbin/zoneadm list -p}.split("\n").each do |line| + %x{/usr/sbin/zoneadm list -cp}.split("\n").collect do |line| hash = line2hash(line) obj = nil @@ -114,10 +187,51 @@ Puppet::Type.newtype(:zone) do end obj.setstatus(hash) + + obj + end + end + + # Execute a configuration string. + def cfg(str) + IO.popen("/usr/sbin/zonecfg -z %s" % @parent[:name], "w") do |pipe| + pipe.puts str + end + + unless $? == 0 + raise ArgumentError, "Failed to apply configuration" + end + end + + # Perform all of our configuration steps. + def configure + # If the thing is entirely absent, then we need to create the config. + if @states[:status].is == :absent + cfg("create; set zonepath=%s" % self[:base]) + end + + # Then perform all of our configuration steps. + @states.each do |name, state| + if state.class.cfgstate? and ! state.insync? + state.sync + end end end def create + # First we must perform all of the configuration steps + + unless @parameters[:base] + raise ArgumentError, "You must provide a zone root directory." + end + + # Now do the rest of the steps. + self.configure() + + # Then we must actually install the zone + self.install() + + # And finally, boot it, if we're marked to do so. end def destroy @@ -158,8 +272,16 @@ Puppet::Type.newtype(:zone) do end end + def install + end + def retrieve - output = execute("/usr/sbin/zoneadm -z #{self[:name]} list -p") + begin + output = execute("/usr/sbin/zoneadm -z #{self[:name]} list -p") + rescue ExecutionFailure + @states[:ensure] = :absent + return + end hash = self.class.line2hash(output.chomp) setstatus(hash) |
