Action to perform container image prepare
This action will be called in the deployment workflow just after validation. It does the following: - Fetches the plan, environment files and role data - Builds a merged environment from the fetched plans - If a ContainerImagePrepare parameter is defined, do a dry-run prepare to determine the image parameters for when the actual prepare is run during the deployment. - Write the resulting image parameters to environments/containers-default-parameters.yaml and insert that file into the environments file list in the plan This dry-run prepare is the same approach used for containerized undercloud deployment. Doing a dry-run is fast compared to a full deploy because there are no image transfers or build performed, only inspect calls to image registries. The actual prepare will be done during the deployment when change I8b0c5e630e63ef6a2e6f70f1eb00fd02f4cfd1c0 lands. Blueprint: container-prepare-workflow Change-Id: Id5a4bec2d82e69ef53e7809984b4adba67deef3e
This commit is contained in:
@@ -83,6 +83,7 @@ mistral.actions =
|
||||
tripleo.config.download_config = tripleo_common.actions.config:DownloadConfigAction
|
||||
tripleo.config.get_overcloud_config = tripleo_common.actions.config:GetOvercloudConfig
|
||||
tripleo.container_images.prepare = tripleo_common.actions.container_images:PrepareContainerImageEnv
|
||||
tripleo.container_images.prepare_params = tripleo_common.actions.container_images:PrepareContainerImageParameters
|
||||
tripleo.deployment.config = tripleo_common.actions.deployment:OrchestrationDeployAction
|
||||
tripleo.deployment.deploy = tripleo_common.actions.deployment:DeployStackAction
|
||||
tripleo.deployment.get_deployment_failures = tripleo_common.actions.deployment:DeploymentFailuresAction
|
||||
|
@@ -13,12 +13,12 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
from mistral_lib import actions
|
||||
import six
|
||||
from swiftclient import exceptions as swiftexceptions
|
||||
import yaml
|
||||
|
||||
@@ -26,6 +26,7 @@ from tripleo_common.actions import base
|
||||
from tripleo_common.actions import heat_capabilities
|
||||
from tripleo_common import constants
|
||||
from tripleo_common.image import kolla_builder
|
||||
from tripleo_common.utils import plan as plan_utils
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@@ -81,3 +82,74 @@ class PrepareContainerImageEnv(base.TripleOAction):
|
||||
update_action = heat_capabilities.UpdateCapabilitiesAction(
|
||||
environments, container=self.container)
|
||||
return update_action.run(context)
|
||||
|
||||
|
||||
class PrepareContainerImageParameters(base.TripleOAction):
|
||||
"""Populate environment with image params
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, container=constants.DEFAULT_CONTAINER_NAME):
|
||||
super(PrepareContainerImageParameters, self).__init__()
|
||||
self.container = container
|
||||
|
||||
def _get_role_data(self, swift):
|
||||
try:
|
||||
j2_role_file = swift.get_object(
|
||||
self.container, constants.OVERCLOUD_J2_ROLES_NAME)[1]
|
||||
role_data = yaml.safe_load(j2_role_file)
|
||||
except swiftexceptions.ClientException:
|
||||
LOG.info("No %s file found, not filtering container images by role"
|
||||
% constants.OVERCLOUD_J2_ROLES_NAME)
|
||||
role_data = None
|
||||
return role_data
|
||||
|
||||
def run(self, context):
|
||||
self.context = context
|
||||
swift = self.get_object_client(context)
|
||||
|
||||
try:
|
||||
plan_env = plan_utils.get_env(swift, self.container)
|
||||
except swiftexceptions.ClientException as err:
|
||||
err_msg = ("Error retrieving environment for plan %s: %s" % (
|
||||
self.container, err))
|
||||
LOG.exception(err_msg)
|
||||
return actions.Result(error=err_msg)
|
||||
|
||||
try:
|
||||
env_paths, temp_env_paths = plan_utils.build_env_paths(
|
||||
swift, self.container, plan_env)
|
||||
env_files, env = plan_utils.process_environments_and_files(
|
||||
swift, env_paths)
|
||||
|
||||
role_data = self._get_role_data(swift)
|
||||
image_params = kolla_builder.container_images_prepare_multi(
|
||||
env, role_data, dry_run=True)
|
||||
except Exception as err:
|
||||
LOG.exception("Error occurred while processing plan files.")
|
||||
return actions.Result(error=six.text_type(err))
|
||||
finally:
|
||||
# cleanup any local temp files
|
||||
for f in temp_env_paths:
|
||||
os.remove(f)
|
||||
|
||||
try:
|
||||
swift.put_object(
|
||||
self.container,
|
||||
constants.CONTAINER_DEFAULTS_ENVIRONMENT,
|
||||
yaml.safe_dump(
|
||||
{'parameter_defaults': image_params},
|
||||
default_flow_style=False
|
||||
)
|
||||
)
|
||||
except swiftexceptions.ClientException as err:
|
||||
err_msg = ("Error updating %s for plan %s: %s" % (
|
||||
constants.CONTAINER_DEFAULTS_ENVIRONMENT, self.container, err))
|
||||
LOG.exception(err_msg)
|
||||
return actions.Result(error=err_msg)
|
||||
|
||||
environments = {constants.CONTAINER_DEFAULTS_ENVIRONMENT: True}
|
||||
|
||||
update_action = heat_capabilities.UpdateCapabilitiesAction(
|
||||
environments, container=self.container)
|
||||
return update_action.run(context)
|
||||
|
@@ -116,3 +116,56 @@ class PrepareContainerImageEnvTest(base.TestCase):
|
||||
'for plan overcloud: nope',
|
||||
action.run(self.ctx).error
|
||||
)
|
||||
|
||||
|
||||
class PrepareContainerImageParametersTest(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(PrepareContainerImageParametersTest, self).setUp()
|
||||
self.ctx = mock.MagicMock()
|
||||
|
||||
@mock.patch("tripleo_common.actions.container_images."
|
||||
"PrepareContainerImageParameters._get_role_data")
|
||||
@mock.patch("tripleo_common.actions.container_images."
|
||||
"PrepareContainerImageParameters.get_object_client")
|
||||
@mock.patch("tripleo_common.actions.heat_capabilities."
|
||||
"UpdateCapabilitiesAction")
|
||||
@mock.patch("tripleo_common.utils.plan.get_env", autospec=True)
|
||||
@mock.patch("tripleo_common.image.kolla_builder."
|
||||
"container_images_prepare_multi")
|
||||
def test_run(self, prepare, get_env, update_action, goc, grd):
|
||||
plan = {
|
||||
'version': '1.0',
|
||||
'environments': [],
|
||||
'parameter_defaults': {}
|
||||
}
|
||||
role_data = [{'name': 'Controller'}]
|
||||
final_env = {'environments': [
|
||||
{'path': 'overcloud-resource-registry-puppet.yaml'},
|
||||
{'path': 'environments/containers-default-parameters.yaml'},
|
||||
{'path': 'user-environment.yaml'}
|
||||
]}
|
||||
image_params = {'FooContainerImage': '192.0.2.1/foo/image'}
|
||||
image_env_contents = yaml.safe_dump(
|
||||
{'parameter_defaults': image_params},
|
||||
default_flow_style=False
|
||||
)
|
||||
|
||||
swift = goc.return_value
|
||||
swift.get_object.return_value = role_data
|
||||
prepare.return_value = image_params
|
||||
grd.return_value = role_data
|
||||
|
||||
get_env.return_value = plan
|
||||
update_action.return_value.run.return_value = final_env
|
||||
action = container_images.PrepareContainerImageParameters(
|
||||
container='overcloud')
|
||||
self.assertEqual(final_env, action.run(self.ctx))
|
||||
|
||||
get_env.assert_called_once_with(swift, 'overcloud')
|
||||
prepare.assert_called_once_with({}, role_data, dry_run=True)
|
||||
swift.put_object.assert_called_once_with(
|
||||
'overcloud',
|
||||
'environments/containers-default-parameters.yaml',
|
||||
image_env_contents
|
||||
)
|
||||
|
Reference in New Issue
Block a user