vagrant-libvirt 0.0.45 → 0.4.0

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.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +542 -167
  3. data/lib/vagrant-libvirt/action.rb +2 -2
  4. data/lib/vagrant-libvirt/action/create_domain.rb +112 -42
  5. data/lib/vagrant-libvirt/action/create_domain_volume.rb +14 -10
  6. data/lib/vagrant-libvirt/action/create_network_interfaces.rb +8 -5
  7. data/lib/vagrant-libvirt/action/create_networks.rb +2 -2
  8. data/lib/vagrant-libvirt/action/destroy_domain.rb +1 -1
  9. data/lib/vagrant-libvirt/action/forward_ports.rb +10 -8
  10. data/lib/vagrant-libvirt/action/halt_domain.rb +1 -1
  11. data/lib/vagrant-libvirt/action/handle_box_image.rb +28 -60
  12. data/lib/vagrant-libvirt/action/handle_storage_pool.rb +4 -4
  13. data/lib/vagrant-libvirt/action/package_domain.rb +64 -12
  14. data/lib/vagrant-libvirt/action/prepare_nfs_settings.rb +3 -9
  15. data/lib/vagrant-libvirt/action/prune_nfs_exports.rb +19 -9
  16. data/lib/vagrant-libvirt/action/remove_libvirt_image.rb +2 -2
  17. data/lib/vagrant-libvirt/action/remove_stale_volume.rb +17 -11
  18. data/lib/vagrant-libvirt/action/set_boot_order.rb +2 -2
  19. data/lib/vagrant-libvirt/action/set_name_of_domain.rb +6 -9
  20. data/lib/vagrant-libvirt/action/start_domain.rb +87 -30
  21. data/lib/vagrant-libvirt/action/wait_till_up.rb +10 -32
  22. data/lib/vagrant-libvirt/cap/public_address.rb +16 -0
  23. data/lib/vagrant-libvirt/cap/synced_folder.rb +3 -3
  24. data/lib/vagrant-libvirt/config.rb +294 -42
  25. data/lib/vagrant-libvirt/driver.rb +49 -34
  26. data/lib/vagrant-libvirt/errors.rb +5 -5
  27. data/lib/vagrant-libvirt/plugin.rb +7 -2
  28. data/lib/vagrant-libvirt/provider.rb +2 -9
  29. data/lib/vagrant-libvirt/templates/domain.xml.erb +52 -10
  30. data/lib/vagrant-libvirt/templates/public_interface.xml.erb +5 -1
  31. data/lib/vagrant-libvirt/util.rb +1 -0
  32. data/lib/vagrant-libvirt/util/erb_template.rb +6 -7
  33. data/lib/vagrant-libvirt/util/network_util.rb +6 -1
  34. data/lib/vagrant-libvirt/util/nfs.rb +17 -0
  35. data/lib/vagrant-libvirt/util/ui.rb +23 -0
  36. data/lib/vagrant-libvirt/version +1 -0
  37. data/lib/vagrant-libvirt/version.rb +72 -1
  38. data/locales/en.yml +6 -6
  39. data/spec/spec_helper.rb +28 -2
  40. data/spec/support/libvirt_context.rb +3 -1
  41. data/spec/support/sharedcontext.rb +7 -3
  42. data/spec/unit/action/create_domain_spec.rb +160 -0
  43. data/spec/unit/action/create_domain_spec/default_system_storage_pool.xml +17 -0
  44. data/spec/unit/action/create_domain_spec/default_user_storage_pool.xml +17 -0
  45. data/spec/unit/action/destroy_domain_spec.rb +2 -2
  46. data/spec/unit/action/set_name_of_domain_spec.rb +3 -3
  47. data/spec/unit/action/start_domain_spec.rb +231 -0
  48. data/spec/unit/action/start_domain_spec/clock_timer_rtc.xml +50 -0
  49. data/spec/unit/action/start_domain_spec/default.xml +48 -0
  50. data/spec/unit/action/start_domain_spec/default_added_tpm_path.xml +48 -0
  51. data/spec/unit/action/start_domain_spec/default_added_tpm_version.xml +48 -0
  52. data/spec/unit/action/wait_till_up_spec.rb +14 -9
  53. data/spec/unit/config_spec.rb +438 -0
  54. data/spec/unit/provider_spec.rb +11 -0
  55. data/spec/unit/templates/domain_all_settings.xml +20 -5
  56. data/spec/unit/templates/domain_custom_cpu_model.xml +4 -1
  57. data/spec/unit/templates/domain_defaults.xml +4 -1
  58. data/spec/unit/templates/domain_spec.rb +92 -4
  59. data/spec/unit/templates/tpm/version_1.2.xml +54 -0
  60. data/spec/unit/templates/tpm/version_2.0.xml +53 -0
  61. metadata +91 -36
  62. data/.coveralls.yml +0 -1
  63. data/.github/issue_template.md +0 -37
  64. data/.gitignore +0 -21
  65. data/.travis.yml +0 -24
  66. data/Gemfile +0 -26
  67. data/Rakefile +0 -8
  68. data/example_box/README.md +0 -29
  69. data/example_box/Vagrantfile +0 -60
  70. data/example_box/metadata.json +0 -5
  71. data/lib/vagrant-libvirt/templates/default_storage_volume.xml.erb +0 -14
  72. data/tools/create_box.sh +0 -130
  73. data/tools/prepare_redhat_for_box.sh +0 -119
  74. data/vagrant-libvirt.gemspec +0 -51
@@ -19,7 +19,7 @@ module VagrantPlugins
19
19
  begin
20
20
  env[:machine].guest.capability(:halt)
21
21
  rescue
22
- @logger.info('Trying libvirt graceful shutdown.')
22
+ @logger.info('Trying Libvirt graceful shutdown.')
23
23
  domain.shutdown
24
24
  end
25
25
 
@@ -4,8 +4,8 @@ module VagrantPlugins
4
4
  module ProviderLibvirt
5
5
  module Action
6
6
  class HandleBoxImage
7
- include VagrantPlugins::ProviderLibvirt::Util::ErbTemplate
8
7
  include VagrantPlugins::ProviderLibvirt::Util::StorageUtil
8
+ include VagrantPlugins::ProviderLibvirt::Util::Ui
9
9
 
10
10
 
11
11
  @@lock = Mutex.new
@@ -64,9 +64,10 @@ module VagrantPlugins
64
64
  # locking all subsequent actions as well.
65
65
  @@lock.synchronize do
66
66
  # Don't continue if image already exists in storage pool.
67
- break if ProviderLibvirt::Util::Collection.find_matching(
68
- env[:machine].provider.driver.connection.volumes.all, env[:box_volume_name]
69
- )
67
+ box_volume = env[:machine].provider.driver.connection.volumes.all(
68
+ name: env[:box_volume_name]
69
+ ).first
70
+ break if box_volume && box_volume.id
70
71
 
71
72
  # Box is not available as a storage pool volume. Create and upload
72
73
  # it as a copy of local box image.
@@ -81,62 +82,42 @@ module VagrantPlugins
81
82
  message << " in storage pool #{config.storage_pool_name}."
82
83
  @logger.info(message)
83
84
 
84
- if config.qemu_use_session
85
- begin
86
- @name = env[:box_volume_name]
87
- @allocation = "#{box_image_size / 1024 / 1024}M"
88
- @capacity = "#{box_virtual_size}G"
89
- @format_type = box_format ? box_format : 'raw'
90
-
91
- @storage_volume_uid = storage_uid env
92
- @storage_volume_gid = storage_gid env
93
-
94
- libvirt_client = env[:machine].provider.driver.connection.client
95
- libvirt_pool = libvirt_client.lookup_storage_pool_by_name(
96
- config.storage_pool_name
97
- )
98
- libvirt_volume = libvirt_pool.create_volume_xml(
99
- to_xml('default_storage_volume')
100
- )
101
- rescue => e
102
- raise Errors::CreatingVolumeError,
103
- error_message: e.message
104
- end
105
- else
106
- begin
107
- fog_volume = env[:machine].provider.driver.connection.volumes.create(
108
- name: env[:box_volume_name],
109
- allocation: "#{box_image_size / 1024 / 1024}M",
110
- capacity: "#{box_virtual_size}G",
111
- format_type: box_format,
112
- pool_name: config.storage_pool_name
113
- )
114
- rescue Fog::Errors::Error => e
115
- raise Errors::FogCreateVolumeError,
116
- error_message: e.message
117
- end
85
+ @storage_volume_uid = storage_uid env
86
+ @storage_volume_gid = storage_gid env
87
+
88
+ begin
89
+ fog_volume = env[:machine].provider.driver.connection.volumes.create(
90
+ name: env[:box_volume_name],
91
+ allocation: "#{box_image_size / 1024 / 1024}M",
92
+ capacity: "#{box_virtual_size}G",
93
+ format_type: box_format,
94
+ owner: @storage_volume_uid,
95
+ group: @storage_volume_gid,
96
+ pool_name: config.storage_pool_name
97
+ )
98
+ rescue Fog::Errors::Error => e
99
+ raise Errors::FogCreateVolumeError,
100
+ error_message: e.message
118
101
  end
119
102
 
120
103
  # Upload box image to storage pool
121
104
  ret = upload_image(box_image_file, config.storage_pool_name,
122
105
  env[:box_volume_name], env) do |progress|
123
- env[:ui].clear_line
124
- env[:ui].report_progress(progress, box_image_size, false)
106
+ rewriting(env[:ui]) do |ui|
107
+ ui.clear_line
108
+ ui.report_progress(progress, box_image_size, false)
109
+ end
125
110
  end
126
111
 
127
112
  # Clear the line one last time since the progress meter doesn't
128
113
  # disappear immediately.
129
- env[:ui].clear_line
114
+ rewriting(env[:ui]) {|ui| ui.clear_line}
130
115
 
131
116
  # If upload failed or was interrupted, remove created volume from
132
117
  # storage pool.
133
118
  if env[:interrupted] || !ret
134
119
  begin
135
- if config.qemu_use_session
136
- libvirt_volume.delete
137
- else
138
- fog_volume.destroy
139
- end
120
+ fog_volume.destroy
140
121
  rescue
141
122
  nil
142
123
  end
@@ -146,22 +127,9 @@ module VagrantPlugins
146
127
  @app.call(env)
147
128
  end
148
129
 
149
- def split_size_unit(text)
150
- if text.kind_of? Integer
151
- # if text is an integer, match will fail
152
- size = text
153
- unit = 'G'
154
- else
155
- matcher = text.match(/(\d+)(.+)/)
156
- size = matcher[1]
157
- unit = matcher[2]
158
- end
159
- [size, unit]
160
- end
161
-
162
130
  protected
163
131
 
164
- # Fog libvirt currently doesn't support uploading images to storage
132
+ # Fog Libvirt currently doesn't support uploading images to storage
165
133
  # pool volumes. Use ruby-libvirt client instead.
166
134
  def upload_image(image_file, pool_name, volume_name, env)
167
135
  image_size = File.size(image_file) # B
@@ -24,9 +24,9 @@ module VagrantPlugins
24
24
  # locking all subsequent actions as well.
25
25
  @@lock.synchronize do
26
26
  # Check for storage pool, where box image should be created
27
- break if ProviderLibvirt::Util::Collection.find_matching(
28
- env[:machine].provider.driver.connection.pools.all, config.storage_pool_name
29
- )
27
+ break unless env[:machine].provider.driver.connection.pools.all(
28
+ name: config.storage_pool_name
29
+ ).empty?
30
30
 
31
31
  @logger.info("No storage pool '#{config.storage_pool_name}' is available.")
32
32
 
@@ -36,7 +36,7 @@ module VagrantPlugins
36
36
 
37
37
  @logger.info("Creating storage pool 'default'")
38
38
 
39
- # Fog libvirt currently doesn't support creating pools. Use
39
+ # Fog Libvirt currently doesn't support creating pools. Use
40
40
  # ruby-libvirt client directly.
41
41
  begin
42
42
  @storage_pool_path = storage_pool_path(env)
@@ -1,10 +1,14 @@
1
+ require 'fileutils'
1
2
  require 'log4r'
2
3
 
3
4
  module VagrantPlugins
4
5
  module ProviderLibvirt
5
6
  module Action
6
- # Action for create new box for libvirt provider
7
+ # Action for create new box for Libvirt provider
7
8
  class PackageDomain
9
+ include VagrantPlugins::ProviderLibvirt::Util::Ui
10
+
11
+
8
12
  def initialize(app, env)
9
13
  @logger = Log4r::Logger.new('vagrant_libvirt::action::package_domain')
10
14
  @app = app
@@ -21,24 +25,34 @@ module VagrantPlugins
21
25
  root_disk = domain.volumes.select do |x|
22
26
  x.name == libvirt_domain.name + '.img'
23
27
  end.first
28
+ raise Errors::NoDomainVolume if root_disk.nil?
24
29
  boxname = env['package.output']
25
30
  raise "#{boxname}: Already exists" if File.exist?(boxname)
26
31
  @tmp_dir = Dir.pwd + '/_tmp_package'
27
32
  @tmp_img = @tmp_dir + '/box.img'
28
- Dir.mkdir(@tmp_dir)
29
- if File.readable?(root_disk.path)
30
- backing = `qemu-img info "#{root_disk.path}" | grep 'backing file:' | cut -d ':' -f2`.chomp
31
- else
32
- env[:ui].error("Require set read access to #{root_disk.path}. sudo chmod a+r #{root_disk.path}")
33
- FileUtils.rm_rf(@tmp_dir)
34
- raise 'Have no access'
33
+ FileUtils.mkdir_p(@tmp_dir)
34
+ env[:ui].info("Downloading #{root_disk.name} to #{@tmp_img}")
35
+ ret = download_image(@tmp_img, env[:machine].provider_config.storage_pool_name,
36
+ root_disk.name, env) do |progress,image_size|
37
+ rewriting(env[:ui]) do |ui|
38
+ ui.clear_line
39
+ ui.report_progress(progress, image_size, false)
40
+ end
41
+ end
42
+ # Clear the line one last time since the progress meter doesn't
43
+ # disappear immediately.
44
+ rewriting(env[:ui]) {|ui| ui.clear_line}
45
+ backing = `qemu-img info "#{@tmp_img}" | grep 'backing file:' | cut -d ':' -f2`.chomp
46
+ if backing
47
+ env[:ui].info('Image has backing image, copying image and rebasing ...')
48
+ `qemu-img rebase -p -b "" #{@tmp_img}`
35
49
  end
36
- env[:ui].info('Image has backing image, copying image and rebasing ...')
37
- FileUtils.cp(root_disk.path, @tmp_img)
38
- `qemu-img rebase -p -b "" #{@tmp_img}`
39
50
  # remove hw association with interface
40
51
  # working for centos with lvs default disks
41
- `virt-sysprep --no-logfile --operations defaults,-ssh-userdir -a #{@tmp_img}`
52
+ options = ENV.fetch('VAGRANT_LIBVIRT_VIRT_SYSPREP_OPTIONS', '')
53
+ operations = ENV.fetch('VAGRANT_LIBVIRT_VIRT_SYSPREP_OPERATIONS', 'defaults,-ssh-userdir,-customize')
54
+ `virt-sysprep --no-logfile --operations #{operations} -a #{@tmp_img} #{options}`
55
+ `virt-sparsify --in-place #{@tmp_img}`
42
56
  # add any user provided file
43
57
  extra = ''
44
58
  @tmp_include = @tmp_dir + '/_include'
@@ -99,6 +113,44 @@ module VagrantPlugins
99
113
  }
100
114
  EOF
101
115
  end
116
+
117
+ protected
118
+
119
+ # Fog libvirt currently doesn't support downloading images from storage
120
+ # pool volumes. Use ruby-libvirt client instead.
121
+ def download_image(image_file, pool_name, volume_name, env)
122
+ begin
123
+ pool = env[:machine].provider.driver.connection.client.lookup_storage_pool_by_name(
124
+ pool_name
125
+ )
126
+ volume = pool.lookup_volume_by_name(volume_name)
127
+ image_size = volume.info.allocation # B
128
+
129
+ stream = env[:machine].provider.driver.connection.client.stream
130
+
131
+ # Use length of 0 to download remaining contents after offset
132
+ volume.download(stream, offset = 0, length = 0)
133
+
134
+ buf_size = 1024 * 250 # 250K, copied from upload_image in handle_box_image.rb
135
+ progress = 0
136
+ retval = stream.recv(buf_size)
137
+ open(image_file, 'wb') do |io|
138
+ while (retval.at(0) > 0)
139
+ recvd = io.write(retval.at(1))
140
+ progress += recvd
141
+ yield [progress, image_size]
142
+ retval = stream.recv(buf_size)
143
+ end
144
+ end
145
+ rescue => e
146
+ raise Errors::ImageDownloadError,
147
+ volume_name: volume_name,
148
+ pool_name: pool_name,
149
+ error_message: e.message
150
+ end
151
+
152
+ progress == image_size
153
+ end
102
154
  end
103
155
  end
104
156
  end
@@ -1,12 +1,13 @@
1
1
  require 'nokogiri'
2
2
  require 'socket'
3
3
  require 'timeout'
4
+ require 'vagrant-libvirt/util/nfs'
4
5
 
5
6
  module VagrantPlugins
6
7
  module ProviderLibvirt
7
8
  module Action
8
9
  class PrepareNFSSettings
9
- include Vagrant::Action::Builtin::MixinSyncedFolders
10
+ include VagrantPlugins::ProviderLibvirt::Util::Nfs
10
11
 
11
12
  def initialize(app, _env)
12
13
  @app = app
@@ -28,13 +29,6 @@ module VagrantPlugins
28
29
  end
29
30
  end
30
31
 
31
- # We're using NFS if we have any synced folder with NFS configured. If
32
- # we are not using NFS we don't need to do the extra work to
33
- # populate these fields in the environment.
34
- def using_nfs?
35
- !!synced_folders(@machine)[:nfs]
36
- end
37
-
38
32
  # Returns the IP address of the host
39
33
  #
40
34
  # @param [Machine] machine
@@ -79,7 +73,7 @@ module VagrantPlugins
79
73
  # Check if we can open a connection to the host
80
74
  def ping(host, timeout = 3)
81
75
  ::Timeout.timeout(timeout) do
82
- s = TCPSocket.new(host, 'echo')
76
+ s = TCPSocket.new(host, 'ssh')
83
77
  s.close
84
78
  end
85
79
  true
@@ -1,22 +1,32 @@
1
+ require 'vagrant-libvirt/util/nfs'
1
2
  require 'yaml'
3
+
2
4
  module VagrantPlugins
3
5
  module ProviderLibvirt
4
6
  module Action
5
7
  class PruneNFSExports
8
+ include VagrantPlugins::ProviderLibvirt::Util::Nfs
9
+
6
10
  def initialize(app, _env)
11
+ @logger = Log4r::Logger.new('vagrant_libvirt::action::prune_nfs_exports')
7
12
  @app = app
8
13
  end
9
14
 
10
15
  def call(env)
11
- if env[:host]
12
- uuid = env[:machine].id
13
- # get all uuids
14
- uuids = env[:machine].provider.driver.connection.servers.all.map(&:id)
15
- # not exiisted in array will removed from nfs
16
- uuids.delete(uuid)
17
- env[:host].capability(
18
- :nfs_prune, env[:machine].ui, uuids
19
- )
16
+ @machine = env[:machine]
17
+
18
+ if using_nfs?
19
+ @logger.info('Using NFS, prunning NFS settings from host')
20
+ if env[:host]
21
+ uuid = env[:machine].id
22
+ # get all uuids
23
+ uuids = env[:machine].provider.driver.connection.servers.all.map(&:id)
24
+ # not exiisted in array will removed from nfs
25
+ uuids.delete(uuid)
26
+ env[:host].capability(
27
+ :nfs_prune, env[:machine].ui, uuids
28
+ )
29
+ end
20
30
  end
21
31
 
22
32
  @app.call(env)
@@ -10,8 +10,8 @@ module VagrantPlugins
10
10
  end
11
11
 
12
12
  def call(env)
13
- env[:ui].info('Vagrant-libvirt plugin removed box only from you LOCAL ~/.vagrant/boxes directory')
14
- env[:ui].info('From libvirt storage pool you have to delete image manually(virsh, virt-manager or by any other tool)')
13
+ env[:ui].info('Vagrant-libvirt plugin removed box only from your LOCAL ~/.vagrant/boxes directory')
14
+ env[:ui].info('From Libvirt storage pool you have to delete image manually(virsh, virt-manager or by any other tool)')
15
15
  @app.call(env)
16
16
  end
17
17
  end
@@ -16,13 +16,19 @@ module VagrantPlugins
16
16
 
17
17
  def call(env)
18
18
  # Remove stale server volume
19
- env[:ui].info(I18n.t('vagrant_libvirt.remove_stale_volume'))
20
-
21
19
  config = env[:machine].provider_config
22
20
  # Check for storage pool, where box image should be created
23
- fog_pool = ProviderLibvirt::Util::Collection.find_matching(
24
- env[:machine].provider.driver.connection.pools.all, config.storage_pool_name
25
- )
21
+ fog_pool = env[:machine].provider.driver.connection.pools.all(
22
+ name: config.storage_pool_name
23
+ ).first
24
+
25
+ env[:result] = nil
26
+
27
+ if not fog_pool
28
+ @logger.debug("**** Pool #{config.storage_pool_name} not found")
29
+ return @app.call(env)
30
+ end
31
+
26
32
  @logger.debug("**** Pool #{fog_pool.name}")
27
33
 
28
34
  # This is name of newly created image for vm.
@@ -30,17 +36,17 @@ module VagrantPlugins
30
36
  @logger.debug("**** Volume name #{name}")
31
37
 
32
38
  # remove root storage
33
- box_volume = ProviderLibvirt::Util::Collection.find_matching(
34
- env[:machine].provider.driver.connection.volumes.all, name
35
- )
36
- if box_volume && box_volume.pool_name == fog_pool.name
39
+ box_volume = env[:machine].provider.driver.connection.volumes.all(
40
+ name: name
41
+ ).find { |x| x.pool_name == fog_pool.name }
42
+ if box_volume && box_volume.id
43
+ env[:ui].info(I18n.t('vagrant_libvirt.remove_stale_volume'))
37
44
  @logger.info("Deleting volume #{box_volume.key}")
38
45
  box_volume.destroy
39
46
  env[:result] = box_volume
40
47
  else
41
- env[:result] = nil
48
+ @logger.debug("**** Volume #{name} not found in pool #{fog_pool.name}")
42
49
  end
43
-
44
50
  # Continue the middleware chain.
45
51
  @app.call(env)
46
52
  end
@@ -33,7 +33,7 @@ module VagrantPlugins
33
33
  if @boot_order.count >= 1
34
34
 
35
35
  # If a domain is initially defined with no box or disk or
36
- # with an explicit boot order, libvirt adds <boot dev="foo">
36
+ # with an explicit boot order, Libvirt adds <boot dev="foo">
37
37
  # This conflicts with an explicit boot_order configuration,
38
38
  # so we need to remove it from the domain xml and feed it back.
39
39
  # Also see https://bugzilla.redhat.com/show_bug.cgi?id=1248514
@@ -66,7 +66,7 @@ module VagrantPlugins
66
66
  logger_msg(node, index)
67
67
  end
68
68
 
69
- # Finally redefine the domain XML through libvirt
69
+ # Finally redefine the domain XML through Libvirt
70
70
  # to apply the boot ordering
71
71
  env[:machine].provider
72
72
  .driver
@@ -13,20 +13,17 @@ module VagrantPlugins
13
13
  env[:domain_name] = build_domain_name(env)
14
14
 
15
15
  begin
16
- @logger.info("Looking for domain #{env[:domain_name]} through list " \
17
- "#{env[:machine].provider.driver.connection.servers.all}")
16
+ @logger.info("Looking for domain #{env[:domain_name]}")
18
17
  # Check if the domain name is not already taken
19
18
 
20
- domain = ProviderLibvirt::Util::Collection.find_matching(
21
- env[:machine].provider.driver.connection.servers.all, env[:domain_name]
19
+ domain = env[:machine].provider.driver.connection.servers.all(
20
+ name: env[:domain_name]
22
21
  )
23
- rescue Fog::Errors::Error => e
22
+ rescue Libvirt::RetrieveError => e
24
23
  @logger.info(e.to_s)
25
24
  domain = nil
26
25
  end
27
26
 
28
- @logger.info("Looking for domain #{env[:domain_name]}")
29
-
30
27
  unless domain.nil?
31
28
  raise ProviderLibvirt::Errors::DomainNameExists,
32
29
  domain_name: env[:domain_name]
@@ -41,7 +38,7 @@ module VagrantPlugins
41
38
  # parsable and sortable by epoch time
42
39
  # @example
43
40
  # development-centos-6-chef-11_1404488971_3b7a569e2fd7c554b852
44
- # @return [String] libvirt domain name
41
+ # @return [String] Libvirt domain name
45
42
  def build_domain_name(env)
46
43
  config = env[:machine].provider_config
47
44
  domain_name =
@@ -51,7 +48,7 @@ module VagrantPlugins
51
48
  # don't have any prefix, not even "_"
52
49
  ''
53
50
  else
54
- config.default_prefix.to_s.dup.concat('_')
51
+ config.default_prefix.to_s.dup
55
52
  end
56
53
  domain_name << env[:machine].name.to_s
57
54
  domain_name.gsub!(/[^-a-z0-9_\.]/i, '')