Functions/Public/Merge-DockerImageLayer.ps1
function Merge-DockerImageLayer { [CmdletBinding()] param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $Registry, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $Name, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $BaseRepository, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string[]] $ParallelRepository ) $ErrorActionPreference = 'Stop' #region Target documents $TargetManifest = Get-DockerImageManifest -Registry $Registry -Repository $BaseRepository | ConvertFrom-Json $TargetConfig = Get-DockerImageBlob -Registry $Registry -Repository $BaseRepository -Digest $TargetManifest.config.digest | ConvertFrom-Json #endregion #region Patch layers 'Patching layers' $BaseManifest = Get-DockerImageManifest -Registry $Registry -Repository $BaseRepository | ConvertFrom-Json $BaseLayerCount = $BaseManifest.layers.Length foreach ($Repository in $ParallelRepository) { " from $Repository" $ParallelManifest = Get-DockerImageManifest -Registry $Registry -Repository $Repository | ConvertFrom-Json $ParallelLayers = $ParallelManifest.layers $TargetManifest.layers += $ParallelLayers[$BaseLayerCount,$ParallelLayers.Length] } #endregion #region Patch history 'Patching history' $BaseConfig = Get-DockerImageBlob -Registry $Registry -Repository $BaseRepository -Digest $BaseManifest.config.digest | ConvertFrom-Json $BaseHistoryCount = $BaseConfig.history.Length " base has $BaseHistoryCount entries" foreach ($Repository in $ParallelRepository) { " from $Repository" $ParallelManifest = Get-DockerImageManifest -Registry $Registry -Repository $Repository | ConvertFrom-Json $ParallelConfig = Get-DockerImageBlob -Registry $Registry -Repository $Repository -Digest $ParallelManifest.config.digest | ConvertFrom-Json $ParallelHistory = $ParallelConfig.history " with $($ParallelHistory.Length) entries" $HistoryEnd = $ParallelHistory.Length - 1 " appending $($ParallelHistory[$BaseHistoryCount..$HistoryEnd].Length) entries" $TargetConfig.history += $ParallelHistory[$BaseHistoryCount..$HistoryEnd] } #endregion #region Patch rootfs 'Patching rootfs' $BaseFsCount = $BaseConfig.rootfs.diff_ids.Length foreach ($Repository in $ParallelRepository) { " from $Repository" $ParallelManifest = Get-DockerImageManifest -Registry $Registry -Repository $Repository | ConvertFrom-Json $ParallelConfig = Get-DockerImageBlob -Registry $Registry -Repository $Repository -Digest $ParallelManifest.config.digest | ConvertFrom-Json $ParallelFs = $ParallelConfig.rootfs.diff_ids " with $($ParallelFs.Length) entries" $FsEnd = $ParallelFs.Length - 1 " appending $($ParallelFs[$BaseFsCount..$FsEnd].Length) entries" $TargetConfig.rootfs.diff_ids += $ParallelFs[$BaseFsCount..$FsEnd] } #endregion #region Mount layers 'Mounting layers' foreach ($Repository in $ParallelRepository) { " from $Repository" $Manifest = Get-DockerImageManifest -Registry $Registry -Repository $Repository | ConvertFrom-Json foreach ($Layer in $Manifest.layers) { Add-DockerImageLayer -Registry $Registry -Repository $Name -Digest $Layer.digest -SourceRepository $Repository } } #endregion #region Upload config 'Uploading config' $TargetConfigRaw = $TargetConfig | ConvertTo-Json -Depth 10 New-DockerImageBlob -Registry $Registry -Repository $Name -Data $TargetConfigRaw -ContentType 'application/vnd.docker.container.image.v1+json' #endregion #region Build manifest 'Uploading manifest' $TargetManifest.config.size = $TargetConfigRaw.Length $ConfigDigest = Get-StringHash -Algorithm SHA256 -Encoding ASCII -Data (ConvertTo-ByteArray -Encoding ASCII -Data $TargetConfigRaw) $TargetManifest.config.digest = "sha256:$ConfigDigest" $TargetManifestRaw = $TargetManifest | ConvertTo-Json -Depth 10 New-DockerImageManifest -Registry $Registry -Repository $Name -Manifest $TargetManifestRaw -ManifestVersion v2 #endregion } |