提交 e45e647f 编写于 作者: C Cleber Rosa

ISO9660: add a pycdlib backend

This implements another backend for the avocado.utils.iso9660 library,
based on the pure Python pycdlib.

The library, as it's the case with all other ISO9660 utilities, is
optional and should only attempted to be be used if they are available
in the system.

In theory, we're well equipped with backends, but this brings the
interesting possibility of running on non-UNIX platforms.
Signed-off-by: NCleber Rosa <crosa@redhat.com>
上级 04329b15
......@@ -21,18 +21,26 @@ either in userspace tools or on the Linux kernel itself (via mount).
"""
__all__ = ['iso9660', 'Iso9660IsoInfo', 'Iso9660IsoRead', 'Iso9660Mount']
__all__ = ['iso9660', 'Iso9660IsoInfo', 'Iso9660IsoRead', 'Iso9660Mount',
'ISO9660PyCDLib']
import os
import io
import logging
import tempfile
import os
import re
import shutil
import sys
import re
import tempfile
from . import process
try:
import pycdlib
except ImportError:
pycdlib = None
def has_userland_tool(executable):
"""
Returns whether the system has a given executable
......@@ -74,6 +82,15 @@ def has_isoread():
return has_userland_tool('iso-read')
def has_pycdlib():
"""
Returns whether the system has the Python "pycdlib" library
:rtype: bool
"""
return pycdlib is not None
def can_mount():
"""
Test whether the current user can perform a loop mount
......@@ -366,6 +383,39 @@ class Iso9660Mount(BaseIso9660):
return self._mnt_dir
class ISO9660PyCDLib(BaseIso9660):
"""
Represents a ISO9660 filesystem
This implementation is based on the pycdlib library
"""
def __init__(self, path):
if not has_pycdlib():
raise RuntimeError('This class requires the pycdlib library')
self._iso = pycdlib.PyCdlib()
self._iso.open(path)
self._iso_closed = False
def read(self, path):
if not os.path.isabs(path):
path = '/' + path
data = io.BytesIO()
self._iso.get_file_from_iso_fp(data, joliet_path=path)
return data.getvalue()
def copy(self, src, dst):
if not os.path.isabs(src):
src = '/' + src
self._iso.get_file_from_iso(dst, joliet_path=src)
def close(self):
if not self._iso_closed:
self._iso.close()
self._iso_closed = True
def iso9660(path):
"""
Checks the available tools on a system and chooses class accordingly
......@@ -377,9 +427,10 @@ def iso9660(path):
:type path: str
:return: an instance of any iso9660 capable tool
:rtype: :class:`Iso9660IsoInfo`, :class:`Iso9660IsoRead`,
:class:`Iso9660Mount` or None
:class:`Iso9660Mount`, :class:`ISO9660PyCDLib` or None
"""
implementations = [('isoinfo', has_isoinfo, Iso9660IsoInfo),
implementations = [('pycdlib', has_pycdlib, ISO9660PyCDLib),
('isoinfo', has_isoinfo, Iso9660IsoInfo),
('iso-read', has_isoread, Iso9660IsoRead),
('mount', can_mount, Iso9660Mount)]
......
......@@ -24,3 +24,4 @@ lxml>=3.4.4
# pkg_resources.packaging, let's pin the version
setuptools==25.1.1
libvirt-python==3.6.0
pycdlib==1.6.0
......@@ -127,5 +127,21 @@ class IsoMount(BaseIso9660):
self.mnt_dir_workflow()
class PyCDLib(BaseIso9660):
"""
PyCDLib-based check
"""
@unittest.skipUnless(iso9660.has_pycdlib(), "pycdlib not installed")
def setUp(self):
super(PyCDLib, self).setUp()
self.iso = iso9660.ISO9660PyCDLib(self.iso_path)
def test_basic_workflow(self):
"""Call the basic workflow"""
self.basic_workflow()
if __name__ == "__main__":
unittest.main()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册