SMB enhancements
This commit is contained in:
parent
e85ef1655b
commit
00fa50c296
|
@ -1,3 +1,4 @@
|
||||||
|
require "tmpdir"
|
||||||
require_relative "subprocess"
|
require_relative "subprocess"
|
||||||
require_relative "which"
|
require_relative "which"
|
||||||
|
|
||||||
|
@ -25,6 +26,10 @@ module Vagrant
|
||||||
# @return [Subprocess::Result]
|
# @return [Subprocess::Result]
|
||||||
def self.execute(path, *args, **opts, &block)
|
def self.execute(path, *args, **opts, &block)
|
||||||
validate_install!
|
validate_install!
|
||||||
|
|
||||||
|
if opts.delete(:sudo) || opts.delete(:runas)
|
||||||
|
powerup_command(path, args, opts)
|
||||||
|
else
|
||||||
command = [
|
command = [
|
||||||
"powershell",
|
"powershell",
|
||||||
"-NoLogo",
|
"-NoLogo",
|
||||||
|
@ -41,6 +46,7 @@ module Vagrant
|
||||||
|
|
||||||
Subprocess.execute(*command, &block)
|
Subprocess.execute(*command, &block)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Execute a powershell command.
|
# Execute a powershell command.
|
||||||
#
|
#
|
||||||
|
@ -56,7 +62,7 @@ module Vagrant
|
||||||
"-ExecutionPolicy", "Bypass",
|
"-ExecutionPolicy", "Bypass",
|
||||||
"-Command",
|
"-Command",
|
||||||
command
|
command
|
||||||
].flatten
|
].flatten.compact
|
||||||
|
|
||||||
r = Subprocess.execute(*c)
|
r = Subprocess.execute(*c)
|
||||||
return nil if r.exit_code != 0
|
return nil if r.exit_code != 0
|
||||||
|
@ -75,7 +81,7 @@ module Vagrant
|
||||||
"-NonInteractive",
|
"-NonInteractive",
|
||||||
"-ExecutionPolicy", "Bypass",
|
"-ExecutionPolicy", "Bypass",
|
||||||
"-Command",
|
"-Command",
|
||||||
"$PSVersionTable.PSVersion.Major"
|
"Write-Output $PSVersionTable.PSVersion.Major"
|
||||||
].flatten
|
].flatten
|
||||||
|
|
||||||
r = Subprocess.execute(*command)
|
r = Subprocess.execute(*command)
|
||||||
|
@ -101,6 +107,60 @@ module Vagrant
|
||||||
end
|
end
|
||||||
@_powershell_validation
|
@_powershell_validation
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Powerup the given command to perform privileged operations.
|
||||||
|
#
|
||||||
|
# @param [String] path
|
||||||
|
# @param [Array<String>] args
|
||||||
|
# @return [Array<String>]
|
||||||
|
def self.powerup_command(path, args, opts)
|
||||||
|
Dir.mktmpdir("vagrant") do |dpath|
|
||||||
|
all_args = ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", path] + args
|
||||||
|
arg_list = "@('" + all_args.join("', '") + "')"
|
||||||
|
stdout = File.join(dpath, "stdout.txt")
|
||||||
|
stderr = File.join(dpath, "stderr.txt")
|
||||||
|
exitcode = File.join(dpath, "exitcode.txt")
|
||||||
|
|
||||||
|
script = "$sp = Start-Process -FilePath powershell -ArgumentList #{arg_list} " \
|
||||||
|
"-PassThru -Wait -RedirectStandardOutput '#{stdout}' -RedirectStandardError '#{stderr}' -WindowStyle Hidden; " \
|
||||||
|
"if($sp){ Set-Content -Path '#{exitcode}' -Value $sp.ExitCode;exit $sp.ExitCode; }else{ exit 1 }"
|
||||||
|
|
||||||
|
# escape quotes so we can nest our script within a start-process
|
||||||
|
script.gsub!("'", "''")
|
||||||
|
|
||||||
|
cmd = [
|
||||||
|
"powershell",
|
||||||
|
"-NoLogo",
|
||||||
|
"-NoProfile",
|
||||||
|
"-NonInteractive",
|
||||||
|
"-ExecutionPolicy", "Bypass",
|
||||||
|
"-Command", "$p = Start-Process -FilePath powershell -ArgumentList " \
|
||||||
|
"@('-NoLogo', '-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-Command', '#{script}') " \
|
||||||
|
"-PassThru -Wait -WindowStyle Hidden -Verb RunAs; if($p){ exit $p.ExitCode; }else{ exit 1 }"
|
||||||
|
]
|
||||||
|
|
||||||
|
result = Subprocess.execute(*cmd.push(opts))
|
||||||
|
if File.exist?(stdout)
|
||||||
|
r_stdout = File.read(stdout)
|
||||||
|
else
|
||||||
|
r_stdout = result.stdout
|
||||||
|
end
|
||||||
|
if File.exist?(stderr)
|
||||||
|
r_stderr = File.read(stderr)
|
||||||
|
else
|
||||||
|
r_stderr = result.stderr
|
||||||
|
end
|
||||||
|
|
||||||
|
code = 1
|
||||||
|
if File.exist?(exitcode)
|
||||||
|
code_txt = File.read(exitcode).strip
|
||||||
|
if code_txt.match(/^\d+$/)
|
||||||
|
code = code_txt.to_i
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Subprocess::Result.new(code, r_stdout, r_stderr)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,7 +24,11 @@ module VagrantPlugins
|
||||||
smb_password = options[:smb_password]
|
smb_password = options[:smb_password]
|
||||||
|
|
||||||
options[:mount_options] ||= []
|
options[:mount_options] ||= []
|
||||||
|
if machine.env.host.capability?(:smb_mount_options)
|
||||||
|
options[:mount_options] += machine.env.host.capability(:smb_mount_options)
|
||||||
|
else
|
||||||
options[:mount_options] << "sec=ntlm"
|
options[:mount_options] << "sec=ntlm"
|
||||||
|
end
|
||||||
options[:mount_options] << "credentials=/etc/smb_creds_#{name}"
|
options[:mount_options] << "credentials=/etc/smb_creds_#{name}"
|
||||||
|
|
||||||
mount_options = "-o uid=#{mount_uid},gid=#{mount_gid}"
|
mount_options = "-o uid=#{mount_uid},gid=#{mount_gid}"
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
require "socket"
|
||||||
|
|
||||||
|
module VagrantPlugins
|
||||||
|
module HostDarwin
|
||||||
|
module Cap
|
||||||
|
class ConfiguredIPAddresses
|
||||||
|
|
||||||
|
def self.configured_ip_addresses(env)
|
||||||
|
Socket.getifaddrs.map do |interface|
|
||||||
|
if interface.addr.ipv4? && !interface.addr.ipv4_loopback?
|
||||||
|
interface.addr.ip_address
|
||||||
|
end
|
||||||
|
end.compact
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,86 @@
|
||||||
|
module VagrantPlugins
|
||||||
|
module HostDarwin
|
||||||
|
module Cap
|
||||||
|
class SMB
|
||||||
|
|
||||||
|
@@logger = Log4r::Logger.new("vagrant::host::darwin::smb")
|
||||||
|
|
||||||
|
# If we have the sharing binary available, smb is installed
|
||||||
|
def self.smb_installed(env)
|
||||||
|
File.exist?("/usr/sbin/sharing")
|
||||||
|
end
|
||||||
|
|
||||||
|
# Required options for mounting a share hosted
|
||||||
|
# on macos.
|
||||||
|
def self.smb_mount_options(env)
|
||||||
|
["ver=3", "sec=ntlmssp", "nounix", "noperm"]
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.smb_cleanup(env, machine, opts)
|
||||||
|
m_id = machine_id(machine)
|
||||||
|
result = Vagrant::Util::Subprocess.execute("/bin/sh", "-c",
|
||||||
|
"/usr/sbin/sharing -l | grep -E \"^name:.+\\svgt-#{m_id}-\" | awk '{print $2}'")
|
||||||
|
if result.exit_code != 0
|
||||||
|
@@logger.warn("failed to locate any shares for cleanup")
|
||||||
|
end
|
||||||
|
shares = result.stdout.split(/\s/).map(&:strip)
|
||||||
|
@@logger.debug("shares to be removed: #{shares}")
|
||||||
|
shares.each do |share_name|
|
||||||
|
@@logger.info("removing share name=#{share_name}")
|
||||||
|
share_name.strip!
|
||||||
|
result = Vagrant::Util::Subprocess.execute("/usr/bin/sudo",
|
||||||
|
"/usr/sbin/sharing", "-r", share_name)
|
||||||
|
if result.exit_code != 0
|
||||||
|
# Removing always returns 0 even if there are currently
|
||||||
|
# guests attached so if we get a non-zero value just
|
||||||
|
# log it as unexpected
|
||||||
|
@@logger.warn("removing share `#{share_name}` returned non-zero")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.smb_prepare(env, machine, folders, opts)
|
||||||
|
folders.each do |id, data|
|
||||||
|
hostpath = data[:hostpath]
|
||||||
|
|
||||||
|
chksum_id = Digest::MD5.hexdigest(id)
|
||||||
|
name = "vgt-#{machine_id(machine)}-#{chksum_id}"
|
||||||
|
data[:smb_id] ||= name
|
||||||
|
|
||||||
|
@@logger.info("creating new share name=#{name} id=#{data[:smb_id]}")
|
||||||
|
|
||||||
|
cmd = [
|
||||||
|
"/usr/bin/sudo",
|
||||||
|
"/usr/sbin/sharing",
|
||||||
|
"-a", hostpath,
|
||||||
|
"-S", data[:smb_id],
|
||||||
|
"-s", "001",
|
||||||
|
"-g", "000",
|
||||||
|
"-n", name
|
||||||
|
]
|
||||||
|
|
||||||
|
r = Vagrant::Util::Subprocess.execute(*cmd)
|
||||||
|
|
||||||
|
if r.exit_code != 0
|
||||||
|
raise Errors::DefineShareFailed,
|
||||||
|
host: hostpath.to_s,
|
||||||
|
stderr: r.stderr,
|
||||||
|
stdout: r.stdout
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Generates a unique identifier for the given machine
|
||||||
|
# based on the name, provider name, and working directory
|
||||||
|
# of the environment.
|
||||||
|
#
|
||||||
|
# @param [Vagrant::Machine] machine
|
||||||
|
# @return [String]
|
||||||
|
def self.machine_id(machine)
|
||||||
|
@@logger.debug("generating machine ID name=#{machine.name} cwd=#{machine.env.cwd}")
|
||||||
|
Digest::MD5.hexdigest("#{machine.name}-#{machine.provider_name}-#{machine.env.cwd}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -20,6 +20,31 @@ module VagrantPlugins
|
||||||
require_relative "cap/rdp"
|
require_relative "cap/rdp"
|
||||||
Cap::RDP
|
Cap::RDP
|
||||||
end
|
end
|
||||||
|
|
||||||
|
host_capability("darwin", "smb_installed") do
|
||||||
|
require_relative "cap/smb"
|
||||||
|
Cap::SMB
|
||||||
|
end
|
||||||
|
|
||||||
|
host_capability("darwin", "smb_prepare") do
|
||||||
|
require_relative "cap/smb"
|
||||||
|
Cap::SMB
|
||||||
|
end
|
||||||
|
|
||||||
|
host_capability("darwin", "smb_mount_options") do
|
||||||
|
require_relative "cap/smb"
|
||||||
|
Cap::SMB
|
||||||
|
end
|
||||||
|
|
||||||
|
host_capability("darwin", "smb_cleanup") do
|
||||||
|
require_relative "cap/smb"
|
||||||
|
Cap::SMB
|
||||||
|
end
|
||||||
|
|
||||||
|
host_capability("darwin", "configured_ip_addresses") do
|
||||||
|
require_relative "cap/configured_ip_addresses"
|
||||||
|
Cap::ConfiguredIPAddresses
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
require "pathname"
|
||||||
|
require "tempfile"
|
||||||
|
|
||||||
|
require "vagrant/util/downloader"
|
||||||
|
require "vagrant/util/file_checksum"
|
||||||
|
require "vagrant/util/powershell"
|
||||||
|
require "vagrant/util/subprocess"
|
||||||
|
|
||||||
|
module VagrantPlugins
|
||||||
|
module HostWindows
|
||||||
|
module Cap
|
||||||
|
class ConfiguredIPAddresses
|
||||||
|
|
||||||
|
def self.configured_ip_addresses(env)
|
||||||
|
script_path = File.expand_path("../../scripts/host_info.ps1", __FILE__)
|
||||||
|
r = Vagrant::Util::PowerShell.execute(script_path)
|
||||||
|
if r.exit_code != 0
|
||||||
|
raise Errors::PowershellError,
|
||||||
|
script: script_path,
|
||||||
|
stderr: r.stderr
|
||||||
|
end
|
||||||
|
|
||||||
|
res = JSON.parse(r.stdout)["ip_addresses"]
|
||||||
|
Array(res)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,102 @@
|
||||||
|
module VagrantPlugins
|
||||||
|
module HostWindows
|
||||||
|
module Cap
|
||||||
|
class SMB
|
||||||
|
|
||||||
|
# Number of seconds to display UAC warning to user
|
||||||
|
UAC_PROMPT_WAIT = 4
|
||||||
|
|
||||||
|
@@logger = Log4r::Logger.new("vagrant::host::windows::smb")
|
||||||
|
|
||||||
|
def self.smb_installed(env)
|
||||||
|
psv = Vagrant::Util::PowerShell.version.to_i
|
||||||
|
if psv < 3
|
||||||
|
if raise_error
|
||||||
|
raise SyncedFolderSMB::Errors::PowershellVersion,
|
||||||
|
version: psv.to_s
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.smb_cleanup(env, machine, opts)
|
||||||
|
script_path = File.expand_path("../../scripts/unset_share.ps1", __FILE__)
|
||||||
|
|
||||||
|
m_id = machine_id(machine)
|
||||||
|
result = Vagrant::Util::PowerShell.execute_cmd("net share")
|
||||||
|
if result.nil?
|
||||||
|
@@logger.warn("failed to get current share list")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
prune_shares = result.split("\n").map do |line|
|
||||||
|
sections = line.split(/\s/)
|
||||||
|
if sections.first.to_s.start_with?("vgt-#{m_id}")
|
||||||
|
sections.first
|
||||||
|
end
|
||||||
|
end.compact
|
||||||
|
@@logger.debug("shares to be removed: #{prune_shares}")
|
||||||
|
|
||||||
|
if prune_shares.size > 0
|
||||||
|
machine.env.ui.warn("\n" + I18n.t("vagrant_sf_smb.uac.prune_warning") + "\n")
|
||||||
|
sleep UAC_PROMPT_WAIT
|
||||||
|
@@logger.info("remove shares: #{prune_shares}")
|
||||||
|
result = Vagrant::Util::PowerShell.execute(script_path, *prune_shares, sudo: true)
|
||||||
|
if result.exit_code != 0
|
||||||
|
failed_name = result.stdout.to_s.sub("share name: ", "")
|
||||||
|
raise SyncedFolderSMB::Errors::PruneShareFailed,
|
||||||
|
name: failed_name,
|
||||||
|
stderr: result.stderr,
|
||||||
|
stdout: result.stdout
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.smb_prepare(env, machine, folders, opts)
|
||||||
|
script_path = File.expand_path("../../scripts/set_share.ps1", __FILE__)
|
||||||
|
|
||||||
|
shares = []
|
||||||
|
folders.each do |id, data|
|
||||||
|
hostpath = data[:hostpath]
|
||||||
|
|
||||||
|
chksum_id = Digest::MD5.hexdigest(id)
|
||||||
|
name = "vgt-#{machine_id(machine)}-#{chksum_id}"
|
||||||
|
data[:smb_id] ||= name
|
||||||
|
|
||||||
|
@@logger.info("creating new share name=#{name} id=#{data[:smb_id]}")
|
||||||
|
|
||||||
|
shares << [
|
||||||
|
"\"#{hostpath.gsub("/", "\\")}\"",
|
||||||
|
name,
|
||||||
|
data[:smb_id]
|
||||||
|
]
|
||||||
|
end
|
||||||
|
if !shares.empty?
|
||||||
|
machine.env.ui.warn("\n" + I18n.t("vagrant_sf_smb.uac.create_warning") + "\n")
|
||||||
|
sleep(UAC_PROMPT_WAIT)
|
||||||
|
result = Vagrant::Util::PowerShell.execute(script_path, *shares, sudo: true)
|
||||||
|
if result.exit_code != 0
|
||||||
|
share_path = result.stdout.to_s.sub("share path: ", "")
|
||||||
|
raise SyncedFolderSMB::Errors::DefineShareFailed,
|
||||||
|
host: share_path,
|
||||||
|
stderr: result.stderr,
|
||||||
|
stdout: result.stdout
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Generates a unique identifier for the given machine
|
||||||
|
# based on the name, provider name, and working directory
|
||||||
|
# of the environment.
|
||||||
|
#
|
||||||
|
# @param [Vagrant::Machine] machine
|
||||||
|
# @return [String]
|
||||||
|
def self.machine_id(machine)
|
||||||
|
@@logger.debug("generating machine ID name=#{machine.name} cwd=#{machine.env.cwd}")
|
||||||
|
Digest::MD5.hexdigest("#{machine.name}-#{machine.provider_name}-#{machine.env.cwd}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -30,6 +30,26 @@ module VagrantPlugins
|
||||||
require_relative "cap/ps"
|
require_relative "cap/ps"
|
||||||
Cap::PS
|
Cap::PS
|
||||||
end
|
end
|
||||||
|
|
||||||
|
host_capability("windows", "smb_installed") do
|
||||||
|
require_relative "cap/smb"
|
||||||
|
Cap::SMB
|
||||||
|
end
|
||||||
|
|
||||||
|
host_capability("windows", "smb_prepare") do
|
||||||
|
require_relative "cap/smb"
|
||||||
|
Cap::SMB
|
||||||
|
end
|
||||||
|
|
||||||
|
host_capability("windows", "smb_cleanup") do
|
||||||
|
require_relative "cap/smb"
|
||||||
|
Cap::SMB
|
||||||
|
end
|
||||||
|
|
||||||
|
host_capability("windows", "configured_ip_addresses") do
|
||||||
|
require_relative "cap/configured_ip_addresses"
|
||||||
|
Cap::ConfiguredIPAddresses
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
# The names of the user are language dependent!
|
||||||
|
$objSID = New-Object System.Security.Principal.SecurityIdentifier("S-1-1-0")
|
||||||
|
$objUser = $objSID.Translate([System.Security.Principal.NTAccount])
|
||||||
|
|
||||||
|
$grant = "$objUser,Full"
|
||||||
|
|
||||||
|
# First we split the defs string by commas to get
|
||||||
|
# each group of parameters
|
||||||
|
for ($i=0; $i -le $args.length; $i = $i + 3) {
|
||||||
|
$path = $args[$i]
|
||||||
|
$share_name = $args[$i+1]
|
||||||
|
$share_id = $args[$i+2]
|
||||||
|
|
||||||
|
|
||||||
|
if ($path -eq $null) {
|
||||||
|
Write-Warning "empty path argument encountered - complete"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($share_name -eq $null) {
|
||||||
|
Write-Output "share path: ${path}"
|
||||||
|
Write-Error "error - no share name provided"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($share_id -eq $null) {
|
||||||
|
Write-Output "share path: ${path}"
|
||||||
|
Write-Error "error - no share ID provided"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = net share $share_name=$path /unlimited /GRANT:$grant /REMARK:"${share_id}"
|
||||||
|
if ($LastExitCode -ne 0) {
|
||||||
|
$host.ui.WriteLine("share path: ${path}")
|
||||||
|
$host.ui.WriteErrorLine("error ${result}")
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exit 0
|
|
@ -0,0 +1,11 @@
|
||||||
|
# Share names are comma delimited
|
||||||
|
ForEach ($share_name in $args) {
|
||||||
|
$result = net share $share_name /DELETE
|
||||||
|
if ($LastExitCode -ne 0) {
|
||||||
|
Write-Output "share name: ${share_name}"
|
||||||
|
Write-Error "error - ${result}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Write-Output "share removal completed"
|
||||||
|
exit 0
|
|
@ -10,6 +10,10 @@ module VagrantPlugins
|
||||||
error_key(:define_share_failed)
|
error_key(:define_share_failed)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class PruneShareFailed < SMBError
|
||||||
|
error_key(:prune_share_failed)
|
||||||
|
end
|
||||||
|
|
||||||
class NoHostIPAddr < SMBError
|
class NoHostIPAddr < SMBError
|
||||||
error_key(:no_routable_host_addr)
|
error_key(:no_routable_host_addr)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
Param(
|
|
||||||
[Parameter(Mandatory=$true)]
|
|
||||||
[string]$path,
|
|
||||||
[Parameter(Mandatory=$true)]
|
|
||||||
[string]$share_name,
|
|
||||||
[string]$host_share_username = $null
|
|
||||||
)
|
|
||||||
|
|
||||||
$ErrorAction = "Stop"
|
|
||||||
|
|
||||||
if (net share | Select-String $share_name) {
|
|
||||||
net share $share_name /delete /y
|
|
||||||
}
|
|
||||||
|
|
||||||
# The names of the user are language dependent!
|
|
||||||
$objSID = New-Object System.Security.Principal.SecurityIdentifier("S-1-1-0")
|
|
||||||
$objUser = $objSID.Translate([System.Security.Principal.NTAccount])
|
|
||||||
|
|
||||||
$grant = "$objUser,Full"
|
|
||||||
|
|
||||||
if (![string]::IsNullOrEmpty($host_share_username)) {
|
|
||||||
$computer_name = $(Get-WmiObject Win32_Computersystem).name
|
|
||||||
$grant = "$computer_name\$host_share_username,Full"
|
|
||||||
|
|
||||||
# Here we need to set the proper ACL for this folder. This lets full
|
|
||||||
# recursive access to this folder.
|
|
||||||
<#
|
|
||||||
Get-ChildItem $path -recurse -Force |% {
|
|
||||||
$current_acl = Get-ACL $_.fullname
|
|
||||||
$permission = "$computer_name\$host_share_username","FullControl","ContainerInherit,ObjectInherit","None","Allow"
|
|
||||||
$acl_access_rule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
|
|
||||||
$current_acl.SetAccessRule($acl_access_rule)
|
|
||||||
$current_acl | Set-Acl $_.fullname
|
|
||||||
}
|
|
||||||
#>
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = net share $share_name=$path /unlimited /GRANT:$grant
|
|
||||||
if ($LastExitCode -eq 0) {
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
$host.ui.WriteErrorLine("Error: $result")
|
|
||||||
exit 1
|
|
|
@ -17,69 +17,46 @@ module VagrantPlugins
|
||||||
end
|
end
|
||||||
|
|
||||||
def usable?(machine, raise_error=false)
|
def usable?(machine, raise_error=false)
|
||||||
if !Vagrant::Util::Platform.windows?
|
# If the machine explicitly states SMB is not supported, then
|
||||||
raise Errors::WindowsHostRequired if raise_error
|
# believe it
|
||||||
return false
|
return false if !machine.config.smb.functional
|
||||||
end
|
return true if machine.env.host.capability?(:smb_installed) &&
|
||||||
|
machine.env.host.capability(:smb_installed)
|
||||||
if !Vagrant::Util::Platform.windows_admin?
|
return false if !raise_error
|
||||||
raise Errors::WindowsAdminRequired if raise_error
|
raise Vagrant::Errors::SMBNotSupported
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
psv = Vagrant::Util::PowerShell.version.to_i
|
|
||||||
if psv < 3
|
|
||||||
if raise_error
|
|
||||||
raise Errors::PowershellVersion,
|
|
||||||
version: psv.to_s
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def prepare(machine, folders, opts)
|
def prepare(machine, folders, opts)
|
||||||
machine.ui.output(I18n.t("vagrant_sf_smb.preparing"))
|
machine.ui.output(I18n.t("vagrant_sf_smb.preparing"))
|
||||||
|
|
||||||
script_path = File.expand_path("../scripts/set_share.ps1", __FILE__)
|
smb_username = smb_password = nil
|
||||||
|
|
||||||
# If we need auth information, then ask the user.
|
# If we need auth information, then ask the user.
|
||||||
have_auth = false
|
have_auth = false
|
||||||
folders.each do |id, data|
|
folders.each do |id, data|
|
||||||
if data[:smb_username] && data[:smb_password]
|
if data[:smb_username] && data[:smb_password]
|
||||||
@creds[:username] = data[:smb_username]
|
smb_username = data[:smb_username]
|
||||||
@creds[:password] = data[:smb_password]
|
smb_password = data[:smb_password]
|
||||||
have_auth = true
|
have_auth = true
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if !have_auth
|
if !have_auth
|
||||||
machine.ui.detail(I18n.t("vagrant_sf_smb.warning_password") + "\n ")
|
machine.env.ui.detail(I18n.t("vagrant_sf_smb.warning_password") + "\n ")
|
||||||
@creds[:username] = machine.ui.ask("Username: ")
|
smb_username = machine.env.ui.ask("Username: ")
|
||||||
@creds[:password] = machine.ui.ask("Password (will be hidden): ", echo: false)
|
smb_password = machine.env.ui.ask("Password (will be hidden): ", echo: false)
|
||||||
end
|
end
|
||||||
|
|
||||||
folders.each do |id, data|
|
folders.each do |id, data|
|
||||||
hostpath = data[:hostpath]
|
data[:smb_username] ||= smb_username
|
||||||
|
data[:smb_password] ||= smb_password
|
||||||
|
|
||||||
data[:smb_id] ||= Digest::MD5.hexdigest(
|
# Register password as sensitive
|
||||||
"#{machine.id}-#{id.gsub("/", "-")}")
|
Vagrant::Util::CredentialScrubber.sensitive(smb_password)
|
||||||
|
|
||||||
args = []
|
|
||||||
args << "-path" << "\"#{hostpath.gsub("/", "\\")}\""
|
|
||||||
args << "-share_name" << data[:smb_id]
|
|
||||||
#args << "-host_share_username" << @creds[:username]
|
|
||||||
|
|
||||||
r = Vagrant::Util::PowerShell.execute(script_path, *args)
|
|
||||||
if r.exit_code != 0
|
|
||||||
raise Errors::DefineShareFailed,
|
|
||||||
host: hostpath.to_s,
|
|
||||||
stderr: r.stderr,
|
|
||||||
stdout: r.stdout
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
machine.env.host.capability(:smb_prepare, machine, folders, opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
def enable(machine, folders, nfsopts)
|
def enable(machine, folders, nfsopts)
|
||||||
|
@ -109,7 +86,7 @@ module VagrantPlugins
|
||||||
end
|
end
|
||||||
|
|
||||||
if need_host_ip
|
if need_host_ip
|
||||||
candidate_ips = load_host_ips
|
candidate_ips = machine.env.host.capability(:configured_ip_addresses)
|
||||||
@logger.debug("Potential host IPs: #{candidate_ips.inspect}")
|
@logger.debug("Potential host IPs: #{candidate_ips.inspect}")
|
||||||
host_ip = machine.guest.capability(
|
host_ip = machine.guest.capability(
|
||||||
:choose_addressable_ip_addr, candidate_ips)
|
:choose_addressable_ip_addr, candidate_ips)
|
||||||
|
@ -141,25 +118,8 @@ module VagrantPlugins
|
||||||
end
|
end
|
||||||
|
|
||||||
def cleanup(machine, opts)
|
def cleanup(machine, opts)
|
||||||
|
if machine.env.host.capability?(:smb_cleanup)
|
||||||
end
|
machine.env.host.capability(:smb_cleanup, machine, opts)
|
||||||
|
|
||||||
protected
|
|
||||||
|
|
||||||
def load_host_ips
|
|
||||||
script_path = File.expand_path("../scripts/host_info.ps1", __FILE__)
|
|
||||||
r = Vagrant::Util::PowerShell.execute(script_path)
|
|
||||||
if r.exit_code != 0
|
|
||||||
raise Errors::PowershellError,
|
|
||||||
script: script_path,
|
|
||||||
stderr: r.stderr
|
|
||||||
end
|
|
||||||
|
|
||||||
res = JSON.parse(r.stdout)["ip_addresses"]
|
|
||||||
if res.instance_of? String
|
|
||||||
[ res ]
|
|
||||||
else
|
|
||||||
res
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,6 +11,13 @@ en:
|
||||||
folders shortly. Please use the proper username/password of your
|
folders shortly. Please use the proper username/password of your
|
||||||
Windows account.
|
Windows account.
|
||||||
|
|
||||||
|
uac:
|
||||||
|
prune_warning: |-
|
||||||
|
Vagrant requires administator access for pruning SMB shares and
|
||||||
|
may request access to complete removal of stale shares.
|
||||||
|
create_warning: |-
|
||||||
|
Vagrant requires administator access to create SMB shares and
|
||||||
|
may request access to complete setup of configured shares.
|
||||||
errors:
|
errors:
|
||||||
define_share_failed: |-
|
define_share_failed: |-
|
||||||
Exporting an SMB share failed! Details about the failure are shown
|
Exporting an SMB share failed! Details about the failure are shown
|
||||||
|
@ -20,6 +27,15 @@ en:
|
||||||
|
|
||||||
Stderr: %{stderr}
|
Stderr: %{stderr}
|
||||||
|
|
||||||
|
Stdout: %{stdout}
|
||||||
|
prune_share_failed: |-
|
||||||
|
Pruning an SMB share failed! Details about the failure are shown
|
||||||
|
below. Please inspect the error message and correct any problems.
|
||||||
|
|
||||||
|
Share name: %{name}
|
||||||
|
|
||||||
|
Stderr: %{stderr}
|
||||||
|
|
||||||
Stdout: %{stdout}
|
Stdout: %{stdout}
|
||||||
no_routable_host_addr: |-
|
no_routable_host_addr: |-
|
||||||
We couldn't detect an IP address that was routable to this
|
We couldn't detect an IP address that was routable to this
|
||||||
|
|
Loading…
Reference in New Issue