# -*- coding: utf-8 -*- # author: Bruno Clermont ''' Archive states =================== ''' from __future__ import absolute_import 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".format(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".format(name)) __salt__['file.makedirs'](name) __salt__['file.mkdir'](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: log.debug("Untar %s in %s", filename, name) files = __salt__['archive.tar'](options='xv{0}f'.format(tar_options), tarfile=filename, dest=name) if not files: 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