Add unzip functionality in sidecar

We will need to unzip the package for Nodejs programming language.

Change-Id: Ib67bc4024861ad5ce3720e46d940bf86a456f44b
Story: 2001580
Task: 6607
This commit is contained in:
Lingxian Kong 2018-03-06 16:07:10 +13:00
parent 5481858247
commit ffc1ceb262

View File

@ -12,7 +12,10 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import logging
import os import os
import sys
import zipfile
from flask import Flask from flask import Flask
from flask import make_response from flask import make_response
@ -21,21 +24,32 @@ from oslo_concurrency import lockutils
import requests import requests
app = Flask(__name__) app = Flask(__name__)
ch = logging.StreamHandler(sys.stdout)
ch.setLevel(logging.DEBUG)
ch.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
del app.logger.handlers[:]
app.logger.addHandler(ch)
DOWNLOAD_ERROR = "Failed to download function package from %s, error: %s" DOWNLOAD_ERROR = "Failed to download function package from %s, error: %s"
def log(message, level="info"):
global app
log_func = getattr(app.logger, level)
log_func(message)
@lockutils.synchronized('download_function', external=True, @lockutils.synchronized('download_function', external=True,
lock_path='/var/lock/qinling') lock_path='/var/lock/qinling')
def _download_package(url, zip_file, token=None): def _download_package(url, zip_file, token=None, unzip=None):
"""Download package as needed. """Download package and unzip as needed.
Return None if successful otherwise a Flask.Response object. Return None if successful otherwise a Flask.Response object.
""" """
if os.path.isfile(zip_file): if os.path.isfile(zip_file):
return None return None
print('Downloading function, download_url:%s' % url) log("Start downloading function")
headers = {} headers = {}
if token: if token:
@ -50,26 +64,41 @@ def _download_package(url, zip_file, token=None):
with open(zip_file, 'wb') as fd: with open(zip_file, 'wb') as fd:
for chunk in r.iter_content(chunk_size=65535): for chunk in r.iter_content(chunk_size=65535):
fd.write(chunk) fd.write(chunk)
log("Downloaded function package to %s" % zip_file)
if unzip:
dest = zip_file.split('.')[0]
with open(zip_file, 'rb') as f:
zf = zipfile.ZipFile(f)
zf.extractall(dest)
log("Unzipped")
except Exception as e: except Exception as e:
return make_response(DOWNLOAD_ERROR % (url, str(e)), 500) return make_response(DOWNLOAD_ERROR % (url, str(e)), 500)
print('Downloaded function package to %s' % zip_file)
@app.route('/download', methods=['POST']) @app.route('/download', methods=['POST'])
def download(): def download():
"""Download function package to a shared folder. """Download function package to a shared folder.
The parameters 'download_url' and 'function_id' need to be specified The parameters 'download_url' and 'function_id' need to be specified
explicitly. It's guaranteed in the server side. explicitly. It's guaranteed on the server side.
:param download_url: The URL for function package download. It's a Qinling
function resource URL with 'download' enabled.
:param function_id: Function ID.
:param token: Optional. The token used for download.
:param unzip: Optional. If unzip is needed after download.
""" """
params = request.get_json() params = request.get_json()
zip_file = '/var/qinling/packages/%s.zip' % params['function_id'] zip_file = '/var/qinling/packages/%s.zip' % params['function_id']
log("Function package download request received, params: %s" % params)
resp = _download_package( resp = _download_package(
params['download_url'], params['download_url'],
zip_file, zip_file,
params.get('token') token=params.get('token'),
unzip=params.get('unzip')
) )
return resp if resp else 'downloaded' return resp if resp else 'downloaded'