Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-osc-tiny for openSUSE:Factory
checked in at 2022-07-21 11:33:08
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-osc-tiny (Old)
and /work/SRC/openSUSE:Factory/.python-osc-tiny.new.1523 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-osc-tiny"
Thu Jul 21 11:33:08 2022 rev:16 rq:990423 version:0.6.5
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-osc-tiny/python-osc-tiny.changes
2022-07-03 18:26:53.320735019 +0200
+++
/work/SRC/openSUSE:Factory/.python-osc-tiny.new.1523/python-osc-tiny.changes
2022-07-21 11:33:37.402961354 +0200
@@ -1,0 +2,22 @@
+Wed Jul 20 08:49:57 UTC 2022 - Andreas Hasenkopf <[email protected]>
+
+- Release 0.6.5: Enhanced dependency management
+ * Removed `responses` as requirement
+ * Use `cached_property` instead of `backports.cached_property`
+ (which is not in the openSUSE repos)
+ * Only install `cached_property` as requirement for Py3.7 and earlier
+
+-------------------------------------------------------------------
+Tue Jul 19 07:01:51 UTC 2022 - Andreas Hasenkopf <[email protected]>
+
+- Release 0.6.4
+ * Handle 40x (x!=1) responses properly in `HttpSignatureAuth`
+
+-------------------------------------------------------------------
+Mon Jul 18 07:55:16 UTC 2022 - Andreas Hasenkopf <[email protected]>
+
+- Release 0.6.3
+ * Do not assume that `oscrc` contains the SSH passphrase
+ * Handle absence of `sshkey` in `.oscrc` gracefully
+
+-------------------------------------------------------------------
Old:
----
osc-tiny-0.6.2.tar.gz
New:
----
osc-tiny-0.6.5.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-osc-tiny.spec ++++++
--- /var/tmp/diff_new_pack.ZFXFJ6/_old 2022-07-21 11:33:38.058962001 +0200
+++ /var/tmp/diff_new_pack.ZFXFJ6/_new 2022-07-21 11:33:38.062962005 +0200
@@ -19,7 +19,7 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
%define skip_python2 1
Name: python-osc-tiny
-Version: 0.6.2
+Version: 0.6.5
Release: 0
Summary: Client API for openSUSE BuildService
License: MIT
@@ -27,7 +27,6 @@
URL: https://github.com/crazyscientist/osc-tiny
Source:
https://files.pythonhosted.org/packages/source/o/osc-tiny/osc-tiny-%{version}.tar.gz
BuildRequires: %{python_module PyYAML}
-BuildRequires: %{python_module cached-property}
BuildRequires: %{python_module devel}
BuildRequires: %{python_module lxml}
BuildRequires: %{python_module pytest}
@@ -39,11 +38,14 @@
BuildRequires: fdupes
BuildRequires: python-rpm-macros
Requires: python-PyYAML
-Requires: python-cached-property
Requires: python-lxml
Requires: python-python-dateutil
Requires: python-pytz
Requires: python-requests
+%if %python_version_nodots < 38
+BuildRequires: python3-cached-property
+Requires: python-cached-property
+%endif
Suggests: openssh
BuildArch: noarch
%python_subpackages
++++++ osc-tiny-0.6.2.tar.gz -> osc-tiny-0.6.5.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osc-tiny-0.6.2/PKG-INFO new/osc-tiny-0.6.5/PKG-INFO
--- old/osc-tiny-0.6.2/PKG-INFO 2022-06-30 10:46:34.485521000 +0200
+++ new/osc-tiny-0.6.5/PKG-INFO 2022-07-20 10:38:48.407163100 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: osc-tiny
-Version: 0.6.2
+Version: 0.6.5
Summary: Client API for openSUSE BuildService
Home-page: http://github.com/crazyscientist/osc-tiny
Download-URL: http://github.com/crazyscientist/osc-tiny/tarball/master
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osc-tiny-0.6.2/osc_tiny.egg-info/PKG-INFO
new/osc-tiny-0.6.5/osc_tiny.egg-info/PKG-INFO
--- old/osc-tiny-0.6.2/osc_tiny.egg-info/PKG-INFO 2022-06-30
10:46:33.000000000 +0200
+++ new/osc-tiny-0.6.5/osc_tiny.egg-info/PKG-INFO 2022-07-20
10:38:48.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: osc-tiny
-Version: 0.6.2
+Version: 0.6.5
Summary: Client API for openSUSE BuildService
Home-page: http://github.com/crazyscientist/osc-tiny
Download-URL: http://github.com/crazyscientist/osc-tiny/tarball/master
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osc-tiny-0.6.2/osc_tiny.egg-info/SOURCES.txt
new/osc-tiny-0.6.5/osc_tiny.egg-info/SOURCES.txt
--- old/osc-tiny-0.6.2/osc_tiny.egg-info/SOURCES.txt 2022-06-30
10:46:34.000000000 +0200
+++ new/osc-tiny-0.6.5/osc_tiny.egg-info/SOURCES.txt 2022-07-20
10:38:48.000000000 +0200
@@ -3,6 +3,7 @@
README.md
requirements.txt
requirements_devel.txt
+requirements_pre38.txt
setup.py
osc_tiny.egg-info/PKG-INFO
osc_tiny.egg-info/SOURCES.txt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osc-tiny-0.6.2/osc_tiny.egg-info/requires.txt
new/osc-tiny-0.6.5/osc_tiny.egg-info/requires.txt
--- old/osc-tiny-0.6.2/osc_tiny.egg-info/requires.txt 2022-06-30
10:46:34.000000000 +0200
+++ new/osc-tiny-0.6.5/osc_tiny.egg-info/requires.txt 2022-07-20
10:38:48.000000000 +0200
@@ -1,7 +1,5 @@
-backports.cached-property
lxml
requests
-responses
python-dateutil
pytz
pyyaml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osc-tiny-0.6.2/osctiny/__init__.py
new/osc-tiny-0.6.5/osctiny/__init__.py
--- old/osc-tiny-0.6.2/osctiny/__init__.py 2022-06-30 10:46:21.000000000
+0200
+++ new/osc-tiny-0.6.5/osctiny/__init__.py 2022-07-20 10:38:38.000000000
+0200
@@ -6,4 +6,4 @@
__all__ = ['Osc', 'bs_requests', 'buildresults', 'comments', 'packages',
'projects', 'search', 'users']
-__version__ = "0.6.2"
+__version__ = "0.6.5"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osc-tiny-0.6.2/osctiny/extensions/origin.py
new/osc-tiny-0.6.5/osctiny/extensions/origin.py
--- old/osc-tiny-0.6.2/osctiny/extensions/origin.py 2022-06-30
10:46:21.000000000 +0200
+++ new/osc-tiny-0.6.5/osctiny/extensions/origin.py 2022-07-20
10:38:38.000000000 +0200
@@ -35,10 +35,7 @@
from functools import cached_property
except ImportError:
# Support for Python3 prior 3.8
- try:
- from backports.cached_property import cached_property
- except ImportError:
- from cached_property import cached_property
+ from cached_property import cached_property
try:
from yaml import CSafeLoader as SafeLoader
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osc-tiny-0.6.2/osctiny/osc.py
new/osc-tiny-0.6.5/osctiny/osc.py
--- old/osc-tiny-0.6.2/osctiny/osc.py 2022-06-30 10:46:21.000000000 +0200
+++ new/osc-tiny-0.6.5/osctiny/osc.py 2022-07-20 10:38:38.000000000 +0200
@@ -88,8 +88,8 @@
:param url: API URL of a BuildService instance
:param username: Username
- :param password: Password; this is either the user password or the SSH
passphrase, if
- ``ssh_key_file`` is defined
+ :param password: Password; this is either the user password
(``ssh_key_file`` is ``None``) or
+ the SSH passphrase, if ``ssh_key_file`` is defined
:param verify: See `SSL Cert Verification`_ for more details
:param cache: Store API responses in a cache
:param ssh_key_file: Path to SSH private key file
@@ -145,7 +145,7 @@
if not self.username and not self.password and not self.ssh_key:
try:
self.username, self.password, self.ssh_key =
get_credentials(self.url)
- except (ValueError, NotImplementedError, FileNotFoundError) as
error:
+ except (ValueError, RuntimeError, FileNotFoundError) as error:
raise OscError from error
# API endpoints
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osc-tiny-0.6.2/osctiny/utils/auth.py
new/osc-tiny-0.6.5/osctiny/utils/auth.py
--- old/osc-tiny-0.6.2/osctiny/utils/auth.py 2022-06-30 10:46:21.000000000
+0200
+++ new/osc-tiny-0.6.5/osctiny/utils/auth.py 2022-07-20 10:38:38.000000000
+0200
@@ -6,6 +6,8 @@
"""
import typing
from base64 import b64decode, b64encode
+import logging
+import os
from pathlib import Path
from subprocess import Popen, PIPE
import re
@@ -43,6 +45,9 @@
super().__init__(username=username, password=password)
if not ssh_key_file.is_file():
raise FileNotFoundError(f"SSH key at location does not exist:
{ssh_key_file}")
+ if not password and not self.is_ssh_agent_available():
+ raise RuntimeError("SSH signing impossible: No password/passphrase
provided and no SSH "
+ "agent running! ")
self.ssh_key_file = ssh_key_file
self.pattern = re.compile(r"(?<=\)) (?=\()")
@@ -58,6 +63,19 @@
parts = self.pattern.split(headers)
return [part.strip("()") for part in parts]
+ @staticmethod
+ def is_ssh_agent_available() -> bool:
+ """
+ Check whether SSH agent is running/available
+
+ :return: ``True``, if agent is running
+
+ .. versionadded:: 0.6.3
+ """
+ relevant_keys = {'SSH_AUTH_SOCK', 'SSH_AGENT_PID'}
+ overlap = os.environ.keys() & relevant_keys
+ return len(overlap) > 0
+
def ssh_sign(self) -> str:
"""
Solve the challenge via SSH signing
@@ -114,6 +132,16 @@
return ""
+ def _log(self, r: Response) -> None:
+ logger = logging.getLogger("osctiny.request")
+ if logger.level >= logging.CRITICAL:
+ return
+
+ logger.info("Server replied with status %d", r.status_code)
+ logger.debug("Response headers:\n%s\n---", "\n".join(f"{k}: {v}"
+ for k, v in
r.headers.items()))
+ logger.debug("Response content:\n%s\n---", r.text)
+
def handle_401(self, r: Response, **kwargs) -> Response:
"""
Handle authentication in case of 401
@@ -124,6 +152,13 @@
self._thread_local.num_401_calls = 1
return r
+ if r.status_code != 401:
+ # If this is not a 401 response, the server does not send the
authentication headers.
+ # So there is no point in pretending otherwise.
+ return r
+
+ self._log(r)
+
if self._thread_local.pos is not None:
# Rewind the file position indicator of the body to where
# it was to resend the request.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osc-tiny-0.6.2/osctiny/utils/conf.py
new/osc-tiny-0.6.5/osctiny/utils/conf.py
--- old/osc-tiny-0.6.2/osctiny/utils/conf.py 2022-06-30 10:46:21.000000000
+0200
+++ new/osc-tiny-0.6.5/osctiny/utils/conf.py 2022-07-20 10:38:38.000000000
+0200
@@ -14,7 +14,6 @@
from configparser import ConfigParser, NoSectionError
import os
from pathlib import Path
-import warnings
try:
from osc import conf as _conf
@@ -45,52 +44,25 @@
raise FileNotFoundError("No `osc` configuration file found")
-# pylint: disable=too-many-branches
-def get_credentials(url: typing.Optional[str] = None) \
- -> typing.Tuple[str, str, typing.Optional[Path]]:
+def _get_credentials_from_oscrc(url: typing.Optional[str] = None) ->
typing.Tuple[str, str, Path]:
"""
- Get credentials for Build Service instance identified by ``url``
+ Get credentials for Build Service instance identified by ``url`` from
``osc`` config file
- .. important::
+ .. note::
- If the ``osc`` package is not installed, this function will only try
to extract the username
- and password from the configuration file.
+ This function does not perform data validation or sanitation. It is
not recommended to call
+ this function directly; use :py:fun:`get_credentials` instead.
- Any credentials stored on a keyring will not be accessible!
-
- :param str url: URL of Build Service instance (including schema). If not
specified, the value
- from the ``apiurl`` parameter in the config file will be
used.
+ :param url: URL of Build Service instance (including schema). If not
specified, the value
+ from the ``apiurl`` parameter in the config file will be used.
:return: (username, password, SSH private key path)
:raises ValueError: if config provides no credentials
- """
- if _conf is not None:
- try:
- _conf.get_config()
- if url is None:
- # get the default api url from osc's config
- url = _conf.config["apiurl"]
- # and now fetch the options for that particular url
- api_config = _conf.get_apiurl_api_host_options(url)
- username = api_config["user"]
- password = api_config["pass"]
- sshkey = Path(api_config["sshkey"]) if api_config["sshkey"] else
None
- except (ConfigError, ConfigMissingApiurl) as error:
- if isinstance(error, ConfigError):
- raise ValueError("`osc` config was not found.") from error
- # this is the case of ConfigMissingApiurl
- raise ValueError("`osc` config has no options for URL
{}".format(url)) from error
-
- if not username:
- raise ValueError("`osc` config provides no username for URL
{}".format(url))
- if not password:
- raise ValueError("`osc` config provides no password for URL
{}".format(url))
- return username, password, sshkey
- warnings.warn("`osc` is not installed. Not all configuration backends of
`osc` will be "
- "available.")
+ .. versionadded:: 0.6.3
+ """
parser = ConfigParser()
path = get_config_path()
- parser.read((path))
+ parser.read(path)
try:
if url is None:
url = parser["general"].get("apiurl", url)
@@ -101,8 +73,6 @@
raise ValueError("`osc` config has no section for URL {}".format(url))
username = parser[url].get("user", None)
- if not username:
- raise ValueError("`osc` config provides no username for URL
{}".format(url))
password = parser[url].get("pass", None)
if not password:
@@ -110,11 +80,84 @@
if password:
password =
decompress(b64decode(password.encode("ascii"))).decode("ascii")
- if not password:
- raise ValueError("`osc` config provides no password for URL
{}".format(url))
-
sshkey = parser[url].get("sshkey", None)
if sshkey:
- sshkey = Path(sshkey)
+ sshkey = Path(sshkey).expanduser()
return username, password, sshkey
+
+
+def _get_credentials_from_oscconf(url: typing.Optional[str] = None) ->
typing.Tuple[str, str, Path]:
+ """
+ Get credentials for Build Service instance identified by ``url`` from
``osc``
+
+ .. note::
+
+ This function does not perform data validation or sanitation. It is
not recommended to call
+ this function directly; use :py:fun:`get_credentials` instead.
+
+ :param url: URL of Build Service instance (including schema). If not
specified, the value
+ from the ``apiurl`` parameter in the config file will be used.
+ :return: (username, password, SSH private key path)
+ :raises ValueError: if config provides no credentials
+ :raises RuntimeError: if ``osc`` is not installed
+
+ .. versionadded:: 0.6.3
+ """
+ if _conf is None:
+ raise RuntimeError("`osc` is not installed. Use
_get_credentials_from_oscrc instead!")
+ try:
+ _conf.get_config()
+ if url is None:
+ # get the default api url from osc's config
+ url = _conf.config["apiurl"]
+ # and now fetch the options for that particular url
+ api_config = _conf.get_apiurl_api_host_options(url)
+ username = api_config["user"]
+ password = api_config["pass"]
+ sshkey = Path(api_config["sshkey"]) if api_config.get("sshkey", None)
else None
+ except (KeyError, ConfigError, ConfigMissingApiurl) as error:
+ if isinstance(error, ConfigError):
+ raise ValueError("`osc` config was not found.") from error
+ # this is the case of ConfigMissingApiurl
+ raise ValueError("`osc` config has no options for URL {}".format(url))
from error
+
+ return username, password, sshkey
+
+
+# pylint: disable=too-many-branches
+def get_credentials(url: typing.Optional[str] = None) \
+ -> typing.Tuple[str, typing.Optional[str], typing.Optional[Path]]:
+ """
+ Get credentials for Build Service instance identified by ``url``
+
+ .. important::
+
+ If the ``osc`` package is not installed, this function will only try
to extract the username
+ and password from the configuration file.
+
+ Any credentials stored on a keyring will not be accessible!
+
+ :param url: URL of Build Service instance (including schema). If not
specified, the value
+ from the ``apiurl`` parameter in the config file will be used.
+ :return: (username, password, SSH private key path)
+ :raises ValueError: if config provides no credentials
+
+ .. versionchanged:: 0.6.3
+
+ If an SSH key is configured, this function will return ``None``
instead of a password.
+ """
+ getter = _get_credentials_from_oscrc if _conf is None else
_get_credentials_from_oscconf
+ username, password, sshkey = getter(url=url)
+
+ if not username:
+ raise ValueError(f"`osc` config provides no username for URL {url}")
+
+ if sshkey is not None:
+ if not sshkey.exists():
+ raise ValueError(f"SSH key from config does not exist: {sshkey}")
+
+ if not password and not sshkey:
+ raise ValueError(f"`osc` config provides no password or SSH key for
URL {url}")
+
+ return username, password if sshkey is None else None, sshkey
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osc-tiny-0.6.2/requirements.txt
new/osc-tiny-0.6.5/requirements.txt
--- old/osc-tiny-0.6.2/requirements.txt 2022-06-30 10:46:21.000000000 +0200
+++ new/osc-tiny-0.6.5/requirements.txt 2022-07-20 10:38:38.000000000 +0200
@@ -1,7 +1,5 @@
-backports.cached-property
lxml
requests
-responses
python-dateutil
pytz
-pyyaml
\ No newline at end of file
+pyyaml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osc-tiny-0.6.2/requirements_devel.txt
new/osc-tiny-0.6.5/requirements_devel.txt
--- old/osc-tiny-0.6.2/requirements_devel.txt 2022-06-30 10:46:21.000000000
+0200
+++ new/osc-tiny-0.6.5/requirements_devel.txt 2022-07-20 10:38:38.000000000
+0200
@@ -1,3 +1,4 @@
pylint
Sphinx
sphinx_rtd_theme
+responses
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osc-tiny-0.6.2/requirements_pre38.txt
new/osc-tiny-0.6.5/requirements_pre38.txt
--- old/osc-tiny-0.6.2/requirements_pre38.txt 1970-01-01 01:00:00.000000000
+0100
+++ new/osc-tiny-0.6.5/requirements_pre38.txt 2022-07-20 10:38:38.000000000
+0200
@@ -0,0 +1 @@
+cached-property
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/osc-tiny-0.6.2/setup.py new/osc-tiny-0.6.5/setup.py
--- old/osc-tiny-0.6.2/setup.py 2022-06-30 10:46:21.000000000 +0200
+++ new/osc-tiny-0.6.5/setup.py 2022-07-20 10:38:38.000000000 +0200
@@ -1,16 +1,23 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
+from sys import version_info
from setuptools import setup, find_packages
def get_requires():
+ requirements = []
+
def _filter(requires):
return [req.strip() for req in requires if req.strip()]
- filename = "requirements.txt"
+ with open("requirements.txt", "r") as fh:
+ requirements += _filter(fh.readlines())
+
+ if version_info.minor < 8:
+ with open("requirements_pre38.txt", "r") as fh:
+ requirements += _filter(fh.readlines())
- with open(filename, "r") as fh:
- return _filter(fh.readlines())
+ return requirements
with open("README.md") as fh:
@@ -19,7 +26,7 @@
setup(
name='osc-tiny',
- version='0.6.2',
+ version='0.6.5',
description='Client API for openSUSE BuildService',
long_description=long_description,
long_description_content_type="text/markdown",