Commit c603d931 authored by Rafael Monnerat's avatar Rafael Monnerat

slapos.shacache was reimplemented on ERP5 and this API do not follow the design.

parent 570d0dea
...@@ -4,9 +4,6 @@ slapos.toolbox ...@@ -4,9 +4,6 @@ slapos.toolbox
SlapOS toolbox contains : SlapOS toolbox contains :
- `builder <./slapos/README.builder.rst>`_
- `cloudmgr <./slapos/README.cloudmgr.rst>`_ - `cloudmgr <./slapos/README.cloudmgr.rst>`_
- `monitor <./slapos/README.monitor.rst>`_
- `onetimeupload <./slapos/README.onetimeupload.rst>`_ - `onetimeupload <./slapos/README.onetimeupload.rst>`_
- `shacache <./slapos/README.shacache.rst>`_
- `webrunner <./slapos/README.webrunner.rst>`_ - `webrunner <./slapos/README.webrunner.rst>`_
...@@ -81,7 +81,6 @@ setup(name=name, ...@@ -81,7 +81,6 @@ setup(name=name,
'pubsubnotifier = slapos.pubsub.notifier:main', 'pubsubnotifier = slapos.pubsub.notifier:main',
'pubsubserver = slapos.pubsub:main', 'pubsubserver = slapos.pubsub:main',
'qemu-qmp-client = slapos.qemuqmpclient:main', 'qemu-qmp-client = slapos.qemuqmpclient:main',
'shacache = slapos.shacache:main',
'slapos-kill = slapos.systool:kill', 'slapos-kill = slapos.systool:kill',
'slaprunnertest = slapos.runner.runnertest:main', 'slaprunnertest = slapos.runner.runnertest:main',
'slaprunnerteststandalone = slapos.runner.runnertest:runStandaloneUnitTest', 'slaprunnerteststandalone = slapos.runner.runnertest:runStandaloneUnitTest',
......
monitor
=======
Monitoring for SLAP (Simple Language for Accounting and Provisioning) python library.
##############################################################################
#
# Copyright (c) 2010 ViFiB SARL and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
import hashlib
import os
import sys
import traceback
from flask import Flask, request, helpers, abort, make_response
from config import NetworkcacheConfiguration, NetworkcacheParser
app = Flask(__name__)
@app.route('/', methods=['POST'])
def post():
""" Save the file on the cache server. """
if getattr(request, 'data', None) is None:
abort(400, 'POST requires data.')
cache_base_folder = app.config.get('CACHE_BASE_FOLDER')
file_name = hashlib.sha512(request.data).hexdigest()
try:
f = open(os.path.join(cache_base_folder, file_name), "w+")
try:
f.write(request.data)
finally:
f.close()
except:
app.logger.info(traceback.format_exc())
abort(500, "Faile to upload the file.")
return make_response(file_name, 201)
@app.route('/<key>', methods=['GET'])
def get(key):
""" Return the file if found, otherwise 404 is raised. """
cache_base_folder = app.config.get('CACHE_BASE_FOLDER')
file_path = os.path.join(cache_base_folder, key)
if not os.path.exists(file_path):
abort(404, 'File not found.')
return helpers.send_file(file_path)
def main():
"Run default configuration."
usage = "usage: %s [options] CONFIGURATION_FILE" % sys.argv[0]
try:
# Parse arguments
configuration = NetworkcacheConfiguration()
configuration.setConfig(*NetworkcacheParser(usage=usage).check_args())
app.config['CACHE_BASE_FOLDER'] = configuration.cache_base_folder
app.run(host=configuration.host, port=int(configuration.port), debug=True)
return_code = 0
except SystemExit, err:
# Catch exception raise by optparse
return_code = err
sys.exit(return_code)
##############################################################################
#
# Copyright (c) 2010 ViFiB SARL and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
import os
import logging
import logging.handlers
import ConfigParser
from optparse import OptionParser, Option
class NetworkcacheParser(OptionParser):
"""
Parse all arguments.
"""
def __init__(self, usage=None, version=None):
"""
Initialize all possible options.
"""
OptionParser.__init__(self, usage=usage, version=version,
option_list=[
Option("-l", "--log_file",
help="The path to the log file used by the script.",
type=str),
Option("-v", "--verbose",
default=False,
action="store_true",
help="Verbose output."),
Option("-c", "--console",
default=False,
action="store_true",
help="Console output."),
Option("-d", "--cache_base_folder",
type=str,
help="Folder to store the files."),
Option("-a", "--host",
type=str,
help="Host address."),
Option("-p", "--port",
type=str,
help="Port number."),
])
def check_args(self):
"""
Check arguments
"""
(options, args) = self.parse_args()
configuration_file_path = []
if len(args) > 1:
self.error("Incorrect number of arguments")
if len(args) == 1:
configuration_file_path = args[0]
return options, configuration_file_path
class NetworkcacheConfiguration:
def setConfig(self, option_dict, configuration_file_path):
"""
Set options given by parameters.
"""
# Set options parameters
for option, value in option_dict.__dict__.items():
setattr(self, option, value)
# Load configuration file
if configuration_file_path:
configuration_parser = ConfigParser.SafeConfigParser()
configuration_parser.read(configuration_file_path)
# Merges the arguments and configuration
for section in ("networkcached",):
configuration_dict = dict(configuration_parser.items(section))
for key in configuration_dict:
if not getattr(self, key, None):
setattr(self, key, configuration_dict[key])
# set up logging
self.logger = logging.getLogger("networkcached")
self.logger.setLevel(logging.INFO)
if self.console:
self.logger.addHandler(logging.StreamHandler())
# cache base folder is required
if not self.cache_base_folder:
raise ValueError('cache_base_folder is required.')
if self.log_file:
if not os.path.isdir(os.path.dirname(self.log_file)):
# fallback to console only if directory for logs does not exists and
# continue to run
raise ValueError('Please create directory %r to store %r log file' % (
os.path.dirname(self.log_file), self.log_file))
else:
file_handler = logging.FileHandler(self.log_file)
format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
file_handler.setFormatter(logging.Formatter(format))
self.logger.addHandler(file_handler)
self.logger.info('Configured logging to file %r' % self.log_file)
self.logger.info("Started.")
if self.verbose:
self.logger.setLevel(logging.DEBUG)
self.logger.debug("Verbose mode enabled.")
[networkcached]
host = 127.0.0.1
port = 5001
cache_base_folder = /opt/slapos/networkcached
##############################################################################
#
# Copyright (c) 2010 ViFiB SARL and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
import hashlib
import os
import shutil
import slapos.tool.networkcached as networkcached
import tempfile
import unittest
class NetworkcacheTestCase(unittest.TestCase):
def setUp(self):
networkcached.app.config['CACHE_BASE_FOLDER'] = tempfile.mkdtemp()
self.cache_base_folder = networkcached.app.config['CACHE_BASE_FOLDER']
self.app = networkcached.app.test_client()
self.file_content = 'test file content.'
def tearDown(self):
shutil.rmtree(self.cache_base_folder)
def create_file_into_cache_base_folder(self):
"""
Create a binary file into the directory.
"""
file_name = hashlib.sha512(self.file_content).hexdigest()
file_path = os.path.join(self.cache_base_folder, file_name)
f = open(file_path, 'w')
try:
f.write(self.file_content)
finally:
f.close()
return file_path
def test_get_non_existing_file(self):
"""
When the client tries to download a file which does not exists, it must
return a 404 error.
"""
result = self.app.get('/does_not_exists')
self.assertEquals('404 NOT FOUND', result.status)
self.assertTrue('File not found.' in result.data)
def test_get_existing_file(self):
"""
Check if the file is returned if it exists.
"""
file_path = self.create_file_into_cache_base_folder()
result = self.app.get('/%s' % file_path.split('/')[-1])
self.assertEquals('200 OK', result.status)
self.assertEquals('application/octet-stream',
result.headers['Content-Type'])
self.assertEquals(self.file_content, result.data)
def test_puti_file(self):
"""
Check if the file will be upload just fine.
"""
file_content = 'file does not exist yet'
file_name = hashlib.sha512(file_content).hexdigest()
result = self.app.put('/', data=file_content)
self.assertEquals('200 OK', result.status)
self.assertEquals('Success', result.data)
f = open(os.path.join(self.cache_base_folder, file_name), 'r')
try:
data = f.read()
finally:
f.close()
self.assertEquals(file_content, data)
def run():
unittest.main(module=networkcached.test)
if __name__ == '__main__':
run()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment