Support download

Add support for downloading software changes and plugins
Default download directory is /tmp/<session_id>
Download url with filename including 'workflow' or 'actions'
are automatically extracted to /tmp/<session_id>/<workflow|actions>
Plugins will be used straight from those directories is Fenix
did not have a plugin with the same name.
Download directory and content will be automatically removed
when session is deleted by the admin

story: 2004147
Task: #27620

Change-Id: Ia1cce13d268da1888f5d8f02d39099b3c113fb86
Signed-off-by: Tomi Juvonen <tomi.juvonen@nokia.com>
This commit is contained in:
Tomi Juvonen
2019-04-28 10:03:46 +03:00
parent 8a375d8417
commit 24bf1a2563
9 changed files with 255 additions and 13 deletions

View File

@@ -23,6 +23,7 @@ from threading import Thread
import time
from fenix.db import api as db_api
from fenix.utils.download import url_to_filename
from fenix.utils.identity_auth import get_identity_auth
from fenix.utils.identity_auth import get_session
@@ -50,6 +51,11 @@ class BaseWorkflow(Thread):
self.actions = self._init_action_plugins(data["actions"])
else:
self.actions = []
if "download" in data:
self.downloads = self._init_downloads(data["download"])
else:
self.downloads = []
self.projects = []
self.instances = []
self.proj_instance_actions = {}
@@ -98,6 +104,21 @@ class BaseWorkflow(Thread):
else:
return data
def _init_downloads(self, download_urls):
downloads = []
session_dir = "%s/%s" % (self.conf.engine.local_cache_dir,
self.session_id)
for url in download_urls:
LOG.info('%s: Download %s' % (self.session_id, url))
local_file = url_to_filename(session_dir, url)
if local_file is None:
raise Exception("cannot make filename from: %s " % url)
ddict = {
'session_id': self.session_id,
'local_file': local_file}
downloads.append(ddict)
return db_api.create_downloads(downloads)
def _init_session(self, data):
session = {
'session_id': self.session_id,

View File

@@ -14,11 +14,26 @@
# under the License.
import datetime
from importlib import import_module
try:
from importlib.machinery import SourceFileLoader
def mod_loader_action_instance(mname, mpath, session_instance,
ap_db_instance):
mi = SourceFileLoader(mname, mpath).load_module()
return mi.ActionPlugin(session_instance, ap_db_instance)
except ImportError:
from imp import load_source
def mod_loader_action_instance(mname, mpath, session_instance,
ap_db_instance):
mi = load_source(mname, mpath)
return mi.ActionPlugin(session_instance, ap_db_instance)
from novaclient import API_MAX_VERSION as nova_max_version
import novaclient.client as novaclient
from novaclient.exceptions import BadRequest
import os
from oslo_log import log as logging
import time
@@ -642,6 +657,9 @@ class Workflow(BaseWorkflow):
def maintenance_by_plugin_type(self, hostname, plugin_type):
aps = self.get_action_plugins_by_type(plugin_type)
session_dir = "%s/%s" % (self.conf.engine.local_cache_dir,
self.session_id)
download_plugin_dir = session_dir + "/actions/"
if aps:
LOG.info("%s: Calling action plug-ins with type %s" %
(self.session_id, plugin_type))
@@ -649,10 +667,27 @@ class Workflow(BaseWorkflow):
ap_name = "fenix.workflow.actions.%s" % ap.plugin
LOG.info("%s: Calling action plug-in module: %s" %
(self.session_id, ap_name))
action_plugin = getattr(import_module(ap_name), 'ActionPlugin')
ap_db_instance = self._create_action_plugin_instance(ap.plugin,
hostname)
ap_instance = action_plugin(self, ap_db_instance)
try:
action_plugin = getattr(import_module(ap_name),
'ActionPlugin')
ap_instance = action_plugin(self, ap_db_instance)
except ImportError:
download_plugin_file = "%s/%s.py" % (download_plugin_dir,
ap.plugin)
LOG.info("%s: Trying from: %s" % (self.session_id,
download_plugin_file))
if os.path.isfile(download_plugin_file):
ap_instance = (
mod_loader_action_instance(ap_name,
download_plugin_file,
self,
ap_db_instance))
else:
raise Exception('%s: could not find action plugin %s' %
(self.session_id, ap.plugin))
ap_instance.run()
if ap_db_instance.state:
LOG.info('%s: %s finished with %s host %s' %