[elbe-devel] [PATCH] soapclient: Fix base64 encoding
Bastian Germann
bage at linutronix.de
Mon Jul 20 15:13:52 CEST 2020
Am 20.07.20 um 01:32 schrieb Olivier Dion:
> In Py2, binascii.b2a_base64 returns a 'str' object, but in Py3
> a 'bytes' object is returned.
>
> The soap service apparently get confused when the data is a 'bytes'
> object and will somehow add an extra 4 bytes at the end of the data.
> This is the reason why cdrom upload did not work, because the upload
> got corrupted.
>
> Thus, the static method 'upload_file' defined for ClientAction can be
> used by sub-classes. This method ensures that the data is of type
> 'str'.
>
> Signed-off-by: Olivier Dion <dion at linutronix.de>
> ---
> elbepack/soapclient.py | 87 ++++++++++++++++++++----------------------
> 1 file changed, 42 insertions(+), 45 deletions(-)
>
> diff --git a/elbepack/soapclient.py b/elbepack/soapclient.py
> index a465b615..3907c849 100644
> --- a/elbepack/soapclient.py
> +++ b/elbepack/soapclient.py
> @@ -146,6 +146,26 @@ class ClientAction(object):
> def __init__(self, node):
> self.node = node
>
> + @staticmethod
> + def upload_file(append, build_dir, filename):
> +
> + size = 1024 * 1024
> +
> + with open(filename, "rb") as f:
> +
> + while True:
> +
> + bin_data = f.read(size)
> + data = binascii.b2a_base64(bin_data)
> +
> + if not isinstance(data, str):
> + data = data.decode("ascii")
> +
> + append(build_dir, data)
> +
> + if len(bin_data) != size:
> + break
> +
> def execute(self, _client, _opt, _args):
> raise NotImplementedError('execute() not implemented')
>
> @@ -331,7 +351,12 @@ class SetXmlAction(ClientAction):
> part = 0
> with open(filename, "rb") as fp:
> while True:
> - xml_base64 = binascii.b2a_base64(fp.read(size)).decode('ascii')
> +
> + xml_base64 = binascii.b2a_base64(fp.read(size))
> +
> + if not isinstance(xml_base64, str):
> + xml_base64 = xml_base64.decode('ascii')
> +
> # finish upload
> if len(xml_base64) == 1:
> part = client.service.upload_file(builddir,
> @@ -634,7 +659,6 @@ class SetCdromAction(ClientAction):
> ClientAction.__init__(self, node)
>
> def execute(self, client, _opt, args):
> - size = 1024 * 1024
>
> if len(args) != 2:
> print(
> @@ -642,19 +666,9 @@ class SetCdromAction(ClientAction):
> file=sys.stderr)
> sys.exit(20)
>
> - builddir = args[0]
> - filename = args[1]
> -
> - fp = open(filename, "rb")
> - client.service.start_cdrom(builddir)
> - while True:
> - bindata = fp.read(size)
> - client.service.append_cdrom(builddir, binascii.b2a_base64(bindata))
> - if len(bindata) != size:
> - break
> -
> - client.service.finish_cdrom(builddir)
> -
> + client.service.start_cdrom(args[0])
> + self.upload_file(client.service.append_cdrom, args[0], args[1])
> + client.service.finish_cdrom(args[0])
>
> ClientAction.register(SetCdromAction)
>
> @@ -667,7 +681,6 @@ class SetOrigAction(ClientAction):
> ClientAction.__init__(self, node)
>
> def execute(self, client, _opt, args):
> - size = 1024 * 1024
>
> if len(args) != 2:
> print(
> @@ -675,20 +688,9 @@ class SetOrigAction(ClientAction):
> file=sys.stderr)
> sys.exit(20)
>
> - builddir = args[0]
> - filename = args[1]
> -
> - fp = open(filename, "r")
> - client.service.start_upload_orig(builddir, os.path.basename(filename))
> - while True:
> - bindata = fp.read(size)
> - client.service.append_upload_orig(
> - builddir, binascii.b2a_base64(bindata))
> - if len(bindata) != size:
> - break
> -
> - client.service.finish_upload_orig(builddir)
> -
> + client.service.start_upload_orig(args[0])
You are missing the second parameter here! Result:
Traceback (most recent call last):
File "/var/cache/elbe/devel/elbepack/daemons/soap/faults.py", line
150, in wrapped
return func(self, arg1, arg2, arg3)
File "/var/cache/elbe/devel/elbepack/daemons/soap/esoap.py", line 318,
in start_upload_orig
orig_fname = os.path.join(builddir, fname)
File "/usr/lib/python2.7/posixpath.py", line 68, in join
if b.startswith('/'):
AttributeError: 'NoneType' object has no attribute 'startswith'
> + self.upload_file(client.service.append_upload_orig, args[0], args[1])
> + client.service.finish_upload_orig(args[0])
>
> ClientAction.register(SetOrigAction)
>
> @@ -723,27 +725,16 @@ class SetPdebuilderAction(ClientAction):
> ClientAction.__init__(self, node)
>
> def execute(self, client, opt, args):
> - size = 1024 * 1024
>
> if len(args) != 2 and len(args) != 3:
> print("usage: elbe control set_pdebuild "
> "<project_dir> <pdebuild file>", file=sys.stderr)
> sys.exit(20)
>
> - builddir = args[0]
> - filename = args[1]
> -
> - fp = open(filename, "r")
> - client.service.start_pdebuild(builddir)
> - while True:
> - bindata = fp.read(size)
> - client.service.append_pdebuild(
> - builddir, binascii.b2a_base64(bindata))
> - if len(bindata) != size:
> - break
> -
> - client.service.finish_pdebuild(builddir, opt.cpuset,
> - opt.profile, opt.cross)
> + client.service.start_pdebuild(args[0])
> + self.upload_file(client.service.append_pdebuild, args[0], args[1])
> + client.service.finish_pdebuild(args[0],
> + opt.cpuset, opt.profile, opt.cross)
>
>
> ClientAction.register(SetPdebuilderAction)
> @@ -902,13 +893,19 @@ class UploadPackageAction(RepoAction):
> RepoAction.__init__(self, node)
>
> @staticmethod
> + # pylint: disable=arguments-differ
> def upload_file(client, f, builddir):
> # Uploads file f into builddir in intivm
> size = 1024 * 1024
> part = 0
> with open(f, "rb") as fp:
> while True:
> +
> xml_base64 = binascii.b2a_base64(fp.read(size))
> +
> + if not isinstance(xml_base64, str):
> + xml_base64 = xml_base64.decode("ascii")
> +
> # finish upload
> if len(xml_base64) == 1:
> part = client.service.upload_file(builddir,
>
More information about the elbe-devel
mailing list