Move the last_bytes util method to libvirt
The only user of this util method is libvirt, so it should live there. This is a precursor to re-writing its single caller to use privsep to read bytes instead of chown'ing files. Change-Id: Ice5cc70eeef3fbeee9a1a0ec0daa801c6f74480c
This commit is contained in:
parent
24a96f4cbe
commit
ddfd93a38c
|
@ -779,33 +779,6 @@ class MkfsTestCase(test.NoDBTestCase):
|
|||
'/my/swap/block/dev', run_as_root=False)
|
||||
|
||||
|
||||
class LastBytesTestCase(test.NoDBTestCase):
|
||||
"""Test the last_bytes() utility method."""
|
||||
|
||||
def setUp(self):
|
||||
super(LastBytesTestCase, self).setUp()
|
||||
self.f = six.BytesIO(b'1234567890')
|
||||
|
||||
def test_truncated(self):
|
||||
self.f.seek(0, os.SEEK_SET)
|
||||
out, remaining = utils.last_bytes(self.f, 5)
|
||||
self.assertEqual(out, b'67890')
|
||||
self.assertGreater(remaining, 0)
|
||||
|
||||
def test_read_all(self):
|
||||
self.f.seek(0, os.SEEK_SET)
|
||||
out, remaining = utils.last_bytes(self.f, 1000)
|
||||
self.assertEqual(out, b'1234567890')
|
||||
self.assertFalse(remaining > 0)
|
||||
|
||||
def test_seek_too_far_real_file(self):
|
||||
# StringIO doesn't raise IOError if you see past the start of the file.
|
||||
with tempfile.TemporaryFile() as flo:
|
||||
content = b'1234567890'
|
||||
flo.write(content)
|
||||
self.assertEqual((content, 0), utils.last_bytes(flo, 1000))
|
||||
|
||||
|
||||
class MetadataToDictTestCase(test.NoDBTestCase):
|
||||
def test_metadata_to_dict(self):
|
||||
self.assertEqual(utils.metadata_to_dict(
|
||||
|
|
|
@ -177,3 +177,7 @@ def chown_for_id_maps(path, id_maps):
|
|||
|
||||
def get_arch(image_meta):
|
||||
return libvirt_utils.get_arch(image_meta)
|
||||
|
||||
|
||||
def last_bytes(file_like_object, num):
|
||||
return libvirt_utils.last_bytes(file_like_object, num)
|
||||
|
|
|
@ -939,3 +939,32 @@ sunrpc /var/lib/nfs/rpc_pipefs rpc_pipefs rw,relatime 0 0
|
|||
disk_path, format = libvirt_utils.find_disk(guest)
|
||||
self.assertEqual('/test/disk', disk_path)
|
||||
self.assertEqual('ploop', format)
|
||||
|
||||
|
||||
class LastBytesTestCase(test.NoDBTestCase):
|
||||
"""Test the last_bytes() utility method."""
|
||||
|
||||
def setUp(self):
|
||||
super(LastBytesTestCase, self).setUp()
|
||||
self.f = six.BytesIO(b'1234567890')
|
||||
|
||||
def test_truncated(self):
|
||||
self.f.seek(0, os.SEEK_SET)
|
||||
out, remaining = libvirt_utils.last_bytes(self.f, 5)
|
||||
self.assertEqual(out, b'67890')
|
||||
self.assertGreater(remaining, 0)
|
||||
|
||||
def test_read_all(self):
|
||||
self.f.seek(0, os.SEEK_SET)
|
||||
out, remaining = libvirt_utils.last_bytes(self.f, 1000)
|
||||
self.assertEqual(out, b'1234567890')
|
||||
self.assertFalse(remaining > 0)
|
||||
|
||||
def test_seek_too_far_real_file(self):
|
||||
# StringIO doesn't raise IOError if you see past the start of the file.
|
||||
with tempfile.TemporaryFile() as flo:
|
||||
content = b'1234567890'
|
||||
flo.write(content)
|
||||
self.assertEqual(
|
||||
(content, 0),
|
||||
libvirt_utils.last_bytes(flo, 1000))
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
import contextlib
|
||||
import copy
|
||||
import datetime
|
||||
import errno
|
||||
import functools
|
||||
import hashlib
|
||||
import inspect
|
||||
|
@ -837,30 +836,6 @@ def mkfs(fs, path, label=None, run_as_root=False):
|
|||
execute(*args, run_as_root=run_as_root)
|
||||
|
||||
|
||||
def last_bytes(file_like_object, num):
|
||||
"""Return num bytes from the end of the file, and remaining byte count.
|
||||
|
||||
:param file_like_object: The file to read
|
||||
:param num: The number of bytes to return
|
||||
|
||||
:returns: (data, remaining)
|
||||
"""
|
||||
|
||||
try:
|
||||
file_like_object.seek(-num, os.SEEK_END)
|
||||
except IOError as e:
|
||||
# seek() fails with EINVAL when trying to go before the start of the
|
||||
# file. It means that num is larger than the file size, so just
|
||||
# go to the start.
|
||||
if e.errno == errno.EINVAL:
|
||||
file_like_object.seek(0, os.SEEK_SET)
|
||||
else:
|
||||
raise
|
||||
|
||||
remaining = file_like_object.tell()
|
||||
return (file_like_object.read(), remaining)
|
||||
|
||||
|
||||
def metadata_to_dict(metadata, include_deleted=False):
|
||||
result = {}
|
||||
for item in metadata:
|
||||
|
|
|
@ -2839,7 +2839,8 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
while bytes_to_read > 0 and os.path.exists(path):
|
||||
libvirt_utils.chown(path, os.getuid())
|
||||
with libvirt_utils.file_open(path, 'rb') as fp:
|
||||
read_log_data, remaining = utils.last_bytes(fp, bytes_to_read)
|
||||
read_log_data, remaining = libvirt_utils.last_bytes(
|
||||
fp, bytes_to_read)
|
||||
# We need the log file content in chronological order,
|
||||
# that's why we *prepend* the log data.
|
||||
log_data = read_log_data + log_data
|
||||
|
|
|
@ -532,3 +532,27 @@ def is_mounted(mount_path, source=None):
|
|||
|
||||
def is_valid_hostname(hostname):
|
||||
return re.match(r"^[\w\-\.:]+$", hostname)
|
||||
|
||||
|
||||
def last_bytes(file_like_object, num):
|
||||
"""Return num bytes from the end of the file, and remaining byte count.
|
||||
|
||||
:param file_like_object: The file to read
|
||||
:param num: The number of bytes to return
|
||||
|
||||
:returns: (data, remaining)
|
||||
"""
|
||||
|
||||
try:
|
||||
file_like_object.seek(-num, os.SEEK_END)
|
||||
except IOError as e:
|
||||
# seek() fails with EINVAL when trying to go before the start of
|
||||
# the file. It means that num is larger than the file size, so
|
||||
# just go to the start.
|
||||
if e.errno == errno.EINVAL:
|
||||
file_like_object.seek(0, os.SEEK_SET)
|
||||
else:
|
||||
raise
|
||||
|
||||
remaining = file_like_object.tell()
|
||||
return (file_like_object.read(), remaining)
|
||||
|
|
Loading…
Reference in New Issue