vagrant-azure 1.0.5 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +19 -15
- data/CHANGELOG.md +24 -24
- data/Gemfile +20 -15
- data/LICENSE +4 -4
- data/README.md +189 -125
- data/Rakefile +15 -14
- data/lib/vagrant-azure.rb +31 -33
- data/lib/vagrant-azure/action.rb +267 -243
- data/lib/vagrant-azure/action/connect_azure.rb +49 -46
- data/lib/vagrant-azure/action/os_type.rb +34 -0
- data/lib/vagrant-azure/action/powershell_run.rb +28 -0
- data/lib/vagrant-azure/action/provision.rb +42 -49
- data/lib/vagrant-azure/action/rdp.rb +63 -62
- data/lib/vagrant-azure/action/read_ssh_info.rb +54 -51
- data/lib/vagrant-azure/action/read_state.rb +47 -46
- data/lib/vagrant-azure/action/read_winrm_info.rb +57 -0
- data/lib/vagrant-azure/action/restart_vm.rb +28 -27
- data/lib/vagrant-azure/action/run_instance.rb +123 -115
- data/lib/vagrant-azure/action/start_instance.rb +35 -35
- data/lib/vagrant-azure/action/stop_instance.rb +42 -38
- data/lib/vagrant-azure/action/sync_folders.rb +64 -63
- data/lib/vagrant-azure/action/terminate_instance.rb +34 -34
- data/lib/vagrant-azure/action/vagrant_azure_service.rb +44 -43
- data/lib/vagrant-azure/action/wait_for_communicate.rb +39 -38
- data/lib/vagrant-azure/action/wait_for_state.rb +50 -49
- data/lib/vagrant-azure/capabilities/winrm.rb +12 -0
- data/lib/vagrant-azure/command/powershell.rb +43 -0
- data/lib/vagrant-azure/command/rdp.rb +24 -0
- data/lib/vagrant-azure/config.rb +158 -147
- data/lib/vagrant-azure/driver.rb +48 -84
- data/lib/vagrant-azure/errors.rb +28 -27
- data/lib/vagrant-azure/monkey_patch/azure.rb +46 -0
- data/lib/vagrant-azure/monkey_patch/winrm.rb +77 -0
- data/lib/vagrant-azure/plugin.rb +102 -91
- data/lib/vagrant-azure/provider.rb +74 -70
- data/lib/vagrant-azure/provisioner/chef-solo.rb +178 -177
- data/lib/vagrant-azure/provisioner/puppet.rb +116 -115
- data/lib/vagrant-azure/version.rb +11 -10
- data/locales/en.yml +37 -37
- data/templates/provisioners/chef-solo/solo.erb +51 -51
- data/vagrant-azure.gemspec +59 -58
- metadata +48 -38
- data/lib/vagrant-azure/command/rdp/command.rb +0 -21
- data/lib/vagrant-azure/communication/powershell.rb +0 -41
- data/lib/vagrant-azure/monkey_patch/machine.rb +0 -22
- data/lib/vagrant-azure/provisioner/shell.rb +0 -83
- data/lib/vagrant-azure/scripts/check_winrm.ps1 +0 -47
- data/lib/vagrant-azure/scripts/export_vm.ps1 +0 -31
- data/lib/vagrant-azure/scripts/file_sync.ps1 +0 -145
- data/lib/vagrant-azure/scripts/host_info.ps1 +0 -25
- data/lib/vagrant-azure/scripts/hyperv_manager.ps1 +0 -36
- data/lib/vagrant-azure/scripts/run_in_remote.ps1 +0 -32
- data/lib/vagrant-azure/scripts/upload_file.ps1 +0 -95
- data/lib/vagrant-azure/scripts/utils/create_session.ps1 +0 -34
- data/lib/vagrant-azure/scripts/utils/write_messages.ps1 +0 -18
data/lib/vagrant-azure/errors.rb
CHANGED
@@ -1,27 +1,28 @@
|
|
1
|
-
#-------------------------------------------------------------------------
|
2
|
-
# Copyright (c) Microsoft Open Technologies, Inc.
|
3
|
-
# All Rights Reserved.
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
1
|
+
#-------------------------------------------------------------------------
|
2
|
+
# Copyright (c) Microsoft Open Technologies, Inc.
|
3
|
+
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
4
|
+
# See License.txt in the project root for license information.
|
5
|
+
#--------------------------------------------------------------------------
|
6
|
+
|
7
|
+
module VagrantPlugins
|
8
|
+
module WinAzure
|
9
|
+
module Errors
|
10
|
+
class WinAzureError < Vagrant::Errors::VagrantError
|
11
|
+
error_namespace("vagrant_azure.errors")
|
12
|
+
end
|
13
|
+
|
14
|
+
class WinRMNotReady < WinAzureError
|
15
|
+
error_key(:win_rm_not_ready)
|
16
|
+
end
|
17
|
+
|
18
|
+
class ServerNotCreated < WinAzureError
|
19
|
+
error_key(:server_not_created)
|
20
|
+
end
|
21
|
+
|
22
|
+
class CreateVMFailure < WinAzureError
|
23
|
+
error_key(:create_vm_failure)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
|
2
|
+
require 'azure'
|
3
|
+
|
4
|
+
# Patch azure-ruby-sdk to enable vhds to be created every millisecond as opposed to every minute...
|
5
|
+
Azure::VirtualMachineManagement::Serialization.module_eval do
|
6
|
+
def self.role_to_xml(params, options)
|
7
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
8
|
+
xml.PersistentVMRole(
|
9
|
+
'xmlns' => 'http://schemas.microsoft.com/windowsazure',
|
10
|
+
'xmlns:i' => 'http://www.w3.org/2001/XMLSchema-instance'
|
11
|
+
) do
|
12
|
+
xml.RoleName { xml.text params[:vm_name] }
|
13
|
+
xml.OsVersion('i:nil' => 'true')
|
14
|
+
xml.RoleType 'PersistentVMRole'
|
15
|
+
|
16
|
+
xml.ConfigurationSets do
|
17
|
+
provisioning_configuration_to_xml(xml, params, options)
|
18
|
+
xml.ConfigurationSet('i:type' => 'NetworkConfigurationSet') do
|
19
|
+
xml.ConfigurationSetType 'NetworkConfiguration'
|
20
|
+
xml.InputEndpoints do
|
21
|
+
default_endpoints_to_xml(xml, options)
|
22
|
+
tcp_endpoints_to_xml(
|
23
|
+
xml,
|
24
|
+
options[:tcp_endpoints],
|
25
|
+
options[:existing_ports]
|
26
|
+
) if options[:tcp_endpoints]
|
27
|
+
end
|
28
|
+
if options[:virtual_network_name] && options[:subnet_name]
|
29
|
+
xml.SubnetNames do
|
30
|
+
xml.SubnetName options[:subnet_name]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
xml.AvailabilitySetName options[:availability_set_name]
|
36
|
+
xml.Label Base64.encode64(params[:vm_name]).strip
|
37
|
+
xml.OSVirtualHardDisk do
|
38
|
+
xml.MediaLink 'http://' + options[:storage_account_name] + '.blob.core.windows.net/vhds/' + (Time.now.strftime('disk_%Y_%m_%d_%H_%M_%S_%L')) + '.vhd'
|
39
|
+
xml.SourceImageName params[:image]
|
40
|
+
end
|
41
|
+
xml.RoleSize options[:vm_size]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
builder.doc
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# patch no_ssl_peer_validation for ssl based winrm
|
2
|
+
|
3
|
+
WinRM::HTTP::HttpTransport.class_eval do
|
4
|
+
|
5
|
+
# provide a patch for no peer verification.
|
6
|
+
# the patch exists upstream, but vagrant depends on an older version of winrm
|
7
|
+
def no_ssl_peer_verification!
|
8
|
+
@httpcli.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
WinRM::HTTP::HttpSSL.class_eval do
|
13
|
+
|
14
|
+
# provide a constructor that offers the ability to disable peer verification
|
15
|
+
def initialize(endpoint, user, pass, ca_trust_path = nil, opts)
|
16
|
+
super(endpoint)
|
17
|
+
@httpcli.set_auth(endpoint, user, pass)
|
18
|
+
@httpcli.ssl_config.set_trust_ca(ca_trust_path) unless ca_trust_path.nil?
|
19
|
+
no_sspi_auth! if opts[:disable_sspi]
|
20
|
+
basic_auth_only! if opts[:basic_auth_only]
|
21
|
+
no_ssl_peer_verification! if opts[:no_ssl_peer_verification]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
VagrantPlugins::CommunicatorWinRM::WinRMShell.class_eval do
|
27
|
+
EXCEPTIONS = class_variable_get(:@@exceptions_to_retry_on)
|
28
|
+
|
29
|
+
protected
|
30
|
+
|
31
|
+
# patch the timeout being raised from openssl that is not handled properly
|
32
|
+
def execute_shell_with_retry(command, shell, &block)
|
33
|
+
retryable(:tries => @max_tries, :on => EXCEPTIONS, :sleep => 10) do
|
34
|
+
@logger.debug("#{shell} executing:\n#{command}")
|
35
|
+
begin
|
36
|
+
output = session.send(shell, command) do |out, err|
|
37
|
+
block.call(:stdout, out) if block_given? && out
|
38
|
+
block.call(:stderr, err) if block_given? && err
|
39
|
+
end
|
40
|
+
rescue Exception => ex
|
41
|
+
raise Timeout::Error if ex.message =~ /execution expired/ # received not friendly timeout, raise a more friendly error
|
42
|
+
raise # didn't include execution expired, so raise for retryable to handle
|
43
|
+
end
|
44
|
+
@logger.debug("Output: #{output.inspect}")
|
45
|
+
return output
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# create a new session using ssl rather than kerberos or plaintext
|
50
|
+
def new_session
|
51
|
+
@logger.info("Attempting to connect to WinRM (patched)...")
|
52
|
+
@logger.info(" - Host: #{@host}")
|
53
|
+
@logger.info(" - Port: #{@port}")
|
54
|
+
@logger.info(" - Username: #{@username}")
|
55
|
+
|
56
|
+
client = ::WinRM::WinRMWebService.new(endpoint, :ssl, endpoint_options)
|
57
|
+
client.set_timeout(@timeout_in_seconds)
|
58
|
+
client.toggle_nori_type_casting(:off) #we don't want coersion of types
|
59
|
+
client
|
60
|
+
end
|
61
|
+
|
62
|
+
# override the internal http endpoint
|
63
|
+
def endpoint
|
64
|
+
"https://#{@host}:#{@port}/wsman"
|
65
|
+
end
|
66
|
+
|
67
|
+
# don't verify azure self signed certs and don't try to use sspi
|
68
|
+
def endpoint_options
|
69
|
+
{user: @username,
|
70
|
+
pass: @password,
|
71
|
+
host: @host,
|
72
|
+
port: @port,
|
73
|
+
operation_timeout: @timeout_in_seconds,
|
74
|
+
no_ssl_peer_verification: true,
|
75
|
+
disable_sspi: true}
|
76
|
+
end
|
77
|
+
end
|
data/lib/vagrant-azure/plugin.rb
CHANGED
@@ -1,91 +1,102 @@
|
|
1
|
-
#--------------------------------------------------------------------------
|
2
|
-
# Copyright (c) Microsoft Open Technologies, Inc.
|
3
|
-
# All Rights Reserved.
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
#
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
1
|
+
#--------------------------------------------------------------------------
|
2
|
+
# Copyright (c) Microsoft Open Technologies, Inc.
|
3
|
+
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
4
|
+
# See License.txt in the project root for license information.
|
5
|
+
#--------------------------------------------------------------------------
|
6
|
+
begin
|
7
|
+
require 'vagrant'
|
8
|
+
rescue LoadError
|
9
|
+
raise 'The Vagrant Azure plugin must be run within Vagrant.'
|
10
|
+
end
|
11
|
+
|
12
|
+
# This is a sanity check to make sure no one is attempting to install this into
|
13
|
+
# an early Vagrant version.
|
14
|
+
if Vagrant::VERSION < '1.6.0'
|
15
|
+
raise 'The Vagrant Azure plugin is only compatible with Vagrant 1.6+'
|
16
|
+
end
|
17
|
+
|
18
|
+
module VagrantPlugins
|
19
|
+
module WinAzure
|
20
|
+
class Plugin < Vagrant.plugin('2')
|
21
|
+
name 'azure'
|
22
|
+
description <<-DESC
|
23
|
+
This plugin installs a provider that allows Vagrant to manage
|
24
|
+
machines in Windows Azure.
|
25
|
+
DESC
|
26
|
+
|
27
|
+
config(:azure, :provider) do
|
28
|
+
require_relative 'config'
|
29
|
+
Config
|
30
|
+
end
|
31
|
+
|
32
|
+
provider(:azure, parallel: true) do
|
33
|
+
# Setup logging and i18n
|
34
|
+
setup_logging
|
35
|
+
setup_i18n
|
36
|
+
|
37
|
+
# Return the provider
|
38
|
+
require_relative 'provider'
|
39
|
+
Provider
|
40
|
+
end
|
41
|
+
|
42
|
+
provider_capability(:azure, :winrm_info) do
|
43
|
+
require_relative 'capabilities/winrm'
|
44
|
+
VagrantPlugins::WinAzure::Cap::WinRM
|
45
|
+
end
|
46
|
+
|
47
|
+
command 'powershell' do
|
48
|
+
require_relative 'command/powershell'
|
49
|
+
VagrantPlugins::WinAzure::Command::PowerShell
|
50
|
+
end
|
51
|
+
|
52
|
+
command 'rdp' do
|
53
|
+
require_relative 'command/rdp'
|
54
|
+
VagrantPlugins::WinAzure::Command::RDP
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.setup_i18n
|
58
|
+
I18n.load_path << File.expand_path(
|
59
|
+
'locales/en.yml',
|
60
|
+
WinAzure.source_root
|
61
|
+
)
|
62
|
+
I18n.load_path << File.expand_path(
|
63
|
+
'templates/locales/en.yml',
|
64
|
+
Vagrant.source_root
|
65
|
+
)
|
66
|
+
I18n.load_path << File.expand_path(
|
67
|
+
'templates/locales/providers_hyperv.yml',
|
68
|
+
Vagrant.source_root
|
69
|
+
)
|
70
|
+
I18n.reload!
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.setup_logging
|
74
|
+
require 'log4r'
|
75
|
+
|
76
|
+
level = nil
|
77
|
+
begin
|
78
|
+
level = Log4r.const_get(ENV['VAGRANT_LOG'].upcase)
|
79
|
+
rescue NameError
|
80
|
+
# This means that the logging constant wasn't found,
|
81
|
+
# which is fine. We just keep `level` as `nil`. But
|
82
|
+
# we tell the user.
|
83
|
+
level = nil
|
84
|
+
end
|
85
|
+
|
86
|
+
# Some constants, such as "true" resolve to booleans, so the
|
87
|
+
# above error checking doesn't catch it. This will check to make
|
88
|
+
# sure that the log level is an integer, as Log4r requires.
|
89
|
+
level = nil if !level.is_a?(Integer)
|
90
|
+
|
91
|
+
# Set the logging level on all "vagrant" namespaced logs as long as
|
92
|
+
# we have a valid level
|
93
|
+
if level
|
94
|
+
logger = Log4r::Logger.new("vagrant_azure")
|
95
|
+
logger.outputters = Log4r::Outputter.stderr
|
96
|
+
logger.level = level
|
97
|
+
logger = nil
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -1,70 +1,74 @@
|
|
1
|
-
#--------------------------------------------------------------------------
|
2
|
-
# Copyright (c) Microsoft Open Technologies, Inc.
|
3
|
-
# All Rights Reserved.
|
4
|
-
|
5
|
-
|
6
|
-
require '
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
nil
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
def
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
env
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
env
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
1
|
+
#--------------------------------------------------------------------------
|
2
|
+
# Copyright (c) Microsoft Open Technologies, Inc.
|
3
|
+
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
4
|
+
# See License.txt in the project root for license information.
|
5
|
+
#--------------------------------------------------------------------------
|
6
|
+
require 'log4r'
|
7
|
+
require 'vagrant'
|
8
|
+
|
9
|
+
module VagrantPlugins
|
10
|
+
module WinAzure
|
11
|
+
class Provider < Vagrant.plugin('2', :provider)
|
12
|
+
attr_reader :driver
|
13
|
+
|
14
|
+
def initialize(machine)
|
15
|
+
@machine = machine
|
16
|
+
|
17
|
+
# Load the driver
|
18
|
+
machine_id_changed
|
19
|
+
|
20
|
+
@machine.config.winrm.password = @machine.provider_config.vm_password || @machine.provider_config.vm_user
|
21
|
+
@machine.config.winrm.username = @machine.provider_config.vm_user
|
22
|
+
end
|
23
|
+
|
24
|
+
def action(name)
|
25
|
+
# Attempt to get the action method from the Action class if it
|
26
|
+
# exists, otherwise return nil to show that we don't support the
|
27
|
+
# given action.
|
28
|
+
action_method = "action_#{name}"
|
29
|
+
return Action.send(action_method) if Action.respond_to?(action_method)
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
|
33
|
+
def machine_id_changed
|
34
|
+
@driver = Driver.new(@machine)
|
35
|
+
end
|
36
|
+
|
37
|
+
def ssh_info
|
38
|
+
# Run a custom action called "read_ssh_info" which does what it
|
39
|
+
# says and puts the resulting SSH info into the `:machine_ssh_info`
|
40
|
+
# key in the environment.
|
41
|
+
env = @machine.action('read_ssh_info')
|
42
|
+
env[:machine_ssh_info]
|
43
|
+
end
|
44
|
+
|
45
|
+
def rdp_info
|
46
|
+
env = @machine.action('read_rdp_info')
|
47
|
+
env[:machine_ssh_info]
|
48
|
+
end
|
49
|
+
|
50
|
+
def winrm_info
|
51
|
+
env = @machine.action('read_winrm_info')
|
52
|
+
env[:machine_winrm_info]
|
53
|
+
end
|
54
|
+
|
55
|
+
def state
|
56
|
+
# Run a custom action we define called "read_state" which does what it
|
57
|
+
# says. It puts the state in the `:machine_state_id` key in the env
|
58
|
+
env = @machine.action('read_state')
|
59
|
+
state_id = env[:machine_state_id]
|
60
|
+
|
61
|
+
short = "Machine's current state is #{state_id}"
|
62
|
+
long = ""
|
63
|
+
|
64
|
+
# Return the MachineState object
|
65
|
+
Vagrant::MachineState.new(state_id, short, long)
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_s
|
69
|
+
id = @machine.id.nil? ? 'new' : @machine.id
|
70
|
+
"Azure (#{id})"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|