Public/Set-PVEContainerVolume.ps1
|
function Set-PVEContainerVolume { <# .SYNOPSIS Grows LXC container volumes or changes their mount options. .DESCRIPTION -SizeGB grows the root file system or a mount point volume with PUT /nodes/{node}/lxc/{vmid}/resize. PVE does not shrink volumes, so a size below the current one is an error and nothing is sent; the current size is skipped with a warning. The other parameters rewrite the entry with PUT .../config, keeping every option not named. .PARAMETER VMId Container ID. Binds from piped PVEPS.ContainerVolume or PVEPS.Container objects. .PARAMETER VMName Container name(s). Wildcards allowed. .PARAMETER Device Volume(s) to change: rootfs or mpN. Binds from piped PVEPS.ContainerVolume objects. .PARAMETER SizeGB New size in GiB, larger than the current size. Fractions are allowed (the API accepts them). .PARAMETER Path New mount path inside the container (mount points only). .PARAMETER ReadOnly Whether the volume is mounted read-only. .PARAMETER Backup Whether the mount point is included in backups. .PARAMETER Parameter Further options by their API names; a $null value removes the option. .PARAMETER Server Connection(s) to use. Defaults to the default connection; binds from piped objects. .EXAMPLE Set-PVEContainerVolume -VMId 200 -Device rootfs -SizeGB 16 .EXAMPLE Get-PVEContainerVolume -VMId 200 -Device mp0 | Set-PVEContainerVolume -Backup $true #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '', Justification = 'ShouldProcess is called on this cmdlet through $PSCmdlet by Invoke-PVEGuestChange.')] [CmdletBinding(DefaultParameterSetName = 'Id', SupportsShouldProcess, ConfirmImpact = 'Medium')] [OutputType('PVEPS.ContainerVolume')] param( [Parameter(Mandatory, ParameterSetName = 'Id', ValueFromPipelineByPropertyName)] [ValidateRange(100, 999999999)] [int[]]$VMId, [Parameter(Mandatory, ParameterSetName = 'Name', Position = 0)] [SupportsWildcards()] [ValidateNotNullOrEmpty()] [string[]]$VMName, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string[]]$Device, [ValidateRange(0.001, [double]::MaxValue)] [double]$SizeGB, [ValidatePattern('^/')] [string]$Path, [bool]$ReadOnly, [bool]$Backup, [hashtable]$Parameter, [Parameter(ValueFromPipelineByPropertyName)] [Alias('Connection')] [object[]]$Server ) begin { $changes = [ordered]@{} if ($Path) { $changes.mp = $Path } if ($PSBoundParameters.ContainsKey('ReadOnly')) { $changes.ro = [int]$ReadOnly } if ($PSBoundParameters.ContainsKey('Backup')) { $changes.backup = [int]$Backup } if ($Parameter) { foreach ($key in $Parameter.Keys) { $changes[$key] = $Parameter[$key] } } $resize = $PSBoundParameters.ContainsKey('SizeGB') if (-not $resize -and $changes.Count -eq 0) { $PSCmdlet.ThrowTerminatingError((New-PVEArgumentError -Message 'No change given; specify -SizeGB or an option to change.' -Target $null)) } $targets = [System.Collections.Generic.List[psobject]]::new() } process { Add-PVEGuestTarget -Cmdlet $PSCmdlet -Target $targets -Server $Server -VMId $VMId -Name $VMName -Device $Device } end { foreach ($selection in @(Resolve-PVEDeviceTarget -Cmdlet $PSCmdlet -Type lxc -Target $targets -Kind ContainerVolume -Noun 'volume')) { $guest = $selection.Guest foreach ($volume in $selection.Devices) { $label = '{0} {1}' -f (Get-PVEGuestLabel -Guest $guest), $volume.Device if ($Path -and $volume.Device -eq 'rootfs') { $PSCmdlet.WriteError((New-PVEArgumentError -Message "$label is the root file system; its mount path is always /." -Target $volume)) continue } $changed = $false if ($resize) { if ($volume.IsBindMount) { $PSCmdlet.WriteError((New-PVEArgumentError -Message "$label is a bind mount of $($volume.Volume); it has no size to change." -Target $volume)) continue } if ($null -ne $volume.SizeGB -and $SizeGB -lt $volume.SizeGB) { $PSCmdlet.WriteError([System.Management.Automation.ErrorRecord]::new( [System.InvalidOperationException]::new("$label is $($volume.SizeGB) GiB; PVE cannot shrink a volume to $SizeGB GiB."), 'PVEShrinkNotSupported', [System.Management.Automation.ErrorCategory]::InvalidArgument, $volume)) continue } if ($null -ne $volume.SizeGB -and $SizeGB -eq $volume.SizeGB) { Write-Warning "$label is already $SizeGB GiB; skipped the resize." } else { $size = '{0}G' -f $SizeGB.ToString([cultureinfo]::InvariantCulture) $from = if ($null -ne $volume.SizeGB) { " from $($volume.SizeGB) GiB" } else { '' } $body = @{ disk = $volume.Device; size = $size } if (-not (Invoke-PVEGuestChange -Cmdlet $PSCmdlet -Guest $guest -Description "Grow volume $($volume.Device)$from to $SizeGB GiB" -Body $body -Endpoint resize)) { continue } $changed = $true } } if ($changes.Count -gt 0) { $action = 'Set volume {0} options: {1}' -f $volume.Device, (@($changes.Keys) -join ', ') if (Set-PVEGuestDeviceOption -Cmdlet $PSCmdlet -Guest $guest -Device $volume.Device -Kind ContainerVolume -Change $changes -Description $action) { $changed = $true } } if ($changed -or ($resize -and $changes.Count -eq 0)) { Write-PVEDeviceResult -Cmdlet $PSCmdlet -Guest $guest -Kind ContainerVolume -Device $volume.Device } } } } } |