vagrant-vmm 1.0.0
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 +15 -0
- data/.gitignore +18 -0
- data/.travis.yml +14 -0
- data/Gemfile +12 -0
- data/LICENSE.txt +22 -0
- data/README.md +118 -0
- data/Rakefile +5 -0
- data/example/Berksfile +6 -0
- data/example/Vagrantfile +53 -0
- data/example/metadata.rb +5 -0
- data/lib/vagrant-vmm/action/delete_vm.rb +25 -0
- data/lib/vagrant-vmm/action/import.rb +35 -0
- data/lib/vagrant-vmm/action/message_will_not_destroy.rb +17 -0
- data/lib/vagrant-vmm/action/read_state.rb +39 -0
- data/lib/vagrant-vmm/action/resume_vm.rb +25 -0
- data/lib/vagrant-vmm/action/start_instance.rb +26 -0
- data/lib/vagrant-vmm/action/stop_instance.rb +26 -0
- data/lib/vagrant-vmm/action/suspend_vm.rb +25 -0
- data/lib/vagrant-vmm/action/wait_for_ip_address.rb +64 -0
- data/lib/vagrant-vmm/action.rb +225 -0
- data/lib/vagrant-vmm/cap/public_address.rb +15 -0
- data/lib/vagrant-vmm/config.rb +44 -0
- data/lib/vagrant-vmm/driver.rb +124 -0
- data/lib/vagrant-vmm/errors.rb +42 -0
- data/lib/vagrant-vmm/plugin.rb +46 -0
- data/lib/vagrant-vmm/provider.rb +103 -0
- data/lib/vagrant-vmm/scripts/delete_vm.ps1 +32 -0
- data/lib/vagrant-vmm/scripts/get_network_config.ps1 +84 -0
- data/lib/vagrant-vmm/scripts/get_vm_status.ps1 +40 -0
- data/lib/vagrant-vmm/scripts/import_vm.ps1 +107 -0
- data/lib/vagrant-vmm/scripts/resume_vm.ps1 +24 -0
- data/lib/vagrant-vmm/scripts/start_vm.ps1 +48 -0
- data/lib/vagrant-vmm/scripts/stop_vm.ps1 +24 -0
- data/lib/vagrant-vmm/scripts/suspend_vm.ps1 +27 -0
- data/lib/vagrant-vmm/scripts/sync_folders.ps1 +200 -0
- data/lib/vagrant-vmm/scripts/utils/manage_credentials.ps1 +26 -0
- data/lib/vagrant-vmm/scripts/utils/vmm_executor.ps1 +30 -0
- data/lib/vagrant-vmm/scripts/utils/write_messages.ps1 +20 -0
- data/lib/vagrant-vmm/synced_folder.rb +89 -0
- data/lib/vagrant-vmm/version.rb +5 -0
- data/lib/vagrant-vmm.rb +17 -0
- data/locales/en.yml +46 -0
- data/vagrant-vmm.gemspec +23 -0
- metadata +114 -0
@@ -0,0 +1,84 @@
|
|
1
|
+
Param(
|
2
|
+
[Parameter(Mandatory=$true)]
|
3
|
+
[string]$vm_id,
|
4
|
+
[Parameter(Mandatory=$true)]
|
5
|
+
[string]$vmm_server_address,
|
6
|
+
[string]$proxy_server_address=$null,
|
7
|
+
[int]$timeout
|
8
|
+
)
|
9
|
+
|
10
|
+
|
11
|
+
# Include the following modules
|
12
|
+
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
13
|
+
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
14
|
+
. ([System.IO.Path]::Combine($Dir, "utils\vmm_executor.ps1"))
|
15
|
+
|
16
|
+
|
17
|
+
$script_block = {
|
18
|
+
# external vars
|
19
|
+
$vm_id = $using:vm_id
|
20
|
+
$timeout = $using:timeout
|
21
|
+
|
22
|
+
|
23
|
+
$vm = Get-SCVirtualMachine -ID $vm_id
|
24
|
+
Write-host "Waiting for IP to be assigned for $($vm.ComputerNameString) (id: $vm_id)..."
|
25
|
+
$ip = $null
|
26
|
+
$tries = 0
|
27
|
+
do {
|
28
|
+
sleep -s 1
|
29
|
+
$ad = Get-SCVirtualNetworkAdapter -VM $vm -ErrorAction Ignore
|
30
|
+
if ( $ad.IPv4Addresses.count -gt 0 )
|
31
|
+
{
|
32
|
+
$ip = $ad.IPv4Addresses[0]
|
33
|
+
} else {
|
34
|
+
$ips = [System.Net.Dns]::GetHostAddresses($vm.ComputerNameString)
|
35
|
+
if ( $ips.count -gt 0 )
|
36
|
+
{
|
37
|
+
$ip = $ips[0].IPAddressToString
|
38
|
+
}
|
39
|
+
}
|
40
|
+
Write-progress -Activity "Trying to get IP from $($vm.ComputerNameString)" -PercentComplete $($tries*100/$timeout) -Status "Try: $tries"
|
41
|
+
$tries += 1
|
42
|
+
} while ( $ip -eq $null -and $tries -le $timeout )
|
43
|
+
#
|
44
|
+
return @{
|
45
|
+
ip = $ip;
|
46
|
+
hostname = $vm.ComputerNameString
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
$address_info = execute $script_block $vmm_server_address $proxy_server_address
|
51
|
+
$address_to_use = $address_info["ip"]
|
52
|
+
|
53
|
+
if ( $address_to_use -ne $null )
|
54
|
+
{
|
55
|
+
try
|
56
|
+
{
|
57
|
+
Write-host "Trying to resolve VM hostname($($address_info["hostname"])) from the current machine."
|
58
|
+
[System.Net.Dns]::GetHostAddresses($address_info["hostname"])
|
59
|
+
$address_to_use = $address_info["hostname"]
|
60
|
+
} catch {
|
61
|
+
Write-host "Failed to resolve hostname, so falling back to IP: $address_to_use"
|
62
|
+
}
|
63
|
+
} else {
|
64
|
+
# ask for manual IP entry if timedout
|
65
|
+
Write-host "Couldn't get ip for the VM within given timeout, you can get and specify it manually (or leave blank and vagrant will stop)."
|
66
|
+
$ip = Read-Host 'Enter VM IP address:'
|
67
|
+
}
|
68
|
+
|
69
|
+
if ( $address_to_use -as [ipaddress] )
|
70
|
+
{
|
71
|
+
$trusted_hosts = get-item wsman:\localhost\Client\TrustedHosts
|
72
|
+
if ( !$trusted_hosts.Value.Contains($address_to_use) )
|
73
|
+
{
|
74
|
+
Write-host "Adding $address_to_use to trusted host list"
|
75
|
+
$new_th_values = "$($trusted_hosts.Value),$address_to_use"
|
76
|
+
set-item wsman:\localhost\Client\TrustedHosts $new_th_values -Force
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
$resultHash = @{
|
81
|
+
address = $address_to_use
|
82
|
+
}
|
83
|
+
$result = ConvertTo-Json $resultHash
|
84
|
+
Write-Output-Message $result
|
@@ -0,0 +1,40 @@
|
|
1
|
+
Param(
|
2
|
+
[Parameter(Mandatory=$true)]
|
3
|
+
[string]$vm_id,
|
4
|
+
[Parameter(Mandatory=$true)]
|
5
|
+
[string]$vmm_server_address,
|
6
|
+
[string]$proxy_server_address=$null
|
7
|
+
)
|
8
|
+
|
9
|
+
# Include the following modules
|
10
|
+
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
11
|
+
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
12
|
+
. ([System.IO.Path]::Combine($Dir, "utils\vmm_executor.ps1"))
|
13
|
+
|
14
|
+
|
15
|
+
$script_block = {
|
16
|
+
# external vars
|
17
|
+
$vm_id = $using:vm_id
|
18
|
+
|
19
|
+
# Get VM
|
20
|
+
Get-SCVirtualMachine -ID $vm_id -ErrorAction Ignore
|
21
|
+
}
|
22
|
+
|
23
|
+
$vm = execute $script_block $vmm_server_address $proxy_server_address
|
24
|
+
|
25
|
+
if ( $vm )
|
26
|
+
{
|
27
|
+
$State = $vm.status
|
28
|
+
$Status = $vm.status
|
29
|
+
} else {
|
30
|
+
$State = 'not_created'
|
31
|
+
$Status = $vm.status
|
32
|
+
}
|
33
|
+
|
34
|
+
$resultHash = @{
|
35
|
+
state = "$State"
|
36
|
+
status = "$Status"
|
37
|
+
}
|
38
|
+
|
39
|
+
$result = ConvertTo-Json $resultHash
|
40
|
+
Write-Output-Message $result
|
@@ -0,0 +1,107 @@
|
|
1
|
+
Param(
|
2
|
+
[Parameter(Mandatory=$true)]
|
3
|
+
[string]$vm_name,
|
4
|
+
[Parameter(Mandatory=$true)]
|
5
|
+
[string]$vmm_server_address,
|
6
|
+
[Parameter(Mandatory=$true)]
|
7
|
+
[string]$vm_template_name,
|
8
|
+
[Parameter(Mandatory=$true)]
|
9
|
+
[string]$vm_host_group_name,
|
10
|
+
[string]$proxy_server_address=$null
|
11
|
+
)
|
12
|
+
|
13
|
+
# Include the following modules
|
14
|
+
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
15
|
+
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
16
|
+
. ([System.IO.Path]::Combine($Dir, "utils\vmm_executor.ps1"))
|
17
|
+
|
18
|
+
|
19
|
+
$script_block = {
|
20
|
+
# external vars
|
21
|
+
$vm_name = $using:vm_name
|
22
|
+
$vm_host_group_name = $using:vm_host_group_name
|
23
|
+
$vmm_credential = $using:vmm_credential
|
24
|
+
$server_address = $using:vmm_server_address
|
25
|
+
$vm_template_name = $using:vm_template_name
|
26
|
+
|
27
|
+
$description = "VM created by vagrant for testing purposes"
|
28
|
+
$MinFreeSpaceGB = 300 #
|
29
|
+
|
30
|
+
# get VM Template object
|
31
|
+
$VMTemplate = Get-SCVMTemplate -Name $vm_template_name
|
32
|
+
# get host group
|
33
|
+
$VMHostGroup = Get-VMHostGroup -Name $vm_host_group_name
|
34
|
+
#
|
35
|
+
Write-Host "Creating VM from template $vm_template_name"
|
36
|
+
|
37
|
+
$tries = 10
|
38
|
+
while ( $tries -gt 0 ) {
|
39
|
+
$vm = Get-SCVirtualMachine -Name $vm_name
|
40
|
+
if ( $vm -eq $null ) {
|
41
|
+
break
|
42
|
+
} else {
|
43
|
+
$vm_name = $vm_name.substring(0, [math]::Min(14, $vm_name.length)) + $(Get-Random -Minimum 0 -Maximum 10)
|
44
|
+
}
|
45
|
+
$tries -= 1
|
46
|
+
}
|
47
|
+
if ( $vm -eq $null )
|
48
|
+
{
|
49
|
+
# Get and sort the host ratings for all the hosts in the host group.
|
50
|
+
# select host which has rating > 0
|
51
|
+
$hRatingHashParams = @{Template=$VMTemplate;
|
52
|
+
DiskSpaceGB=$MinFreeSpaceGB;
|
53
|
+
VMName=$vm_name;
|
54
|
+
VMHostGroup=$VMHostGroup;
|
55
|
+
VMMServer=$vmmServer
|
56
|
+
}
|
57
|
+
|
58
|
+
$VMHost = $null
|
59
|
+
$HostRatings = @(Get-VMHostRating @hRatingHashParams | Sort-Object -property Rating -descending)
|
60
|
+
If($HostRatings.Count -eq 0) { throw "No hosts meet the requirements." }
|
61
|
+
$VMHost = $HostRatings[0].VMHost
|
62
|
+
|
63
|
+
# If there is at least one host that will support the virtual machine, create the virtual machine on the highest-rated host.
|
64
|
+
If ($VMHost -ne $null )
|
65
|
+
{
|
66
|
+
# get placement path
|
67
|
+
$path = $($VMHost.DiskVolumes | where { $_.IsAvailableForPlacement -eq $True } | Sort-Object -Property FreeSpace -Descending)[0]
|
68
|
+
Write-Host "----- Creating VM ----"
|
69
|
+
Write-Host "Host: $VMHost, $($VMHost.CPUManufacturer) $($VMHost.Rank)"
|
70
|
+
Write-host "Placement path: $($path.Name), Free space - $($path.FreeSpace/1024/1024/1024) GB"
|
71
|
+
Write-Host "Name: $vm_name"
|
72
|
+
Write-Host "----- ----------- ----"
|
73
|
+
# Create the virtual machine.
|
74
|
+
$vmCreateParams = @{Name=$vm_name;
|
75
|
+
Path=$path.Name;
|
76
|
+
VMHost = $VMHost;
|
77
|
+
VMTemplate=$VMTemplate;
|
78
|
+
Description=$description;
|
79
|
+
ComputerName=$vm_name;
|
80
|
+
BlockDynamicOptimization=$false;
|
81
|
+
ReturnImmediately = $false; AnswerFile = $null;
|
82
|
+
StartAction = "NeverAutoTurnOnVM";
|
83
|
+
StopAction = "TurnOffVM";
|
84
|
+
StartVM=$false;
|
85
|
+
ErrorAction="stop";
|
86
|
+
DelayStartSeconds = $(Get-Random -Minimum 20 -Maximum 100)
|
87
|
+
}
|
88
|
+
|
89
|
+
New-SCVirtualMachine @vmCreateParams
|
90
|
+
} else {
|
91
|
+
Write-Error "Cannot find suitable host for the VM."
|
92
|
+
}
|
93
|
+
} else {
|
94
|
+
Write-Warning "Machine $vm_name already exists on host $($vm.VMHost.Name)"
|
95
|
+
$vm
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
$vm = execute $script_block $vmm_server_address $proxy_server_address
|
100
|
+
|
101
|
+
$resultHash = @{
|
102
|
+
name = $vm.Name
|
103
|
+
id = $vm.id.guid
|
104
|
+
}
|
105
|
+
|
106
|
+
$result = ConvertTo-Json $resultHash
|
107
|
+
Write-Output-Message $result
|
@@ -0,0 +1,24 @@
|
|
1
|
+
Param(
|
2
|
+
[Parameter(Mandatory=$true)]
|
3
|
+
[string]$vm_id,
|
4
|
+
[Parameter(Mandatory=$true)]
|
5
|
+
[string]$vmm_server_address,
|
6
|
+
[string]$proxy_server_address=$null
|
7
|
+
)
|
8
|
+
|
9
|
+
# Include the following modules
|
10
|
+
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
11
|
+
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
12
|
+
. ([System.IO.Path]::Combine($Dir, "utils\vmm_executor.ps1"))
|
13
|
+
|
14
|
+
|
15
|
+
$script_block = {
|
16
|
+
# external vars
|
17
|
+
$vm_id = $using:vm_id
|
18
|
+
|
19
|
+
# Get VM
|
20
|
+
$vm = Get-SCVirtualMachine -ID $vm_id -ErrorAction Ignore
|
21
|
+
Resume-VM $vm
|
22
|
+
}
|
23
|
+
|
24
|
+
execute $script_block $vmm_server_address $proxy_server_address
|
@@ -0,0 +1,48 @@
|
|
1
|
+
Param(
|
2
|
+
[Parameter(Mandatory=$true)]
|
3
|
+
[string]$vm_id,
|
4
|
+
[Parameter(Mandatory=$true)]
|
5
|
+
[string]$vmm_server_address,
|
6
|
+
[string]$proxy_server_address=$null
|
7
|
+
)
|
8
|
+
|
9
|
+
|
10
|
+
# Include the following modules
|
11
|
+
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
12
|
+
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
13
|
+
. ([System.IO.Path]::Combine($Dir, "utils\vmm_executor.ps1"))
|
14
|
+
|
15
|
+
|
16
|
+
$script_block = {
|
17
|
+
# external vars
|
18
|
+
$vm_id = $using:vm_id
|
19
|
+
|
20
|
+
# Get VM
|
21
|
+
$vm = Get-SCVirtualMachine -ID $vm_id -ErrorAction Ignore
|
22
|
+
if ( $vm.status -ne 'Running')
|
23
|
+
{
|
24
|
+
Start-VM $vm
|
25
|
+
}
|
26
|
+
$vm
|
27
|
+
}
|
28
|
+
|
29
|
+
$vm = execute $script_block $vmm_server_address $proxy_server_address
|
30
|
+
|
31
|
+
if ( $vm )
|
32
|
+
{
|
33
|
+
$State = $vm.status
|
34
|
+
$Status = $vm.status
|
35
|
+
} else {
|
36
|
+
$State = 'undefined'
|
37
|
+
$Status = $vm.status
|
38
|
+
Write-Error-Message "Failed to start a VM $_"
|
39
|
+
}
|
40
|
+
|
41
|
+
$resultHash = @{
|
42
|
+
state = "$State"
|
43
|
+
status = "$Status"
|
44
|
+
name = $vm.Name
|
45
|
+
}
|
46
|
+
|
47
|
+
$result = ConvertTo-Json $resultHash
|
48
|
+
Write-Output-Message $result
|
@@ -0,0 +1,24 @@
|
|
1
|
+
Param(
|
2
|
+
[Parameter(Mandatory=$true)]
|
3
|
+
[string]$vm_id,
|
4
|
+
[Parameter(Mandatory=$true)]
|
5
|
+
[string]$vmm_server_address,
|
6
|
+
[string]$proxy_server_address=$null
|
7
|
+
)
|
8
|
+
|
9
|
+
# Include the following modules
|
10
|
+
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
11
|
+
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
12
|
+
. ([System.IO.Path]::Combine($Dir, "utils\vmm_executor.ps1"))
|
13
|
+
|
14
|
+
|
15
|
+
$script_block = {
|
16
|
+
# external vars
|
17
|
+
$vm_id = $using:vm_id
|
18
|
+
|
19
|
+
# Get VM
|
20
|
+
$vm = Get-SCVirtualMachine -ID $vm_id -ErrorAction Ignore
|
21
|
+
Stop-VM $vm
|
22
|
+
}
|
23
|
+
|
24
|
+
execute $script_block $vmm_server_address $proxy_server_address
|
@@ -0,0 +1,27 @@
|
|
1
|
+
Param(
|
2
|
+
[Parameter(Mandatory=$true)]
|
3
|
+
[string]$vm_id,
|
4
|
+
[Parameter(Mandatory=$true)]
|
5
|
+
[string]$vmm_server_address,
|
6
|
+
[string]$proxy_server_address=$null
|
7
|
+
)
|
8
|
+
|
9
|
+
# Include the following modules
|
10
|
+
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
11
|
+
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
12
|
+
. ([System.IO.Path]::Combine($Dir, "utils\vmm_executor.ps1"))
|
13
|
+
|
14
|
+
|
15
|
+
$script_block = {
|
16
|
+
# external vars
|
17
|
+
$vm_id = $using:vm_id
|
18
|
+
|
19
|
+
# Get VM
|
20
|
+
$vm = Get-SCVirtualMachine -ID $vm_id -ErrorAction Ignore
|
21
|
+
if ($vm.status -eq 'Running')
|
22
|
+
{
|
23
|
+
Suspend-VM $vm
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
execute $script_block $vmm_server_address $proxy_server_address
|
@@ -0,0 +1,200 @@
|
|
1
|
+
#-------------------------------------------------------------------------
|
2
|
+
# Copyright (c) Microsoft Open Technologies, Inc.
|
3
|
+
# All Rights Reserved. Licensed under the Apache 2.0 License.
|
4
|
+
#--------------------------------------------------------------------------
|
5
|
+
# part of code taken from:
|
6
|
+
# https://github.com/MSOpenTech/vagrant-windows-hyperv/blob/master/lib/vagrant-windows-hyperv/scripts/file_sync.ps1
|
7
|
+
|
8
|
+
Param(
|
9
|
+
[Parameter(Mandatory=$true)]
|
10
|
+
[string]$vm_address,
|
11
|
+
[Parameter(Mandatory=$true)]
|
12
|
+
[string]$folders_to_sync,
|
13
|
+
[string]$winrm_vm_username,
|
14
|
+
[string]$winrm_vm_password
|
15
|
+
)
|
16
|
+
# Include the following modules
|
17
|
+
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
18
|
+
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
19
|
+
. ([System.IO.Path]::Combine($Dir, "utils\manage_credentials.ps1"))
|
20
|
+
|
21
|
+
# Sync flow:
|
22
|
+
# get list of files to sync, compare hashes with the remote ones
|
23
|
+
# create fileshare on the remote machine
|
24
|
+
# get access to fileshare from the current machine
|
25
|
+
# transfer all required files to the fileshare
|
26
|
+
# re-copy/move files on remote machine from fileshare to correct folders
|
27
|
+
|
28
|
+
|
29
|
+
# convert from json to ps object
|
30
|
+
$folders_to_sync_obj = ConvertFrom-Json $folders_to_sync
|
31
|
+
$delimiter = " || "
|
32
|
+
|
33
|
+
function Get-file-hash($source_paths, $delimiter) {
|
34
|
+
$source_files = @{}
|
35
|
+
Write-host "$(&hostname) :: Collecting file hashes..."
|
36
|
+
|
37
|
+
foreach ( $source_path in $source_paths )
|
38
|
+
{
|
39
|
+
$source_files[$source_path] = @()
|
40
|
+
# convert unix style to windows
|
41
|
+
$source_path_normalized = [System.IO.Path]::GetFullPath($source_path)
|
42
|
+
if ( Test-path $source_path_normalized )
|
43
|
+
{
|
44
|
+
(Get-ChildItem $source_path_normalized -rec | ForEach-Object -Process {
|
45
|
+
Get-FileHash -Path $_.FullName -Algorithm MD5
|
46
|
+
}
|
47
|
+
) | ForEach-Object -Process {
|
48
|
+
$source_files[$source_path] += $_.Path.Replace($source_path_normalized, "") + $delimiter + $_.Hash
|
49
|
+
}
|
50
|
+
# get empty dirs, set hash to be 0 for them
|
51
|
+
Get-ChildItem $source_path_normalized -recurse |
|
52
|
+
Where-Object {$_.PSIsContainer -eq $True} |
|
53
|
+
Where-Object {$_.GetFiles().Count -eq 0} |
|
54
|
+
Select-Object FullName | ForEach-Object -Process {
|
55
|
+
$source_files[$source_path] += $_.FullName.Replace($source_path_normalized, "") + $delimiter + "0"
|
56
|
+
}
|
57
|
+
}
|
58
|
+
}
|
59
|
+
return $source_files
|
60
|
+
}
|
61
|
+
|
62
|
+
function Get-remote-file-hash($source_paths, $delimiter, $session) {
|
63
|
+
return Invoke-Command -Session $session -ScriptBlock ${function:Get-file-hash} -ArgumentList $source_paths, $delimiter
|
64
|
+
}
|
65
|
+
|
66
|
+
$trusted_hosts = get-item wsman:\localhost\Client\TrustedHosts
|
67
|
+
if ( !$trusted_hosts.Value.Contains($vm_address) )
|
68
|
+
{
|
69
|
+
Write-host "Adding $vm_address to trusted host list"
|
70
|
+
$new_th_values = "$($trusted_hosts.Value),$vm_address"
|
71
|
+
set-item wsman:\localhost\Client\TrustedHosts $new_th_values -Force
|
72
|
+
}
|
73
|
+
|
74
|
+
$creds_to_vm = Get-Creds $vm_address "Credentials for access to the VM ($vm_address) via WinRM" $winrm_vm_username $winrm_vm_password
|
75
|
+
$auth_method = "default"
|
76
|
+
if ( !$creds_to_vm.UserName.contains("\") -and !$creds_to_vm.UserName.contains("@") )
|
77
|
+
{
|
78
|
+
$auth_method = "basic"
|
79
|
+
}
|
80
|
+
$session = New-PSSession -ComputerName $vm_address -Credential $creds_to_vm -Authentication $auth_method
|
81
|
+
|
82
|
+
# Compare source and destination files
|
83
|
+
$remove_files = @{}
|
84
|
+
$copy_files = @{}
|
85
|
+
$folder_mappings = @{}
|
86
|
+
foreach ( $hst_path in $folders_to_sync_obj.psobject.properties.Name )
|
87
|
+
{
|
88
|
+
$guest_path = $folders_to_sync_obj.$hst_path
|
89
|
+
$folder_mappings[$hst_path] = $guest_path
|
90
|
+
$copy_files[$hst_path] = @()
|
91
|
+
$remove_files[$guest_path] = @()
|
92
|
+
}
|
93
|
+
|
94
|
+
$source_files = Get-file-hash $folder_mappings.Keys $delimiter
|
95
|
+
$destination_files = Get-remote-file-hash $folder_mappings.Values $delimiter $session
|
96
|
+
if (!$destination_files) {
|
97
|
+
$destination_files = @{}
|
98
|
+
}
|
99
|
+
|
100
|
+
# compare hashes and derive what should be copied over and what removed
|
101
|
+
foreach ( $hst_path in $folder_mappings.Keys )
|
102
|
+
{
|
103
|
+
$guest_path = $folder_mappings[$hst_path]
|
104
|
+
Write-host "Comparing hashes $hst_path <=> $guest_path"
|
105
|
+
if ( !$destination_files[$guest_path] ) {
|
106
|
+
$destination_files[$guest_path] = @()
|
107
|
+
}
|
108
|
+
|
109
|
+
Compare-Object -ReferenceObject $source_files[$hst_path] -DifferenceObject $destination_files[$guest_path] | ForEach-Object {
|
110
|
+
if ($_.SideIndicator -eq '=>') {
|
111
|
+
$remove_files[$guest_path] += $_.InputObject.Split($delimiter)[0]
|
112
|
+
} else {
|
113
|
+
$copy_files[$hst_path] += $_.InputObject.Split($delimiter)[0]
|
114
|
+
}
|
115
|
+
}
|
116
|
+
}
|
117
|
+
|
118
|
+
# create file share on the remote machine
|
119
|
+
Invoke-Command -Session $session -ScriptBlock {
|
120
|
+
$fileshare_dest = "$($env:SystemDrive)\vagrant-sync"
|
121
|
+
if (Test-path $fileshare_dest)
|
122
|
+
{
|
123
|
+
Remove-item "$fileshare_dest\*" -recurse -force
|
124
|
+
} else {
|
125
|
+
$sync_dir = New-item $fileshare_dest -itemtype directory
|
126
|
+
}
|
127
|
+
$shr = Get-SmbShare -Name "vagrant-sync" -ErrorAction Ignore
|
128
|
+
if ( $shr -eq $null )
|
129
|
+
{
|
130
|
+
Write-host "$(&hostname) :: Creating fileshare on the remote host in $fileshare_dest, granting access to $($env:USERDOMAIN)\$($env:USERNAME)"
|
131
|
+
$shr = New-SmbShare -Name "vagrant-sync" -Temporary -Path $fileshare_dest -FullAccess "$($env:USERDOMAIN)\$($env:USERNAME)"
|
132
|
+
}
|
133
|
+
}
|
134
|
+
|
135
|
+
# get access to the fileshare from the current machine
|
136
|
+
Write-host "Getting access from the current machine to the created fileshare (\\$vm_address\vagrant-sync)"
|
137
|
+
$vagrant_sync_drive = New-PSDrive -Name 'V' -PSProvider 'FileSystem' -Root "\\$vm_address\vagrant-sync" -Credential $creds_to_vm
|
138
|
+
|
139
|
+
Write-host "Syncing files to fileshare..."
|
140
|
+
foreach ( $hst_path in $copy_files.Keys)
|
141
|
+
{
|
142
|
+
$current = 0
|
143
|
+
$total = $copy_files[$hst_path].Count
|
144
|
+
# copy files to the fileshare
|
145
|
+
foreach( $file in $copy_files[$hst_path] )
|
146
|
+
{
|
147
|
+
$current += 1
|
148
|
+
$file_path = $hst_path + $file
|
149
|
+
$guest_path = $folder_mappings[$hst_path]
|
150
|
+
$guest_path = [System.IO.Path]::GetFullPath("$($vagrant_sync_drive.root)\$guest_path")
|
151
|
+
Write-progress -Activity "Syncing $hst_path with $guest_path" -PercentComplete $($current*100/$total) -Status "Copying $file"
|
152
|
+
if (Test-Path $file_path -pathtype container)
|
153
|
+
{
|
154
|
+
# folder
|
155
|
+
$out = New-Item $file_path -itemtype directory -ErrorAction Ignore
|
156
|
+
} else {
|
157
|
+
# file
|
158
|
+
$file_dir = split-path $file
|
159
|
+
$out = New-item "$guest_path\$file_dir" -itemtype directory -ErrorAction Ignore
|
160
|
+
Copy-Item $file_path "$guest_path\$file" -recurse
|
161
|
+
}
|
162
|
+
}
|
163
|
+
}
|
164
|
+
|
165
|
+
# copy from fileshare to the dest locations on the remote machine
|
166
|
+
# as well as remove files that shouldn't be there
|
167
|
+
Invoke-Command -Session $session -ScriptBlock {
|
168
|
+
$remove_files = $using:remove_files
|
169
|
+
$fileshare_dest = "$($env:SystemDrive)\vagrant-sync"
|
170
|
+
write-host "$(&hostname) :: Distributing files from $fileshare_dest..."
|
171
|
+
# remove files
|
172
|
+
$total = $remove_files.Keys.Count
|
173
|
+
$current = 0
|
174
|
+
foreach ( $g_path in $remove_files.Keys )
|
175
|
+
{
|
176
|
+
$current += 1
|
177
|
+
Write-progress -Activity "Cleaning redundant files" -PercentComplete $($current*100/$total) -Status "Cleaning under: $g_path"
|
178
|
+
foreach ($r_file in $remove_files[$g_path])
|
179
|
+
{
|
180
|
+
Remove-Item $($g_path+$r_file) -recurse -force -ErrorAction Ignore
|
181
|
+
}
|
182
|
+
}
|
183
|
+
$root_files_in_share = Get-ChildItem $fileshare_dest -Directory -ErrorAction Ignore
|
184
|
+
$total = $root_files_in_share.Count
|
185
|
+
$current = 0
|
186
|
+
#TODO: remove hard-code to SystemDrive
|
187
|
+
foreach ( $guest_path in $root_files_in_share )
|
188
|
+
{
|
189
|
+
$current += 1
|
190
|
+
Write-progress -Activity "Distributing files on the remote machine" -PercentComplete $($current*100/$total) -Status "Copying: $guest_path"
|
191
|
+
Copy-Item "$fileshare_dest\$guest_path" "$($env:SystemDrive)\" -recurse -force
|
192
|
+
}
|
193
|
+
}
|
194
|
+
|
195
|
+
|
196
|
+
Remove-PSSession -Id $session.Id
|
197
|
+
|
198
|
+
$resultHash = $folder_mappings
|
199
|
+
$result = ConvertTo-Json $resultHash
|
200
|
+
Write-Output-Message $result
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
# get either cached or entered in the prompt credentials
|
3
|
+
function Get-Creds($server_address, $prompt_message, $username = $null, $password = $null )
|
4
|
+
{
|
5
|
+
$temp_folder = $env:temp
|
6
|
+
# get creds
|
7
|
+
$cred_file = $temp_folder + "\creds_$server_address.clixml"
|
8
|
+
if ( Test-Path $cred_file )
|
9
|
+
{
|
10
|
+
$credential = Import-CliXml $cred_file
|
11
|
+
} else
|
12
|
+
{
|
13
|
+
if ( $username -ne $null -and $password -ne $null )
|
14
|
+
{
|
15
|
+
# creds passed, use them
|
16
|
+
$password = ConvertTo-SecureString -string $password -asPlainText -force
|
17
|
+
$credential = New-Object System.Management.Automation.PSCredential($username, $password)
|
18
|
+
} else
|
19
|
+
{
|
20
|
+
$credential = Get-Credential -Message $prompt_message
|
21
|
+
}
|
22
|
+
$credential | Export-CliXml $cred_file
|
23
|
+
Write-host "Credentials for $server_address is cached in $cred_file"
|
24
|
+
}
|
25
|
+
return $credential
|
26
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#
|
2
|
+
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
3
|
+
. ([System.IO.Path]::Combine($Dir, "manage_credentials.ps1"))
|
4
|
+
|
5
|
+
# execute script block for VMM
|
6
|
+
function execute($block, $vmm_server_address, $proxy_server_address)
|
7
|
+
{
|
8
|
+
$vmm_credential = Get-Creds $vmm_server_address "Credentials for VMM server: $vmm_server_address"
|
9
|
+
#
|
10
|
+
$init_vmm_block = {
|
11
|
+
try {
|
12
|
+
ipmo 'C:\Program Files\Microsoft System Center 2012 R2\Virtual Machine Manager\bin\psModules\virtualmachinemanager'
|
13
|
+
} catch {
|
14
|
+
write-error 'You need to install Virtual Machine Manager R2 client first.'
|
15
|
+
throw $_.Exception
|
16
|
+
}
|
17
|
+
#
|
18
|
+
$vmmServer = Get-VMMServer -ComputerName $using:vmm_server_address -Credential $using:vmm_credential
|
19
|
+
}
|
20
|
+
$block_to_run = [ScriptBlock]::Create($init_vmm_block.ToString() + $block.ToString())
|
21
|
+
#
|
22
|
+
if ( $proxy_server_address -eq $null )
|
23
|
+
{
|
24
|
+
$res = $(Start-Job $block_to_run | Wait-Job | Receive-Job)
|
25
|
+
} else {
|
26
|
+
$proxy_credential = Get-Creds $proxy_server_address "Credentials for proxy server: $proxy_server_address"
|
27
|
+
$res = invoke-command -ComputerName $proxy_server_address -Credential $proxy_credential -ScriptBlock $block_to_run
|
28
|
+
}
|
29
|
+
return $res
|
30
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#-------------------------------------------------------------------------
|
2
|
+
# Copyright (c) Microsoft Open Technologies, Inc.
|
3
|
+
# All Rights Reserved. Licensed under the MIT License.
|
4
|
+
#--------------------------------------------------------------------------
|
5
|
+
|
6
|
+
function Write-Error-Message($message) {
|
7
|
+
$error_message = @{
|
8
|
+
error = "$message"
|
9
|
+
}
|
10
|
+
Write-Host "===Begin-Error==="
|
11
|
+
$result = ConvertTo-json $error_message
|
12
|
+
Write-Host $result
|
13
|
+
Write-Host "===End-Error==="
|
14
|
+
}
|
15
|
+
|
16
|
+
function Write-Output-Message($message) {
|
17
|
+
Write-Host "===Begin-Output==="
|
18
|
+
Write-Host $message
|
19
|
+
Write-Host "===End-Output==="
|
20
|
+
}
|