Kaspar Schiess avatar Kaspar Schiess committed ddcc85f

Multiple VM definitions in a single file allowed

Comments (0)

Files changed (7)

 PATH
   remote: .
   specs:
-    mushroom (0.2.16)
+    mushroom (0.2.18)
       thor
 
 GEM
   ! Fixes default on storadm create.
   + A lot of configuration options, please see spec/fixture/etc/all.rb
   + VLAN support in nic via: syntax. Just use physical:VLAN, ie: e1000g0:2.
+  + Allows multiple VM definitions in a single Ruby file.
 
 = 0.2.10 / 25Sep12
 

lib/mushroom/dsl.rb

   #   end
   #   bar = Bar.new
   #
-  #   dsl = Mushroom::DSL.new(:foo, bar)
+  #   dsl = Mushroom::DSL::File.new
+  #   dsl.add_toplevel_target :foo, { |name| Bar.new(name) }
   #   dsl.load_file(some_file)
   #
   #   # In this example, some_file would contain something like
   #   bar.test # => 'something'
   #
   class DSL
-    def initialize(target, object)
-      @target, @object = target, object
-
-      define_singleton_method(target) { |name, &block|
-        @object.name = name
-        
-        instance_eval(&block)
-      }
-    end
-    
-    def method_missing(sym, *args, &block)
-      delegate = find_delegate_method(sym, @object)
-      return super unless delegate
+    class File
+      attr_reader :objects
       
-      if delegate.arity == args.size
-        delegate.call(*args, &block)
-      else
-        delegate.call(args, &block)
+      def initialize
+        @objects = []
+      end
+      def load_file(path)
+        eval(
+          ::File.read(path), 
+          binding, 
+          path)
+      end
+      def add_toplevel_target target, producer
+        define_singleton_method(target) { |*args, &block| 
+          object = producer.call(*args) 
+          Unit.new(object, &block)
+          
+          @objects << object
+        }
       end
     end
-    def respond_to?(sym)
-      find_delegate_method(sym, @object) || super
-    end
-    
-    def load_file(path)
-      eval(
-        File.read(path), 
-        binding, 
-        path)
-    end
-    
-  private 
-    def find_delegate_method sym, obj
-      ["#{sym}=", "add_#{sym}"].each { |dm| 
-        return obj.method(dm) if obj.respond_to? dm } 
-      nil
+    class Unit
+      def initialize(obj, &block)
+        @object = obj
+        instance_eval(&block)
+      end
+      
+      def method_missing(sym, *args, &block)
+        delegate = find_delegate_method(sym, @object)
+        return super unless delegate
+
+        if delegate.arity == args.size
+          delegate.call(*args, &block)
+        else
+          delegate.call(args, &block)
+        end
+      end
+      def respond_to?(sym)
+        find_delegate_method(sym, @object) || super
+      end
+
+    private 
+      def find_delegate_method sym, obj
+        ["#{sym}=", "add_#{sym}"].each { |dm| 
+          return obj.method(dm) if obj.respond_to? dm } 
+        nil
+      end
     end
   end
 end

lib/mushroom/vm.rb

       def all(backend=nil)
         Enumerator.new do |yielder|
           Dir[Config.etc('*.rb')].each do |vm_file|
-            vm  = VM.new(backend)
-            
-            dsl = DSL.new(:virtual_machine, vm)
+            # Load all virtual machines from the given file
+            dsl = DSL::File.new
+            dsl.add_toplevel_target :virtual_machine, lambda { |name| 
+              VM.new(backend).tap { |vm| vm.name = name } }
+              
             dsl.load_file(vm_file)
 
-            yielder << vm
+            # Yield them all in turn
+            dsl.objects.each do |vm|
+              yielder << vm
+            end
           end
         end
       end
 
 Gem::Specification.new do |s|
   s.name = 'mushroom'
-  s.version = '0.2.17'
+  s.version = '0.2.18'
 
   s.authors = ['Kaspar Schiess']
   s.email = 'kaspar.schiess@technologyastronauts.ch'

spec/acceptance/vmadm_spec.rb

     it "lists all vms" do
       invoke('list').grep(/vm1/).should_not be_nil
     end 
+    it "contains multiple vms in one file" do
+      list = invoke('list')
+      list.grep(/multi1/).should_not be_nil
+      list.grep(/multi2/).should_not be_nil
+    end 
   end
   describe 'create VM' do
     let(:config_file) { fixture_path('etc/foobar.rb') }

spec/fixture/etc/multi.rb

+virtual_machine "multi1" do
+  disk '/dev/null'
+
+  iscsi_target 'iqn.2010-01.com.mushroom:vm1', "10.0.30.1"
+end
+
+virtual_machine "multi2" do
+  disk '/dev/null'
+
+  iscsi_target 'iqn.2010-01.com.mushroom:vm1', "10.0.30.1"
+end
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.