summaryrefslogtreecommitdiff
path: root/morph-cache-server
diff options
context:
space:
mode:
Diffstat (limited to 'morph-cache-server')
-rwxr-xr-xmorph-cache-server103
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)