Merge pull request #10263 from chrisroberts/e-winrm-extensions

Add winrm and upload commands
This commit is contained in:
Chris Roberts 2018-10-09 14:42:54 -07:00 committed by GitHub
commit 93c2f0f497
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 1923 additions and 1 deletions

View File

@ -816,6 +816,22 @@ module Vagrant
error_key(:unimplemented_provider_action)
end
class UploadInvalidCompressionType < VagrantError
error_key(:upload_invalid_compression_type)
end
class UploadMissingExtractCapability < VagrantError
error_key(:upload_missing_extract_capability)
end
class UploadMissingTempCapability < VagrantError
error_key(:upload_missing_temp_capability)
end
class UploadSourceMissing < VagrantError
error_key(:upload_source_missing)
end
class VagrantInterrupt < VagrantError
error_key(:interrupted)
end
@ -968,6 +984,10 @@ module Vagrant
error_key(:power_off, "vagrant.actions.vm.export")
end
class WinRMInvalidCommunicator < VagrantError
error_key(:winrm_invalid_communicator)
end
class WSLVagrantVersionMismatch < VagrantError
error_key(:wsl_vagrant_version_mismatch)
end

View File

@ -0,0 +1,236 @@
require 'optparse'
require "rubygems/package"
module VagrantPlugins
module CommandUpload
class Command < Vagrant.plugin("2", :command)
VALID_COMPRESS_TYPES = [:tgz, :zip].freeze
def self.synopsis
"upload to machine via communicator"
end
def execute
options = {}
opts = OptionParser.new do |o|
o.banner = "Usage: vagrant upload [options] <source> [destination] [name|id]"
o.separator ""
o.separator "Options:"
o.separator ""
o.on("-t", "--temporary", "Upload source to temporary directory") do |t|
options[:temporary] = t
end
o.on("-c", "--compress", "Use gzip compression for upload") do |c|
options[:compress] = c
end
o.on("-C", "--compression-type=TYPE", "Type of compression to use (#{VALID_COMPRESS_TYPES.join(", ")})") do |c|
options[:compression_type] = c.to_sym
options[:compress] = true
end
end
argv = parse_options(opts)
return if !argv
case argv.size
when 3
source, destination, guest = argv
when 2, 1
source = argv[0]
if @env.active_machines.map(&:first).map(&:to_s).include?(argv[1])
guest = argv[1]
else
destination = argv[1]
end
else
raise Vagrant::Errors::CLIInvalidUsage, help: opts.help.chomp
end
# NOTE: We do this to handle paths on Windows like: "..\space dir\"
# because the final separater acts to escape the quote and ends up
# in the source value.
source = source.sub(/["']$/, "")
destination ||= File.basename(source)
if File.file?(source)
type = :file
elsif File.directory?(source)
type = :directory
else
raise Vagrant::Errors::UploadSourceMissing,
source: source
end
with_target_vms(guest, single_target: true) do |machine|
if options[:temporary]
if !machine.guest.capability?(:create_tmp_path)
raise Vagrant::Errors::UploadMissingTempCapability
end
extension = File.extname(source) if type == :file
destination = machine.guest.capability(:create_tmp_path, type: type, extension: extension)
end
if options[:compress]
compression_setup!(machine, options)
@env.ui.info(I18n.t("vagrant.commands.upload.compress",
source: source,
type: options[:compression_type]
))
destination_decompressed = destination
destination = machine.guest.capability(:create_tmp_path, type: :file, extension: ".#{options[:compression_type]}")
source_display = source
source = options[:compression_type] == :zip ? compress_source_zip(source) : compress_source_tgz(source)
end
@env.ui.info(I18n.t("vagrant.commands.upload.start",
source: source,
destination: destination
))
# If the source is a directory, attach a `/.` to the end so we
# upload the contents to the destination instead of within a
# folder at the destination
if File.directory?(source) && !source.end_with?(".")
upload_source = File.join(source, ".")
else
upload_source = source
end
machine.communicate.upload(upload_source, destination)
if options[:compress]
@env.ui.info(I18n.t("vagrant.commands.upload.decompress",
destination: destination_decompressed,
type: options[:compression_type]
))
machine.guest.capability(options[:decompression_method], destination, destination_decompressed, type: type)
destination = destination_decompressed
FileUtils.rm(source)
source = source_display
end
end
@env.ui.info(I18n.t("vagrant.commands.upload.complete",
source: source,
destination: destination
))
# Success, exit status 0
0
end
# Setup compression options and validate host and guest have capability
# to handle compression
#
# @param [Vagrant::Machine] machine Vagrant guest machine
# @param [Hash] options Command options
def compression_setup!(machine, options)
if !options[:compression_type]
if machine.guest.capability_host_chain.first[0] == :windows
options[:compression_type] = :zip
else
options[:compression_type] = :tgz
end
end
if !VALID_COMPRESS_TYPES.include?(options[:compression_type])
raise Vagrant::Errors::UploadInvalidCompressionType,
type: options[:compression_type],
valid_types: VALID_COMPRESS_TYPES.join(", ")
end
options[:decompression_method] = "decompress_#{options[:compression_type]}".to_sym
if !machine.guest.capability?(options[:decompression_method])
raise Vagrant::Errors::UploadMissingExtractCapability,
type: options[:compression_type]
end
end
# Compress path using zip into temporary file
#
# @param [String] path Path to compress
# @return [String] path to compressed file
def compress_source_zip(path)
require "zip"
zipfile = Tempfile.create(["vagrant", ".zip"])
zipfile.close
if File.file?(path)
source_items = [path]
else
source_items = Dir.glob(File.join(path, "**", "**", "*"))
end
c_dir = nil
Zip::File.open(zipfile.path, Zip::File::CREATE) do |zip|
source_items.each do |source_item|
next if File.directory?(source_item)
trim_item = source_item.sub(path, "").sub(%r{^[/\\]}, "")
dirname = File.dirname(trim_item)
zip.mkdir dirname if c_dir != dirname
c_dir = dirname
zip.get_output_stream(trim_item) do |f|
source_file = File.open(source_item, "rb")
while data = source_file.read(2048)
f.write(data)
end
end
end
end
zipfile.path
end
# Compress path using tar and gzip into temporary file
#
# @param [String] path Path to compress
# @return [String] path to compressed file
def compress_source_tgz(path)
tarfile = Tempfile.create(["vagrant", ".tar"])
tarfile.close
tarfile = File.open(tarfile.path, "wb+")
tgzfile = Tempfile.create(["vagrant", ".tgz"])
tgzfile.close
tgzfile = File.open(tgzfile.path, "wb")
tar = Gem::Package::TarWriter.new(tarfile)
tgz = Zlib::GzipWriter.new(tgzfile)
if File.file?(path)
tar.add_file(File.basename(path), File.stat(path).mode) do |io|
File.open(path, "rb") do |file|
while bytes = file.read(4096)
io.write(bytes)
end
end
end
else
Dir.glob(File.join(path, "**/**/*")).each do |item|
rel_path = item.sub(path, "")
item_mode = File.stat(item).mode
if File.directory?(item)
tar.mkdir(rel_path, item_mode)
else
tar.add_file(rel_path, item_mode) do |io|
File.open(item, "rb") do |file|
while bytes = file.read(4096)
io.write(bytes)
end
end
end
end
end
end
tar.close
tarfile.rewind
while bytes = tarfile.read(4096)
tgz.write bytes
end
tgz.close
tgzfile.close
tarfile.close
File.delete(tarfile.path)
tgzfile.path
end
end
end
end

View File

@ -0,0 +1,17 @@
require "vagrant"
module VagrantPlugins
module CommandUpload
class Plugin < Vagrant.plugin("2")
name "upload command"
description <<-DESC
The `upload` command uploads files to guest via communicator
DESC
command("upload") do
require File.expand_path("../command", __FILE__)
Command
end
end
end
end

View File

@ -0,0 +1,69 @@
require 'optparse'
require "vagrant/util/safe_puts"
module VagrantPlugins
module CommandWinRM
class Command < Vagrant.plugin("2", :command)
include Vagrant::Util::SafePuts
def self.synopsis
"executes commands on a machine via WinRM"
end
def execute
options = {
command: [],
shell: :powershell
}
opts = OptionParser.new do |o|
o.banner = "Usage: vagrant winrm [options] [name|id]"
o.separator ""
o.separator "Options:"
o.separator ""
o.on("-c", "--command COMMAND", "Execute a WinRM command directly") do |c|
options[:command] << c
end
o.on("-e", "--elevated", "Run with elevated credentials") do |e|
options[:elevated] = true
end
o.on("-s", "--shell SHELL", [:powershell, :cmd], "Use specified shell (powershell, cmd)") do |s|
options[:shell] = s
end
end
argv = parse_options(opts)
return if !argv
with_target_vms(argv, single_target: true) do |machine|
if machine.config.vm.communicator != :winrm
raise Vagrant::Errors::WinRMInvalidCommunicator
end
opts = {
shell: options[:shell],
elevated: !!options[:elevated]
}
options[:command].each do |cmd|
begin
machine.communicate.execute(cmd, opts) do |type, data|
io = type == :stderr ? $stderr : $stdout
safe_puts(data, io: io, printer: :print)
end
rescue VagrantPlugins::CommunicatorWinRM::Errors::WinRMBadExitStatus
return 1
end
end
end
# Success, exit status 0
0
end
end
end
end

View File

@ -0,0 +1,17 @@
require "vagrant"
module VagrantPlugins
module CommandWinRM
class Plugin < Vagrant.plugin("2")
name "winrm command"
description <<-DESC
The `winrm` command executes commands on a machine via WinRM
DESC
command("winrm") do
require File.expand_path("../command", __FILE__)
Command
end
end
end
end

View File

@ -0,0 +1,125 @@
require 'optparse'
require "vagrant/util/safe_puts"
require_relative "../../communicators/winrm/helper"
module VagrantPlugins
module CommandWinRMConfig
class Command < Vagrant.plugin("2", :command)
include Vagrant::Util::SafePuts
def self.synopsis
"outputs WinRM configuration to connect to the machine"
end
def convert_win_paths(paths)
paths.map! { |path| Vagrant::Util::Platform.format_windows_path(path, :disable_unc) }
end
def execute
options = {}
opts = OptionParser.new do |o|
o.banner = "Usage: vagrant winrm-config [options] [name|id]"
o.separator ""
o.separator "Options:"
o.separator ""
o.on("--host NAME", "Name the host for the config") do |h|
options[:host] = h
end
end
argv = parse_options(opts)
return if !argv
with_target_vms(argv) do |machine|
winrm_info = CommunicatorWinRM::Helper.winrm_info(machine)
raise Vagrant::Errors::WinRMNotRead if winrm_info.nil?
rdp_info = get_rdp_info(machine) || {}
variables = {
host_key: options[:host] || machine.name || "vagrant",
rdp_host: rdp_info[:host] || winrm_info[:host],
rdp_port: rdp_info[:port],
rdp_user: rdp_info[:username],
rdp_pass: rdp_info[:password],
winrm_host: winrm_info[:host],
winrm_port: winrm_info[:port],
winrm_user: machine.config.winrm.username,
winrm_password: machine.config.winrm.password
}
template = "commands/winrm_config/config"
config = Vagrant::Util::TemplateRenderer.render(template, variables)
machine.ui.machine("winrm-config", config)
safe_puts(config)
safe_puts
end
# Success, exit status 0
0
end
protected
# Generate RDP information for machine
#
# @param [Vagrant::Machine] machine Guest machine
# @return [Hash, nil]
def get_rdp_info(machine)
rdp_info = {}
if machine.provider.capability?(:rdp_info)
rdp_info = machine.provider.capability(:rdp_info)
rdp_info ||= {}
end
ssh_info = machine.ssh_info || {}
if !rdp_info[:username]
username = ssh_info[:username]
if machine.config.vm.communicator == :winrm
username = machine.config.winrm.username
end
rdp_info[:username] = username
end
if !rdp_info[:password]
password = ssh_info[:password]
if machine.config.vm.communicator == :winrm
password = machine.config.winrm.password
end
rdp_info[:password] = password
end
rdp_info[:host] ||= ssh_info[:host]
rdp_info[:port] ||= machine.config.rdp.port
rdp_info[:username] ||= machine.config.rdp.username
if rdp_info[:host] == "127.0.0.1"
# We need to find a forwarded port...
search_port = machine.config.rdp.search_port
ports = nil
if machine.provider.capability?(:forwarded_ports)
ports = machine.provider.capability(:forwarded_ports)
else
ports = {}.tap do |result|
machine.config.vm.networks.each do |type, netopts|
next if type != :forwarded_port
next if !netopts[:host]
result[netopts[:host]] = netopts[:guest]
end
end
end
ports = ports.invert
port = ports[search_port]
rdp_info[:port] = port
return nil if !port
end
rdp_info
end
end
end
end

View File

@ -0,0 +1,17 @@
require "vagrant"
module VagrantPlugins
module CommandWinRMConfig
class Plugin < Vagrant.plugin("2")
name "winrm-config command"
description <<-DESC
The `winrm-config` command dumps WinRM configuration information
DESC
command("winrm-config") do
require File.expand_path("../command", __FILE__)
Command
end
end
end
end

View File

@ -0,0 +1,77 @@
module VagrantPlugins
module GuestBSD
module Cap
class FileSystem
# Create a temporary file or directory on the guest
#
# @param [Vagrant::Machine] machine Vagrant guest machine
# @param [Hash] opts Path options
# @return [String] path to temporary file or directory
def self.create_tmp_path(machine, opts)
template = "vagrant"
cmd = ["mktemp"]
if opts[:type] == :directory
cmd << "-d"
end
cmd << "-t"
cmd << template
tmp_path = ""
machine.communicate.execute(cmd.join(" ")) do |type, data|
if type == :stdout
tmp_path << data
end
end
tmp_path.strip
end
# Decompress tgz file on guest to given location
#
# @param [Vagrant::Machine] machine Vagrant guest machine
# @param [String] compressed_file Path to compressed file on guest
# @param [String] destination Path for decompressed files on guest
def self.decompress_tgz(machine, compressed_file, destination, opts={})
comm = machine.communicate
extract_dir = create_tmp_path(machine, type: :directory)
cmds = []
if opts[:type] == :directory
cmds << "mkdir -p '#{destination}'"
else
cmds << "mkdir -p '#{File.dirname(destination)}'"
end
cmds += [
"tar -C '#{extract_dir}' -xzf '#{compressed_file}'",
"mv '#{extract_dir}'/* '#{destination}'",
"rm -f '#{compressed_file}'",
"rm -rf '#{extract_dir}'"
]
cmds.each{ |cmd| comm.execute(cmd) }
true
end
# Decompress zip file on guest to given location
#
# @param [Vagrant::Machine] machine Vagrant guest machine
# @param [String] compressed_file Path to compressed file on guest
# @param [String] destination Path for decompressed files on guest
def self.decompress_zip(machine, compressed_file, destination, opts={})
comm = machine.communicate
extract_dir = create_tmp_path(machine, type: :directory)
cmds = []
if opts[:type] == :directory
cmds << "mkdir -p '#{destination}'"
else
cmds << "mkdir -p '#{File.dirname(destination)}'"
end
cmds += [
"unzip '#{compressed_file}' -d '#{extract_dir}'",
"mv '#{extract_dir}'/* '#{destination}'",
"rm -f '#{compressed_file}'",
"rm -rf '#{extract_dir}'"
]
cmds.each{ |cmd| comm.execute(cmd) }
true
end
end
end
end
end

View File

@ -11,6 +11,21 @@ module VagrantPlugins
Guest
end
guest_capability(:bsd, :create_tmp_path) do
require_relative "cap/file_system"
Cap::FileSystem
end
guest_capability(:bsd, :decompress_tgz) do
require_relative "cap/file_system"
Cap::FileSystem
end
guest_capability(:bsd, :decompress_zip) do
require_relative "cap/file_system"
Cap::FileSystem
end
guest_capability(:bsd, :halt) do
require_relative "cap/halt"
Cap::Halt

View File

@ -0,0 +1,79 @@
module VagrantPlugins
module GuestLinux
module Cap
class FileSystem
# Create a temporary file or directory on the guest
#
# @param [Vagrant::Machine] machine Vagrant guest machine
# @param [Hash] opts Path options
# @return [String] path to temporary file or directory
def self.create_tmp_path(machine, opts)
template = "vagrant-XXXXXX"
if opts[:extension]
template << opts[:extension].to_s
end
cmd = ["mktemp", "--tmpdir"]
if opts[:type] == :directory
cmd << "-d"
end
cmd << template
tmp_path = ""
machine.communicate.execute(cmd.join(" ")) do |type, data|
if type == :stdout
tmp_path << data
end
end
tmp_path.strip
end
# Decompress tgz file on guest to given location
#
# @param [Vagrant::Machine] machine Vagrant guest machine
# @param [String] compressed_file Path to compressed file on guest
# @param [String] destination Path for decompressed files on guest
def self.decompress_tgz(machine, compressed_file, destination, opts={})
comm = machine.communicate
extract_dir = create_tmp_path(machine, type: :directory)
cmds = []
if opts[:type] == :directory
cmds << "mkdir -p '#{destination}'"
else
cmds << "mkdir -p '#{File.dirname(destination)}'"
end
cmds += [
"tar -C '#{extract_dir}' -xzf '#{compressed_file}'",
"mv '#{extract_dir}'/* '#{destination}'",
"rm -f '#{compressed_file}'",
"rm -rf '#{extract_dir}'"
]
cmds.each{ |cmd| comm.execute(cmd) }
true
end
# Decompress zip file on guest to given location
#
# @param [Vagrant::Machine] machine Vagrant guest machine
# @param [String] compressed_file Path to compressed file on guest
# @param [String] destination Path for decompressed files on guest
def self.decompress_zip(machine, compressed_file, destination, opts={})
comm = machine.communicate
extract_dir = create_tmp_path(machine, type: :directory)
cmds = []
if opts[:type] == :directory
cmds << "mkdir -p '#{destination}'"
else
cmds << "mkdir -p '#{File.dirname(destination)}'"
end
cmds += [
"unzip '#{compressed_file}' -d '#{extract_dir}'",
"mv '#{extract_dir}'/* '#{destination}'",
"rm -f '#{compressed_file}'",
"rm -rf '#{extract_dir}'"
]
cmds.each{ |cmd| comm.execute(cmd) }
true
end
end
end
end
end

View File

@ -16,6 +16,21 @@ module VagrantPlugins
Cap::ChooseAddressableIPAddr
end
guest_capability(:linux, :create_tmp_path) do
require_relative "cap/file_system"
Cap::FileSystem
end
guest_capability(:linux, :decompress_tgz) do
require_relative "cap/file_system"
Cap::FileSystem
end
guest_capability(:linux, :decompress_zip) do
require_relative "cap/file_system"
Cap::FileSystem
end
guest_capability(:linux, :halt) do
require_relative "cap/halt"
Cap::Halt

View File

@ -0,0 +1,77 @@
module VagrantPlugins
module GuestSolaris
module Cap
class FileSystem
# Create a temporary file or directory on the guest
#
# @param [Vagrant::Machine] machine Vagrant guest machine
# @param [Hash] opts Path options
# @return [String] path to temporary file or directory
def self.create_tmp_path(machine, opts)
template = "vagrant-XXXXXX"
cmd = ["mktemp"]
if opts[:type] == :directory
cmd << "-d"
end
cmd << "-t"
cmd << template
tmp_path = ""
machine.communicate.execute(cmd.join(" ")) do |type, data|
if type == :stdout
tmp_path << data
end
end
tmp_path.strip
end
# Decompress tgz file on guest to given location
#
# @param [Vagrant::Machine] machine Vagrant guest machine
# @param [String] compressed_file Path to compressed file on guest
# @param [String] destination Path for decompressed files on guest
def self.decompress_tgz(machine, compressed_file, destination, opts={})
comm = machine.communicate
extract_dir = create_tmp_path(machine, type: :directory)
cmds = []
if opts[:type] == :directory
cmds << "mkdir -p '#{destination}'"
else
cmds << "mkdir -p '#{File.dirname(destination)}'"
end
cmds += [
"tar xzf '#{compressed_file}' -C '#{extract_dir}'",
"mv '#{extract_dir}'/* '#{destination}'",
"rm -f '#{compressed_file}'",
"rm -rf '#{extract_dir}'"
]
cmds.each{ |cmd| comm.execute(cmd) }
true
end
# Decompress zip file on guest to given location
#
# @param [Vagrant::Machine] machine Vagrant guest machine
# @param [String] compressed_file Path to compressed file on guest
# @param [String] destination Path for decompressed files on guest
def self.decompress_zip(machine, compressed_file, destination, opts={})
comm = machine.communicate
extract_dir = create_tmp_path(machine, type: :directory)
cmds = []
if opts[:type] == :directory
cmds << "mkdir -p '#{destination}'"
else
cmds << "mkdir -p '#{File.dirname(destination)}'"
end
cmds += [
"unzip '#{compressed_file}' -d '#{extract_dir}'",
"mv '#{extract_dir}'/* '#{destination}'",
"rm -f '#{compressed_file}'",
"rm -rf '#{extract_dir}'"
]
cmds.each{ |cmd| comm.execute(cmd) }
true
end
end
end
end
end

View File

@ -16,6 +16,21 @@ module VagrantPlugins
Guest
end
guest_capability(:solaris, :create_tmp_path) do
require_relative "cap/file_system"
Cap::FileSystem
end
guest_capability(:solaris, :decompress_tgz) do
require_relative "cap/file_system"
Cap::FileSystem
end
guest_capability(:solaris, :decompress_zip) do
require_relative "cap/file_system"
Cap::FileSystem
end
guest_capability(:solaris, :change_host_name) do
require_relative "cap/change_host_name"
Cap::ChangeHostName

View File

@ -0,0 +1,65 @@
module VagrantPlugins
module GuestWindows
module Cap
class FileSystem
# Create a temporary file or directory on the guest
#
# @param [Vagrant::Machine] machine Vagrant guest machine
# @param [Hash] opts Path options
# @return [String] path to temporary file or directory
def self.create_tmp_path(machine, opts)
comm = machine.communicate
path = ""
cmd = "Write-Output ([System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), " \
"[System.IO.Path]::GetRandomFileName())) | Out-String -Width 2048"
comm.execute(cmd, shell: :powershell) do |type, data|
if type == :stdout
path << data
end
end
path.strip!
if opts[:extension]
path << opts[:extension].to_s
end
if opts[:type] == :directory
comm.execute("[System.IO.Directory]::CreateDirectory('#{path}')")
end
path
end
# Decompress zip file on guest to given location
#
# @param [Vagrant::Machine] machine Vagrant guest machine
# @param [String] compressed_file Path to compressed file on guest
# @param [String] destination Path for decompressed files on guest
def self.decompress_zip(machine, compressed_file, destination, opts={})
comm = machine.communicate
extract_dir = create_tmp_path(machine, type: :directory)
cmds = []
destination = destination.tr("/", "\\")
if opts[:type] == :directory
cmds << "New-Item -ItemType Directory -Force -Path \"#{destination}\""
else
d_parts = destination.split("\\")
d_parts.pop
parent_dir = d_parts.join("\\") + "\\"
cmds << "New-Item -ItemType Directory -Force -Path \"#{parent_dir}\""
end
cmd = "$f = \"#{compressed_file}\"; $d = \"#{extract_dir}\"; "
cmd << '$s = New-Object -ComObject "Shell.Application"; $z = $s.NameSpace($f); '
cmd << 'foreach($i in $z.items()){ $s.Namespace($d).copyhere($i); }'
cmds << cmd
cmds += [
"Move-Item -Force -Path \"#{extract_dir}\\*\" -Destination \"#{destination}\\\"",
"Remove-Item -Path \"#{compressed_file}\" -Force",
"Remove-Item -Path \"#{extract_dir}\" -Recurse -Force"
]
cmds.each do |cmd|
comm.execute(cmd, shell: :powershell)
end
true
end
end
end
end
end

View File

@ -34,6 +34,16 @@ module VagrantPlugins
Cap::Halt
end
guest_capability(:windows, :create_tmp_path) do
require_relative "cap/file_system"
Cap::FileSystem
end
guest_capability(:windows, :decompress_zip) do
require_relative "cap/file_system"
Cap::FileSystem
end
guest_capability(:windows, :mount_virtualbox_shared_folder) do
require_relative "cap/mount_shared_folder"
Cap::MountSharedFolder

View File

@ -0,0 +1,11 @@
Host <%= host_key %>
HostName <%= winrm_host %>
User <%= winrm_user %>
Password <%= winrm_password %>
Port <%= winrm_port %>
<% if rdp_port -%>
RDPHostName <%= rdp_host %>
RDPPort <%= rdp_port %>
RDPUser <%= rdp_user %>
RDPPassword <%= rdp_pass %>
<% end -%>

View File

@ -1462,6 +1462,8 @@ en:
your current setup. Please verify you have all the proper
prerequisites for using this shared folder type and try again.
test_key: |-
test value
triggers_run_fail: |-
Trigger run failed
triggers_guest_not_running: |-
@ -1489,6 +1491,24 @@ en:
'%{provider}', but this provider doesn't support this action. This
is probably a bug in either the provider or the plugin calling this
action, and should be reported.
upload_invalid_compression_type: |-
The compression type requested for upload (`%{type}`) is not a
supported value. Try uploading again using a valid compression
type.
Supported types: %{valid_types}
upload_missing_extract_capability: |-
The guest does not provide extraction capability for the requested
compression type (`%{type}`). Try a different compression type or
upload without compression.
upload_missing_temp_capability: |-
The guest does not provide temporary path capabilities. Please
try the upload again without requesting a temporary path.
upload_source_missing: |-
The source path provided for upload cannot be found. Please validate
the source location for upload an try again.
Source Path: %{source}
vagrantfile_exists: |-
`Vagrantfile` already exists in this directory. Remove it before
running `vagrant init`.
@ -1685,7 +1705,9 @@ en:
vm_not_running: |-
VM must be running to open SSH connection. Run `vagrant up`
to start the virtual machine.
test_key: "test value"
winrm_invalid_communicator: |-
The winrm command requires a WinRM communicator to be used when connecting
to the guest. Please update your configuration and try the command again.
wsl_vagrant_version_mismatch: |-
Vagrant cannot currently enable access to manage machines within the Windows
environment because the version of Vagrant installed on Windows does not
@ -2025,6 +2047,18 @@ en:
up:
upping: |-
Bringing machine '%{name}' up with '%{provider}' provider...
upload:
compress: |-
Compressing %{source} to %{type} for upload...
complete: |-
Upload has completed successfully!
Source: %{source}
Destination: %{destination}
decompress: |-
Decompressing %{type} upload to %{destination}...
start: |-
Uploading %{source} to %{destination}
validate:
success: |-
Vagrantfile validated successfully.

View File

@ -0,0 +1,242 @@
require File.expand_path("../../../../base", __FILE__)
require Vagrant.source_root.join("plugins/commands/upload/command")
describe VagrantPlugins::CommandUpload::Command do
include_context "unit"
include_context "virtualbox"
let(:iso_env) do
# We have to create a Vagrantfile so there is a root path
env = isolated_environment
env.vagrantfile("")
env.create_vagrant_env
end
let(:guest) { double("guest", capability_host_chain: guest_chain) }
let(:host) { double("host", capability_host_chain: host_chain) }
let(:machine) { iso_env.machine(iso_env.machine_names[0], :dummy) }
let(:communicator) { double("communicator") }
let(:host_chain){ [[]] }
let(:guest_chain){ [[]] }
let(:argv) { [] }
let(:config) {
double("config")
}
subject { described_class.new(argv, iso_env) }
before do
allow(machine).to receive(:communicate).and_return(communicator)
allow(machine).to receive(:config).and_return(config)
allow(subject).to receive(:with_target_vms)
end
it "should raise invalid usage error by default" do
expect { subject.execute }.to raise_error(Vagrant::Errors::CLIInvalidUsage)
end
context "when three arguments are provided" do
let(:argv) { ["source", "destination", "guest"] }
before { allow(File).to receive(:file?).and_return(true) }
it "should use third argument as name of guest" do
expect(subject).to receive(:with_target_vms).with("guest", any_args)
subject.execute
end
it "should use first argument as source and second as destination" do
allow(subject).to receive(:with_target_vms) { |&block| block.call machine }
expect(communicator).to receive(:upload).with("source", "destination")
subject.execute
end
end
context "when two arguments are provided" do
let(:argv) { ["source", "ambiguous"] }
let(:active_machines) { [] }
before do
allow(File).to receive(:file?).and_return(true)
allow(iso_env).to receive(:active_machines).and_return(active_machines)
end
it "should use the the second argument as destination when not a machine name" do
allow(subject).to receive(:with_target_vms) { |&block| block.call machine }
expect(communicator).to receive(:upload).with("source", "ambiguous")
subject.execute
end
context "when active machine matches second argument" do
let(:active_machines) { [["ambiguous"]] }
it "should use second argument as guest name and generate destination" do
allow(subject).to receive(:with_target_vms).with("ambiguous", any_args) { |&block| block.call machine }
expect(communicator).to receive(:upload).with("source", "source")
subject.execute
end
end
end
context "when single argument is provided" do
let(:argv) { ["item"] }
before do
allow(File).to receive(:file?)
allow(File).to receive(:directory?)
end
it "should check if source is a file" do
expect(File).to receive(:file?).with("item").and_return(true)
subject.execute
end
it "should check if source is a directory" do
expect(File).to receive(:directory?).with("item").and_return(true)
subject.execute
end
it "should raise error if source is not a directory or file" do
expect { subject.execute }.to raise_error(Vagrant::Errors::UploadSourceMissing)
end
context "when source path ends with double quote" do
let(:argv) { [".\\item\""] }
it "should remove trailing quote" do
expect(File).to receive(:file?).with(".\\item").and_return(true)
subject.execute
end
end
context "when source path ends with single quote" do
let(:argv) { ['.\item\''] }
it "should remove trailing quote" do
expect(File).to receive(:file?).with(".\\item").and_return(true)
subject.execute
end
end
context "when source is a directory" do
before do
allow(File).to receive(:file?).with("item").and_return(false)
allow(File).to receive(:directory?).with("item").and_return(true)
allow(communicator).to receive(:upload)
allow(subject).to receive(:with_target_vms) { |&block| block.call machine }
end
it "should upload the directory" do
expect(communicator).to receive(:upload).with(/item/, anything)
subject.execute
end
it "should append separator and dot to source path for upload" do
expect(communicator).to receive(:upload).with("item/.", anything)
subject.execute
end
end
context "when source is a file" do
before do
allow(File).to receive(:file?).with("item").and_return(true)
allow(communicator).to receive(:upload)
allow(subject).to receive(:with_target_vms) { |&block| block.call machine }
allow(machine).to receive(:guest).and_return(guest)
allow(machine).to receive(:env).and_return(double("env", host: host))
allow(guest).to receive(:capability?).and_return(true)
allow(guest).to receive(:capability)
end
it "should upload the file" do
expect(communicator).to receive(:upload).with("item", anything)
subject.execute
end
it "should name destination after the source" do
expect(communicator).to receive(:upload).with("item", "item")
subject.execute
end
context "when temporary option is set" do
before { argv << "-t" }
it "should get temporary path for destination from guest" do
expect(guest).to receive(:capability).with(:create_tmp_path, any_args).and_return("TMP_PATH")
expect(communicator).to receive(:upload).with("item", "TMP_PATH")
subject.execute
end
end
context "when compress option is set" do
before do
argv << "-c"
allow(guest).to receive(:capability).with(:create_tmp_path, any_args).and_return("TMP")
allow(subject).to receive(:compress_source_zip).and_return("COMPRESS_SOURCE")
allow(subject).to receive(:compress_source_tgz).and_return("COMPRESS_SOURCE")
allow(FileUtils).to receive(:rm).with("COMPRESS_SOURCE")
end
it "should check for guest decompression" do
expect(guest).to receive(:capability?).with(:decompress_tgz).and_return(true)
subject.execute
end
it "should compress the source" do
expect(subject).to receive(:compress_source_tgz).with("item").and_return("COMPRESS_SOURCE")
subject.execute
end
it "should cleanup compressed source" do
expect(FileUtils).to receive(:rm).with("COMPRESS_SOURCE")
subject.execute
end
it "should upload the compressed source" do
expect(communicator).to receive(:upload).with("COMPRESS_SOURCE", anything)
subject.execute
end
it "should upload compressed source to temporary location" do
expect(communicator).to receive(:upload).with("COMPRESS_SOURCE", "TMP")
subject.execute
end
it "should have guest decompress file" do
expect(guest).to receive(:capability).with(:decompress_tgz, "TMP", any_args)
subject.execute
end
it "should provide destination for guest decompression of file" do
expect(guest).to receive(:capability).with(:decompress_tgz, "TMP", "item", any_args)
subject.execute
end
it "should provide the destination type for guest decompression" do
expect(guest).to receive(:capability).with(:decompress_tgz, "TMP", "item", hash_including(type: :file))
subject.execute
end
context "with compression type set to zip" do
before { argv << "-C" << "zip" }
it "should test guest for decompression capability" do
expect(guest).to receive(:capability?).with(:decompress_zip).and_return(true)
subject.execute
end
it "should compress source using zip" do
expect(subject).to receive(:compress_source_zip)
subject.execute
end
it "should have guest decompress file using zip" do
expect(guest).to receive(:capability).with(:decompress_zip, any_args)
subject.execute
end
end
end
end
end
end

View File

@ -0,0 +1,95 @@
require File.expand_path("../../../../base", __FILE__)
require Vagrant.source_root.join("plugins/commands/winrm/command")
describe VagrantPlugins::CommandWinRM::Command do
include_context "unit"
include_context "virtualbox"
let(:iso_env) do
# We have to create a Vagrantfile so there is a root path
env = isolated_environment
env.vagrantfile("")
env.create_vagrant_env
end
let(:guest) { double("guest") }
let(:host) { double("host") }
let(:machine) { iso_env.machine(iso_env.machine_names[0], :dummy) }
let(:communicator) { double("communicator") }
let(:argv) { [] }
let(:config) {
double("config",
vm: double("vm-config", communicator: communicator_name))
}
let(:communicator_name) { :winrm }
subject { described_class.new(argv, iso_env) }
before do
allow(machine).to receive(:communicate).and_return(communicator)
allow(machine).to receive(:config).and_return(config)
allow(subject).to receive(:with_target_vms) { |&block| block.call machine }
allow(communicator).to receive(:execute)
end
it "should exit successfully when no command is provided" do
expect(subject.execute).to eq(0)
end
context "with command provided" do
let(:argv){ ["-c", "dir"] }
it "should execute the command via the communicator" do
expect(communicator).to receive(:execute).with("dir", any_args)
subject.execute
end
it "should execute with default shell" do
expect(communicator).to receive(:execute).with(anything, hash_including(shell: :powershell))
subject.execute
end
it "should execute without elevated privileges" do
expect(communicator).to receive(:execute).with(anything, hash_including(elevated: false))
subject.execute
end
context "with elevated option set" do
let(:argv) { ["-c", "dir", "-e"] }
it "should execute with elevated privileges" do
expect(communicator).to receive(:execute).with(anything, hash_including(elevated: true))
subject.execute
end
end
context "with shell option set" do
let(:argv) { ["-c", "dir", "-s", "cmd"] }
it "should execute with custom shell" do
expect(communicator).to receive(:execute).with(anything, hash_including(shell: :cmd))
subject.execute
end
end
end
context "with multiple command provided" do
let(:argv) { ["-c", "dir", "-c", "dir2"] }
it "should execute multiple commands via the communicator" do
expect(communicator).to receive(:execute).with("dir", any_args)
expect(communicator).to receive(:execute).with("dir2", any_args)
subject.execute
end
end
context "with invalid communicator configured" do
let(:communicator_name) { :ssh }
it "should raise an error" do
expect { subject.execute }.to raise_error(Vagrant::Errors::WinRMInvalidCommunicator)
end
end
end

View File

@ -0,0 +1,143 @@
require File.expand_path("../../../../base", __FILE__)
require Vagrant.source_root.join("plugins/commands/winrm_config/command")
require Vagrant.source_root.join("plugins/communicators/winrm/helper")
describe VagrantPlugins::CommandWinRMConfig::Command do
include_context "unit"
include_context "virtualbox"
let(:iso_env) do
# We have to create a Vagrantfile so there is a root path
env = isolated_environment
env.vagrantfile("")
env.create_vagrant_env
end
let(:guest) { double("guest") }
let(:host) { double("host") }
let(:machine) { iso_env.machine(iso_env.machine_names[0], :dummy) }
let(:argv) { [] }
let(:winrm_info) {{
host: "testhost.vagrant.dev",
port: 1234
}}
let(:config) {
double("config",
winrm: double("winrm-config", username: "vagrant", password: "vagrant"),
rdp: rdp_config,
vm: double("vm-config", communicator: :winrm)
)
}
let(:rdp_config) { double("rdp-config", port: 9876) }
subject { described_class.new(argv, iso_env) }
before do
allow(machine).to receive(:config).and_return(config)
allow(VagrantPlugins::CommunicatorWinRM::Helper).to receive(:winrm_info).and_return(winrm_info)
allow(subject).to receive(:with_target_vms) { |&block| block.call machine }
end
describe "execute" do
it "prints out the winrm config for the given machine" do
output = ""
allow(subject).to receive(:safe_puts) do |data|
output += data if data
end
subject.execute
expect(output).to eq(<<-WINRMCONFIG)
Host #{machine.name}
HostName testhost.vagrant.dev
User vagrant
Password vagrant
Port 1234
RDPHostName testhost.vagrant.dev
RDPPort 9876
RDPUser vagrant
RDPPassword vagrant
WINRMCONFIG
end
context "with host option set" do
let(:argv) { ["--host", "my-host"]}
it "should use custom host name in config output" do
output = ""
allow(subject).to receive(:safe_puts) do |data|
output += data if data
end
subject.execute
expect(output).to eq(<<-WINRMCONFIG)
Host my-host
HostName testhost.vagrant.dev
User vagrant
Password vagrant
Port 1234
RDPHostName testhost.vagrant.dev
RDPPort 9876
RDPUser vagrant
RDPPassword vagrant
WINRMCONFIG
end
end
context "when no RDP port is configured" do
let(:rdp_config) { double("rdp-config", port: nil) }
it "should not include any RDP configuration information" do
output = ""
allow(subject).to receive(:safe_puts) do |data|
output += data if data
end
subject.execute
expect(output).not_to include("RDP")
end
end
context "when provider has rdp_info capability" do
let(:rdp_info) {
{host: "provider-host", port: 9999, username: "pvagrant", password: "pvagrant"}
}
before do
allow(machine.provider).to receive(:capability?).with(:rdp_info).and_return(true)
allow(machine.provider).to receive(:capability).with(:rdp_info).and_return(rdp_info)
end
it "should use provider RDP information" do
output = ""
allow(subject).to receive(:safe_puts) do |data|
output += data if data
end
subject.execute
expect(output).to include("RDPPort 9999")
expect(output).to include("RDPHostName provider-host")
expect(output).to include("RDPUser pvagrant")
expect(output).to include("RDPPassword pvagrant")
end
context "when provider rdp_info does not include host" do
before { rdp_info[:host] = nil }
it "should use winrm host" do
output = ""
allow(subject).to receive(:safe_puts) do |data|
output += data if data
end
subject.execute
expect(output).to include("RDPHostName testhost.vagrant.dev")
end
end
end
end
end

View File

@ -0,0 +1,127 @@
require_relative "../../../../base"
describe "VagrantPlugins::GuestBSD::Cap::FileSystem" do
let(:caps) do
VagrantPlugins::GuestBSD::Plugin
.components
.guest_capabilities[:bsd]
end
let(:machine) { double("machine", communicate: comm) }
let(:comm) { double("comm") }
before { allow(comm).to receive(:execute) }
describe ".create_tmp_path" do
let(:cap) { caps.get(:create_tmp_path) }
let(:opts) { {} }
it "should generate path on guest" do
expect(comm).to receive(:execute).with(/mktemp/)
cap.create_tmp_path(machine, opts)
end
it "should capture path generated on guest" do
expect(comm).to receive(:execute).with(/mktemp/).and_yield(:stdout, "TMP_PATH")
expect(cap.create_tmp_path(machine, opts)).to eq("TMP_PATH")
end
it "should strip newlines on path" do
expect(comm).to receive(:execute).with(/mktemp/).and_yield(:stdout, "TMP_PATH\n")
expect(cap.create_tmp_path(machine, opts)).to eq("TMP_PATH")
end
context "when type is a directory" do
before { opts[:type] = :directory }
it "should create guest path as a directory" do
expect(comm).to receive(:execute).with(/-d/)
cap.create_tmp_path(machine, opts)
end
end
end
describe ".decompress_tgz" do
let(:cap) { caps.get(:decompress_tgz) }
let(:comp) { "compressed_file" }
let(:dest) { "path/to/destination" }
let(:opts) { {} }
before { allow(cap).to receive(:create_tmp_path).and_return("TMP_DIR") }
after{ cap.decompress_tgz(machine, comp, dest, opts) }
it "should create temporary directory for extraction" do
expect(cap).to receive(:create_tmp_path)
end
it "should extract file with tar" do
expect(comm).to receive(:execute).with(/tar/)
end
it "should extract file to temporary directory" do
expect(comm).to receive(:execute).with(/TMP_DIR/)
end
it "should remove compressed file from guest" do
expect(comm).to receive(:execute).with(/rm .*#{comp}/)
end
it "should remove extraction directory from guest" do
expect(comm).to receive(:execute).with(/rm .*TMP_DIR/)
end
it "should create parent directories for destination" do
expect(comm).to receive(:execute).with(/mkdir -p .*to'/)
end
context "when type is directory" do
before { opts[:type] = :directory }
it "should create destination directory" do
expect(comm).to receive(:execute).with(/mkdir -p .*destination'/)
end
end
end
describe ".decompress_zip" do
let(:cap) { caps.get(:decompress_zip) }
let(:comp) { "compressed_file" }
let(:dest) { "path/to/destination" }
let(:opts) { {} }
before { allow(cap).to receive(:create_tmp_path).and_return("TMP_DIR") }
after{ cap.decompress_zip(machine, comp, dest, opts) }
it "should create temporary directory for extraction" do
expect(cap).to receive(:create_tmp_path)
end
it "should extract file with zip" do
expect(comm).to receive(:execute).with(/zip/)
end
it "should extract file to temporary directory" do
expect(comm).to receive(:execute).with(/TMP_DIR/)
end
it "should remove compressed file from guest" do
expect(comm).to receive(:execute).with(/rm .*#{comp}/)
end
it "should remove extraction directory from guest" do
expect(comm).to receive(:execute).with(/rm .*TMP_DIR/)
end
it "should create parent directories for destination" do
expect(comm).to receive(:execute).with(/mkdir -p .*to'/)
end
context "when type is directory" do
before { opts[:type] = :directory }
it "should create destination directory" do
expect(comm).to receive(:execute).with(/mkdir -p .*destination'/)
end
end
end
end

View File

@ -0,0 +1,127 @@
require_relative "../../../../base"
describe "VagrantPlugins::GuestLinux::Cap::FileSystem" do
let(:caps) do
VagrantPlugins::GuestLinux::Plugin
.components
.guest_capabilities[:linux]
end
let(:machine) { double("machine", communicate: comm) }
let(:comm) { double("comm") }
before { allow(comm).to receive(:execute) }
describe ".create_tmp_path" do
let(:cap) { caps.get(:create_tmp_path) }
let(:opts) { {} }
it "should generate path on guest" do
expect(comm).to receive(:execute).with(/mktemp/)
cap.create_tmp_path(machine, opts)
end
it "should capture path generated on guest" do
expect(comm).to receive(:execute).with(/mktemp/).and_yield(:stdout, "TMP_PATH")
expect(cap.create_tmp_path(machine, opts)).to eq("TMP_PATH")
end
it "should strip newlines on path" do
expect(comm).to receive(:execute).with(/mktemp/).and_yield(:stdout, "TMP_PATH\n")
expect(cap.create_tmp_path(machine, opts)).to eq("TMP_PATH")
end
context "when type is a directory" do
before { opts[:type] = :directory }
it "should create guest path as a directory" do
expect(comm).to receive(:execute).with(/-d/)
cap.create_tmp_path(machine, opts)
end
end
end
describe ".decompress_tgz" do
let(:cap) { caps.get(:decompress_tgz) }
let(:comp) { "compressed_file" }
let(:dest) { "path/to/destination" }
let(:opts) { {} }
before { allow(cap).to receive(:create_tmp_path).and_return("TMP_DIR") }
after{ cap.decompress_tgz(machine, comp, dest, opts) }
it "should create temporary directory for extraction" do
expect(cap).to receive(:create_tmp_path)
end
it "should extract file with tar" do
expect(comm).to receive(:execute).with(/tar/)
end
it "should extract file to temporary directory" do
expect(comm).to receive(:execute).with(/TMP_DIR/)
end
it "should remove compressed file from guest" do
expect(comm).to receive(:execute).with(/rm .*#{comp}/)
end
it "should remove extraction directory from guest" do
expect(comm).to receive(:execute).with(/rm .*TMP_DIR/)
end
it "should create parent directories for destination" do
expect(comm).to receive(:execute).with(/mkdir -p .*to'/)
end
context "when type is directory" do
before { opts[:type] = :directory }
it "should create destination directory" do
expect(comm).to receive(:execute).with(/mkdir -p .*destination'/)
end
end
end
describe ".decompress_zip" do
let(:cap) { caps.get(:decompress_zip) }
let(:comp) { "compressed_file" }
let(:dest) { "path/to/destination" }
let(:opts) { {} }
before { allow(cap).to receive(:create_tmp_path).and_return("TMP_DIR") }
after{ cap.decompress_zip(machine, comp, dest, opts) }
it "should create temporary directory for extraction" do
expect(cap).to receive(:create_tmp_path)
end
it "should extract file with zip" do
expect(comm).to receive(:execute).with(/zip/)
end
it "should extract file to temporary directory" do
expect(comm).to receive(:execute).with(/TMP_DIR/)
end
it "should remove compressed file from guest" do
expect(comm).to receive(:execute).with(/rm .*#{comp}/)
end
it "should remove extraction directory from guest" do
expect(comm).to receive(:execute).with(/rm .*TMP_DIR/)
end
it "should create parent directories for destination" do
expect(comm).to receive(:execute).with(/mkdir -p .*to'/)
end
context "when type is directory" do
before { opts[:type] = :directory }
it "should create destination directory" do
expect(comm).to receive(:execute).with(/mkdir -p .*destination'/)
end
end
end
end

View File

@ -0,0 +1,127 @@
require_relative "../../../../base"
describe "VagrantPlugins::GuestSolaris::Cap::FileSystem" do
let(:caps) do
VagrantPlugins::GuestSolaris::Plugin
.components
.guest_capabilities[:solaris]
end
let(:machine) { double("machine", communicate: comm) }
let(:comm) { double("comm") }
before { allow(comm).to receive(:execute) }
describe ".create_tmp_path" do
let(:cap) { caps.get(:create_tmp_path) }
let(:opts) { {} }
it "should generate path on guest" do
expect(comm).to receive(:execute).with(/mktemp/)
cap.create_tmp_path(machine, opts)
end
it "should capture path generated on guest" do
expect(comm).to receive(:execute).with(/mktemp/).and_yield(:stdout, "TMP_PATH")
expect(cap.create_tmp_path(machine, opts)).to eq("TMP_PATH")
end
it "should strip newlines on path" do
expect(comm).to receive(:execute).with(/mktemp/).and_yield(:stdout, "TMP_PATH\n")
expect(cap.create_tmp_path(machine, opts)).to eq("TMP_PATH")
end
context "when type is a directory" do
before { opts[:type] = :directory }
it "should create guest path as a directory" do
expect(comm).to receive(:execute).with(/-d/)
cap.create_tmp_path(machine, opts)
end
end
end
describe ".decompress_tgz" do
let(:cap) { caps.get(:decompress_tgz) }
let(:comp) { "compressed_file" }
let(:dest) { "path/to/destination" }
let(:opts) { {} }
before { allow(cap).to receive(:create_tmp_path).and_return("TMP_DIR") }
after{ cap.decompress_tgz(machine, comp, dest, opts) }
it "should create temporary directory for extraction" do
expect(cap).to receive(:create_tmp_path)
end
it "should extract file with tar" do
expect(comm).to receive(:execute).with(/tar/)
end
it "should extract file to temporary directory" do
expect(comm).to receive(:execute).with(/TMP_DIR/)
end
it "should remove compressed file from guest" do
expect(comm).to receive(:execute).with(/rm .*#{comp}/)
end
it "should remove extraction directory from guest" do
expect(comm).to receive(:execute).with(/rm .*TMP_DIR/)
end
it "should create parent directories for destination" do
expect(comm).to receive(:execute).with(/mkdir -p .*to'/)
end
context "when type is directory" do
before { opts[:type] = :directory }
it "should create destination directory" do
expect(comm).to receive(:execute).with(/mkdir -p .*destination'/)
end
end
end
describe ".decompress_zip" do
let(:cap) { caps.get(:decompress_zip) }
let(:comp) { "compressed_file" }
let(:dest) { "path/to/destination" }
let(:opts) { {} }
before { allow(cap).to receive(:create_tmp_path).and_return("TMP_DIR") }
after{ cap.decompress_zip(machine, comp, dest, opts) }
it "should create temporary directory for extraction" do
expect(cap).to receive(:create_tmp_path)
end
it "should extract file with zip" do
expect(comm).to receive(:execute).with(/zip/)
end
it "should extract file to temporary directory" do
expect(comm).to receive(:execute).with(/TMP_DIR/)
end
it "should remove compressed file from guest" do
expect(comm).to receive(:execute).with(/rm .*#{comp}/)
end
it "should remove extraction directory from guest" do
expect(comm).to receive(:execute).with(/rm .*TMP_DIR/)
end
it "should create parent directories for destination" do
expect(comm).to receive(:execute).with(/mkdir -p .*to'/)
end
context "when type is directory" do
before { opts[:type] = :directory }
it "should create destination directory" do
expect(comm).to receive(:execute).with(/mkdir -p .*destination'/)
end
end
end
end

View File

@ -0,0 +1,85 @@
require_relative "../../../../base"
describe "VagrantPlugins::GuestWindows::Cap::FileSystem" do
let(:caps) do
VagrantPlugins::GuestWindows::Plugin
.components
.guest_capabilities[:windows]
end
let(:machine) { double("machine", communicate: comm) }
let(:comm) { double("comm") }
before { allow(comm).to receive(:execute) }
describe ".create_tmp_path" do
let(:cap) { caps.get(:create_tmp_path) }
let(:opts) { {} }
it "should generate path on guest" do
expect(comm).to receive(:execute).with(/GetRandomFileName/, any_args)
cap.create_tmp_path(machine, opts)
end
it "should capture path generated on guest" do
expect(comm).to receive(:execute).with(/Write-Output/, any_args).and_yield(:stdout, "TMP_PATH")
expect(cap.create_tmp_path(machine, opts)).to eq("TMP_PATH")
end
it "should strip newlines on path" do
expect(comm).to receive(:execute).with(/Write-Output/, any_args).and_yield(:stdout, "TMP_PATH\r\n")
expect(cap.create_tmp_path(machine, opts)).to eq("TMP_PATH")
end
context "when type is a directory" do
before { opts[:type] = :directory }
it "should create guest path as a directory" do
expect(comm).to receive(:execute).with(/CreateDirectory/, any_args)
cap.create_tmp_path(machine, opts)
end
end
end
describe ".decompress_zip" do
let(:cap) { caps.get(:decompress_zip) }
let(:comp) { "compressed_file" }
let(:dest) { "path/to/destination" }
let(:opts) { {} }
before { allow(cap).to receive(:create_tmp_path).and_return("TMP_DIR") }
after{ cap.decompress_zip(machine, comp, dest, opts) }
it "should create temporary directory for extraction" do
expect(cap).to receive(:create_tmp_path)
end
it "should extract file with zip" do
expect(comm).to receive(:execute).with(/copyhere/, any_args)
end
it "should extract file to temporary directory" do
expect(comm).to receive(:execute).with(/TMP_DIR/, any_args)
end
it "should remove compressed file from guest" do
expect(comm).to receive(:execute).with(/Remove-Item .*#{comp}/, any_args)
end
it "should remove extraction directory from guest" do
expect(comm).to receive(:execute).with(/Remove-Item .*TMP_DIR/, any_args)
end
it "should create parent directories for destination" do
expect(comm).to receive(:execute).with(/New-Item .*Directory .*to\\"/, any_args)
end
context "when type is directory" do
before { opts[:type] = :directory }
it "should create destination directory" do
expect(comm).to receive(:execute).with(/New-Item .*Directory .*destination"/, any_args)
end
end
end
end

View File

@ -27,6 +27,7 @@ Gem::Specification.new do |s|
s.add_dependency "net-scp", "~> 1.2.0"
s.add_dependency "rb-kqueue", "~> 0.2.0"
s.add_dependency "rest-client", ">= 1.6.0", "< 3.0"
s.add_dependency "rubyzip", "~> 1.2.2"
s.add_dependency "wdm", "~> 0.1.0"
s.add_dependency "winrm", "~> 2.1"
s.add_dependency "winrm-fs", "~> 1.0"

View File

@ -0,0 +1,30 @@
---
layout: "docs"
page_title: "vagrant upload - Command-Line Interface"
sidebar_current: "cli-upload"
description: |-
The "vagrant upload" command is used to upload files from the host
to a guest machine.
---
# Upload
**Command: `vagrant upload source [destination] [name|id]`**
This command uploads files and directories from the host to the guest
machine.
## Options
* `destination` - Path on the guest machine to upload file or directory.
* `source` - Path to file or diretory on host to upload to guest machine.
* `--compress` - Compress the file or directory before uploading to guest machine.
* `--compression-type type` - Type of compression to use when compressing
file or directory for upload. Defaults to `zip` for Windows guests and
`tgz` for non-Windows guests. Valid values: `tgz`, `zip`.
* `--temporary` - Create a temporary location on the guest machine and upload
files to that location.

View File

@ -0,0 +1,26 @@
---
layout: "docs"
page_title: "vagrant winrm - Command-Line Interface"
sidebar_current: "cli-winrm"
description: |-
The "vagrant winrm" command is used execute commands on the remote
machine via WinRM
---
# WinRM
**Command: `vagrant winrm [name|id]`**
Executes the provided command(s) on the guest machine using the
WinRM communicator. Commands are provided with the `--command`
option and multiple `--command` flags may be provided for
executing multiple commands. This command requires the guest
machine to be configured with the WinRM communicator.
## Options
* `--command COMMAND` - Command to execute.
* `--elevated` - Run command(s) with elevated credentials.
* `--shell (cmd|powershell)` - Shell to execute commands. Defaults to `powershell`.

View File

@ -0,0 +1,20 @@
---
layout: "docs"
page_title: "vagrant winrm-config - Command-Line Interface"
sidebar_current: "cli-winrm_config"
description: |-
The "vagrant winrm-config" command is used to output the WinRM configuration
used to connect to the guest machine.
---
# WinRM Config
**Command: `vagrant winrm-config [name|id]`**
This will output the WinRM configuration used for connecting to
the guest machine. It requires that the WinRM communicator is in
use for the guest machine.
## Options
* `--host NAME` - Name of the host for the outputted configuration.