forked from cerc-io/stack-orchestrator
Make remote image tags unique to the deployment (#838)
Reviewed-on: cerc-io/stack-orchestrator#838 Reviewed-by: Thomas E Lackey <telackey@noreply.git.vdb.to> Co-authored-by: David Boreham <david@bozemanpass.com> Co-committed-by: David Boreham <david@bozemanpass.com>
This commit is contained in:
parent
4acb06325b
commit
3fb025b5c9
@ -29,16 +29,29 @@ def _image_needs_pushed(image: str):
|
|||||||
return image.endswith(":local")
|
return image.endswith(":local")
|
||||||
|
|
||||||
|
|
||||||
|
def _remote_tag_for_image(image: str, remote_repo_url: str):
|
||||||
|
# Turns image tags of the form: foo/bar:local into remote.repo/org/bar:deploy
|
||||||
|
major_parts = image.split("/", 2)
|
||||||
|
image_name_with_version = major_parts[1] if 2 == len(major_parts) else major_parts[0]
|
||||||
|
(image_name, image_version) = image_name_with_version.split(":")
|
||||||
|
if image_version == "local":
|
||||||
|
return f"{remote_repo_url}/{image_name}:deploy"
|
||||||
|
else:
|
||||||
|
return image
|
||||||
|
|
||||||
|
|
||||||
|
# Note: do not add any calls this function
|
||||||
def remote_image_exists(remote_repo_url: str, local_tag: str):
|
def remote_image_exists(remote_repo_url: str, local_tag: str):
|
||||||
docker = DockerClient()
|
docker = DockerClient()
|
||||||
try:
|
try:
|
||||||
remote_tag = remote_tag_for_image(local_tag, remote_repo_url)
|
remote_tag = _remote_tag_for_image(local_tag, remote_repo_url)
|
||||||
result = docker.manifest.inspect(remote_tag)
|
result = docker.manifest.inspect(remote_tag)
|
||||||
return True if result else False
|
return True if result else False
|
||||||
except Exception: # noqa: E722
|
except Exception: # noqa: E722
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
# Note: do not add any calls this function
|
||||||
def add_tags_to_image(remote_repo_url: str, local_tag: str, *additional_tags):
|
def add_tags_to_image(remote_repo_url: str, local_tag: str, *additional_tags):
|
||||||
if not additional_tags:
|
if not additional_tags:
|
||||||
return
|
return
|
||||||
@ -47,18 +60,20 @@ def add_tags_to_image(remote_repo_url: str, local_tag: str, *additional_tags):
|
|||||||
raise Exception(f"{local_tag} does not exist in {remote_repo_url}")
|
raise Exception(f"{local_tag} does not exist in {remote_repo_url}")
|
||||||
|
|
||||||
docker = DockerClient()
|
docker = DockerClient()
|
||||||
remote_tag = remote_tag_for_image(local_tag, remote_repo_url)
|
remote_tag = _remote_tag_for_image(local_tag, remote_repo_url)
|
||||||
new_remote_tags = [remote_tag_for_image(tag, remote_repo_url) for tag in additional_tags]
|
new_remote_tags = [_remote_tag_for_image(tag, remote_repo_url) for tag in additional_tags]
|
||||||
docker.buildx.imagetools.create(sources=[remote_tag], tags=new_remote_tags)
|
docker.buildx.imagetools.create(sources=[remote_tag], tags=new_remote_tags)
|
||||||
|
|
||||||
|
|
||||||
def remote_tag_for_image(image: str, remote_repo_url: str):
|
def remote_tag_for_image_unique(image: str, remote_repo_url: str, deployment_id: str):
|
||||||
# Turns image tags of the form: foo/bar:local into remote.repo/org/bar:deploy
|
# Turns image tags of the form: foo/bar:local into remote.repo/org/bar:deploy
|
||||||
major_parts = image.split("/", 2)
|
major_parts = image.split("/", 2)
|
||||||
image_name_with_version = major_parts[1] if 2 == len(major_parts) else major_parts[0]
|
image_name_with_version = major_parts[1] if 2 == len(major_parts) else major_parts[0]
|
||||||
(image_name, image_version) = image_name_with_version.split(":")
|
(image_name, image_version) = image_name_with_version.split(":")
|
||||||
if image_version == "local":
|
if image_version == "local":
|
||||||
return f"{remote_repo_url}/{image_name}:deploy"
|
# Salt the tag with part of the deployment id to make it unique to this deployment
|
||||||
|
deployment_tag = deployment_id[0, 7]
|
||||||
|
return f"{remote_repo_url}/{image_name}:deploy-{deployment_tag}"
|
||||||
else:
|
else:
|
||||||
return image
|
return image
|
||||||
|
|
||||||
@ -73,14 +88,14 @@ def push_images_operation(command_context: DeployCommandContext, deployment_cont
|
|||||||
docker = DockerClient()
|
docker = DockerClient()
|
||||||
for image in images:
|
for image in images:
|
||||||
if _image_needs_pushed(image):
|
if _image_needs_pushed(image):
|
||||||
remote_tag = remote_tag_for_image(image, remote_repo_url)
|
remote_tag = remote_tag_for_image_unique(image, remote_repo_url, deployment_context.id)
|
||||||
if opts.o.verbose:
|
if opts.o.verbose:
|
||||||
print(f"Tagging {image} to {remote_tag}")
|
print(f"Tagging {image} to {remote_tag}")
|
||||||
docker.image.tag(image, remote_tag)
|
docker.image.tag(image, remote_tag)
|
||||||
# Run docker push commands to upload
|
# Run docker push commands to upload
|
||||||
for image in images:
|
for image in images:
|
||||||
if _image_needs_pushed(image):
|
if _image_needs_pushed(image):
|
||||||
remote_tag = remote_tag_for_image(image, remote_repo_url)
|
remote_tag = remote_tag_for_image_unique(image, remote_repo_url, deployment_context.id)
|
||||||
if opts.o.verbose:
|
if opts.o.verbose:
|
||||||
print(f"Pushing image {remote_tag}")
|
print(f"Pushing image {remote_tag}")
|
||||||
docker.image.push(remote_tag)
|
docker.image.push(remote_tag)
|
||||||
|
@ -26,7 +26,7 @@ from stack_orchestrator.deploy.k8s.helpers import envs_from_environment_variable
|
|||||||
from stack_orchestrator.deploy.deploy_util import parsed_pod_files_map_from_file_names, images_for_deployment
|
from stack_orchestrator.deploy.deploy_util import parsed_pod_files_map_from_file_names, images_for_deployment
|
||||||
from stack_orchestrator.deploy.deploy_types import DeployEnvVars
|
from stack_orchestrator.deploy.deploy_types import DeployEnvVars
|
||||||
from stack_orchestrator.deploy.spec import Spec, Resources, ResourceLimits
|
from stack_orchestrator.deploy.spec import Spec, Resources, ResourceLimits
|
||||||
from stack_orchestrator.deploy.images import remote_tag_for_image
|
from stack_orchestrator.deploy.images import remote_tag_for_image_unique
|
||||||
|
|
||||||
DEFAULT_VOLUME_RESOURCES = Resources({
|
DEFAULT_VOLUME_RESOURCES = Resources({
|
||||||
"reservations": {"storage": "2Gi"}
|
"reservations": {"storage": "2Gi"}
|
||||||
@ -326,8 +326,11 @@ class ClusterInfo:
|
|||||||
if opts.o.debug:
|
if opts.o.debug:
|
||||||
print(f"Merged envs: {envs}")
|
print(f"Merged envs: {envs}")
|
||||||
# Re-write the image tag for remote deployment
|
# Re-write the image tag for remote deployment
|
||||||
image_to_use = remote_tag_for_image(
|
# Note self.app_name has the same value as deployment_id
|
||||||
image, self.spec.get_image_registry()) if self.spec.get_image_registry() is not None else image
|
image_to_use = remote_tag_for_image_unique(
|
||||||
|
image,
|
||||||
|
self.spec.get_image_registry(),
|
||||||
|
self.app_name) if self.spec.get_image_registry() is not None else image
|
||||||
volume_mounts = volume_mounts_for_service(self.parsed_pod_yaml_map, service_name)
|
volume_mounts = volume_mounts_for_service(self.parsed_pod_yaml_map, service_name)
|
||||||
container = client.V1Container(
|
container = client.V1Container(
|
||||||
name=container_name,
|
name=container_name,
|
||||||
|
Loading…
Reference in New Issue
Block a user