summaryrefslogtreecommitdiff
path: root/kvmd/plugins/msd/otg/__init__.py
diff options
context:
space:
mode:
authorMaxim Devaev <[email protected]>2022-07-23 18:34:58 +0300
committerMaxim Devaev <[email protected]>2022-07-24 05:38:26 +0300
commit0e3ebac3627fe5039957d2d48d68d8620ff9384f (patch)
tree2792d2c261edffedf8bd8675f6ad8a5ea1bb56a3 /kvmd/plugins/msd/otg/__init__.py
parentde140537254a517559c78de048791a197011c1f6 (diff)
reading images api
Diffstat (limited to 'kvmd/plugins/msd/otg/__init__.py')
-rw-r--r--kvmd/plugins/msd/otg/__init__.py34
1 files changed, 34 insertions, 0 deletions
diff --git a/kvmd/plugins/msd/otg/__init__.py b/kvmd/plugins/msd/otg/__init__.py
index 1f670de5..1149b39e 100644
--- a/kvmd/plugins/msd/otg/__init__.py
+++ b/kvmd/plugins/msd/otg/__init__.py
@@ -57,6 +57,7 @@ from .. import MsdImageNotSelected
from .. import MsdUnknownImageError
from .. import MsdImageExistsError
from .. import BaseMsd
+from .. import MsdImageReader
from .. import MsdImageWriter
from . import fs
@@ -136,6 +137,7 @@ class _State:
class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
def __init__( # pylint: disable=super-init-not-called
self,
+ read_chunk_size: int,
write_chunk_size: int,
sync_chunk_size: int,
@@ -148,6 +150,7 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
gadget: str, # XXX: Not from options, see /kvmd/apps/kvmd/__init__.py for details
) -> None:
+ self.__read_chunk_size = read_chunk_size
self.__write_chunk_size = write_chunk_size
self.__sync_chunk_size = sync_chunk_size
@@ -162,6 +165,7 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
self.__drive = Drive(gadget, instance=0, lun=0)
+ self.__reader: Optional[MsdImageReader] = None
self.__writer: Optional[MsdImageWriter] = None
self.__writer_tick = 0.0
@@ -175,6 +179,7 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
@classmethod
def get_plugin_options(cls) -> Dict:
return {
+ "read_chunk_size": Option(65536, type=functools.partial(valid_number, min=1024)),
"write_chunk_size": Option(65536, type=functools.partial(valid_number, min=1024)),
"sync_chunk_size": Option(4194304, type=functools.partial(valid_number, min=1024)),
@@ -253,6 +258,7 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
@aiotools.atomic
async def cleanup(self) -> None:
+ await self.__close_reader()
await self.__close_writer()
# =====
@@ -318,6 +324,29 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
self.__state.vd.connected = connected
@contextlib.asynccontextmanager
+ async def read_image(self, name: str) -> AsyncGenerator[int, None]:
+ async with self.__state.busy():
+ assert self.__state.storage
+ assert self.__state.vd
+
+ if self.__state.vd.connected or self.__drive.get_image_path():
+ raise MsdConnectedError()
+
+ path = os.path.join(self.__images_path, name)
+ if name not in self.__state.storage.images or not os.path.exists(path):
+ raise MsdUnknownImageError()
+
+ try:
+ self.__reader = await MsdImageReader(path, self.__read_chunk_size).open()
+ yield self.__reader.get_size()
+ finally:
+ await self.__close_reader()
+
+ async def read_image_chunk(self) -> bytes:
+ assert self.__reader
+ return (await self.__reader.read())
+
+ @contextlib.asynccontextmanager
async def write_image(self, name: str, size: int) -> AsyncGenerator[int, None]:
try:
async with self.__state._region: # pylint: disable=protected-access
@@ -387,6 +416,11 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
# =====
+ async def __close_reader(self) -> None:
+ if self.__reader:
+ await self.__reader.close()
+ self.__reader = None
+
async def __close_writer(self) -> None:
if self.__writer:
await self.__writer.close()