diff --git a/.gitignore b/.gitignore index 3d2c1be..e9d2fe9 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/python-rhsm-1.13.10.tar.gz +SOURCES/python-rhsm-1.15.4.tar.gz diff --git a/.python-rhsm.metadata b/.python-rhsm.metadata index 4b71a4d..a291a52 100644 --- a/.python-rhsm.metadata +++ b/.python-rhsm.metadata @@ -1 +1 @@ -5aacef3155491c3cec40c41075d133ca3ca435a7 SOURCES/python-rhsm-1.13.10.tar.gz +41a60713b8fdf71959c2afada27ae2f213c78628 SOURCES/python-rhsm-1.15.4.tar.gz diff --git a/SOURCES/python-rhsm-1.15.4-1-to-python-rhsm-1.15.4-2.patch b/SOURCES/python-rhsm-1.15.4-1-to-python-rhsm-1.15.4-2.patch new file mode 100644 index 0000000..f5cdccb --- /dev/null +++ b/SOURCES/python-rhsm-1.15.4-1-to-python-rhsm-1.15.4-2.patch @@ -0,0 +1,42 @@ +diff --git a/python-rhsm.spec b/python-rhsm.spec +index 56bb1e7..0318cc1 100644 +--- a/python-rhsm.spec ++++ b/python-rhsm.spec +@@ -13,7 +13,7 @@ + + Name: python-rhsm + Version: 1.15.4 +-Release: 1%{?dist} ++Release: 2%{?dist} + + Summary: A Python library to communicate with a Red Hat Unified Entitlement Platform + Group: Development/Libraries +@@ -74,6 +74,9 @@ rm -rf %{buildroot} + %attr(644,root,root) %{_sysconfdir}/rhsm/ca/*.pem + + %changelog ++* Thu Jul 23 2015 Chris Rog 1.15.4-2 ++- Fedora 20 has been retired. (awood@redhat.com) ++ + * Fri Jul 10 2015 Chris Rog 1.15.4-1 + - + +diff --git a/rel-eng/packages/python-rhsm b/rel-eng/packages/python-rhsm +index 8ff10ef..ace4dde 100644 +--- a/rel-eng/packages/python-rhsm ++++ b/rel-eng/packages/python-rhsm +@@ -1 +1 @@ +-1.15.4-1 ./ ++1.15.4-2 ./ +diff --git a/rel-eng/releasers.conf b/rel-eng/releasers.conf +index 6c37bf7..faabcb0 100644 +--- a/rel-eng/releasers.conf ++++ b/rel-eng/releasers.conf +@@ -1,6 +1,6 @@ + [fedora] + releaser = tito.release.FedoraGitReleaser +-branches = master f22 f21 f20 ++branches = master f23 f22 f21 + + [rhel-7.1] + releaser = tito.release.DistGitReleaser diff --git a/SOURCES/python-rhsm-1.15.4-2-to-python-rhsm-1.15.4-3.patch b/SOURCES/python-rhsm-1.15.4-2-to-python-rhsm-1.15.4-3.patch new file mode 100644 index 0000000..1dd9c2d --- /dev/null +++ b/SOURCES/python-rhsm-1.15.4-2-to-python-rhsm-1.15.4-3.patch @@ -0,0 +1,315 @@ +diff --git a/python-rhsm.spec b/python-rhsm.spec +index 0318cc1..d2e00c1 100644 +--- a/python-rhsm.spec ++++ b/python-rhsm.spec +@@ -13,7 +13,7 @@ + + Name: python-rhsm + Version: 1.15.4 +-Release: 2%{?dist} ++Release: 3%{?dist} + + Summary: A Python library to communicate with a Red Hat Unified Entitlement Platform + Group: Development/Libraries +@@ -74,6 +74,11 @@ rm -rf %{buildroot} + %attr(644,root,root) %{_sysconfdir}/rhsm/ca/*.pem + + %changelog ++* Wed Aug 12 2015 Chris Rog 1.15.4-3 ++- Add user-agent to rhsm requests. (alikins@redhat.com) ++- 1247890: KeyErrors are now caught when checking manager capabilities ++ (csnyder@redhat.com) ++ + * Thu Jul 23 2015 Chris Rog 1.15.4-2 + - Fedora 20 has been retired. (awood@redhat.com) + +diff --git a/rel-eng/packages/python-rhsm b/rel-eng/packages/python-rhsm +index ace4dde..c370a05 100644 +--- a/rel-eng/packages/python-rhsm ++++ b/rel-eng/packages/python-rhsm +@@ -1 +1 @@ +-1.15.4-2 ./ ++1.15.4-3 ./ +diff --git a/rel-eng/tito.props b/rel-eng/tito.props +index fd057f6..6c86a16 100644 +--- a/rel-eng/tito.props ++++ b/rel-eng/tito.props +@@ -1,4 +1,4 @@ +-[buildconfig] +-builder = tito.builder.Builder +-tagger = tito.tagger.VersionTagger ++[globalconfig] ++default_builder = tito.distributionbuilder.DistributionBuilder ++default_tagger = tito.tagger.ReleaseTagger + +diff --git a/src/rhsm/connection.py b/src/rhsm/connection.py +index 465405d..f5cbbdf 100644 +--- a/src/rhsm/connection.py ++++ b/src/rhsm/connection.py +@@ -43,7 +43,7 @@ except ImportError: + subman_version = "unknown" + + from rhsm import ourjson as json +-from rhsm.utils import get_env_proxy_info ++from rhsm import utils + + global_socket_timeout = 60 + timeout_altered = None +@@ -115,6 +115,7 @@ def drift_check(utc_time_string, hours=1): + return drift + + ++ + class ConnectionException(Exception): + pass + +@@ -264,7 +265,6 @@ class ContentConnection(object): + self.username = username + self.password = password + self.ssl_verify_depth = ssl_verify_depth +- + self.timeout_altered = False + + # get the proxy information from the environment variable +@@ -275,13 +275,17 @@ class ContentConnection(object): + 'proxy_port': '', + 'proxy_password': ''} + else: +- info = get_env_proxy_info() ++ info = utils.get_env_proxy_info() + + self.proxy_hostname = proxy_hostname or config.get('server', 'proxy_hostname') or info['proxy_hostname'] + self.proxy_port = proxy_port or config.get('server', 'proxy_port') or info['proxy_port'] + self.proxy_user = proxy_user or config.get('server', 'proxy_user') or info['proxy_username'] + self.proxy_password = proxy_password or config.get('server', 'proxy_password') or info['proxy_password'] + ++ @property ++ def user_agent(self): ++ return "RHSM-content/1.0 (cmd=%s)" % utils.cmd_name(sys.argv) ++ + def _request(self, request_type, handler, body=None): + # See note in Restlib._request + context = SSL.Context("sslv23") +@@ -304,7 +308,11 @@ class ContentConnection(object): + + set_default_socket_timeout_if_python_2_3() + +- conn.request("GET", handler, body="", headers={"Host": "%s:%s" % (self.host, self.ssl_port), "Content-Length": "0"}) ++ conn.request("GET", handler, ++ body="", ++ headers={"Host": "%s:%s" % (self.host, self.ssl_port), ++ "Content-Length": "0", ++ "User-Agent": self.user_agent}) + response = conn.getresponse() + result = { + "content": response.read(), +@@ -383,6 +391,9 @@ class Restlib(object): + self.apihandler = apihandler + lc = _get_locale() + ++ # Default, updated by UepConnection ++ self.user_agent = "python-rhsm-user-agent" ++ + self.headers = {"Content-type": "application/json", + "Accept": "application/json", + "x-python-rhsm-version": python_rhsm_version, +@@ -492,6 +503,7 @@ class Restlib(object): + else: + conn = httpslib.HTTPSConnection(self.host, self.ssl_port, ssl_context=context) + ++ + if info is not None: + body = json.dumps(info, default=json.encode) + else: +@@ -499,6 +511,9 @@ class Restlib(object): + + log.debug("Making request: %s %s" % (request_type, handler)) + ++ if self.user_agent: ++ self.headers['User-Agent'] = self.user_agent ++ + headers = self.headers + if body is None: + headers = dict(self.headers.items() + +@@ -665,7 +680,7 @@ class UEPConnection: + 'proxy_port': '', + 'proxy_password': ''} + else: +- info = get_env_proxy_info() ++ info = utils.get_env_proxy_info() + + self.proxy_hostname = proxy_hostname or config.get('server', 'proxy_hostname') or info['proxy_hostname'] + self.proxy_port = proxy_port or config.get('server', 'proxy_port') or info['proxy_port'] +@@ -731,6 +746,8 @@ class UEPConnection: + ssl_verify_depth=self.ssl_verify_depth) + auth_description = "auth=none" + ++ self.conn.user_agent = "RHSM/1.0 (cmd=%s)" % utils.cmd_name(sys.argv) ++ + self.resources = None + self.capabilities = None + connection_description = "" +@@ -771,21 +788,27 @@ class UEPConnection: + def _load_manager_capabilities(self): + """ + Loads manager capabilities by doing a GET on the status +- resource located at '/status/' +- """ +- self.capabilities = {} +- self.capabilities = self.conn.request_get("/status/") +- self.capabilities = self.capabilities['managerCapabilities'] +- log.debug("Server has the following capabilities: %s", +- self.capabilities) ++ resource located at '/status' ++ """ ++ status = self.getStatus() ++ capabilities = status.get('managerCapabilities') ++ if capabilities is None: ++ log.debug("The status retrieved did not \ ++ include key 'managerCapabilities'.\nStatus:'%s'" % status) ++ capabilities = [] ++ elif isinstance(capabilities, list) and not capabilities: ++ log.debug("The managerCapabilities list \ ++ was empty\nStatus:'%s'" % status) ++ else: ++ log.debug("Server has the following capabilities: %s", capabilities) ++ return capabilities + + def has_capability(self, capability): + """ + Check if the server we're connected to has a particular capability. + """ + if self.capabilities is None: +- self._load_manager_capabilities() +- ++ self.capabilities = self._load_manager_capabilities() + return capability in self.capabilities + + def shutDown(self): +diff --git a/src/rhsm/utils.py b/src/rhsm/utils.py +index dd41161..f1a7f4e 100644 +--- a/src/rhsm/utils.py ++++ b/src/rhsm/utils.py +@@ -17,6 +17,7 @@ import gettext + import os + import re + from urlparse import urlparse ++ + from rhsm.config import DEFAULT_PROXY_PORT + + _ = lambda x: gettext.ldgettext("rhsm", x) +@@ -232,3 +233,24 @@ def get_env_proxy_info(): + else: + the_proxy['proxy_port'] = int(info[3]) + return the_proxy ++ ++ ++def cmd_name(argv): ++ """Attempt to get a meaningful command name from argv. ++ ++ This handles cases where argv[0] isn't helpful (for ++ example, '/usr/bin/python' or '__main__.py'. ++ """ ++ argv0 = os.path.basename(argv[0]) ++ argvdir = os.path.dirname(argv[0]) ++ head, tail = os.path.split(argvdir) ++ ++ cmd_name_string = argv0 ++ # initial-setup is launched as 'python -m initial_setup', so ++ # sys.argv looks like ++ # ['/usr/lib/python2.7/site-packages/initial_setup/__main__.py'], ++ # so we look for initial_setup in the exe path. ++ if tail == "initial_setup": ++ cmd_name_string = "initial-setup" ++ ++ return cmd_name_string +diff --git a/test/unit/connection-tests.py b/test/unit/connection-tests.py +index 6e449ad..8a0091d 100644 +--- a/test/unit/connection-tests.py ++++ b/test/unit/connection-tests.py +@@ -37,6 +37,26 @@ class ConnectionTests(unittest.TestCase): + self.cp = UEPConnection(username="dummy", password="dummy", + handler="/Test/", insecure=True) + ++ def test_load_manager_capabilities(self): ++ expected_capabilities = ['hypervisors_async', 'cores'] ++ proper_status = {'version':'1', ++ 'result':True, ++ 'managerCapabilities':expected_capabilities} ++ improper_status = dict.copy(proper_status) ++ # Remove the managerCapabilities key from the dict ++ del improper_status['managerCapabilities'] ++ self.cp.conn = Mock() ++ # The first call will return the proper_status, the second, the improper ++ # status ++ original_getStatus = self.cp.getStatus ++ self.cp.getStatus = Mock(side_effect=[proper_status, ++ improper_status]) ++ actual_capabilities = self.cp._load_manager_capabilities() ++ self.assertEquals(sorted(actual_capabilities), ++ sorted(expected_capabilities)) ++ self.assertEquals([], self.cp._load_manager_capabilities()) ++ self.cp.getStatus = original_getStatus ++ + def test_get_environment_by_name_requires_owner(self): + self.assertRaises(Exception, self.cp.getEnvironment, None, {"name": "env name"}) + +diff --git a/test/unit/util-tests.py b/test/unit/util-tests.py +index c650d74..4d4a65b 100644 +--- a/test/unit/util-tests.py ++++ b/test/unit/util-tests.py +@@ -6,7 +6,7 @@ from rhsm.utils import remove_scheme, get_env_proxy_info, \ + ServerUrlParseErrorEmpty, ServerUrlParseErrorNone, \ + ServerUrlParseErrorPort, ServerUrlParseErrorScheme, \ + ServerUrlParseErrorJustScheme, has_bad_scheme, has_good_scheme, \ +- parse_url ++ parse_url, cmd_name + from rhsm.config import DEFAULT_PORT, DEFAULT_PREFIX, DEFAULT_HOSTNAME, \ + DEFAULT_CDN_HOSTNAME, DEFAULT_CDN_PORT, DEFAULT_CDN_PREFIX + +@@ -379,3 +379,45 @@ class TestProxyInfo(unittest.TestCase): + self.assertEquals(None, proxy_info["proxy_password"]) + self.assertEquals("host", proxy_info["proxy_hostname"]) + self.assertEquals(int("1111"), proxy_info["proxy_port"]) ++ ++ ++class TestCmdName(unittest.TestCase): ++ def test_usr_sbin(self): ++ argv = ['/usr/sbin/subscription-manager', 'list'] ++ self.assertEquals("subscription-manager", cmd_name(argv)) ++ ++ def test_bin(self): ++ argv = ['bin/subscription-manager', 'subscribe', '--auto'] ++ self.assertEquals("subscription-manager", cmd_name(argv)) ++ ++ def test_sbin(self): ++ argv = ['/sbin/subscription-manager', 'list'] ++ self.assertEquals("subscription-manager", cmd_name(argv)) ++ ++ def test_subscription_manager_gui(self): ++ argv = ['/sbin/subscription-manager-gui'] ++ self.assertEquals("subscription-manager-gui", cmd_name(argv)) ++ ++ def test_initial_setup(self): ++ argv = ['/usr/lib/python2.7/site-packages/initial_setup/__main__.py'] ++ self.assertEquals("initial-setup", cmd_name(argv)) ++ ++ def test_yum(self): ++ argv = ['/bin/yum', 'install', 'zsh'] ++ self.assertEquals("yum", cmd_name(argv)) ++ ++ def test_rhsmcertd_worker(self): ++ argv = ['/usr/libexec/rhsmcertd-worker'] ++ self.assertEquals("rhsmcertd-worker", cmd_name(argv)) ++ ++ def test_rhsm_debug(self): ++ argv = ['/bin/rhsm-debug'] ++ self.assertEquals("rhsm-debug", cmd_name(argv)) ++ ++ def test_virt_who(self): ++ argv = ['/usr/share/virt-who/virtwho.py'] ++ self.assertEquals("virtwho.py", cmd_name(argv)) ++ ++ def test_rhsmd(self): ++ argv = ['/usr/libexec/rhsmd', '-i', '-f', 'valid'] ++ self.assertEquals("rhsmd", cmd_name(argv)) diff --git a/SOURCES/python-rhsm-1.15.4-3-to-python-rhsm-1.15.4-4.patch b/SOURCES/python-rhsm-1.15.4-3-to-python-rhsm-1.15.4-4.patch new file mode 100644 index 0000000..f1894d5 --- /dev/null +++ b/SOURCES/python-rhsm-1.15.4-3-to-python-rhsm-1.15.4-4.patch @@ -0,0 +1,181 @@ +diff --git a/python-rhsm.spec b/python-rhsm.spec +index d2e00c1..d998de9 100644 +--- a/python-rhsm.spec ++++ b/python-rhsm.spec +@@ -13,7 +13,7 @@ + + Name: python-rhsm + Version: 1.15.4 +-Release: 3%{?dist} ++Release: 4%{?dist} + + Summary: A Python library to communicate with a Red Hat Unified Entitlement Platform + Group: Development/Libraries +@@ -74,6 +74,10 @@ rm -rf %{buildroot} + %attr(644,root,root) %{_sysconfdir}/rhsm/ca/*.pem + + %changelog ++* Wed Sep 02 2015 Chris Rog 1.15.4-4 ++- Adds RateLimitExceededException which is raised in response to 429 from the ++ remote host (csnyder@redhat.com) ++ + * Wed Aug 12 2015 Chris Rog 1.15.4-3 + - Add user-agent to rhsm requests. (alikins@redhat.com) + - 1247890: KeyErrors are now caught when checking manager capabilities +diff --git a/rel-eng/packages/python-rhsm b/rel-eng/packages/python-rhsm +index c370a05..6f475ed 100644 +--- a/rel-eng/packages/python-rhsm ++++ b/rel-eng/packages/python-rhsm +@@ -1 +1 @@ +-1.15.4-3 ./ ++1.15.4-4 ./ +diff --git a/src/rhsm/connection.py b/src/rhsm/connection.py +index f5cbbdf..c4d0264 100644 +--- a/src/rhsm/connection.py ++++ b/src/rhsm/connection.py +@@ -115,7 +115,6 @@ def drift_check(utc_time_string, hours=1): + return drift + + +- + class ConnectionException(Exception): + pass + +@@ -137,9 +136,10 @@ class BadCertificateException(ConnectionException): + + class RestlibException(ConnectionException): + +- def __init__(self, code, msg=None): ++ def __init__(self, code, msg=None, headers=None): + self.code = code + self.msg = msg or "" ++ self.headers = headers or {} + + def __str__(self): + return self.msg +@@ -192,6 +192,17 @@ class AuthenticationException(RemoteServerException): + return buf + + ++class RateLimitExceededException(RestlibException): ++ def __init__(self, code, ++ msg=None, ++ headers=None): ++ super(RateLimitExceededException, self).__init__(code, ++ msg) ++ self.headers = headers or {} ++ self.msg = msg or "" ++ self.retry_after = safe_int(self.headers.get('Retry-After')) ++ ++ + class UnauthorizedException(AuthenticationException): + prefix = "Unauthorized" + +@@ -316,7 +327,8 @@ class ContentConnection(object): + response = conn.getresponse() + result = { + "content": response.read(), +- "status": response.status} ++ "status": response.status, ++ "headers": dict(response.getheaders())} + + return result + +@@ -503,7 +515,6 @@ class Restlib(object): + else: + conn = httpslib.HTTPSConnection(self.host, self.ssl_port, ssl_context=context) + +- + if info is not None: + body = json.dumps(info, default=json.encode) + else: +@@ -534,6 +545,7 @@ class Restlib(object): + result = { + "content": response.read(), + "status": response.status, ++ "headers": dict(response.getheaders()) + } + + response_log = 'Response: status=' + str(result['status']) +@@ -588,10 +600,15 @@ class Restlib(object): + # had more meaningful exceptions. We've gotten a response from + # the server that means something. + ++ error_msg = self._parse_msg_from_error_response_body(parsed) ++ if str(response['status']) in ['429']: ++ raise RateLimitExceededException(response['status'], ++ error_msg, ++ headers=response.get('headers')) ++ + # FIXME: we can get here with a valid json response that + # could be anything, we don't verify it anymore +- error_msg = self._parse_msg_from_error_response_body(parsed) +- raise RestlibException(response['status'], error_msg) ++ raise RestlibException(response['status'], error_msg, response.get('headers')) + else: + # This really needs an exception mapper too... + if str(response['status']) in ["404", "410", "500", "502", "503", "504"]: +@@ -606,6 +623,9 @@ class Restlib(object): + raise ForbiddenException(response['status'], + request_type=request_type, + handler=handler) ++ elif str(response['status']) in ['429']: ++ raise RateLimitExceededException(response['status']) ++ + else: + # unexpected with no valid content + raise NetworkException(response['status']) +diff --git a/test/unit/connection-tests.py b/test/unit/connection-tests.py +index 8a0091d..a17b3ed 100644 +--- a/test/unit/connection-tests.py ++++ b/test/unit/connection-tests.py +@@ -20,7 +20,8 @@ import unittest + from rhsm.connection import UEPConnection, Restlib, ConnectionException, ConnectionSetupException, \ + BadCertificateException, RestlibException, GoneException, NetworkException, \ + RemoteServerException, drift_check, ExpiredIdentityCertException, UnauthorizedException, \ +- ForbiddenException, AuthenticationException, set_default_socket_timeout_if_python_2_3 ++ ForbiddenException, AuthenticationException, set_default_socket_timeout_if_python_2_3, \ ++ RateLimitExceededException + + from mock import Mock, patch + from datetime import date +@@ -157,9 +158,11 @@ class RestlibValidateResponseTests(unittest.TestCase): + self.request_type = "GET" + self.handler = "https://server/path" + +- def vr(self, status, content): ++ def vr(self, status, content, headers=None): + response = {'status': status, + 'content': content} ++ if headers: ++ response['headers'] = headers + #print "response", response + self.restlib.validateResponse(response, self.request_type, self.handler) + +@@ -347,6 +350,26 @@ class RestlibValidateResponseTests(unittest.TestCase): + else: + self.fail("Should have raised a GoneException") + ++ def test_429_empty(self): ++ try: ++ self.vr("429", "") ++ except RateLimitExceededException, e: ++ self.assertEquals("429", e.code) ++ else: ++ self.fail("Should have raised a RateLimitExceededException") ++ ++ def test_429_body(self): ++ content = u'{"errors": ["TooFast"]}' ++ headers = {'Retry-After': 20} ++ try: ++ self.vr("429", content, headers) ++ except RateLimitExceededException, e: ++ self.assertEquals(20, e.retry_after) ++ self.assertEquals("TooFast", e.msg) ++ self.assertEquals("429", e.code) ++ else: ++ self.fail("Should have raised a RateLimitExceededException") ++ + def test_500_empty(self): + try: + self.vr("500", "") diff --git a/SOURCES/python-rhsm-1.15.4-4-to-python-rhsm-1.15.4-5.patch b/SOURCES/python-rhsm-1.15.4-4-to-python-rhsm-1.15.4-5.patch new file mode 100644 index 0000000..4a8f2ad --- /dev/null +++ b/SOURCES/python-rhsm-1.15.4-4-to-python-rhsm-1.15.4-5.patch @@ -0,0 +1,77 @@ +diff --git a/etc-conf/ca/candlepin-stage.pem b/etc-conf/ca/candlepin-stage.pem +deleted file mode 100644 +index 018dd48..0000000 +--- a/etc-conf/ca/candlepin-stage.pem ++++ /dev/null +@@ -1,41 +0,0 @@ +------BEGIN CERTIFICATE----- +-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 +-g6EHdPrR+A== +------END CERTIFICATE----- +- +diff --git a/python-rhsm.spec b/python-rhsm.spec +index d998de9..a7682be 100644 +--- a/python-rhsm.spec ++++ b/python-rhsm.spec +@@ -13,7 +13,7 @@ + + Name: python-rhsm + Version: 1.15.4 +-Release: 4%{?dist} ++Release: 5%{?dist} + + Summary: A Python library to communicate with a Red Hat Unified Entitlement Platform + Group: Development/Libraries +@@ -74,6 +74,9 @@ rm -rf %{buildroot} + %attr(644,root,root) %{_sysconfdir}/rhsm/ca/*.pem + + %changelog ++* Thu Sep 10 2015 Chris Rog 1.15.4-5 ++- 1242057: This cert is no longer used and can be removed (wpoteat@redhat.com) ++ + * Wed Sep 02 2015 Chris Rog 1.15.4-4 + - Adds RateLimitExceededException which is raised in response to 429 from the + remote host (csnyder@redhat.com) +diff --git a/rel-eng/packages/python-rhsm b/rel-eng/packages/python-rhsm +index 6f475ed..dd64b5f 100644 +--- a/rel-eng/packages/python-rhsm ++++ b/rel-eng/packages/python-rhsm +@@ -1 +1 @@ +-1.15.4-4 ./ ++1.15.4-5 ./ diff --git a/SPECS/python-rhsm.spec b/SPECS/python-rhsm.spec index 1862b1f..8559a2c 100644 --- a/SPECS/python-rhsm.spec +++ b/SPECS/python-rhsm.spec @@ -8,10 +8,12 @@ # simplejson is not available in RHEL 7 at all. %global use_simplejson (0%{?rhel} && 0%{?rhel} == 5) +%global _hardened_build 1 +%{!?__global_ldflags: %global __global_ldflags -Wl,-z,relro -Wl,-z,now} Name: python-rhsm -Version: 1.13.10 -Release: 1%{?dist} +Version: 1.15.4 +Release: 5%{?dist} Summary: A Python library to communicate with a Red Hat Unified Entitlement Platform Group: Development/Libraries @@ -22,7 +24,11 @@ License: GPLv2 # cd client/python-rhsm # tito build --tag python-rhsm-$VERSION-$RELEASE --tgz Source0: %{name}-%{version}.tar.gz -URL: http://fedorahosted.org/candlepin +Patch0: python-rhsm-1.15.4-1-to-python-rhsm-1.15.4-2.patch +Patch1: python-rhsm-1.15.4-2-to-python-rhsm-1.15.4-3.patch +Patch2: python-rhsm-1.15.4-3-to-python-rhsm-1.15.4-4.patch +Patch3: python-rhsm-1.15.4-4-to-python-rhsm-1.15.4-5.patch +URL: http://www.candlepinproject.org BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Requires: m2crypto @@ -45,9 +51,14 @@ entitlements, certificates, and access to content. %prep %setup -q -n python-rhsm-%{version} +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 %build -%{__python} setup.py build +# create a version.py with the rpm version info +PYTHON_RHSM_VERSION=%{version} PYTHON_RHSM_RELEASE=%{release} CFLAGS="%{optflags}" LDFLAGS="%{__global_ldflags}" %{__python} setup.py build %install rm -rf %{buildroot} @@ -71,6 +82,56 @@ rm -rf %{buildroot} %attr(644,root,root) %{_sysconfdir}/rhsm/ca/*.pem %changelog +* Thu Sep 10 2015 Chris Rog 1.15.4-5 +- 1242057: This cert is no longer used and can be removed (wpoteat@redhat.com) + +* Wed Sep 02 2015 Chris Rog 1.15.4-4 +- Adds RateLimitExceededException which is raised in response to 429 from the + remote host (csnyder@redhat.com) + +* Wed Aug 12 2015 Chris Rog 1.15.4-3 +- Add user-agent to rhsm requests. (alikins@redhat.com) +- 1247890: KeyErrors are now caught when checking manager capabilities + (csnyder@redhat.com) + +* Thu Jul 23 2015 Chris Rog 1.15.4-2 +- Fedora 20 has been retired. (awood@redhat.com) + +* Fri Jul 10 2015 Chris Rog 1.15.4-1 +- + +* Tue Jul 07 2015 Adrian Likins 1.15.3-1 +- Define global_ld_flags when not already defined. (awood@redhat.com) +- Adding tests for 202s from alikins/AsyncBind (csnyder@redhat.com) +- Updates to accomodate candlepin/virt-who/csnyder/new_report_api + (csnyder@redhat.com) +- Adding jobStatus helper methods from alikins/AsyncBind (csnyder@redhat.com) +- HypervisorCheckIn now uses the new API, if available (csnyder@redhat.com) + +* Mon Jun 22 2015 Chris Rog 1.15.2-1 +- Added releaser configuration for RHEL 7.2 (crog@redhat.com) +- Use non-deprecated Tito properties. (awood@redhat.com) + +* Thu Jun 11 2015 Alex Wood 1.15.1-1 +- Move Python.h include to be first include (alikins@redhat.com) +- 1092564: Provide LDFLAGS to setup.py to enable hardened build. + (awood@redhat.com) +- Bump version to 1.15 (wpoteat@redhat.com) +- Do not process proxy environment variables if host is in no_proxy + (martin.matuska@axelspringer.de) + +* Tue Jun 02 2015 William Poteat 1.14.3-1 +- 1225600: Default config entry needs to include the substitution string + (wpoteat@redhat.com) +- Add F22 to Fedora branches. (awood@redhat.com) + +* Thu Feb 26 2015 Alex Wood 1.14.2-1 +- 1195446: Only set global socket timeout on RHEL 5. (alikins@redhat.com) +- Cleanup up connection logging. (alikins@redhat.com) + +* Fri Feb 06 2015 Devan Goodwin 1.14.1-1 +- 976855: build_py now populates version.py with ver (alikins@redhat.com) +- 1187587: Correct project URL in spec file. (awood@redhat.com) * Fri Jan 09 2015 William Poteat 1.13.10-1 - Add custom JSON encoding for set objects. (awood@redhat.com) - Update SSL context options to follow the M2Crypto standard idiom.