for primitive in vnfr.primitive:
if primitive.execution_status == "failure":
errs += '<error>'
- errs += primitive.execution_error_details
+ if primitive.execution_error_details:
+ errs += primitive.execution_error_details
+ else:
+ errs += '{}: Unknown error'.format(primitive.name)
errs += "</error>"
return errs
job_status = []
for primitive in vnfr.primitive:
+ if primitive.execution_status != 'pending':
+ continue
+
if primitive.execution_id == "":
- # TODO: For some config data, the id will be empty, check if
- # mapping is needed.
+ # Actions which failed to queue can have empty id
job_status.append(primitive.execution_status)
continue
- task = self.loop.create_task(self.get_primitive_status(primitive))
+ elif primitive.execution_id == "config":
+ # Config job. Check if service is active
+ task = self.loop.create_task(self.get_service_status(vnfr.id, primitive))
+
+ else:
+ task = self.loop.create_task(self.get_primitive_status(primitive))
+
tasks.append(task)
if tasks:
vnfr.vnf_job_status = "success"
return "success"
+ @asyncio.coroutine
+ def get_service_status(self, vnfr_id, primitive):
+ try:
+ status = yield from self.loop.run_in_executor(
+ self.executor,
+ self.config_plugin.get_service_status,
+ vnfr_id
+ )
+
+ self.log.debug("Service status: {}".format(status))
+ if status in ['error', 'blocked']:
+ self.log.warning("Execution of config {} failed: {}".
+ format(primitive.execution_id, status))
+ primitive.execution_error_details = 'Config failed'
+ status = 'failure'
+ elif status in ['active']:
+ status = 'success'
+ elif status is None:
+ status = 'failure'
+ else:
+ status = 'pending'
+
+ except Exception as e:
+ self.log.exception(e)
+ status = "failed"
+
+ primitive.execution_status = status
+ return primitive.execution_status
+
@asyncio.coroutine
def get_primitive_status(self, primitive):
"""
self.log.debug("Creating a job monitor for Job id: {}".format(
rpc_output.job_id))
+ # If the tasks are none, assume juju actions
+ # TBD: This logic need to be revisited
+ ca = self.nsm.config_agent_plugins[0]
+ if tasks is None:
+ for agent in self.nsm.config_agent_plugins:
+ if agent.agent_type == 'juju':
+ ca = agent
+ break
+
# For every Job we will schedule a new monitoring process.
job_monitor = ConfigAgentJobMonitor(
self.dts,
self.jobs[nsr_id],
self.executor,
self.loop,
- self.nsm.config_agent_plugins[0] # Hack
+ ca
)
task = self.loop.create_task(job_monitor.publish_action_status())
except Exception as e:
msg = "{}: Resolve on unit {}: {}". \
format(self, unit, e)
- self.log.error(msg)
- self.log.exception(e)
- raise JujuResolveError(msg)
+ self.log.warn(msg)
@asyncio.coroutine
def resolve_error(self, service=None, status=None, env=None):
for vnfr_id in agent_nsr.vnfr_ids:
vnfr = agent_vnfrs[vnfr_id]
- self._log.debug("CA_RPC: VNFR metadata: {}".format(vnfr))
+ self._log.debug("CA-RPC: VNFR metadata: {}".format(vnfr))
# index->vnfr ref
vnfr_index_map[vnfr.member_vnf_index] = vnfr_id
for primitive in vnfr.vnf_configuration['initial_config_primitive']:
if 'parameter' in primitive:
for parameter in primitive['parameter']:
- value = xlate(parameter['value'], vnfr.tags)
- param_data[parameter.name] = value
+ try:
+ value = xlate(parameter['value'], vnfr.tags)
+ param_data[parameter['name']] = value
+ except KeyError as e:
+ self._log.warn("Unable to parse the parameter{}: {}".
+ format(parameter))
initial_params[vnfr_id] = param_data
return config_plugin.agent_data
return ret
- unit_names, init_data, vnfr_index_map, vnf_data_map = get_meta(agent_nsr, agent_vnfrs)
+ unit_names, init_data, vnfr_index_map, vnfr_data_map = get_meta(agent_nsr, agent_vnfrs)
# The data consists of 4 sections
# 1. Account data
tmp_file.write(yaml.dump(data, default_flow_style=True)
.encode("UTF-8"))
- self._log.debug("CA_RPC: Creating a temp file {} with input data: {}".
+ self._log.debug("CA-RPC: Creating a temp file {} with input data: {}".
format(tmp_file.name, data))
# Get the full path to the script
else:
script = os.path.join(self._rift_artif_dir, 'launchpad/libs', agent_nsr.id, 'scripts',
rpc_ip.user_defined_script)
- self.log.debug("CA_RPC: Checking for script in %s", script)
+ self._log.debug("CA-RPC: Checking for script in %s", script)
if not os.path.exists(script):
script = os.path.join(self._rift_install_dir, 'usr/bin', rpc_ip.user_defined_script)
cmd = "{} {}".format(rpc_ip.user_defined_script, tmp_file.name)
- self._log.debug("CA_RPC: Running the CMD: {}".format(cmd))
+ self._log.debug("CA-RPC: Running the CMD: {}".format(cmd))
coro = asyncio.create_subprocess_shell(cmd, loop=self._loop,
stderr=asyncio.subprocess.PIPE)
#
import asyncio
+import os
import re
import tempfile
+import time
import yaml
-import os
import rift.mano.utils.juju_api as juju
from . import riftcm_config_plugin
def vnf_config_primitive(self, nsr_id, vnfr_id, primitive, output):
self._log.debug("jujuCA: VNF config primititve {} for nsr {}, vnfr_id {}".
format(primitive, nsr_id, vnfr_id))
- output.execution_status = "failed"
- output.execution_id = ''
- output.execution_error_details = ''
-
try:
vnfr = self._juju_vnfs[vnfr_id].vnfr
except KeyError:
vnfr_id)
return
+ output.execution_status = "failed"
+ output.execution_id = ''
+ output.execution_error_details = ''
+
try:
service = vnfr['vnf_juju_name']
vnf_config = vnfr['config']
params.update({parameter.name: val})
if config.name == 'config':
+ output.execution_id = 'config'
if len(params):
self._log.debug("jujuCA: applying config with params {} for service {}".
format(params, service))
- rc = yield from self.api.apply_config(params, service=service)
+ rc = yield from self.api.apply_config(params, service=service, wait=False)
if rc:
- output.execution_status = "completed"
+ # Mark as pending and check later for the status
+ output.execution_status = "pending"
self._log.debug("jujuCA: applied config {} on {}".
format(params, service))
else:
self._log.error("jujuCA: Error applying config {} on service {}".
format(params, service))
else:
- self._log.warn("jujuCA: Did not find valid paramaters for config : {}".
+ self._log.warn("jujuCA: Did not find valid parameters for config : {}".
format(primitive.parameter))
+ output.execution_status = "completed"
else:
self._log.debug("jujuCA: Execute action {} on service {} with params {}".
format(config.name, service, params))
resp = yield from self.api.execute_action(action, params,
service=service)
if 'error' in resp:
- self._log.error("Applying initial config failed for {} with {}: {}".
- format(action, params, resp))
+ self._log.error("Applying initial config on {} failed for {} with {}: {}".
+ format(vnfr['vnf_juju_name'], action, params, resp))
return False
action_ids.append(resp['action']['tag'])
execution_id)
self._log.exception(e)
raise e
+
+ def get_service_status(self, vnfr_id):
+ '''Get the service status, used by job status handle
+ Make sure this is NOT a coroutine
+ '''
+ service = self.get_service_name(vnfr_id)
+ if service is None:
+ self._log.error("jujuCA: VNFR {} not managed by this Juju agent".
+ format(vnfr_id))
+ return None
+
+ # Delay for 3 seconds before checking as config apply takes a
+ # few seconds to transfer to the service
+ time.sleep(3)
+ return self.api._get_service_status(service=service)
""" Add VNR to be managed by this config agent """
pass
+ def get_service_status(self, vnfr_id):
+ """Get the status of the service"""
+ return None
+
@asyncio.coroutine
def invoke(self, method, *args):
try: