Ensure deletion of conditional charts on application-remove

Armada delete does not support --value overrides files, so any
conditional manifest changes applied via overrides during apply will not
be reflected when the manifest is applied during delete.

With the addition of the ArmadaManifestOperator, a final view of the
manifest can be generated so that the armada delete has an accurate view
of what needs to be cleaned up.

Create this file an use it during the application-remove instead of the
original manifest.

Change-Id: I20191656805c5d8a419dbdeb7d2e97f87c5b2f2c
Depends-On: I7e0c5bbe7daa0b0b8365ca1ed5f8fdf11a348c62
Closes-Bug: #1833718
Signed-off-by: Robert Church <robert.church@windriver.com>
This commit is contained in:
Robert Church 2019-07-10 23:38:36 -04:00
parent e6b177eb93
commit 41a74dca8d
3 changed files with 56 additions and 5 deletions

View File

@ -2113,8 +2113,13 @@ class DockerHelper(object):
LOG.info("Application releases %s were successfully "
"rolled back." % app_releases)
elif request == constants.APP_DELETE_OP:
# Since armada delete doesn't support --values overrides
# files, use the delete manifest generated from the
# ArmadaManifestOperator during overrides generation. It
# will contain an accurate view of what was applied
manifest_delete_file = "%s-del%s" % os.path.splitext(manifest_file)
cmd = "/bin/bash -c 'set -o pipefail; armada delete --debug " +\
"--manifest " + manifest_file + tiller_host + " | tee " +\
"--manifest " + manifest_delete_file + tiller_host + " | tee " +\
logfile + "'"
(exit_code, exec_logs) = armada_svc.exec_run(cmd)
if exit_code == 0:

View File

@ -550,9 +550,11 @@ class HelmOperator(object):
manifest.platform_mode_manifest_updates(
self.dbapi, manifest_op, app_name, mode)
# Write the manifest doc overrides for the chart, chart group and manifest
manifest_op.save()
# Write the manifest doc overrides, a summmary file for easy --value
# generation on the apply, and a unified manifest for deletion.
manifest_op.save_overrides()
manifest_op.save_summary(path=path)
manifest_op.save_delete_manifest()
else:
# Generic applications

View File

@ -48,7 +48,8 @@ SUMMARY_FILE = 'armada-overrides.yaml'
class ArmadaManifestOperator(object):
def __init__(self, manifest_fqpn=None):
self.manifest_path = None # Location to write overrides
self.manifest_path = None # Location to write overrides
self.delete_manifest = None # Unified manifest for app deletion
self.content = [] # original app manifest content
@ -98,7 +99,12 @@ class ArmadaManifestOperator(object):
:param manifest_fqpn: fully qualified path name of the application manifest
"""
if os.path.exists(manifest_fqpn):
# Save the path for writing overrides files
self.manifest_path = os.path.dirname(manifest_fqpn)
# Save the name for a delete manifest
self.delete_manifest = "%s-del%s" % os.path.splitext(manifest_fqpn)
with open(manifest_fqpn, 'r') as f:
self.content = list(yaml.load_all(
f, Loader=yaml.RoundTripLoader))
@ -135,6 +141,12 @@ class ArmadaManifestOperator(object):
for f in glob(filepath):
os.remove(f)
def _cleanup_deletion_manifest(self):
""" Remove any previously written deletion manifest
"""
if self.delete_manifest and os.path.exists(self.delete_manifest):
os.remove(self.delete_manifest)
def _write_file(self, path, filename, pathfilename, data):
""" Write a yaml file
@ -186,7 +198,7 @@ class ArmadaManifestOperator(object):
os.path.join(self.manifest_path, SUMMARY_FILE),
files_written)
def save(self):
def save_overrides(self):
""" Save the overrides files
Write the elements of the manifest (manifest, chart_group, chart) that
@ -208,6 +220,38 @@ class ArmadaManifestOperator(object):
else:
LOG.error("Manifest directory %s does not exist" % self.manifest_path)
def save_delete_manifest(self):
""" Save an updated manifest for deletion
armada delete doesn't support --values files as does the apply. To
handle proper deletion of the conditional charts/chart groups that end
up in the overrides files, create a unified file for use when deleting.
NOTE #1: If we want to abandon using manifest overrides files altogether,
this generated file could probably be used on apply and delete.
NOTE #2: Diffing the original manifest and this manifest provides a
clear view of the conditional changes that were enforced by the system
in the plugins
"""
if os.path.exists(self.manifest_path):
# cleanup existing deletion manifest
self._cleanup_deletion_manifest()
with open(self.delete_manifest, 'w') as f:
try:
yaml.dump_all(self.content, f, Dumper=yaml.RoundTripDumper,
explicit_start=True,
default_flow_style=False)
LOG.info("Delete manifest file %s generated" %
self.delete_manifest)
except Exception as e:
LOG.error("Failed to generate delete manifest file %s: "
"%s" % (self.delete_manifest, e))
else:
LOG.error("Manifest directory %s does not exist" % self.manifest_path)
def _validate_manifest(self, manifest):
""" Ensure that the manifest is known