Commits

Kaspar Schiess  committed 296843b

local device path generation

  • Participants
  • Parent commits a9237d6
  • Tags r0.2.12

Comments (0)

Files changed (6)

File Gemfile.lock

 PATH
   remote: .
   specs:
-    mushroom (0.2.10)
+    mushroom (0.2.11)
       thor
 
 GEM
 = 0.3.0
   
   + Allows controlling #ram and #cpus
+  + Automatic generation of local device path candidates if storage is 
+    available locally as well.
 
 = 0.2.10 / 25Sep12
 

File lib/mushroom/local_disk_set.rb

+module Mushroom
+
+  class LocalDiskSet
+    def self.for(name, backend)
+      output = backend.zfs :list, '-oname,mushroom:export -H'
+      candidates = output.lines.map { |l| l.chomp.strip.split }
+      candidates.reject! { |n,_| ! n }
+      
+      # Finds all mushroom storage spaces that end in '/name':
+      # Output from this step are only the spaces that match
+      storage_spaces = candidates.
+        select { |cand_name, flag| 
+          %w(true false).include?(flag) && cand_name.end_with?('/'+name) }
+
+      # Finds all disks for each of the candidate exports: 
+      # Output from this step should be <name, disks> tuples
+      storage_spaces.
+        map { |base_name, _| new(
+          base_name, 
+          candidates.map(&:first).
+            select { |name| 
+              
+              name.match(/#{Regexp.escape(base_name)}\/disk\d+/) } ) }
+    end
+    
+    def initialize(name, disks)
+      @name = name
+      @disks = disks
+    end
+    
+    attr_reader :name
+    
+    def each_disk
+      @disks.sort.each do |path|
+        yield "/dev/zvol/dsk/#{path}"
+      end
+    end
+  end
+end

File lib/mushroom/vmadm.rb

 require 'thor'
 
+require 'mushroom/local_disk_set'
+
 module Mushroom
   class Vmadm < Thor 
     def initialize(args, opts, config)
     end
     
     def vm_template(name)
+      local_disks = StringIO.new
+      
+      disk_sets = LocalDiskSet.for(name, @backend)
+      disk_sets.each do |set|
+        local_disks.puts "  # Disks for storage at #{set.name}"
+        set.each_disk do |dev_path|
+          local_disks.puts "  disk '#{dev_path}'"
+        end
+        local_disks.puts
+      end
+      
       %Q(virtual_machine "#{name}" do
   # Block device setup
+  # 
+  # Either configure a remote disk (via iSCSI):
   # iscsi_target 'iqn.2012-01.com.mushroom:#{name}', "10.0.30.1"
+  # 
+  # Or a local disk, like a zvol for example: 
+  # disk /dev/zvol/dsk/pool/#{name}/disk1
+#{local_disks.string}
 
   # Network configuration
   # nic 'eth0', 

File mushroom.gemspec

 
 Gem::Specification.new do |s|
   s.name = 'mushroom'
-  s.version = '0.2.11'
+  s.version = '0.2.12'
 
   s.authors = ['Kaspar Schiess']
   s.email = 'kaspar.schiess@technologyastronauts.ch'

File spec/acceptance/vmadm_spec.rb

 
     # Create instance
     capture(:stdout) {
-      vmadm = Mushroom::Vmadm.send(:dispatch, nil, given_args, nil, {
-        backend: backend
-      }) }.split("\n")
+      vmadm = Mushroom::Vmadm.send(:dispatch, nil, given_args, nil,
+        backend: backend) 
+      }.split("\n")
   end
 
   describe 'list' do
       FileUtils.rm_f(config_file) if File.exist?(config_file) }
     before(:each) { 
       FileUtils.rm_rf(varrun_dir) if File.directory?(varrun_dir) }
+      
+    before(:each) { 
+      backend.mapping.store(/zfs list -oname,mushroom:export -H/, '') }
     
     it "creates a configuration file template" do
       invoke 'create', 'foobar'
       
       Pathname.new(config_file).should be_file
     end 
+    context "when local pools contain a corresponding storage space" do
+      before(:each) { 
+        backend.mapping.store(
+          /zfs list -oname,mushroom:export -H/, 
+          %q(
+            pool1      -
+            pool1/foobar    true
+            pool1/foobar/disk1      true
+            pool1/foobar/disk2      true
+          )) }
+      
+      it "links the template to local zvols if possible" do
+        invoke 'create', 'foobar'
+
+        File.readlines(config_file).map(&:strip).should include(
+          "disk '/dev/zvol/dsk/pool1/foobar/disk1'")
+        File.readlines(config_file).map(&:strip).should include(
+          "disk '/dev/zvol/dsk/pool1/foobar/disk2'")
+      end 
+    end
     it "fails if the machine exists" do
       invoke 'create', 'foobar'