vagrant-azure 1.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/.gitignore +12 -0
 - data/Gemfile +19 -0
 - data/LICENSE +4 -0
 - data/README.md +9 -0
 - data/Rakefile +14 -0
 - data/lib/vagrant-azure.rb +24 -0
 - data/lib/vagrant-azure/action.rb +249 -0
 - data/lib/vagrant-azure/action/connect_azure.rb +41 -0
 - data/lib/vagrant-azure/action/provision.rb +40 -0
 - data/lib/vagrant-azure/action/rdp.rb +62 -0
 - data/lib/vagrant-azure/action/read_ssh_info.rb +51 -0
 - data/lib/vagrant-azure/action/read_state.rb +46 -0
 - data/lib/vagrant-azure/action/restart_vm.rb +27 -0
 - data/lib/vagrant-azure/action/run_instance.rb +111 -0
 - data/lib/vagrant-azure/action/start_instance.rb +35 -0
 - data/lib/vagrant-azure/action/stop_instance.rb +38 -0
 - data/lib/vagrant-azure/action/terminate_instance.rb +34 -0
 - data/lib/vagrant-azure/action/wait_for_state.rb +49 -0
 - data/lib/vagrant-azure/command/rdp/command.rb +21 -0
 - data/lib/vagrant-azure/config.rb +147 -0
 - data/lib/vagrant-azure/driver.rb +79 -0
 - data/lib/vagrant-azure/plugin.rb +87 -0
 - data/lib/vagrant-azure/provider.rb +70 -0
 - data/lib/vagrant-azure/provisioner/puppet.rb +109 -0
 - data/lib/vagrant-azure/scripts/check_winrm.ps1 +41 -0
 - data/lib/vagrant-azure/scripts/export_vm.ps1 +31 -0
 - data/lib/vagrant-azure/scripts/file_sync.ps1 +145 -0
 - data/lib/vagrant-azure/scripts/host_info.ps1 +25 -0
 - data/lib/vagrant-azure/scripts/hyperv_manager.ps1 +36 -0
 - data/lib/vagrant-azure/scripts/run_in_remote.ps1 +32 -0
 - data/lib/vagrant-azure/scripts/upload_file.ps1 +95 -0
 - data/lib/vagrant-azure/scripts/utils/create_session.ps1 +34 -0
 - data/lib/vagrant-azure/scripts/utils/write_messages.ps1 +18 -0
 - data/lib/vagrant-azure/version.rb +10 -0
 - data/locales/en.yml +14 -0
 - data/vagrant-azure.gemspec +58 -0
 - metadata +167 -0
 
| 
         @@ -0,0 +1,79 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #---------------------------------------------------------------------------
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Copyright (c) Microsoft Open Technologies, Inc.
         
     | 
| 
      
 3 
     | 
    
         
            +
            # All Rights Reserved. Licensed under the Apache 2.0 License.
         
     | 
| 
      
 4 
     | 
    
         
            +
            #--------------------------------------------------------------------------
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'json'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require "#{Vagrant::source_root}/plugins/providers/hyperv/driver"
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            module VagrantPlugins
         
     | 
| 
      
 9 
     | 
    
         
            +
              module WinAzure
         
     | 
| 
      
 10 
     | 
    
         
            +
                class Driver < VagrantPlugins::HyperV::Driver
         
     | 
| 
      
 11 
     | 
    
         
            +
                  def initialize(machine)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @id = machine.id
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @machine = machine
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  def ssh_info
         
     | 
| 
      
 17 
     | 
    
         
            +
                    @ssh_info ||= @machine.provider.winrm_info
         
     | 
| 
      
 18 
     | 
    
         
            +
                    @ssh_info[:username] ||= @machine.config.ssh.username
         
     | 
| 
      
 19 
     | 
    
         
            +
                    @ssh_info[:password] ||= @machine.config.ssh.password
         
     | 
| 
      
 20 
     | 
    
         
            +
                    @ssh_info
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                  def remote_credentials
         
     | 
| 
      
 24 
     | 
    
         
            +
                    @remote_credentials ||= {
         
     | 
| 
      
 25 
     | 
    
         
            +
                      guest_ip: ssh_info[:host],
         
     | 
| 
      
 26 
     | 
    
         
            +
                      guest_port: ssh_info[:port],
         
     | 
| 
      
 27 
     | 
    
         
            +
                      username: ssh_info[:username],
         
     | 
| 
      
 28 
     | 
    
         
            +
                      password: ssh_info[:password]
         
     | 
| 
      
 29 
     | 
    
         
            +
                    }
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  def run_remote_ps(command, &block)
         
     | 
| 
      
 33 
     | 
    
         
            +
                    options = remote_credentials.merge(command: command)
         
     | 
| 
      
 34 
     | 
    
         
            +
                    script_path = local_script_path('run_in_remote.ps1')
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                    ps_options = []
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                    options.each do |key, value|
         
     | 
| 
      
 39 
     | 
    
         
            +
                      ps_options << "-#{key}"
         
     | 
| 
      
 40 
     | 
    
         
            +
                      ps_options << "'#{value}'"
         
     | 
| 
      
 41 
     | 
    
         
            +
                    end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                    ps_options << '-ErrorAction' << 'Stop'
         
     | 
| 
      
 44 
     | 
    
         
            +
                    opts = { notify: [:stdout, :stderr, :stdin] }
         
     | 
| 
      
 45 
     | 
    
         
            +
                    Vagrant::Util::PowerShell.execute(
         
     | 
| 
      
 46 
     | 
    
         
            +
                      script_path,
         
     | 
| 
      
 47 
     | 
    
         
            +
                      *ps_options,
         
     | 
| 
      
 48 
     | 
    
         
            +
                      **opts,
         
     | 
| 
      
 49 
     | 
    
         
            +
                      &block
         
     | 
| 
      
 50 
     | 
    
         
            +
                    )
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  def upload(from, to)
         
     | 
| 
      
 54 
     | 
    
         
            +
                    options = {
         
     | 
| 
      
 55 
     | 
    
         
            +
                      host_path: windows_path(from),
         
     | 
| 
      
 56 
     | 
    
         
            +
                      guest_path: windows_path(to)
         
     | 
| 
      
 57 
     | 
    
         
            +
                    }.merge(remote_credentials)
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                    script_path = local_script_path('upload_file.ps1')
         
     | 
| 
      
 60 
     | 
    
         
            +
                    execute(script_path, options)
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                  protected
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  def local_script_path(path)
         
     | 
| 
      
 66 
     | 
    
         
            +
                    lib_path = Pathname.new(File.expand_path('../scripts', __FILE__))
         
     | 
| 
      
 67 
     | 
    
         
            +
                    windows_path(lib_path.join(path).to_s)
         
     | 
| 
      
 68 
     | 
    
         
            +
                  end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                  def windows_path(path)
         
     | 
| 
      
 71 
     | 
    
         
            +
                    if path
         
     | 
| 
      
 72 
     | 
    
         
            +
                      path = path.gsub('/', "\\")
         
     | 
| 
      
 73 
     | 
    
         
            +
                      path = "c:#{path}" if path =~ /^\\/
         
     | 
| 
      
 74 
     | 
    
         
            +
                    end
         
     | 
| 
      
 75 
     | 
    
         
            +
                    path
         
     | 
| 
      
 76 
     | 
    
         
            +
                  end
         
     | 
| 
      
 77 
     | 
    
         
            +
                end
         
     | 
| 
      
 78 
     | 
    
         
            +
              end
         
     | 
| 
      
 79 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,87 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #--------------------------------------------------------------------------
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Copyright (c) Microsoft Open Technologies, Inc.
         
     | 
| 
      
 3 
     | 
    
         
            +
            # All Rights Reserved. Licensed under the Apache 2.0 License.
         
     | 
| 
      
 4 
     | 
    
         
            +
            #--------------------------------------------------------------------------
         
     | 
| 
      
 5 
     | 
    
         
            +
            begin
         
     | 
| 
      
 6 
     | 
    
         
            +
              require 'vagrant'
         
     | 
| 
      
 7 
     | 
    
         
            +
            rescue LoadError
         
     | 
| 
      
 8 
     | 
    
         
            +
              raise 'The Vagrant Azure plugin must be run within Vagrant.'
         
     | 
| 
      
 9 
     | 
    
         
            +
            end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            # This is a sanity check to make sure no one is attempting to install this into
         
     | 
| 
      
 12 
     | 
    
         
            +
            # an early Vagrant version.
         
     | 
| 
      
 13 
     | 
    
         
            +
            if Vagrant::VERSION < '1.2.0'
         
     | 
| 
      
 14 
     | 
    
         
            +
              raise 'The Vagrant Azure plugin is only compatible with Vagrant 1.2+'
         
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            module VagrantPlugins
         
     | 
| 
      
 18 
     | 
    
         
            +
              module WinAzure
         
     | 
| 
      
 19 
     | 
    
         
            +
                class Plugin < Vagrant.plugin('2')
         
     | 
| 
      
 20 
     | 
    
         
            +
                  name 'azure'
         
     | 
| 
      
 21 
     | 
    
         
            +
                  description <<-DESC
         
     | 
| 
      
 22 
     | 
    
         
            +
                  This plugin installs a provider that allows Vagrant to manage
         
     | 
| 
      
 23 
     | 
    
         
            +
                  machines in Windows Azure.
         
     | 
| 
      
 24 
     | 
    
         
            +
                  DESC
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  config(:azure, :provider) do
         
     | 
| 
      
 27 
     | 
    
         
            +
                    require_relative 'config'
         
     | 
| 
      
 28 
     | 
    
         
            +
                    Config
         
     | 
| 
      
 29 
     | 
    
         
            +
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  provider(:azure, parallel: true) do
         
     | 
| 
      
 32 
     | 
    
         
            +
                    # Setup logging and i18n
         
     | 
| 
      
 33 
     | 
    
         
            +
                    setup_logging
         
     | 
| 
      
 34 
     | 
    
         
            +
                    setup_i18n
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                    # Return the provider
         
     | 
| 
      
 37 
     | 
    
         
            +
                    require_relative 'provider'
         
     | 
| 
      
 38 
     | 
    
         
            +
                    Provider
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  command 'rdp' do
         
     | 
| 
      
 42 
     | 
    
         
            +
                    require_relative 'command/rdp/command'
         
     | 
| 
      
 43 
     | 
    
         
            +
                    Command
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                  def self.setup_i18n
         
     | 
| 
      
 47 
     | 
    
         
            +
                    I18n.load_path << File.expand_path(
         
     | 
| 
      
 48 
     | 
    
         
            +
                      'locales/en.yml',
         
     | 
| 
      
 49 
     | 
    
         
            +
                      WinAzure.source_root
         
     | 
| 
      
 50 
     | 
    
         
            +
                    )
         
     | 
| 
      
 51 
     | 
    
         
            +
                    I18n.load_path << File.expand_path(
         
     | 
| 
      
 52 
     | 
    
         
            +
                      'templates/locales/providers_hyperv.yml',
         
     | 
| 
      
 53 
     | 
    
         
            +
                      Vagrant.source_root
         
     | 
| 
      
 54 
     | 
    
         
            +
                    )
         
     | 
| 
      
 55 
     | 
    
         
            +
                    I18n.reload!
         
     | 
| 
      
 56 
     | 
    
         
            +
                  end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                  def self.setup_logging
         
     | 
| 
      
 59 
     | 
    
         
            +
                    require 'log4r'
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                    level = nil
         
     | 
| 
      
 62 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 63 
     | 
    
         
            +
                      level = Log4r.const_get(ENV['VAGRANT_LOG'].upcase)
         
     | 
| 
      
 64 
     | 
    
         
            +
                    rescue NameError
         
     | 
| 
      
 65 
     | 
    
         
            +
                      # This means that the logging constant wasn't found,
         
     | 
| 
      
 66 
     | 
    
         
            +
                      # which is fine. We just keep `level` as `nil`. But
         
     | 
| 
      
 67 
     | 
    
         
            +
                      # we tell the user.
         
     | 
| 
      
 68 
     | 
    
         
            +
                      level = nil
         
     | 
| 
      
 69 
     | 
    
         
            +
                    end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                    # Some constants, such as "true" resolve to booleans, so the
         
     | 
| 
      
 72 
     | 
    
         
            +
                    # above error checking doesn't catch it. This will check to make
         
     | 
| 
      
 73 
     | 
    
         
            +
                    # sure that the log level is an integer, as Log4r requires.
         
     | 
| 
      
 74 
     | 
    
         
            +
                    level = nil if !level.is_a?(Integer)
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                    # Set the logging level on all "vagrant" namespaced logs as long as
         
     | 
| 
      
 77 
     | 
    
         
            +
                    # we have a valid level
         
     | 
| 
      
 78 
     | 
    
         
            +
                    if level
         
     | 
| 
      
 79 
     | 
    
         
            +
                      logger = Log4r::Logger.new("vagrant_azure")
         
     | 
| 
      
 80 
     | 
    
         
            +
                      logger.outputters = Log4r::Outputter.stderr
         
     | 
| 
      
 81 
     | 
    
         
            +
                      logger.level = level
         
     | 
| 
      
 82 
     | 
    
         
            +
                      logger = nil
         
     | 
| 
      
 83 
     | 
    
         
            +
                    end
         
     | 
| 
      
 84 
     | 
    
         
            +
                  end
         
     | 
| 
      
 85 
     | 
    
         
            +
                end
         
     | 
| 
      
 86 
     | 
    
         
            +
              end
         
     | 
| 
      
 87 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,70 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #--------------------------------------------------------------------------
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Copyright (c) Microsoft Open Technologies, Inc.
         
     | 
| 
      
 3 
     | 
    
         
            +
            # All Rights Reserved. Licensed under the Apache 2.0 License.
         
     | 
| 
      
 4 
     | 
    
         
            +
            #--------------------------------------------------------------------------
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'log4r'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'vagrant'
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            module VagrantPlugins
         
     | 
| 
      
 9 
     | 
    
         
            +
              module WinAzure
         
     | 
| 
      
 10 
     | 
    
         
            +
                class Provider < Vagrant.plugin('2', :provider)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  attr_reader :driver
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  def initialize(machine)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    @machine = machine
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                    # Load the driver
         
     | 
| 
      
 17 
     | 
    
         
            +
                    machine_id_changed
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  def action(name)
         
     | 
| 
      
 21 
     | 
    
         
            +
                    # Attempt to get the action method from the Action class if it
         
     | 
| 
      
 22 
     | 
    
         
            +
                    # exists, otherwise return nil to show that we don't support the
         
     | 
| 
      
 23 
     | 
    
         
            +
                    # given action.
         
     | 
| 
      
 24 
     | 
    
         
            +
                    action_method = "action_#{name}"
         
     | 
| 
      
 25 
     | 
    
         
            +
                    return Action.send(action_method) if Action.respond_to?(action_method)
         
     | 
| 
      
 26 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  def machine_id_changed
         
     | 
| 
      
 30 
     | 
    
         
            +
                    @driver = Driver.new(@machine)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  def ssh_info
         
     | 
| 
      
 34 
     | 
    
         
            +
                    # Run a custom action called "read_ssh_info" which does what it
         
     | 
| 
      
 35 
     | 
    
         
            +
                    # says and puts the resulting SSH info into the `:machine_ssh_info`
         
     | 
| 
      
 36 
     | 
    
         
            +
                    # key in the environment.
         
     | 
| 
      
 37 
     | 
    
         
            +
                    env = @machine.action('read_ssh_info')
         
     | 
| 
      
 38 
     | 
    
         
            +
                    env[:machine_ssh_info]
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  def rdp_info
         
     | 
| 
      
 42 
     | 
    
         
            +
                    env = @machine.action('read_rdp_info')
         
     | 
| 
      
 43 
     | 
    
         
            +
                    env[:machine_ssh_info]
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                  def winrm_info
         
     | 
| 
      
 47 
     | 
    
         
            +
                    env = @machine.action('read_winrm_info')
         
     | 
| 
      
 48 
     | 
    
         
            +
                    env[:machine_ssh_info]
         
     | 
| 
      
 49 
     | 
    
         
            +
                  end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                  def state
         
     | 
| 
      
 52 
     | 
    
         
            +
                    # Run a custom action we define called "read_state" which does what it
         
     | 
| 
      
 53 
     | 
    
         
            +
                    # says. It puts the state in the `:machine_state_id` key in the env
         
     | 
| 
      
 54 
     | 
    
         
            +
                    env = @machine.action('read_state')
         
     | 
| 
      
 55 
     | 
    
         
            +
                    state_id = env[:machine_state_id]
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                    short = "Machine's current state is #{state_id}"
         
     | 
| 
      
 58 
     | 
    
         
            +
                    long = ""
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                    # Return the MachineState object
         
     | 
| 
      
 61 
     | 
    
         
            +
                    Vagrant::MachineState.new(state_id, short, long)
         
     | 
| 
      
 62 
     | 
    
         
            +
                  end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                  def to_s
         
     | 
| 
      
 65 
     | 
    
         
            +
                    id = @machine.id.nil? ? 'new' : @machine.id
         
     | 
| 
      
 66 
     | 
    
         
            +
                    "Azure (#{id})"
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end
         
     | 
| 
      
 68 
     | 
    
         
            +
                end
         
     | 
| 
      
 69 
     | 
    
         
            +
              end
         
     | 
| 
      
 70 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,109 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #---------------------------------------------------------------------------
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Copyright (c) Microsoft Open Technologies, Inc.
         
     | 
| 
      
 3 
     | 
    
         
            +
            # All Rights Reserved. Licensed under the Apache 2.0 License.
         
     | 
| 
      
 4 
     | 
    
         
            +
            #---------------------------------------------------------------------------
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'fileutils'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'tempfile'
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            module VagrantPlugins
         
     | 
| 
      
 9 
     | 
    
         
            +
              module WinAzure
         
     | 
| 
      
 10 
     | 
    
         
            +
                module Provisioner
         
     | 
| 
      
 11 
     | 
    
         
            +
                  class Puppet
         
     | 
| 
      
 12 
     | 
    
         
            +
                    attr_reader :provisioner
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                    def initialize(env)
         
     | 
| 
      
 15 
     | 
    
         
            +
                      @env = env
         
     | 
| 
      
 16 
     | 
    
         
            +
                      @provisioner = env[:provisioner]
         
     | 
| 
      
 17 
     | 
    
         
            +
                    end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                    def provision_for_windows
         
     | 
| 
      
 20 
     | 
    
         
            +
                      options = [config.options].flatten
         
     | 
| 
      
 21 
     | 
    
         
            +
                      @module_paths = provisioner.instance_variable_get('@module_paths')
         
     | 
| 
      
 22 
     | 
    
         
            +
                      @hiera_config_path = provisioner.instance_variable_get(
         
     | 
| 
      
 23 
     | 
    
         
            +
                        '@hiera_config_path'
         
     | 
| 
      
 24 
     | 
    
         
            +
                      )
         
     | 
| 
      
 25 
     | 
    
         
            +
                      @manifest_file = provisioner.instance_variable_get('@manifest_file')
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                      # Copy the manifests directory to the guest
         
     | 
| 
      
 28 
     | 
    
         
            +
                      if config.manifests_path[0].to_sym == :host
         
     | 
| 
      
 29 
     | 
    
         
            +
                        @env[:machine].provider.driver.upload(
         
     | 
| 
      
 30 
     | 
    
         
            +
                          File.expand_path(
         
     | 
| 
      
 31 
     | 
    
         
            +
                            config.manifests_path[1], @env[:machine].env.root_path
         
     | 
| 
      
 32 
     | 
    
         
            +
                          ),
         
     | 
| 
      
 33 
     | 
    
         
            +
                          provisioner.manifests_guest_path
         
     | 
| 
      
 34 
     | 
    
         
            +
                        )
         
     | 
| 
      
 35 
     | 
    
         
            +
                      end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                      # Copy the module paths to the guest
         
     | 
| 
      
 38 
     | 
    
         
            +
                      @module_paths.each do |from, to|
         
     | 
| 
      
 39 
     | 
    
         
            +
                        @env[:machine].provider.driver.upload(from.to_s, to)
         
     | 
| 
      
 40 
     | 
    
         
            +
                      end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                      module_paths = @module_paths.map { |_, to| to }
         
     | 
| 
      
 43 
     | 
    
         
            +
                      unless module_paths.empty?
         
     | 
| 
      
 44 
     | 
    
         
            +
                        # Prepend the default module path
         
     | 
| 
      
 45 
     | 
    
         
            +
                        module_paths.unshift('/ProgramData/PuppetLabs/puppet/etc/modules')
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                        # Add the command  line switch to add the module path
         
     | 
| 
      
 48 
     | 
    
         
            +
                        options << "--modulepath \"#{module_paths.join(':')}\""
         
     | 
| 
      
 49 
     | 
    
         
            +
                      end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                      if @hiera_config_path
         
     | 
| 
      
 52 
     | 
    
         
            +
                        options << "--hiera_config=#{@hiera_config_path}"
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                        # Upload Hiera configuration if we have it
         
     | 
| 
      
 55 
     | 
    
         
            +
                        local_hiera_path = File.expand_path(
         
     | 
| 
      
 56 
     | 
    
         
            +
                          config.hiera_config_path,
         
     | 
| 
      
 57 
     | 
    
         
            +
                          @env[:machine].env.root_path
         
     | 
| 
      
 58 
     | 
    
         
            +
                        )
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                        @env[:machine].provider.driver.upload(
         
     | 
| 
      
 61 
     | 
    
         
            +
                          local_hiera_path,
         
     | 
| 
      
 62 
     | 
    
         
            +
                          @hiera_config_path
         
     | 
| 
      
 63 
     | 
    
         
            +
                        )
         
     | 
| 
      
 64 
     | 
    
         
            +
                      end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                      options << "--manifestdir #{provisioner.manifests_guest_path}"
         
     | 
| 
      
 67 
     | 
    
         
            +
                      options << "--detailed-exitcodes"
         
     | 
| 
      
 68 
     | 
    
         
            +
                      options << @manifest_file
         
     | 
| 
      
 69 
     | 
    
         
            +
                      options  = options.join(' ')
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                      # Build up the custome facts if we have any
         
     | 
| 
      
 72 
     | 
    
         
            +
                      facter = ''
         
     | 
| 
      
 73 
     | 
    
         
            +
                      unless config.facter.empty?
         
     | 
| 
      
 74 
     | 
    
         
            +
                        facts = []
         
     | 
| 
      
 75 
     | 
    
         
            +
                        config.facter.each do |key, value|
         
     | 
| 
      
 76 
     | 
    
         
            +
                          facts << "FACTER_#{key}='#{value}'"
         
     | 
| 
      
 77 
     | 
    
         
            +
                        end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                        facter = "#{facts.join(' ')}"
         
     | 
| 
      
 80 
     | 
    
         
            +
                      end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                      command = "#{facter}puppet apply #{options}"
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                      if config.working_directory
         
     | 
| 
      
 85 
     | 
    
         
            +
                        command = "cd #{config.working_directory} && #{command}"
         
     | 
| 
      
 86 
     | 
    
         
            +
                      end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                      @env[:ui].info I18n.t(
         
     | 
| 
      
 89 
     | 
    
         
            +
                        'vagrant_azure.provisioners.puppet.running_puppet',
         
     | 
| 
      
 90 
     | 
    
         
            +
                        manifest: config.manifest_file
         
     | 
| 
      
 91 
     | 
    
         
            +
                      )
         
     | 
| 
      
 92 
     | 
    
         
            +
                      @env[:ui].info 'Executing puppet script in Windows Azure VM'
         
     | 
| 
      
 93 
     | 
    
         
            +
                      @env[:machine].provider.driver.run_remote_ps(command) do |type, data|
         
     | 
| 
      
 94 
     | 
    
         
            +
                        # Output the data with the proper color based on the stream.
         
     | 
| 
      
 95 
     | 
    
         
            +
                        if (type == :stdout || type == :stderr)
         
     | 
| 
      
 96 
     | 
    
         
            +
                          @env[:ui].detail data
         
     | 
| 
      
 97 
     | 
    
         
            +
                        end
         
     | 
| 
      
 98 
     | 
    
         
            +
                      end
         
     | 
| 
      
 99 
     | 
    
         
            +
                    end
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                    protected
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
                    def config
         
     | 
| 
      
 104 
     | 
    
         
            +
                      provisioner.config
         
     | 
| 
      
 105 
     | 
    
         
            +
                    end
         
     | 
| 
      
 106 
     | 
    
         
            +
                  end
         
     | 
| 
      
 107 
     | 
    
         
            +
                end
         
     | 
| 
      
 108 
     | 
    
         
            +
              end
         
     | 
| 
      
 109 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,41 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #-------------------------------------------------------------------------
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Copyright (c) Microsoft Open Technologies, Inc.
         
     | 
| 
      
 3 
     | 
    
         
            +
            # All Rights Reserved. Licensed under the Apache 2.0 License.
         
     | 
| 
      
 4 
     | 
    
         
            +
            #--------------------------------------------------------------------------
         
     | 
| 
      
 5 
     | 
    
         
            +
            param (
         
     | 
| 
      
 6 
     | 
    
         
            +
                [string]$guest_ip = $(throw "-guest_ip is required."),
         
     | 
| 
      
 7 
     | 
    
         
            +
                [string]$username = $(throw "-guest_username is required."),
         
     | 
| 
      
 8 
     | 
    
         
            +
                [string]$password = $(throw "-guest_password is required.")
         
     | 
| 
      
 9 
     | 
    
         
            +
            )
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            # Include the following modules
         
     | 
| 
      
 12 
     | 
    
         
            +
            $presentDir = Split-Path -parent $PSCommandPath
         
     | 
| 
      
 13 
     | 
    
         
            +
            . ([System.IO.Path]::Combine($presentDir, "utils\write_messages.ps1"))
         
     | 
| 
      
 14 
     | 
    
         
            +
            . ([System.IO.Path]::Combine($presentDir, "utils\create_session.ps1"))
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            try {
         
     | 
| 
      
 17 
     | 
    
         
            +
              $response = Create-Remote-Session $guest_ip $username $password
         
     | 
| 
      
 18 
     | 
    
         
            +
              if (!$response["session"] -and $response["error"]) {
         
     | 
| 
      
 19 
     | 
    
         
            +
                  Write-Host $response["error"]
         
     | 
| 
      
 20 
     | 
    
         
            +
                  return
         
     | 
| 
      
 21 
     | 
    
         
            +
              }
         
     | 
| 
      
 22 
     | 
    
         
            +
                function Remote-Execute() {
         
     | 
| 
      
 23 
     | 
    
         
            +
                  $winrm_state = ""
         
     | 
| 
      
 24 
     | 
    
         
            +
                  get-service winrm | ForEach-Object {
         
     | 
| 
      
 25 
     | 
    
         
            +
                    $winrm_state = $_.status
         
     | 
| 
      
 26 
     | 
    
         
            +
                  }
         
     | 
| 
      
 27 
     | 
    
         
            +
                  return "$winrm_state"
         
     | 
| 
      
 28 
     | 
    
         
            +
                }
         
     | 
| 
      
 29 
     | 
    
         
            +
                $result = Invoke-Command -Session $response["session"] -ScriptBlock ${function:Remote-Execute} -ErrorAction "stop"
         
     | 
| 
      
 30 
     | 
    
         
            +
                $resultHash = @{
         
     | 
| 
      
 31 
     | 
    
         
            +
                  message = "$result"
         
     | 
| 
      
 32 
     | 
    
         
            +
                }
         
     | 
| 
      
 33 
     | 
    
         
            +
                Write-Output-Message $resultHash
         
     | 
| 
      
 34 
     | 
    
         
            +
              } catch {
         
     | 
| 
      
 35 
     | 
    
         
            +
                $errortHash = @{
         
     | 
| 
      
 36 
     | 
    
         
            +
                  type = "PowerShellError"
         
     | 
| 
      
 37 
     | 
    
         
            +
                  error ="Failed to copy file $_"
         
     | 
| 
      
 38 
     | 
    
         
            +
                }
         
     | 
| 
      
 39 
     | 
    
         
            +
                Write-Error-Message $errortHash
         
     | 
| 
      
 40 
     | 
    
         
            +
                return
         
     | 
| 
      
 41 
     | 
    
         
            +
              }
         
     | 
| 
         @@ -0,0 +1,31 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #-------------------------------------------------------------------------
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Copyright (c) Microsoft Open Technologies, Inc.
         
     | 
| 
      
 3 
     | 
    
         
            +
            # All Rights Reserved. Licensed under the Apache 2.0 License.
         
     | 
| 
      
 4 
     | 
    
         
            +
            #--------------------------------------------------------------------------
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            param (
         
     | 
| 
      
 7 
     | 
    
         
            +
                [string]$vm_id = $(throw "-vm_id is required."),
         
     | 
| 
      
 8 
     | 
    
         
            +
                [string]$path = $(throw "-path is required.")
         
     | 
| 
      
 9 
     | 
    
         
            +
            )
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            # Include the following modules
         
     | 
| 
      
 12 
     | 
    
         
            +
            $presentDir = Split-Path -parent $PSCommandPath
         
     | 
| 
      
 13 
     | 
    
         
            +
            . ([System.IO.Path]::Combine($presentDir, "utils\write_messages.ps1"))
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            # Export the Virtual Machine
         
     | 
| 
      
 17 
     | 
    
         
            +
            try {
         
     | 
| 
      
 18 
     | 
    
         
            +
              $vm = Get-Vm -Id $vm_id
         
     | 
| 
      
 19 
     | 
    
         
            +
              $vm  | Export-VM -Path $path -ErrorAction "stop"
         
     | 
| 
      
 20 
     | 
    
         
            +
              $name = $vm.name
         
     | 
| 
      
 21 
     | 
    
         
            +
              $resultHash = @{
         
     | 
| 
      
 22 
     | 
    
         
            +
                name = "$name"
         
     | 
| 
      
 23 
     | 
    
         
            +
              }
         
     | 
| 
      
 24 
     | 
    
         
            +
              Write-Output-Message $resultHash
         
     | 
| 
      
 25 
     | 
    
         
            +
              } catch {
         
     | 
| 
      
 26 
     | 
    
         
            +
                $errortHash = @{
         
     | 
| 
      
 27 
     | 
    
         
            +
                  type = "PowerShellError"
         
     | 
| 
      
 28 
     | 
    
         
            +
                  error = "Failed to export a  VM $_"
         
     | 
| 
      
 29 
     | 
    
         
            +
                }
         
     | 
| 
      
 30 
     | 
    
         
            +
                Write-Error-Message $errortHash
         
     | 
| 
      
 31 
     | 
    
         
            +
              }
         
     | 
| 
         @@ -0,0 +1,145 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #-------------------------------------------------------------------------
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Copyright (c) Microsoft Open Technologies, Inc.
         
     | 
| 
      
 3 
     | 
    
         
            +
            # All Rights Reserved. Licensed under the Apache 2.0 License.
         
     | 
| 
      
 4 
     | 
    
         
            +
            #--------------------------------------------------------------------------
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            param (
         
     | 
| 
      
 7 
     | 
    
         
            +
                [string]$vm_id = $(throw "-vm_id is required."),
         
     | 
| 
      
 8 
     | 
    
         
            +
                [string]$guest_ip = $(throw "-guest_ip is required."),
         
     | 
| 
      
 9 
     | 
    
         
            +
                [string]$username = $(throw "-guest_username is required."),
         
     | 
| 
      
 10 
     | 
    
         
            +
                [string]$password = $(throw "-guest_password is required."),
         
     | 
| 
      
 11 
     | 
    
         
            +
                [string]$host_path = $(throw "-host_path is required."),
         
     | 
| 
      
 12 
     | 
    
         
            +
                [string]$guest_path = $(throw "-guest_path is required.")
         
     | 
| 
      
 13 
     | 
    
         
            +
             )
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            # Include the following modules
         
     | 
| 
      
 16 
     | 
    
         
            +
            $presentDir = Split-Path -parent $PSCommandPath
         
     | 
| 
      
 17 
     | 
    
         
            +
            $modules = @()
         
     | 
| 
      
 18 
     | 
    
         
            +
            $modules += $presentDir + "\utils\write_messages.ps1"
         
     | 
| 
      
 19 
     | 
    
         
            +
            $modules += $presentDir + "\utils\create_session.ps1"
         
     | 
| 
      
 20 
     | 
    
         
            +
            forEach ($module in $modules) { . $module }
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            function Get-file-hash($source_path, $delimiter) {
         
     | 
| 
      
 23 
     | 
    
         
            +
                $source_files = @()
         
     | 
| 
      
 24 
     | 
    
         
            +
                (Get-ChildItem $source_path -rec -force | ForEach-Object -Process {
         
     | 
| 
      
 25 
     | 
    
         
            +
                  Get-FileHash -Path $_.FullName -Algorithm MD5 } ) |
         
     | 
| 
      
 26 
     | 
    
         
            +
                    ForEach-Object -Process {
         
     | 
| 
      
 27 
     | 
    
         
            +
                      $source_files += $_.Path.Replace($source_path, "") + $delimiter + $_.Hash
         
     | 
| 
      
 28 
     | 
    
         
            +
                    }
         
     | 
| 
      
 29 
     | 
    
         
            +
                $source_files
         
     | 
| 
      
 30 
     | 
    
         
            +
            }
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            function Get-remote-file-hash($source_path, $delimiter, $session) {
         
     | 
| 
      
 33 
     | 
    
         
            +
                Invoke-Command -Session $session -ScriptBlock ${function:Get-file-hash} -ArgumentList $source_path, $delimiter
         
     | 
| 
      
 34 
     | 
    
         
            +
                # TODO:
         
     | 
| 
      
 35 
     | 
    
         
            +
                # Check if remote PS Scripting errors
         
     | 
| 
      
 36 
     | 
    
         
            +
            }
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            function Sync-Remote-Machine($machine, $remove_files, $copy_files, $host_path, $guest_path) {
         
     | 
| 
      
 39 
     | 
    
         
            +
                ForEach ($item in $copy_files) {
         
     | 
| 
      
 40 
     | 
    
         
            +
                  $from = $host_path + $item
         
     | 
| 
      
 41 
     | 
    
         
            +
                  $to = $guest_path + $item
         
     | 
| 
      
 42 
     | 
    
         
            +
                  # Copy VM can also take a VM object
         
     | 
| 
      
 43 
     | 
    
         
            +
                  Copy-VMFile  -VM $machine -SourcePath $from -DestinationPath $to -CreateFullPath -FileSource Host -Force
         
     | 
| 
      
 44 
     | 
    
         
            +
                }
         
     | 
| 
      
 45 
     | 
    
         
            +
            }
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            function Create-Remote-Folders($empty_source_folders, $guest_path) {
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                ForEach ($item in $empty_source_folders) {
         
     | 
| 
      
 50 
     | 
    
         
            +
                    $new_name =  $guest_path + $item
         
     | 
| 
      
 51 
     | 
    
         
            +
                    New-Item "$new_name" -type directory -Force
         
     | 
| 
      
 52 
     | 
    
         
            +
                }
         
     | 
| 
      
 53 
     | 
    
         
            +
            }
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            function Create-Guest-Folder($guest_path) {
         
     | 
| 
      
 56 
     | 
    
         
            +
              try {
         
     | 
| 
      
 57 
     | 
    
         
            +
                if (Test-Path $guest_path) {
         
     | 
| 
      
 58 
     | 
    
         
            +
                  $junction = Get-Item $guest_path
         
     | 
| 
      
 59 
     | 
    
         
            +
                  $junction.Delete()
         
     | 
| 
      
 60 
     | 
    
         
            +
                }
         
     | 
| 
      
 61 
     | 
    
         
            +
              }
         
     | 
| 
      
 62 
     | 
    
         
            +
              # Catch any [IOException]
         
     | 
| 
      
 63 
     | 
    
         
            +
               catch {
         
     | 
| 
      
 64 
     | 
    
         
            +
                 Remove-Item "$guest_path" -Force -Recurse
         
     | 
| 
      
 65 
     | 
    
         
            +
               }
         
     | 
| 
      
 66 
     | 
    
         
            +
               New-Item "$guest_path" -type directory -Force
         
     | 
| 
      
 67 
     | 
    
         
            +
            }
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
            function Get-Empty-folders-From-Source($host_path) {
         
     | 
| 
      
 70 
     | 
    
         
            +
              Get-ChildItem $host_path -recurse |
         
     | 
| 
      
 71 
     | 
    
         
            +
                    Where-Object {$_.PSIsContainer -eq $True} |
         
     | 
| 
      
 72 
     | 
    
         
            +
                        Where-Object {$_.GetFiles().Count -eq 0} |
         
     | 
| 
      
 73 
     | 
    
         
            +
                            Select-Object FullName | ForEach-Object -Process {
         
     | 
| 
      
 74 
     | 
    
         
            +
                                $empty_source_folders += ($_.FullName.Replace($host_path, ""))
         
     | 
| 
      
 75 
     | 
    
         
            +
                            }
         
     | 
| 
      
 76 
     | 
    
         
            +
            }
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
            $delimiter = " || "
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
            $machine = Get-VM -Id $vm_id
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
            # FIXME: PowerShell guys please fix this.
         
     | 
| 
      
 83 
     | 
    
         
            +
            # The below script checks for all VMIntegrationService which are not enabled
         
     | 
| 
      
 84 
     | 
    
         
            +
            # and will enable this.
         
     | 
| 
      
 85 
     | 
    
         
            +
            # When when all the services are enabled this throws an error.
         
     | 
| 
      
 86 
     | 
    
         
            +
            # Enable VMIntegrationService to true
         
     | 
| 
      
 87 
     | 
    
         
            +
            try {
         
     | 
| 
      
 88 
     | 
    
         
            +
              Get-VM -Id $vm_id | Get-VMIntegrationService -Name "Guest Service Interface" | Enable-VMIntegrationService -Passthru
         
     | 
| 
      
 89 
     | 
    
         
            +
              }
         
     | 
| 
      
 90 
     | 
    
         
            +
              catch { }
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
            $response = Create-Remote-Session $guest_ip $username $password
         
     | 
| 
      
 94 
     | 
    
         
            +
            if (!$response["session"] -and $response["error"]) {
         
     | 
| 
      
 95 
     | 
    
         
            +
              $errortHash = @{
         
     | 
| 
      
 96 
     | 
    
         
            +
                type = "PowerShellError"
         
     | 
| 
      
 97 
     | 
    
         
            +
                error = $response["error"]
         
     | 
| 
      
 98 
     | 
    
         
            +
              }
         
     | 
| 
      
 99 
     | 
    
         
            +
              Write-Error-Message $errortHash
         
     | 
| 
      
 100 
     | 
    
         
            +
              return
         
     | 
| 
      
 101 
     | 
    
         
            +
            }
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
            $session = $response["session"]
         
     | 
| 
      
 104 
     | 
    
         
            +
            # Create the guest folder if not exist
         
     | 
| 
      
 105 
     | 
    
         
            +
            $result = Invoke-Command -Session $session -ScriptBlock ${function:Create-Guest-Folder} -ArgumentList $guest_path
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
            $source_files = Get-file-hash $host_path $delimiter
         
     | 
| 
      
 109 
     | 
    
         
            +
            $destination_files = Get-remote-file-hash $guest_path $delimiter $session
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
            if (!$destination_files) {
         
     | 
| 
      
 112 
     | 
    
         
            +
              $destination_files = @()
         
     | 
| 
      
 113 
     | 
    
         
            +
            }
         
     | 
| 
      
 114 
     | 
    
         
            +
            if (!$source_files) {
         
     | 
| 
      
 115 
     | 
    
         
            +
              $source_files = @()
         
     | 
| 
      
 116 
     | 
    
         
            +
            }
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
            # Compare source and destination files
         
     | 
| 
      
 119 
     | 
    
         
            +
            $remove_files = @()
         
     | 
| 
      
 120 
     | 
    
         
            +
            $copy_files = @()
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
            Compare-Object -ReferenceObject $source_files -DifferenceObject $destination_files | ForEach-Object {
         
     | 
| 
      
 124 
     | 
    
         
            +
              if ($_.SideIndicator -eq '=>') {
         
     | 
| 
      
 125 
     | 
    
         
            +
                  $remove_files += $_.InputObject.Split($delimiter)[0]
         
     | 
| 
      
 126 
     | 
    
         
            +
              } else {
         
     | 
| 
      
 127 
     | 
    
         
            +
                  $copy_files += $_.InputObject.Split($delimiter)[0]
         
     | 
| 
      
 128 
     | 
    
         
            +
              }
         
     | 
| 
      
 129 
     | 
    
         
            +
            }
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
            # Update the files to remote machine
         
     | 
| 
      
 132 
     | 
    
         
            +
            Sync-Remote-Machine $machine $remove_files $copy_files $host_path $guest_path
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
            # Create any empty folders which missed to sync to remote machine
         
     | 
| 
      
 135 
     | 
    
         
            +
            $empty_source_folders = @()
         
     | 
| 
      
 136 
     | 
    
         
            +
            $directories = Get-Empty-folders-From-Source $host_path
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
            $result = Invoke-Command -Session $session -ScriptBlock ${function:Create-Remote-Folders} -ArgumentList $empty_source_folders, $guest_path
         
     | 
| 
      
 139 
     | 
    
         
            +
            # Always remove the connection after Use
         
     | 
| 
      
 140 
     | 
    
         
            +
            Remove-PSSession -Id $session.Id
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
            $resultHash = @{
         
     | 
| 
      
 143 
     | 
    
         
            +
              message = "OK"
         
     | 
| 
      
 144 
     | 
    
         
            +
            }
         
     | 
| 
      
 145 
     | 
    
         
            +
            Write-Output-Message $resultHash
         
     |