Signed-off-by: Martin Englund <[email protected]>
---
 lib/puppet/provider/zone/solaris.rb |   14 +++++-
 lib/puppet/type/zone.rb             |   78 ++++++++++++++++++++++------------
 spec/unit/type/zone.rb              |   13 +++++-
 3 files changed, 73 insertions(+), 32 deletions(-)

diff --git a/lib/puppet/provider/zone/solaris.rb 
b/lib/puppet/provider/zone/solaris.rb
index f33886b..1aaa70d 100644
--- a/lib/puppet/provider/zone/solaris.rb
+++ b/lib/puppet/provider/zone/solaris.rb
@@ -65,7 +65,9 @@ Puppet::Type.type(:zone).provide(:solaris) do
     end
 
     def install(dummy_argument=:work_arround_for_ruby_GC_bug)
-        if @resource[:install_args]
+        if @resource[:clone] # TODO: add support for "-s snapshot"
+            zoneadm :clone, @resource[:clone]
+        elsif @resource[:install_args]
             zoneadm :install, @resource[:install_args].split(" ")
         else
             zoneadm :install
@@ -229,7 +231,15 @@ Puppet::Type.type(:zone).provide(:solaris) do
         end
         result[:iptype] = config[:"ip-type"]
         if net = config["net"]
-            result[:ip] = net.collect { |params| "%s:%s" % [params[:physical], 
params[:address]] }
+            result[:ip] = net.collect do |params|
+                if params[:defrouter]
+                    "%s:%s:%s" % [params[:physical], params[:address], 
params[:defrouter]]
+                elsif params[:address]
+                    "%s:%s" % [params[:physical], params[:address]]
+                else
+                    params[:physical]
+                end
+            end
         end
 
         result
diff --git a/lib/puppet/type/zone.rb b/lib/puppet/type/zone.rb
index be23912..70dd3e0 100644
--- a/lib/puppet/type/zone.rb
+++ b/lib/puppet/type/zone.rb
@@ -173,7 +173,7 @@ Puppet::Type.newtype(:zone) do
                     provider.send(method)
                 else
                     raise Puppet::DevError, "Cannot move %s from %s" %
-                        [direction, st[:name]]
+                    [direction, st[:name]]
                 end
             end
 
@@ -198,6 +198,13 @@ Puppet::Type.newtype(:zone) do
             and cannot be changed."
     end
 
+    newparam(:clone) do
+        desc "Instead of installing the zone, clone it from another zone.
+          If the zone root resides on a zfs file system, a snapshot will be
+          used to create the clone, is it redisides on ufs, a copy of the zone
+          will be used. The zone you clone from must not be running."
+    end
+
     newproperty(:ip, :parent => ZoneMultiConfigProperty) do
         require 'ipaddr'
 
@@ -207,27 +214,34 @@ Puppet::Type.newtype(:zone) do
 
         # Add an interface.
         def add(str)
-            interface, ip = ipsplit(str)
-            "add net
-set address=#{ip}
-set physical=#{interface}
-end
-"
+            interface, ip, defrouter = ipsplit(str)
+            cmd = "add net\n"
+            cmd += "set physical=#{interface}\n" if interface
+            cmd += "set address=#{ip}\n" if ip
+            cmd += "set defrouter=#{defrouter}\n" if defrouter
+            #if @resource[:iptype] == :shared
+            cmd += "end\n"
         end
 
-        # Convert a string into the component interface and address
+        # Convert a string into the component interface, address and defrouter
         def ipsplit(str)
-            interface, address = str.split(':')
-            return interface, address
+            interface, address, defrouter = str.split(':')
+            return interface, address, defrouter
         end
 
         # Remove an interface.
         def rm(str)
-            interface, ip = ipsplit(str)
+            interface, ip, defrouter = ipsplit(str)
             # Reality seems to disagree with the documentation here; the docs
             # specify that braces are required, but they're apparently only
             # required if you're specifying multiple values.
-            "remove net address=#{ip}"
+            if ip
+                "remove net address=#{ip}"
+            elsif interface
+                "remove net interface=#{interface}"
+            else
+                raise ArgumentError, "can not remove network based on default 
router"
+            end
         end
     end
 
@@ -236,8 +250,8 @@ end
 
         defaultto :shared
 
-       newvalue :shared
-       newvalue :exclusive
+        newvalue :shared
+        newvalue :exclusive
 
         def configtext
             "set ip-type=#{self.should}"
@@ -378,23 +392,32 @@ end
         end
     end
 
+    def validate_ip(ip, name)
+        begin
+            IPAddr.new(ip) if ip
+        rescue ArgumentError
+            self.fail "'%s' is an invalid %s" % [ip, name]
+        end
+    end
+
     validate do
         value = self[:ip]
-       if self[:iptype] == :exclusive
-           self.fail "ip must only contain interface name" if value =~ /:/
-       elsif value
-           self.fail "ip must contain interface name and ip address separated 
by a \":\"" unless value =~ /:/
-           interface, address = value.split(':')
-           begin
-                IPAddr.new(address)
-            rescue ArgumentError
-                self.fail "'%s' is an invalid IP address" % address
+        interface, address, defrouter = value.split(':')
+        if self[:iptype] == :shared
+            if (interface && address && defrouter.nil?) ||
+               (interface && address && defrouter)
+               validate_ip(address, "IP address")
+               validate_ip(defrouter, "default router")
+            else
+                self.fail "ip must contain interface name and ip address 
separated by a \":\""
+            end
+        else
+            unless interface && address.nil? && defrouter.nil?
+                self.fail "only interface may be specified when using 
exclusive IP stack: %s" % value
             end
-       end
+        end
 
-       unless self[:path]
-           self.fail "zone path is required"
-       end
+        self.fail "zone path is required" unless self[:path]
     end
 
     def retrieve
@@ -429,4 +452,3 @@ end
         return prophash
     end
 end
-
diff --git a/spec/unit/type/zone.rb b/spec/unit/type/zone.rb
index 6744b09..679141e 100755
--- a/spec/unit/type/zone.rb
+++ b/spec/unit/type/zone.rb
@@ -42,11 +42,20 @@ describe zone do
            :iptype => :exclusive) }.should raise_error
     end
 
-    it "should be valid when :iptype is :shared" do
+    it "should be invalid when :ip has two \":\" and iptype is :exclusive" do
+        lambda { zone.new(:name => "dummy", :ip => "if:1.2.3.4:2.3.4.5",
+           :iptype => :exclusive) }.should raise_error
+    end
+
+    it "should be valid when :iptype is :shared and using interface and ip" do
         zone.new(:name => "dummy", :path => "/dummy", :ip => "if:1.2.3.4")
     end
 
-    it "should be valid when :iptype is :exclusive" do
+    it "should be valid when :iptype is :shared and using interface, ip and 
default route" do
+        zone.new(:name => "dummy", :path => "/dummy", :ip => 
"if:1.2.3.4:2.3.4.5")
+    end
+
+    it "should be valid when :iptype is :exclusive and using interface" do
         zone.new(:name => "dummy", :path => "/dummy", :ip => "if",
            :iptype => :exclusive)
     end
-- 
1.6.4.4

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to