Solve the stx-openstack reapply issue on controller-1

After stx-openstack applied, the stx-openstack reapply shouldn't
trigger the charts reinstallation if there has no overrides changed
for charts. However, the reinstallation happens after swacting active
controller to controller-1 due to the generated images overrides on
controller-1 are different from before. The images overrides generation
requires walking through the stx-openstack charts stored under
/scratch, but charts do not exist on controller-1's /scratch as it's
an unreplicated filesystem. This causes the images overrides to differ
between controller-1 and controller-0.

This commit updates to walk through charts and get the images for
charts during application-upload, then save the images list for each
chart into the existing images file under aramda directory
/opt/platform/armada. The images file would be used for retrieving
the images for charts to generate images overrides.

Closes-Bug: 1816173
Change-Id: I4f00c3031decb063f8f126d0c837acd4dde56fc3
Signed-off-by: Angie Wang <angie.wang@windriver.com>
This commit is contained in:
Angie Wang 2019-02-22 01:21:07 -05:00
parent 234c04aee2
commit cb4b30bf56
2 changed files with 55 additions and 34 deletions

View File

@ -1,2 +1,2 @@
SRC_DIR="sysinv"
TIS_PATCH_VER=305
TIS_PATCH_VER=306

View File

@ -309,30 +309,26 @@ class AppOperator(object):
image_tags = []
ids = []
for r, f in cutils.get_files_matching(path, 'values.yaml'):
with open(os.path.join(r, f), 'r') as file:
with open(os.path.join(r, f), 'r') as value_f:
try:
y = yaml.load(file)
y = yaml.load(value_f)
ids = y["images"]["tags"].values()
except (TypeError, KeyError):
pass
image_tags.extend(ids)
return list(set(image_tags))
def _get_image_tags_by_charts(self, app_path, charts):
""" Mine the image tags from the chart paths. Add the converted
image tags to the overrides if the image tags from the chart
paths do not exist. Intended for system app.
def _get_image_tags_by_charts(self, app_images_file, charts):
""" Mine the image tags for charts from the images file. Add the
converted image tags to the overrides if the image tags from
the charts do not exist. Intended for system app.
The image tagging conversion(local docker registry address prepended):
${LOCAL_DOCKER_REGISTRY_IP}:${REGISTRY_PORT}/<image-name>
(ie..192.168.204.2:9001/docker.io/mariadb:10.2.13)
"""
local_docker_registry_ip = self._dbapi.address_get_by_name(
cutils.format_address_name(constants.CONTROLLER_HOSTNAME,
constants.NETWORK_TYPE_MGMT)
).address
local_registry_server = self._docker.get_local_docker_registry_server()
image_tags = []
for chart in charts:
images_charts = {}
@ -340,23 +336,21 @@ class AppOperator(object):
overrides = chart.namespace + '-' + chart.name + '.yaml'
overrides_file = os.path.join(common.HELM_OVERRIDES_PATH,
overrides)
chart_name = os.path.join(app_path, chart.name)
chart_path = os.path.join(chart_name, 'values.yaml')
# Get the image tags from the chart path
if os.path.exists(chart_path):
with open(chart_path, 'r') as file:
# Get the image tags by chart from the images file
if os.path.exists(app_images_file):
with open(app_images_file, 'r') as f:
try:
doc = yaml.load(file)
images_charts = doc["images"]["tags"]
doc = yaml.load(f)
images_charts = doc[chart.name]
except (TypeError, KeyError):
pass
# Get the image tags from the overrides file
if os.path.exists(overrides_file):
with open(overrides_file, 'r') as file:
with open(overrides_file, 'r') as f:
try:
y = yaml.load(file)
y = yaml.load(f)
images_overrides = y["data"]["values"]["images"]["tags"]
except (TypeError, KeyError):
LOG.info("Overrides file %s has no img tags" %
@ -368,22 +362,22 @@ class AppOperator(object):
tags_updated = False
for key, image_tag in images_charts.items():
if (key not in images_overrides and
not image_tag.startswith(local_docker_registry_ip)):
not image_tag.startswith(local_registry_server)):
images_overrides.update(
{key: '{}:{}/{}'.format(local_docker_registry_ip, common.REGISTRY_PORT, image_tag)})
{key: '{}/{}'.format(local_registry_server, image_tag)})
tags_updated = True
if tags_updated:
with open(overrides_file, 'w') as file:
with open(overrides_file, 'w') as f:
try:
if "images" not in y["data"]["values"]:
file.seek(0)
file.truncate()
f.seek(0)
f.truncate()
y["data"]["values"]["images"] = {"tags": images_overrides}
else:
y["data"]["values"]["images"]["tags"] = images_overrides
yaml.safe_dump(y, file, explicit_start=True,
yaml.safe_dump(y, f, explicit_start=True,
default_flow_style=False)
LOG.info("Overrides file %s updated with new image tags" %
overrides_file)
@ -421,9 +415,10 @@ class AppOperator(object):
self._helm.generate_helm_application_overrides(
app.name, cnamespace=None, armada_format=True, combined=True)
app.charts = self._get_list_of_charts(app.armada_mfile_abs)
self._save_images_list_by_charts(app)
# Get the list of images from the updated images overrides
images_to_download = self._get_image_tags_by_charts(
app.charts_dir, app.charts)
app.imgfile_abs, app.charts)
else:
# For custom apps, mine image tags from application path
images_to_download = self._get_image_tags_by_path(app.path)
@ -436,8 +431,31 @@ class AppOperator(object):
name=app.name,
reason="charts specify no docker images.")
with open(app.imgfile_abs, 'ab') as f:
yaml.safe_dump({"download_images": images_to_download}, f,
default_flow_style=False)
def _save_images_list_by_charts(self, app):
# Mine the images from values.yaml files in the charts directory.
# The list of images for each chart are saved to the images file.
images_by_charts = {}
for chart in app.charts:
images = {}
chart_name = os.path.join(app.charts_dir, chart.name)
chart_path = os.path.join(chart_name, 'values.yaml')
if os.path.exists(chart_path):
with open(chart_path, 'r') as f:
try:
y = yaml.load(f)
images = y["images"]["tags"]
except (TypeError, KeyError):
LOG.warn("Chart %s has no image tags" % chart_name)
if images:
images_by_charts.update({chart.name: images})
with open(app.imgfile_abs, 'wb') as f:
yaml.safe_dump(images_to_download, f, explicit_start=True,
yaml.safe_dump(images_by_charts, f, explicit_start=True,
default_flow_style=False)
def _retrieve_images_list(self, app_images_file):
@ -454,16 +472,19 @@ class AppOperator(object):
# between upload and apply, or between applies. Refresh the
# saved images list.
saved_images_list = self._retrieve_images_list(app.imgfile_abs)
combined_images_list = list(saved_images_list)
saved_download_images_list = saved_images_list.get("download_images")
combined_images_list = list(saved_download_images_list)
combined_images_list.extend(
self._get_image_tags_by_charts(app.charts_dir, app.charts))
self._get_image_tags_by_charts(app.imgfile_abs, app.charts))
images_to_download = list(set(combined_images_list))
if saved_images_list != images_to_download:
if set(saved_download_images_list) != set(images_to_download):
saved_images_list.update({"download_images": images_to_download})
with open(app.imgfile_abs, 'wb') as f:
yaml.safe_dump(images_to_download, f, explicit_start=True,
yaml.safe_dump(saved_images_list, f, explicit_start=True,
default_flow_style=False)
else:
images_to_download = self._retrieve_images_list(app.imgfile_abs)
images_to_download = self._retrieve_images_list(
app.imgfile_abs).get("download_images")
total_count = len(images_to_download)
threads = min(MAX_DOWNLOAD_THREAD, total_count)