sos/SOURCES/sos-bz2011349-replace-dropbox-by-sftp.patch
2022-02-01 20:15:15 +00:00

747 lines
30 KiB
Diff

From 5298080d7360202c72b0af2e24994e4bfad72322 Mon Sep 17 00:00:00 2001
From: Jake Hunsaker <jhunsake@redhat.com>
Date: Fri, 14 May 2021 13:10:04 -0400
Subject: [PATCH] [Policy] Add SFTP upload support
Adds support for uploading via SFTP. This is done via pexpect calling
the system's locally available SFTP binary. If either that binary or
pexpect are unavailable on the local system, we will exit gracefully and
report the issue. This allows sos to keep python3-pexpect as a
recommends rather than a hard dependency.
Signed-off-by: Jake Hunsaker <jhunsake@redhat.com>
---
man/en/sos-report.1 | 14 +++++
sos/collector/__init__.py | 7 ++-
sos/policies/distros/__init__.py | 105 +++++++++++++++++++++++++++++--
sos/report/__init__.py | 4 ++
4 files changed, 125 insertions(+), 5 deletions(-)
diff --git a/man/en/sos-report.1 b/man/en/sos-report.1
index c38753d4a..799defafc 100644
--- a/man/en/sos-report.1
+++ b/man/en/sos-report.1
@@ -35,6 +35,7 @@ sosreport \- Collect and package diagnos
[--encrypt-pass PASS]\fR
[--upload] [--upload-url url] [--upload-user user]\fR
[--upload-directory dir] [--upload-pass pass]\fR
+ [--upload-protocol protocol]\fR
[--experimental]\fR
[-h|--help]\fR
@@ -354,6 +355,19 @@ be used provided all other required valu
Specify a directory to upload to, if one is not specified by a vendor default location
or if your destination server does not allow writes to '/'.
.TP
+.B \--upload-protocol PROTO
+Manually specify the protocol to use for uploading to the target \fBupload-url\fR.
+
+Normally this is determined via the upload address, assuming that the protocol is part
+of the address provided, e.g. 'https://example.com'. By using this option, sos will skip
+the protocol check and use the method defined for the specified PROTO.
+
+For RHEL systems, setting this option to \fBsftp\fR will skip the initial attempt to
+upload to the Red Hat Customer Portal, and only attempt an upload to Red Hat's SFTP server,
+which is typically used as a fallback target.
+
+Valid values for PROTO are: 'auto' (default), 'https', 'ftp', 'sftp'.
+.TP
.B \--experimental
Enable plugins marked as experimental. Experimental plugins may not have
been tested for this port or may still be under active development.
diff --git a/sos/collector/__init__.py b/sos/collector/__init__.py
index 5d1c599ac..1c742cf50 100644
--- a/sos/collector/__init__.py
+++ b/sos/collector/__init__.py
@@ -106,6 +106,7 @@ class SoSCollector(SoSComponent):
'upload_directory': None,
'upload_user': None,
'upload_pass': None,
+ 'upload_protocol': 'auto'
}
def __init__(self, parser, parsed_args, cmdline_args):
@@ -383,6 +384,9 @@ class SoSCollector(SoSComponent):
help="Username to authenticate with")
collect_grp.add_argument("--upload-pass", default=None,
help="Password to authenticate with")
+ collect_grp.add_argument("--upload-protocol", default='auto',
+ choices=['auto', 'https', 'ftp', 'sftp'],
+ help="Manually specify the upload protocol")
# Group the cleaner options together
cleaner_grp = parser.add_argument_group(
diff --git a/sos/policies/distros/__init__.py b/sos/policies/distros/__init__.py
index 4268688c6..9fe31513b 100644
--- a/sos/policies/distros/__init__.py
+++ b/sos/policies/distros/__init__.py
@@ -20,7 +20,7 @@
from sos.policies.runtimes.podman import PodmanContainerRuntime
from sos.policies.runtimes.docker import DockerContainerRuntime
-from sos.utilities import shell_out
+from sos.utilities import shell_out, is_executable
try:
@@ -295,7 +295,9 @@ def _determine_upload_type(self):
'sftp': self.upload_sftp,
'https': self.upload_https
}
- if '://' not in self.upload_url:
+ if self.commons['cmdlineopts'].upload_protocol in prots.keys():
+ return prots[self.commons['cmdlineopts'].upload_protocol]
+ elif '://' not in self.upload_url:
raise Exception("Must provide protocol in upload URL")
prot, url = self.upload_url.split('://')
if prot not in prots.keys():
@@ -361,7 +363,7 @@ def get_upload_password(self):
self.upload_password or
self._upload_password)
- def upload_sftp(self):
+ def upload_sftp(self, user=None, password=None):
"""Attempts to upload the archive to an SFTP location.
Due to the lack of well maintained, secure, and generally widespread
@@ -371,7 +373,102 @@ def upload_sftp(self):
Do not override this method with one that uses python-paramiko, as the
upstream sos team will reject any PR that includes that dependency.
"""
- raise NotImplementedError("SFTP support is not yet implemented")
+ # if we somehow don't have sftp available locally, fail early
+ if not is_executable('sftp'):
+ raise Exception('SFTP is not locally supported')
+
+ # soft dependency on python3-pexpect, which we need to use to control
+ # sftp login since as of this writing we don't have a viable solution
+ # via ssh python bindings commonly available among downstreams
+ try:
+ import pexpect
+ except ImportError:
+ raise Exception('SFTP upload requires python3-pexpect, which is '
+ 'not currently installed')
+
+ sftp_connected = False
+
+ if not user:
+ user = self.get_upload_user()
+ if not password:
+ password = self.get_upload_password()
+
+ # need to strip the protocol prefix here
+ sftp_url = self.get_upload_url().replace('sftp://', '')
+ sftp_cmd = "sftp -oStrictHostKeyChecking=no %s@%s" % (user, sftp_url)
+ ret = pexpect.spawn(sftp_cmd, encoding='utf-8')
+
+ sftp_expects = [
+ u'sftp>',
+ u'password:',
+ u'Connection refused',
+ pexpect.TIMEOUT,
+ pexpect.EOF
+ ]
+
+ idx = ret.expect(sftp_expects, timeout=15)
+
+ if idx == 0:
+ sftp_connected = True
+ elif idx == 1:
+ ret.sendline(password)
+ pass_expects = [
+ u'sftp>',
+ u'Permission denied',
+ pexpect.TIMEOUT,
+ pexpect.EOF
+ ]
+ sftp_connected = ret.expect(pass_expects, timeout=10) == 0
+ if not sftp_connected:
+ ret.close()
+ raise Exception("Incorrect username or password for %s"
+ % self.get_upload_url_string())
+ elif idx == 2:
+ raise Exception("Connection refused by %s. Incorrect port?"
+ % self.get_upload_url_string())
+ elif idx == 3:
+ raise Exception("Timeout hit trying to connect to %s"
+ % self.get_upload_url_string())
+ elif idx == 4:
+ raise Exception("Unexpected error trying to connect to sftp: %s"
+ % ret.before)
+
+ if not sftp_connected:
+ ret.close()
+ raise Exception("Unable to connect via SFTP to %s"
+ % self.get_upload_url_string())
+
+ put_cmd = 'put %s %s' % (self.upload_archive_name,
+ self._get_sftp_upload_name())
+ ret.sendline(put_cmd)
+
+ put_expects = [
+ u'100%',
+ pexpect.TIMEOUT,
+ pexpect.EOF
+ ]
+
+ put_success = ret.expect(put_expects, timeout=180)
+
+ if put_success == 0:
+ ret.sendline('bye')
+ return True
+ elif put_success == 1:
+ raise Exception("Timeout expired while uploading")
+ elif put_success == 2:
+ raise Exception("Unknown error during upload: %s" % ret.before)
+ else:
+ raise Exception("Unexpected response from server: %s" % ret.before)
+
+ def _get_sftp_upload_name(self):
+ """If a specific file name pattern is required by the SFTP server,
+ override this method in the relevant Policy. Otherwise the archive's
+ name on disk will be used
+
+ :returns: Filename as it will exist on the SFTP server
+ :rtype: ``str``
+ """
+ return self.upload_archive_name.split('/')[-1]
def _upload_https_streaming(self, archive):
"""If upload_https() needs to use requests.put(), this method is used
diff --git a/sos/report/__init__.py b/sos/report/__init__.py
index df99186db..d43454092 100644
--- a/sos/report/__init__.py
+++ b/sos/report/__init__.py
@@ -119,6 +119,7 @@ class SoSReport(SoSComponent):
'upload_directory': None,
'upload_user': None,
'upload_pass': None,
+ 'upload_protocol': 'auto',
'add_preset': '',
'del_preset': ''
}
@@ -300,6 +301,9 @@ class SoSReport(SoSComponent):
help="Username to authenticate to server with")
report_grp.add_argument("--upload-pass", default=None,
help="Password to authenticate to server with")
+ report_grp.add_argument("--upload-protocol", default='auto',
+ choices=['auto', 'https', 'ftp', 'sftp'],
+ help="Manually specify the upload protocol")
# Group to make add/del preset exclusive
preset_grp = report_grp.add_mutually_exclusive_group()
From d5316de87313c3eaf9fe4ce7a5eea3ed8c7d17ce Mon Sep 17 00:00:00 2001
From: Jake Hunsaker <jhunsake@redhat.com>
Date: Fri, 14 May 2021 13:11:27 -0400
Subject: [PATCH] [Red Hat] Update policy to use SFTP instead of legacy FTP
dropbox
As the FTP dropbox for Red Hat is being decomissioned and replaced with
an SFTP alternative, update the policy to fallback to the SFTP host and
remove legacy FTP host references.
The default behavior for --upload remains the same, just targeting a
different location. If a username, password, and case number are given,
the first attempt will be to upload to the Red Hat Customer Portal. If
any are missing, or are invalid, then we will fallback to SFTP. During
the fallback if a valid username and password are not provided, sos will
attempt to obtain an anonymous token for the upload before failing out
entirely.
Closes: #2467
Resolves: #2552
Signed-off-by: Jake Hunsaker <jhunsake@redhat.com>
---
sos/policies/distros/redhat.py | 115 ++++++++++++++++++++++-----------
1 file changed, 76 insertions(+), 39 deletions(-)
diff --git a/sos/policies/distros/redhat.py b/sos/policies/distros/redhat.py
index f37519910..241d3f139 100644
--- a/sos/policies/distros/redhat.py
+++ b/sos/policies/distros/redhat.py
@@ -8,6 +8,7 @@
#
# See the LICENSE file in the source distribution for further information.
+import json
import os
import sys
import re
@@ -20,6 +21,11 @@
from sos.policies.package_managers.rpm import RpmPackageManager
from sos import _sos as _
+try:
+ import requests
+ REQUESTS_LOADED = True
+except ImportError:
+ REQUESTS_LOADED = False
OS_RELEASE = "/etc/os-release"
RHEL_RELEASE_STR = "Red Hat Enterprise Linux"
@@ -39,9 +45,8 @@ class RedHatPolicy(LinuxPolicy):
_host_sysroot = '/'
default_scl_prefix = '/opt/rh'
name_pattern = 'friendly'
- upload_url = 'dropbox.redhat.com'
- upload_user = 'anonymous'
- upload_directory = '/incoming'
+ upload_url = None
+ upload_user = None
default_container_runtime = 'podman'
sos_pkg_name = 'sos'
sos_bin_path = '/usr/sbin'
@@ -196,7 +201,7 @@ def get_tmp_dir(self, opt_tmp_dir):
"""
RH_API_HOST = "https://access.redhat.com"
-RH_FTP_HOST = "ftp://dropbox.redhat.com"
+RH_SFTP_HOST = "sftp://sftp.access.redhat.com"
class RHELPolicy(RedHatPolicy):
@@ -216,9 +216,7 @@ An archive containing the collected info
generated in %(tmpdir)s and may be provided to a %(vendor)s \
support representative.
""" + disclaimer_text + "%(vendor_text)s\n")
- _upload_url = RH_FTP_HOST
- _upload_user = 'anonymous'
- _upload_directory = '/incoming'
+ _upload_url = RH_SFTP_HOST
def __init__(self, sysroot=None, init=None, probe_runtime=True,
remote_exec=None):
@@ -260,33 +263,17 @@ def prompt_for_upload_user(self):
return
if self.case_id and not self.get_upload_user():
self.upload_user = input(_(
- "Enter your Red Hat Customer Portal username (empty to use "
- "public dropbox): ")
+ "Enter your Red Hat Customer Portal username for uploading ["
+ "empty for anonymous SFTP]: ")
)
- if not self.upload_user:
- self.upload_url = RH_FTP_HOST
- self.upload_user = self._upload_user
-
- def _upload_user_set(self):
- user = self.get_upload_user()
- return user and (user != 'anonymous')
def get_upload_url(self):
if self.upload_url:
return self.upload_url
- if self.commons['cmdlineopts'].upload_url:
+ elif self.commons['cmdlineopts'].upload_url:
return self.commons['cmdlineopts'].upload_url
- # anonymous FTP server should be used as fallback when either:
- # - case id is not set, or
- # - upload user isn't set AND batch mode prevents to prompt for it
- if (not self.case_id) or \
- ((not self._upload_user_set()) and
- self.commons['cmdlineopts'].batch):
- self.upload_user = self._upload_user
- if self.upload_directory is None:
- self.upload_directory = self._upload_directory
- self.upload_password = None
- return RH_FTP_HOST
+ elif self.commons['cmdlineopts'].upload_protocol == 'sftp':
+ return RH_SFTP_HOST
else:
rh_case_api = "/hydra/rest/cases/%s/attachments"
return RH_API_HOST + rh_case_api % self.case_id
@@ -299,27 +286,77 @@ def _get_upload_headers(self):
def get_upload_url_string(self):
if self.get_upload_url().startswith(RH_API_HOST):
return "Red Hat Customer Portal"
- return self.upload_url or RH_FTP_HOST
+ elif self.get_upload_url().startswith(RH_SFTP_HOST):
+ return "Red Hat Secure FTP"
+ return self.upload_url
- def get_upload_user(self):
- # if this is anything other than dropbox, annonymous won't work
- if self.upload_url != RH_FTP_HOST:
- return os.getenv('SOSUPLOADUSER', None) or self.upload_user
- return self._upload_user
+ def _get_sftp_upload_name(self):
+ """The RH SFTP server will only automatically connect file uploads to
+ cases if the filename _starts_ with the case number
+ """
+ if self.case_id:
+ return "%s_%s" % (self.case_id,
+ self.upload_archive_name.split('/')[-1])
+ return self.upload_archive_name
+
+ def upload_sftp(self):
+ """Override the base upload_sftp to allow for setting an on-demand
+ generated anonymous login for the RH SFTP server if a username and
+ password are not given
+ """
+ if RH_SFTP_HOST.split('//')[1] not in self.get_upload_url():
+ return super(RHELPolicy, self).upload_sftp()
+
+ if not REQUESTS_LOADED:
+ raise Exception("python3-requests is not installed and is required"
+ " for obtaining SFTP auth token.")
+ _token = None
+ _user = None
+ # we have a username and password, but we need to reset the password
+ # to be the token returned from the auth endpoint
+ if self.get_upload_user() and self.get_upload_password():
+ url = RH_API_HOST + '/hydra/rest/v1/sftp/token'
+ auth = self.get_upload_https_auth()
+ ret = requests.get(url, auth=auth, timeout=10)
+ if ret.status_code == 200:
+ # credentials are valid
+ _user = self.get_upload_user()
+ _token = json.loads(ret.text)['token']
+ else:
+ print("Unable to retrieve Red Hat auth token using provided "
+ "credentials. Will try anonymous.")
+ # we either do not have a username or password/token, or both
+ if not _token:
+ aurl = RH_API_HOST + '/hydra/rest/v1/sftp/token?isAnonymous=true'
+ anon = requests.get(aurl, timeout=10)
+ if anon.status_code == 200:
+ resp = json.loads(anon.text)
+ _user = resp['username']
+ _token = resp['token']
+ print("Using anonymous user %s for upload. Please inform your "
+ "support engineer." % _user)
+ if _user and _token:
+ return super(RHELPolicy, self).upload_sftp(user=_user,
+ password=_token)
+ raise Exception("Could not retrieve valid or anonymous credentials")
def upload_archive(self, archive):
"""Override the base upload_archive to provide for automatic failover
from RHCP failures to the public RH dropbox
"""
try:
+ if not self.get_upload_user() or not self.get_upload_password():
+ self.upload_url = RH_SFTP_HOST
uploaded = super(RHELPolicy, self).upload_archive(archive)
except Exception:
uploaded = False
- if not uploaded and self.upload_url.startswith(RH_API_HOST):
- print("Upload to Red Hat Customer Portal failed. Trying %s"
- % RH_FTP_HOST)
- self.upload_url = RH_FTP_HOST
- uploaded = super(RHELPolicy, self).upload_archive(archive)
+ if not self.upload_url.startswith(RH_API_HOST):
+ raise
+ else:
+ print("Upload to Red Hat Customer Portal failed. Trying %s"
+ % RH_SFTP_HOST)
+ self.upload_url = RH_SFTP_HOST
+ uploaded = super(RHELPolicy, self).upload_archive(archive)
return uploaded
def dist_version(self):
From 8a7ae6a3ac69a020758f7b0825a872e44714dbed Mon Sep 17 00:00:00 2001
From: Jake Hunsaker <jhunsake@redhat.com>
Date: Fri, 9 Apr 2021 11:05:47 -0400
Subject: [PATCH] [ubuntu|Policy] Fix exception when attempting upload
Fixes an issue where an upload attempt on Ubuntu systems would fail with
a traceback due to the upload archive's name not being available when we
first check to make sure we have an upload location, since the Ubuntu
default location requires an archive/file name.
Related to this, stop clobbering `upload_archive` and assign the archive
name to an `upload_archive_name` variable instead.
Closes: #2472
Resolves: #2479
Signed-off-by: Jake Hunsaker <jhunsake@redhat.com>
---
sos/policies/distros/__init__.py | 9 +++++----
sos/policies/distros/ubuntu.py | 4 +++-
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/sos/policies/distros/__init__.py b/sos/policies/distros/__init__.py
index 022ba7f4c6..a24a0e5beb 100644
--- a/sos/policies/distros/__init__.py
+++ b/sos/policies/distros/__init__.py
@@ -149,6 +149,7 @@ def pre_work(self):
self.upload_user = cmdline_opts.upload_user
self.upload_directory = cmdline_opts.upload_directory
self.upload_password = cmdline_opts.upload_pass
+ self.upload_archive_name = ''
if not cmdline_opts.batch and not \
cmdline_opts.quiet:
@@ -237,7 +238,7 @@ def upload_archive(self, archive):
`get_upload_url_string()`
Print a more human-friendly string than vendor URLs
"""
- self.upload_archive = archive
+ self.upload_archive_name = archive
if not self.upload_url:
self.upload_url = self.get_upload_url()
if not self.upload_url:
@@ -384,7 +385,7 @@ def upload_https(self):
raise Exception("Unable to upload due to missing python requests "
"library")
- with open(self.upload_archive, 'rb') as arc:
+ with open(self.upload_archive_name, 'rb') as arc:
if not self._use_https_streaming:
r = self._upload_https_no_stream(arc)
else:
@@ -467,9 +468,9 @@ def upload_ftp(self, url=None, directory=None, user=None, password=None):
% str(err))
try:
- with open(self.upload_archive, 'rb') as _arcfile:
+ with open(self.upload_archive_name, 'rb') as _arcfile:
session.storbinary(
- "STOR %s" % self.upload_archive.split('/')[-1],
+ "STOR %s" % self.upload_archive_name.split('/')[-1],
_arcfile
)
session.quit()
diff --git a/sos/policies/distros/ubuntu.py b/sos/policies/distros/ubuntu.py
index 94a4a241b0..308c1e3544 100644
--- a/sos/policies/distros/ubuntu.py
+++ b/sos/policies/distros/ubuntu.py
@@ -74,7 +74,9 @@ def get_upload_url_string(self):
def get_upload_url(self):
if not self.upload_url or self.upload_url.startswith(self._upload_url):
- fname = os.path.basename(self.upload_archive)
+ if not self.upload_archive_name:
+ return self._upload_url
+ fname = os.path.basename(self.upload_archive_name)
return self._upload_url + fname
super(UbuntuPolicy, self).get_upload_url()
From 2e8b5e2d4f30854cce93d149fc7d24b9d9cfd02c Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Fri, 19 Nov 2021 16:16:07 +0100
Subject: [PATCH 1/3] [policies] strip path from SFTP upload filename
When case_id is not supplied, we ask SFTP server to store the uploaded
file under name /var/tmp/<tarball>, which is confusing.
Let remove the path from it also in case_id not supplied.
Related to: #2764
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/policies/distros/redhat.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/sos/policies/distros/redhat.py b/sos/policies/distros/redhat.py
index 3476e21fb..8817fc785 100644
--- a/sos/policies/distros/redhat.py
+++ b/sos/policies/distros/redhat.py
@@ -269,10 +269,10 @@ def _get_sftp_upload_name(self):
"""The RH SFTP server will only automatically connect file uploads to
cases if the filename _starts_ with the case number
"""
+ fname = self.upload_archive_name.split('/')[-1]
if self.case_id:
- return "%s_%s" % (self.case_id,
- self.upload_archive_name.split('/')[-1])
- return self.upload_archive_name
+ return "%s_%s" % (self.case_id, fname)
+ return fname
def upload_sftp(self):
"""Override the base upload_sftp to allow for setting an on-demand
From 61023b29a656dd7afaa4a0643368b0a53f1a3779 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Fri, 19 Nov 2021 17:31:31 +0100
Subject: [PATCH 2/3] [redhat] update SFTP API version to v2
Change API version from v1 to v2, which includes:
- change of URL
- different URI
- POST method for token generation instead of GET
Resolves: #2764
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/policies/distros/redhat.py | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/sos/policies/distros/redhat.py b/sos/policies/distros/redhat.py
index 8817fc785..e4e2b8835 100644
--- a/sos/policies/distros/redhat.py
+++ b/sos/policies/distros/redhat.py
@@ -175,7 +175,7 @@ def get_tmp_dir(self, opt_tmp_dir):
No changes will be made to system configuration.
"""
-RH_API_HOST = "https://access.redhat.com"
+RH_API_HOST = "https://api.access.redhat.com"
RH_SFTP_HOST = "sftp://sftp.access.redhat.com"
@@ -287,12 +287,12 @@ def upload_sftp(self):
" for obtaining SFTP auth token.")
_token = None
_user = None
+ url = RH_API_HOST + '/support/v2/sftp/token'
# we have a username and password, but we need to reset the password
# to be the token returned from the auth endpoint
if self.get_upload_user() and self.get_upload_password():
- url = RH_API_HOST + '/hydra/rest/v1/sftp/token'
auth = self.get_upload_https_auth()
- ret = requests.get(url, auth=auth, timeout=10)
+ ret = requests.post(url, auth=auth, timeout=10)
if ret.status_code == 200:
# credentials are valid
_user = self.get_upload_user()
@@ -302,8 +302,8 @@ def upload_sftp(self):
"credentials. Will try anonymous.")
# we either do not have a username or password/token, or both
if not _token:
- aurl = RH_API_HOST + '/hydra/rest/v1/sftp/token?isAnonymous=true'
- anon = requests.get(aurl, timeout=10)
+ adata = {"isAnonymous": True}
+ anon = requests.post(url, data=json.dumps(adata), timeout=10)
if anon.status_code == 200:
resp = json.loads(anon.text)
_user = resp['username']
From 267da2156ec61f526dd28e760ff6528408a76c3f Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Mon, 22 Nov 2021 15:22:32 +0100
Subject: [PATCH 3/3] [policies] Deal 200 return code as success
Return code 200 of POST method request must be dealt as success.
Newly required due to the SFTP API change using POST.
Related to: #2764
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/policies/distros/__init__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sos/policies/distros/__init__.py b/sos/policies/distros/__init__.py
index 0906fa779..6f257fdce 100644
--- a/sos/policies/distros/__init__.py
+++ b/sos/policies/distros/__init__.py
@@ -488,7 +488,7 @@ class LinuxPolicy(Policy):
r = self._upload_https_no_stream(arc)
else:
r = self._upload_https_streaming(arc)
- if r.status_code != 201:
+ if r.status_code != 200 and r.status_code != 201:
if r.status_code == 401:
raise Exception(
"Authentication failed: invalid user credentials"
From 8da1b14246226792c160dd04e5c7c75dd4e8d44b Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Mon, 22 Nov 2021 10:44:09 +0100
Subject: [PATCH] [collect] fix moved get_upload_url under Policy class
SoSCollector does not further declare get_upload_url method
as that was moved under Policy class(es).
Resolves: #2766
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/collector/__init__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sos/collector/__init__.py b/sos/collector/__init__.py
index 50183e873..42a7731d6 100644
--- a/sos/collector/__init__.py
+++ b/sos/collector/__init__.py
@@ -1219,7 +1219,7 @@ this utility or remote systems that it c
msg = 'No sosreports were collected, nothing to archive...'
self.exit(msg, 1)
- if self.opts.upload and self.get_upload_url():
+ if self.opts.upload and self.policy.get_upload_url():
try:
self.policy.upload_archive(arc_name)
self.ui_log.info("Uploaded archive successfully")
From abb2fc65bd14760021c61699ad3113cab3bd4c64 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Tue, 30 Nov 2021 11:37:02 +0100
Subject: [PATCH 1/2] [redhat] Fix broken URI to upload to customer portal
Revert back the unwanted change in URI of uploading tarball to the
Red Hat Customer portal.
Related: #2772
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/policies/distros/redhat.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sos/policies/distros/redhat.py b/sos/policies/distros/redhat.py
index e4e2b883..eb442407 100644
--- a/sos/policies/distros/redhat.py
+++ b/sos/policies/distros/redhat.py
@@ -250,7 +250,7 @@ support representative.
elif self.commons['cmdlineopts'].upload_protocol == 'sftp':
return RH_SFTP_HOST
else:
- rh_case_api = "/hydra/rest/cases/%s/attachments"
+ rh_case_api = "/support/v1/cases/%s/attachments"
return RH_API_HOST + rh_case_api % self.case_id
def _get_upload_headers(self):
--
2.31.1
From ea4f9e88a412c80a4791396e1bb78ac1e24ece14 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Tue, 30 Nov 2021 13:00:26 +0100
Subject: [PATCH 2/2] [policy] Add error message when FTP upload write failure
When (S)FTP upload fails to write the destination file,
our "expect" code should detect it sooner than after timeout happens
and write appropriate error message.
Resolves: #2772
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
sos/policies/distros/__init__.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/sos/policies/distros/__init__.py b/sos/policies/distros/__init__.py
index 6f257fdc..7bdc81b8 100644
--- a/sos/policies/distros/__init__.py
+++ b/sos/policies/distros/__init__.py
@@ -473,7 +473,8 @@ class LinuxPolicy(Policy):
put_expects = [
u'100%',
pexpect.TIMEOUT,
- pexpect.EOF
+ pexpect.EOF,
+ u'No such file or directory'
]
put_success = ret.expect(put_expects, timeout=180)
@@ -485,6 +486,8 @@ class LinuxPolicy(Policy):
raise Exception("Timeout expired while uploading")
elif put_success == 2:
raise Exception("Unknown error during upload: %s" % ret.before)
+ elif put_success == 3:
+ raise Exception("Unable to write archive to destination")
else:
raise Exception("Unexpected response from server: %s" % ret.before)
--
2.31.1