mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 08:58:59 +00:00
Merge pull request #18908 from Unity-Technologies/win-add-unzip
Added unzipping via zipfile module
This commit is contained in:
commit
1f39a65665
@ -5,6 +5,8 @@ A module to wrap (non-Windows) archive calls
|
||||
.. versionadded:: 2014.1.0
|
||||
'''
|
||||
from __future__ import absolute_import
|
||||
import os
|
||||
from salt.exceptions import CommandExecutionError
|
||||
|
||||
from salt.ext.six import string_types
|
||||
|
||||
@ -12,6 +14,7 @@ from salt.ext.six import string_types
|
||||
from salt.utils import \
|
||||
which as _which, which_bin as _which_bin, is_windows as _is_windows
|
||||
import salt.utils.decorators as decorators
|
||||
import salt.utils
|
||||
|
||||
# TODO: Check that the passed arguments are correct
|
||||
|
||||
@ -21,9 +24,17 @@ __func_alias__ = {
|
||||
}
|
||||
|
||||
|
||||
HAS_ZIPFILE = False
|
||||
try:
|
||||
import zipfile
|
||||
HAS_ZIPFILE = True
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
def __virtual__():
|
||||
if _is_windows():
|
||||
return False
|
||||
return HAS_ZIPFILE
|
||||
commands = ('tar', 'gzip', 'gunzip', 'zip', 'unzip', 'rar', 'unrar')
|
||||
# If none of the above commands are in $PATH this module is a no-go
|
||||
if not any(_which(cmd) for cmd in commands):
|
||||
@ -149,7 +160,7 @@ def gunzip(gzipfile, template=None, runas=None):
|
||||
|
||||
|
||||
@decorators.which('zip')
|
||||
def zip_(zipfile, sources, template=None, runas=None):
|
||||
def cmd_zip_(zipfile, sources, template=None, runas=None):
|
||||
'''
|
||||
Uses the zip command to create zip files
|
||||
|
||||
@ -175,8 +186,53 @@ def zip_(zipfile, sources, template=None, runas=None):
|
||||
return __salt__['cmd.run'](cmd, template=template, runas=runas).splitlines()
|
||||
|
||||
|
||||
@decorators.depends('zipfile', fallback_function=cmd_zip_)
|
||||
def zip_(archive, sources, template=None, runas=None):
|
||||
'''
|
||||
Uses the zipfile module to create zip files
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' archive.zip /tmp/zipfile.zip /tmp/sourcefile1,/tmp/sourcefile2
|
||||
|
||||
The template arg can be set to 'jinja' or another supported template
|
||||
engine to render the command arguments before execution.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' archive.zip template=jinja /tmp/zipfile.zip /tmp/sourcefile1,/tmp/{{grains.id}}.txt
|
||||
|
||||
'''
|
||||
(archive, sources) = _render_filenames(archive, sources, None, template)
|
||||
|
||||
if isinstance(sources, string_types):
|
||||
sources = [s.strip() for s in sources.split(',')]
|
||||
|
||||
archived_files = []
|
||||
with zipfile.ZipFile(archive, "w", zipfile.ZIP_DEFLATED) as zf:
|
||||
for src in sources:
|
||||
if os.path.exists(src):
|
||||
if os.path.isdir(src):
|
||||
rel_root = os.path.abspath(os.path.join(src, os.pardir))
|
||||
for dir_name, sub_dirs, files in os.walk(src):
|
||||
for filename in files:
|
||||
abs_name = os.path.abspath(os.path.join(dir_name, filename))
|
||||
arc_name = os.path.join(os.path.relpath(dir_name, rel_root), filename)
|
||||
archived_files.append(arc_name)
|
||||
zf.write(abs_name, arc_name)
|
||||
else:
|
||||
archived_files.append(src)
|
||||
zf.write(src)
|
||||
|
||||
return archived_files
|
||||
|
||||
|
||||
@decorators.which('unzip')
|
||||
def unzip(zipfile, dest, excludes=None, template=None, options=None, runas=None):
|
||||
def unzip_cmd(zipfile, dest, excludes=None, template=None, options=None, runas=None):
|
||||
'''
|
||||
Uses the unzip command to unpack zip files
|
||||
|
||||
@ -212,6 +268,45 @@ def unzip(zipfile, dest, excludes=None, template=None, options=None, runas=None)
|
||||
return __salt__['cmd.run'](cmd, template=template, runas=runas).splitlines()
|
||||
|
||||
|
||||
@decorators.depends('zipfile', fallback_function=unzip_cmd)
|
||||
def unzip(archive, dest, excludes=None, template=None, options=None, runas=None):
|
||||
'''
|
||||
Uses the zipfile module to unpack zip files
|
||||
|
||||
options:
|
||||
Options to pass to the ``unzip`` binary.
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' archive.unzip /tmp/zipfile.zip /home/strongbad/ excludes=file_1,file_2
|
||||
|
||||
The template arg can be set to 'jinja' or another supported template
|
||||
engine to render the command arguments before execution.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' archive.unzip template=jinja /tmp/zipfile.zip /tmp/{{grains.id}}/ excludes=file_1,file_2
|
||||
|
||||
'''
|
||||
(archive, dest) = _render_filenames(archive, dest, None, template)
|
||||
with zipfile.ZipFile(archive) as zf:
|
||||
files = zf.namelist()
|
||||
if excludes is None:
|
||||
zf.extractall(dest)
|
||||
return files
|
||||
|
||||
excludes = excludes.split(",")
|
||||
cleaned_files = [x for x in files if x not in excludes]
|
||||
for f in cleaned_files:
|
||||
if f not in excludes:
|
||||
zf.extract(f, dest)
|
||||
return cleaned_files
|
||||
|
||||
|
||||
@decorators.which('rar')
|
||||
def rar(rarfile, sources, template=None, runas=None):
|
||||
'''
|
||||
@ -272,3 +367,56 @@ def unrar(rarfile, dest, excludes=None, template=None, runas=None):
|
||||
cmd.extend(['-x', exclude])
|
||||
cmd.append(dest)
|
||||
return __salt__['cmd.run'](' '.join(cmd), template=template, runas=runas).splitlines()
|
||||
|
||||
|
||||
def _render_filenames(filenames, zipfile, saltenv, template):
|
||||
'''
|
||||
Process markup in the :param:`filenames` and :param:`zipfile` variables (NOT the
|
||||
files under the paths they ultimately point to) according to the markup
|
||||
format provided by :param:`template`.
|
||||
'''
|
||||
if not template:
|
||||
return (filenames, zipfile)
|
||||
|
||||
# render the path as a template using path_template_engine as the engine
|
||||
if template not in salt.utils.templates.TEMPLATE_REGISTRY:
|
||||
raise CommandExecutionError(
|
||||
'Attempted to render file paths with unavailable engine '
|
||||
'{0}'.format(template)
|
||||
)
|
||||
|
||||
kwargs = {}
|
||||
kwargs['salt'] = __salt__
|
||||
kwargs['pillar'] = __pillar__
|
||||
kwargs['grains'] = __grains__
|
||||
kwargs['opts'] = __opts__
|
||||
kwargs['saltenv'] = saltenv
|
||||
|
||||
def _render(contents):
|
||||
'''
|
||||
Render :param:`contents` into a literal pathname by writing it to a
|
||||
temp file, rendering that file, and returning the result.
|
||||
'''
|
||||
# write out path to temp file
|
||||
tmp_path_fn = salt.utils.mkstemp()
|
||||
with salt.utils.fopen(tmp_path_fn, 'w+') as fp_:
|
||||
fp_.write(contents)
|
||||
data = salt.utils.templates.TEMPLATE_REGISTRY[template](
|
||||
tmp_path_fn,
|
||||
to_str=True,
|
||||
**kwargs
|
||||
)
|
||||
salt.utils.safe_rm(tmp_path_fn)
|
||||
if not data['result']:
|
||||
# Failed to render the template
|
||||
raise CommandExecutionError(
|
||||
'Failed to render file path with error: {0}'.format(
|
||||
data['data']
|
||||
)
|
||||
)
|
||||
else:
|
||||
return data['data']
|
||||
|
||||
filenames = _render(filenames)
|
||||
zipfile = _render(zipfile)
|
||||
return (filenames, zipfile)
|
||||
|
@ -97,8 +97,13 @@ class Depends(object):
|
||||
)
|
||||
# if not, unload dependent_set
|
||||
if module:
|
||||
try:
|
||||
func_name = module.__func_alias__[func.__name__]
|
||||
except (AttributeError, KeyError):
|
||||
func_name = func.__name__
|
||||
|
||||
mod_key = '{0}.{1}'.format(module.__name__.split('.')[-1],
|
||||
func.__name__)
|
||||
func_name)
|
||||
|
||||
# if we don't have this module loaded, skip it!
|
||||
if mod_key not in functions:
|
||||
|
Loading…
Reference in New Issue
Block a user