зеркало из https://github.com/Azure/vagrant-azure.git
Merge branch 'jlm/sync_folder'
This commit is contained in:
Коммит
d15326a4b0
|
@ -0,0 +1,24 @@
|
|||
## 1.0.5 (Unreleased)
|
||||
|
||||
FEATURES
|
||||
|
||||
- Provision for windows VM.
|
||||
- Windows VM has to be specifically mentioned in the Vagrantfile with
|
||||
`config.vm.guest = :windows`
|
||||
- Chef, Puppet and Shell provision for Linux and Windows VM.
|
||||
- **SyncedFolders**
|
||||
- Linux VM uses `rsync` and has be mentioned in the VagrantFile.
|
||||
- Windows VM will default to use PowerShell to copy files.
|
||||
|
||||
IMPROVEMENTS
|
||||
|
||||
- Better exception handling when VM fails to get created in cloud.
|
||||
- Better exception handling for WinRM session errors.
|
||||
|
||||
BUGFIXES
|
||||
|
||||
- Cleaned up few typo in README
|
||||
- Compatible with Vagrant 1.6 [GH-15]
|
||||
|
||||
## Previous
|
||||
See git commits
|
4
Gemfile
4
Gemfile
|
@ -13,7 +13,3 @@ group :development do
|
|||
# Vagrant environment itself using `vagrant plugin`.
|
||||
gem "vagrant", :git => "git://github.com/mitchellh/vagrant.git"
|
||||
end
|
||||
|
||||
group :plugins do
|
||||
gem 'vagrant-azure', path: '.'
|
||||
end
|
||||
|
|
|
@ -12,10 +12,17 @@ module VagrantPlugins
|
|||
autoload :Errors, lib_path.join('errors')
|
||||
autoload :Driver, lib_path.join('driver')
|
||||
|
||||
# Load a communicator for Windows guest
|
||||
require lib_path.join("communication/powershell")
|
||||
|
||||
require lib_path.join('provisioner/puppet')
|
||||
require lib_path.join('provisioner/chef-solo')
|
||||
require lib_path.join('provisioner/shell')
|
||||
|
||||
monkey_patch = Pathname.new(File.expand_path("../vagrant-azure/monkey_patch", __FILE__))
|
||||
# Monkey Patch the core Hyper-V vagrant with the following
|
||||
require monkey_patch.join("machine")
|
||||
|
||||
# This returns the path to the source of this plugin.
|
||||
#
|
||||
# @return [Pathname]
|
||||
|
|
|
@ -65,9 +65,7 @@ module VagrantPlugins
|
|||
b2.use Message, I18n.t('vagrant_azure.not_created')
|
||||
next
|
||||
end
|
||||
|
||||
b2.use Provision
|
||||
# b2.use SyncFolders
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -158,32 +156,33 @@ module VagrantPlugins
|
|||
|
||||
def self.action_prepare_boot
|
||||
Vagrant::Action::Builder.new.tap do |b|
|
||||
b.use Provision
|
||||
# b.use SyncFolders
|
||||
# b.use WarnNetworks
|
||||
b.use Call, WaitForState, :ReadyRole do |env, b1|
|
||||
if env[:result]
|
||||
env[:machine].id =~ /@/
|
||||
b1.use Message, I18n.t(
|
||||
'vagrant_azure.vm_started', :name => $`
|
||||
)
|
||||
b1.use WaitForCommunicate
|
||||
b1.use Provision
|
||||
b1.use SyncFolders
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# This action is called to bring the box up from nothing
|
||||
def self.action_up
|
||||
Vagrant::Action::Builder.new.tap do |b|
|
||||
b.use HandleBoxUrl
|
||||
b.use HandleBox
|
||||
b.use ConfigValidate
|
||||
b.use ConnectAzure
|
||||
|
||||
b.use Call, IsState, :NotCreated do |env1, b1|
|
||||
if !env1[:result]
|
||||
b1.use Call, IsState, :StoppedDeallocated do |env2, b2|
|
||||
if env2[:result]
|
||||
b2.use action_prepare_boot
|
||||
b2.use StartInstance # start this instance again
|
||||
b2.use Call, WaitForState, :ReadyRole do |env3, b3|
|
||||
if env3[:result]
|
||||
env3[:machine].id =~ /@/
|
||||
b3.use Message, I18n.t(
|
||||
'vagrant_azure.vm_started', :name => $`
|
||||
)
|
||||
end
|
||||
end
|
||||
b2.use action_prepare_boot
|
||||
else
|
||||
b2.use Message, I18n.t(
|
||||
'vagrant_azure.already_status', :status => 'created'
|
||||
|
@ -192,14 +191,7 @@ module VagrantPlugins
|
|||
end
|
||||
else
|
||||
b1.use RunInstance # Launch a new instance
|
||||
b1.use Call, WaitForState, :ReadyRole do |env2, b2|
|
||||
if env2[:result]
|
||||
env2[:machine].id =~ /@/
|
||||
b2.use Message, I18n.t(
|
||||
'vagrant_azure.vm_started', :name => $`
|
||||
)
|
||||
end
|
||||
end
|
||||
b1.use action_prepare_boot
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -240,11 +232,12 @@ module VagrantPlugins
|
|||
autoload :RunInstance, action_root.join('run_instance')
|
||||
autoload :StartInstance, action_root.join('start_instance')
|
||||
autoload :StopInstance, action_root.join('stop_instance')
|
||||
# autoload :SyncFolders, action_root.join('sync_folders')
|
||||
autoload :SyncFolders, action_root.join('sync_folders')
|
||||
autoload :TerminateInstance, action_root.join('terminate_instance')
|
||||
# autoload :TimedProvision, action_root.join('timed_provision')
|
||||
# autoload :WarnNetworks, action_root.join('warn_networks')
|
||||
autoload :WaitForState, action_root.join('wait_for_state')
|
||||
autoload :WaitForCommunicate, action_root.join('wait_for_communicate')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
require 'azure'
|
||||
require 'log4r'
|
||||
|
||||
# FIXME:
|
||||
# This is a required to patch few exception handling which are not done in
|
||||
# Azure Ruby SDK
|
||||
require_relative "vagrant_azure_service"
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Action
|
||||
|
@ -17,11 +22,6 @@ module VagrantPlugins
|
|||
def call (env)
|
||||
config = env[:machine].provider_config
|
||||
|
||||
env[:ui].warn "Subscription ID: [#{config.subscription_id}]"
|
||||
env[:ui].warn "Mangement Certificate: [#{config.mgmt_certificate}]"
|
||||
env[:ui].warn "Mangement Endpoint: [#{config.mgmt_endpoint}]"
|
||||
env[:ui].warn "Storage Account Name: [#{config.storage_acct_name}]"
|
||||
|
||||
Azure.configure do |c|
|
||||
c.subscription_id = config.subscription_id
|
||||
c.management_certificate = config.mgmt_certificate
|
||||
|
@ -30,7 +30,13 @@ module VagrantPlugins
|
|||
c.storage_access_key = config.storage_access_key
|
||||
end
|
||||
|
||||
env[:azure_vm_service] = Azure::VirtualMachineManagementService.new
|
||||
# FIXME:
|
||||
# Defining a new class VagrantAzureService
|
||||
# Here we call the native azure virtual machine management service method
|
||||
# and add some exception handling.
|
||||
# Remove this once the Azure SDK adds the exception handling for the
|
||||
# methods defined in VagrantAzureService
|
||||
env[:azure_vm_service] = VagrantAzureService.new(Azure::VirtualMachineManagementService.new)
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
|
|
|
@ -102,8 +102,7 @@ module VagrantPlugins
|
|||
# machine as a string.
|
||||
|
||||
if server.instance_of? String
|
||||
env[:ui].info "Server not created. Error is: #{server}"
|
||||
raise Errors::CreateVMError, message: "#{server}"
|
||||
raise Errors::ServerNotCreated, message: server
|
||||
end
|
||||
|
||||
env[:machine].id = "#{server.vm_name}@#{server.cloud_service_name}"
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
# Copyright (c) 2014 Mitchell Hashimoto
|
||||
# Under The MIT License (MIT)
|
||||
#---------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache 2.0 License.
|
||||
#--------------------------------------------------------------------------
|
||||
require "log4r"
|
||||
require "vagrant/util/subprocess"
|
||||
require "vagrant/util/scoped_hash_override"
|
||||
require "vagrant/util/which"
|
||||
require "#{Vagrant::source_root}/lib/vagrant/action/builtin/synced_folders"
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Action
|
||||
# This middleware uses `rsync` to sync the folders
|
||||
class SyncFolders < Vagrant::Action::Builtin::SyncedFolders
|
||||
include Vagrant::Util::ScopedHashOverride
|
||||
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
@logger = Log4r::Logger.new("vagrant_azure::action::sync_folders")
|
||||
end
|
||||
|
||||
def call(env)
|
||||
if env[:machine].config.vm.guest != :windows
|
||||
super
|
||||
else
|
||||
@app.call(env)
|
||||
env[:machine].config.vm.synced_folders.each do |id, data|
|
||||
data = scoped_hash_override(data, :azure)
|
||||
|
||||
# Ignore disabled shared folders
|
||||
next if data[:disabled]
|
||||
|
||||
hostpath = File.expand_path(data[:hostpath], env[:root_path])
|
||||
guestpath = data[:guestpath]
|
||||
|
||||
env[:ui].info(I18n.t("vagrant_azure.copy_folder",
|
||||
:hostpath => hostpath,
|
||||
:guestpath => guestpath))
|
||||
|
||||
# Create the host path if it doesn't exist and option flag is set
|
||||
if data[:create]
|
||||
begin
|
||||
FileUtils::mkdir_p(hostpath)
|
||||
rescue => err
|
||||
raise Errors::MkdirError,
|
||||
:hostpath => hostpath,
|
||||
:err => err
|
||||
end
|
||||
end
|
||||
|
||||
env[:machine].provider.driver.upload(hostpath, guestpath)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,43 @@
|
|||
#---------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache 2.0 License.
|
||||
#--------------------------------------------------------------------------
|
||||
# FIXME:
|
||||
# This is a stop gap arrangement until the azure ruby SDK fixes the exceptions
|
||||
# and gracefully fails.
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Action
|
||||
class VagrantAzureService
|
||||
attr_reader :azure
|
||||
def initialize(azure)
|
||||
@azure = azure
|
||||
end
|
||||
|
||||
# At times due to network latency the SDK raises SocketError, this can
|
||||
# be rescued and re-try for three attempts.
|
||||
def get_virtual_machine(*args)
|
||||
vm = nil
|
||||
attempt = 0
|
||||
while true
|
||||
begin
|
||||
vm = azure.get_virtual_machine(*args)
|
||||
rescue SocketError
|
||||
attempt = attempt + 1
|
||||
sleep 5
|
||||
next if attempt < 3
|
||||
end
|
||||
break
|
||||
end
|
||||
vm
|
||||
end
|
||||
|
||||
def method_missing(method, *args, &block)
|
||||
azure.send(method, *args, &block)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,38 @@
|
|||
#--------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache 2.0 License.
|
||||
#--------------------------------------------------------------------------
|
||||
require 'log4r'
|
||||
require 'timeout'
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Action
|
||||
class WaitForCommunicate
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
@logger = Log4r::Logger.new("vagrant_azure::action::wait_for_communicate")
|
||||
end
|
||||
|
||||
def call(env)
|
||||
|
||||
if !env[:interrupted]
|
||||
# Wait for SSH to be ready.
|
||||
env[:ui].info(I18n.t("vagrant_azure.waiting_for_ssh"))
|
||||
while true
|
||||
# If we're interrupted then just back out
|
||||
break if env[:interrupted]
|
||||
break if env[:machine].communicate.ready?
|
||||
sleep 5
|
||||
end
|
||||
|
||||
# Ready and booted!
|
||||
env[:ui].info(I18n.t("vagrant_azure.ssh_ready"))
|
||||
end
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,41 @@
|
|||
#-------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache 2.0 License.
|
||||
#--------------------------------------------------------------------------
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Communicator
|
||||
class PowerShell < Vagrant.plugin("2", :communicator)
|
||||
def initialize(machine)
|
||||
@machine = machine
|
||||
end
|
||||
|
||||
def wait_for_ready(timeout)
|
||||
ready?
|
||||
end
|
||||
|
||||
def ready?
|
||||
# Return True when the guest has enabled WinRM
|
||||
# In this case we can try any remote PowerShell commands to see if
|
||||
# further vagrant can be carried out using this communication
|
||||
if !@winrm_status
|
||||
status = false
|
||||
response = @machine.provider.driver.check_winrm
|
||||
message = nil
|
||||
if response && response["message"]
|
||||
message = response["message"]
|
||||
@winrm_status = message == "Running"
|
||||
end
|
||||
raise Errors::WinRMNotReady, message: message if !@winrm_status
|
||||
end
|
||||
@winrm_status
|
||||
end
|
||||
|
||||
def test(command, opts=nil)
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -119,7 +119,7 @@ module VagrantPlugins
|
|||
self.mgmt_endpoint
|
||||
result.subscription_id = other.subscription_id || \
|
||||
self.subscription_id
|
||||
result.storage_account_name = other.storage_acct_name || \
|
||||
result.storage_acct_name = other.storage_acct_name || \
|
||||
self.storage_acct_name
|
||||
result.storage_access_key = other.storage_access_key || \
|
||||
self.storage_access_key
|
||||
|
|
|
@ -60,6 +60,11 @@ module VagrantPlugins
|
|||
execute(script_path, options)
|
||||
end
|
||||
|
||||
def check_winrm
|
||||
script_path = local_script_path('check_winrm.ps1')
|
||||
execute(script_path, remote_credentials)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def local_script_path(path)
|
||||
|
|
|
@ -1,21 +1,27 @@
|
|||
#--------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache 2.0 License.
|
||||
#--------------------------------------------------------------------------
|
||||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
module Errors
|
||||
class VagrantAzureError < Vagrant::Errors::VagrantError
|
||||
class WinAzureError < Vagrant::Errors::VagrantError
|
||||
error_namespace("vagrant_azure.errors")
|
||||
end
|
||||
|
||||
class CreateVMFailure < VagrantAzureError
|
||||
class WinRMNotReady < WinAzureError
|
||||
error_key(:win_rm_not_ready)
|
||||
end
|
||||
|
||||
class ServerNotCreated < WinAzureError
|
||||
error_key(:server_not_created)
|
||||
end
|
||||
|
||||
class CreateVMFailure < WinAzureError
|
||||
error_key(:create_vm_failure)
|
||||
end
|
||||
|
||||
class CreateVMError < VagrantAzureError
|
||||
error_key(:create_vm_error)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#-------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache 2.0 License.
|
||||
#--------------------------------------------------------------------------
|
||||
|
||||
module Vagrant
|
||||
class Machine
|
||||
|
||||
ssh_communicate = instance_method(:communicate)
|
||||
|
||||
define_method(:communicate) do
|
||||
unless @communicator
|
||||
if @config.vm.guest == :windows
|
||||
@communicator = VagrantPlugins::WinAzure::Communicator::PowerShell.new(self)
|
||||
else
|
||||
@communicator = ssh_communicate.bind(self).()
|
||||
end
|
||||
end
|
||||
@communicator
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2,10 +2,12 @@
|
|||
# Copyright (c) Microsoft Open Technologies, Inc.
|
||||
# All Rights Reserved. Licensed under the Apache 2.0 License.
|
||||
#--------------------------------------------------------------------------
|
||||
|
||||
param (
|
||||
[string]$guest_ip = $(throw "-guest_ip is required."),
|
||||
[string]$username = $(throw "-guest_username is required."),
|
||||
[string]$password = $(throw "-guest_password is required.")
|
||||
[string]$password = $(throw "-guest_password is required."),
|
||||
[string]$guest_port = $(throw "-guest_port is required")
|
||||
)
|
||||
|
||||
# Include the following modules
|
||||
|
@ -14,9 +16,13 @@ $presentDir = Split-Path -parent $PSCommandPath
|
|||
. ([System.IO.Path]::Combine($presentDir, "utils\create_session.ps1"))
|
||||
|
||||
try {
|
||||
$response = Create-Remote-Session $guest_ip $username $password
|
||||
$response = Create-Remote-Session $guest_ip $guest_port $username $password
|
||||
if (!$response["session"] -and $response["error"]) {
|
||||
Write-Host $response["error"]
|
||||
$session_message = $response['error']
|
||||
$resultHash = @{
|
||||
message = "$session_message"
|
||||
}
|
||||
Write-Output-Message $resultHash
|
||||
return
|
||||
}
|
||||
function Remote-Execute() {
|
||||
|
@ -34,7 +40,7 @@ try {
|
|||
} catch {
|
||||
$errortHash = @{
|
||||
type = "PowerShellError"
|
||||
error ="Failed to copy file $_"
|
||||
error ="$_"
|
||||
}
|
||||
Write-Error-Message $errortHash
|
||||
return
|
||||
|
|
|
@ -5,6 +5,6 @@
|
|||
|
||||
module VagrantPlugins
|
||||
module WinAzure
|
||||
VERSION = '1.0.4'
|
||||
VERSION = '1.0.5'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,10 +14,24 @@ en:
|
|||
VM '%{name}' has been started
|
||||
vm_stopped: |-
|
||||
VM '%{name}' has been stopped
|
||||
copy_folder: |-
|
||||
Copying folder: %{hostpath} ==>
|
||||
%{guestpath}
|
||||
rsync_not_found_warning: |-
|
||||
Warning! Folder sync disabled because the rsync binary is missing in the %{side}.
|
||||
Make sure rsync is installed and the binary can be found in the PATH.
|
||||
waiting_for_ssh: |-
|
||||
Waiting for SSH
|
||||
ssh_ready: |-
|
||||
SSH Ready
|
||||
read_attempt: |-
|
||||
Failed to connect to Virtual Machine. Re-Connecting %{attempt}
|
||||
errors:
|
||||
create_vm_failure: |-
|
||||
There was some error in creating the VM, this could be due to some network latency.
|
||||
Generally the next vagrant up command should fix this error.
|
||||
create_vm_error: |-
|
||||
Failed to create a VM in azure cloud with the following message.
|
||||
win_rm_not_ready: |-
|
||||
Vagrant failed to communicate to the VM using powershell. The operation failed
|
||||
with the following message.
|
||||
%{message}
|
||||
server_not_created: |-
|
||||
Server not created. Error is: %{message}
|
||||
create_vm_failure: |-
|
||||
There was some error in creating the VM.
|
||||
|
|
Загрузка…
Ссылка в новой задаче