mirror of
https://github.com/GNS3/gns3-registry.git
synced 2024-12-24 06:56:41 +00:00
Docker build: Support logins to multiple registries
This commit is contained in:
parent
78f5477e37
commit
3a5d352f1c
66
.github/bin/docker_build
vendored
66
.github/bin/docker_build
vendored
@ -108,7 +108,7 @@ def parse_repository(repository):
|
|||||||
match = RE_REPOSITORY.fullmatch(repository)
|
match = RE_REPOSITORY.fullmatch(repository)
|
||||||
if not match:
|
if not match:
|
||||||
raise ValueError("invalid reference format")
|
raise ValueError("invalid reference format")
|
||||||
registry = match.group('host') or "docker.io"
|
registry = (match.group('host') or "docker.io").lower()
|
||||||
repo = match.group('repo')
|
repo = match.group('repo')
|
||||||
tag = match.group('digest') or match.group('tag') or "latest"
|
tag = match.group('digest') or match.group('tag') or "latest"
|
||||||
len_registry = len(registry)
|
len_registry = len(registry)
|
||||||
@ -123,17 +123,12 @@ def parse_repository(repository):
|
|||||||
return registry, repo, tag
|
return registry, repo, tag
|
||||||
|
|
||||||
|
|
||||||
def docker_auth_user(docker, response):
|
def docker_auth(docker, response):
|
||||||
""" authenticate with user/password """
|
""" authenticate docker access """
|
||||||
docker.authenticate(docker_login["user"], docker_login["password"],
|
docker.authenticate(docker.registry_auth[0], docker.registry_auth[1],
|
||||||
response=response)
|
response=response)
|
||||||
|
|
||||||
|
|
||||||
def docker_auth_none(docker, response):
|
|
||||||
""" public access """
|
|
||||||
docker.authenticate(None, None, response=response)
|
|
||||||
|
|
||||||
|
|
||||||
def get_time_layers(repository):
|
def get_time_layers(repository):
|
||||||
"""
|
"""
|
||||||
get created time and layer info from the docker registry
|
get created time and layer info from the docker registry
|
||||||
@ -144,14 +139,10 @@ def get_time_layers(repository):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
registry, repo, tag = parse_repository(repository)
|
registry, repo, tag = parse_repository(repository)
|
||||||
if registry == docker_login["registry"] and \
|
|
||||||
docker_login["user"] and docker_login["password"]:
|
|
||||||
docker_auth = docker_auth_user
|
|
||||||
else:
|
|
||||||
docker_auth = docker_auth_none
|
|
||||||
|
|
||||||
# open docker connection
|
# open docker connection
|
||||||
with dxf.DXF(registry, repo, docker_auth, timeout=30) as docker:
|
with dxf.DXF(registry, repo, docker_auth, timeout=30) as docker:
|
||||||
|
docker.registry_auth = docker_login.get(registry, [None, None])
|
||||||
# get config digest
|
# get config digest
|
||||||
try:
|
try:
|
||||||
digest = docker.get_digest(tag, platform="linux/amd64")
|
digest = docker.get_digest(tag, platform="linux/amd64")
|
||||||
@ -188,11 +179,11 @@ def expand_base_image(base_name):
|
|||||||
match = re.match(r"\$\{?DOCKER_REPOSITORY\}?/(.+)", base_name)
|
match = re.match(r"\$\{?DOCKER_REPOSITORY\}?/(.+)", base_name)
|
||||||
if not match:
|
if not match:
|
||||||
return (base_name, [])
|
return (base_name, [])
|
||||||
if not docker_login["repository"]:
|
if not docker_env["repository"]:
|
||||||
raise ValueError("Environment variable DOCKER_REPOSITORY "
|
raise ValueError("Environment variable DOCKER_REPOSITORY "
|
||||||
"is not defined or is empty")
|
"is not defined or is empty")
|
||||||
base_name = docker_login["repository"] + "/" + match.group(1)
|
base_name = docker_env["repository"] + "/" + match.group(1)
|
||||||
options = ["--build-arg", "DOCKER_REPOSITORY=" + docker_login["repository"]]
|
options = ["--build-arg", "DOCKER_REPOSITORY=" + docker_env["repository"]]
|
||||||
return (base_name, options)
|
return (base_name, options)
|
||||||
|
|
||||||
|
|
||||||
@ -200,10 +191,10 @@ def full_image_name(image_name):
|
|||||||
""" get full image name """
|
""" get full image name """
|
||||||
if "/" in image_name:
|
if "/" in image_name:
|
||||||
return image_name
|
return image_name
|
||||||
if not docker_login["repository"]:
|
if not docker_env["repository"]:
|
||||||
raise ValueError("Environment variable DOCKER_REPOSITORY "
|
raise ValueError("Environment variable DOCKER_REPOSITORY "
|
||||||
"is not defined or is empty")
|
"is not defined or is empty")
|
||||||
return docker_login["repository"] + "/" + image_name
|
return docker_env["repository"] + "/" + image_name
|
||||||
|
|
||||||
|
|
||||||
def dockerfile_base(directory):
|
def dockerfile_base(directory):
|
||||||
@ -398,6 +389,24 @@ def build(image):
|
|||||||
sys.exit(f"{image['name']}: Can't get image layers")
|
sys.exit(f"{image['name']}: Can't get image layers")
|
||||||
|
|
||||||
|
|
||||||
|
def fill_login_table():
|
||||||
|
""" fill login table from DOCKER_LOGIN* environment variables """
|
||||||
|
login_table = {}
|
||||||
|
for key, val in list(os.environ.items()):
|
||||||
|
if key.startswith("DOCKER_LOGIN"):
|
||||||
|
val_split = val.strip().split(maxsplit=2)
|
||||||
|
if len(val_split) != 3:
|
||||||
|
sys.exit(f"{key} requires 3 fields: registry user password")
|
||||||
|
registry = val_split[0].lower()
|
||||||
|
if registry == "docker.io":
|
||||||
|
registry = "registry-1.docker.io"
|
||||||
|
if registry in login_table:
|
||||||
|
sys.exit(f"DOCKER_LOGIN: {registry} defined multiple times")
|
||||||
|
login_table[registry] = val_split[1:3]
|
||||||
|
del os.environ[key]
|
||||||
|
return login_table
|
||||||
|
|
||||||
|
|
||||||
def xor(*params):
|
def xor(*params):
|
||||||
""" logical xor """
|
""" logical xor """
|
||||||
result = False
|
result = False
|
||||||
@ -410,18 +419,19 @@ def xor(*params):
|
|||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
sys.stdout.reconfigure(line_buffering=True)
|
sys.stdout.reconfigure(line_buffering=True)
|
||||||
|
|
||||||
docker_login = {"repository": os.environ.get("DOCKER_REPOSITORY", "").lower(),
|
# DOCKER_REPOSITORY environment
|
||||||
"user": os.environ.pop("DOCKER_USERNAME", None),
|
docker_env = {"repository": os.environ.get("DOCKER_REPOSITORY", "")
|
||||||
"password": os.environ.pop("DOCKER_PASSWORD", None)}
|
.lower().rstrip("/")}
|
||||||
if docker_login["repository"]:
|
if docker_env["repository"]:
|
||||||
docker_login["repository"] = docker_login["repository"].rstrip("/")
|
|
||||||
try:
|
try:
|
||||||
docker_login["registry"], *_ = \
|
docker_env["registry"], *_ = parse_repository(docker_env["repository"])
|
||||||
parse_repository(docker_login["repository"])
|
|
||||||
except ValueError as err_info:
|
except ValueError as err_info:
|
||||||
sys.exit(f"DOCKER_REPOSITORY={docker_login['repository']}: {err_info}")
|
sys.exit(f"DOCKER_REPOSITORY={docker_env['repository']}: {err_info}")
|
||||||
else:
|
else:
|
||||||
docker_login["registry"] = None
|
docker_env["repository"] = docker_env["registry"] = None
|
||||||
|
|
||||||
|
# fill user/password table
|
||||||
|
docker_login = fill_login_table()
|
||||||
|
|
||||||
if args.dir:
|
if args.dir:
|
||||||
try:
|
try:
|
||||||
|
17
.github/docker_build.md
vendored
17
.github/docker_build.md
vendored
@ -95,6 +95,21 @@ FROM $DOCKER_REPOSITORY/base-image
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Environment Variables
|
||||||
|
|
||||||
|
In addition to the DOCKER_REPOSITORY variable described above
|
||||||
|
the build tool uses the environment variables whose names begin
|
||||||
|
with "DOCKER_LOGIN". Each variable contains the user/password
|
||||||
|
of a docker registry. The format is: `<registry> <user> <password>`.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```
|
||||||
|
DOCKER_LOGIN_DH="docker.io dockerhub-user dockerhub-password"
|
||||||
|
DOCKER_LOGIN_GH="ghcr.io github-user github-password"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Workflow Definition
|
## Workflow Definition
|
||||||
|
|
||||||
[GitHub Actions](https://docs.github.com/en/actions)
|
[GitHub Actions](https://docs.github.com/en/actions)
|
||||||
@ -107,7 +122,7 @@ need to be done:
|
|||||||
* Check out the repository code
|
* Check out the repository code
|
||||||
* Set up QEMU (for multi-arch building)
|
* Set up QEMU (for multi-arch building)
|
||||||
* Set up Docker Buildx
|
* Set up Docker Buildx
|
||||||
* Login to the Container Registry
|
* Login to the Container Registries
|
||||||
* Install python requirements
|
* Install python requirements
|
||||||
|
|
||||||
Then `docker_build` can be executed,
|
Then `docker_build` can be executed,
|
||||||
|
56
.github/workflows/build-docker-images.yml
vendored
56
.github/workflows/build-docker-images.yml
vendored
@ -1,4 +1,5 @@
|
|||||||
name: Build Docker images and upload to DockerHub
|
name: Build and upload Docker images
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
@ -24,40 +25,59 @@ jobs:
|
|||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
# https://github.com/marketplace/actions/docker-setup-qemu
|
# https://github.com/marketplace/actions/docker-setup-qemu
|
||||||
uses: docker/setup-qemu-action@v2
|
uses: docker/setup-qemu-action@v2
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
# https://github.com/marketplace/actions/docker-setup-buildx
|
# https://github.com/marketplace/actions/docker-setup-buildx
|
||||||
uses: docker/setup-buildx-action@v2
|
uses: docker/setup-buildx-action@v2
|
||||||
- name: Login to GitHub Container Registry
|
|
||||||
|
- name: Login to DockerHub Registry
|
||||||
# https://github.com/marketplace/actions/docker-login
|
# https://github.com/marketplace/actions/docker-login
|
||||||
|
# set the condition depending on whether you want to login to Docker.
|
||||||
|
if: true
|
||||||
uses: docker/login-action@v2
|
uses: docker/login-action@v2
|
||||||
with:
|
with:
|
||||||
# GitHub Container Registry:
|
|
||||||
# registry: ghcr.io
|
|
||||||
# username: ${{ github.repository_owner }}
|
|
||||||
# password: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
#
|
|
||||||
# DockerHub:
|
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Login to GitHub Container Registry
|
||||||
|
# https://github.com/marketplace/actions/docker-login
|
||||||
|
# set the condition depending on whether you want to login to ghcr.io.
|
||||||
|
if: false
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.repository_owner }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Install python requirements
|
- name: Install python requirements
|
||||||
run: python3 -m pip install --requirement .github/bin/requirements.txt
|
run: python3 -m pip install --requirement .github/bin/requirements.txt
|
||||||
|
|
||||||
- name: Build and push images
|
- name: Build and push images
|
||||||
env:
|
env:
|
||||||
# DOCKER_USERNAME and DOCKER_PASSWORD are optional, they
|
|
||||||
# are only needed to authenticate into private repositories
|
|
||||||
#
|
|
||||||
# GitHub Container Registry:
|
|
||||||
# DOCKER_REPOSITORY: ghcr.io/${{ github.repository_owner }}
|
|
||||||
# DOCKER_USERNAME: ${{ github.repository_owner }}
|
|
||||||
# DOCKER_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
#
|
|
||||||
# DockerHub:
|
# DockerHub:
|
||||||
DOCKER_REPOSITORY: ${{ secrets.DOCKERHUB_REPOSITORY }}
|
DOCKER_REPOSITORY: ${{ secrets.DOCKERHUB_REPOSITORY }}
|
||||||
# DOCKER_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
|
# GitHub Container Registry:
|
||||||
# DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
|
# DOCKER_REPOSITORY: ghcr.io/${{ github.repository_owner }}
|
||||||
|
#
|
||||||
|
# Variables whose name are starting with "DOCKER_LOGIN"
|
||||||
|
# contain the user/password for a docker registry.
|
||||||
|
# They are only needed to authenticate into private repositories.
|
||||||
|
#
|
||||||
|
# DockerHub:
|
||||||
|
#DOCKER_LOGIN_DH: >-
|
||||||
|
# docker.io
|
||||||
|
# ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
# ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
#
|
||||||
|
# GitHub Container Registry:
|
||||||
|
#DOCKER_LOGIN_GH: >-
|
||||||
|
# ghcr.io
|
||||||
|
# ${{ github.repository_owner }}
|
||||||
|
# ${{ secrets.GITHUB_TOKEN }}
|
||||||
#
|
#
|
||||||
IMAGES: ${{ inputs.images }}
|
IMAGES: ${{ inputs.images }}
|
||||||
run: |
|
run: |
|
||||||
|
Loading…
Reference in New Issue
Block a user