Search code examples
pythonrestpostartifactory

How to promote (Copy) a Docker image from one repository to another with JFrog Rest API


I have a repository with all Docker Images. I want to copy all docker images from there to another repository that were used in the last 7 days. I must be a python script and I cannot use curl.

I have figured out everything except the way to copy the image.

URL = "https://repo.url/artifactory"
REPOSITORY = "repo-with-all-images"
IMAGE_NAME = "image-name"
VERSION = "latest"
TARGET_REPOSITORY = "repo-to-paste-images"

url = f"{URL}/api/docker/{REPOSITORY}/{IMAGE_NAME}/{VERSION}/promote"

payload = {
      "targetRepo": TARGET_REPOSITORY,
      "copy": True,
}

headers = ({"Authorization": token})

status = urllib3.PoolManager().request(method="POST", url=url, body=json.dumps(payload), headers=headers)
logging.error(status.data)
logging.error(status.headers

When running it I get this message:

ERROR:root:b'{\n "errors" : [ {\n "status" : 405,\n "message" : "Method Not Allowed"\n } ]\n}'

ERROR:root:HTTPHeaderDict({'Date': 'Wed, 11 Jan 2023 09:36:13 GMT', 'Content-Type': 'application/json', 'Transfer-Encoding': 'chunked', 'Connection': 'keep-alive', 'X-JFrog-Version': 'Artifactory/X.XX.XX XXXXXXXX', 'X-Artifactory-Id': 'xxxxxxxxxxxxxxxx:-xxxxxxx:xxxxxxxxxx:-xxxx', 'X-Artifactory-Node-Id': 'xxx-xxxxxx-xxx', 'Allow': 'HEAD,GET,OPTIONS'})


Solution

  • Looking at the documentation for Promote Docker Image REST API, it looks you are using it wrong.

    It says:

    POST api/docker/<repoKey>/v2/promote
    
    {
        "targetRepo" : "<targetRepo>",
        "dockerRepository" : "<dockerRepository>",
        "targetDockerRepository" : "<targetDockerRepository>",
        "tag" : "<tag>",
        "targetTag" : "<tag>",
        "copy": false
    }
    

    Which means in your case it should be (based on the original code in the question):

    URL = "https://repo.url/artifactory"
    REPOSITORY = "repo-with-all-images"
    IMAGE_NAME = "image-name"
    VERSION = "latest"
    TARGET_REPOSITORY = "repo-to-paste-images"
    
    url = f"{URL}/api/docker/{REPOSITORY}/v2/promote"
    
    payload = {
          "targetRepo": TARGET_REPOSITORY,
          "dockerRepository": IMAGE_NAME,
          "tag": VERSION,
          "copy": True,
    }
    
    headers = ({"Authorization": token, "Content-Type": "application/json"})
    
    status = urllib3.PoolManager().request(method="POST", url=url, body=json.dumps(payload), headers=headers)
    logging.error(status.data)
    logging.error(status.headers