WIP: Check for existing tag in remote repo before building.
Some checks failed
Lint Checks / Run linter (pull_request) Failing after 24s
Deploy Test / Run deploy test suite (pull_request) Successful in 4m33s
K8s Deploy Test / Run deploy test suite on kind/k8s (pull_request) Successful in 6m30s
Webapp Test / Run webapp test suite (pull_request) Successful in 5m34s
Smoke Test / Run basic test suite (pull_request) Successful in 3m44s

This commit is contained in:
Thomas E Lackey 2024-02-23 14:37:25 -06:00
parent 704c42c404
commit 2d8cc09e6f
2 changed files with 25 additions and 8 deletions

View File

@ -29,6 +29,15 @@ def _image_needs_pushed(image: str):
return image.endswith(":local") return image.endswith(":local")
def remote_image_exists(local_tag: str, remote_repo_url: str):
docker = DockerClient()
try:
result = docker.manifest.inspect(remote_tag_for_image(local_tag, remote_repo_url))
return True if result else False
except:
return False
def remote_tag_for_image(image: str, remote_repo_url: str): 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 # 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)

View File

@ -24,6 +24,8 @@ import uuid
import click import click
from stack_orchestrator import constants
from stack_orchestrator.deploy.images import remote_image_exists
from stack_orchestrator.deploy.webapp import deploy_webapp from stack_orchestrator.deploy.webapp import deploy_webapp
from stack_orchestrator.deploy.webapp.util import (LaconicRegistryClient, from stack_orchestrator.deploy.webapp.util import (LaconicRegistryClient,
build_container_image, push_container_image, build_container_image, push_container_image,
@ -43,7 +45,8 @@ def process_app_deployment_request(
deployment_parent_dir, deployment_parent_dir,
kube_config, kube_config,
image_registry, image_registry,
log_file=None force_rebuild = False,
log_file = None
): ):
# 1. look up application # 1. look up application
app = laconic.get_record(app_deployment_request.attributes.application, require=True) app = laconic.get_record(app_deployment_request.attributes.application, require=True)
@ -91,7 +94,7 @@ def process_app_deployment_request(
deployment_record = laconic.get_record(app_deployment_crn) deployment_record = laconic.get_record(app_deployment_crn)
deployment_dir = os.path.join(deployment_parent_dir, fqdn) deployment_dir = os.path.join(deployment_parent_dir, fqdn)
deployment_config_file = os.path.join(deployment_dir, "config.env") deployment_config_file = os.path.join(deployment_dir, "config.env")
deployment_container_tag = "laconic-webapp/%s:local" % hashlib.md5(deployment_dir.encode()).hexdigest() deployment_container_tag = f"laconic-webapp/{app.id}:local"
# b. check for deployment directory (create if necessary) # b. check for deployment directory (create if necessary)
if not os.path.exists(deployment_dir): if not os.path.exists(deployment_dir):
if deployment_record: if deployment_record:
@ -106,11 +109,14 @@ def process_app_deployment_request(
needs_k8s_deploy = False needs_k8s_deploy = False
# 6. build container (if needed) # 6. build container (if needed)
if not deployment_record or deployment_record.attributes.application != app.id: if not deployment_record or deployment_record.attributes.application != app.id:
# TODO: pull from request print(ctx)
extra_build_args = [] # check if the image already exists
build_container_image(app, deployment_container_tag, extra_build_args, log_file) if force_rebuild or not remote_image_exists(deployment_container_tag, ctx.spec[constants.image_registry_key]):
push_container_image(deployment_dir, log_file) # TODO: pull from request
needs_k8s_deploy = True extra_build_args = []
build_container_image(app, deployment_container_tag, extra_build_args, log_file)
push_container_image(deployment_dir, log_file)
needs_k8s_deploy = True
# 7. update config (if needed) # 7. update config (if needed)
if not deployment_record or file_hash(deployment_config_file) != deployment_record.attributes.meta.config: if not deployment_record or file_hash(deployment_config_file) != deployment_record.attributes.meta.config:
@ -171,12 +177,13 @@ def dump_known_requests(filename, requests, status="SEEN"):
@click.option("--dry-run", help="Don't do anything, just report what would be done.", is_flag=True) @click.option("--dry-run", help="Don't do anything, just report what would be done.", is_flag=True)
@click.option("--include-tags", help="Only include requests with matching tags (comma-separated).", default="") @click.option("--include-tags", help="Only include requests with matching tags (comma-separated).", default="")
@click.option("--exclude-tags", help="Exclude requests with matching tags (comma-separated).", default="") @click.option("--exclude-tags", help="Exclude requests with matching tags (comma-separated).", default="")
@click.option("--force-rebuild", help="Rebuild even if the image already exists.", is_flag=True)
@click.option("--log-dir", help="Output build/deployment logs to directory.", default=None) @click.option("--log-dir", help="Output build/deployment logs to directory.", default=None)
@click.pass_context @click.pass_context
def command(ctx, kube_config, laconic_config, image_registry, deployment_parent_dir, # noqa: C901 def command(ctx, kube_config, laconic_config, image_registry, deployment_parent_dir, # noqa: C901
request_id, discover, state_file, only_update_state, request_id, discover, state_file, only_update_state,
dns_suffix, record_namespace_dns, record_namespace_deployments, dry_run, dns_suffix, record_namespace_dns, record_namespace_deployments, dry_run,
include_tags, exclude_tags, log_dir): include_tags, exclude_tags, force_rebuild, log_dir):
if request_id and discover: if request_id and discover:
print("Cannot specify both --request-id and --discover", file=sys.stderr) print("Cannot specify both --request-id and --discover", file=sys.stderr)
sys.exit(2) sys.exit(2)
@ -306,6 +313,7 @@ def command(ctx, kube_config, laconic_config, image_registry, deployment_parent_
os.path.abspath(deployment_parent_dir), os.path.abspath(deployment_parent_dir),
kube_config, kube_config,
image_registry, image_registry,
force_rebuild,
run_log_file run_log_file
) )
status = "DEPLOYED" status = "DEPLOYED"