Skip to content

Commit 1444b87

Browse files
committed
0.7
create/destroy-vmfleet & update-csv: don't rely on the csv name containing the friendlyname of the vd create-vmfleet: err if basevhd inaccessible create-vmfleet: simplify call-throughs using $using: syntax create-vmfleet: change vhdx layout to match scvmm behavior of seperate directory per VM (important for ReFS MRV) create-vmfleet: use A1 VM size by default (1VCPU 1.75GiB RAM) start-vmfleet: try starting "failed" vms, usually works set-vmfleet: add support for -SizeSpec <Azure Size Specs> for A/D/D2v1 & v2 size specification, for ease of reconfig stop-vmfleet: pass in full namelist to allow best-case internal parallelization of shutdown sweep-cputarget: use %Processor Performance to rescale utilization and account for Turbo effects test-clusterhealth: support cleaning out dumps/triage material to simplify ongoing monitoring (assume they're already gathered/etc.) test-clusterhealth: additional triage output for storport unresponsive device events test-clusterhealth: additional triage comments on SMB client connectivity events test-clusterhealth: new test for Mellanox CX3/CX4 error counters that diagnose fabric issues (bad cable/transceiver/roce specifics/etc.) get-log: new triage log gatherer for all hv/clustering/smb event channels get-cluspc: new cross-cluster performance counter gatherer remove run-*.ps1 scripts that were replaced with run-demo-*.ps1 check-outlier: EXPERIMENTAL way to ferret out outlier devices in the cluster, using average sampled latency
1 parent 88071d9 commit 1444b87

11 files changed

+413
-108
lines changed

Frameworks/VMFleet/create-vmfleet.ps1

Lines changed: 57 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,17 @@ SOFTWARE.
2626
#>
2727

2828
param(
29-
[string]$basevhd = $(throw "please specify a base vhd"),
30-
[int]$vms = $(throw "please specify a number of vms per node csv"),
31-
[string[]]$groups = @(),
32-
[string]$adminpass = $(throw "need admin password for autologin"),
33-
[string]$admin = 'administrator',
34-
[string]$connectpass = $(throw "need password for loopback host connection"),
35-
[string]$connectuser = $(throw "need username for loopback host connection"),
36-
[validateset("CreateVMSwitch","CopyVHD","CreateVM","CreateVMGroup","AssertComplete")][string]$stopafter,
37-
[validateset("Force","Auto","None")][string]$specialize = "Auto",
38-
[switch]$fixedvhd = $true,
39-
[string[]]$nodes = @()
29+
[string]$BaseVHD = $(throw "please specify a base vhd"),
30+
[int]$VMs = $(throw "please specify a number of vms per node csv"),
31+
[string[]]$Groups = @(),
32+
[string]$AdminPass = $(throw 'need admin password for autologin'),
33+
[string]$Admin = 'administrator',
34+
[string]$ConnectPass = $(throw 'need password for loopback host connection'),
35+
[string]$ConnectUser = $(throw 'need username for loopback host connection'),
36+
[validateset('CreateVMSwitch','CopyVHD','CreateVM','CreateVMGroup','AssertComplete')][string]$StopAfter,
37+
[validateset('Force','Auto','None')][string]$Specialize = 'Auto',
38+
[switch]$FixedVHD = $true,
39+
[string[]]$Nodes = @()
4040
)
4141

4242
function Stop-After($step)
@@ -48,6 +48,13 @@ function Stop-After($step)
4848
return $false
4949
}
5050

51+
##################
52+
53+
# validate existence of basevhd
54+
if (!(test-path -path $BaseVHD)) {
55+
throw "Base VHD $BaseVHD not found"
56+
}
57+
5158
if (Get-ClusterNode |? State -ne Up) {
5259
throw "not all cluster nodes are up; please address before creating vmfleet"
5360
}
@@ -97,17 +104,9 @@ if (Stop-After "CreateVMSwitch") {
97104
# create $vms vms per each csv named as <nodename><group prefix>
98105
# vm name is vm-<group prefix><$group>-<hostname>-<number>
99106

100-
icm $nodes -ArgumentList $basevhd,$vms,$groups,$admin,$adminpass,$connectpass,$connectuser,$stopafter,$specialize,(Get-Command Stop-After) {
101-
102-
param( [string[]]$basevhd,
103-
[int]$vms,
104-
[string[]]$groups,
105-
[string]$admin,
106-
[string]$adminpass,
107-
[string]$connectpass,
108-
[string]$connectuser,
109-
[string]$stopafter,
110-
[string]$specialize,
107+
icm $nodes -ArgumentList $stopafter,(Get-Command Stop-After) {
108+
109+
param( [string]$stopafter,
111110
$fn )
112111

113112
set-item -Path function:\$($fn.name) -Value $fn.definition
@@ -134,9 +133,9 @@ icm $nodes -ArgumentList $basevhd,$vms,$groups,$admin,$adminpass,$connectpass,$c
134133
# autologon
135134
$null = reg load 'HKLM\tmp' z:\windows\system32\config\software
136135
$ok = $ok -band $?
137-
$null = reg add 'HKLM\tmp\Microsoft\Windows NT\CurrentVersion\WinLogon' /f /v DefaultUserName /t REG_SZ /d $admin
136+
$null = reg add 'HKLM\tmp\Microsoft\Windows NT\CurrentVersion\WinLogon' /f /v DefaultUserName /t REG_SZ /d $using:admin
138137
$ok = $ok -band $?
139-
$null = reg add 'HKLM\tmp\Microsoft\Windows NT\CurrentVersion\WinLogon' /f /v DefaultPassword /t REG_SZ /d $adminpass
138+
$null = reg add 'HKLM\tmp\Microsoft\Windows NT\CurrentVersion\WinLogon' /f /v DefaultPassword /t REG_SZ /d $using:adminpass
140139
$ok = $ok -band $?
141140
$null = reg add 'HKLM\tmp\Microsoft\Windows NT\CurrentVersion\WinLogon' /f /v AutoAdminLogon /t REG_DWORD /d 1
142141
$ok = $ok -band $?
@@ -161,7 +160,7 @@ icm $nodes -ArgumentList $basevhd,$vms,$groups,$admin,$adminpass,$connectpass,$c
161160
}
162161

163162
del -Force z:\users\administrator\launch.ps1 -ErrorAction SilentlyContinue
164-
gc C:\ClusterStorage\collect\control\launch-template.ps1 |% { $_ -replace '__CONNECTUSER__',$connectuser -replace '__CONNECTPASS__',$connectpass } > z:\users\administrator\launch.ps1
163+
gc C:\ClusterStorage\collect\control\launch-template.ps1 |% { $_ -replace '__CONNECTUSER__',$using:connectuser -replace '__CONNECTPASS__',$using:connectpass } > z:\users\administrator\launch.ps1
165164
$ok = $ok -band $?
166165
if (-not $ok) {
167166
Write-Error "failed injection of launch.ps1 for $vhdpath"
@@ -213,32 +212,52 @@ icm $nodes -ArgumentList $basevhd,$vms,$groups,$admin,$adminpass,$connectpass,$c
213212
return $ok
214213
}
215214

216-
foreach ($csv in get-clustersharedvolume) {
215+
$csvs = Get-ClusterSharedVolume
216+
217+
# handle restore cases by mapping the csv to the friendly name of the volume
218+
# don't rely on the csv name to contain this data
219+
220+
$vh = @{}
221+
Get-Volume |? FileSystem -eq CSVFS |% { $vh[$_.Path] = $_ }
222+
223+
$csvs |% {
224+
$v = $vh[$_.SharedVolumeInfo.Partition.Name]
225+
if ($v -ne $null) {
226+
$_ | Add-Member -NotePropertyName VDName -NotePropertyValue $v.FileSystemLabel
227+
}
228+
}
229+
230+
foreach ($csv in $csvs) {
217231

218-
if ($groups.Length -eq 0) {
232+
if ($($using:groups).Length -eq 0) {
219233
$groups = @( 'base' )
234+
} else {
235+
$groups = $using:groups
220236
}
221237

222238
# identify the CSvs for which this node should create its VMs
223239
# the trailing characters (if any) are the group prefix
224-
if ($csv.Name -match "\(($env:COMPUTERNAME)") {
240+
if ($csv.VDName -match "^$env:COMPUTERNAME(?:-.+){0,1}") {
225241

226242
foreach ($group in $groups) {
227243

228-
if ($csv.Name -match "\(($env:COMPUTERNAME)-([^-]+)?\)") {
229-
$g = $group+$matches[2]
244+
if ($csv.VDName -match "^$env:COMPUTERNAME-([^-]+)$") {
245+
$g = $group+$matches[1]
230246
} else {
231247
$g = $group
232248
}
233249

234-
foreach ($vm in 1..$vms) {
250+
foreach ($vm in 1..$using:vms) {
235251

236252
$stop = $false
237253

238254
$newvm = $false
239255
$name = "vm-$g-$env:COMPUTERNAME-$vm"
240256
$path = Join-Path $csv.SharedVolumeInfo.FriendlyVolumeName $name
241-
$vhd = $path+".vhdx"
257+
258+
# place vhdx in subdirectory, per scvmm layout defaults
259+
# $vhd = $path+".vhdx"
260+
$vhd = join-path $path "$name.vhdx"
242261

243262
# if the vm cluster group exists, we are already deployed
244263
if (-not (Get-ClusterGroup -Name $name -ErrorAction SilentlyContinue)) {
@@ -267,7 +286,7 @@ icm $nodes -ArgumentList $basevhd,$vms,$groups,$admin,$adminpass,$connectpass,$c
267286
$null = mkdir -ErrorAction SilentlyContinue $path
268287

269288
if (-not (gi $vhd -ErrorAction SilentlyContinue)) {
270-
cp $basevhd $vhd
289+
cp $using:basevhd $vhd
271290
} else {
272291
write-host "vm vhd $vhd already exists"
273292
}
@@ -280,6 +299,9 @@ icm $nodes -ArgumentList $basevhd,$vms,$groups,$admin,$adminpass,$connectpass,$c
280299
if (-not $stop) {
281300
$o = new-vm -VHDPath $vhd -Generation 2 -SwitchName Internal -Path $path -Name $name
282301

302+
# create A1 VM. use set-vmfleet to alter fleet sizing post-creation.
303+
$o | set-vm -ProcessorCount 1 -MemoryStartupBytes 1.75GB -StaticMemory
304+
283305
# do not monitor the internal switch connection; this allows live migration
284306
$o | Get-VMNetworkAdapter| Set-VMNetworkAdapter -NotMonitoredInCluster $true
285307
}
@@ -307,10 +329,10 @@ icm $nodes -ArgumentList $basevhd,$vms,$groups,$admin,$adminpass,$connectpass,$c
307329
$stop = Stop-After "CreateVMGroup"
308330
}
309331

310-
if (-not $stop -or ($specialize -eq 'Force')) {
332+
if (-not $stop -or ($using:specialize -eq 'Force')) {
311333
# specialize as needed
312334
# auto only specializes new vms; force always; none skips it
313-
if (($specialize -eq 'Auto' -and $newvm) -or ($specialize -eq 'Force')) {
335+
if (($using:specialize -eq 'Auto' -and $newvm) -or ($using:specialize -eq 'Force')) {
314336
write-host -fore yellow specialize $vhd
315337
if (-not (specialize-vhd $vhd)) {
316338
write-host -fore red "Failed specialize of $vhd, halting."

Frameworks/VMFleet/destroy-vmfleet.ps1

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,22 @@ icm (Get-ClusterNode) {
3636

3737
# delete all vm content from csv
3838
$csv = Get-ClusterSharedVolume
39+
40+
# handle restore cases by mapping the csv to the friendly name of the volume
41+
# don't rely on the csv name to contain this data
42+
43+
$vh = @{}
44+
Get-Volume |? FileSystem -eq CSVFS |% { $vh[$_.Path] = $_ }
45+
46+
$csv |% {
47+
$v = $vh[$_.SharedVolumeInfo.Partition.Name]
48+
if ($v -ne $null) {
49+
$_ | Add-Member -NotePropertyName VDName -NotePropertyValue $v.FileSystemLabel
50+
}
51+
}
52+
3953
Get-ClusterNode |% {
40-
$csv |? Name -match "\($($_.Name)(-.+)?"
54+
$csv |? VDName -match "$($_.Name)(-.+)?"
4155
} |% {
4256

4357
del -Recurse -Force "$($_.sharedvolumeinfo.friendlyvolumename)\vm*"

Frameworks/VMFleet/s2d-vmfleet.docx

1.72 KB
Binary file not shown.

Frameworks/VMFleet/s2d-vmfleet.pdf

172 KB
Binary file not shown.

Frameworks/VMFleet/set-vmfleet.ps1

Lines changed: 118 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -25,42 +25,133 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2525
SOFTWARE.
2626
#>
2727

28-
param( [int] $ProcessorCount,
29-
[int64] $MemoryStartupBytes,
30-
[int64] $MemoryMaximumBytes = 0,
31-
[int64] $MemoryMinimumBytes = 0,
32-
[switch]$DynamicMemory = $true )
33-
34-
if ($MemoryMaximumBytes -eq 0) {
35-
$MemoryMaximumBytes = $MemoryStartupBytes
36-
}
37-
if ($MemoryMinimumBytes -eq 0) {
38-
$MemoryMinimumBytes = $MemoryStartupBytes
28+
param( [Parameter(ParameterSetName = 'FullSpec', Mandatory = $true)]
29+
[int] $ProcessorCount,
30+
[Parameter(ParameterSetName = 'FullSpec', Mandatory = $true)]
31+
[int64] $MemoryStartupBytes,
32+
[Parameter(ParameterSetName = 'FullSpec')]
33+
[int64] $MemoryMaximumBytes = 0,
34+
[Parameter(ParameterSetName = 'FullSpec')]
35+
[int64] $MemoryMinimumBytes = 0,
36+
[Parameter(ParameterSetName = 'FullSpec')]
37+
[switch]$DynamicMemory = $true,
38+
[Parameter(ParameterSetName = 'SizeSpec', Mandatory = $true)]
39+
[ValidateSet('A0','A1','A1v2','A2','A2mv2','A2v2','A3','A4','A4mv2','A4v2','A5','A6','A7','A8mv2','A8v2','D1','D11','D11v2','D12','D12v2','D13','D13v2','D14','D14v2','D1
40+
5v2','D1v2','D2','D2v2','D3','D3v2','D4','D4v2','D5v2','DS11','DS11v2','DS12','DS12v2','DS13','DS13v2','DS14','DS14v2','DS15v2')]
41+
[string]$Compute = 'A1'
42+
)
43+
44+
# to regenerate validateset
45+
# ($vmsize.keys | sort |% { "'$_'" }) -join ','
46+
47+
# c = compute cores
48+
# m = memory
49+
# a = alias for another (ex: d -> ds, d -> dv2)
50+
# note that alias is only chased once
51+
52+
$vmsize = @{
53+
54+
# general purpose table
55+
'A0' = @{ 'c' = 1; 'm' = 0.75GB; };
56+
'A1' = @{ 'c' = 1; 'm' = 1.75GB; };
57+
'A2' = @{ 'c' = 2; 'm' = 3.5GB; };
58+
'A3' = @{ 'c' = 4; 'm' = 7GB; };
59+
'A4' = @{ 'c' = 8; 'm' = 14GB; };
60+
'A5' = @{ 'c' = 2; 'm' = 14GB };
61+
'A6' = @{ 'c' = 4; 'm' = 28GB };
62+
'A7' = @{ 'c' = 8; 'm' = 56GB };
63+
64+
'A1v2' = @{ 'c' = 1; 'm' = 2GB; };
65+
'A2v2' = @{ 'c' = 2; 'm' = 4GB; };
66+
'A4v2' = @{ 'c' = 4; 'm' = 8GB; };
67+
'A8v2' = @{ 'c' = 8; 'm' = 16GB; };
68+
'A2mv2' = @{ 'c' = 2; 'm' = 16GB; }
69+
'A4mv2' = @{ 'c' = 4; 'm' = 32GB; };
70+
'A8mv2' = @{ 'c' = 8; 'm' = 64GB; };
71+
72+
'D1' = @{ 'c' = 1; 'm' = 3.5GB };
73+
'D2' = @{ 'c' = 2; 'm' = 7GB };
74+
'D3' = @{ 'c' = 4; 'm' = 14GB };
75+
'D4' = @{ 'c' = 8; 'm' = 28GB };
76+
77+
'D1v2' = @{ 'a' = 'D1' }
78+
'D2v2' = @{ 'a' = 'D2' }
79+
'D3v2' = @{ 'a' = 'D3' }
80+
'D4v2' = @{ 'a' = 'D4' }
81+
'D5v2' = @{ 'c' = 16; 'm' = 56GB };
82+
83+
# memory optimized table (just the d's)
84+
'D11' = @{ 'c' = 2; 'm' = 14GB };
85+
'D12' = @{ 'c' = 4; 'm' = 28GB };
86+
'D13' = @{ 'c' = 8; 'm' = 56GB };
87+
'D14' = @{ 'c' = 16; 'm' = 112GB };
88+
89+
'DS11' = @{ 'a' = 'D11' };
90+
'DS12' = @{ 'a' = 'D12' };
91+
'DS13' = @{ 'a' = 'D13' };
92+
'DS14' = @{ 'a' = 'D14' };
93+
94+
'D11v2' = @{ 'a' = 'D11' };
95+
'D12v2' = @{ 'a' = 'D12' };
96+
'D13v2' = @{ 'a' = 'D13' };
97+
'D14v2' = @{ 'a' = 'D14' };
98+
'D15v2' = @{ 'c' = 20; 'm' = 140GB };
99+
100+
'DS11v2' = @{ 'a' = 'D11v2' };
101+
'DS12v2' = @{ 'a' = 'D12v2' };
102+
'DS13v2' = @{ 'a' = 'D13v2' };
103+
'DS14v2' = @{ 'a' = 'D14v2' };
104+
'DS15v2' = @{ 'a' = 'D15v2' };
39105
}
40106

41107
$g = Get-ClusterGroup |? GroupType -eq VirtualMachine | group -Property OwnerNode -NoElement
42108

43-
icm ($g.Name) -ArgumentList $ProcessorCount,$MemoryStartupBytes,$MemoryMaximumBytes,$MemoryMinimumBytes,$DynamicMemory {
109+
icm $g.Name {
44110

45-
param( [int] $ProcessorCount,
46-
[int64] $MemoryStartupBytes,
47-
[int64] $MemoryMaximumBytes,
48-
[int64] $MemoryMinimumBytes,
49-
[boolean]$DynamicMemory )
111+
# import vmsize hash (cannot $using[$using])
112+
$vmsize = $using:vmsize
50113

51114
Get-ClusterGroup |? GroupType -eq VirtualMachine |? OwnerNode -eq $env:COMPUTERNAME |% {
52115

53-
$memswitch = '-StaticMemory'
54-
$dynamicMemArg = ""
55-
if ($DynamicMemory) {
56-
$memswitch = '-DynamicMemory'
57-
$dynamicMemArg += "-MemoryMinimumBytes $MemoryMinimumBytes -MemoryMaximumBytes $MemoryMaximumBytes"
58-
}
116+
$g = $_
117+
118+
switch ($using:PSCmdlet.ParameterSetName) {
119+
120+
'FullSpec' {
121+
122+
if ($using:MemoryMaximumBytes -eq 0) {
123+
$MemoryMaximumBytes = $MemoryStartupBytes
124+
} else {
125+
$MemoryMaximumBytes = $using:MemoryMaximumBytes
126+
}
127+
if ($using:MemoryMinimumBytes -eq 0) {
128+
$MemoryMinimumBytes = $MemoryStartupBytes
129+
} else {
130+
$MemoryMinimumBytes = $using:MemoryMinimumBytes
131+
}
132+
133+
$memswitch = '-StaticMemory'
134+
$dynamicMemArg = ""
135+
if ($using:DynamicMemory) {
136+
$memswitch = '-DynamicMemory'
137+
$dynamicMemArg += "-MemoryMinimumBytes $MemoryMinimumBytes -MemoryMaximumBytes $MemoryMaximumBytes"
138+
}
139+
140+
if ($g.State -ne 'Offline') {
141+
write-host -ForegroundColor Yellow Cannot alter VM sizing on running VMs "($($_.Name))"
142+
} else {
143+
iex "Set-VM -ComputerName $($g.OwnerNode) -Name $($g.Name) -ProcessorCount $using:ProcessorCount -MemoryStartupBytes $using:MemoryStartupBytes $dynamicMemArg $memswitch"
144+
}
145+
}
146+
147+
'SizeSpec' {
148+
$a = $vmsize[$using:compute].a
149+
if ($a -eq $null) {
150+
$a = $using:compute
151+
}
59152

60-
if ($_.State -ne 'Offline') {
61-
write-host -ForegroundColor Yellow Cannot alter VM sizing on running VMs "($($_.Name))"
62-
} else {
63-
iex "Set-VM -ComputerName $($_.OwnerNode) -Name $($_.Name) -ProcessorCount $ProcessorCount -MemoryStartupBytes $MemoryStartupBytes $dynamicMemArg $memswitch"
153+
Set-VM -ComputerName $($g.OwnerNode) -Name $($g.Name) -ProcessorCount $vmsize[$a].c -MemoryStartupBytes $vmsize[$a].m -StaticMemory
154+
}
64155
}
65156
}
66157
}

Frameworks/VMFleet/start-vmfleet.ps1

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,11 @@ param([string[]]$group = "*")
3030
icm (get-clusternode |? State -eq Up) -arg $group {
3131
param([string[]]$group)
3232

33+
# failed is an unclean offline tbd root causes (can usually be recovered)
34+
3335
$group |% {
34-
Get-ClusterGroup |? GroupType -eq VirtualMachine |? Name -like "vm-$_-$env:COMPUTERNAME-*" |? State -eq 'Offline' |
35-
Start-ClusterGroup
36+
Get-ClusterGroup |? OwnerNode -eq $env:COMPUTERNAME |? GroupType -eq VirtualMachine |? Name -like "vm-$_-*" |? {
37+
$_.State -eq 'Offline' -or $_.State -eq 'Failed'
38+
} | Start-ClusterGroup
3639
}
3740
} | ft -AutoSize

0 commit comments

Comments
 (0)