Inedo Community Forums Forums
    • Recent
    • Tags
    • Popular
    • Login

    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

    Scheduled Pinned Locked Moved Support
    4 Posts 2 Posters 21 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • S Offline
      Stephen.Schaff
      last edited by Stephen.Schaff

      My Docker container images flow goes like this:

      1. Devs create the image with a Version Number like this: 1.5.0-build.62
      2. 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?

      1 Reply Last reply Reply Quote 0
      • S Offline
        Stephen.Schaff
        last edited by Stephen.Schaff

        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"}
        }
        
        1 Reply Last reply Reply Quote 0
        • atrippA Offline
          atripp inedo-engineer
          last edited by

          @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

          1 Reply Last reply Reply Quote 1
          • S Offline
            Stephen.Schaff
            last edited by Stephen.Schaff

            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
            	}
            }
            
            1 Reply Last reply Reply Quote 0

            Hello! It looks like you're interested in this conversation, but you don't have an account yet.

            Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

            With your input, this post could be even better 💗

            Register Login
            • 1 / 1
            • First post
              Last post
            Inedo Website Home • Support Home • Code of Conduct • Forums Guide • Documentation