Skip to content

Commit

Permalink
Merge pull request #21770 from isbm/isbm-zypper-diff-backport-2015.2
Browse files Browse the repository at this point in the history
Backport PR #21769 to 2015.2
  • Loading branch information
thatch45 committed Mar 18, 2015
2 parents ac4264d + 26fab4b commit 8a301bc
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 2 deletions.
31 changes: 31 additions & 0 deletions salt/modules/rpm.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

# Import Salt libs
import salt.utils
import salt.utils.decorators as decorators

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -222,3 +223,33 @@ def owner(*paths):
if len(ret) == 1:
return list(ret.values())[0]
return ret


@decorators.which('rpm2cpio')
@decorators.which('cpio')
@decorators.which('diff')
def diff(package, path):
'''
Return a formatted diff between current file and original in a package.
NOTE: this function includes all files (configuration and not), but does
not work on binary content.
:param package: The name of the package
:param path: Full path to the installed file
:return: Difference or empty string. For binary files only a notification.
CLI example:
.. code-block:: bash
salt '*' lowpkg.diff apache2 /etc/apache2/httpd.conf
'''

cmd = "rpm2cpio {0} " \
"| cpio -i --quiet --to-stdout .{1} " \
"| diff -u --label 'A {1}' --from-file=- --label 'B {1}' {1}"
res = __salt__['cmd.shell'](cmd.format(package, path), output_loglevel='trace')
if res and res.startswith('Binary file'):
return 'File "{0}" is binary and its content has been modified.'.format(path)

return res
72 changes: 70 additions & 2 deletions salt/modules/zypper.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ def del_repo(repo):
return {
repo: True,
'message': msg[0].childNodes[0].nodeValue,
}
}

raise CommandExecutionError('Repository \'{0}\' not found.'.format(repo))

Expand Down Expand Up @@ -662,7 +662,7 @@ def upgrade(refresh=True):
ret = {'changes': {},
'result': True,
'comment': '',
}
}

if salt.utils.is_true(refresh):
refresh_db()
Expand Down Expand Up @@ -1092,3 +1092,71 @@ def list_products():
ret[product.pop('name')] = product

return ret


def download(*packages):
"""
Download packages to the local disk.
CLI example:
.. code-block:: bash
salt '*' pkg.download httpd
salt '*' pkg.download httpd postfix
"""
if not packages:
raise CommandExecutionError("No packages has been specified.")

doc = dom.parseString(__salt__['cmd.run'](
('zypper -x --non-interactive download {0}'.format(' '.join(packages))),
output_loglevel='trace'))
pkg_ret = {}
for dld_result in doc.getElementsByTagName("download-result"):
repo = dld_result.getElementsByTagName("repository")[0]
pkg_info = {
'repository-name': repo.getAttribute("name"),
'repository-alias': repo.getAttribute("alias"),
'path': dld_result.getElementsByTagName("localfile")[0].getAttribute("path"),
}
pkg_ret[_get_first_aggregate_text(dld_result.getElementsByTagName("name"))] = pkg_info

if pkg_ret:
return pkg_ret

raise CommandExecutionError("Unable to download packages: {0}.".format(', '.join(packages)))


def diff(*paths):
'''
Return a formatted diff between current files and original in a package.
NOTE: this function includes all files (configuration and not), but does
not work on binary content.
:param path: Full path to the installed file
:return: Difference string or raises and exception if examined file is binary.
CLI example:
.. code-block:: bash
salt '*' pkg.diff /etc/apache2/httpd.conf /etc/sudoers
'''
ret = {}

pkg_to_paths = {}
for pth in paths:
pth_pkg = __salt__['lowpkg.owner'](pth)
if not pth_pkg:
ret[pth] = os.path.exists(pth) and 'Not managed' or 'N/A'
else:
if pkg_to_paths.get(pth_pkg) is None:
pkg_to_paths[pth_pkg] = []
pkg_to_paths[pth_pkg].append(pth)

local_pkgs = __salt__['pkg.download'](*pkg_to_paths.keys())
for pkg, files in pkg_to_paths.items():
for path in files:
ret[path] = __salt__['lowpkg.diff'](local_pkgs[pkg]['path'], path) or 'Unchanged'

return ret

0 comments on commit 8a301bc

Please sign in to comment.