Add timed logging for the build
Some checks failed
Lint Checks / Run linter (pull_request) Failing after 48s
Smoke Test / Run basic test suite (pull_request) Successful in 3m13s
Deploy Test / Run deploy test suite (pull_request) Successful in 4m46s
Webapp Test / Run webapp test suite (pull_request) Successful in 5m25s
K8s Deploy Test / Run deploy test suite on kind/k8s (pull_request) Has been cancelled
Some checks failed
Lint Checks / Run linter (pull_request) Failing after 48s
Smoke Test / Run basic test suite (pull_request) Successful in 3m13s
Deploy Test / Run deploy test suite (pull_request) Successful in 4m46s
Webapp Test / Run webapp test suite (pull_request) Successful in 5m25s
K8s Deploy Test / Run deploy test suite on kind/k8s (pull_request) Has been cancelled
This commit is contained in:
parent
01e4437b62
commit
c90bb74d32
@ -3,7 +3,7 @@
|
|||||||
# it under the terms of the GNU Affero General Public License as published by
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
|
import datetime
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
@ -26,7 +26,7 @@ import click
|
|||||||
|
|
||||||
from stack_orchestrator.deploy.images import remote_image_exists, add_tags_to_image
|
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 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,
|
build_container_image, push_container_image,
|
||||||
file_hash, deploy_to_k8s, publish_deployment,
|
file_hash, deploy_to_k8s, publish_deployment,
|
||||||
hostname_for_deployment_request, generate_hostname_for_app,
|
hostname_for_deployment_request, generate_hostname_for_app,
|
||||||
@ -34,7 +34,6 @@ from stack_orchestrator.deploy.webapp.util import (LaconicRegistryClient,
|
|||||||
|
|
||||||
|
|
||||||
def process_app_deployment_request(
|
def process_app_deployment_request(
|
||||||
run_id,
|
|
||||||
ctx,
|
ctx,
|
||||||
laconic: LaconicRegistryClient,
|
laconic: LaconicRegistryClient,
|
||||||
app_deployment_request,
|
app_deployment_request,
|
||||||
@ -44,14 +43,18 @@ def process_app_deployment_request(
|
|||||||
deployment_parent_dir,
|
deployment_parent_dir,
|
||||||
kube_config,
|
kube_config,
|
||||||
image_registry,
|
image_registry,
|
||||||
force_rebuild=False,
|
force_rebuild,
|
||||||
log_file=None
|
logger
|
||||||
):
|
):
|
||||||
|
logger.log("BEGIN - process_app_deployment_request")
|
||||||
|
|
||||||
# 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)
|
||||||
|
logger.log(f"Retrieved app record {app_deployment_request.attributes.application}")
|
||||||
|
|
||||||
# 2. determine dns
|
# 2. determine dns
|
||||||
requested_name = hostname_for_deployment_request(app_deployment_request, laconic)
|
requested_name = hostname_for_deployment_request(app_deployment_request, laconic)
|
||||||
|
logger.log(f"Determined requested name: {requested_name}")
|
||||||
|
|
||||||
# HACK
|
# HACK
|
||||||
if "." in requested_name:
|
if "." in requested_name:
|
||||||
@ -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))
|
matched_owner = match_owner(app_deployment_request, laconic.get_record(dns_record.attributes.request, require=True))
|
||||||
|
|
||||||
if matched_owner:
|
if matched_owner:
|
||||||
print("Matched DnsRecord ownership:", matched_owner)
|
logger.log(f"Matched DnsRecord ownership: {matched_owner}")
|
||||||
else:
|
else:
|
||||||
raise Exception("Unable to confirm ownership of DnsRecord %s for request %s" %
|
raise Exception("Unable to confirm ownership of DnsRecord %s for request %s" %
|
||||||
(dns_record.id, app_deployment_request.id))
|
(dns_record.id, app_deployment_request.id))
|
||||||
@ -115,15 +118,21 @@ def process_app_deployment_request(
|
|||||||
shared_tag_exists = remote_image_exists(image_registry, app_image_shared_tag)
|
shared_tag_exists = remote_image_exists(image_registry, app_image_shared_tag)
|
||||||
if shared_tag_exists and not force_rebuild:
|
if shared_tag_exists and not force_rebuild:
|
||||||
# simply add our unique tag to the existing image and we are done
|
# 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)
|
add_tags_to_image(image_registry, app_image_shared_tag, deployment_container_tag)
|
||||||
|
logger.log(f"Tag complete")
|
||||||
else:
|
else:
|
||||||
extra_build_args = [] # TODO: pull from request
|
extra_build_args = [] # TODO: pull from request
|
||||||
build_container_image(app, deployment_container_tag, extra_build_args, log_file)
|
logger.log(f"Building container image {deployment_container_tag}")
|
||||||
push_container_image(deployment_dir, log_file)
|
build_container_image(app, deployment_container_tag, extra_build_args, logger.file)
|
||||||
|
logger.log("Build complete")
|
||||||
|
logger.log(f"Pushing container image {deployment_container_tag}")
|
||||||
|
push_container_image(deployment_dir, logger.file)
|
||||||
|
logger.log("Push complete")
|
||||||
# The build/push commands above will use the unique deployment tag, so now we need to add the shared tag.
|
# 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)
|
add_tags_to_image(image_registry, deployment_container_tag, app_image_shared_tag)
|
||||||
|
logger.log(f"Tag complete")
|
||||||
|
|
||||||
# 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:
|
||||||
@ -131,13 +140,15 @@ def process_app_deployment_request(
|
|||||||
|
|
||||||
# 8. update k8s deployment
|
# 8. update k8s deployment
|
||||||
if needs_k8s_deploy:
|
if needs_k8s_deploy:
|
||||||
print("Deploying to k8s")
|
logger.log("Deploying to k8s")
|
||||||
deploy_to_k8s(
|
deploy_to_k8s(
|
||||||
deployment_record,
|
deployment_record,
|
||||||
deployment_dir,
|
deployment_dir,
|
||||||
log_file
|
logger.file
|
||||||
)
|
)
|
||||||
|
logger.log("Deploy complete")
|
||||||
|
|
||||||
|
logger.log("Publishing deployment to registry.")
|
||||||
publish_deployment(
|
publish_deployment(
|
||||||
laconic,
|
laconic,
|
||||||
app,
|
app,
|
||||||
@ -148,6 +159,8 @@ def process_app_deployment_request(
|
|||||||
deployment_dir,
|
deployment_dir,
|
||||||
app_deployment_request
|
app_deployment_request
|
||||||
)
|
)
|
||||||
|
logger.log("Publish complete.")
|
||||||
|
logger.log("END - process_app_deployment_request")
|
||||||
|
|
||||||
|
|
||||||
def load_known_requests(filename):
|
def load_known_requests(filename):
|
||||||
@ -309,8 +322,9 @@ def command(ctx, kube_config, laconic_config, image_registry, deployment_parent_
|
|||||||
run_log_file = open(run_log_file_path, "wt")
|
run_log_file = open(run_log_file_path, "wt")
|
||||||
run_reg_client = LaconicRegistryClient(laconic_config, log_file=run_log_file)
|
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(
|
process_app_deployment_request(
|
||||||
run_id,
|
|
||||||
ctx,
|
ctx,
|
||||||
run_reg_client,
|
run_reg_client,
|
||||||
r,
|
r,
|
||||||
@ -321,12 +335,14 @@ def command(ctx, kube_config, laconic_config, image_registry, deployment_parent_
|
|||||||
kube_config,
|
kube_config,
|
||||||
image_registry,
|
image_registry,
|
||||||
force_rebuild,
|
force_rebuild,
|
||||||
run_log_file
|
logger
|
||||||
)
|
)
|
||||||
status = "DEPLOYED"
|
status = "DEPLOYED"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("ERROR: " + str(e), file=run_log_file)
|
logger.log("ERROR: " + str(e))
|
||||||
finally:
|
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)
|
dump_known_requests(state_file, [r], status)
|
||||||
if run_log_file:
|
if run_log_file:
|
||||||
run_log_file.close()
|
run_log_file.close()
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <http:#www.gnu.org/licenses/>.
|
# along with this program. If not, see <http:#www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import datetime
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
@ -39,6 +40,25 @@ class AttrDict(dict):
|
|||||||
return v
|
return v
|
||||||
|
|
||||||
|
|
||||||
|
class TimedLogger:
|
||||||
|
def __init__(self, id="", file=None):
|
||||||
|
self.start = datetime.datetime.now()
|
||||||
|
self.last = self.start
|
||||||
|
self.id = id
|
||||||
|
self.file = file
|
||||||
|
|
||||||
|
def log(self, msg, show_step_time=True, show_total_time=False):
|
||||||
|
prefix = f"{datetime.datetime.utcnow()}"
|
||||||
|
if show_step_time:
|
||||||
|
prefix += f" - {datetime.datetime.now() - self.last} (step)"
|
||||||
|
if show_step_time:
|
||||||
|
prefix += f" - {datetime.datetime.now() - self.start} (total)"
|
||||||
|
prefix += f" - {self.id}"
|
||||||
|
|
||||||
|
print(f"{prefix}: {msg}", file=self.file)
|
||||||
|
self.last = datetime.datetime.now()
|
||||||
|
|
||||||
|
|
||||||
def logged_cmd(log_file, *vargs):
|
def logged_cmd(log_file, *vargs):
|
||||||
result = None
|
result = None
|
||||||
try:
|
try:
|
||||||
|
Loading…
Reference in New Issue
Block a user