예제 #1
0
    def _heat_deploy(self, stack, stack_name, template_path, parameters,
                     env_files, timeout, tht_root, env, update_plan_only,
                     run_validations, skip_deploy_identifier, plan_env_file,
                     deployment_options=None):
        """Verify the Baremetal nodes are available and do a stack update"""

        if stack:
            self.log.debug(
                "Checking compatibilities of neutron drivers for {0}".format(
                    stack_name))
            msg = update.check_neutron_mechanism_drivers(
                env, stack, self.object_client, stack_name)
            if msg:
                raise oscexc.CommandError(msg)

        self.log.debug("Getting template contents from plan %s" % stack_name)
        # We need to reference the plan here, not the local
        # tht root, as we need template_object to refer to
        # the rendered overcloud.yaml, not the tht_root overcloud.j2.yaml
        # FIXME(shardy) we need to move more of this into mistral actions
        plan_yaml_path = os.path.relpath(template_path, tht_root)

        # heatclient template_utils needs a function that can
        # retrieve objects from a container by name/path
        def do_object_request(method='GET', object_path=None):
            obj = self.object_client.get_object(stack_name, object_path)
            return obj and obj[1]

        template_files, template = template_utils.get_template_contents(
            template_object=plan_yaml_path,
            object_request=do_object_request)

        files = dict(list(template_files.items()) + list(env_files.items()))

        moved_files = self._upload_missing_files(
            stack_name, files, tht_root)
        self._process_and_upload_environment(
            stack_name, env, moved_files, tht_root)

        # Invokes the workflows specified in plan environment file
        if plan_env_file:
            workflow_params.invoke_plan_env_workflows(self.clients,
                                                      stack_name,
                                                      plan_env_file)

        workflow_params.check_deprecated_parameters(self.clients, stack_name)

        if not update_plan_only:
            print("Deploying templates in the directory {0}".format(
                os.path.abspath(tht_root)))
            deployment.deploy_and_wait(
                self.log, self.clients, stack,
                stack_name, self.app_args.verbose_level,
                timeout=timeout,
                run_validations=run_validations,
                skip_deploy_identifier=skip_deploy_identifier,
                deployment_options=deployment_options)
예제 #2
0
 def test_update_check_mechanism_drivers_match_stack_env(self,
                                                         mock_search_stack,
                                                         mock_ex_driver):
     env = {'parameter_defaults': {
         'ForceNeutronDriverUpdate': False,
         'NeutronMechanismDrivers': 'ovn'
     }}
     stack = mock.Mock()
     self.assertIsNone(update.check_neutron_mechanism_drivers(
         env, stack, None, None))
예제 #3
0
 def test_update_check_mechanism_drivers_match_stack_template(
         self, mock_search_stack):
     env = {'parameter_defaults': {'ForceNeutronDriverUpdate': False}}
     stack = mock.Mock()
     plan_client = mock.Mock()
     plan_client.get_object.return_value = (
         0, 'parameters:\n  NeutronMechanismDrivers: {default: ovn}\n')
     self.assertIsNone(
         update.check_neutron_mechanism_drivers(env, stack, plan_client,
                                                None))
예제 #4
0
    def run(self, context):
        # check to see if the stack exists
        heat = self.get_orchestration_client(context)
        try:
            stack = heat.stacks.get(self.container, resolve_outputs=False)
        except heat_exc.HTTPNotFound:
            stack = None

        stack_is_new = stack is None

        # update StackAction, DeployIdentifier and UpdateIdentifier
        swift = self.get_object_client(context)

        parameters = dict()
        if not self.skip_deploy_identifier:
            parameters['DeployIdentifier'] = int(time.time())
        parameters['UpdateIdentifier'] = ''
        parameters['StackAction'] = 'CREATE' if stack_is_new else 'UPDATE'

        try:
            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)

        self.set_tls_parameters(parameters, env)
        try:
            plan_utils.update_in_env(swift, env, 'parameter_defaults',
                                     parameters)
        except swiftexceptions.ClientException as err:
            err_msg = ("Error updating environment for plan %s: %s" %
                       (self.container, err))
            LOG.exception(err_msg)
            return actions.Result(error=err_msg)

        if not stack_is_new:
            try:
                LOG.debug('Checking for compatible neutron mechanism drivers')
                msg = update.check_neutron_mechanism_drivers(
                    env, stack, swift, self.container)
                if msg:
                    return actions.Result(error=msg)
            except swiftexceptions.ClientException as err:
                err_msg = ("Error getting template %s: %s" %
                           (self.container, err))
                LOG.exception(err_msg)
                return actions.Result(error=err_msg)

        # process all plan files and create or update a stack
        process_templates_action = templates.ProcessTemplatesAction(
            container=self.container)
        processed_data = process_templates_action.run(context)

        # If we receive a 'Result' instance it is because the parent action
        # had an error.
        if isinstance(processed_data, actions.Result):
            return processed_data

        stack_args = processed_data.copy()
        stack_args['timeout_mins'] = self.timeout_mins

        if stack_is_new:
            try:
                swift.copy_object(
                    "%s-swift-rings" % self.container, "swift-rings.tar.gz",
                    "%s-swift-rings/%s-%d" %
                    (self.container, "swift-rings.tar.gz", time.time()))
                swift.delete_object("%s-swift-rings" % self.container,
                                    "swift-rings.tar.gz")
            except swiftexceptions.ClientException:
                pass
            LOG.info("Perfoming Heat stack create")
            try:
                return heat.stacks.create(**stack_args)
            except heat_exc.HTTPException as err:
                err_msg = "Error during stack creation: %s" % (err, )
                LOG.exception(err_msg)
                return actions.Result(error=err_msg)

        LOG.info("Performing Heat stack update")
        stack_args['existing'] = 'true'
        try:
            return heat.stacks.update(stack.id, **stack_args)
        except heat_exc.HTTPException as err:
            err_msg = "Error during stack update: %s" % (err, )
            LOG.exception(err_msg)
            return actions.Result(error=err_msg)
예제 #5
0
 def test_update_check_mechanism_drivers_force_update(self,
                                                      mock_search_stack):
     env = {'parameter_defaults': {'ForceNeutronDriverUpdate': True}}
     stack = mock.Mock()
     update.check_neutron_mechanism_drivers(env, stack, None, None)
     self.assertFalse(mock_search_stack.called)
예제 #6
0
    def run(self, context):
        # check to see if the stack exists
        heat = self.get_orchestration_client(context)
        try:
            stack = heat.stacks.get(self.container, resolve_outputs=False)
        except heat_exc.HTTPNotFound:
            stack = None

        stack_is_new = stack is None

        # update StackAction, DeployIdentifier and UpdateIdentifier
        swift = self.get_object_client(context)

        parameters = dict()
        if not self.skip_deploy_identifier:
            parameters['DeployIdentifier'] = int(time.time())
        parameters['UpdateIdentifier'] = ''
        parameters['StackAction'] = 'CREATE' if stack_is_new else 'UPDATE'

        try:
            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)

        self.set_tls_parameters(parameters, env)
        try:
            plan_utils.update_in_env(swift, env, 'parameter_defaults',
                                     parameters)
        except swiftexceptions.ClientException as err:
            err_msg = ("Error updating environment for plan %s: %s" % (
                self.container, err))
            LOG.exception(err_msg)
            return actions.Result(error=err_msg)

        if not stack_is_new:
            try:
                LOG.debug('Checking for compatible neutron mechanism drivers')
                msg = update.check_neutron_mechanism_drivers(env, stack,
                                                             swift,
                                                             self.container)
                if msg:
                    return actions.Result(error=msg)
            except swiftexceptions.ClientException as err:
                err_msg = ("Error getting template %s: %s" % (
                    self.container, err))
                LOG.exception(err_msg)
                return actions.Result(error=err_msg)

        # process all plan files and create or update a stack
        processed_data = super(DeployStackAction, self).run(context)

        # If we receive a 'Result' instance it is because the parent action
        # had an error.
        if isinstance(processed_data, actions.Result):
            return processed_data

        stack_args = processed_data.copy()
        stack_args['timeout_mins'] = self.timeout_mins

        if stack_is_new:
            try:
                swift.copy_object(
                    "%s-swift-rings" % self.container, "swift-rings.tar.gz",
                    "%s-swift-rings/%s-%d" % (
                        self.container, "swift-rings.tar.gz", time.time()))
                swift.delete_object(
                    "%s-swift-rings" % self.container, "swift-rings.tar.gz")
            except swiftexceptions.ClientException:
                pass
            LOG.info("Perfoming Heat stack create")
            try:
                return heat.stacks.create(**stack_args)
            except heat_exc.HTTPException as err:
                err_msg = "Error during stack creation: %s" % (err,)
                LOG.exception(err_msg)
                return actions.Result(error=err_msg)

        LOG.info("Performing Heat stack update")
        stack_args['existing'] = 'true'
        try:
            return heat.stacks.update(stack.id, **stack_args)
        except heat_exc.HTTPException as err:
            err_msg = "Error during stack update: %s" % (err,)
            LOG.exception(err_msg)
            return actions.Result(error=err_msg)