added archive.py from salt-contrib (it should be removed once it enters the package salt-minion)
authorPaul Tonelli <paul.tonelli@logilab.fr>
Wed, 06 Mar 2013 18:02:01 +0100
changeset 34 434bfcf7aa95
parent 33 1032b357595e
child 35 0792b2bd0795
added archive.py from salt-contrib (it should be removed once it enters the package salt-minion)
_states/archive.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/_states/archive.py	Wed Mar 06 18:02:01 2013 +0100
@@ -0,0 +1,132 @@
+# -*- coding: utf-8 -*-
+# author: Bruno Clermont <patate@fastmail.cn>
+
+'''
+Archive states
+===================
+
+'''
+
+import logging
+import os
+
+log = logging.getLogger(__name__)
+
+def extracted(name, source, archive_format, tar_options=None, source_hash=None,
+              if_missing=None):
+    '''
+    State that make sure an archive is extracted in a directory.
+    The downloaded archive is erased if succesfully extracted.
+    The archive is downloaded only if necessary.
+
+    .. code-block:: yaml
+
+    graylog2-server:
+      archive:
+        - extracted
+        - name: /opt/
+        - source: https://github.com/downloads/Graylog2/graylog2-server/graylog2-server-0.9.6p1.tar.gz
+        - source_hash: md5=499ae16dcae71eeb7c3a30c75ea7a1a6
+        - archive_format: tar
+        - tar_options: z
+        - if_missing: /opt/graylog2-server-0.9.6p1/
+
+    name
+        Directory name where to extract the archive
+
+    source
+        Archive source, same syntax as file.managed source argument.
+
+    archive_format
+        tar, zip or rar
+
+    if_missing
+        Some archive, such as tar, extract themself in a subfolder.
+        This directive can be used to validate if the archive had been
+        previously extracted.
+
+    tar_options
+        Only used for tar format, it need to be the tar argument specific to
+        this archive, such as 'j' for bzip2, 'z' for gzip, '' for uncompressed
+        tar, 'J' for LZMA.
+    '''
+    ret = {'name': name, 'result': None, 'changes': {}, 'comment': ''}
+    valid_archives = ('tar', 'rar', 'zip')
+
+    if __opts__['test']:
+        ret['comment'] = 'Archive {0} would have been extracted in {1}'.format(
+            source, name)
+        return ret
+
+    if archive_format not in valid_archives:
+        ret['result'] = False
+        ret['comment'] = '{0} is not supported, valids: {1}'.format(
+            name, ','.join(valid_archives))
+        return ret
+
+    if archive_format == 'tar' and tar_options is None:
+        ret['result'] = False
+        ret['comment'] = 'tar archive need argument tar_options'
+        return ret
+
+    if if_missing is None:
+        if_missing = name
+    if __salt__['file.directory_exists'](if_missing):
+        ret['result'] = True
+        ret['comment'] = '{0} already exists'.format(if_missing)
+        return ret
+
+    log.debug("Input seem valid so far")
+    filename = os.path.join(__opts__['cachedir'],
+                            '{0}.{1}'.format(if_missing.replace('/', '_'),
+                                             archive_format))
+    if not os.path.exists(filename):
+        log.debug("Archive file {0} is not in cache, download it", source)
+        data = {
+            filename: {
+                'file': [
+                    'managed',
+                    {'name': filename},
+                    {'source': source},
+                    {'source_hash': source_hash},
+                    {'makedirs': True}
+                ]
+            }
+        }
+        file_result = __salt__['state.high'](data)
+        log.debug("file.managed: %s", file_result)
+        # get value of first key
+        file_result = file_result[file_result.keys()[0]]
+        if not file_result['result']:
+            log.debug("failed to download %s", source)
+            return file_result
+    else:
+        log.debug("Archive file {0} is already in cache", name)
+
+    __salt__['file.makedirs'](name)
+
+    if archive_format in ('zip', 'rar'):
+        log.debug("Extract %s in %s", filename, name)
+        files = __salt__['archive.un{0}'.format(archive_format)](filename, name)
+    else:
+        # this is needed until merging PR 2651
+        log.debug("Untar %s in %s", filename, name)
+        results = __salt__['cmd.run_all']('tar -xv{0}f {1}'.format(tar_options,
+                                                                   filename),
+                                          cwd=name)
+        if results['retcode'] != 0:
+            return results
+        files = results['stdout']
+    if len(files) > 0:
+        ret['result'] = True
+        ret['changes']['directories_created'] = [name]
+        if if_missing != name:
+            ret['changes']['directories_created'].append(if_missing)
+        ret['changes']['extracted_files'] = files
+        ret['comment'] = "{0} extracted in {1}".format(source, name)
+        os.unlink(filename)
+    else:
+        __salt__['file.remove'](if_missing)
+        ret['result'] = False
+        ret['comment'] = "Can't extract content of {0}".format(source)
+    return ret