Add pithcat tool
authorGiorgos Verigakis <verigak@gmail.com>
Fri, 9 Dec 2011 11:41:37 +0000 (13:41 +0200)
committerGiorgos Verigakis <verigak@gmail.com>
Fri, 9 Dec 2011 11:41:37 +0000 (13:41 +0200)
It connects to a Pithos backend and either fetches
the data of a file or returns its size.

Refs #1745

snf-image-host/pithcat [new file with mode: 0755]

diff --git a/snf-image-host/pithcat b/snf-image-host/pithcat
new file mode 100755 (executable)
index 0000000..4cb8e80
--- /dev/null
@@ -0,0 +1,102 @@
+#!/usr/bin/env python
+
+# Copyright 2011 GRNET S.A. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or
+# without modification, are permitted provided that the following
+# conditions are met:
+#
+#   1. Redistributions of source code must retain the above
+#      copyright notice, this list of conditions and the following
+#      disclaimer.
+#
+#   2. Redistributions in binary form must reproduce the above
+#      copyright notice, this list of conditions and the following
+#      disclaimer in the documentation and/or other materials
+#      provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
+# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# The views and conclusions contained in the software and
+# documentation are those of the authors and should not be
+# interpreted as representing official policies, either expressed
+# or implied, of GRNET S.A.
+
+"""
+A tool that connects to the Pithos backend and returns the size and contents
+of a pithos object.
+
+Since the backend does not have a "root" account we use the account given in
+the URL as the user when connecting to the backend.
+"""
+
+from optparse import OptionParser
+from sys import exit, stdout
+
+from pithos.backends.modular import ModularBackend
+
+
+parser = OptionParser(usage='%prog [options] <URL>')
+parser.add_option('--db', dest='db', metavar='URI',
+        help='SQLAlchemy URI of the database [REQUIRED]')
+parser.add_option('--data', dest='data', metavar='DIR',
+        help='path to the directory where data are stored [REQUIRED]')
+parser.add_option('-s', action='store_true', dest='size', default=False,
+        help='print file size and exit')
+
+
+def urlsplit(url):
+    """Returns (accout, container, object) from a location string"""
+    
+    assert url.startswith('pithos://'), "Invalid URL"
+    t = url.split('/', 4)
+    assert len(t) == 5, "Invalid URL"
+    return t[2:5]
+
+
+def print_size(backend, url):
+    """Writes object's size to stdout."""
+    
+    account, container, object = urlsplit(url)
+    meta = backend.get_object_meta(account, account, container, object)
+    print meta['bytes']
+
+
+def print_data(backend, url):
+    """Writes object's size to stdout."""
+    
+    account, container, object = urlsplit(url)
+    size, hashmap = backend.get_object_hashmap(account, account, container,
+            object)
+    for hash in hashmap:
+        block = backend.get_block(hash)
+        stdout.write(block)
+
+
+def main():
+    options, args = parser.parse_args()
+    if len(args) != 1 or not options.db or not options.data:
+        parser.print_help()
+        exit(1)
+
+    url = args[0]
+    backend = ModularBackend(None, options.db, None, options.data)
+    
+    if options.size:
+        print_size(backend, url)
+    else:
+        print_data(backend, url)
+
+if __name__ == '__main__':
+    main()