mirror of
https://github.com/GNS3/gns3-registry.git
synced 2024-12-19 21:07:55 +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)
|
||||
if not match:
|
||||
raise ValueError("invalid reference format")
|
||||
registry = match.group('host') or "docker.io"
|
||||
registry = (match.group('host') or "docker.io").lower()
|
||||
repo = match.group('repo')
|
||||
tag = match.group('digest') or match.group('tag') or "latest"
|
||||
len_registry = len(registry)
|
||||
@ -123,17 +123,12 @@ def parse_repository(repository):
|
||||
return registry, repo, tag
|
||||
|
||||
|
||||
def docker_auth_user(docker, response):
|
||||
""" authenticate with user/password """
|
||||
docker.authenticate(docker_login["user"], docker_login["password"],
|
||||
def docker_auth(docker, response):
|
||||
""" authenticate docker access """
|
||||
docker.authenticate(docker.registry_auth[0], docker.registry_auth[1],
|
||||
response=response)
|
||||
|
||||
|
||||
def docker_auth_none(docker, response):
|
||||
""" public access """
|
||||
docker.authenticate(None, None, response=response)
|
||||
|
||||
|
||||
def get_time_layers(repository):
|
||||
"""
|
||||
get created time and layer info from the docker registry
|
||||
@ -144,14 +139,10 @@ def get_time_layers(repository):
|
||||
|
||||
try:
|
||||
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
|
||||
with dxf.DXF(registry, repo, docker_auth, timeout=30) as docker:
|
||||
docker.registry_auth = docker_login.get(registry, [None, None])
|
||||
# get config digest
|
||||
try:
|
||||
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)
|
||||
if not match:
|
||||
return (base_name, [])
|
||||
if not docker_login["repository"]:
|
||||
if not docker_env["repository"]:
|
||||
raise ValueError("Environment variable DOCKER_REPOSITORY "
|
||||
"is not defined or is empty")
|
||||
base_name = docker_login["repository"] + "/" + match.group(1)
|
||||
options = ["--build-arg", "DOCKER_REPOSITORY=" + docker_login["repository"]]
|
||||
base_name = docker_env["repository"] + "/" + match.group(1)
|
||||
options = ["--build-arg", "DOCKER_REPOSITORY=" + docker_env["repository"]]
|
||||
return (base_name, options)
|
||||
|
||||
|
||||
@ -200,10 +191,10 @@ def full_image_name(image_name):
|
||||
""" get full image name """
|
||||
if "/" in image_name:
|
||||
return image_name
|
||||
if not docker_login["repository"]:
|
||||
if not docker_env["repository"]:
|
||||
raise ValueError("Environment variable DOCKER_REPOSITORY "
|
||||
"is not defined or is empty")
|
||||
return docker_login["repository"] + "/" + image_name
|
||||
return docker_env["repository"] + "/" + image_name
|
||||
|
||||
|
||||
def dockerfile_base(directory):
|
||||
@ -398,6 +389,24 @@ def build(image):
|
||||
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):
|
||||
""" logical xor """
|
||||
result = False
|
||||
@ -410,18 +419,19 @@ def xor(*params):
|
||||
args = parser.parse_args()
|
||||
sys.stdout.reconfigure(line_buffering=True)
|
||||
|
||||
docker_login = {"repository": os.environ.get("DOCKER_REPOSITORY", "").lower(),
|
||||
"user": os.environ.pop("DOCKER_USERNAME", None),
|
||||
"password": os.environ.pop("DOCKER_PASSWORD", None)}
|
||||
if docker_login["repository"]:
|
||||
docker_login["repository"] = docker_login["repository"].rstrip("/")
|
||||
# DOCKER_REPOSITORY environment
|
||||
docker_env = {"repository": os.environ.get("DOCKER_REPOSITORY", "")
|
||||
.lower().rstrip("/")}
|
||||
if docker_env["repository"]:
|
||||
try:
|
||||
docker_login["registry"], *_ = \
|
||||
parse_repository(docker_login["repository"])
|
||||
docker_env["registry"], *_ = parse_repository(docker_env["repository"])
|
||||
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:
|
||||
docker_login["registry"] = None
|
||||
docker_env["repository"] = docker_env["registry"] = None
|
||||
|
||||
# fill user/password table
|
||||
docker_login = fill_login_table()
|
||||
|
||||
if args.dir:
|
||||
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
|
||||
|
||||
[GitHub Actions](https://docs.github.com/en/actions)
|
||||
@ -107,7 +122,7 @@ need to be done:
|
||||
* Check out the repository code
|
||||
* Set up QEMU (for multi-arch building)
|
||||
* Set up Docker Buildx
|
||||
* Login to the Container Registry
|
||||
* Login to the Container Registries
|
||||
* Install python requirements
|
||||
|
||||
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:
|
||||
push:
|
||||
branches:
|
||||
@ -24,40 +25,59 @@ jobs:
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up QEMU
|
||||
# https://github.com/marketplace/actions/docker-setup-qemu
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
# https://github.com/marketplace/actions/docker-setup-buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login to GitHub Container Registry
|
||||
|
||||
- name: Login to DockerHub Registry
|
||||
# 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
|
||||
with:
|
||||
# GitHub Container Registry:
|
||||
# registry: ghcr.io
|
||||
# username: ${{ github.repository_owner }}
|
||||
# password: ${{ secrets.GITHUB_TOKEN }}
|
||||
#
|
||||
# DockerHub:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
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
|
||||
run: python3 -m pip install --requirement .github/bin/requirements.txt
|
||||
|
||||
- name: Build and push images
|
||||
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:
|
||||
DOCKER_REPOSITORY: ${{ secrets.DOCKERHUB_REPOSITORY }}
|
||||
# DOCKER_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
# DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
# GitHub Container Registry:
|
||||
# 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 }}
|
||||
run: |
|
||||
|
Loading…
Reference in New Issue
Block a user