Check whether the named image is pushed to Docker Hub. Note that this operation requires a rather slow network request.
(name: str)
| 260 | |
| 261 | |
| 262 | def is_docker_image_pushed(name: str) -> bool: |
| 263 | """Check whether the named image is pushed to Docker Hub. |
| 264 | |
| 265 | Note that this operation requires a rather slow network request. |
| 266 | """ |
| 267 | global _known_docker_images |
| 268 | |
| 269 | if _known_docker_images is None: |
| 270 | with _known_docker_images_lock: |
| 271 | if not KNOWN_DOCKER_IMAGES_FILE.exists(): |
| 272 | _known_docker_images = set() |
| 273 | else: |
| 274 | with KNOWN_DOCKER_IMAGES_FILE.open() as f: |
| 275 | _known_docker_images = set(line.strip() for line in f) |
| 276 | |
| 277 | if name in _known_docker_images: |
| 278 | return True |
| 279 | |
| 280 | if ":" not in name: |
| 281 | image, tag = name, "latest" |
| 282 | else: |
| 283 | image, tag = name.rsplit(":", 1) |
| 284 | |
| 285 | dockerhub_username = os.getenv("DOCKERHUB_USERNAME") |
| 286 | dockerhub_token = os.getenv("DOCKERHUB_ACCESS_TOKEN") |
| 287 | |
| 288 | exists: bool = False |
| 289 | |
| 290 | try: |
| 291 | if dockerhub_username and dockerhub_token: |
| 292 | response = requests.head( |
| 293 | f"https://registry-1.docker.io/v2/{image}/manifests/{tag}", |
| 294 | headers={ |
| 295 | "Accept": "application/vnd.docker.distribution.manifest.v2+json", |
| 296 | }, |
| 297 | auth=HTTPBasicAuth(dockerhub_username, dockerhub_token), |
| 298 | timeout=10, |
| 299 | ) |
| 300 | else: |
| 301 | token = requests.get( |
| 302 | "https://auth.docker.io/token", |
| 303 | params={ |
| 304 | "service": "registry.docker.io", |
| 305 | "scope": f"repository:{image}:pull", |
| 306 | }, |
| 307 | timeout=10, |
| 308 | ).json()["token"] |
| 309 | response = requests.head( |
| 310 | f"https://registry-1.docker.io/v2/{image}/manifests/{tag}", |
| 311 | headers={ |
| 312 | "Accept": "application/vnd.docker.distribution.manifest.v2+json", |
| 313 | "Authorization": f"Bearer {token}", |
| 314 | }, |
| 315 | timeout=10, |
| 316 | ) |
| 317 | |
| 318 | if response.status_code in (401, 429, 500, 502, 503, 504): |
| 319 | # Fall back to 5x slower method |