Skip to content

Commit

Permalink
Add timed logging for the webapp build (#771)
Browse files Browse the repository at this point in the history
Add lots of log and timer output to webapp builds.

Reviewed-on: https://git.vdb.to/cerc-io/stack-orchestrator/pulls/771
  • Loading branch information
Thomas E Lackey committed Feb 28, 2024
1 parent f32bbf9 commit 10e2311
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 47 deletions.
35 changes: 25 additions & 10 deletions stack_orchestrator/build/build_webapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import click
from pathlib import Path
from stack_orchestrator.build import build_containers
from stack_orchestrator.deploy.webapp.util import determine_base_container
from stack_orchestrator.deploy.webapp.util import determine_base_container, TimedLogger
from stack_orchestrator.build.build_types import BuildContext


Expand All @@ -40,9 +40,11 @@
@click.pass_context
def command(ctx, base_container, source_repo, force_rebuild, extra_build_args, tag):
'''build the specified webapp container'''
logger = TimedLogger()

quiet = ctx.obj.quiet
debug = ctx.obj.debug
verbose = ctx.obj.verbose
local_stack = ctx.obj.local_stack
stack = ctx.obj.stack

Expand All @@ -51,12 +53,12 @@ def command(ctx, base_container, source_repo, force_rebuild, extra_build_args, t

if local_stack:
dev_root_path = os.getcwd()[0:os.getcwd().rindex("stack-orchestrator")]
print(f'Local stack dev_root_path (CERC_REPO_BASE_DIR) overridden to: {dev_root_path}')
logger.log(f'Local stack dev_root_path (CERC_REPO_BASE_DIR) overridden to: {dev_root_path}')
else:
dev_root_path = os.path.expanduser(config("CERC_REPO_BASE_DIR", default="~/cerc"))

if not quiet:
print(f'Dev Root is: {dev_root_path}')
if verbose:
logger.log(f'Dev Root is: {dev_root_path}')

if not base_container:
base_container = determine_base_container(source_repo)
Expand All @@ -65,6 +67,9 @@ def command(ctx, base_container, source_repo, force_rebuild, extra_build_args, t
container_build_env = build_containers.make_container_build_env(dev_root_path, container_build_dir, debug,
force_rebuild, extra_build_args)

if verbose:
logger.log(f"Building base container: {base_container}")

build_context_1 = BuildContext(
stack,
base_container,
Expand All @@ -74,9 +79,12 @@ def command(ctx, base_container, source_repo, force_rebuild, extra_build_args, t
)
ok = build_containers.process_container(build_context_1)
if not ok:
print("ERROR: Build failed.", file=sys.stderr)
logger.log("ERROR: Build failed.")
sys.exit(1)

if verbose:
logger.log(f"Base container {base_container} build finished.")

# Now build the target webapp. We use the same build script, but with a different Dockerfile and work dir.
container_build_env["CERC_WEBAPP_BUILD_RUNNING"] = "true"
container_build_env["CERC_CONTAINER_BUILD_WORK_DIR"] = os.path.abspath(source_repo)
Expand All @@ -85,9 +93,12 @@ def command(ctx, base_container, source_repo, force_rebuild, extra_build_args, t
"Dockerfile.webapp")
if not tag:
webapp_name = os.path.abspath(source_repo).split(os.path.sep)[-1]
container_build_env["CERC_CONTAINER_BUILD_TAG"] = f"cerc/{webapp_name}:local"
else:
container_build_env["CERC_CONTAINER_BUILD_TAG"] = tag
tag = f"cerc/{webapp_name}:local"

container_build_env["CERC_CONTAINER_BUILD_TAG"] = tag

if verbose:
logger.log(f"Building app container: {tag}")

build_context_2 = BuildContext(
stack,
Expand All @@ -98,5 +109,9 @@ def command(ctx, base_container, source_repo, force_rebuild, extra_build_args, t
)
ok = build_containers.process_container(build_context_2)
if not ok:
print("ERROR: Build failed.", file=sys.stderr)
sys.exit(1)
logger.log("ERROR: Build failed.")
sys.exit(1)

if verbose:
logger.log(f"App container {base_container} build finished.")
logger.log("build-webapp complete", show_step_time=False, show_total_time=True)
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ if [ "$CERC_NEXT_VERSION" != "keep" ] && [ "$CUR_NEXT_VERSION" != "$CERC_NEXT_VE
mv package.json.$$ package.json
fi

$CERC_BUILD_TOOL install || exit 1
time $CERC_BUILD_TOOL install || exit 1

CUR_NEXT_VERSION=`jq -r '.version' node_modules/next/package.json`

Expand All @@ -138,9 +138,9 @@ to use for the build with:
EOF
cat package.json | jq ".dependencies.next = \"^$CERC_MIN_NEXTVER\"" > package.json.$$
mv package.json.$$ package.json
$CERC_BUILD_TOOL install || exit 1
time $CERC_BUILD_TOOL install || exit 1
fi

$CERC_BUILD_TOOL run cerc_compile || exit 1
time $CERC_BUILD_TOOL run cerc_compile || exit 1

exit 0
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ elif [ -f "${WORK_DIR}/package.json" ]; then
fi
fi

$CERC_BUILD_TOOL install || exit 1
$CERC_BUILD_TOOL build || exit 1
time $CERC_BUILD_TOOL install || exit 1
time $CERC_BUILD_TOOL build || exit 1

rm -rf "${DEST_DIR}"
if [ -z "${CERC_BUILD_OUTPUT_DIR}" ]; then
Expand Down
45 changes: 30 additions & 15 deletions stack_orchestrator/deploy/webapp/deploy_webapp_from_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,14 @@

from stack_orchestrator.deploy.images import remote_image_exists, add_tags_to_image
from stack_orchestrator.deploy.webapp import deploy_webapp
from stack_orchestrator.deploy.webapp.util import (LaconicRegistryClient,
from stack_orchestrator.deploy.webapp.util import (LaconicRegistryClient, TimedLogger,
build_container_image, push_container_image,
file_hash, deploy_to_k8s, publish_deployment,
hostname_for_deployment_request, generate_hostname_for_app,
match_owner, skip_by_tag)


def process_app_deployment_request(
run_id,
ctx,
laconic: LaconicRegistryClient,
app_deployment_request,
Expand All @@ -44,14 +43,18 @@ def process_app_deployment_request(
deployment_parent_dir,
kube_config,
image_registry,
force_rebuild=False,
log_file=None
force_rebuild,
logger
):
logger.log("BEGIN - process_app_deployment_request")

# 1. look up application
app = laconic.get_record(app_deployment_request.attributes.application, require=True)
logger.log(f"Retrieved app record {app_deployment_request.attributes.application}")

# 2. determine dns
requested_name = hostname_for_deployment_request(app_deployment_request, laconic)
logger.log(f"Determined requested name: {requested_name}")

# HACK
if "." in requested_name:
Expand All @@ -69,7 +72,7 @@ def process_app_deployment_request(
matched_owner = match_owner(app_deployment_request, laconic.get_record(dns_record.attributes.request, require=True))

if matched_owner:
print("Matched DnsRecord ownership:", matched_owner)
logger.log(f"Matched DnsRecord ownership: {matched_owner}")
else:
raise Exception("Unable to confirm ownership of DnsRecord %s for request %s" %
(dns_record.id, app_deployment_request.id))
Expand Down Expand Up @@ -115,29 +118,35 @@ def process_app_deployment_request(
shared_tag_exists = remote_image_exists(image_registry, app_image_shared_tag)
if shared_tag_exists and not force_rebuild:
# simply add our unique tag to the existing image and we are done
print(f"Using existing app image {app_image_shared_tag} for {deployment_container_tag}", file=log_file)
logger.log(f"Using existing app image {app_image_shared_tag} for {deployment_container_tag}")
add_tags_to_image(image_registry, app_image_shared_tag, deployment_container_tag)
logger.log("Tag complete")
else:
extra_build_args = [] # TODO: pull from request
build_container_image(app, deployment_container_tag, extra_build_args, log_file)
push_container_image(deployment_dir, log_file)
logger.log(f"Building container image {deployment_container_tag}")
build_container_image(app, deployment_container_tag, extra_build_args, logger)
logger.log("Build complete")
logger.log(f"Pushing container image {deployment_container_tag}")
push_container_image(deployment_dir, logger)
logger.log("Push complete")
# The build/push commands above will use the unique deployment tag, so now we need to add the shared tag.
print(f"Updating app image tag {app_image_shared_tag} from build of {deployment_container_tag}", file=log_file)
logger.log(f"Updating app image tag {app_image_shared_tag} from build of {deployment_container_tag}")
add_tags_to_image(image_registry, deployment_container_tag, app_image_shared_tag)
logger.log("Tag complete")

# 7. update config (if needed)
if not deployment_record or file_hash(deployment_config_file) != deployment_record.attributes.meta.config:
needs_k8s_deploy = True

# 8. update k8s deployment
if needs_k8s_deploy:
print("Deploying to k8s")
deploy_to_k8s(
deployment_record,
deployment_dir,
log_file
logger
)

logger.log("Publishing deployment to registry.")
publish_deployment(
laconic,
app,
Expand All @@ -146,8 +155,11 @@ def process_app_deployment_request(
dns_record,
dns_crn,
deployment_dir,
app_deployment_request
app_deployment_request,
logger
)
logger.log("Publication complete.")
logger.log("END - process_app_deployment_request")


def load_known_requests(filename):
Expand Down Expand Up @@ -309,8 +321,9 @@ def command(ctx, kube_config, laconic_config, image_registry, deployment_parent_
run_log_file = open(run_log_file_path, "wt")
run_reg_client = LaconicRegistryClient(laconic_config, log_file=run_log_file)

logger = TimedLogger(run_id, run_log_file)
logger.log("Processing ...")
process_app_deployment_request(
run_id,
ctx,
run_reg_client,
r,
Expand All @@ -321,12 +334,14 @@ def command(ctx, kube_config, laconic_config, image_registry, deployment_parent_
kube_config,
image_registry,
force_rebuild,
run_log_file
logger
)
status = "DEPLOYED"
except Exception as e:
print("ERROR: " + str(e), file=run_log_file)
logger.log("ERROR: " + str(e))
finally:
if logger:
logger.log(f"DONE with status {status}", show_step_time=False, show_total_time=True)
dump_known_requests(state_file, [r], status)
if run_log_file:
run_log_file.close()
Loading

0 comments on commit 10e2311

Please sign in to comment.