Commits

Albert Hopkins  committed fe409f6

Through the miracle of kludgery, live clouds can now store metadata

  • Participants
  • Parent commits 4668506
  • Tags 0.4.10

Comments (0)

Files changed (1)

File hemp/hemp.py

 from helpers import get_device, sudo_popen, mount_qcow, unmount_qcow
 import settings
 
-__version__ = '0.4.9.2'
+__version__ = '0.4.10'
 __revision__ = '$Revision$'
 
 DIRS = ('.hemp', '.hemp/images',)
 CLOUD_FILE_SIGNATURE = '\x08\x05\x13\x16'
 CLOUD_FILE_FORMAT = 2
 QCOW_FILE_SIGNATURE = '\x51\x46\x49\xfb'
+LIVE_CLOUD_FILE_FORMAT = 1
 NULL = os.open('/dev/null', os.O_RDWR)
 
 class InvalidCloudFile(Exception):
     # remove the temporary file
     os.unlink(tmpfile)
 
+    # we create a "special" snapshot to store metadata
+    metadata = ('HLC!%02d\n%s\n%s\n%s\n' % (
+        LIVE_CLOUD_FILE_FORMAT,
+        name,
+        os.uname()[4],
+        get_num_servers_for(args.path),
+        ))
+    # qcow2 snapshots only allow 256 bytes for the name. worse than that,
+    # "qemu-img snapshot -l" only shows the first 245 bytes of the name, so
+    # to store the author, may need to strip it.
+    author = args.author or os.getlogin()
+    remaining_bytes = 245 - len(metadata) - 1 # for the newline
+    metadata = metadata + author[:remaining_bytes] + '\n'
+    call(('qemu-img', 'snapshot', '-c', metadata, outfile))
+
 def unpack_live(args):
     """Unpack a "live" cloud"""
     filename = os.path.realpath(args.filename)
     # They are handled a bit differently
     signature = cloud_file.read(len(QCOW_FILE_SIGNATURE))
     if signature == QCOW_FILE_SIGNATURE:
-        return {'cloud_type': 'qcow'}
-    else:
-        cloud_file.seek(0)
+        cloud_file.close()
+        popen = Popen(('qemu-img', 'snapshot', '-l', filename), stdout=PIPE)
+        lines = popen.communicate()[0].split('\n')
+        if len(lines) >= 7 and lines[2].startswith('1         HLC!'):
+            # we are are live cloud
+            metadata = {
+                'name': lines[3],
+                'machine': lines[4],
+                'servers': lines[5],
+                'author': lines[6],
+                'url': None
+                }
+            if len(lines) > 7 and lines[7].startswith('      0 '):
+                # because sometimes 'qemu-img -snapshot -l' cuts this part
+                # off
+                metadata['create_time'] = ' '.join(lines[7].split()[1:3])
+            else:
+                metadata['create_time'] = 'unknown'
+            metadata['cloud_type'] = 'qcow'
+            return metadata
+        else:
+            raise InvalidCloudFile('%s does not appear to be a hemp cloud'
+                    % filename)
 
+    cloud_file.seek(0)
     signature = cloud_file.read(len(CLOUD_FILE_SIGNATURE))
     if signature != CLOUD_FILE_SIGNATURE or cloud_file.read(1) != '\x00':
         cloud_file.close()
         sys.stderr.write('%s\n' % error)
         sys.exit(1)
 
-    if metadata['cloud_type'] == 'qcow':
-        print 'File    : %s' % os.path.basename(args.filename)
-        print '          Possible Live cloud. No other info avaiable.'
-        return
-
     print 'File    : %s' % os.path.basename(args.filename)
+    print 'Type    : %s' % ('Live Cloud' if metadata['cloud_type'] == 'qcow'
+            else 'Archive Cloud')
     print 'Created : %s' % metadata['create_time']
     print 'Author  : %s' % metadata['author']
     print 'Name    : %s' % metadata['name']