Modules/businessdev.ALbuild.Containers/Private/Get-BcHostFreeDiskGb.ps1
|
function Get-BcHostFreeDiskGb { <# .SYNOPSIS Free/total space (GB) on the drive Docker stores containers on - for the container disk preflight and failure diagnostics. .DESCRIPTION A Business Central container copies the service tier, web client and apps into its writable layer and restores the demo database - many GB - on the drive that holds Docker's data-root. On a nearly-full drive the service tier cannot start and the container exits with a cryptic "Failed to start service" after a long wait. This resolves that drive via 'docker info' (DockerRootDir), falling back to the system drive when it cannot be read, and returns its free and total GiB. Returns $null only when no drive/space could be determined (so callers skip the check rather than block on a false negative). .PARAMETER DockerExecutable The Docker executable to query (default 'docker'). .OUTPUTS PSCustomObject { Drive; FreeGb; TotalGb } or $null. #> [CmdletBinding()] [OutputType([PSCustomObject])] param([string] $DockerExecutable = 'docker') $rootDir = $null try { $info = Invoke-BcDocker -DockerExecutable $DockerExecutable -Quiet -PassThru -Arguments @('info', '--format', '{{.DockerRootDir}}') if ($info.Success) { $rootDir = "$($info.StdOut)".Trim() } } catch { Write-Verbose "Could not read Docker's data-root directory: $($_.Exception.Message)" } # Fall back to the system drive; Docker's data-root is on it by default anyway. $probe = if (-not [string]::IsNullOrWhiteSpace($rootDir)) { $rootDir } else { ([System.Environment]::GetEnvironmentVariable('SystemDrive') + '\') } try { $driveRoot = [System.IO.Path]::GetPathRoot($probe) if ([string]::IsNullOrWhiteSpace($driveRoot)) { return $null } $di = New-Object System.IO.DriveInfo($driveRoot) if (-not $di.IsReady) { return $null } return [PSCustomObject]@{ Drive = $di.Name FreeGb = [math]::Round($di.AvailableFreeSpace / 1GB, 1) TotalGb = [math]::Round($di.TotalSize / 1GB, 1) } } catch { Write-Verbose "Could not read free disk space for '$probe': $($_.Exception.Message)"; return $null } } function Get-BcLowDiskHint { <# .SYNOPSIS Returns an actionable "low disk space" hint string when the Docker drive is below a threshold, else an empty string. Appended to container-readiness failure messages so the true cause (a full drive, which makes the BC service tier fail to start) is visible instead of a bare "Failed to start service". .PARAMETER DockerExecutable The Docker executable to query (default 'docker'). .PARAMETER ThresholdGb Emit the hint when free space is below this many GB. Default 20. .OUTPUTS System.String - the hint (with a leading newline) or ''. #> [CmdletBinding()] [OutputType([string])] param( [string] $DockerExecutable = 'docker', [int] $ThresholdGb = 20 ) $disk = Get-BcHostFreeDiskGb -DockerExecutable $DockerExecutable if ($disk -and $disk.FreeGb -lt $ThresholdGb) { return "$([Environment]::NewLine)Likely cause: low disk space - only $($disk.FreeGb) GB free on drive $($disk.Drive). A BC container needs well over that to restore its database and start the service tier. Free space on that drive (e.g. 'docker system prune -a --volumes', remove old BC versions under the artifact cache) or move Docker's data-root / the artifact cache to a larger drive." } return '' } |