Welcome to the Inedo Forums! Check out the Forums Guide for help getting started.
If you are experiencing any issues with the forum software, please visit the Contact Form on our website and let us know!
API to apply an Alternate Tag to Docker Container Image
-
My Docker container images flow goes like this:
- Devs create the image with a Version Number like this: 1.5.0-build.62
- Ops promotes the image to Test (using Octopus Deploy calling the Proget Package Promotion API)
As part of the second step, I want set the container image to a release version. So in my example above, it would get the alternate tag of 1.5.0.
But I need to have this done when Ops promotes the release to Test in Octopus Deploy. I have not been able to find documentation on how to apply an alternate tag to a docker container image via API (It is very clear how to do it via the UI). I considered using the Repackage API for it, but the UI does not offer Repackage for Docker container images, so I assume the API is also not setup for it.
How can I apply an alternate tag to a container image via an API?
-
I found a way to do this by downloading the image manifest and then uploading it again as a different tag.
Here is the PowerShell function that does both the promotion and the tagging (incase anyone ever needs something like this). Kind of a "do it yourself" repackaging. (Might be nice to have the Repackaging API support Docker container images someday).
function RepackageContainerImage() { param ( [string] $packageName = $(throw "-packageName is required. This is the namespace/image-name"), [string] $fromFeed = $(throw "-fromFeed is required"), [string] $toFeed = $(throw "-toFeed is required"), [string] $fromVersion = $(throw "-fromVersion is required. This is the current tag on the image in the fromFeed."), [string] $toVersion = $(throw "-toVersion is required. This is the tag to be applied after the image is promoted."), [string] $comments = "Promoted by automation", [string] $apiKey = $(throw "-apiKey is required"), [string] $progetBaseUrl = $(throw "-progetBaseUrl is required") ) $postBody = @{ packageName="$packageName"; groupName=""; version="$fromVersion"; fromFeed="$fromFeed"; toFeed="$toFeed"; comments="$comments" } # Promote the Container Image Invoke-WebRequest -Uri "$progetBaseUrl/api/promotions/promote" -Method POST -Body $postBody -Headers @{"X-ApiKey"="$apiKey"} # Retag the container image by downloading the manifest and then re-uploading it as the new version $manifest = Invoke-WebRequest -Uri "$progetBaseUrl/v2/$toFeed/$packageName/manifests/$fromVersion" -Method GET ` -Headers @{"X-ApiKey"="$apiKey";"accept"="application/vnd.docker.distribution.manifest.v2+json"} Invoke-WebRequest -Uri "$progetBaseUrl/v2/$toFeed/$packageName/manifests/$toVersion" -Method PUT -Body $manifest.ToString() ` -Headers @{"X-ApiKey"="$apiKey";"content-type"="application/vnd.docker.distribution.manifest.v2+json"} }
-
@Stephen-Schaff said in API to apply an Alternate Tag to Docker Container Image:
Here is the PowerShell function that does both the promotion and the tagging (incase anyone ever needs something like this). Kind of a "do it yourself" repackaging. (Might be nice to have the Repackaging API support Docker container images someday).
Thanks for sharing this, I've added it to our Semantic Versioning for Containers docs page, I hope that's okay :)
And yes I agree, it woudl be nice to make this an easier API call
-
Version 6 of ProGet removes the ability to make calls to the docker API via a ProGet API Key.
As such the code posted above no longer works. I updated it to work using the Docker Token based Authentication system. I am posting it here in case someone comes along this post and wanted to use this code:
function RepackageContainerImage() { param ( [string] $packageName = $(throw "-packageName is required. This is the namespace/image-name"), [string] $fromFeed = $(throw "-fromFeed is required"), [string] $toFeed = $(throw "-toFeed is required"), [string] $fromVersion = $(throw "-fromVersion is required. This is the current tag on the image in the fromFeed."), [string] $toVersion = $(throw "-toVersion is required. This is the tag to be applied after the image is promoted."), [string] $comments = "Promoted by automation", [string] $apiKey = $(throw "-apiKey is required"), [string] $progetBaseUrl = $(throw "-progetBaseUrl is required") ) # Promote the Container Image $postBody = @{ packageName="$packageName"; groupName=""; version="$fromVersion"; fromFeed="$fromFeed"; toFeed="$toFeed"; comments="$comments" } $promoteResponse = Invoke-WebRequest -Uri "$progetBaseUrl/api/promotions/promote" -Method POST -Body $postBody -Headers @{"X-ApiKey"="$apiKey"} # Retag the container image by downloading the manifest and then re-uploading it as the new version $pullToken = GetDockerToken -feed $toFeed -packageName $packageName -actionToAuthorize "pull" -apiKey $apiKey -progetBaseUrl $progetBaseUrl $manifest = Invoke-WebRequest -Uri "$progetBaseUrl/v2/$fromFeed/$packageName/manifests/$fromVersion" -Method GET -Headers @{Authorization=("Bearer {0}" -f $pullToken)} $pushToken = GetDockerToken -feed $toFeed -packageName $packageName -actionToAuthorize "push" -apiKey $apiKey -progetBaseUrl $progetBaseUrl Invoke-WebRequest -Uri "$progetBaseUrl/v2/$toFeed/$packageName/manifests/$toVersion" -Method PUT -Body $manifest.ToString() -Headers @{Authorization=("Bearer {0}" -f $pushToken)} } function GetDockerToken() { param ( [string] $packageName = $(throw "-packageName is required. This is the namespace and image name. For example: library/my-container-image"), [string] $feed = $(throw "-feed is required"), [string] $actionToAuthorize = $(throw "-action is required. This is the docker action to be authorized (pull, push, delete, etc)"), [string] $apiKey = $(throw "-apiKey is required"), [string] $progetBaseUrl = $(throw "-progetBaseUrl is required"), [string] $service ) if ($service -eq "") { $service = $progetBaseUrl.SubString(8,$progetBaseUrl.Length-8) } $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "api","$apiKey"))) $response = Invoke-WebRequest -Uri "$progetBaseUrl/v2/_auth?service=$service&scope=repository`:$feed/$packageName`:$actionToAuthorize" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} if ($response.StatusDescription -eq "OK") { $token = ($response.Content | ConvertFrom-Json).token $token } }