vagrant-mutate 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ # 0.1.4 (2013-12-08)
2
+ * Rework box and converter implementation (#7)
3
+ * Write disk images as sparse files (#13)
4
+ * Switch vagrant-kvm disk format from raw to qcow2 (#16)
5
+ * Prefer the binary named qemu-system-* over qemu-kvm or kvm (#20)
6
+
1
7
  # 0.1.3 (2013-12-03)
2
8
 
3
9
  * Add support for vagrant-kvm (#12)
@@ -0,0 +1,27 @@
1
+ module VagrantMutate
2
+ module Box
3
+ class Box
4
+
5
+ attr_reader :name, :dir, :provider_name, :supported_input, :supported_output, :image_format, :image_name
6
+
7
+ def initialize(env, name, dir)
8
+ @env = env
9
+ @name = name
10
+ @dir = dir
11
+ @logger = Log4r::Logger.new('vagrant::mutate')
12
+ end
13
+
14
+ def virtual_size
15
+ input_file = File.join( @dir, @image_name )
16
+ info = `qemu-img info #{input_file}`
17
+ @logger.debug "qemu-img info output\n#{info}"
18
+ if info =~ /(\d+) bytes/
19
+ return $1
20
+ else
21
+ raise Errors::DetermineImageSizeFailed
22
+ end
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,18 @@
1
+ require_relative 'box'
2
+
3
+ module VagrantMutate
4
+ module Box
5
+ class Kvm < Box
6
+
7
+ def initialize(env, name, dir)
8
+ super
9
+ @provider_name = 'kvm'
10
+ @supported_input = false,
11
+ @supported_output = true,
12
+ @image_format = 'qcow2',
13
+ @image_name = 'box-disk1.img'
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ require_relative 'box'
2
+
3
+ module VagrantMutate
4
+ module Box
5
+ class Libvirt < Box
6
+
7
+ def initialize(env, name, dir)
8
+ super
9
+ @provider_name = 'libvirt'
10
+ @supported_input = false,
11
+ @supported_output = true,
12
+ @image_format = 'qcow2',
13
+ @image_name = 'box.img'
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -1,19 +1,17 @@
1
1
  require "rexml/document"
2
+ require_relative 'box'
2
3
 
3
4
  module VagrantMutate
4
- module Provider
5
+ module Box
6
+ class Virtualbox < Box
5
7
 
6
- class Virtualbox < Provider
7
- def initialize(box)
8
- @box = box
9
- @name = 'virtualbox'
10
- @supported_input = true,
11
- @supported_output = false,
12
- @image_format = 'vmdk',
13
- @image_name = 'box-disk1.vmdk'
14
-
15
- definition = File.read( File.join( box.dir, 'box.ovf') )
16
- @ovf = REXML::Document.new(definition)
8
+ def initialize(env, name, dir)
9
+ super
10
+ @provider_name = 'virtualbox'
11
+ @supported_input = true,
12
+ @supported_output = false,
13
+ @image_format = 'vmdk',
14
+ @image_name = 'box-disk1.vmdk'
17
15
  end
18
16
 
19
17
  # the architecture is not defined in the ovf file,
@@ -28,7 +26,7 @@ module VagrantMutate
28
26
 
29
27
  # use mac from the first enabled nic
30
28
  def mac_address
31
- @ovf.elements.each("//vbox:Machine/Hardware//Adapter") do |ele|
29
+ ovf.elements.each("//vbox:Machine/Hardware//Adapter") do |ele|
32
30
  if ele.attributes['enabled'] == 'true'
33
31
  mac = ele.attributes['MACAddress']
34
32
  # convert to more standarad format with colons
@@ -40,7 +38,7 @@ module VagrantMutate
40
38
  end
41
39
 
42
40
  def cpus
43
- @ovf.elements.each("//VirtualHardwareSection/Item") do |device|
41
+ ovf.elements.each("//VirtualHardwareSection/Item") do |device|
44
42
  if device.elements["rasd:ResourceType"].text == '3'
45
43
  return device.elements["rasd:VirtualQuantity"].text
46
44
  end
@@ -48,7 +46,7 @@ module VagrantMutate
48
46
  end
49
47
 
50
48
  def memory
51
- @ovf.elements.each("//VirtualHardwareSection/Item") do |device|
49
+ ovf.elements.each("//VirtualHardwareSection/Item") do |device|
52
50
  if device.elements["rasd:ResourceType"].text == '4'
53
51
  return size_in_bytes(device.elements["rasd:VirtualQuantity"].text,
54
52
  device.elements["rasd:AllocationUnits"].text)
@@ -58,6 +56,10 @@ module VagrantMutate
58
56
 
59
57
  private
60
58
 
59
+ def ovf
60
+ @ovf ||= REXML::Document.new( File.read( File.join( @dir, 'box.ovf') ) )
61
+ end
62
+
61
63
  # Takes a quantity and a unit
62
64
  # returns quantity in bytes
63
65
  # mib = true to use mebibytes, etc
@@ -99,4 +101,3 @@ module VagrantMutate
99
101
 
100
102
  end
101
103
  end
102
-
@@ -4,73 +4,80 @@ require 'json'
4
4
  require 'zlib'
5
5
 
6
6
  module VagrantMutate
7
- class Box
7
+ class BoxLoader
8
8
 
9
9
  include Archive::Tar
10
10
 
11
- attr_reader :dir, :name, :provider
12
-
13
11
  def initialize( env )
14
12
  @env = env
15
13
  @logger = Log4r::Logger.new('vagrant::mutate')
14
+ @tmp_dir = nil
15
+ end
16
+
17
+ def create_box(provider_name, name, dir)
18
+ @logger.info "Creating box #{name} with provider #{provider_name} in #{dir}"
19
+ case provider_name
20
+ when 'kvm'
21
+ require_relative 'box/kvm'
22
+ Box::Kvm.new(@env, name, dir)
23
+ when 'libvirt'
24
+ require_relative 'box/libvirt'
25
+ Box::Libvirt.new(@env, name, dir)
26
+ when 'virtualbox'
27
+ require_relative 'box/virtualbox'
28
+ Box::Virtualbox.new(@env, name, dir)
29
+ else
30
+ raise Errors::ProviderNotSupported, :provider => provider_name, :direction => 'input or output'
31
+ end
16
32
  end
17
33
 
18
- def prepare_for_output( box_name, provider_name )
19
- @logger.info "Preparing #{box_name} for output as #{provider_name}"
20
- @name = box_name
21
- @provider = Provider::Provider.create( provider_name, self )
22
- @dir = create_output_dir()
23
- @dir_is_tmp = false
34
+ def prepare_for_output(name, provider_name)
35
+ @logger.info "Preparing #{name} for output as #{provider_name}"
36
+ dir = create_output_dir(name, provider_name)
37
+ box = create_box(provider_name, name, dir)
24
38
 
25
- unless @provider.supported_output
39
+ unless box.supported_output
26
40
  raise Errors::ProviderNotSupported, :provider => provider_name, :direction => 'output'
27
41
  end
42
+
43
+ return box
28
44
  end
29
45
 
30
46
  def load_from_file(file)
31
47
  @logger.info "Loading box from file #{file}"
32
- @name = File.basename( file, File.extname(file) )
33
- @dir = unpack(file)
34
- @dir_is_tmp = true
35
- @provider = determine_provider()
48
+ name = File.basename( file, File.extname(file) )
49
+ dir = unpack(file)
50
+ @tmp_dir = dir
51
+ provider_name = determine_provider(dir)
52
+ box = create_box(provider_name, name, dir)
36
53
 
37
- unless @provider.supported_input
54
+ unless box.supported_input
38
55
  raise Errors::ProviderNotSupported, :provider => provider_name, :direction => 'input'
39
56
  end
57
+
58
+ return box
40
59
  end
41
60
 
42
61
  def load_by_name(name)
43
62
  @logger.info "Loading box from name #{name}"
44
- @name = name
63
+ dir = find_input_dir(name)
45
64
  # cheat for now since only supported input is virtualbox
46
- @provider = Provider::Provider.create('virtualbox', self)
47
- @dir = find_input_dir()
48
- @dir_is_tmp = false
65
+ box = create_box('virtualbox', name, dir)
66
+ return box
49
67
  end
50
68
 
51
69
  def cleanup
52
- if @dir_is_tmp
70
+ if @tmp_dir
53
71
  @env.ui.info "Cleaning up temporary files."
54
- @logger.info "Deleting #{dir}"
55
- FileUtils.remove_entry_secure(@dir)
56
- end
57
- end
58
-
59
- def virtual_size
60
- input_file = File.join( @dir, @provider.image_name )
61
- info = `qemu-img info #{input_file}`
62
- @logger.debug "qemu-img info output\n#{info}"
63
- if info =~ /(\d+) bytes/
64
- return $1
65
- else
66
- raise Errors::DetermineImageSizeFailed
72
+ @logger.info "Deleting #{@tmp_dir}"
73
+ FileUtils.remove_entry_secure(@tmp_dir)
67
74
  end
68
75
  end
69
76
 
70
77
  private
71
78
 
72
- def determine_provider
73
- metadata_file = File.join(@dir, 'metadata.json')
79
+ def determine_provider(dir)
80
+ metadata_file = File.join(dir, 'metadata.json')
74
81
  if File.exists? metadata_file
75
82
  begin
76
83
  metadata = JSON.load( File.new( metadata_file, 'r') )
@@ -78,15 +85,16 @@ module VagrantMutate
78
85
  raise Errors::DetermineProviderFailed, :error_message => e.message
79
86
  end
80
87
  @logger.info "Determined input provider is #{metadata['provider']}"
81
- return Provider::Provider.create( metadata['provider'], self )
88
+ return metadata['provider']
82
89
  else
83
90
  @logger.info "No metadata found, so assuming input provider is virtualbox"
84
- return Provider::Provider.create('virtualbox', self)
91
+ return 'virtualbox'
85
92
  end
86
93
  end
87
94
 
88
- def find_input_dir
89
- in_dir = File.join( @env.boxes_path, @name, 'virtualbox' )
95
+ def find_input_dir(name)
96
+ # cheat for now since only supported input is virtualbox
97
+ in_dir = File.join( @env.boxes_path, name, 'virtualbox' )
90
98
  if File.directory?(in_dir)
91
99
  @logger.info "Found input directory #{in_dir}"
92
100
  return in_dir
@@ -95,9 +103,9 @@ module VagrantMutate
95
103
  end
96
104
  end
97
105
 
98
- def create_output_dir
106
+ def create_output_dir(name, provider_name)
99
107
  # e.g. $HOME/.vagrant.d/boxes/fedora-19/libvirt
100
- out_dir = File.join( @env.boxes_path, @name, @provider.name )
108
+ out_dir = File.join( @env.boxes_path, name, provider_name )
101
109
  begin
102
110
  FileUtils.mkdir_p(out_dir)
103
111
  rescue => e
@@ -0,0 +1,136 @@
1
+ require 'fileutils'
2
+
3
+ module VagrantMutate
4
+ module Converter
5
+ class Converter
6
+
7
+ def self.create(env, input_box, output_box)
8
+ case output_box.provider_name
9
+ when 'kvm'
10
+ require_relative 'kvm'
11
+ Kvm.new(env, input_box, output_box)
12
+ when 'libvirt'
13
+ require_relative 'libvirt'
14
+ Libvirt.new(env, input_box, output_box)
15
+ else
16
+ raise Errors::ProviderNotSupported, :provider => output_box.provider_name, :direction => 'output'
17
+ end
18
+ end
19
+
20
+ def initialize(env, input_box, output_box)
21
+ @env = env
22
+ @input_box = input_box
23
+ @output_box = output_box
24
+ @logger = Log4r::Logger.new('vagrant::mutate')
25
+ verify_qemu_installed
26
+ verify_qemu_version
27
+ end
28
+
29
+ def convert()
30
+ @env.ui.info "Converting #{@input_box.name} from #{@input_box.provider_name} "\
31
+ "to #{@output_box.provider_name}."
32
+
33
+ write_metadata
34
+ copy_vagrantfile
35
+ write_specific_files
36
+ write_disk
37
+ end
38
+
39
+ private
40
+
41
+ # http://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby
42
+ def verify_qemu_installed
43
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
44
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
45
+ exts.each do |ext|
46
+ exe = File.join(path, "qemu-img#{ext}")
47
+ if File.executable? exe
48
+ @logger.info "Found qemu"
49
+ return
50
+ end
51
+ end
52
+ end
53
+ # if we make it here qemu-img command was not found
54
+ raise Errors::QemuNotFound
55
+ end
56
+
57
+ def verify_qemu_version
58
+ usage = `qemu-img`
59
+ if usage =~ /(\d+\.\d+\.\d+)/
60
+ recommended_version = Gem::Version.new('1.2.0')
61
+ installed_version = Gem::Version.new($1)
62
+ if installed_version < recommended_version
63
+ @env.ui.warn "You have qemu #{installed_version} installed. "\
64
+ "This version is too old to read some virtualbox boxes. "\
65
+ "If conversion fails, try upgrading to qemu 1.2.0 or newer."
66
+ end
67
+ else
68
+ raise Errors::ParseQemuVersionFailed
69
+ end
70
+ end
71
+
72
+
73
+ def write_metadata
74
+ metadata = generate_metadata
75
+ begin
76
+ File.open( File.join( @output_box.dir, 'metadata.json'), 'w') do |f|
77
+ f.write( JSON.generate(metadata) )
78
+ end
79
+ rescue => e
80
+ raise Errors::WriteMetadataFailed, :error_message => e.message
81
+ end
82
+ @logger.info "Wrote metadata"
83
+ end
84
+
85
+ def copy_vagrantfile
86
+ input = File.join( @input_box.dir, 'Vagrantfile' )
87
+ if File.exists? input
88
+ output = File.join( @output_box.dir, 'Vagrantfile' )
89
+ @logger.info "Copying #{input} to #{output}"
90
+ begin
91
+ FileUtils.copy_file(input, output)
92
+ rescue => e
93
+ raise Errors::WriteVagrantfileFailed, :error_message => e.message
94
+ end
95
+ end
96
+ end
97
+
98
+ def write_disk
99
+ if @input_box.image_format == @output_box.image_format
100
+ copy_disk
101
+ else
102
+ convert_disk
103
+ end
104
+ end
105
+
106
+ def copy_disk
107
+ input = File.join( @input_box.dir, @input_box.image_name )
108
+ output = File.join( @output_box.dir, @output_box.image_name )
109
+ @logger.info "Copying #{input} to #{output}"
110
+ begin
111
+ FileUtils.copy_file(input, output)
112
+ rescue => e
113
+ raise Errors::WriteDiskFailed, :error_message => e.message
114
+ end
115
+ end
116
+
117
+ def convert_disk
118
+ input_file = File.join( @input_box.dir, @input_box.image_name )
119
+ output_file = File.join( @output_box.dir, @output_box.image_name )
120
+ input_format = @input_box.image_format
121
+ output_format = @output_box.image_format
122
+
123
+ # p for progress bar
124
+ # S for sparse file
125
+ qemu_options = '-p -S 16k'
126
+
127
+ command = "qemu-img convert #{qemu_options} -f #{input_format} -O #{output_format} #{input_file} #{output_file}"
128
+ @logger.info "Running #{command}"
129
+ unless system(command)
130
+ raise Errors::WriteDiskFailed, :error_message => "qemu-img exited with status #{$?.exitstatus}"
131
+ end
132
+ end
133
+
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,53 @@
1
+ require 'erb'
2
+
3
+ module VagrantMutate
4
+ module Converter
5
+ class Kvm < Converter
6
+
7
+ def generate_metadata
8
+ metadata = {
9
+ 'provider' => @output_box.provider_name,
10
+ }
11
+ end
12
+
13
+ def write_specific_files
14
+ template_path = VagrantMutate.source_root.join('templates', 'kvm', 'box.xml.erb')
15
+ template = File.read(template_path)
16
+
17
+ uuid = nil
18
+ gui = true
19
+ disk_bus = 'virtio'
20
+
21
+ image_type = @output_box.image_format
22
+ disk = @output_box.image_name
23
+
24
+ name = @input_box.name
25
+ memory = @input_box.memory / 1024 # convert bytes to kib
26
+ cpus = @input_box.cpus
27
+ mac = @input_box.mac_address
28
+ arch = @input_box.architecture
29
+
30
+ qemu_bin = find_kvm
31
+
32
+ File.open( File.join( @output_box.dir, 'box.xml'), 'w') do |f|
33
+ f.write( ERB.new(template).result(binding) )
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def find_kvm
40
+ qemu_bin_list = [ '/usr/bin/qemu-system-x86_64',
41
+ '/usr/bin/qemu-system-i386',
42
+ '/usr/bin/qemu-kvm',
43
+ '/usr/bin/kvm' ]
44
+ qemu_bin = qemu_bin_list.detect { |binary| File.exists? binary }
45
+ unless qemu_bin
46
+ raise Errors::QemuNotFound
47
+ end
48
+ return qemu_bin
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,19 @@
1
+ module VagrantMutate
2
+ module Converter
3
+ class Libvirt < Converter
4
+
5
+ def generate_metadata
6
+ metadata = {
7
+ 'provider' => @output_box.provider_name,
8
+ 'format' => @output_box.image_format,
9
+ 'virtual_size' => ( @input_box.virtual_size.to_f / (1024 * 1024 * 1024) ).ceil
10
+ }
11
+ end
12
+
13
+ def write_specific_files
14
+ # nothing to do here
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -1,6 +1,5 @@
1
- require 'vagrant-mutate/box'
2
- require 'vagrant-mutate/converter'
3
- require 'vagrant-mutate/provider/provider'
1
+ require 'vagrant-mutate/box_loader'
2
+ require 'vagrant-mutate/converter/converter'
4
3
 
5
4
  module VagrantMutate
6
5
 
@@ -21,23 +20,23 @@ module VagrantMutate
21
20
  box_arg = argv[0]
22
21
  output_provider_arg = argv[1]
23
22
 
24
- converter = Converter.new(@env)
25
- input_box = Box.new(@env)
26
- output_box = Box.new(@env)
23
+ input_loader = BoxLoader.new(@env)
24
+ output_loader = BoxLoader.new(@env)
27
25
 
28
26
  if box_arg =~ /\.box$/
29
- input_box.load_from_file(box_arg)
27
+ input_box = input_loader.load_from_file(box_arg)
30
28
  else
31
- input_box.load_by_name(box_arg)
29
+ input_box = input_loader.load_by_name(box_arg)
32
30
  end
33
31
 
34
- output_box.prepare_for_output( input_box.name, output_provider_arg)
32
+ output_box = output_loader.prepare_for_output( input_box.name, output_provider_arg)
35
33
 
36
- converter.convert(input_box, output_box)
34
+ converter = Converter::Converter.create(@env, input_box, output_box)
35
+ converter.convert
37
36
 
38
- input_box.cleanup
37
+ input_loader.cleanup
39
38
 
40
- @env.ui.info "The box #{output_box.name} (#{output_box.provider.name}) is now ready to use."
39
+ @env.ui.info "The box #{output_box.name} (#{output_box.provider_name}) is now ready to use."
41
40
 
42
41
  end
43
42
 
@@ -1,3 +1,3 @@
1
1
  module VagrantMutate
2
- VERSION = '0.1.3'
2
+ VERSION = '0.1.4'
3
3
  end
@@ -18,9 +18,9 @@
18
18
  <on_reboot>restart</on_reboot>
19
19
  <on_crash>restart</on_crash>
20
20
  <devices>
21
- <emulator>/usr/bin/kvm</emulator>
21
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
22
22
  <disk type='file' device='disk'>
23
- <driver name='qemu' type='raw'/>
23
+ <driver name='qemu' type='qcow2'/>
24
24
  <source file='box-disk1.img'/>
25
25
  <target dev='vda' bus='virtio'/>
26
26
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-mutate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-12-03 00:00:00.000000000 Z
12
+ date: 2013-12-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: archive-tar-minitar
@@ -73,14 +73,16 @@ files:
73
73
  - README.md
74
74
  - Rakefile
75
75
  - lib/vagrant-mutate.rb
76
- - lib/vagrant-mutate/box.rb
77
- - lib/vagrant-mutate/converter.rb
76
+ - lib/vagrant-mutate/box/box.rb
77
+ - lib/vagrant-mutate/box/kvm.rb
78
+ - lib/vagrant-mutate/box/libvirt.rb
79
+ - lib/vagrant-mutate/box/virtualbox.rb
80
+ - lib/vagrant-mutate/box_loader.rb
81
+ - lib/vagrant-mutate/converter/converter.rb
82
+ - lib/vagrant-mutate/converter/kvm.rb
83
+ - lib/vagrant-mutate/converter/libvirt.rb
78
84
  - lib/vagrant-mutate/errors.rb
79
85
  - lib/vagrant-mutate/mutate.rb
80
- - lib/vagrant-mutate/provider/kvm.rb
81
- - lib/vagrant-mutate/provider/libvirt.rb
82
- - lib/vagrant-mutate/provider/provider.rb
83
- - lib/vagrant-mutate/provider/virtualbox.rb
84
86
  - lib/vagrant-mutate/version.rb
85
87
  - locales/en.yml
86
88
  - templates/kvm/box.xml.erb
@@ -1,119 +0,0 @@
1
- require 'fileutils'
2
-
3
- module VagrantMutate
4
- class Converter
5
-
6
- def initialize(env)
7
- @env = env
8
- @logger = Log4r::Logger.new('vagrant::mutate')
9
- verify_qemu_installed
10
- verify_qemu_version
11
- end
12
-
13
- def convert(input_box, output_box)
14
- @input_box = input_box
15
- @output_box = output_box
16
-
17
- @env.ui.info "Converting #{input_box.name} from #{input_box.provider.name} "\
18
- "to #{output_box.provider.name}."
19
-
20
- write_metadata
21
- # will have to rethink this if any providers need to alter the vagrantfile
22
- copy_vagrantfile
23
- output_box.provider.write_specific_files(input_box)
24
- write_disk
25
- end
26
-
27
- private
28
-
29
- # http://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby
30
- def verify_qemu_installed
31
- exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
32
- ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
33
- exts.each do |ext|
34
- exe = File.join(path, "qemu-img#{ext}")
35
- if File.executable? exe
36
- @logger.info "Found qemu"
37
- return
38
- end
39
- end
40
- end
41
- # if we make it here qemu-img command was not found
42
- raise Errors::QemuNotFound
43
- end
44
-
45
- def verify_qemu_version
46
- usage = `qemu-img`
47
- if usage =~ /(\d+\.\d+\.\d+)/
48
- recommended_version = Gem::Version.new('1.2.0')
49
- installed_version = Gem::Version.new($1)
50
- if installed_version < recommended_version
51
- @env.ui.warn "You have qemu #{installed_version} installed. "\
52
- "This version is too old to read some virtualbox boxes. "\
53
- "If conversion fails, try upgrading to qemu 1.2.0 or newer."
54
- end
55
- else
56
- raise Errors::ParseQemuVersionFailed
57
- end
58
- end
59
-
60
-
61
- def write_metadata
62
- metadata = @output_box.provider.generate_metadata(@input_box)
63
- begin
64
- File.open( File.join( @output_box.dir, 'metadata.json'), 'w') do |f|
65
- f.write( JSON.generate(metadata) )
66
- end
67
- rescue => e
68
- raise Errors::WriteMetadataFailed, :error_message => e.message
69
- end
70
- @logger.info "Wrote metadata"
71
- end
72
-
73
- def copy_vagrantfile
74
- input = File.join( @input_box.dir, 'Vagrantfile' )
75
- if File.exists? input
76
- output = File.join( @output_box.dir, 'Vagrantfile' )
77
- @logger.info "Copying #{input} to #{output}"
78
- begin
79
- FileUtils.copy_file(input, output)
80
- rescue => e
81
- raise Errors::WriteVagrantfileFailed, :error_message => e.message
82
- end
83
- end
84
- end
85
-
86
- def write_disk
87
- if @input_box.provider.image_format == @output_box.provider.image_format
88
- copy_disk
89
- else
90
- convert_disk
91
- end
92
- end
93
-
94
- def copy_disk
95
- input = File.join( @input_box.dir, @input_box.provider.image_name )
96
- output = File.join( @output_box.dir, @output_box.provider.image_name )
97
- @logger.info "Copying #{input} to #{output}"
98
- begin
99
- FileUtils.copy_file(input, output)
100
- rescue => e
101
- raise Errors::WriteDiskFailed, :error_message => e.message
102
- end
103
- end
104
-
105
- def convert_disk
106
- input_file = File.join( @input_box.dir, @input_box.provider.image_name )
107
- output_file = File.join( @output_box.dir, @output_box.provider.image_name )
108
- input_format = @input_box.provider.image_format
109
- output_format = @output_box.provider.image_format
110
-
111
- command = "qemu-img convert -p -f #{input_format} -O #{output_format} #{input_file} #{output_file}"
112
- @logger.info "Running #{command}"
113
- unless system(command)
114
- raise Errors::WriteDiskFailed, :error_message => "qemu-img exited with status #{$?.exitstatus}"
115
- end
116
- end
117
-
118
- end
119
- end
@@ -1,57 +0,0 @@
1
- require 'erb'
2
-
3
- module VagrantMutate
4
- module Provider
5
- class Kvm < Provider
6
- def initialize(box)
7
- @box = box
8
- @name = 'kvm'
9
- @supported_input = false,
10
- @supported_output = true,
11
- @image_format = 'raw',
12
- @image_name = 'box-disk1.img'
13
- end
14
-
15
- def generate_metadata(input_box)
16
- metadata = {
17
- 'provider' => @box.provider.name,
18
- }
19
- end
20
-
21
- def write_specific_files(input_box)
22
- template_path = VagrantMutate.source_root.join('templates', 'kvm', 'box.xml.erb')
23
- template = File.read(template_path)
24
-
25
- uuid = nil
26
- gui = true
27
- disk_bus = 'virtio'
28
- name = input_box.name
29
- image_type = @image_format
30
- disk = @image_name
31
- qemu_bin = find_kvm
32
- memory = input_box.provider.memory / 1024 # convert bytes to kib
33
- cpus = input_box.provider.cpus
34
- mac = input_box.provider.mac_address
35
- arch = input_box.provider.architecture
36
-
37
- File.open( File.join( @box.dir, 'box.xml'), 'w') do |f|
38
- f.write( ERB.new(template).result(binding) )
39
- end
40
- end
41
-
42
- private
43
-
44
- def find_kvm
45
- qemu_bin_list = [ '/usr/bin/qemu-kvm', '/usr/bin/kvm',
46
- '/usr/bin/qemu-system-x86_64',
47
- '/usr/bin/qemu-system-i386' ]
48
- qemu_bin = qemu_bin_list.detect { |binary| File.exists? binary }
49
- unless qemu_bin
50
- raise Errors::QemuNotFound
51
- end
52
- return qemu_bin
53
- end
54
-
55
- end
56
- end
57
- end
@@ -1,27 +0,0 @@
1
- module VagrantMutate
2
- module Provider
3
- class Libvirt < Provider
4
- def initialize(box)
5
- @box = box
6
- @name = 'libvirt'
7
- @supported_input = false,
8
- @supported_output = true,
9
- @image_format = 'qcow2',
10
- @image_name = 'box.img'
11
- end
12
-
13
- def generate_metadata(input_box)
14
- metadata = {
15
- 'provider' => @box.provider.name,
16
- 'format' => 'qcow2',
17
- 'virtual_size' => ( input_box.virtual_size.to_f / (1024 * 1024 * 1024) ).ceil
18
- }
19
- end
20
-
21
- def write_specific_files(input_box)
22
- # nothing to do here
23
- end
24
-
25
- end
26
- end
27
- end
@@ -1,24 +0,0 @@
1
- module VagrantMutate
2
- module Provider
3
- class Provider
4
- attr_reader :name, :supported_input, :supported_output, :image_format, :image_name
5
-
6
- def self.create(name, box)
7
- case name
8
- when 'kvm'
9
- require_relative 'kvm'
10
- Kvm.new(box)
11
- when 'libvirt'
12
- require_relative 'libvirt'
13
- Libvirt.new(box)
14
- when 'virtualbox'
15
- require_relative 'virtualbox'
16
- Virtualbox.new(box)
17
- else
18
- raise Errors::ProviderNotSupported, :provider => name, :direction => 'input or output'
19
- end
20
- end
21
-
22
- end
23
- end
24
- end