Modules/businessdev.ALbuild.Containers/Private/Get-BcHostVolumeInfo.ps1
|
function Get-BcHostVolumeInfo { <# .SYNOPSIS What a path's volume is: file system, drive type, free space, and whether deduplication is on. .DESCRIPTION Docker's Windows storage driver ('windowsfilter') is particular about where it lives, and each requirement has a failure mode that only shows up much later: * NTFS. ReFS is not supported; layers fail to mount. * A fixed local disk. A network or removable path cannot host layers at all. * No Data Deduplication. Dedup on the Docker root rewrites layer files underneath the driver and corrupts images - the damage surfaces as containers that cannot be removed. Everything is best-effort and reported as $null when it cannot be determined, so a caller can distinguish "not NTFS" from "could not tell". Get-Volume and Get-DedupVolume are absent on some editions and inside containers, which must not turn into a hard failure. One function so callers have one thing to mock; the real cmdlets are never reached in tests. .PARAMETER Path The path whose volume is inspected. It need not exist yet - its root does. .OUTPUTS PSCustomObject with Drive, FileSystem, DriveType, FreeGb, TotalGb, DeduplicationEnabled. #> [CmdletBinding()] [OutputType([PSCustomObject])] param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $Path ) $result = [PSCustomObject]@{ Drive = $null FileSystem = $null DriveType = $null FreeGb = $null TotalGb = $null DeduplicationEnabled = $null } $root = $null try { $root = [System.IO.Path]::GetPathRoot($Path) } catch { } if ([string]::IsNullOrWhiteSpace($root)) { return $result } $result.Drive = $root # DriveInfo covers type and space on every edition, so it comes first and stands alone. try { $di = New-Object System.IO.DriveInfo($root) if ($di.IsReady) { $result.DriveType = "$($di.DriveType)" $result.FileSystem = "$($di.DriveFormat)" $result.FreeGb = [Math]::Round($di.AvailableFreeSpace / 1GB, 1) $result.TotalGb = [Math]::Round($di.TotalSize / 1GB, 1) } else { # Not ready is an answer, not an error: an empty removable drive lands here. $result.DriveType = "$($di.DriveType)" } } catch { Write-Verbose "Could not read volume information for '$root': $($_.Exception.Message)" } # Deduplication is a server feature; the cmdlet is missing on client editions, which is not an error. if (Get-Command -Name 'Get-DedupVolume' -ErrorAction SilentlyContinue) { try { $letter = "$root".TrimEnd('\', '/') $dedup = Get-DedupVolume -Volume $letter -ErrorAction Stop $result.DeduplicationEnabled = [bool]$dedup.Enabled } catch { # Get-DedupVolume throws when the volume simply is not enabled for dedup - which is the # answer we want, not a failure. $result.DeduplicationEnabled = $false } } return $result } |