vagrant-libvirt 0.1.0 → 0.4.1

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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +321 -76
  3. data/lib/vagrant-libvirt/action.rb +1 -1
  4. data/lib/vagrant-libvirt/action/create_domain.rb +54 -14
  5. data/lib/vagrant-libvirt/action/create_domain_volume.rb +0 -2
  6. data/lib/vagrant-libvirt/action/create_network_interfaces.rb +1 -0
  7. data/lib/vagrant-libvirt/action/forward_ports.rb +4 -3
  8. data/lib/vagrant-libvirt/action/handle_box_image.rb +6 -3
  9. data/lib/vagrant-libvirt/action/package_domain.rb +10 -4
  10. data/lib/vagrant-libvirt/action/prune_nfs_exports.rb +4 -3
  11. data/lib/vagrant-libvirt/action/start_domain.rb +86 -29
  12. data/lib/vagrant-libvirt/action/wait_till_up.rb +7 -27
  13. data/lib/vagrant-libvirt/cap/public_address.rb +16 -0
  14. data/lib/vagrant-libvirt/config.rb +233 -32
  15. data/lib/vagrant-libvirt/driver.rb +49 -32
  16. data/lib/vagrant-libvirt/plugin.rb +6 -0
  17. data/lib/vagrant-libvirt/provider.rb +2 -9
  18. data/lib/vagrant-libvirt/templates/domain.xml.erb +34 -5
  19. data/lib/vagrant-libvirt/templates/public_interface.xml.erb +5 -1
  20. data/lib/vagrant-libvirt/util.rb +1 -0
  21. data/lib/vagrant-libvirt/util/erb_template.rb +6 -7
  22. data/lib/vagrant-libvirt/util/ui.rb +23 -0
  23. data/lib/vagrant-libvirt/version +1 -0
  24. data/lib/vagrant-libvirt/version.rb +72 -1
  25. data/spec/spec_helper.rb +28 -2
  26. data/spec/support/binding_proc.rb +24 -0
  27. data/spec/support/libvirt_context.rb +3 -1
  28. data/spec/support/sharedcontext.rb +7 -3
  29. data/spec/unit/action/create_domain_spec.rb +160 -0
  30. data/spec/unit/action/create_domain_spec/default_system_storage_pool.xml +17 -0
  31. data/spec/unit/action/create_domain_spec/default_user_storage_pool.xml +17 -0
  32. data/spec/unit/action/destroy_domain_spec.rb +2 -2
  33. data/spec/unit/action/set_name_of_domain_spec.rb +2 -2
  34. data/spec/unit/action/start_domain_spec.rb +231 -0
  35. data/spec/unit/action/start_domain_spec/clock_timer_rtc.xml +50 -0
  36. data/spec/unit/action/start_domain_spec/default.xml +48 -0
  37. data/spec/unit/action/start_domain_spec/default_added_tpm_path.xml +48 -0
  38. data/spec/unit/action/start_domain_spec/default_added_tpm_version.xml +48 -0
  39. data/spec/unit/action/wait_till_up_spec.rb +32 -9
  40. data/spec/unit/config_spec.rb +438 -0
  41. data/spec/unit/provider_spec.rb +11 -0
  42. data/spec/unit/templates/domain_all_settings.xml +8 -3
  43. data/spec/unit/templates/domain_custom_cpu_model.xml +4 -1
  44. data/spec/unit/templates/domain_defaults.xml +4 -1
  45. data/spec/unit/templates/domain_spec.rb +82 -2
  46. data/spec/unit/templates/tpm/version_1.2.xml +54 -0
  47. data/spec/unit/templates/tpm/version_2.0.xml +53 -0
  48. metadata +62 -6
@@ -21,7 +21,7 @@ module VagrantPlugins
21
21
  env[:metrics] ||= {}
22
22
 
23
23
  # Get domain object
24
- domain = env[:machine].provider.driver.get_domain(env[:machine].id.to_s)
24
+ domain = env[:machine].provider.driver.get_domain(env[:machine])
25
25
  if domain.nil?
26
26
  raise Errors::NoDomainError,
27
27
  error_message: "Domain #{env[:machine].id} not found"
@@ -34,33 +34,13 @@ module VagrantPlugins
34
34
  @logger.debug("Searching for IP for MAC address: #{domain.mac}")
35
35
  env[:ui].info(I18n.t('vagrant_libvirt.waiting_for_ip'))
36
36
 
37
- if env[:machine].provider_config.qemu_use_session
38
- env[:metrics]['instance_ip_time'] = Util::Timer.time do
39
- retryable(on: Fog::Errors::TimeoutError, tries: 300) do
40
- # just return if interrupted and let the warden call recover
41
- return if env[:interrupted]
37
+ env[:metrics]['instance_ip_time'] = Util::Timer.time do
38
+ retryable(on: Fog::Errors::TimeoutError, tries: 300) do
39
+ # just return if interrupted and let the warden call recover
40
+ return if env[:interrupted]
42
41
 
43
- # Wait for domain to obtain an ip address
44
- domain.wait_for(2) do
45
- env[:ip_address] = env[:machine].provider.driver.get_ipaddress_system(domain.mac)
46
- !env[:ip_address].nil?
47
- end
48
- end
49
- end
50
- else
51
- env[:metrics]['instance_ip_time'] = Util::Timer.time do
52
- retryable(on: Fog::Errors::TimeoutError, tries: 300) do
53
- # just return if interrupted and let the warden call recover
54
- return if env[:interrupted]
55
-
56
- # Wait for domain to obtain an ip address
57
- domain.wait_for(2) do
58
- addresses.each_pair do |_type, ip|
59
- env[:ip_address] = ip[0] unless ip[0].nil?
60
- end
61
- !env[:ip_address].nil?
62
- end
63
- end
42
+ # Wait for domain to obtain an ip address
43
+ env[:ip_address] = env[:machine].provider.driver.get_domain_ipaddress(env[:machine], domain)
64
44
  end
65
45
  end
66
46
 
@@ -0,0 +1,16 @@
1
+ module VagrantPlugins
2
+ module ProviderLibvirt
3
+ module Cap
4
+ class PublicAddress
5
+ def self.public_address(machine)
6
+ # This does not need to be a globally routable address, it
7
+ # only needs to be accessible from the machine running
8
+ # Vagrant.
9
+ ssh_info = machine.ssh_info
10
+ return nil if !ssh_info
11
+ ssh_info[:host]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -37,6 +37,8 @@ module VagrantPlugins
37
37
  # ID SSH key file
38
38
  attr_accessor :id_ssh_key_file
39
39
 
40
+ attr_accessor :proxy_command
41
+
40
42
  # Libvirt storage pool name, where box image and instance snapshots will
41
43
  # be stored.
42
44
  attr_accessor :storage_pool_name
@@ -67,6 +69,8 @@ module VagrantPlugins
67
69
  attr_accessor :default_prefix
68
70
 
69
71
  # Domain specific settings used while creating new domain.
72
+ attr_accessor :title
73
+ attr_accessor :description
70
74
  attr_accessor :uuid
71
75
  attr_accessor :memory
72
76
  attr_accessor :nodeset
@@ -82,6 +86,8 @@ module VagrantPlugins
82
86
  attr_accessor :shares
83
87
  attr_accessor :features
84
88
  attr_accessor :features_hyperv
89
+ attr_accessor :clock_offset
90
+ attr_accessor :clock_timers
85
91
  attr_accessor :numa_nodes
86
92
  attr_accessor :loader
87
93
  attr_accessor :nvram
@@ -91,9 +97,10 @@ module VagrantPlugins
91
97
  attr_accessor :machine_virtual_size
92
98
  attr_accessor :disk_bus
93
99
  attr_accessor :disk_device
100
+ attr_accessor :disk_driver_opts
94
101
  attr_accessor :nic_model_type
95
102
  attr_accessor :nested
96
- attr_accessor :volume_cache
103
+ attr_accessor :volume_cache # deprecated, kept for backwards compatibility; use disk_driver
97
104
  attr_accessor :kernel
98
105
  attr_accessor :cmd_line
99
106
  attr_accessor :initrd
@@ -115,6 +122,13 @@ module VagrantPlugins
115
122
  attr_accessor :tpm_model
116
123
  attr_accessor :tpm_type
117
124
  attr_accessor :tpm_path
125
+ attr_accessor :tpm_version
126
+
127
+ # Configure the memballoon
128
+ attr_accessor :memballoon_enabled
129
+ attr_accessor :memballoon_model
130
+ attr_accessor :memballoon_pci_bus
131
+ attr_accessor :memballoon_pci_slot
118
132
 
119
133
  # Sets the max number of NICs that can be created
120
134
  # Default set to 8. Don't change the default unless you know
@@ -179,6 +193,8 @@ module VagrantPlugins
179
193
  @username = UNSET_VALUE
180
194
  @password = UNSET_VALUE
181
195
  @id_ssh_key_file = UNSET_VALUE
196
+ @socket = UNSET_VALUE
197
+ @proxy_command = UNSET_VALUE
182
198
  @storage_pool_name = UNSET_VALUE
183
199
  @snapshot_pool_name = UNSET_VALUE
184
200
  @random_hostname = UNSET_VALUE
@@ -197,6 +213,8 @@ module VagrantPlugins
197
213
  @system_uri = UNSET_VALUE
198
214
 
199
215
  # Domain specific settings.
216
+ @title = UNSET_VALUE
217
+ @description = UNSET_VALUE
200
218
  @uuid = UNSET_VALUE
201
219
  @memory = UNSET_VALUE
202
220
  @nodeset = UNSET_VALUE
@@ -211,6 +229,8 @@ module VagrantPlugins
211
229
  @shares = UNSET_VALUE
212
230
  @features = UNSET_VALUE
213
231
  @features_hyperv = UNSET_VALUE
232
+ @clock_offset = UNSET_VALUE
233
+ @clock_timers = []
214
234
  @numa_nodes = UNSET_VALUE
215
235
  @loader = UNSET_VALUE
216
236
  @nvram = UNSET_VALUE
@@ -219,6 +239,7 @@ module VagrantPlugins
219
239
  @machine_virtual_size = UNSET_VALUE
220
240
  @disk_bus = UNSET_VALUE
221
241
  @disk_device = UNSET_VALUE
242
+ @disk_driver_opts = {}
222
243
  @nic_model_type = UNSET_VALUE
223
244
  @nested = UNSET_VALUE
224
245
  @volume_cache = UNSET_VALUE
@@ -241,6 +262,12 @@ module VagrantPlugins
241
262
  @tpm_model = UNSET_VALUE
242
263
  @tpm_type = UNSET_VALUE
243
264
  @tpm_path = UNSET_VALUE
265
+ @tpm_version = UNSET_VALUE
266
+
267
+ @memballoon_enabled = UNSET_VALUE
268
+ @memballoon_model = UNSET_VALUE
269
+ @memballoon_pci_bus = UNSET_VALUE
270
+ @memballoon_pci_slot = UNSET_VALUE
244
271
 
245
272
  @nic_adapter_count = UNSET_VALUE
246
273
 
@@ -375,6 +402,25 @@ module VagrantPlugins
375
402
  state: options[:state])
376
403
  end
377
404
 
405
+ def clock_timer(options = {})
406
+ if options[:name].nil?
407
+ raise 'Clock timer name must be specified'
408
+ end
409
+
410
+ options.each do |key, value|
411
+ case key
412
+ when :name, :track, :tickpolicy, :frequency, :mode, :present
413
+ if value.nil?
414
+ raise "Value of timer option #{key} is nil"
415
+ end
416
+ else
417
+ raise "Unknown clock timer option: #{key}"
418
+ end
419
+ end
420
+
421
+ @clock_timers.push(options.dup)
422
+ end
423
+
378
424
  def cputopology(options = {})
379
425
  if options[:sockets].nil? || options[:cores].nil? || options[:threads].nil?
380
426
  raise 'CPU topology must have all of sockets, cores and threads specified'
@@ -547,6 +593,12 @@ module VagrantPlugins
547
593
  @smartcard_dev[:source_service] = options[:source_service] if @smartcard_dev[:type] == 'tcp'
548
594
  end
549
595
 
596
+ # Disk driver options for primary disk
597
+ def disk_driver(options = {})
598
+ supported_opts = [:cache, :io, :copy_on_read, :discard, :detect_zeroes]
599
+ @disk_driver_opts = options.select { |k,_| supported_opts.include? k }
600
+ end
601
+
550
602
  # NOTE: this will run twice for each time it's needed- keep it idempotent
551
603
  def storage(storage_type, options = {})
552
604
  if storage_type == :file
@@ -600,7 +652,13 @@ module VagrantPlugins
600
652
  cache: options[:cache] || 'default',
601
653
  allow_existing: options[:allow_existing],
602
654
  shareable: options[:shareable],
603
- serial: options[:serial]
655
+ serial: options[:serial],
656
+ io: options[:io],
657
+ copy_on_read: options[:copy_on_read],
658
+ discard: options[:discard],
659
+ detect_zeroes: options[:detect_zeroes],
660
+ pool: options[:pool], # overrides storage_pool setting for additional disks
661
+ wwn: options[:wwn],
604
662
  }
605
663
 
606
664
  @disks << disk # append
@@ -618,14 +676,31 @@ module VagrantPlugins
618
676
  @qemu_env.merge!(options)
619
677
  end
620
678
 
621
- # code to generate URI from a config moved out of the connect action
622
- def _generate_uri
679
+ def _default_uri
680
+ # Determine if any settings except driver provided explicitly, if not
681
+ # and the LIBVIRT_DEFAULT_URI var is set, use that.
682
+ #
683
+ # Skipping driver because that may be set on individual boxes rather
684
+ # than by the user.
685
+ if [
686
+ @connect_via_ssh, @host, @username, @password,
687
+ @id_ssh_key_file, @qemu_use_session, @socket,
688
+ ].none?{ |v| v != UNSET_VALUE }
689
+ if ENV.fetch('LIBVIRT_DEFAULT_URI', '') != ""
690
+ @uri = ENV['LIBVIRT_DEFAULT_URI']
691
+ end
692
+ end
693
+ end
694
+
695
+ # code to generate URI from from either the LIBVIRT_URI environment
696
+ # variable or a config moved out of the connect action
697
+ def _generate_uri(qemu_use_session)
623
698
  # builds the Libvirt connection URI from the given driver config
624
699
  # Setup connection uri.
625
700
  uri = @driver.dup
626
701
  virt_path = case uri
627
702
  when 'qemu', 'kvm'
628
- @qemu_use_session ? '/session' : '/system'
703
+ qemu_use_session ? '/session' : '/system'
629
704
  when 'openvz', 'uml', 'phyp', 'parallels'
630
705
  '/system'
631
706
  when '@en', 'esx'
@@ -639,42 +714,62 @@ module VagrantPlugins
639
714
  uri = 'qemu' # use QEMU uri for KVM domain type
640
715
  end
641
716
 
642
- if @connect_via_ssh
717
+ # turn on ssh if an ssh key file is explicitly provided
718
+ if @connect_via_ssh == UNSET_VALUE && @id_ssh_key_file && @id_ssh_key_file != UNSET_VALUE
719
+ @connect_via_ssh = true
720
+ end
721
+
722
+ params = {}
723
+
724
+ if @connect_via_ssh == true
725
+ finalize_id_ssh_key_file
726
+
643
727
  uri << '+ssh://'
644
- uri << @username + '@' if @username
728
+ uri << @username + '@' if @username && @username != UNSET_VALUE
729
+
730
+ uri << ( @host && @host != UNSET_VALUE ? @host : 'localhost' )
645
731
 
646
- uri << if @host
647
- @host
648
- else
649
- 'localhost'
650
- end
732
+ params['no_verify'] = '1'
733
+ params['keyfile'] = @id_ssh_key_file if @id_ssh_key_file
651
734
  else
652
735
  uri << '://'
653
- uri << @host if @host
736
+ uri << @host if @host && @host != UNSET_VALUE
654
737
  end
655
738
 
656
739
  uri << virt_path
657
- uri << '?no_verify=1'
658
740
 
659
- if @id_ssh_key_file
660
- # set ssh key for access to Libvirt host
661
- uri << "\&keyfile="
662
- # if no slash, prepend $HOME/.ssh/
663
- @id_ssh_key_file.prepend("#{`echo ${HOME}`.chomp}/.ssh/") if @id_ssh_key_file !~ /\A\//
664
- uri << @id_ssh_key_file
665
- end
666
741
  # set path to Libvirt socket
667
- uri << "\&socket=" + @socket if @socket
742
+ params['socket'] = @socket if @socket
743
+
744
+ uri << "?" + params.map{|pair| pair.join('=')}.join('&') if !params.empty?
668
745
  uri
669
746
  end
670
747
 
748
+ def _parse_uri(uri)
749
+ begin
750
+ URI.parse(uri)
751
+ rescue
752
+ raise "@uri set to invalid uri '#{uri}'"
753
+ end
754
+ end
755
+
671
756
  def finalize!
757
+ _default_uri if @uri == UNSET_VALUE
758
+
759
+ # settings which _generate_uri
672
760
  @driver = 'kvm' if @driver == UNSET_VALUE
673
- @host = nil if @host == UNSET_VALUE
674
- @connect_via_ssh = false if @connect_via_ssh == UNSET_VALUE
675
- @username = nil if @username == UNSET_VALUE
676
761
  @password = nil if @password == UNSET_VALUE
677
- @id_ssh_key_file = 'id_rsa' if @id_ssh_key_file == UNSET_VALUE
762
+ @socket = nil if @socket == UNSET_VALUE
763
+
764
+ # If uri isn't set then let's build one from various sources.
765
+ # Default to passing false for qemu_use_session if it's not set.
766
+ if @uri == UNSET_VALUE
767
+ @uri = _generate_uri(@qemu_use_session == UNSET_VALUE ? false : @qemu_use_session)
768
+ end
769
+
770
+ finalize_from_uri
771
+ finalize_proxy_command
772
+
678
773
  @storage_pool_name = 'default' if @storage_pool_name == UNSET_VALUE
679
774
  @snapshot_pool_name = @storage_pool_name if @snapshot_pool_name == UNSET_VALUE
680
775
  @storage_pool_path = nil if @storage_pool_path == UNSET_VALUE
@@ -691,12 +786,9 @@ module VagrantPlugins
691
786
  @management_network_domain = nil if @management_network_domain == UNSET_VALUE
692
787
  @system_uri = 'qemu:///system' if @system_uri == UNSET_VALUE
693
788
 
694
- @qemu_use_session = false if @qemu_use_session == UNSET_VALUE
695
-
696
- # generate a URI if none is supplied
697
- @uri = _generate_uri if @uri == UNSET_VALUE
698
-
699
789
  # Domain specific settings.
790
+ @title = '' if @title == UNSET_VALUE
791
+ @description = '' if @description == UNSET_VALUE
700
792
  @uuid = '' if @uuid == UNSET_VALUE
701
793
  @memory = 512 if @memory == UNSET_VALUE
702
794
  @nodeset = nil if @nodeset == UNSET_VALUE
@@ -717,6 +809,8 @@ module VagrantPlugins
717
809
  @shares = nil if @shares == UNSET_VALUE
718
810
  @features = ['acpi','apic','pae'] if @features == UNSET_VALUE
719
811
  @features_hyperv = [] if @features_hyperv == UNSET_VALUE
812
+ @clock_offset = 'utc' if @clock_offset == UNSET_VALUE
813
+ @clock_timers = [] if @clock_timers == UNSET_VALUE
720
814
  @numa_nodes = @numa_nodes == UNSET_VALUE ? nil : _generate_numa
721
815
  @loader = nil if @loader == UNSET_VALUE
722
816
  @nvram = nil if @nvram == UNSET_VALUE
@@ -725,9 +819,10 @@ module VagrantPlugins
725
819
  @machine_virtual_size = nil if @machine_virtual_size == UNSET_VALUE
726
820
  @disk_bus = 'virtio' if @disk_bus == UNSET_VALUE
727
821
  @disk_device = 'vda' if @disk_device == UNSET_VALUE
822
+ @disk_driver_opts = {} if @disk_driver_opts == UNSET_VALUE
728
823
  @nic_model_type = nil if @nic_model_type == UNSET_VALUE
729
824
  @nested = false if @nested == UNSET_VALUE
730
- @volume_cache = 'default' if @volume_cache == UNSET_VALUE
825
+ @volume_cache = nil if @volume_cache == UNSET_VALUE
731
826
  @kernel = nil if @kernel == UNSET_VALUE
732
827
  @cmd_line = '' if @cmd_line == UNSET_VALUE
733
828
  @initrd = '' if @initrd == UNSET_VALUE
@@ -749,6 +844,11 @@ module VagrantPlugins
749
844
  @tpm_model = 'tpm-tis' if @tpm_model == UNSET_VALUE
750
845
  @tpm_type = 'passthrough' if @tpm_type == UNSET_VALUE
751
846
  @tpm_path = nil if @tpm_path == UNSET_VALUE
847
+ @tpm_version = nil if @tpm_version == UNSET_VALUE
848
+ @memballoon_enabled = nil if @memballoon_enabled == UNSET_VALUE
849
+ @memballoon_model = 'virtio' if @memballoon_model == UNSET_VALUE
850
+ @memballoon_pci_bus = '0x00' if @memballoon_pci_bus == UNSET_VALUE
851
+ @memballoon_pci_slot = '0x0f' if @memballoon_pci_slot == UNSET_VALUE
752
852
  @nic_adapter_count = 8 if @nic_adapter_count == UNSET_VALUE
753
853
  @emulator_path = nil if @emulator_path == UNSET_VALUE
754
854
 
@@ -814,6 +914,14 @@ module VagrantPlugins
814
914
  def validate(machine)
815
915
  errors = _detected_errors
816
916
 
917
+ # The @uri and @qemu_use_session should not conflict
918
+ uri = _parse_uri(@uri)
919
+ if (uri.scheme.start_with? "qemu") && (uri.path.include? "session")
920
+ if @qemu_use_session != true
921
+ errors << "the URI and qemu_use_session configuration conflict: uri:'#{@uri}' qemu_use_session:'#{@qemu_use_session}'"
922
+ end
923
+ end
924
+
817
925
  machine.provider_config.disks.each do |disk|
818
926
  if disk[:path] && (disk[:path][0] == '/')
819
927
  errors << "absolute volume paths like '#{disk[:path]}' not yet supported"
@@ -832,6 +940,14 @@ module VagrantPlugins
832
940
  end
833
941
  end
834
942
 
943
+ if !machine.provider_config.volume_cache.nil? and machine.provider_config.volume_cache != UNSET_VALUE
944
+ machine.ui.warn("Libvirt Provider: volume_cache is deprecated. Use disk_driver :cache => '#{machine.provider_config.volume_cache}' instead.")
945
+
946
+ if !machine.provider_config.disk_driver_opts.empty?
947
+ machine.ui.warn("Libvirt Provider: volume_cache has no effect when disk_driver is defined.")
948
+ end
949
+ end
950
+
835
951
  { 'Libvirt Provider' => errors }
836
952
  end
837
953
 
@@ -845,11 +961,96 @@ module VagrantPlugins
845
961
  c += other.cdroms
846
962
  result.cdroms = c
847
963
 
964
+ result.disk_driver_opts = disk_driver_opts.merge(other.disk_driver_opts)
965
+
966
+ c = clock_timers.dup
967
+ c += other.clock_timers
968
+ result.clock_timers = c
969
+
848
970
  c = qemu_env != UNSET_VALUE ? qemu_env.dup : {}
849
971
  c.merge!(other.qemu_env) if other.qemu_env != UNSET_VALUE
850
972
  result.qemu_env = c
851
973
  end
852
974
  end
975
+
976
+ private
977
+
978
+ def finalize_from_uri
979
+ # Parse uri to extract individual components
980
+ uri = _parse_uri(@uri)
981
+
982
+ # only set @connect_via_ssh if not explicitly to avoid overriding
983
+ # and allow an error to occur if the @uri and @connect_via_ssh disagree
984
+ @connect_via_ssh = uri.scheme.include? "ssh" if @connect_via_ssh == UNSET_VALUE
985
+
986
+ # Set qemu_use_session based on the URI if it wasn't set by the user
987
+ if @qemu_use_session == UNSET_VALUE
988
+ if (uri.scheme.start_with? "qemu") && (uri.path.include? "session")
989
+ @qemu_use_session = true
990
+ else
991
+ @qemu_use_session = false
992
+ end
993
+ end
994
+
995
+ # Extract host and username values from uri if provided, otherwise nil
996
+ @host = uri.host
997
+ @username = uri.user
998
+
999
+ finalize_id_ssh_key_file
1000
+ end
1001
+
1002
+ def resolve_ssh_key_file(key_file)
1003
+ # set ssh key for access to Libvirt host
1004
+ # if no slash, prepend $HOME/.ssh/
1005
+ key_file.prepend("#{ENV['HOME']}/.ssh/") if key_file && key_file !~ /\A\//
1006
+
1007
+ key_file
1008
+ end
1009
+
1010
+ def finalize_id_ssh_key_file
1011
+ # resolve based on the following roles
1012
+ # 1) if @connect_via_ssh is set to true, and id_ssh_key_file not current set,
1013
+ # set default if the file exists
1014
+ # 2) if supplied the key name, attempt to expand based on user home
1015
+ # 3) otherwise set to nil
1016
+
1017
+ if @connect_via_ssh == true && @id_ssh_key_file == UNSET_VALUE
1018
+ # set default if using ssh while allowing a user using nil to disable this
1019
+ id_ssh_key_file = resolve_ssh_key_file('id_rsa')
1020
+ id_ssh_key_file = nil if !File.file?(id_ssh_key_file)
1021
+ elsif @id_ssh_key_file != UNSET_VALUE
1022
+ id_ssh_key_file = resolve_ssh_key_file(@id_ssh_key_file)
1023
+ else
1024
+ id_ssh_key_file = nil
1025
+ end
1026
+
1027
+ @id_ssh_key_file = id_ssh_key_file
1028
+ end
1029
+
1030
+ def finalize_proxy_command
1031
+ if @connect_via_ssh
1032
+ if @proxy_command == UNSET_VALUE
1033
+ proxy_command = "ssh '#{@host}' "
1034
+ proxy_command << "-l '#{@username}' " if @username
1035
+ proxy_command << "-i '#{@id_ssh_key_file}' " if @id_ssh_key_file
1036
+ proxy_command << '-W %h:%p'
1037
+ else
1038
+ inputs = { host: @host }
1039
+ inputs[:username] = @username if @username
1040
+ inputs[:id_ssh_key_file] = @id_ssh_key_file if @id_ssh_key_file
1041
+
1042
+ proxy_command = @proxy_command
1043
+ # avoid needing to escape '%' symbols
1044
+ inputs.each do |key, value|
1045
+ proxy_command.gsub!("{#{key}}", value)
1046
+ end
1047
+ end
1048
+
1049
+ @proxy_command = proxy_command
1050
+ else
1051
+ @proxy_command = nil
1052
+ end
1053
+ end
853
1054
  end
854
1055
  end
855
1056
  end