vagrant-plugin-dummy 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.
- data/.gitignore +20 -0
- data/Gemfile +11 -0
- data/README.md +24 -0
- data/Rakefile +15 -0
- data/lib/vagrant-plugin-dummy/communication/communicator.rb +51 -0
- data/lib/vagrant-plugin-dummy/errors.rb +13 -0
- data/lib/vagrant-plugin-dummy/guest/dummy.rb +48 -0
- data/lib/vagrant-plugin-dummy/monkey_patches/lib/vagrant/machine.rb +27 -0
- data/lib/vagrant-plugin-dummy/plugin.rb +100 -0
- data/lib/vagrant-plugin-dummy/version.rb +3 -0
- data/lib/vagrant-plugin-dummy.rb +24 -0
- data/locales/en.yml +8 -0
- data/oldgit/FETCH_HEAD +4 -0
- data/oldgit/HEAD +1 -0
- data/oldgit/ORIG_HEAD +1 -0
- data/oldgit/config +12 -0
- data/oldgit/description +1 -0
- data/oldgit/hooks/applypatch-msg.sample +15 -0
- data/oldgit/hooks/commit-msg.sample +24 -0
- data/oldgit/hooks/post-update.sample +8 -0
- data/oldgit/hooks/pre-applypatch.sample +14 -0
- data/oldgit/hooks/pre-commit.sample +50 -0
- data/oldgit/hooks/pre-rebase.sample +169 -0
- data/oldgit/hooks/prepare-commit-msg.sample +36 -0
- data/oldgit/hooks/update.sample +128 -0
- data/oldgit/index +0 -0
- data/oldgit/info/exclude +6 -0
- data/oldgit/logs/HEAD +13 -0
- data/oldgit/logs/refs/heads/dummy-master +1 -0
- data/oldgit/logs/refs/heads/master +2 -0
- data/oldgit/logs/refs/heads/vagrant-1.2 +3 -0
- data/oldgit/logs/refs/remotes/origin/HEAD +1 -0
- data/oldgit/logs/refs/remotes/origin/chef-schtasks +1 -0
- data/oldgit/logs/refs/remotes/origin/master +2 -0
- data/oldgit/logs/refs/remotes/origin/vagrant-1.2 +3 -0
- data/oldgit/logs/refs/remotes/origin/winrm-2.0 +1 -0
- data/oldgit/objects/pack/pack-829e113048479ca488917c38a7779511189ee623.idx +0 -0
- data/oldgit/objects/pack/pack-829e113048479ca488917c38a7779511189ee623.pack +0 -0
- data/oldgit/objects/pack/pack-9d783f03b5d312d0eb7c60c232336524cf240841.idx +0 -0
- data/oldgit/objects/pack/pack-9d783f03b5d312d0eb7c60c232336524cf240841.pack +0 -0
- data/oldgit/objects/pack/pack-fc30e147a30fce4b4b0e300c3cdb4743945456d4.idx +0 -0
- data/oldgit/objects/pack/pack-fc30e147a30fce4b4b0e300c3cdb4743945456d4.pack +0 -0
- data/oldgit/packed-refs +9 -0
- data/oldgit/refs/heads/dummy-master +1 -0
- data/oldgit/refs/heads/master +1 -0
- data/oldgit/refs/heads/vagrant-1.2 +1 -0
- data/oldgit/refs/remotes/origin/chef-schtasks +1 -0
- data/oldgit/refs/remotes/origin/master +1 -0
- data/oldgit/refs/remotes/origin/vagrant-1.2 +1 -0
- data/oldgit/refs/remotes/origin/winrm-2.0 +1 -0
- data/spec/vagrant-windows/config_spec.rb +58 -0
- data/spec/vagrant-windows/guestnetwork_spec.rb +48 -0
- data/spec/vagrant-windows/helper_spec.rb +38 -0
- data/spec/vagrant-windows/winrmcommunicator_spec.rb +27 -0
- data/vagrant-plugin-dummy.gemspec +53 -0
- data/windows/communication/guestnetwork.rb +133 -0
- data/windows/communication/winrmcommunicator.rb +120 -0
- data/windows/communication/winrmfinder.rb +45 -0
- data/windows/communication/winrmshell.rb +141 -0
- data/windows/config/windows.rb +35 -0
- data/windows/config/winrm.rb +51 -0
- data/windows/errors.rb +27 -0
- data/windows/guest/cap/change_host_name.rb +14 -0
- data/windows/guest/cap/configure_networks.rb +69 -0
- data/windows/guest/cap/halt.rb +22 -0
- data/windows/guest/cap/mount_virtualbox_shared_folder.rb +17 -0
- data/windows/guest/cap/mount_vmware_shared_folder.rb +15 -0
- data/windows/guest/windows.rb +71 -0
- data/windows/helper.rb +19 -0
- data/windows/monkey_patches/lib/vagrant/machine.rb +32 -0
- data/windows/monkey_patches/plugins/providers/virtualbox/action/share_folders.rb +44 -0
- data/windows/monkey_patches/plugins/providers/virtualbox/driver/version_4_2.rb +20 -0
- data/windows/monkey_patches/plugins/provisioners/chef/provisioner/chef_client.rb +1 -0
- data/windows/monkey_patches/plugins/provisioners/chef/provisioner/chef_solo.rb +106 -0
- data/windows/monkey_patches/plugins/provisioners/puppet/provisioner/puppet.rb +101 -0
- data/windows/monkey_patches/plugins/provisioners/puppet/provisioner/puppet_server.rb +1 -0
- data/windows/monkey_patches/plugins/provisioners/shell/provisioner.rb +89 -0
- data/windows/plugin.rb +129 -0
- data/windows/scripts/cheftask.ps1.erb +47 -0
- data/windows/scripts/cheftask.xml.erb +45 -0
- data/windows/scripts/cheftaskrun.ps1.erb +16 -0
- data/windows/scripts/command_alias.ps1 +36 -0
- data/windows/scripts/mount_volume.virtualbox.ps1.erb +49 -0
- data/windows/scripts/mount_volume.vmware.ps1.erb +49 -0
- data/windows/scripts/set_work_network.ps1 +6 -0
- data/windows/scripts/winrs_v3_get_adapters.ps1 +11 -0
- data/windows/version.rb +3 -0
- metadata +207 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require "#{Vagrant::source_root}/plugins/providers/virtualbox/action/share_folders"
|
|
2
|
+
require_relative '../../../../../helper'
|
|
3
|
+
|
|
4
|
+
module VagrantPlugins
|
|
5
|
+
module ProviderVirtualBox
|
|
6
|
+
module Action
|
|
7
|
+
class ShareFolders
|
|
8
|
+
include VagrantWindows::Helper
|
|
9
|
+
|
|
10
|
+
alias_method :original_create_metadata, :create_metadata
|
|
11
|
+
|
|
12
|
+
def create_metadata
|
|
13
|
+
|
|
14
|
+
unless @env[:machine].is_windows?
|
|
15
|
+
# don't change the shared folder name for linux guests. We don't want the shared folder name of linux guests to be different
|
|
16
|
+
# depending on whether the vagrant-windows plugin is installed or not.
|
|
17
|
+
original_create_metadata
|
|
18
|
+
else
|
|
19
|
+
@env[:ui].info I18n.t("vagrant.actions.vm.share_folders.creating")
|
|
20
|
+
|
|
21
|
+
folders = []
|
|
22
|
+
shared_folders.each do |id, data|
|
|
23
|
+
hostpath = File.expand_path(data[:hostpath], @env[:root_path])
|
|
24
|
+
hostpath = Vagrant::Util::Platform.cygwin_windows_path(hostpath)
|
|
25
|
+
|
|
26
|
+
folder_name = win_friendly_share_id(id.gsub(/[\/\/]/,'_').sub(/^_/, ''))
|
|
27
|
+
|
|
28
|
+
folders << {
|
|
29
|
+
:name => folder_name,
|
|
30
|
+
:hostpath => hostpath,
|
|
31
|
+
:transient => data[:transient]
|
|
32
|
+
}
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
@env[:machine].provider.driver.share_folders(folders)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module VagrantPlugins
|
|
2
|
+
module ProviderVirtualBox
|
|
3
|
+
module Driver
|
|
4
|
+
class Version_4_2
|
|
5
|
+
def read_mac_addresses
|
|
6
|
+
macs = {}
|
|
7
|
+
info = execute("showvminfo", @uuid, "--machinereadable", :retryable => true)
|
|
8
|
+
info.split("\n").each do |line|
|
|
9
|
+
if matcher = /^macaddress(\d+)="(.+?)"$/.match(line)
|
|
10
|
+
adapter = matcher[1].to_i
|
|
11
|
+
mac = matcher[2].to_s
|
|
12
|
+
macs[adapter] = mac
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
macs
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# TODO: support Chef client
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
require 'tempfile'
|
|
2
|
+
require "#{Vagrant::source_root}/plugins/provisioners/chef/provisioner/chef_solo"
|
|
3
|
+
require_relative '../../../../../helper'
|
|
4
|
+
|
|
5
|
+
module VagrantPlugins
|
|
6
|
+
module Chef
|
|
7
|
+
module Provisioner
|
|
8
|
+
class ChefSolo < Base
|
|
9
|
+
|
|
10
|
+
include VagrantWindows::Helper
|
|
11
|
+
|
|
12
|
+
run_chef_solo_on_linux = instance_method(:run_chef_solo)
|
|
13
|
+
|
|
14
|
+
# This patch is needed until Vagrant supports chef on Windows guests
|
|
15
|
+
define_method(:run_chef_solo) do
|
|
16
|
+
is_windows ? run_chef_solo_on_windows() : run_chef_solo_on_linux.bind(self).()
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def run_chef_solo_on_windows
|
|
20
|
+
# create cheftaskrun.ps1 that the scheduled task will invoke when run
|
|
21
|
+
render_file_and_upload("cheftaskrun.ps1", chef_script_options[:chef_task_run_ps1], :options => chef_script_options)
|
|
22
|
+
|
|
23
|
+
# create cheftask.xml that the scheduled task will be created with
|
|
24
|
+
render_file_and_upload("cheftask.xml", chef_script_options[:chef_task_xml], :options => chef_script_options)
|
|
25
|
+
|
|
26
|
+
# create cheftask.ps1 that will immediately invoke the scheduled task and wait for completion
|
|
27
|
+
render_file_and_upload("cheftask.ps1", chef_script_options[:chef_task_ps1], :options => chef_script_options)
|
|
28
|
+
|
|
29
|
+
command = <<-EOH
|
|
30
|
+
$old = Get-ExecutionPolicy;
|
|
31
|
+
Set-ExecutionPolicy Unrestricted -force;
|
|
32
|
+
#{chef_script_options[:chef_task_ps1]};
|
|
33
|
+
Set-ExecutionPolicy $old -force
|
|
34
|
+
exit $LASTEXITCODE
|
|
35
|
+
EOH
|
|
36
|
+
|
|
37
|
+
@config.attempts.times do |attempt|
|
|
38
|
+
if attempt == 0
|
|
39
|
+
@machine.env.ui.info I18n.t("vagrant.provisioners.chef.running_solo")
|
|
40
|
+
else
|
|
41
|
+
@machine.env.ui.info I18n.t("vagrant.provisioners.chef.running_solo_again")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
exit_status = @machine.communicate.execute(command) do |type, data|
|
|
45
|
+
# Output the data with the proper color based on the stream.
|
|
46
|
+
color = type == :stdout ? :green : :red
|
|
47
|
+
|
|
48
|
+
@machine.env.ui.info(
|
|
49
|
+
data, :color => color, :new_line => false, :prefix => false)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# There is no need to run Chef again if it converges
|
|
53
|
+
return if exit_status == 0
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# If we reached this point then Chef never converged! Error.
|
|
57
|
+
raise ChefError, :no_convergence
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def render_file_and_upload(script_name, dest_file, options)
|
|
61
|
+
script_contents = VagrantWindows.load_script_template(script_name, options)
|
|
62
|
+
|
|
63
|
+
# render cheftaskrun.ps1 to local temp file
|
|
64
|
+
script_local = Tempfile.new(script_name)
|
|
65
|
+
IO.write(script_local, script_contents)
|
|
66
|
+
|
|
67
|
+
# upload cheftaskrun.ps1 file
|
|
68
|
+
@machine.communicate.upload(script_local, dest_file)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def chef_script_options
|
|
72
|
+
if @chef_script_options.nil?
|
|
73
|
+
command_env = @config.binary_env ? "#{@config.binary_env} " : ""
|
|
74
|
+
command_args = @config.arguments ? " #{@config.arguments}" : ""
|
|
75
|
+
chef_solo_path = win_friendly_path(File.join(@config.provisioning_path, 'solo.rb'))
|
|
76
|
+
chef_dna_path = win_friendly_path(File.join(@config.provisioning_path, 'dna.json'))
|
|
77
|
+
|
|
78
|
+
chef_arguments = "-c #{chef_solo_path} "
|
|
79
|
+
chef_arguments << "-j #{chef_dna_path} "
|
|
80
|
+
chef_arguments << "#{command_args}"
|
|
81
|
+
|
|
82
|
+
@chef_script_options = {
|
|
83
|
+
:user => @machine.config.winrm.username,
|
|
84
|
+
:pass => @machine.config.winrm.password,
|
|
85
|
+
:chef_arguments => chef_arguments,
|
|
86
|
+
:chef_task_xml => win_friendly_path("#{@config.provisioning_path}/cheftask.xml"),
|
|
87
|
+
:chef_task_running => win_friendly_path("#{@config.provisioning_path}/cheftask.running"),
|
|
88
|
+
:chef_task_exitcode => win_friendly_path("#{@config.provisioning_path}/cheftask.exitcode"),
|
|
89
|
+
:chef_task_ps1 => win_friendly_path("#{@config.provisioning_path}/cheftask.ps1"),
|
|
90
|
+
:chef_task_run_ps1 => win_friendly_path("#{@config.provisioning_path}/cheftaskrun.ps1"),
|
|
91
|
+
:chef_stdout_log => win_friendly_path("#{@config.provisioning_path}/chef-solo.log"),
|
|
92
|
+
:chef_stderr_log => win_friendly_path("#{@config.provisioning_path}/chef-solo.err.log"),
|
|
93
|
+
:chef_binary_path => win_friendly_path("#{command_env}#{chef_binary_path("chef-solo")}")
|
|
94
|
+
}
|
|
95
|
+
end
|
|
96
|
+
@chef_script_options
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def is_windows
|
|
100
|
+
@machine.config.vm.guest.eql? :windows
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
end # ChefSolo class
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
require "#{Vagrant::source_root}/plugins/provisioners/puppet/provisioner/puppet"
|
|
2
|
+
|
|
3
|
+
module VagrantPlugins
|
|
4
|
+
module Puppet
|
|
5
|
+
module Provisioner
|
|
6
|
+
class Puppet < Vagrant.plugin("2", :provisioner)
|
|
7
|
+
|
|
8
|
+
# This patch is needed until Vagrant supports Puppet on Windows guests
|
|
9
|
+
run_puppet_apply_on_linux = instance_method(:run_puppet_apply)
|
|
10
|
+
configure_on_linux = instance_method(:configure)
|
|
11
|
+
|
|
12
|
+
define_method(:run_puppet_apply) do
|
|
13
|
+
is_windows ? run_puppet_apply_on_windows() : run_puppet_apply_on_linux.bind(self).()
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
define_method(:configure) do |root_config|
|
|
17
|
+
is_windows ? configure_on_windows(root_config) : configure_on_linux.bind(self).(root_config)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def run_puppet_apply_on_windows
|
|
21
|
+
options = [config.options].flatten
|
|
22
|
+
module_paths = @module_paths.map { |_, to| to }
|
|
23
|
+
if !@module_paths.empty?
|
|
24
|
+
# Prepend the default module path
|
|
25
|
+
module_paths.unshift("/ProgramData/PuppetLabs/puppet/etc/modules")
|
|
26
|
+
|
|
27
|
+
# Add the command line switch to add the module path
|
|
28
|
+
options << "--modulepath '#{module_paths.join(';')}'"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
options << @manifest_file
|
|
32
|
+
options = options.join(" ")
|
|
33
|
+
|
|
34
|
+
# Build up the custom facts if we have any
|
|
35
|
+
facter = ""
|
|
36
|
+
if !config.facter.empty?
|
|
37
|
+
facts = []
|
|
38
|
+
config.facter.each do |key, value|
|
|
39
|
+
facts << "$env:FACTER_#{key}='#{value}';"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
facter = "#{facts.join(" ")} "
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
command = "cd #{manifests_guest_path}; if($?) \{ #{facter} puppet apply #{options} \}"
|
|
46
|
+
|
|
47
|
+
@machine.env.ui.info I18n.t("vagrant.provisioners.puppet.running_puppet",
|
|
48
|
+
:manifest => @manifest_file)
|
|
49
|
+
|
|
50
|
+
@machine.communicate.sudo(command) do |type, data|
|
|
51
|
+
if !data.empty?
|
|
52
|
+
@machine.env.ui.info(data, :new_line => false, :prefix => false)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def configure_on_windows(root_config)
|
|
58
|
+
# Calculate the paths we're going to use based on the environment
|
|
59
|
+
root_path = @machine.env.root_path
|
|
60
|
+
@expanded_manifests_path = @config.expanded_manifests_path(root_path)
|
|
61
|
+
@expanded_module_paths = @config.expanded_module_paths(root_path)
|
|
62
|
+
@manifest_file = @config.manifest_file
|
|
63
|
+
|
|
64
|
+
# Setup the module paths
|
|
65
|
+
@module_paths = []
|
|
66
|
+
@expanded_module_paths.each_with_index do |path, i|
|
|
67
|
+
@module_paths << [path, File.join(config.temp_dir, "modules-#{i}")]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
@logger.debug("Syncing folders from puppet configure")
|
|
71
|
+
@logger.debug("manifests_guest_path = #{manifests_guest_path}")
|
|
72
|
+
@logger.debug("expanded_manifests_path = #{@expanded_manifests_path}")
|
|
73
|
+
|
|
74
|
+
# Windows guest volume mounting fails without an "id" specified
|
|
75
|
+
# This hacks around that problem and allows the PS mount script to work
|
|
76
|
+
root_config.vm.synced_folder(
|
|
77
|
+
@expanded_manifests_path, manifests_guest_path,
|
|
78
|
+
:id => "v-manifests-1")
|
|
79
|
+
|
|
80
|
+
# Share the manifests directory with the guest
|
|
81
|
+
#root_config.vm.synced_folder(
|
|
82
|
+
# @expanded_manifests_path, manifests_guest_path)
|
|
83
|
+
|
|
84
|
+
# Share the module paths
|
|
85
|
+
count = 0
|
|
86
|
+
@module_paths.each do |from, to|
|
|
87
|
+
# Sorry for the cryptic key here, but VirtualBox has a strange limit on
|
|
88
|
+
# maximum size for it and its something small (around 10)
|
|
89
|
+
root_config.vm.synced_folder(from, to, :id => "v-modules-#{count}")
|
|
90
|
+
count += 1
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def is_windows
|
|
95
|
+
@machine.config.vm.guest.eql? :windows
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
end # Puppet class
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#TODO: Support Puppet server
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
require "#{Vagrant::source_root}/plugins/provisioners/shell/provisioner"
|
|
2
|
+
require_relative '../../../../helper'
|
|
3
|
+
|
|
4
|
+
module VagrantPlugins
|
|
5
|
+
module Shell
|
|
6
|
+
class Provisioner < Vagrant.plugin("2", :provisioner)
|
|
7
|
+
|
|
8
|
+
include VagrantWindows::Helper
|
|
9
|
+
|
|
10
|
+
# This patch is needed until Vagrant supports Puppet on Windows guests
|
|
11
|
+
provision_on_linux = instance_method(:provision)
|
|
12
|
+
|
|
13
|
+
define_method(:provision) do
|
|
14
|
+
is_windows ? provision_on_windows() : provision_on_linux.bind(self).()
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def provision_on_windows
|
|
18
|
+
args = ""
|
|
19
|
+
args = " #{config.args}" if config.args
|
|
20
|
+
|
|
21
|
+
with_script_file do |path|
|
|
22
|
+
# Upload the script to the machine
|
|
23
|
+
@machine.communicate.tap do |comm|
|
|
24
|
+
# Ensure the uploaded script has a file extension, by default
|
|
25
|
+
# config.upload_path from vagrant core does not
|
|
26
|
+
fixed_upload_path = if File.extname(config.upload_path) == ""
|
|
27
|
+
"#{config.upload_path}#{File.extname(path.to_s)}"
|
|
28
|
+
else
|
|
29
|
+
config.upload_path
|
|
30
|
+
end
|
|
31
|
+
comm.upload(path.to_s, fixed_upload_path)
|
|
32
|
+
|
|
33
|
+
command = <<-EOH
|
|
34
|
+
$old = Get-ExecutionPolicy;
|
|
35
|
+
Set-ExecutionPolicy Unrestricted -force;
|
|
36
|
+
#{win_friendly_path(fixed_upload_path)}#{args};
|
|
37
|
+
Set-ExecutionPolicy $old -force
|
|
38
|
+
EOH
|
|
39
|
+
|
|
40
|
+
# Execute it with sudo
|
|
41
|
+
comm.sudo(command) do |type, data|
|
|
42
|
+
if [:stderr, :stdout].include?(type)
|
|
43
|
+
# Output the data with the proper color based on the stream.
|
|
44
|
+
color = type == :stdout ? :green : :red
|
|
45
|
+
|
|
46
|
+
@machine.ui.info(
|
|
47
|
+
data,
|
|
48
|
+
:color => color, :new_line => false, :prefix => false)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
protected
|
|
58
|
+
|
|
59
|
+
# This method yields the path to a script to upload and execute
|
|
60
|
+
# on the remote server. This method will properly clean up the
|
|
61
|
+
# script file if needed.
|
|
62
|
+
def with_script_file
|
|
63
|
+
if config.path
|
|
64
|
+
# Just yield the path to that file...
|
|
65
|
+
yield config.path
|
|
66
|
+
else
|
|
67
|
+
# Otherwise we have an inline script, we need to Tempfile it,
|
|
68
|
+
# and handle it specially...
|
|
69
|
+
file = Tempfile.new(['vagrant-powershell', '.ps1'])
|
|
70
|
+
|
|
71
|
+
begin
|
|
72
|
+
file.write(config.inline)
|
|
73
|
+
file.fsync
|
|
74
|
+
file.close
|
|
75
|
+
yield file.path
|
|
76
|
+
ensure
|
|
77
|
+
file.close
|
|
78
|
+
file.unlink
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def is_windows
|
|
84
|
+
@machine.config.vm.guest.eql? :windows
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
end # Provisioner class
|
|
88
|
+
end
|
|
89
|
+
end
|
data/windows/plugin.rb
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require "vagrant"
|
|
3
|
+
rescue LoadError
|
|
4
|
+
raise "The Vagrant Windows plugin must be run within Vagrant."
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
# This is a sanity check to make sure no one is attempting to install
|
|
8
|
+
# this into an early Vagrant version.
|
|
9
|
+
if Vagrant::VERSION < "1.1.0"
|
|
10
|
+
raise "The Vagrant Windows plugin is only compatible with Vagrant 1.1+"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
if Vagrant::VERSION >= "1.2.0"
|
|
14
|
+
# Monkey Patch the virtualbox share_folders action to make valid share names on windows
|
|
15
|
+
require_relative "monkey_patches/plugins/providers/virtualbox/action/share_folders"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Monkey patch the vbox42 driver to support read mac addresses
|
|
19
|
+
require_relative "monkey_patches/plugins/providers/virtualbox/driver/version_4_2"
|
|
20
|
+
|
|
21
|
+
# Monkey Patch the VM object to support multiple channels, i.e. WinRM
|
|
22
|
+
require_relative "monkey_patches/lib/vagrant/machine"
|
|
23
|
+
|
|
24
|
+
# Monkey patch the Puppet provisioners to support PowerShell/Windows
|
|
25
|
+
require_relative "monkey_patches/plugins/provisioners/puppet/provisioner/puppet"
|
|
26
|
+
require_relative "monkey_patches/plugins/provisioners/puppet/provisioner/puppet_server"
|
|
27
|
+
|
|
28
|
+
# Monkey patch the Chef provisioners to support PowerShell/Windows
|
|
29
|
+
require_relative "monkey_patches/plugins/provisioners/chef/provisioner/chef_solo"
|
|
30
|
+
require_relative "monkey_patches/plugins/provisioners/chef/provisioner/chef_client"
|
|
31
|
+
|
|
32
|
+
# Monkey patch the shell provisioner to support PowerShell/batch/exe/Windows/etc
|
|
33
|
+
require_relative "monkey_patches/plugins/provisioners/shell/provisioner"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
module VagrantWindows
|
|
37
|
+
class Plugin < Vagrant.plugin("2")
|
|
38
|
+
name "Windows guest"
|
|
39
|
+
description <<-DESC
|
|
40
|
+
This plugin installs a provider that allows Vagrant to manage
|
|
41
|
+
Windows machines as guests.
|
|
42
|
+
DESC
|
|
43
|
+
|
|
44
|
+
config(:windows) do
|
|
45
|
+
require_relative "config/windows"
|
|
46
|
+
VagrantWindows::Config::Windows
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
config(:winrm) do
|
|
50
|
+
require_relative "config/winrm"
|
|
51
|
+
VagrantWindows::Config::WinRM
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
guest(:windows) do
|
|
55
|
+
require_relative "guest/windows"
|
|
56
|
+
VagrantWindows::Guest::Windows
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Vagrant 1.2 introduced the concept of capabilities instead of implementing
|
|
60
|
+
# an interface on the guest.
|
|
61
|
+
if Vagrant::VERSION >= "1.2.0"
|
|
62
|
+
|
|
63
|
+
guest_capability(:windows, :change_host_name) do
|
|
64
|
+
require_relative "guest/cap/change_host_name"
|
|
65
|
+
VagrantWindows::Guest::Cap::ChangeHostName
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
guest_capability(:windows, :configure_networks) do
|
|
69
|
+
require_relative "guest/cap/configure_networks"
|
|
70
|
+
VagrantWindows::Guest::Cap::ConfigureNetworks
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
guest_capability(:windows, :halt) do
|
|
74
|
+
require_relative "guest/cap/halt"
|
|
75
|
+
VagrantWindows::Guest::Cap::Halt
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
guest_capability(:windows, :mount_virtualbox_shared_folder) do
|
|
79
|
+
require_relative "guest/cap/mount_virtualbox_shared_folder"
|
|
80
|
+
VagrantWindows::Guest::Cap::MountVirtualBoxSharedFolder
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
guest_capability(:windows, :mount_vmware_shared_folder) do
|
|
84
|
+
require_relative "guest/cap/mount_vmware_shared_folder"
|
|
85
|
+
VagrantWindows::Guest::Cap::MountVMwareSharedFolder
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# This initializes the internationalization strings.
|
|
91
|
+
def self.setup_i18n
|
|
92
|
+
I18n.load_path << File.expand_path("locales/en.yml", VagrantWindows.vagrant_windows_root)
|
|
93
|
+
I18n.reload!
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# This sets up our log level to be whatever VAGRANT_LOG is.
|
|
97
|
+
def self.setup_logging
|
|
98
|
+
require "log4r"
|
|
99
|
+
|
|
100
|
+
level = nil
|
|
101
|
+
begin
|
|
102
|
+
level = Log4r.const_get(ENV["VAGRANT_LOG"].upcase)
|
|
103
|
+
rescue NameError
|
|
104
|
+
# This means that the logging constant wasn't found,
|
|
105
|
+
# which is fine. We just keep `level` as `nil`. But
|
|
106
|
+
# we tell the user.
|
|
107
|
+
level = nil
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Some constants, such as "true" resolve to booleans, so the
|
|
111
|
+
# above error checking doesn't catch it. This will check to make
|
|
112
|
+
# sure that the log level is an integer, as Log4r requires.
|
|
113
|
+
level = nil if !level.is_a?(Integer)
|
|
114
|
+
|
|
115
|
+
# Set the logging level on all "vagrant" namespaced
|
|
116
|
+
# logs as long as we have a valid level.
|
|
117
|
+
if level
|
|
118
|
+
logger = Log4r::Logger.new("vagrant_windows")
|
|
119
|
+
logger.outputters = Log4r::Outputter.stderr
|
|
120
|
+
logger.level = level
|
|
121
|
+
logger = nil
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
VagrantWindows::Plugin.setup_logging()
|
|
129
|
+
VagrantWindows::Plugin.setup_i18n()
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
schtasks /query /tn "chef-solo" | Out-Null
|
|
2
|
+
if ($?) {
|
|
3
|
+
# task already exists, kill it
|
|
4
|
+
schtasks /delete /tn "chef-solo" /f | Out-Null
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
# Ensure the chef task running file doesn't exist from a previous failure
|
|
8
|
+
if (Test-Path "<%= options[:chef_task_running] %>") {
|
|
9
|
+
del "<%= options[:chef_task_running] %>"
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
# schedule the task to run once in the far distant future
|
|
13
|
+
schtasks /create /tn "chef-solo" /xml "<%= options[:chef_task_xml] %>" /ru "<%= options[:user] %>" /rp "<%= options[:pass] %>" | Out-Null
|
|
14
|
+
|
|
15
|
+
# start the scheduled task right now
|
|
16
|
+
schtasks /run /tn "chef-solo" | Out-Null
|
|
17
|
+
|
|
18
|
+
# wait for run_chef.ps1 to start or timeout after 1 minute
|
|
19
|
+
$timeoutSeconds = 60
|
|
20
|
+
$elapsedSeconds = 0
|
|
21
|
+
while ( (!(Test-Path "<%= options[:chef_task_running] %>")) -and ($elapsedSeconds -lt $timeoutSeconds) ) {
|
|
22
|
+
Start-Sleep -s 1
|
|
23
|
+
$elapsedSeconds++
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if ($elapsedSeconds -ge $timeoutSeconds) {
|
|
27
|
+
Write-Error "Timed out waiting for chef scheduled task to start"
|
|
28
|
+
exit -2
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
# read the entire file, but only write out new lines we haven't seen before
|
|
32
|
+
$numLinesRead = 0
|
|
33
|
+
$success = $TRUE
|
|
34
|
+
while (Test-Path "<%= options[:chef_task_running] %>") {
|
|
35
|
+
Start-Sleep -m 100
|
|
36
|
+
|
|
37
|
+
$text = (get-content "<%= options[:chef_stdout_log] %>")
|
|
38
|
+
$numLines = ($text | Measure-Object -line).lines
|
|
39
|
+
$numLinesToRead = $numLines - $numLinesRead
|
|
40
|
+
|
|
41
|
+
$text | select -first $numLinesToRead -skip $numLinesRead | ForEach {
|
|
42
|
+
Write-Host "$_"
|
|
43
|
+
}
|
|
44
|
+
$numLinesRead += $numLinesToRead
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
exit Get-Content "<%= options[:chef_task_exitcode] %>"
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-16"?>
|
|
2
|
+
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
|
|
3
|
+
<RegistrationInfo>
|
|
4
|
+
<Date>2013-06-21T22:41:43</Date>
|
|
5
|
+
<Author>Administrator</Author>
|
|
6
|
+
</RegistrationInfo>
|
|
7
|
+
<Triggers>
|
|
8
|
+
<TimeTrigger>
|
|
9
|
+
<StartBoundary>2045-01-01T12:00:00</StartBoundary>
|
|
10
|
+
<Enabled>true</Enabled>
|
|
11
|
+
</TimeTrigger>
|
|
12
|
+
</Triggers>
|
|
13
|
+
<Principals>
|
|
14
|
+
<Principal id="Author">
|
|
15
|
+
<UserId>vagrant</UserId>
|
|
16
|
+
<LogonType>Password</LogonType>
|
|
17
|
+
<RunLevel>HighestAvailable</RunLevel>
|
|
18
|
+
</Principal>
|
|
19
|
+
</Principals>
|
|
20
|
+
<Settings>
|
|
21
|
+
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
|
|
22
|
+
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
|
|
23
|
+
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
|
|
24
|
+
<AllowHardTerminate>true</AllowHardTerminate>
|
|
25
|
+
<StartWhenAvailable>false</StartWhenAvailable>
|
|
26
|
+
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
|
|
27
|
+
<IdleSettings>
|
|
28
|
+
<StopOnIdleEnd>true</StopOnIdleEnd>
|
|
29
|
+
<RestartOnIdle>false</RestartOnIdle>
|
|
30
|
+
</IdleSettings>
|
|
31
|
+
<AllowStartOnDemand>true</AllowStartOnDemand>
|
|
32
|
+
<Enabled>true</Enabled>
|
|
33
|
+
<Hidden>false</Hidden>
|
|
34
|
+
<RunOnlyIfIdle>false</RunOnlyIfIdle>
|
|
35
|
+
<WakeToRun>false</WakeToRun>
|
|
36
|
+
<ExecutionTimeLimit>PT2H</ExecutionTimeLimit>
|
|
37
|
+
<Priority>7</Priority>
|
|
38
|
+
</Settings>
|
|
39
|
+
<Actions Context="Author">
|
|
40
|
+
<Exec>
|
|
41
|
+
<Command>powershell</Command>
|
|
42
|
+
<Arguments>-file <%= options[:chef_task_run_ps1] %></Arguments>
|
|
43
|
+
</Exec>
|
|
44
|
+
</Actions>
|
|
45
|
+
</Task>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
$exitCode = -1
|
|
2
|
+
Set-ExecutionPolicy Unrestricted -force;
|
|
3
|
+
|
|
4
|
+
Try
|
|
5
|
+
{
|
|
6
|
+
"running" | Out-File "<%= options[:chef_task_running] %>"
|
|
7
|
+
$process = (Start-Process "<%= options[:chef_binary_path] %>" -ArgumentList "<%= options[:chef_arguments] %>" -NoNewWindow -PassThru -Wait -RedirectStandardOutput "<%= options[:chef_stdout_log] %>" -RedirectStandardError "<%= options[:chef_stderr_log] %>")
|
|
8
|
+
$exitCode = $process.ExitCode
|
|
9
|
+
}
|
|
10
|
+
Finally
|
|
11
|
+
{
|
|
12
|
+
$exitCode | Out-File "<%= options[:chef_task_exitcode] %>"
|
|
13
|
+
del "<%= options[:chef_task_running] %>"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
exit $exitCode
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
function which {
|
|
2
|
+
$command = [Array](Get-Command $args[0] -errorAction SilentlyContinue)
|
|
3
|
+
if($null -eq $command)
|
|
4
|
+
{
|
|
5
|
+
exit 1
|
|
6
|
+
}
|
|
7
|
+
write-host $command[0].Definition
|
|
8
|
+
exit 0
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function test ([Switch] $d, [String] $path) {
|
|
12
|
+
if(Test-Path $path)
|
|
13
|
+
{
|
|
14
|
+
exit 0
|
|
15
|
+
}
|
|
16
|
+
exit 1
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function chmod {
|
|
20
|
+
exit 0
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function chown {
|
|
24
|
+
exit 0
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function mkdir ([Switch] $p, [String] $path)
|
|
28
|
+
{
|
|
29
|
+
if(Test-Path $path)
|
|
30
|
+
{
|
|
31
|
+
exit 0
|
|
32
|
+
} else {
|
|
33
|
+
New-Item $path -Type Directory -Force | Out-Null
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|