diff options
Diffstat (limited to 'morph-cache-server')
-rwxr-xr-x | morph-cache-server | 103 |
1 files changed, 99 insertions, 4 deletions
diff --git a/morph-cache-server b/morph-cache-server index 3f72c18..b4f8fa1 100755 --- a/morph-cache-server +++ b/morph-cache-server @@ -20,6 +20,7 @@ import cliapp import logging import os import urllib +import shutil from bottle import Bottle, request, response, run, static_file @@ -30,12 +31,17 @@ defaults = { 'repo-dir': '/var/cache/morph-cache-server/gits', 'bundle-dir': '/var/cache/morph-cache-server/bundles', 'artifact-dir': '/var/cache/morph-cache-server/artifacts', + 'port': 8080, } class MorphCacheServer(cliapp.Application): def add_settings(self): + self.settings.integer(['port'], + 'port to listen on', + metavar='PORTNUM', + default=defaults['port']) self.settings.string(['repo-dir'], 'path to the repository cache directory', metavar='PATH', @@ -48,13 +54,101 @@ class MorphCacheServer(cliapp.Application): 'path to the artifact cache directory', metavar='PATH', default=defaults['artifact-dir']) + self.settings.boolean(['direct-mode'], + 'cache directories are directly managed') + self.settings.boolean(['enable-writes'], + 'enable the write methods (fetch and delete)') def process_args(self, args): app = Bottle() repo_cache = RepoCache(self, self.settings['repo-dir'], - self.settings['bundle-dir']) + self.settings['bundle-dir'], + self.settings['direct-mode']) + + def writable(prefix): + """Selectively enable bottle prefixes. + + prefix -- The path prefix we are enabling + + If the runtime configuration setting --enable-writes is provided + then we return the app.get() decorator for the given path prefix + otherwise we return a lambda which passes the function through + undecorated. + + This has the effect of being a runtime-enablable @app.get(...) + + """ + if self.settings['enable-writes']: + return app.get(prefix) + return lambda fn: fn + + @writable('/list') + def list(): + response.set_header('Cache-Control', 'no-cache') + results = {} + files = {} + results["files"] = files + for artifactdir, __, filenames in \ + os.walk(self.settings['artifact-dir']): + fsstinfo = os.statvfs(artifactdir) + results["freespace"] = fsstinfo.f_bsize * fsstinfo.f_bavail + for fname in filenames: + if not fname.startswith(".dl."): + try: + stinfo = os.stat("%s/%s" % (artifactdir, fname)) + files[fname] = { + "atime": stinfo.st_atime, + "size": stinfo.st_size, + "used": stinfo.st_blocks * 512, + } + except Exception, e: + print(e) + return results + + @writable('/fetch') + def fetch(): + host = self._unescape_parameter(request.query.host) + artifact = self._unescape_parameter(request.query.artifact) + try: + response.set_header('Cache-Control', 'no-cache') + in_fh = urllib.urlopen("http://%s/artifacts?basename=%s" % + (host, urllib.quote(artifact))) + tmpname = "%s/.dl.%s" % ( + self.settings['artifact-dir'], + artifact) + localtmp = open(tmpname, "w") + shutil.copyfileobj(in_fh, localtmp) + localtmp.close() + in_fh.close() + artifilename = "%s/%s" % (self.settings['artifact-dir'], + artifact) + os.rename(tmpname, artifilename) + stinfo = os.stat(artifilename) + ret = {} + ret[artifact] = { + "size": stinfo.st_size, + "used": stinfo.st_blocks * 512 + } + return ret + + except Exception, e: + response.status = 500 + logging.debug('%s' % e) + + @writable('/delete') + def delete(): + artifact = self._unescape_parameter(request.query.artifact) + try: + os.unlink('%s/%s' % (self.settings['artifact-dir'], + artifact)) + return { "status": 0, "reason": "success" } + except OSError, ose: + return { "status": ose.errno, "reason": ose.strerror } + except Exception, e: + response.status = 500 + logging.debug('%s' % e) @app.get('/sha1s') def sha1(): @@ -62,11 +156,12 @@ class MorphCacheServer(cliapp.Application): ref = self._unescape_parameter(request.query.ref) try: response.set_header('Cache-Control', 'no-cache') - sha1 = repo_cache.resolve_ref(repo, ref) + sha1, tree = repo_cache.resolve_ref(repo, ref) return { 'repo': '%s' % repo, 'ref': '%s' % ref, - 'sha1': '%s' % sha1 + 'sha1': '%s' % sha1, + 'tree': '%s' % tree } except Exception, e: response.status = 404 @@ -124,7 +219,7 @@ class MorphCacheServer(cliapp.Application): root = Bottle() root.mount(app, '/1.0') - run(root, host='0.0.0.0', port=8080, reloader=True) + run(root, host='0.0.0.0', port=self.settings['port'], reloader=True) def _unescape_parameter(self, param): return urllib.unquote(param) |