Accepting request 354612 from devel:languages:python
1 OBS-URL: https://build.opensuse.org/request/show/354612 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/salt?expand=0&rev=54
This commit is contained in:
parent
084075d360
commit
86c13548fd
@ -1,139 +0,0 @@
|
|||||||
From 1832daa1d247a546069f901427995f0b9f2addf3 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Klaus=20K=C3=A4mpf?= <kkaempf@suse.de>
|
|
||||||
Date: Tue, 15 Dec 2015 14:36:41 +0100
|
|
||||||
Subject: [PATCH 1/2] Add rpm.minimal_info, fix rpm.info
|
|
||||||
|
|
||||||
rpm.info: report epoch (if present) and architecture
|
|
||||||
|
|
||||||
add rpm.minimal_info to just report name, epoch, version, release,
|
|
||||||
architecture, and installtime
|
|
||||||
---
|
|
||||||
salt/modules/rpm.py | 97 +++++++++++++++++++++++++++++++++++------------------
|
|
||||||
1 file changed, 65 insertions(+), 32 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/salt/modules/rpm.py b/salt/modules/rpm.py
|
|
||||||
index 032f8dadc87a..9fb89c994d9b 100644
|
|
||||||
--- a/salt/modules/rpm.py
|
|
||||||
+++ b/salt/modules/rpm.py
|
|
||||||
@@ -413,43 +413,15 @@ def _pkg_time_to_iso(pkg_time):
|
|
||||||
return datetime.datetime(ptime.tm_year, ptime.tm_mon, ptime.tm_mday,
|
|
||||||
ptime.tm_hour, ptime.tm_min, ptime.tm_sec).isoformat() + "Z"
|
|
||||||
|
|
||||||
-
|
|
||||||
-def info(*packages):
|
|
||||||
+def query_rpm(queryformat, *packages):
|
|
||||||
'''
|
|
||||||
- Return a detailed package(s) summary information.
|
|
||||||
- If no packages specified, all packages will be returned.
|
|
||||||
-
|
|
||||||
- :param packages:
|
|
||||||
- :return:
|
|
||||||
-
|
|
||||||
- CLI example:
|
|
||||||
-
|
|
||||||
- .. code-block:: bash
|
|
||||||
-
|
|
||||||
- salt '*' lowpkg.info apache2 bash
|
|
||||||
+ Internal function for info() and minimal_info() to query rpm and parse it's output
|
|
||||||
'''
|
|
||||||
|
|
||||||
cmd = packages and "rpm -q {0}".format(' '.join(packages)) or "rpm -qa"
|
|
||||||
|
|
||||||
# Locale needs to be en_US instead of C, because RPM otherwise will yank the timezone from the timestamps
|
|
||||||
- call = __salt__['cmd.run_all'](cmd + (" --queryformat 'Name: %{NAME}\n"
|
|
||||||
- "Relocations: %|PREFIXES?{[%{PREFIXES} ]}:{(not relocatable)}|\n"
|
|
||||||
- "Version: %{VERSION}\n"
|
|
||||||
- "Vendor: %{VENDOR}\n"
|
|
||||||
- "Release: %{RELEASE}\n"
|
|
||||||
- "Build Date: %{BUILDTIME:date}\n"
|
|
||||||
- "Install Date: %|INSTALLTIME?{%{INSTALLTIME:date}}:{(not installed)}|\n"
|
|
||||||
- "Build Host: %{BUILDHOST}\n"
|
|
||||||
- "Group: %{GROUP}\n"
|
|
||||||
- "Source RPM: %{SOURCERPM}\n"
|
|
||||||
- "Size: %{LONGSIZE}\n"
|
|
||||||
- "%|LICENSE?{License: %{LICENSE}\n}|"
|
|
||||||
- "Signature: %|DSAHEADER?{%{DSAHEADER:pgpsig}}:{%|RSAHEADER?{%{RSAHEADER:pgpsig}}:{%|SIGGPG?{%{SIGGPG:pgpsig}}:{%|SIGPGP?{%{SIGPGP:pgpsig}}:{(none)}|}|}|}|\n"
|
|
||||||
- "%|PACKAGER?{Packager: %{PACKAGER}\n}|"
|
|
||||||
- "%|URL?{URL: %{URL}\n}|"
|
|
||||||
- "Summary: %{SUMMARY}\n"
|
|
||||||
- "Description:\n%{DESCRIPTION}\n"
|
|
||||||
- "-----\n'"),
|
|
||||||
+ call = __salt__['cmd.run_all'](cmd + queryformat,
|
|
||||||
output_loglevel='trace', env={'LC_ALL': 'en_US', 'TZ': 'UTC'}, clean_env=True)
|
|
||||||
if call['retcode'] != 0:
|
|
||||||
comment = ''
|
|
||||||
@@ -490,8 +462,69 @@ def info(*packages):
|
|
||||||
value = _pkg_time_to_iso(value)
|
|
||||||
if key != 'description' and value:
|
|
||||||
pkg_data[key] = value
|
|
||||||
- pkg_data['description'] = os.linesep.join(descr)
|
|
||||||
+ if len(descr) > 0:
|
|
||||||
+ pkg_data['description'] = os.linesep.join(descr)
|
|
||||||
if pkg_name:
|
|
||||||
ret[pkg_name] = pkg_data
|
|
||||||
|
|
||||||
return ret
|
|
||||||
+
|
|
||||||
+def info(*packages):
|
|
||||||
+ '''
|
|
||||||
+ Return a detailed package(s) summary information.
|
|
||||||
+ If no packages specified, all packages will be returned.
|
|
||||||
+
|
|
||||||
+ :param packages:
|
|
||||||
+ :return:
|
|
||||||
+
|
|
||||||
+ CLI example:
|
|
||||||
+
|
|
||||||
+ .. code-block:: bash
|
|
||||||
+
|
|
||||||
+ salt '*' lowpkg.info apache2 bash
|
|
||||||
+ '''
|
|
||||||
+
|
|
||||||
+ return query_rpm(" --queryformat 'Name: %{NAME}\n"
|
|
||||||
+ "Relocations: %|PREFIXES?{[%{PREFIXES} ]}:{(not relocatable)}|\n"
|
|
||||||
+ "%|EPOCH?{Epoch: %{EPOCH}\n}|"
|
|
||||||
+ "Version: %{VERSION}\n"
|
|
||||||
+ "Vendor: %{VENDOR}\n"
|
|
||||||
+ "Release: %{RELEASE}\n"
|
|
||||||
+ "Architecture: %{ARCH}\n"
|
|
||||||
+ "Build Date: %{BUILDTIME:date}\n"
|
|
||||||
+ "Install Date: %|INSTALLTIME?{%{INSTALLTIME:date}}:{(not installed)}|\n"
|
|
||||||
+ "Build Host: %{BUILDHOST}\n"
|
|
||||||
+ "Group: %{GROUP}\n"
|
|
||||||
+ "Source RPM: %{SOURCERPM}\n"
|
|
||||||
+ "Size: %{LONGSIZE}\n"
|
|
||||||
+ "%|LICENSE?{License: %{LICENSE}\n}|"
|
|
||||||
+ "Signature: %|DSAHEADER?{%{DSAHEADER:pgpsig}}:{%|RSAHEADER?{%{RSAHEADER:pgpsig}}:{%|SIGGPG?{%{SIGGPG:pgpsig}}:{%|SIGPGP?{%{SIGPGP:pgpsig}}:{(none)}|}|}|}|\n"
|
|
||||||
+ "%|PACKAGER?{Packager: %{PACKAGER}\n}|"
|
|
||||||
+ "%|URL?{URL: %{URL}\n}|"
|
|
||||||
+ "Summary: %{SUMMARY}\n"
|
|
||||||
+ "Description:\n%{DESCRIPTION}\n"
|
|
||||||
+ "-----\n'", *packages)
|
|
||||||
+
|
|
||||||
+def minimal_info(*packages):
|
|
||||||
+ '''
|
|
||||||
+ Return a minimal package(s) information (name, epoch, version, release, arch, installtime).
|
|
||||||
+ If no packages specified, all packages will be returned.
|
|
||||||
+
|
|
||||||
+ :param packages:
|
|
||||||
+ :return:
|
|
||||||
+
|
|
||||||
+ CLI example:
|
|
||||||
+
|
|
||||||
+ .. code-block:: bash
|
|
||||||
+
|
|
||||||
+ salt '*' lowpkg.minimal_info apache2 bash
|
|
||||||
+ '''
|
|
||||||
+
|
|
||||||
+ return query_rpm(" --queryformat 'Name: %{NAME}\n"
|
|
||||||
+ "%|EPOCH?{Epoch: %{EPOCH}\n}|"
|
|
||||||
+ "Version: %{VERSION}\n"
|
|
||||||
+ "Release: %{RELEASE}\n"
|
|
||||||
+ "Architecture: %{ARCH}\n"
|
|
||||||
+ "Install Date: %|INSTALLTIME?{%{INSTALLTIME:date}}:{(not installed)}|\n"
|
|
||||||
+ "-----\n'", *packages)
|
|
||||||
+
|
|
||||||
\ No newline at end of file
|
|
||||||
--
|
|
||||||
2.6.3
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
|||||||
From e6c0629e1fbbc739a856494641330a346966ccfb Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Klaus=20K=C3=A4mpf?= <kkaempf@suse.de>
|
|
||||||
Date: Tue, 15 Dec 2015 14:37:54 +0100
|
|
||||||
Subject: [PATCH 2/2] Reduce information returned from pkg.info_installed
|
|
||||||
|
|
||||||
Only report name, epoch (if set), version, release, architecture, and
|
|
||||||
installtime
|
|
||||||
---
|
|
||||||
salt/modules/zypper.py | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/salt/modules/zypper.py b/salt/modules/zypper.py
|
|
||||||
index 26c0580d027e..2954e8b1f06d 100644
|
|
||||||
--- a/salt/modules/zypper.py
|
|
||||||
+++ b/salt/modules/zypper.py
|
|
||||||
@@ -111,7 +111,7 @@ def info_installed(*names):
|
|
||||||
salt '*' pkg.info_installed <package1> <package2> <package3> ...
|
|
||||||
'''
|
|
||||||
ret = dict()
|
|
||||||
- for pkg_name, pkg_nfo in __salt__['lowpkg.info'](*names).items():
|
|
||||||
+ for pkg_name, pkg_nfo in __salt__['lowpkg.minimal_info'](*names).items():
|
|
||||||
t_nfo = dict()
|
|
||||||
# Translate dpkg-specific keys to a common structure
|
|
||||||
for key, value in pkg_nfo.items():
|
|
||||||
--
|
|
||||||
2.6.3
|
|
||||||
|
|
201
salt-2015.8-pkg-zypper-attr-filtering.patch
Normal file
201
salt-2015.8-pkg-zypper-attr-filtering.patch
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
diff --git a/salt/modules/rpm.py b/salt/modules/rpm.py
|
||||||
|
index 7810e22..51c72c9 100644
|
||||||
|
--- a/salt/modules/rpm.py
|
||||||
|
+++ b/salt/modules/rpm.py
|
||||||
|
@@ -8,7 +8,6 @@ from __future__ import absolute_import
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
-import time
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
# Import Salt libs
|
||||||
|
@@ -399,24 +398,20 @@ def diff(package, path):
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
-def _pkg_time_to_iso(pkg_time):
|
||||||
|
- '''
|
||||||
|
- Convert package time to ISO 8601.
|
||||||
|
-
|
||||||
|
- :param pkg_time:
|
||||||
|
- :return:
|
||||||
|
- '''
|
||||||
|
- ptime = time.strptime(pkg_time, '%a %d %b %Y %H:%M:%S %p %Z')
|
||||||
|
- return datetime.datetime(ptime.tm_year, ptime.tm_mon, ptime.tm_mday,
|
||||||
|
- ptime.tm_hour, ptime.tm_min, ptime.tm_sec).isoformat() + "Z"
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-def info(*packages):
|
||||||
|
+def info(*packages, **attr):
|
||||||
|
'''
|
||||||
|
Return a detailed package(s) summary information.
|
||||||
|
If no packages specified, all packages will be returned.
|
||||||
|
|
||||||
|
:param packages:
|
||||||
|
+
|
||||||
|
+ :param attr:
|
||||||
|
+ Comma-separated package attributes. If no 'attr' is specified, all available attributes returned.
|
||||||
|
+
|
||||||
|
+ Valid attributes are:
|
||||||
|
+ version, vendor, release, build_date, build_date_time_t, install_date, install_date_time_t,
|
||||||
|
+ build_host, group, source_rpm, arch, epoch, size, license, signature, packager, url, summary, description.
|
||||||
|
+
|
||||||
|
:return:
|
||||||
|
|
||||||
|
CLI example:
|
||||||
|
@@ -424,30 +419,59 @@ def info(*packages):
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt '*' lowpkg.info apache2 bash
|
||||||
|
+ salt '*' lowpkg.info apache2 bash attr=version
|
||||||
|
+ salt '*' lowpkg.info apache2 bash attr=version,build_date_iso,size
|
||||||
|
'''
|
||||||
|
|
||||||
|
cmd = packages and "rpm -q {0}".format(' '.join(packages)) or "rpm -qa"
|
||||||
|
|
||||||
|
- # Locale needs to be en_US instead of C, because RPM otherwise will yank the timezone from the timestamps
|
||||||
|
- call = __salt__['cmd.run_all'](cmd + (" --queryformat 'Name: %{NAME}\n"
|
||||||
|
- "Relocations: %|PREFIXES?{[%{PREFIXES} ]}:{(not relocatable)}|\n"
|
||||||
|
- "Version: %{VERSION}\n"
|
||||||
|
- "Vendor: %{VENDOR}\n"
|
||||||
|
- "Release: %{RELEASE}\n"
|
||||||
|
- "Build Date: %{BUILDTIME:date}\n"
|
||||||
|
- "Install Date: %|INSTALLTIME?{%{INSTALLTIME:date}}:{(not installed)}|\n"
|
||||||
|
- "Build Host: %{BUILDHOST}\n"
|
||||||
|
- "Group: %{GROUP}\n"
|
||||||
|
- "Source RPM: %{SOURCERPM}\n"
|
||||||
|
- "Size: %{LONGSIZE}\n"
|
||||||
|
- "%|LICENSE?{License: %{LICENSE}\n}|"
|
||||||
|
- "Signature: %|DSAHEADER?{%{DSAHEADER:pgpsig}}:{%|RSAHEADER?{%{RSAHEADER:pgpsig}}:{%|SIGGPG?{%{SIGGPG:pgpsig}}:{%|SIGPGP?{%{SIGPGP:pgpsig}}:{(none)}|}|}|}|\n"
|
||||||
|
- "%|PACKAGER?{Packager: %{PACKAGER}\n}|"
|
||||||
|
- "%|URL?{URL: %{URL}\n}|"
|
||||||
|
- "Summary: %{SUMMARY}\n"
|
||||||
|
- "Description:\n%{DESCRIPTION}\n"
|
||||||
|
- "-----\n'"),
|
||||||
|
- output_loglevel='trace', env={'LC_ALL': 'en_US', 'TZ': 'UTC'}, clean_env=True)
|
||||||
|
+ # Construct query format
|
||||||
|
+ attr_map = {
|
||||||
|
+ "name": "name: %{NAME}\\n",
|
||||||
|
+ "relocations": "relocations: %|PREFIXES?{[%{PREFIXES} ]}:{(not relocatable)}|\\n",
|
||||||
|
+ "version": "version: %{VERSION}\\n",
|
||||||
|
+ "vendor": "vendor: %{VENDOR}\\n",
|
||||||
|
+ "release": "release: %{RELEASE}\\n",
|
||||||
|
+ "epoch": "%|EPOCH?{epoch: %{EPOCH}\\n}|",
|
||||||
|
+ "build_date_time_t": "build_date_time_t: %{BUILDTIME}\\n",
|
||||||
|
+ "build_date": "build_date: %{BUILDTIME}\\n",
|
||||||
|
+ "install_date_time_t": "install_date_time_t: %|INSTALLTIME?{%{INSTALLTIME}}:{(not installed)}|\\n",
|
||||||
|
+ "install_date": "install_date: %|INSTALLTIME?{%{INSTALLTIME}}:{(not installed)}|\\n",
|
||||||
|
+ "build_host": "build_host: %{BUILDHOST}\\n",
|
||||||
|
+ "group": "group: %{GROUP}\\n",
|
||||||
|
+ "source_rpm": "source_rpm: %{SOURCERPM}\\n",
|
||||||
|
+ "size": "size: %{LONGSIZE}\\n",
|
||||||
|
+ "arch": "arch: %{ARCH}\\n",
|
||||||
|
+ "license": "%|LICENSE?{license: %{LICENSE}\\n}|",
|
||||||
|
+ "signature": "signature: %|DSAHEADER?{%{DSAHEADER:pgpsig}}:{%|RSAHEADER?{%{RSAHEADER:pgpsig}}:"
|
||||||
|
+ "{%|SIGGPG?{%{SIGGPG:pgpsig}}:{%|SIGPGP?{%{SIGPGP:pgpsig}}:{(none)}|}|}|}|\\n",
|
||||||
|
+ "packager": "%|PACKAGER?{packager: %{PACKAGER}\\n}|",
|
||||||
|
+ "url": "%|URL?{url: %{URL}\\n}|",
|
||||||
|
+ "summary": "summary: %{SUMMARY}\\n",
|
||||||
|
+ "description": "description:\\n%{DESCRIPTION}\\n",
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ attr = attr.get('attr', None) and attr['attr'].split(",") or None
|
||||||
|
+ query = list()
|
||||||
|
+ if attr:
|
||||||
|
+ for attr_k in attr:
|
||||||
|
+ if attr_k in attr_map and attr_k != 'description':
|
||||||
|
+ query.append(attr_map[attr_k])
|
||||||
|
+ if not query:
|
||||||
|
+ raise CommandExecutionError('No valid attributes found.')
|
||||||
|
+ if 'name' not in attr:
|
||||||
|
+ attr.append('name')
|
||||||
|
+ query.append(attr_map['name'])
|
||||||
|
+ else:
|
||||||
|
+ for attr_k, attr_v in attr_map.iteritems():
|
||||||
|
+ if attr_k != 'description':
|
||||||
|
+ query.append(attr_v)
|
||||||
|
+ if attr and 'description' in attr or not attr:
|
||||||
|
+ query.append(attr_map['description'])
|
||||||
|
+ query.append("-----\\n")
|
||||||
|
+
|
||||||
|
+ call = __salt__['cmd.run_all'](cmd + (" --queryformat '{0}'".format(''.join(query))),
|
||||||
|
+ output_loglevel='trace', env={'TZ': 'UTC'}, clean_env=True)
|
||||||
|
if call['retcode'] != 0:
|
||||||
|
comment = ''
|
||||||
|
if 'stderr' in call:
|
||||||
|
@@ -477,17 +501,31 @@ def info(*packages):
|
||||||
|
if len(line) != 2:
|
||||||
|
continue
|
||||||
|
key, value = line
|
||||||
|
- key = key.replace(' ', '_').lower()
|
||||||
|
if key == 'description':
|
||||||
|
descr_marker = True
|
||||||
|
continue
|
||||||
|
if key == 'name':
|
||||||
|
pkg_name = value
|
||||||
|
+
|
||||||
|
+ # Convert Unix ticks into ISO time format
|
||||||
|
if key in ['build_date', 'install_date']:
|
||||||
|
- value = _pkg_time_to_iso(value)
|
||||||
|
- if key != 'description' and value:
|
||||||
|
+ try:
|
||||||
|
+ pkg_data[key] = datetime.datetime.fromtimestamp(int(value)).isoformat() + "Z"
|
||||||
|
+ except ValueError:
|
||||||
|
+ log.warning('Could not convert "{0}" into Unix time'.format(value))
|
||||||
|
+ continue
|
||||||
|
+
|
||||||
|
+ # Convert Unix ticks into an Integer
|
||||||
|
+ if key in ['build_date_time_t', 'install_date_time_t']:
|
||||||
|
+ try:
|
||||||
|
+ pkg_data[key] = int(value)
|
||||||
|
+ except ValueError:
|
||||||
|
+ log.warning('Could not convert "{0}" into Unix time'.format(value))
|
||||||
|
+ continue
|
||||||
|
+ if key not in ['description', 'name'] and value:
|
||||||
|
pkg_data[key] = value
|
||||||
|
- pkg_data['description'] = os.linesep.join(descr)
|
||||||
|
+ if attr and 'description' in attr or not attr:
|
||||||
|
+ pkg_data['description'] = os.linesep.join(descr)
|
||||||
|
if pkg_name:
|
||||||
|
ret[pkg_name] = pkg_data
|
||||||
|
|
||||||
|
diff --git a/salt/modules/zypper.py b/salt/modules/zypper.py
|
||||||
|
index 84b5d51..ccba713 100644
|
||||||
|
--- a/salt/modules/zypper.py
|
||||||
|
+++ b/salt/modules/zypper.py
|
||||||
|
@@ -96,19 +96,32 @@ def list_upgrades(refresh=True):
|
||||||
|
list_updates = salt.utils.alias_function(list_upgrades, 'list_updates')
|
||||||
|
|
||||||
|
|
||||||
|
-def info_installed(*names):
|
||||||
|
+def info_installed(*names, **attr):
|
||||||
|
'''
|
||||||
|
Return the information of the named package(s), installed on the system.
|
||||||
|
|
||||||
|
+ :param names:
|
||||||
|
+ Names of the packages to get information about.
|
||||||
|
+
|
||||||
|
+ :param attr:
|
||||||
|
+ Comma-separated package attributes. If no 'attr' is specified, all available attributes returned.
|
||||||
|
+
|
||||||
|
+ Valid attributes are:
|
||||||
|
+ version, vendor, release, build_date, build_date_time_t, install_date, install_date_time_t,
|
||||||
|
+ build_host, group, source_rpm, arch, epoch, size, license, signature, packager, url,
|
||||||
|
+ summary, description.
|
||||||
|
+
|
||||||
|
CLI example:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
salt '*' pkg.info_installed <package1>
|
||||||
|
salt '*' pkg.info_installed <package1> <package2> <package3> ...
|
||||||
|
+ salt '*' pkg.info_installed <package1> attr=version,vendor
|
||||||
|
+ salt '*' pkg.info_installed <package1> <package2> <package3> ... attr=version,vendor
|
||||||
|
'''
|
||||||
|
ret = dict()
|
||||||
|
- for pkg_name, pkg_nfo in __salt__['lowpkg.info'](*names).items():
|
||||||
|
+ for pkg_name, pkg_nfo in __salt__['lowpkg.info'](*names, **attr).items():
|
||||||
|
t_nfo = dict()
|
||||||
|
# Translate dpkg-specific keys to a common structure
|
||||||
|
for key, value in pkg_nfo.items():
|
170
salt-2015.8-schedule-ret.patch
Normal file
170
salt-2015.8-schedule-ret.patch
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
diff --git a/salt/utils/schedule.py b/salt/utils/schedule.py
|
||||||
|
index 4458202..cae5fcf 100644
|
||||||
|
--- a/salt/utils/schedule.py
|
||||||
|
+++ b/salt/utils/schedule.py
|
||||||
|
@@ -482,24 +482,24 @@ class Schedule(object):
|
||||||
|
func = None
|
||||||
|
if func not in self.functions:
|
||||||
|
log.info(
|
||||||
|
- 'Invalid function: {0} in job {1}. Ignoring.'.format(
|
||||||
|
+ 'Invalid function: {0} in scheduled job {1}.'.format(
|
||||||
|
func, name
|
||||||
|
)
|
||||||
|
)
|
||||||
|
+
|
||||||
|
+ if 'name' not in data:
|
||||||
|
+ data['name'] = name
|
||||||
|
+ log.info(
|
||||||
|
+ 'Running Job: {0}.'.format(name)
|
||||||
|
+ )
|
||||||
|
+ if self.opts.get('multiprocessing', True):
|
||||||
|
+ thread_cls = multiprocessing.Process
|
||||||
|
else:
|
||||||
|
- if 'name' not in data:
|
||||||
|
- data['name'] = name
|
||||||
|
- log.info(
|
||||||
|
- 'Running Job: {0}.'.format(name)
|
||||||
|
- )
|
||||||
|
- if self.opts.get('multiprocessing', True):
|
||||||
|
- thread_cls = multiprocessing.Process
|
||||||
|
- else:
|
||||||
|
- thread_cls = threading.Thread
|
||||||
|
- proc = thread_cls(target=self.handle_func, args=(func, data))
|
||||||
|
- proc.start()
|
||||||
|
- if self.opts.get('multiprocessing', True):
|
||||||
|
- proc.join()
|
||||||
|
+ thread_cls = threading.Thread
|
||||||
|
+ proc = thread_cls(target=self.handle_func, args=(func, data))
|
||||||
|
+ proc.start()
|
||||||
|
+ if self.opts.get('multiprocessing', True):
|
||||||
|
+ proc.join()
|
||||||
|
|
||||||
|
def enable_schedule(self):
|
||||||
|
'''
|
||||||
|
@@ -642,33 +642,39 @@ class Schedule(object):
|
||||||
|
except OSError:
|
||||||
|
log.info('Unable to remove file: {0}.'.format(fn_))
|
||||||
|
|
||||||
|
- salt.utils.daemonize_if(self.opts)
|
||||||
|
+ try:
|
||||||
|
+ salt.utils.daemonize_if(self.opts)
|
||||||
|
|
||||||
|
- ret['pid'] = os.getpid()
|
||||||
|
+ ret['pid'] = os.getpid()
|
||||||
|
|
||||||
|
- if 'jid_include' not in data or data['jid_include']:
|
||||||
|
- log.debug('schedule.handle_func: adding this job to the jobcache '
|
||||||
|
- 'with data {0}'.format(ret))
|
||||||
|
- # write this to /var/cache/salt/minion/proc
|
||||||
|
- with salt.utils.fopen(proc_fn, 'w+b') as fp_:
|
||||||
|
- fp_.write(salt.payload.Serial(self.opts).dumps(ret))
|
||||||
|
-
|
||||||
|
- args = tuple()
|
||||||
|
- if 'args' in data:
|
||||||
|
- args = data['args']
|
||||||
|
-
|
||||||
|
- kwargs = {}
|
||||||
|
- if 'kwargs' in data:
|
||||||
|
- kwargs = data['kwargs']
|
||||||
|
- # if the func support **kwargs, lets pack in the pub data we have
|
||||||
|
- # TODO: pack the *same* pub data as a minion?
|
||||||
|
- argspec = salt.utils.args.get_function_argspec(self.functions[func])
|
||||||
|
- if argspec.keywords:
|
||||||
|
- # this function accepts **kwargs, pack in the publish data
|
||||||
|
- for key, val in six.iteritems(ret):
|
||||||
|
- kwargs['__pub_{0}'.format(key)] = val
|
||||||
|
+ if 'jid_include' not in data or data['jid_include']:
|
||||||
|
+ log.debug('schedule.handle_func: adding this job to the jobcache '
|
||||||
|
+ 'with data {0}'.format(ret))
|
||||||
|
+ # write this to /var/cache/salt/minion/proc
|
||||||
|
+ with salt.utils.fopen(proc_fn, 'w+b') as fp_:
|
||||||
|
+ fp_.write(salt.payload.Serial(self.opts).dumps(ret))
|
||||||
|
+
|
||||||
|
+ args = tuple()
|
||||||
|
+ if 'args' in data:
|
||||||
|
+ args = data['args']
|
||||||
|
+
|
||||||
|
+ kwargs = {}
|
||||||
|
+ if 'kwargs' in data:
|
||||||
|
+ kwargs = data['kwargs']
|
||||||
|
+
|
||||||
|
+ if func not in self.functions:
|
||||||
|
+ ret['return'] = self.functions.missing_fun_string(func)
|
||||||
|
+ salt.utils.error.raise_error(
|
||||||
|
+ message=self.functions.missing_fun_string(func))
|
||||||
|
+
|
||||||
|
+ # if the func support **kwargs, lets pack in the pub data we have
|
||||||
|
+ # TODO: pack the *same* pub data as a minion?
|
||||||
|
+ argspec = salt.utils.args.get_function_argspec(self.functions[func])
|
||||||
|
+ if argspec.keywords:
|
||||||
|
+ # this function accepts **kwargs, pack in the publish data
|
||||||
|
+ for key, val in six.iteritems(ret):
|
||||||
|
+ kwargs['__pub_{0}'.format(key)] = val
|
||||||
|
|
||||||
|
- try:
|
||||||
|
ret['return'] = self.functions[func](*args, **kwargs)
|
||||||
|
|
||||||
|
data_returner = data.get('returner', None)
|
||||||
|
@@ -694,28 +700,34 @@ class Schedule(object):
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
- # Only attempt to return data to the master
|
||||||
|
- # if the scheduled job is running on a minion.
|
||||||
|
- if '__role' in self.opts and self.opts['__role'] == 'minion':
|
||||||
|
- if 'return_job' in data and not data['return_job']:
|
||||||
|
- pass
|
||||||
|
- else:
|
||||||
|
- # Send back to master so the job is included in the job list
|
||||||
|
- mret = ret.copy()
|
||||||
|
- mret['jid'] = 'req'
|
||||||
|
- channel = salt.transport.Channel.factory(self.opts, usage='salt_schedule')
|
||||||
|
- load = {'cmd': '_return', 'id': self.opts['id']}
|
||||||
|
- for key, value in six.iteritems(mret):
|
||||||
|
- load[key] = value
|
||||||
|
- channel.send(load)
|
||||||
|
-
|
||||||
|
+ ret['retcode'] = self.functions.pack['__context__']['retcode']
|
||||||
|
+ ret['success'] = True
|
||||||
|
except Exception:
|
||||||
|
log.exception("Unhandled exception running {0}".format(ret['fun']))
|
||||||
|
# Although catch-all exception handlers are bad, the exception here
|
||||||
|
# is to let the exception bubble up to the top of the thread context,
|
||||||
|
# where the thread will die silently, which is worse.
|
||||||
|
+ if 'return' not in ret:
|
||||||
|
+ ret['return'] = "Unhandled exception running {0}".format(ret['fun'])
|
||||||
|
+ ret['success'] = False
|
||||||
|
+ ret['retcode'] = 254
|
||||||
|
finally:
|
||||||
|
try:
|
||||||
|
+ # Only attempt to return data to the master
|
||||||
|
+ # if the scheduled job is running on a minion.
|
||||||
|
+ if '__role' in self.opts and self.opts['__role'] == 'minion':
|
||||||
|
+ if 'return_job' in data and not data['return_job']:
|
||||||
|
+ pass
|
||||||
|
+ else:
|
||||||
|
+ # Send back to master so the job is included in the job list
|
||||||
|
+ mret = ret.copy()
|
||||||
|
+ mret['jid'] = 'req'
|
||||||
|
+ channel = salt.transport.Channel.factory(self.opts, usage='salt_schedule')
|
||||||
|
+ load = {'cmd': '_return', 'id': self.opts['id']}
|
||||||
|
+ for key, value in six.iteritems(mret):
|
||||||
|
+ load[key] = value
|
||||||
|
+ channel.send(load)
|
||||||
|
+
|
||||||
|
log.debug('schedule.handle_func: Removing {0}'.format(proc_fn))
|
||||||
|
os.unlink(proc_fn)
|
||||||
|
except OSError as exc:
|
||||||
|
@@ -757,11 +769,10 @@ class Schedule(object):
|
||||||
|
func = None
|
||||||
|
if func not in self.functions:
|
||||||
|
log.info(
|
||||||
|
- 'Invalid function: {0} in job {1}. Ignoring.'.format(
|
||||||
|
+ 'Invalid function: {0} in scheduled job {1}.'.format(
|
||||||
|
func, job
|
||||||
|
)
|
||||||
|
)
|
||||||
|
- continue
|
||||||
|
if 'name' not in data:
|
||||||
|
data['name'] = job
|
||||||
|
# Add up how many seconds between now and then
|
20
salt-2015.8-zypper-info.patch
Normal file
20
salt-2015.8-zypper-info.patch
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
diff --git a/salt/modules/zypper.py b/salt/modules/zypper.py
|
||||||
|
index ccba713..9d654a2 100644
|
||||||
|
--- a/salt/modules/zypper.py
|
||||||
|
+++ b/salt/modules/zypper.py
|
||||||
|
@@ -164,12 +164,14 @@ def info_available(*names, **kwargs):
|
||||||
|
# Run in batches
|
||||||
|
while batch:
|
||||||
|
cmd = 'zypper info -t package {0}'.format(' '.join(batch[:batch_size]))
|
||||||
|
- pkg_info.extend(re.split(r"----*", __salt__['cmd.run_stdout'](cmd, output_loglevel='trace')))
|
||||||
|
+ pkg_info.extend(re.split(r"Information for package*", __salt__['cmd.run_stdout'](cmd, output_loglevel='trace')))
|
||||||
|
batch = batch[batch_size:]
|
||||||
|
|
||||||
|
for pkg_data in pkg_info:
|
||||||
|
nfo = {}
|
||||||
|
for line in [data for data in pkg_data.split("\n") if ":" in data]:
|
||||||
|
+ if line.startswith("-----"):
|
||||||
|
+ continue
|
||||||
|
kw = [data.strip() for data in line.split(":", 1)]
|
||||||
|
if len(kw) == 2 and kw[1]:
|
||||||
|
nfo[kw[0].lower()] = kw[1]
|
26
salt.changes
26
salt.changes
@ -1,3 +1,29 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Fri Jan 15 13:16:46 UTC 2016 - dmacvicar@suse.de
|
||||||
|
|
||||||
|
- Fix zypper module info_available on SLE-11
|
||||||
|
* add salt-2015.8-zypper-info.patch
|
||||||
|
* https://github.com/saltstack/salt/pull/30384
|
||||||
|
- zypper/pkg: add package attributes filtering
|
||||||
|
* add salt-2015.8-pkg-zypper-attr-filtering.patch
|
||||||
|
* https://github.com/saltstack/salt/pull/30267
|
||||||
|
- Remove obsoleted patches and fixes:
|
||||||
|
* 0001-Add-rpm.minimal_info-fix-rpm.info.patch
|
||||||
|
* 0002-Reduce-information-returned-from-pkg.info_installed.patch
|
||||||
|
* Remove require on glibc-locale (bsc#959572)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Wed Jan 13 12:03:06 UTC 2016 - dmacvicar@suse.de
|
||||||
|
|
||||||
|
- Add missing return data to scheduled jobs
|
||||||
|
* add salt-2015.8-schedule-ret.patch for
|
||||||
|
* https://github.com/saltstack/salt/pull/30246
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Mon Dec 21 14:06:27 UTC 2015 - kkaempf@suse.com
|
||||||
|
|
||||||
|
- Update zypper-utf-8.patch for Python 2.6
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Thu Dec 17 15:53:47 UTC 2015 - kkaempf@suse.com
|
Thu Dec 17 15:53:47 UTC 2015 - kkaempf@suse.com
|
||||||
|
|
||||||
|
16
salt.spec
16
salt.spec
@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# spec file for package salt
|
# spec file for package salt
|
||||||
#
|
#
|
||||||
# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany.
|
# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
|
||||||
#
|
#
|
||||||
# All modifications and additions to the file contributed by third parties
|
# All modifications and additions to the file contributed by third parties
|
||||||
# remain the property of their copyright owners, unless otherwise agreed
|
# remain the property of their copyright owners, unless otherwise agreed
|
||||||
@ -53,11 +53,12 @@ Patch2: use-salt-user-for-master.patch
|
|||||||
Patch3: 1efe484309a5c776974e723f3da0f5181f4bdb86.patch
|
Patch3: 1efe484309a5c776974e723f3da0f5181f4bdb86.patch
|
||||||
# PATCH-FIX-OPENSUSE detect bad UTF-8 in package header, bsc#958350
|
# PATCH-FIX-OPENSUSE detect bad UTF-8 in package header, bsc#958350
|
||||||
Patch4: zypper-utf-8.patch
|
Patch4: zypper-utf-8.patch
|
||||||
# PATCH-FIX-OPENSUSE report epoch and architecture
|
# PATCH-FIX-UPSTREAM https://github.com/saltstack/salt/pull/30246
|
||||||
Patch5: 0001-Add-rpm.minimal_info-fix-rpm.info.patch
|
Patch5: salt-2015.8-schedule-ret.patch
|
||||||
# PATCH-FIX-OPENSUSE use minimal_info for pkg.info_installed
|
# PATCH-FIX-UPSTREAM https://github.com/saltstack/salt/pull/30267
|
||||||
Patch6: 0002-Reduce-information-returned-from-pkg.info_installed.patch
|
Patch6: salt-2015.8-pkg-zypper-attr-filtering.patch
|
||||||
|
# PATCH-FIX-UPSTREAM https://github.com/saltstack/salt/pull/30384
|
||||||
|
Patch7: salt-2015.8-zypper-info.patch
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||||
BuildRequires: logrotate
|
BuildRequires: logrotate
|
||||||
BuildRequires: python
|
BuildRequires: python
|
||||||
@ -105,8 +106,6 @@ Requires(pre): %{_sbindir}/useradd
|
|||||||
%if 0%{?suse_version}
|
%if 0%{?suse_version}
|
||||||
Requires(pre): %fillup_prereq
|
Requires(pre): %fillup_prereq
|
||||||
Requires(pre): pwdutils
|
Requires(pre): pwdutils
|
||||||
# bsc#959572
|
|
||||||
Requires: glibc-locale
|
|
||||||
%endif
|
%endif
|
||||||
Requires: logrotate
|
Requires: logrotate
|
||||||
Requires: python
|
Requires: python
|
||||||
@ -405,6 +404,7 @@ cp %{S:1} .
|
|||||||
%patch4 -p1
|
%patch4 -p1
|
||||||
%patch5 -p1
|
%patch5 -p1
|
||||||
%patch6 -p1
|
%patch6 -p1
|
||||||
|
%patch7 -p1
|
||||||
|
|
||||||
%build
|
%build
|
||||||
python setup.py --salt-transport=both build
|
python setup.py --salt-transport=both build
|
||||||
|
@ -1,15 +1,40 @@
|
|||||||
diff -wruN -x '*~' -x '*.o' -x '*.a' -x '*.so' -x '*.so.[0-9]' -x autom4te.cache -x .deps -x .libs ../orig-salt-2015.8.3/salt/modules/zypper.py ./salt/modules/zypper.py
|
From 8fcc530f0473e9fcd5a7099617516a6d184b5303 Mon Sep 17 00:00:00 2001
|
||||||
--- ../orig-salt-2015.8.3/salt/modules/zypper.py 2015-12-01 22:25:13.000000000 +0100
|
From: =?UTF-8?q?Klaus=20K=C3=A4mpf?= <kkaempf@suse.de>
|
||||||
+++ ./salt/modules/zypper.py 2015-12-09 09:15:41.157266587 +0100
|
Date: Thu, 10 Dec 2015 13:21:41 +0100
|
||||||
@@ -112,6 +112,11 @@
|
Subject: [PATCH] zypper: check package header content for valid utf-8
|
||||||
|
|
||||||
|
"salt 'system.domain.tld' pkg.info_installed --out json" can crash with
|
||||||
|
|
||||||
|
[ERROR ] An un-handled exception was caught by salt's global exception handler:
|
||||||
|
UnicodeDecodeError: 'utf8' codec can't decode byte ...
|
||||||
|
|
||||||
|
if a package name, summary, or description contains invalid UTF-8.
|
||||||
|
|
||||||
|
This patch detects such rpm header values, logs them as errors, and
|
||||||
|
replaces them with "*** Bad UTF-8 ***".
|
||||||
|
|
||||||
|
Update: drop the 'errors=' named parameter from the encode() call as it
|
||||||
|
is incompatible with Python 2.6 as used in SLE 11.
|
||||||
|
---
|
||||||
|
salt/modules/zypper.py | 5 +++++
|
||||||
|
1 file changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/salt/modules/zypper.py b/salt/modules/zypper.py
|
||||||
|
index be28311ae1bd..483d63e08edc 100644
|
||||||
|
--- a/salt/modules/zypper.py
|
||||||
|
+++ b/salt/modules/zypper.py
|
||||||
|
@@ -115,6 +115,11 @@ def info_installed(*names):
|
||||||
t_nfo = dict()
|
t_nfo = dict()
|
||||||
# Translate dpkg-specific keys to a common structure
|
# Translate dpkg-specific keys to a common structure
|
||||||
for key, value in pkg_nfo.items():
|
for key, value in pkg_nfo.items():
|
||||||
+ try:
|
+ try:
|
||||||
+ value = value.encode('UTF-8', errors='replace')
|
+ value = value.encode('UTF-8', 'replace')
|
||||||
+ except(UnicodeDecodeError):
|
+ except(UnicodeDecodeError):
|
||||||
+ log.error('Package ' + pkg_name + ' has bad UTF-8 code in ' + key + ': ' + value)
|
+ log.error('Package {0} has bad UTF-8 code in {1}: {2}'.format(pkg_name, key, value))
|
||||||
+ value = '*** Bad UTF-8 ***'
|
+ value = '*** Bad UTF-8 ***'
|
||||||
if key == 'source_rpm':
|
if key == 'source_rpm':
|
||||||
t_nfo['source'] = value
|
t_nfo['source'] = value
|
||||||
else:
|
else:
|
||||||
|
--
|
||||||
|
2.6.3
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user