Since byte strings are no longer the default in Python 3, we have to
explicitly use them where we need to, which is mostly when working with
structures. It also means that we need to open a file in binary mode
when we want to use structures.
On the other hand, we have to accomodate for the fact that some
functions (still) work with byte strings but we want to use unicode
strings (in Python 3 at least, and it does not matter in Python 2).
This includes base64 encoding, but it is most notable when working with
the subprocess module: Either we set universal_newlines to True so that
the default streams are opened in text mode (hence this parameter is
aliased as "text" as of 3.7), or, if that is not possible, we have to
decode the output to a normal string.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Message-Id: <
20181022135307.14398-4-mreitz@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
@param qtest_cmd: qtest command text to be sent
"""
- self._sock.sendall(qtest_cmd + "\n")
+ self._sock.sendall((qtest_cmd + "\n").encode('utf-8'))
def close(self):
self._sock.close()
fd.seek(off_reftable)
for i in xrange(0, h.refcount_table_clusters):
- sector = ''.join(struct.pack('>Q',
+ sector = b''.join(struct.pack('>Q',
off_refblock + i * 64 * 512 + j * 512)
for j in xrange(0, 64))
fd.write(sector)
# Write the refcount blocks
assert(fd.tell() == off_refblock)
- sector = ''.join(struct.pack('>H', 1) for j in xrange(0, 64 * 256))
+ sector = b''.join(struct.pack('>H', 1) for j in range(0, 64 * 256))
for block in xrange(0, h.refcount_table_clusters):
fd.write(sector)
# Write the L1 table
assert(fd.tell() == off_l1)
assert(off_l2 + 512 * h.l1_size == off_data)
- table = ''.join(struct.pack('>Q', (1 << 63) | off_l2 + 512 * j)
+ table = b''.join(struct.pack('>Q', (1 << 63) | off_l2 + 512 * j)
for j in xrange(0, h.l1_size))
fd.write(table)
remaining = remaining - 1024 * 512
off = off + 1024 * 512
- table = ''.join(struct.pack('>Q', (1 << 63) | off + 512 * j)
+ table = b''.join(struct.pack('>Q', (1 << 63) | off + 512 * j)
for j in xrange(0, remaining / 512))
fd.write(table)
def first_password_base64(self):
(pw, slot) = self.first_password()
- return base64.b64encode(pw)
+ return base64.b64encode(pw.encode('ascii')).decode('ascii')
def active_slots(self):
slots = []
proc = subprocess.Popen(args,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
+ stderr=subprocess.STDOUT,
+ universal_newlines=True)
msg = proc.communicate()[0]
proc = subprocess.Popen(fullargs,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
+ stderr=subprocess.STDOUT,
+ universal_newlines=True)
msg = proc.communicate(password)[0]
md5_key = subprocess.check_output(
'ssh-keyscan -t rsa 127.0.0.1 2>/dev/null | grep -v "\\^#" | ' +
'cut -d" " -f3 | base64 -d | md5sum -b | cut -d" " -f1',
- shell=True).rstrip()
+ shell=True).rstrip().decode('ascii')
vm.launch()
blockdev_create(vm, { 'driver': 'ssh',
sha1_key = subprocess.check_output(
'ssh-keyscan -t rsa 127.0.0.1 2>/dev/null | grep -v "\\^#" | ' +
'cut -d" " -f3 | base64 -d | sha1sum -b | cut -d" " -f1',
- shell=True).rstrip()
+ shell=True).rstrip().decode('ascii')
vm.launch()
blockdev_create(vm, { 'driver': 'ssh',
'''Run qemu-img and return its output'''
subp = subprocess.Popen(qemu_img_args + list(args),
stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
+ stderr=subprocess.STDOUT,
+ universal_newlines=True)
exitcode = subp.wait()
if exitcode < 0:
sys.stderr.write('qemu-img received signal %i: %s\n' % (-exitcode, ' '.join(qemu_img_args + list(args))))
'''Run qemu-io and return the stdout data'''
args = qemu_io_args + list(args)
subp = subprocess.Popen(args, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
+ stderr=subprocess.STDOUT,
+ universal_newlines=True)
exitcode = subp.wait()
if exitcode < 0:
sys.stderr.write('qemu-io received signal %i: %s\n' % (-exitcode, ' '.join(args)))
self.args = qemu_io_args + list(args)
self._p = subprocess.Popen(self.args, stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
+ stderr=subprocess.STDOUT,
+ universal_newlines=True)
assert self._p.stdout.read(9) == 'qemu-io> '
def close(self):
def create_image(name, size):
'''Create a fully-allocated raw image with sector markers'''
- file = open(name, 'w')
+ file = open(name, 'wb')
i = 0
while i < size:
sector = struct.pack('>l504xl', i / 512, i / 512)
raise Exception('unexpected disconnect')
chunks.append(chunk)
received += len(chunk)
- return ''.join(chunks)
+ return b''.join(chunks)
class Rule(object):
def __init__(self, name, event, io, when):
req = read_request(conn)
if req.type == NBD_CMD_READ:
write_reply(conn, 0, req.handle)
- conn.send('\0' * req.len, event='data')
+ conn.send(b'\0' * req.len, event='data')
elif req.type == NBD_CMD_WRITE:
_ = conn.recv(req.len, event='data')
write_reply(conn, 0, req.handle)
def __init__(self, magic, length, data):
if length % 8 != 0:
padding = 8 - (length % 8)
- data += "\0" * padding
+ data += b"\0" * padding
self.magic = magic
self.length = length
fd.seek(self.header_length)
extensions = self.extensions
- extensions.append(QcowHeaderExtension(0, 0, ""))
+ extensions.append(QcowHeaderExtension(0, 0, b""))
for ex in extensions:
buf = struct.pack('>II', ex.magic, ex.length)
fd.write(buf)
for ex in self.extensions:
data = ex.data[:ex.length]
- if all(c in string.printable for c in data):
- data = "'%s'" % data
+ if all(c in string.printable.encode('ascii') for c in data):
+ data = "'%s'" % data.decode('ascii')
else:
data = "<binary>"
sys.exit(1)
h = QcowHeader(fd)
- h.extensions.append(QcowHeaderExtension.create(magic, data))
+ h.extensions.append(QcowHeaderExtension.create(magic, data.encode('ascii')))
h.update(fd)
def cmd_add_header_ext_stdio(fd, magic):