vagrant-mutate 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
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