vagrant-local 0.0.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.
- checksums.yaml +7 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +27 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/dependabot.yml +6 -0
- data/.github/workflows/codeql-analysis.yml +72 -0
- data/.github/workflows/lint-release-and-publish-nightly.yml +73 -0
- data/.github/workflows/lint-release-and-publish.yml +71 -0
- data/.github/workflows/ruby-lint.yml +35 -0
- data/.gitignore +35 -0
- data/.rspec +2 -0
- data/.rubocop.yml +143 -0
- data/CHANGELOG.md +32 -0
- data/CODE_OF_CONDUCT.md +128 -0
- data/CONTRIBUTING.md +97 -0
- data/Gemfile +26 -0
- data/LICENSE +651 -0
- data/PULL_REQUEST_TEMPLATE.md +39 -0
- data/README.md +92 -0
- data/RELEASE.md +22 -0
- data/Rakefile +32 -0
- data/SECURITY.md +19 -0
- data/ansible.cfg +5 -0
- data/docs/CNAME +1 -0
- data/docs/_config.yml +1 -0
- data/docs/css/main.css +55 -0
- data/docs/css/styles.css +8678 -0
- data/docs/index.html +125 -0
- data/lib/vagrant-local/action/create.rb +27 -0
- data/lib/vagrant-local/action/destroy.rb +25 -0
- data/lib/vagrant-local/action/halt.rb +24 -0
- data/lib/vagrant-local/action/import.rb +27 -0
- data/lib/vagrant-local/action/is_created.rb +22 -0
- data/lib/vagrant-local/action/network.rb +24 -0
- data/lib/vagrant-local/action/network_cleanup.rb +26 -0
- data/lib/vagrant-local/action/not_created.rb +20 -0
- data/lib/vagrant-local/action/package.rb +135 -0
- data/lib/vagrant-local/action/restart.rb +27 -0
- data/lib/vagrant-local/action/setup.rb +24 -0
- data/lib/vagrant-local/action/shutdown.rb +47 -0
- data/lib/vagrant-local/action/start.rb +25 -0
- data/lib/vagrant-local/action/wait_till_boot.rb +47 -0
- data/lib/vagrant-local/action/wait_till_up.rb +65 -0
- data/lib/vagrant-local/action.rb +187 -0
- data/lib/vagrant-local/command/guest_power_controls.rb +58 -0
- data/lib/vagrant-local/command/local.rb +69 -0
- data/lib/vagrant-local/command/restart_guest.rb +29 -0
- data/lib/vagrant-local/command/shutdown_guest.rb +29 -0
- data/lib/vagrant-local/command/vnc_console.rb +48 -0
- data/lib/vagrant-local/command/webvnc_console.rb +49 -0
- data/lib/vagrant-local/config.rb +55 -0
- data/lib/vagrant-local/driver.rb +208 -0
- data/lib/vagrant-local/errors.rb +84 -0
- data/lib/vagrant-local/executor.rb +38 -0
- data/lib/vagrant-local/plugin.rb +76 -0
- data/lib/vagrant-local/provider.rb +83 -0
- data/lib/vagrant-local/util/subprocess.rb +31 -0
- data/lib/vagrant-local/util/timer.rb +19 -0
- data/lib/vagrant-local/version.rb +8 -0
- data/lib/vagrant-local.rb +29 -0
- data/locales/en.yml +187 -0
- data/vagrant-zones.gemspec +37 -0
- metadata +191 -0
@@ -0,0 +1,208 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'log4r'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'digest/md5'
|
6
|
+
require 'io/console'
|
7
|
+
require 'ruby_expect'
|
8
|
+
require 'netaddr'
|
9
|
+
require 'ipaddr'
|
10
|
+
require 'vagrant/util/numeric'
|
11
|
+
require 'pty'
|
12
|
+
require 'expect'
|
13
|
+
require 'vagrant'
|
14
|
+
require 'resolv'
|
15
|
+
require 'open3'
|
16
|
+
require 'vagrant-local/util/timer'
|
17
|
+
require 'vagrant-local/util/subprocess'
|
18
|
+
require 'vagrant/util/retryable'
|
19
|
+
|
20
|
+
module VagrantPlugins
|
21
|
+
module ProviderLocal
|
22
|
+
# This class does the heavy lifting of the local provider
|
23
|
+
class Driver
|
24
|
+
include Vagrant::Util::Retryable
|
25
|
+
attr_accessor :executor
|
26
|
+
|
27
|
+
def initialize(machine)
|
28
|
+
@logger = Log4r::Logger.new('vagrant_local::driver')
|
29
|
+
@machine = machine
|
30
|
+
@executor = Executor::Exec.new
|
31
|
+
@pfexec = if Process.uid.zero?
|
32
|
+
''
|
33
|
+
elsif system('sudo -v')
|
34
|
+
'sudo'
|
35
|
+
else
|
36
|
+
'pfexec'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def state(machine)
|
41
|
+
vm_data = YAML.load_file("#{machine.name}.vmstate")
|
42
|
+
return :not_created unless vm_data.is_a?(Array) && !vm_data.empty? && vm_data.first.is_a?(Hash)
|
43
|
+
|
44
|
+
vm_state = vm_data.first['state']
|
45
|
+
case vm_state
|
46
|
+
when 'running'
|
47
|
+
:running
|
48
|
+
when 'installed', 'stopped'
|
49
|
+
:stopped
|
50
|
+
else
|
51
|
+
:not_created
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Execute System commands
|
56
|
+
def execute(...)
|
57
|
+
@executor.execute(...)
|
58
|
+
end
|
59
|
+
|
60
|
+
## Begin installation
|
61
|
+
def install(_uii)
|
62
|
+
config = @machine.config.vm.provisioners[0].config.extra_vars.to_json
|
63
|
+
command = "#{@pfexec} ansible-playbook ./providers/ansible/install.yml -e '#{config}'"
|
64
|
+
_stdin, stdout, _stderr, wait_thr = Open3.popen3(command)
|
65
|
+
puts stdout.readline until stdout.eof?
|
66
|
+
wait_thr.value
|
67
|
+
end
|
68
|
+
|
69
|
+
## Run commands over SSH instead of ZLogin
|
70
|
+
def ssh_run_command(uii, command)
|
71
|
+
config = @machine.provider_config
|
72
|
+
ip = get_ip_address
|
73
|
+
user = user(@machine)
|
74
|
+
key = userprivatekeypath(@machine).to_s
|
75
|
+
port = sshport(@machine).to_s
|
76
|
+
port = 22 if sshport(@machine).to_s.nil?
|
77
|
+
execute_return = ''
|
78
|
+
Util::Timer.time do
|
79
|
+
retryable(on: Errors::TimeoutError, tries: 60) do
|
80
|
+
# If we're interrupted don't worry about waiting
|
81
|
+
ssh_string = "#{@pfexec} ssh -o 'StrictHostKeyChecking=no' -p"
|
82
|
+
execute_return = execute(false, %(#{ssh_string} #{port} -i #{key} #{user}@#{ip} "#{command}"))
|
83
|
+
uii.info(I18n.t('vagrant_local.ssh_run_command')) if config.debug
|
84
|
+
uii.info(I18n.t('vagrant_local.ssh_run_command') + command) if config.debug
|
85
|
+
loop do
|
86
|
+
break if @machine.communicate.ready?
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
execute_return
|
91
|
+
end
|
92
|
+
|
93
|
+
## Boot the Machine
|
94
|
+
def boot(uii)
|
95
|
+
config = @machine.config.vm.provisioners[0].config.extra_vars.to_json
|
96
|
+
command = "#{@pfexec} ansible-playbook ./providers/ansible/boot.yml -e '#{config}'"
|
97
|
+
uii.info(I18n.t('vagrant_local.start'))
|
98
|
+
_stdin, stdout, _stderr, wait_thr = Open3.popen3(command)
|
99
|
+
puts stdout.readline until stdout.eof?
|
100
|
+
wait_thr.value
|
101
|
+
end
|
102
|
+
|
103
|
+
# This ensures the host is ready for provisioning
|
104
|
+
def check_support(uii)
|
105
|
+
uii.info(I18n.t('vagrant_local.preflight_checks'))
|
106
|
+
uii.info(I18n.t('vagrant_local.ansible_playbook_check'))
|
107
|
+
playbook_result = execute(false, "#{@pfexec} which ansible-playbook")
|
108
|
+
raise Errors::AnsiblePlaybookNotDetected if playbook_result.empty?
|
109
|
+
|
110
|
+
uii.info(I18n.t('vagrant_local.ansible_check'))
|
111
|
+
result = execute(false, "#{@pfexec} which ansible")
|
112
|
+
raise Errors::AnsibleNotDetected if result.empty?
|
113
|
+
end
|
114
|
+
|
115
|
+
def get_ip_address
|
116
|
+
vm_data = YAML.load_file("#{@machine.name}.vmstate")
|
117
|
+
return nil unless vm_data.is_a?(Array) && !vm_data.empty? && vm_data.first.is_a?(Hash)
|
118
|
+
|
119
|
+
vm_data.first['public_ip']
|
120
|
+
end
|
121
|
+
|
122
|
+
# This filters the vagrantuser
|
123
|
+
def user(machine)
|
124
|
+
config = machine.provider_config
|
125
|
+
user = config.vagrant_user unless config.vagrant_user.nil?
|
126
|
+
user = 'vagrant' if config.vagrant_user.nil?
|
127
|
+
user
|
128
|
+
end
|
129
|
+
|
130
|
+
# This filters the userprivatekeypath
|
131
|
+
def userprivatekeypath(machine)
|
132
|
+
config = machine.provider_config
|
133
|
+
userkey = config.vagrant_user_private_key_path.to_s
|
134
|
+
if config.vagrant_user_private_key_path.to_s.nil?
|
135
|
+
id_rsa = 'https://raw.githubusercontent.com/hashicorp/vagrant/master/keys/vagrant'
|
136
|
+
file = './id_rsa'
|
137
|
+
command = "#{@pfexec} curl #{id_rsa} -O #{file}"
|
138
|
+
Util::Subprocess.new command do |_stdout, stderr, _thread|
|
139
|
+
uii.rewriting do |uipkp|
|
140
|
+
uipkp.clear_line
|
141
|
+
uipkp.info(I18n.t('vagrant_local.importing_vagrant_key'), new_line: false)
|
142
|
+
uipkp.report_progress(stderr, 100, false)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
uii.clear_line
|
146
|
+
userkey = './id_rsa'
|
147
|
+
end
|
148
|
+
userkey
|
149
|
+
end
|
150
|
+
|
151
|
+
# This filters the sshport
|
152
|
+
def sshport(machine)
|
153
|
+
config = machine.provider_config
|
154
|
+
sshport = '22'
|
155
|
+
sshport = config.sshport.to_s unless config.sshport.to_s.nil? || config.sshport.to_i.zero?
|
156
|
+
# uii.info(I18n.t('vagrant_local.sshport')) if config.debug
|
157
|
+
sshport
|
158
|
+
end
|
159
|
+
|
160
|
+
# This filters the vagrantuserpass
|
161
|
+
def vagrantuserpass(machine)
|
162
|
+
config = machine.provider_config
|
163
|
+
# uii.info(I18n.t('vagrant_local.vagrantuserpass')) if config.debug
|
164
|
+
config.vagrant_user_pass unless config.vagrant_user_pass.to_s.nil?
|
165
|
+
end
|
166
|
+
|
167
|
+
# Halts the instance, first via shutdown command, then a halt.
|
168
|
+
def halt(uii)
|
169
|
+
provider_config = @machine.provider_config
|
170
|
+
config = @machine.config.vm.provisioners[0].config.extra_vars.to_json
|
171
|
+
uii.info(I18n.t('vagrant_local.graceful_shutdown'))
|
172
|
+
begin
|
173
|
+
Timeout.timeout(provider_config.clean_shutdown_time) do
|
174
|
+
command = "#{@pfexec} ansible-playbook ./providers/ansible/halt.yml -e '#{config}'"
|
175
|
+
_stdin, stdout, _stderr, wait_thr = Open3.popen3(command)
|
176
|
+
puts stdout.readline until stdout.eof?
|
177
|
+
wait_thr.value
|
178
|
+
end
|
179
|
+
rescue Timeout::Error
|
180
|
+
uii.info(I18n.t('vagrant_local.graceful_shutdown_failed') + provider_config.clean_shutdown_time.to_s)
|
181
|
+
begin
|
182
|
+
Timeout.timeout(provider_config.clean_shutdown_time) do
|
183
|
+
command = "#{@pfexec} ansible-playbook ./providers/ansible/halt.yml -e '#{config}'"
|
184
|
+
_stdin, stdout, _stderr, wait_thr = Open3.popen3(command)
|
185
|
+
puts stdout.readline until stdout.eof?
|
186
|
+
wait_thr.value
|
187
|
+
end
|
188
|
+
rescue Timeout::Error
|
189
|
+
raise Errors::TimeoutHalt
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
# Destroys the instance
|
195
|
+
def destroy(id)
|
196
|
+
config = @machine.config.vm.provisioners[0].config.extra_vars.to_json
|
197
|
+
if state(@machine) == :stopped
|
198
|
+
id.info(I18n.t('vagrant_local.destroy'))
|
199
|
+
command = "#{@pfexec} ansible-playbook ./providers/ansible/destroy.yml -e '#{config}'"
|
200
|
+
_stdin, stdout, _stderr, wait_thr = Open3.popen3(command)
|
201
|
+
puts stdout.readline until stdout.eof?
|
202
|
+
wait_thr.value
|
203
|
+
end
|
204
|
+
id.info(I18n.t('vagrant_local.destroyed'))
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'vagrant'
|
4
|
+
|
5
|
+
module VagrantPlugins
|
6
|
+
module ProviderLocal
|
7
|
+
module Errors
|
8
|
+
# Namespace for Vagrant Local Errors
|
9
|
+
class VagrantLocalError < Vagrant::Errors::VagrantError
|
10
|
+
error_namespace('vagrant_local.errors')
|
11
|
+
end
|
12
|
+
|
13
|
+
# System Check Results
|
14
|
+
class SystemVersionIsTooLow < VagrantLocalError
|
15
|
+
error_key(:system_version_too_low)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Compatability Check Tool
|
19
|
+
class MissingCompatCheckTool < VagrantLocalError
|
20
|
+
error_key(:missing_compatability_check_tool)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Missing Bhyve
|
24
|
+
class MissingBhyve < VagrantLocalError
|
25
|
+
error_key(:missing_bhyve)
|
26
|
+
end
|
27
|
+
|
28
|
+
# HasNoRootPrivilege
|
29
|
+
class HasNoRootPrivilege < VagrantLocalError
|
30
|
+
error_key(:has_no_root_privilege)
|
31
|
+
end
|
32
|
+
|
33
|
+
# ExecuteError
|
34
|
+
class ExecuteError < VagrantLocalError
|
35
|
+
error_key(:execute_error)
|
36
|
+
end
|
37
|
+
|
38
|
+
# TimeoutError
|
39
|
+
class TimeoutError < VagrantLocalError
|
40
|
+
error_key(:timeout_error)
|
41
|
+
end
|
42
|
+
|
43
|
+
# VirtualBoxRunningConflictDetected
|
44
|
+
class VirtualBoxRunningConflictDetected < VagrantLocalError
|
45
|
+
error_key(:virtual_box_running_conflict_detected)
|
46
|
+
end
|
47
|
+
|
48
|
+
# AnsibleNotDetected
|
49
|
+
class AnsibleNotDetected < VagrantLocalError
|
50
|
+
error_key(:ansible_not_detected)
|
51
|
+
end
|
52
|
+
|
53
|
+
# AnsiblePlaybookNotDetected
|
54
|
+
class AnsiblePlaybookNotDetected < VagrantLocalError
|
55
|
+
error_key(:ansible_playbook_not_detected)
|
56
|
+
end
|
57
|
+
|
58
|
+
# NotYetImplemented
|
59
|
+
class NotYetImplemented < VagrantLocalError
|
60
|
+
error_key(:not_yet_implemented)
|
61
|
+
end
|
62
|
+
|
63
|
+
# TimeoutHalt
|
64
|
+
class TimeoutHalt < VagrantLocalError
|
65
|
+
error_key(:halt_timeout)
|
66
|
+
end
|
67
|
+
|
68
|
+
# InvalidbhyveBrand
|
69
|
+
class InvalidbhyveBrand < VagrantLocalError
|
70
|
+
error_key(:invalidbhyve_brand)
|
71
|
+
end
|
72
|
+
|
73
|
+
# InvalidLXBrand
|
74
|
+
class InvalidLXBrand < VagrantLocalError
|
75
|
+
error_key(:invalidLX_brand)
|
76
|
+
end
|
77
|
+
|
78
|
+
# ConsoleFailed
|
79
|
+
class ConsoleFailed < VagrantLocalError
|
80
|
+
error_key(:console_failed_exit)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'vagrant/util/busy'
|
4
|
+
require 'vagrant/util/subprocess'
|
5
|
+
|
6
|
+
module VagrantPlugins
|
7
|
+
module ProviderLocal
|
8
|
+
module Executor
|
9
|
+
# This class is used to execute commands as subprocess.
|
10
|
+
class Exec
|
11
|
+
# When we need the command's exit code we should set parameter
|
12
|
+
# exit_code to true, otherwise this method will return executed
|
13
|
+
# command's stdout
|
14
|
+
def execute(exit_code, *cmd, **_opts, &block)
|
15
|
+
# Append in the options for subprocess
|
16
|
+
cmd << { notify: %i[stdout stderr] }
|
17
|
+
|
18
|
+
cmd.unshift('sh', '-c')
|
19
|
+
interrupted = false
|
20
|
+
# Lambda to change interrupted to true
|
21
|
+
int_callback = -> { interrupted = true }
|
22
|
+
result = ::Vagrant::Util::Busy.busy(int_callback) do
|
23
|
+
::Vagrant::Util::Subprocess.execute(*cmd, &block)
|
24
|
+
end
|
25
|
+
return result.exit_code if exit_code
|
26
|
+
|
27
|
+
result.stderr.gsub!("\r\n", "\n")
|
28
|
+
result.stdout.gsub!("\r\n", "\n")
|
29
|
+
puts "Command Failed: #{cmd}" if result.exit_code != 0 || interrupted
|
30
|
+
puts "Exit Results: #{result.stderr}" if result.exit_code != 0 || interrupted
|
31
|
+
raise Errors::ExecuteError if result.exit_code != 0 || interrupted
|
32
|
+
|
33
|
+
result.stdout[0..-2]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'vagrant'
|
5
|
+
rescue LoadError
|
6
|
+
raise 'The Vagrant Local plugin must be run within Vagrant.'
|
7
|
+
end
|
8
|
+
|
9
|
+
module VagrantPlugins
|
10
|
+
module ProviderLocal
|
11
|
+
# This is a the plugin droping for the vagrant-local vagrant plugin
|
12
|
+
class Plugin < Vagrant.plugin('2')
|
13
|
+
name 'local'
|
14
|
+
description <<-DESC
|
15
|
+
This plugin allows vagrant to manage a host as a VM
|
16
|
+
DESC
|
17
|
+
|
18
|
+
config(:local, :provider) do
|
19
|
+
require_relative 'config'
|
20
|
+
Config
|
21
|
+
end
|
22
|
+
provider(:local, parallel: false) do
|
23
|
+
require_relative 'provider'
|
24
|
+
Provider
|
25
|
+
end
|
26
|
+
|
27
|
+
# This initializes the internationalization strings.
|
28
|
+
def self.setup_i18n
|
29
|
+
I18n.load_path << File.expand_path('locales/en.yml', ProviderLocal.source_root)
|
30
|
+
I18n.reload!
|
31
|
+
end
|
32
|
+
|
33
|
+
# This sets up our log level to be whatever VAGRANT_LOG is.
|
34
|
+
def self.setup_logging
|
35
|
+
require 'log4r'
|
36
|
+
|
37
|
+
level = nil
|
38
|
+
begin
|
39
|
+
level = Log4r.const_get(ENV['VAGRANT_LOG'].upcase)
|
40
|
+
rescue NameError
|
41
|
+
# This means that the logging constant wasn't found,
|
42
|
+
# which is fine. We just keep `level` as `nil`. But
|
43
|
+
# we tell the user.
|
44
|
+
level = nil
|
45
|
+
end
|
46
|
+
|
47
|
+
# Some constants, such as "true" resolve to booleans, so the
|
48
|
+
# above error checking doesn't catch it. This will check to make
|
49
|
+
# sure that the log level is an integer, as Log4r requires.
|
50
|
+
level = nil unless level.is_a?(Integer)
|
51
|
+
|
52
|
+
# Set the logging level on all "vagrant" namespaced
|
53
|
+
# logs as long as we have a valid level.
|
54
|
+
|
55
|
+
return unless level
|
56
|
+
|
57
|
+
logger = Log4r::Logger.new('vagrant_local')
|
58
|
+
logger.outputters = Log4r::Outputter.stderr
|
59
|
+
logger.level = level
|
60
|
+
logger
|
61
|
+
end
|
62
|
+
|
63
|
+
# Setup logging and i18n before any autoloading loads other classes
|
64
|
+
# with logging configured as this prevents inheritance of the log level
|
65
|
+
# from the parent logger.
|
66
|
+
setup_logging
|
67
|
+
setup_i18n
|
68
|
+
|
69
|
+
## This setups the local commands master
|
70
|
+
command('local') do
|
71
|
+
require_relative 'command/local'
|
72
|
+
Command::Local
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'vagrant'
|
4
|
+
require 'log4r'
|
5
|
+
|
6
|
+
module VagrantPlugins
|
7
|
+
# This is a module to assist in managing a Host
|
8
|
+
module ProviderLocal
|
9
|
+
autoload :Driver, 'vagrant-local/driver'
|
10
|
+
# This is a module to assist in managing a Host
|
11
|
+
class Provider < Vagrant.plugin('2', :provider)
|
12
|
+
def initialize(machine)
|
13
|
+
@logger = Log4r::Logger.new('vagrant::provider::local')
|
14
|
+
@machine = machine
|
15
|
+
super(machine)
|
16
|
+
end
|
17
|
+
|
18
|
+
def driver
|
19
|
+
return @driver if @driver
|
20
|
+
|
21
|
+
@driver = Driver.new(@machine)
|
22
|
+
end
|
23
|
+
|
24
|
+
def ssh_info
|
25
|
+
# We just return nil if were not able to identify the VM's IP and
|
26
|
+
# let Vagrant core deal with it like docker provider does
|
27
|
+
return nil if state.id != :running
|
28
|
+
return nil unless driver.get_ip_address
|
29
|
+
|
30
|
+
passwordauth = 'passwordauth'
|
31
|
+
ssh_info = {
|
32
|
+
host: driver.get_ip_address,
|
33
|
+
port: driver.sshport(@machine).to_s,
|
34
|
+
password: driver.vagrantuserpass(@machine).to_s,
|
35
|
+
username: driver.user(@machine),
|
36
|
+
private_key_path: driver.userprivatekeypath(@machine).to_s,
|
37
|
+
PasswordAuthentication: passwordauth
|
38
|
+
}
|
39
|
+
ssh_info unless ssh_info.nil?
|
40
|
+
end
|
41
|
+
|
42
|
+
# This should return an action callable for the given name.
|
43
|
+
# @param [Symbol] name Name of the action.
|
44
|
+
# @return [Object] A callable action sequence object, whether it
|
45
|
+
# is a proc, object, etc.
|
46
|
+
def action(name)
|
47
|
+
# Attempt to get the action method from the Action class if it
|
48
|
+
# exists, otherwise return nil to show that we don't support the
|
49
|
+
# given action
|
50
|
+
action_method = "action_#{name}"
|
51
|
+
return Action.send(action_method) if Action.respond_to?(action_method)
|
52
|
+
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
|
56
|
+
# This method is called if the underying machine ID changes. Providers
|
57
|
+
# can use this method to load in new data for the actual backing
|
58
|
+
# machine or to realize that the machine is now gone (the ID can
|
59
|
+
# become `nil`). No parameters are given, since the underlying machine
|
60
|
+
# is simply the machine instance given to this object. And no
|
61
|
+
# return value is necessary.
|
62
|
+
def machine_id_changed
|
63
|
+
nil
|
64
|
+
end
|
65
|
+
|
66
|
+
def state
|
67
|
+
state_id = nil
|
68
|
+
state_id = :not_created unless @machine.id
|
69
|
+
state_id = driver.state(@machine) if @machine.id && !state_id
|
70
|
+
# This is a special pseudo-state so that we don't set the
|
71
|
+
# NOT_CREATED_ID while we're setting up the machine. This avoids
|
72
|
+
# clearing the data dir.
|
73
|
+
state_id = :preparing if @machine.id == 'preparing'
|
74
|
+
# Get the short and long description
|
75
|
+
short = state_id.to_s.tr('_', ' ')
|
76
|
+
# If we're not created, then specify the special ID flag
|
77
|
+
state_id = Vagrant::MachineState::NOT_CREATED_ID if state_id == :not_created
|
78
|
+
# Return the MachineState object
|
79
|
+
Vagrant::MachineState.new(state_id, short, short)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'open3'
|
4
|
+
require 'log4r'
|
5
|
+
module VagrantPlugins
|
6
|
+
module ProviderLocal
|
7
|
+
module Util
|
8
|
+
# This shiny device polishes bared foos
|
9
|
+
class Subprocess
|
10
|
+
def initialize(cmd, &_block)
|
11
|
+
Open3.popen3(cmd) do |_stdin, stdout, stderr, thread|
|
12
|
+
# read each stream from a new thread
|
13
|
+
{ :out => stdout, :err => stderr }.each do |key, stream|
|
14
|
+
Thread.new do
|
15
|
+
until (line = stream.gets).nil?
|
16
|
+
# yield the block depending on the stream
|
17
|
+
if key == :out
|
18
|
+
yield line, nil, thread if block_given?
|
19
|
+
elsif block_given?
|
20
|
+
yield nil, line, thread
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
thread.join # don't exit until the external process is done
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module ProviderLocal
|
5
|
+
module Util
|
6
|
+
# This is a utlity to time commands and scripts
|
7
|
+
class Timer
|
8
|
+
# A basic utility method that times the execution of the given
|
9
|
+
# block and returns it.
|
10
|
+
def self.time
|
11
|
+
start_time = Time.now.to_f
|
12
|
+
yield
|
13
|
+
end_time = Time.now.to_f
|
14
|
+
end_time - start_time
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
|
5
|
+
module VagrantPlugins
|
6
|
+
# This is used to configure, manage, create and destroy local where vagrant by itself cannot
|
7
|
+
module ProviderLocal
|
8
|
+
lib_path = Pathname.new(File.expand_path('vagrant-local', __dir__))
|
9
|
+
autoload :Action, lib_path.join('action')
|
10
|
+
autoload :Executor, lib_path.join('executor')
|
11
|
+
autoload :Driver, lib_path.join('driver')
|
12
|
+
autoload :Errors, lib_path.join('errors')
|
13
|
+
# This function returns the path to the source of this plugin
|
14
|
+
# @return [Pathname]
|
15
|
+
def self.source_root
|
16
|
+
@source_root ||= Pathname.new(File.expand_path('..', __dir__))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
begin
|
22
|
+
require 'vagrant'
|
23
|
+
rescue LoadError
|
24
|
+
raise 'The Vagrant vagrant-local plugin must be run within Vagrant.'
|
25
|
+
end
|
26
|
+
|
27
|
+
raise 'The Vagrant vagrant-local plugin is only compatible with Vagrant 2+.' if Vagrant::VERSION < '2'
|
28
|
+
|
29
|
+
require 'vagrant-local/plugin'
|