Support to sepcify module.function for python function

Currenty, the function entry is hard-coded to be 'main.main' which is
not flexible. This patch adds support for specifying module name and
function name in the code package.

Change-Id: I92ea36f668073f380a4aef4526a6fad321d8cc95
This commit is contained in:
Lingxian Kong 2017-06-19 23:07:27 +12:00
parent 0d3ba2f7c8
commit fa10083c3b
4 changed files with 31 additions and 18 deletions

View File

@ -103,7 +103,7 @@ class FunctionsController(rest.RestController):
'description': kwargs.get('description'),
'runtime_id': kwargs.get('runtime_id'),
'code': json.loads(kwargs['code']),
'entry': kwargs.get('entry', 'main'),
'entry': kwargs.get('entry', 'main.main'),
}
source = values['code'].get('source')

View File

@ -101,7 +101,8 @@ class DefaultEngine(object):
image=image,
identifier=identifier,
labels=labels,
input=input
input=input,
entry=function.entry
)
output = self.orchestrator.run_execution(

View File

@ -157,7 +157,7 @@ class KubernetesManager(base.OrchestratorBase):
return pod
def _prepare_pod(self, pod, deployment_name, function_id, labels):
def _prepare_pod(self, pod, deployment_name, function_id, labels, entry):
"""Pod preparation.
1. Update pod labels.
@ -230,7 +230,8 @@ class KubernetesManager(base.OrchestratorBase):
data = {
'download_url': download_url,
'function_id': function_id,
'token': context.get_ctx().auth_token
'entry': entry,
'token': context.get_ctx().auth_token,
}
LOG.debug(
@ -271,7 +272,7 @@ class KubernetesManager(base.OrchestratorBase):
)
def prepare_execution(self, function_id, image=None, identifier=None,
labels=None, input=None):
labels=None, input=None, entry='main.main'):
"""Prepare service URL for function.
For image function, create a single pod with input, so the function
@ -291,7 +292,7 @@ class KubernetesManager(base.OrchestratorBase):
if not pod:
raise exc.OrchestratorException('No pod available.')
return self._prepare_pod(pod, identifier, function_id, labels)
return self._prepare_pod(pod, identifier, function_id, labels, entry)
def run_execution(self, function_id, input=None, identifier=None,
service_url=None):

View File

@ -26,46 +26,56 @@ from flask import Response
import requests
app = Flask(__name__)
file_name = ''
zip_file = ''
function_module = 'main'
function_method = 'main'
@app.route('/download', methods=['POST'])
def download():
download_url = request.form['download_url']
function_id = request.form['function_id']
entry = request.form['entry']
token = request.form.get('token')
headers = {}
if token:
headers = {'X-Auth-Token': token}
global file_name
file_name = '%s.zip' % function_id
global zip_file
zip_file = '%s.zip' % function_id
app.logger.info(
'Request received, download_url:%s, headers: %s' %
(download_url, headers)
'Request received, download_url:%s, headers: %s, entry: %s' %
(download_url, headers, entry)
)
r = requests.get(download_url, headers=headers, stream=True)
with open(file_name, 'wb') as fd:
with open(zip_file, 'wb') as fd:
for chunk in r.iter_content(chunk_size=65535):
fd.write(chunk)
if not zipfile.is_zipfile(file_name):
if not zipfile.is_zipfile(zip_file):
abort(500)
app.logger.info('Code package downloaded to %s' % file_name)
app.logger.info('Code package downloaded to %s' % zip_file)
global function_module
global function_method
function_module, function_method = tuple(entry.rsplit('.', 1))
return 'success'
@app.route('/execute', methods=['POST'])
def execute():
global file_name
importer = zipimport.zipimporter(file_name)
module = importer.load_module('main')
global zip_file
global function_module
global function_method
importer = zipimport.zipimporter(zip_file)
module = importer.load_module(function_module)
input = {}
if request.form:
@ -77,7 +87,8 @@ def execute():
start = time.time()
try:
result = module.main(**input)
func = getattr(module, function_method)
result = func(**input)
except Exception as e:
result = str(e)