vagrant-libvirt 0.3.0 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +421 -50
  3. data/lib/vagrant-libvirt/action.rb +7 -1
  4. data/lib/vagrant-libvirt/action/clean_machine_folder.rb +30 -0
  5. data/lib/vagrant-libvirt/action/create_domain.rb +56 -18
  6. data/lib/vagrant-libvirt/action/create_domain_volume.rb +57 -55
  7. data/lib/vagrant-libvirt/action/create_network_interfaces.rb +0 -3
  8. data/lib/vagrant-libvirt/action/create_networks.rb +11 -4
  9. data/lib/vagrant-libvirt/action/destroy_domain.rb +1 -1
  10. data/lib/vagrant-libvirt/action/forward_ports.rb +37 -38
  11. data/lib/vagrant-libvirt/action/halt_domain.rb +25 -9
  12. data/lib/vagrant-libvirt/action/handle_box_image.rb +163 -74
  13. data/lib/vagrant-libvirt/action/is_running.rb +1 -3
  14. data/lib/vagrant-libvirt/action/is_suspended.rb +4 -4
  15. data/lib/vagrant-libvirt/action/package_domain.rb +2 -1
  16. data/lib/vagrant-libvirt/action/set_boot_order.rb +6 -2
  17. data/lib/vagrant-libvirt/action/start_domain.rb +86 -29
  18. data/lib/vagrant-libvirt/action/wait_till_up.rb +8 -52
  19. data/lib/vagrant-libvirt/cap/{mount_p9.rb → mount_9p.rb} +2 -2
  20. data/lib/vagrant-libvirt/cap/mount_virtiofs.rb +37 -0
  21. data/lib/vagrant-libvirt/cap/{synced_folder.rb → synced_folder_9p.rb} +4 -5
  22. data/lib/vagrant-libvirt/cap/synced_folder_virtiofs.rb +109 -0
  23. data/lib/vagrant-libvirt/config.rb +236 -43
  24. data/lib/vagrant-libvirt/driver.rb +49 -32
  25. data/lib/vagrant-libvirt/errors.rb +24 -1
  26. data/lib/vagrant-libvirt/plugin.rb +14 -5
  27. data/lib/vagrant-libvirt/provider.rb +2 -9
  28. data/lib/vagrant-libvirt/templates/domain.xml.erb +35 -10
  29. data/lib/vagrant-libvirt/templates/private_network.xml.erb +1 -1
  30. data/lib/vagrant-libvirt/util/network_util.rb +21 -3
  31. data/lib/vagrant-libvirt/version +1 -1
  32. data/lib/vagrant-libvirt/version.rb +57 -9
  33. data/locales/en.yml +12 -0
  34. data/spec/spec_helper.rb +37 -3
  35. data/spec/support/binding_proc.rb +24 -0
  36. data/spec/support/libvirt_context.rb +2 -0
  37. data/spec/support/matchers/have_file_content.rb +63 -0
  38. data/spec/support/sharedcontext.rb +4 -0
  39. data/spec/unit/action/clean_machine_folder_spec.rb +58 -0
  40. data/spec/unit/action/create_domain_spec.rb +121 -36
  41. data/spec/unit/action/create_domain_spec/additional_disks_domain.xml +54 -0
  42. data/spec/unit/action/create_domain_spec/default_domain.xml +49 -0
  43. data/spec/unit/action/create_domain_spec/{default_storage_pool.xml → default_system_storage_pool.xml} +0 -0
  44. data/spec/unit/action/create_domain_spec/default_user_storage_pool.xml +17 -0
  45. data/spec/unit/action/create_domain_volume_spec.rb +102 -0
  46. data/spec/unit/action/create_domain_volume_spec/one_disk_in_storage.xml +21 -0
  47. data/spec/unit/action/create_domain_volume_spec/three_disks_in_storage_disk_0.xml +21 -0
  48. data/spec/unit/action/create_domain_volume_spec/three_disks_in_storage_disk_1.xml +21 -0
  49. data/spec/unit/action/create_domain_volume_spec/three_disks_in_storage_disk_2.xml +21 -0
  50. data/spec/unit/action/destroy_domain_spec.rb +1 -1
  51. data/spec/unit/action/forward_ports_spec.rb +202 -0
  52. data/spec/unit/action/halt_domain_spec.rb +90 -0
  53. data/spec/unit/action/handle_box_image_spec.rb +363 -0
  54. data/spec/unit/action/start_domain_spec.rb +183 -1
  55. data/spec/unit/action/start_domain_spec/clock_timer_rtc.xml +50 -0
  56. data/spec/unit/action/start_domain_spec/default.xml +2 -2
  57. data/spec/unit/action/start_domain_spec/default_added_tpm_path.xml +48 -0
  58. data/spec/unit/action/start_domain_spec/default_added_tpm_version.xml +48 -0
  59. data/spec/unit/action/wait_till_up_spec.rb +22 -21
  60. data/spec/unit/config_spec.rb +395 -127
  61. data/spec/unit/templates/domain_all_settings.xml +14 -3
  62. data/spec/unit/templates/domain_custom_cpu_model.xml +2 -1
  63. data/spec/unit/templates/domain_defaults.xml +2 -1
  64. data/spec/unit/templates/domain_spec.rb +100 -3
  65. data/spec/unit/templates/tpm/version_1.2.xml +54 -0
  66. data/spec/unit/templates/tpm/version_2.0.xml +53 -0
  67. metadata +105 -19
@@ -60,12 +60,12 @@ module VagrantPlugins
60
60
  @@system_connection
61
61
  end
62
62
 
63
- def get_domain(mid)
63
+ def get_domain(machine)
64
64
  begin
65
- domain = connection.servers.get(mid)
65
+ domain = connection.servers.get(machine.id)
66
66
  rescue Libvirt::RetrieveError => e
67
67
  if e.libvirt_code == ProviderLibvirt::Util::ErrorCodes::VIR_ERR_NO_DOMAIN
68
- @logger.debug("machine #{mid} not found #{e}.")
68
+ @logger.debug("machine #{machine.name} domain not found #{e}.")
69
69
  return nil
70
70
  else
71
71
  raise e
@@ -75,36 +75,35 @@ module VagrantPlugins
75
75
  domain
76
76
  end
77
77
 
78
- def created?(mid)
79
- domain = get_domain(mid)
78
+ def created?(machine)
79
+ domain = get_domain(machine)
80
80
  !domain.nil?
81
81
  end
82
82
 
83
83
  def get_ipaddress(machine)
84
84
  # Find the machine
85
- domain = get_domain(machine.id)
86
- if @machine.provider_config.qemu_use_session
87
- return get_ipaddress_system domain.mac
88
- end
85
+ domain = get_domain(machine)
89
86
 
90
87
  if domain.nil?
91
88
  # The machine can't be found
92
89
  return nil
93
90
  end
94
91
 
95
- # Get IP address from arp table
96
- ip_address = nil
92
+ get_domain_ipaddress(machine, domain)
93
+ end
94
+
95
+ def get_domain_ipaddress(machine, domain)
96
+ if @machine.provider_config.qemu_use_session
97
+ return get_ipaddress_from_system domain.mac
98
+ end
99
+
100
+ # Get IP address from dhcp leases table
97
101
  begin
98
- domain.wait_for(2) do
99
- addresses.each_pair do |_type, ip|
100
- # Multiple leases are separated with a newline, return only
101
- # the most recent address
102
- ip_address = ip[0].split("\n").first unless ip[0].nil?
103
- end
104
- !ip_address.nil?
105
- end
102
+ ip_address = get_ipaddress_from_domain(domain)
106
103
  rescue Fog::Errors::TimeoutError
107
104
  @logger.info('Timeout at waiting for an ip address for machine %s' % machine.name)
105
+
106
+ raise
108
107
  end
109
108
 
110
109
  unless ip_address
@@ -115,7 +114,24 @@ module VagrantPlugins
115
114
  ip_address
116
115
  end
117
116
 
118
- def get_ipaddress_system(mac)
117
+ def state(machine)
118
+ # may be other error states with initial retreival we can't handle
119
+ begin
120
+ domain = get_domain(machine)
121
+ rescue Libvirt::RetrieveError => e
122
+ @logger.debug("Machine #{machine.id} not found #{e}.")
123
+ return :not_created
124
+ end
125
+
126
+ # TODO: terminated no longer appears to be a valid fog state, remove?
127
+ return :not_created if domain.nil? || domain.state.to_sym == :terminated
128
+
129
+ domain.state.tr('-', '_').to_sym
130
+ end
131
+
132
+ private
133
+
134
+ def get_ipaddress_from_system(mac)
119
135
  ip_address = nil
120
136
 
121
137
  system_connection.list_all_networks.each do |net|
@@ -125,23 +141,24 @@ module VagrantPlugins
125
141
  break if ip_address
126
142
  end
127
143
 
128
- return ip_address
144
+ ip_address
129
145
  end
130
146
 
131
- def state(machine)
132
- # may be other error states with initial retreival we can't handle
133
- begin
134
- domain = get_domain(machine.id)
135
- rescue Libvirt::RetrieveError => e
136
- @logger.debug("Machine #{machine.id} not found #{e}.")
137
- return :not_created
138
- end
147
+ def get_ipaddress_from_domain(domain)
148
+ ip_address = nil
149
+ domain.wait_for(2) do
150
+ addresses.each_pair do |type, ip|
151
+ # Multiple leases are separated with a newline, return only
152
+ # the most recent address
153
+ ip_address = ip[0].split("\n").first if ip[0] != nil
154
+ end
139
155
 
140
- # TODO: terminated no longer appears to be a valid fog state, remove?
141
- return :not_created if domain.nil? || domain.state.to_sym == :terminated
156
+ ip_address != nil
157
+ end
142
158
 
143
- domain.state.tr('-', '_').to_sym
159
+ ip_address
144
160
  end
161
+
145
162
  end
146
163
  end
147
164
  end
@@ -37,7 +37,22 @@ module VagrantPlugins
37
37
  error_key(:image_download_error)
38
38
  end
39
39
 
40
- # Box exceptions
40
+ # Box exceptions, capture all under one
41
+ class BoxError < VagrantLibvirtError
42
+ end
43
+
44
+ class BoxFormatMissingAttribute < BoxError
45
+ error_key(:box_format_missing_attribute)
46
+ end
47
+
48
+ class BoxFormatDuplicateVolume < BoxError
49
+ error_key(:box_format_duplicate_volume)
50
+ end
51
+
52
+ class BadBoxImage < VagrantLibvirtError
53
+ error_key(:bad_box_image)
54
+ end
55
+
41
56
  class NoBoxVolume < VagrantLibvirtError
42
57
  error_key(:no_box_volume)
43
58
  end
@@ -46,6 +61,10 @@ module VagrantPlugins
46
61
  error_key(:no_box_virtual_size)
47
62
  end
48
63
 
64
+ class NoDiskVirtualSizeSet < VagrantLibvirtError
65
+ error_key(:no_disk_virtual_size)
66
+ end
67
+
49
68
  class NoBoxFormatSet < VagrantLibvirtError
50
69
  error_key(:no_box_format)
51
70
  end
@@ -54,6 +73,10 @@ module VagrantPlugins
54
73
  error_key(:wrong_box_format)
55
74
  end
56
75
 
76
+ class WrongDiskFormatSet < VagrantLibvirtError
77
+ error_key(:wrong_disk_format)
78
+ end
79
+
57
80
  # Fog Libvirt exceptions
58
81
  class FogError < VagrantLibvirtError
59
82
  error_key(:fog_error)
@@ -26,12 +26,17 @@ module VagrantPlugins
26
26
  end
27
27
 
28
28
  action_hook(:remove_libvirt_image) do |hook|
29
+ require_relative 'action'
29
30
  hook.after Vagrant::Action::Builtin::BoxRemove, Action.remove_libvirt_image
30
31
  end
31
32
 
32
- guest_capability('linux', 'mount_p9_shared_folder') do
33
- require_relative 'cap/mount_p9'
34
- Cap::MountP9
33
+ guest_capability('linux', 'mount_9p_shared_folder') do
34
+ require_relative 'cap/mount_9p'
35
+ Cap::Mount9P
36
+ end
37
+ guest_capability('linux', 'mount_virtiofs_shared_folder') do
38
+ require_relative 'cap/mount_virtiofs'
39
+ Cap::MountVirtioFS
35
40
  end
36
41
 
37
42
  provider_capability(:libvirt, :nic_mac_addresses) do
@@ -47,8 +52,12 @@ module VagrantPlugins
47
52
  # lower priority than nfs or rsync
48
53
  # https://github.com/vagrant-libvirt/vagrant-libvirt/pull/170
49
54
  synced_folder('9p', 4) do
50
- require_relative 'cap/synced_folder'
51
- VagrantPlugins::SyncedFolder9p::SyncedFolder
55
+ require_relative 'cap/synced_folder_9p'
56
+ VagrantPlugins::SyncedFolder9P::SyncedFolder
57
+ end
58
+ synced_folder('virtiofs', 5) do
59
+ require_relative 'cap/synced_folder_virtiofs'
60
+ VagrantPlugins::SyncedFolderVirtioFS::SyncedFolder
52
61
  end
53
62
 
54
63
  # This initializes the internationalization strings.
@@ -68,14 +68,7 @@ module VagrantPlugins
68
68
  forward_x11: @machine.config.ssh.forward_x11
69
69
  }
70
70
 
71
- if @machine.provider_config.connect_via_ssh
72
- ssh_info[:proxy_command] =
73
- "ssh '#{@machine.provider_config.host}' " \
74
- "-l '#{@machine.provider_config.username}' " \
75
- "-i '#{@machine.provider_config.id_ssh_key_file}' " \
76
- 'nc %h %p'
77
-
78
- end
71
+ ssh_info[:proxy_command] = @machine.provider_config.proxy_command if @machine.provider_config.proxy_command
79
72
 
80
73
  ssh_info
81
74
  end
@@ -98,7 +91,7 @@ module VagrantPlugins
98
91
  state_id = nil
99
92
  state_id = :not_created unless @machine.id
100
93
  state_id = :not_created if
101
- !state_id && (!@machine.id || !driver.created?(@machine.id))
94
+ !state_id && (!@machine.id || !driver.created?(@machine))
102
95
  # Query the driver for the current state of the machine
103
96
  state_id = driver.state(@machine) if @machine.id && !state_id
104
97
  state_id = :unknown unless state_id
@@ -99,28 +99,41 @@
99
99
  <% if !@features_hyperv.empty? %>
100
100
  <hyperv>
101
101
  <% @features_hyperv.each do |feature| %>
102
- <<%= feature[:name] %> state='<%= feature[:state] %>' />
102
+ <<%= feature[:name] %> state='<%= feature[:state] %>'<% if feature[:name] == 'spinlocks' %> retries='<%= feature[:retries] %>'<% end %> />
103
103
  <% end %>
104
104
  </hyperv>
105
105
  <% end %>
106
106
  </features>
107
- <clock offset='utc'/>
107
+ <clock offset='<%= @clock_offset %>'>
108
+ <% @clock_timers.each do |clock_timer| %>
109
+ <timer<% clock_timer.each do |attr, value| %> <%= attr %>='<%= value %>'<% end %>/>
110
+ <% end %>
111
+ </clock>
108
112
  <devices>
109
113
  <% if @emulator_path %>
110
114
  <emulator><%= @emulator_path %></emulator>
111
115
  <% end %>
112
- <% if @domain_volume_path %>
116
+ <% @domain_volumes.each do |volume| -%>
113
117
  <disk type='file' device='disk'>
114
- <driver name='qemu' type='qcow2' cache='<%= @domain_volume_cache %>'/>
115
- <source file='<%= @domain_volume_path %>'/>
118
+ <driver name='qemu' type='qcow2' <%=
119
+ @disk_driver_opts.empty? ? "cache='#{volume[:cache]}'" :
120
+ @disk_driver_opts.reject { |k,v| v.nil? }
121
+ .map { |k,v| "#{k}='#{v}'"}
122
+ .join(' ') -%>/>
123
+ <source file='<%= volume[:path] %>'/>
116
124
  <%# we need to ensure a unique target dev -%>
117
- <target dev='<%= @disk_device %>' bus='<%= @disk_bus %>'/>
125
+ <target dev='<%= volume[:dev] %>' bus='<%= volume[:bus] %>'/>
118
126
  </disk>
119
- <% end %>
127
+ <% end -%>
120
128
  <%# additional disks -%>
121
129
  <% @disks.each do |d| -%>
122
130
  <disk type='file' device='disk'>
123
- <driver name='qemu' type='<%= d[:type] %>' cache='<%= d[:cache] %>'/>
131
+ <driver name='qemu' type='<%= d[:type] %>' <%=
132
+ d.select { |k,_| [:cache, :io, :copy_on_read, :discard, :detect_zeroes].include? k }
133
+ .reject { |k,v| v.nil? }
134
+ .map { |k,v| "#{k}='#{v}'"}
135
+ .join(' ')
136
+ -%>/>
124
137
  <source file='<%= d[:absolute_path] %>'/>
125
138
  <target dev='<%= d[:device] %>' bus='<%= d[:bus] %>'/>
126
139
  <% if d[:shareable] %>
@@ -140,6 +153,7 @@
140
153
 
141
154
  <% @cdroms.each do |c| %>
142
155
  <disk type='file' device='cdrom'>
156
+ <driver name='qemu' type='<%= c[:type] %>' />
143
157
  <source file='<%= c[:path] %>'/>
144
158
  <target dev='<%= c[:dev] %>' bus='<%= c[:bus] %>'/>
145
159
  <readonly/>
@@ -257,11 +271,13 @@
257
271
  <% end %>
258
272
  <% end -%>
259
273
 
260
- <% if @tpm_path -%>
274
+ <% if @tpm_path || @tpm_version -%>
261
275
  <%# TPM Device -%>
262
276
  <tpm model='<%= @tpm_model %>'>
263
- <backend type='<%= @tpm_type %>'>
277
+ <backend type='<%= @tpm_type %>'<% if @tpm_version %> version='<%= @tpm_version %>'<% end %>>
278
+ <% if @tpm_path -%>
264
279
  <device path='<%= @tpm_path %>'/>
280
+ <% end -%>
265
281
  </backend>
266
282
  </tpm>
267
283
  <% end -%>
@@ -269,6 +285,15 @@
269
285
  <%# USB Controller -%>
270
286
  <controller type='usb' model='<%= @usbctl_dev[:model] %>' <%= "ports=\"#{@usbctl_dev[:ports]}\" " if @usbctl_dev[:ports] %>/>
271
287
  <% end %>
288
+ <% unless @memballoon_enabled.nil? %>
289
+ <% if @memballoon_enabled %>
290
+ <memballoon model='<%= @memballoon_model %>'>
291
+ <address type='pci' domain='0x0000' bus='<%= @memballoon_pci_bus %>' slot='<%= @memballoon_pci_slot %>' function='0x0'/>
292
+ </memballoon>
293
+ <% else %>
294
+ <memballoon model='none'/>
295
+ <% end %>
296
+ <% end %>
272
297
  </devices>
273
298
 
274
299
  <% if not @qemu_args.empty? or not @qemu_env.empty? %>
@@ -1,6 +1,6 @@
1
1
  <network ipv6='<%= @guest_ipv6 %>'>
2
2
  <name><%= @network_name %></name>
3
- <bridge name="<%= @network_bridge_name %>" />
3
+ <bridge name="<%= @network_bridge_name %>" stp="<%= @network_bridge_stp %>" delay="<%= @network_bridge_delay %>" />
4
4
 
5
5
  <% if @network_domain_name %>
6
6
  <domain name="<%= @network_domain_name %>" localOnly="yes" />
@@ -1,6 +1,15 @@
1
+ require 'ipaddr'
1
2
  require 'nokogiri'
2
3
  require 'vagrant/util/network_ip'
3
4
 
5
+ class IPAddr
6
+ def get_mask
7
+ if @addr
8
+ _to_string(@mask_addr)
9
+ end
10
+ end
11
+ end
12
+
4
13
  module VagrantPlugins
5
14
  module ProviderLibvirt
6
15
  module Util
@@ -19,6 +28,7 @@ module VagrantPlugins
19
28
  management_network_pci_bus = env[:machine].provider_config.management_network_pci_bus
20
29
  management_network_pci_slot = env[:machine].provider_config.management_network_pci_slot
21
30
  management_network_domain = env[:machine].provider_config.management_network_domain
31
+ management_network_mtu = env[:machine].provider_config.management_network_mtu
22
32
  logger.info "Using #{management_network_name} at #{management_network_address} as the management network #{management_network_mode} is the mode"
23
33
 
24
34
  begin
@@ -70,6 +80,10 @@ module VagrantPlugins
70
80
  management_network_options[:domain_name] = management_network_domain
71
81
  end
72
82
 
83
+ unless management_network_mtu.nil?
84
+ management_network_options[:mtu] = management_network_mtu
85
+ end
86
+
73
87
  unless management_network_pci_bus.nil? and management_network_pci_slot.nil?
74
88
  management_network_options[:bus] = management_network_pci_bus
75
89
  management_network_options[:slot] = management_network_pci_slot
@@ -97,14 +111,18 @@ module VagrantPlugins
97
111
  # store type in options
98
112
  # use default values if not already set
99
113
  options = {
100
- iface_type: type,
101
- netmask: '255.255.255.0',
114
+ iface_type: type,
115
+ netmask: options[:network_address] ?
116
+ IPAddr.new(options[:network_address]).get_mask :
117
+ '255.255.255.0',
102
118
  dhcp_enabled: true,
103
119
  forward_mode: 'nat'
104
120
  }.merge(options)
105
121
 
106
122
  if options[:type].to_s == 'dhcp' && options[:ip].nil?
107
- options[:network_name] = 'vagrant-private-dhcp'
123
+ options[:network_name] = options[:network_name] ?
124
+ options[:network_name] :
125
+ 'vagrant-private-dhcp'
108
126
  end
109
127
 
110
128
  # add to list of networks to check
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.5.2
@@ -1,21 +1,49 @@
1
+ require 'open3'
2
+ require 'tmpdir'
3
+
1
4
  module VagrantPlugins
2
5
  module ProviderLibvirt
3
6
  VERSION_FILE = File.dirname(__FILE__) + "/version"
4
7
 
8
+ GIT_ARCHIVE_VERSION = "$Format:%H %D$"
9
+
10
+ HOMEPAGE = 'https://github.com/vagrant-libvirt/vagrant-libvirt'
11
+
5
12
  def self.get_version
6
13
  if File.exist?(VERSION_FILE)
14
+ # built gem
7
15
  version = File.read(VERSION_FILE)
8
- else
16
+ elsif self.inside_git_repository
17
+ # local repo
9
18
  git_version = `git describe --tags`
10
- version_parts = git_version.split('-').first(2) # drop the git sha if it exists
11
- if version_parts.length > 1
12
- # increment the patch number so that this is marked as a pre-release of the
13
- # next possible release
14
- main_version_parts = Gem::Version.new(version_parts[0]).segments
15
- main_version_parts[-1] = main_version_parts.last + 1
16
- version_parts = main_version_parts + ["pre", version_parts[1]]
19
+ version = self.version_from_describe(git_version)
20
+ elsif !GIT_ARCHIVE_VERSION.start_with?('$Format')
21
+ # archive - format string replaced during export
22
+ hash, refs = GIT_ARCHIVE_VERSION.split(' ', 2)
23
+
24
+ tag = refs.split(',').select { |ref| ref.strip.start_with?("tag:") }.first
25
+ if tag != nil
26
+ # tagged
27
+ version = tag.strip.split(' ').last
28
+ else
29
+ version = ""
30
+ # arbitrary branch/commit
31
+ Dir.mktmpdir do |dir|
32
+ stdout_and_stderr, status = Open3.capture2e("git -C #{dir} clone --bare #{HOMEPAGE}")
33
+ raise "failed to clone original to resolve version: #{stdout_and_stderr}" unless status.success?
34
+
35
+ stdout_and_stderr, status = Open3.capture2e("git --git-dir=#{dir}/vagrant-libvirt.git describe --tags #{hash}")
36
+ raise "failed to determine version for #{hash}: #{stdout_and_stderr}" unless status.success?
37
+
38
+ version = version_from_describe(stdout_and_stderr)
39
+ end
40
+
41
+ # in this case write the version file to avoid cloning a second time
42
+ File.write(VERSION_FILE, version)
17
43
  end
18
- version = version_parts.join(".")
44
+ else
45
+ # no idea
46
+ version = "9999"
19
47
  end
20
48
 
21
49
  return version.freeze
@@ -24,5 +52,25 @@ module VagrantPlugins
24
52
  def self.write_version
25
53
  File.write(VERSION_FILE, self.get_version)
26
54
  end
55
+
56
+ private
57
+
58
+ def self.inside_git_repository
59
+ _, status = Open3.capture2e("git rev-parse --git-dir")
60
+
61
+ status.success?
62
+ end
63
+
64
+ def self.version_from_describe(describe)
65
+ version_parts = describe.split('-').first(2) # drop the git sha if it exists
66
+ if version_parts.length > 1
67
+ # increment the patch number so that this is marked as a pre-release of the
68
+ # next possible release
69
+ main_version_parts = Gem::Version.new(version_parts[0]).segments
70
+ main_version_parts[-1] = main_version_parts.last + 1
71
+ version_parts = main_version_parts + ["pre", version_parts[1]]
72
+ end
73
+ version = version_parts.join(".")
74
+ end
27
75
  end
28
76
  end