@@ -33,11 +33,15 @@ Vagrant.configure(2) do |config|
33
33
vbox . cpus = Integer ( ENV [ 'VAGRANT_CPUS' ] || 4 )
34
34
end
35
35
36
+ # Vagrant and ruby stdlib expand '.' differently, so look for the build
37
+ # in the directory containing the Vagrantfile
38
+ vagrantfile_dir = File . expand_path ( '..' , __FILE__ )
39
+
36
40
# Switch the default share for the project root from /vagrant to
37
41
# /elasticsearch because /vagrant is confusing when there is a project inside
38
42
# the elasticsearch project called vagrant....
39
- config . vm . synced_folder '.' , '/vagrant' , disabled : true
40
- config . vm . synced_folder '.' , '/elasticsearch'
43
+ config . vm . synced_folder vagrantfile_dir , '/vagrant' , disabled : true
44
+ config . vm . synced_folder vagrantfile_dir , '/elasticsearch'
41
45
42
46
# Expose project directory. Note that VAGRANT_CWD may not be the same as Dir.pwd
43
47
PROJECT_DIR = ENV [ 'VAGRANT_PROJECT_DIR' ] || Dir . pwd
@@ -121,6 +125,30 @@ Vagrant.configure(2) do |config|
121
125
sles_common config , box
122
126
end
123
127
end
128
+
129
+ windows_2012r2_box = ENV [ 'VAGRANT_WINDOWS_2012R2_BOX' ]
130
+ if windows_2012r2_box && windows_2012r2_box . empty? == false
131
+ 'windows-2012r2' . tap do |box |
132
+ config . vm . define box , define_opts do |config |
133
+ config . vm . box = windows_2012r2_box
134
+ windows_common config , box
135
+ end
136
+ end
137
+ end
138
+
139
+ windows_2016_box = ENV [ 'VAGRANT_WINDOWS_2016_BOX' ]
140
+ if windows_2016_box && windows_2016_box . empty? == false
141
+ 'windows-2016' . tap do |box |
142
+ config . vm . define box , define_opts do |config |
143
+ config . vm . box = windows_2016_box
144
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
145
+ config . vm . provision 'enable long paths' , type : 'shell' , inline : <<-SHELL
146
+ Set-ItemProperty -Path "HKLM:/SYSTEM/CurrentControlSet/Control/Filesystem/" -Name "LongPathsEnabled" -Value 1
147
+ SHELL
148
+ windows_common config , box
149
+ end
150
+ end
151
+ end
124
152
end
125
153
126
154
def deb_common ( config , name , extra : '' )
@@ -351,3 +379,121 @@ SUDOERS_VARS
351
379
chmod 0440 /etc/sudoers.d/elasticsearch_vars
352
380
SHELL
353
381
end
382
+
383
+ def windows_common ( config , name )
384
+ config . vm . provision 'markerfile' , type : 'shell' , inline : <<-SHELL
385
+ $ErrorActionPreference = "Stop"
386
+ New-Item C:/is_vagrant_vm -ItemType file -Force | Out-Null
387
+ SHELL
388
+
389
+ config . vm . provision 'clean es installs in tmp' , run : 'always' , type : 'shell' , inline : <<-SHELL
390
+ Remove-Item -Recurse -Force C:\\ tmp\\ elasticsearch*
391
+ SHELL
392
+
393
+ config . vm . provision 'set prompt' , type : 'shell' , inline : <<-SHELL
394
+ $ErrorActionPreference = "Stop"
395
+ $ps_prompt = 'function Prompt { "#{ name } :$($ExecutionContext.SessionState.Path.CurrentLocation)>" }'
396
+ $ps_prompt | Out-File $PsHome/Microsoft.PowerShell_profile.ps1
397
+ SHELL
398
+
399
+ # Windows' system APIs limit paths to 260 characters. In server 2016 we can raise this limit,
400
+ # (see LongPathsEnabled above) but not in server 2012r2. This adds a powershell module that has basic
401
+ # copy and delete command that can handle long paths
402
+ config . vm . provision 'long path shim module' , type : 'shell' do |s |
403
+ s . privileged = false
404
+ s . inline = <<-SHELL
405
+ $ErrorActionPreference = "Stop"
406
+ $longPathScript = @'
407
+ #{ powershell_long_path_module }
408
+ '@
409
+ $ModuleDir = "C:/Users/vagrant/Documents/WindowsPowerShell/Modules/LongPathShims"
410
+ $ModuleFile = "$ModuleDir/LongPathShims.psm1"
411
+ if (-Not (Test-Path "$ModuleDir")) {
412
+ New-Item "$ModuleDir" -ItemType Directory | Out-Null
413
+ }
414
+ $longPathScript | Out-File "$ModuleFile"
415
+ SHELL
416
+ end
417
+
418
+ powershell_install_deps config
419
+ end
420
+
421
+ # Powershell's filesystem commands cannot handle long paths by default. This module implements
422
+ # the required commands by calling Robocopy [1], a Windows system utility for moving files around
423
+ # that can handle long paths by default. Robocopy returns unusual exit codes [2] so we call it in
424
+ # a wrapper that converts them to what we'd normally expect.
425
+ #
426
+ # The Remove-Long-Path function works by syncing the contents of an empty directory to the
427
+ # delete target, which has the effect of recursively deleting it.
428
+ #
429
+ # [1] https://ss64.com/nt/robocopy.html
430
+ # [2] https://ss64.com/nt/robocopy-exit.html
431
+ def powershell_long_path_module
432
+ <<-SHELL
433
+ function Copy-Long-Path {
434
+ param(
435
+ [string]$Source,
436
+ [string]$Destination
437
+ )
438
+
439
+ robocopy "$Source" "$Destination" /E /COPY:DT /DCOPY:T /NFL /NDL /NJH /NJS /NC /NS /NP
440
+ Handle-Robocopy-Exit-Code $LASTEXITCODE
441
+ }
442
+
443
+ function Remove-Long-Path {
444
+ param(
445
+ [string]$Target
446
+ )
447
+
448
+ $EmptyDir = "C:\\ intentionally_empty"
449
+
450
+ try {
451
+ New-Item "$EmptyDir" -ItemType Directory | Out-Null
452
+ # There doesn't appear to be a way to silence output about files that are purged,
453
+ # so just sent it to null as writing it to the terminal is very slow
454
+ robocopy "$EmptyDir" "$Target" /PURGE /NFL /NDL /NJH /NJS /NC /NS /NP | Out-Null
455
+ $RobocopyExitCode = $LASTEXITCODE
456
+ Remove-Item "$Target" -Recurse
457
+ Handle-Robocopy-Exit-Code $RobocopyExitCode
458
+ } finally {
459
+ Remove-Item "$EmptyDir" -Recurse
460
+ }
461
+ }
462
+
463
+ function Handle-Robocopy-Exit-Code {
464
+ param(
465
+ [int]$ExitCode
466
+ )
467
+
468
+ Write-Verbose "robocopy returned exit code $ExitCode"
469
+ if ($ExitCode -ge 7) {
470
+ Write-Error "robocopy encountered an error and returned exit code $ExitCode"
471
+ }
472
+ }
473
+ SHELL
474
+ end
475
+
476
+ # Just check that java is installed - when other dependencies are needed
477
+ # in the future, this is where they'll go
478
+ def powershell_install_deps ( config )
479
+ config . vm . provision 'install deps' , type : 'shell' , inline : <<-SHELL
480
+ $ErrorActionPreference = "Stop"
481
+
482
+ function Installed {
483
+ Param(
484
+ [string]$command
485
+ )
486
+
487
+ try {
488
+ Get-Command $command
489
+ return $true
490
+ } catch {
491
+ return $false
492
+ }
493
+ }
494
+
495
+ if (-Not (Installed java)) {
496
+ Write-Error "java is not installed"
497
+ }
498
+ SHELL
499
+ end
0 commit comments