public/Add-PulpContentUnit.ps1
# .ExternalHelp powershell-pulp-help.xml Function Add-PulpContentUnit { [Cmdletbinding(DefaultParameterSetName='StringsPath')] Param( [Parameter(Mandatory=$false)] [string]$Server = (Get-PulpLocalConfig -Server).Server, [Parameter(Mandatory=$false)] [int]$Port = (Get-PulpLocalConfig -Port).Port, [Parameter(Mandatory=$false)] [string]$Protocol = (Get-PulpLocalConfig -Protocol).Protocol, [Parameter(Mandatory=$false)] [string]$AuthenticationMethod = (Get-PulpLocalConfig -AuthenticationMethod).AuthenticationMethod, [Parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName="ObjectsPath")] [Parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName="ObjectsUrl")] [PSCustomObject[]]$TargetRepo, [Parameter(Mandatory=$true, Position=1, ValueFromPipeline=$true, ParameterSetName="StringsPath")] [Parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName="StringsUrl")] [string[]]$TargetRepoId, [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$false, ParameterSetName="ObjectsPath")] [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$false, ParameterSetName="StringsPath")] [string[]]$Path, [Parameter(Mandatory=$true, ValueFromPipeline=$false, ParameterSetName="ObjectsUrl")] [Parameter(Mandatory=$true, ValueFromPipeline=$false, ParameterSetName="StringsUrl")] [string]$Url, [Parameter(Mandatory=$false)] [switch]$NoPublish, [Parameter(Mandatory=$true)] [string]$Type ) Begin { If ($Type -eq 'puppet'){ $unitType = 'puppet_module' } Else { $unitType = $Type } # Do downloads If ($Url) { $null = New-Item -Type Directory -Force "$ENV:TMP\powershell-pulp" $DownloadPath = "$ENV:TMP\powershell-pulp\" + (Split-Path -Path $Url -Leaf) Invoke-WebRequest -Uri $Url -OutFile $DownloadPath } # Upload each file and record uploadId, fileName, fileSize in array of # hashes for later use $uploadHashes = @() if ($DownloadPath) { $files = Get-ChildItem $DownloadPath } else { $files = Get-ChildItem $Path } foreach ($file in $files) { # Get upload id $uri = "/pulp/api/v2/content/uploads/" $response = Invoke-PulpRestMethod -Server $Server -Port $Port ` -Protocol $Protocol ` -AuthenticationMethod $AuthenticationMethod -Uri $uri ` -Method Post $uploadId = $response.upload_id $uploadRef = $response._href # Upload file (in chunks if bigger than 1MB) $fileName = [string]$file $shortFileName = Split-Path $fileName -leaf -resolve $chunkSize=1048576 $fileSize = (get-item $fileName).length $uploadHashes += ,@{'uploadId' = $uploadId; 'fileName' = $fileName; 'shortFileName' = $shortFileName; 'fileSize' = $fileSize} # If big file, upload in chunks appending offset to URL if ($fileSize -gt $chunksize) { $uri = $uploadRef #+ "0/" $fileStream = [System.IO.File]::OpenRead($file) $chunk = New-Object byte[] $chunkSize $offset = 0 while( $bytesRead = $fileStream.Read($chunk,0,$chunkSize) ){ $thisUpload = New-Object byte[] $bytesRead $thisUpload = [byte[]]($chunk[0..($bytesRead - 1)]) $progressPreference = 'silentlyContinue' $response = Invoke-PulpRestMethod -Server $Server -Port $Port ` -Protocol $Protocol ` -AuthenticationMethod $AuthenticationMethod ` -Uri "${uri}${offset}/" -Method Put ` -ContentType "application/data" -Body $thisUpload $progressPreference = 'Continue' $offset += $chunkSize if (($offset / $fileSize*100) -le 100){ $percentComplete = ($offset / $fileSize*100) } else { $percentComplete = 100 } Write-Progress -Activity ` "Uploading ${shortFileName} to ${Server}" ` -status "Uploaded $offset bytes" ` -percentComplete $percentComplete } $fileStream.Close() # If small file upload the whole thing in one go } else { $uri = $uploadRef + "0/" $response = Invoke-PulpRestMethod -Server $Server -Port $Port ` -Protocol $Protocol ` -AuthenticationMethod $AuthenticationMethod -Uri $uri ` -InFile $fileName -Method Put } } $pipelineCount = 0 $firstRepoId = '' } Process { If ($TargetRepo) { # Object-based parameter $TargetRepoId = $TargetRepo | Select-Object -ExpandProperty id } elseif ($_) { #else { $TargetRepoId = $_ } $repos = Get-PulpRepo -Server $Server -Port $Port -Protocol $Protocol ` -AuthenticationMethod $AuthenticationMethod -Id $TargetRepoId ` -Type $Type # Import/copy each file into each repo using uploadhashes recorded earlier $repocount = 0 foreach ($repoObject in $repos) { $addId = $repoObject.id foreach ($uploadHash in $uploadHashes) { $uploadId = $uploadHash.uploadId $fileName = $uploadHash.fileName $shortFileName = $uploadHash.shortFileName $fileSize = $uploadHash.fileSize # If this is the first repo we import using upload ID... if (($repocount -eq 0) -and ($pipelineCount -eq 0)) { $firstRepoId = $addId # Metadata for RPM upload if ($unitType -eq 'rpm') { $unitKey = '{}' $unitMetaData = '{}' } # Metadata for Puppet module upload elseif ($unitType -eq 'puppet_module') { $unitKey = '{}' $unitMetaData = '{}' } # Metadata for other uploads (inc ISO) else { $checksum = ((Get-FileHash -Path $fileName ` -Algorithm SHA256).Hash).ToLower() $unitKey = '{"checksum": "' + $checksum + '", "name": "' + $shortFileName + '", "size": ' + $fileSize + '}' $unitMetaData = '{}' } $uri = "/pulp/api/v2/repositories/${addId}/actions/import_upload/" $body = '{"override_config": {}, "unit_type_id": "' + $unitType +'", ' + '"upload_id": "' + $uploadId + '", "unit_key": ' + $unitKey + ', "unit_metadata": '+ $unitMetadata +'}' Invoke-PulpRestMethod -Server $Server -Port $Port ` -Protocol $Protocol ` -AuthenticationMethod $AuthenticationMethod ` -Uri $uri -Body $body -Method Post Start-Sleep -s 5 } # ...otherwise we copy from the first repo else { # Horrible hack to get puppet module name from file name If ($unitType -eq 'puppet_module') { $splitName = ($shortFileName -Split '.') $shortFileName = $split[0..($split.Length-3)] -join '.' } Get-PulpContentUnit -Server $Server -Port $Port -Protocol $Protocol ` -AuthenticationMethod $AuthenticationMethod ` -RepoId $firstRepoId -Name $shortFileName ` -Type $Type | Copy-PulpContentUnit -Server $Server -Port $Port -Protocol $Protocol ` -AuthenticationMethod $AuthenticationMethod ` -TargetRepoId $addId -Type $Type } } # Publish changes If (!$NoPublish) { Publish-PulpRepo -Server $Server -Port $Port -Protocol $Protocol ` -AuthenticationMethod $AuthenticationMethod ` -Id $addId -Type $Type } $repocount += 1 } $pipelineCount += 1 } End { # Delete downloaded file If ($DownloadPath) { Remove-Item -Recurse -Force $DownloadPath } } } |