summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxim Devaev <[email protected]>2022-07-23 06:57:38 +0300
committerMaxim Devaev <[email protected]>2022-07-24 05:38:26 +0300
commit477e6f05e44d3c83ff19a97f1454ac1ba9191e70 (patch)
treea976dcd5550ad549699f54b5c10a0e68cececb6e
parentaa5a538c64f8ef8fe268bf1f78b44a0d70f14389 (diff)
writable msd
-rw-r--r--kvmd/plugins/msd/otg/__init__.py34
-rw-r--r--web/kvm/index.html11
-rw-r--r--web/kvm/navbar-msd.pug3
-rw-r--r--web/share/js/kvm/msd.js12
4 files changed, 44 insertions, 16 deletions
diff --git a/kvmd/plugins/msd/otg/__init__.py b/kvmd/plugins/msd/otg/__init__.py
index 3a2250e8..f04d5084 100644
--- a/kvmd/plugins/msd/otg/__init__.py
+++ b/kvmd/plugins/msd/otg/__init__.py
@@ -56,7 +56,6 @@ from .. import MsdDisconnectedError
from .. import MsdImageNotSelected
from .. import MsdUnknownImageError
from .. import MsdImageExistsError
-from .. import MsdRwNotSupported
from .. import BaseMsd
from .. import MsdImageWriter
@@ -95,6 +94,7 @@ class _VirtualDriveState:
image: Optional[_DriveImage]
connected: bool
cdrom: bool
+ rw: bool
@classmethod
def from_drive_state(cls, state: _DriveState) -> "_VirtualDriveState":
@@ -102,6 +102,7 @@ class _VirtualDriveState:
image=state.image,
connected=bool(state.image),
cdrom=state.cdrom,
+ rw=state.rw,
)
@@ -223,7 +224,7 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
"features": {
"multi": True,
"cdrom": True,
- "rw": False,
+ "rw": True,
},
}
@@ -244,10 +245,11 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
async with self.__state.busy(check_online=False):
try:
self.__drive.set_image_path("")
- self.__drive.set_rw_flag(False)
self.__drive.set_cdrom_flag(False)
+ self.__drive.set_rw_flag(False)
+ await self.__remount_rw(False)
except Exception:
- get_logger(0).exception("Can't reset MSD")
+ get_logger(0).exception("Can't reset MSD properly")
@aiotools.atomic
async def cleanup(self) -> None:
@@ -264,9 +266,6 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
) -> None:
async with self.__state.busy():
- if rw is not None:
- raise MsdRwNotSupported()
-
assert self.__state.storage
assert self.__state.vd
@@ -286,6 +285,9 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
if cdrom is not None:
self.__state.vd.cdrom = cdrom
+ if rw is not None:
+ self.__state.vd.rw = rw
+
@aiotools.atomic
async def set_connected(self, connected: bool) -> None:
async with self.__state.busy():
@@ -301,13 +303,17 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
if not os.path.exists(self.__state.vd.image.path):
raise MsdUnknownImageError()
+ self.__drive.set_rw_flag(self.__state.vd.rw)
self.__drive.set_cdrom_flag(self.__state.vd.cdrom)
+ if self.__state.vd.rw:
+ await self.__remount_rw(True)
self.__drive.set_image_path(self.__state.vd.image.path)
else:
if not (self.__state.vd.connected or self.__drive.get_image_path()):
raise MsdDisconnectedError()
self.__drive.set_image_path("")
+ await self.__remount_rw(False, fatal=False)
self.__state.vd.connected = connected
@@ -339,10 +345,7 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
finally:
await self.__close_new_writer()
- try:
- await self.__remount_rw(False)
- except Exception:
- pass
+ await self.__remount_rw(False, fatal=False)
finally:
# Между закрытием файла и эвентом айнотифи состояние может быть не обновлено,
# так что форсим обновление вручную, чтобы получить актуальное состояние.
@@ -442,9 +445,6 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
async with self.__state._lock: # pylint: disable=protected-access
try:
drive_state = self.__get_drive_state()
- if drive_state.rw:
- # Внештатное использование MSD, ломаемся
- raise MsdError("MSD has been switched to RW-mode manually")
if self.__state.vd is None and drive_state.image is None:
# Если только что включились и образ не подключен - попробовать
@@ -485,6 +485,7 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
if os.path.exists(path):
logger.info("Setting up initial image %r ...", self.__initial_image)
try:
+ self.__drive.set_rw_flag(False)
self.__drive.set_cdrom_flag(self.__initial_cdrom)
self.__drive.set_image_path(path)
except Exception:
@@ -550,6 +551,7 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
# =====
- async def __remount_rw(self, rw: bool) -> None:
+ async def __remount_rw(self, rw: bool, fatal: bool=True) -> None:
if not (await aiohelpers.remount("MSD", self.__remount_cmd, rw)):
- raise MsdError("Can't execute remount helper")
+ if fatal:
+ raise MsdError("Can't execute remount helper")
diff --git a/web/kvm/index.html b/web/kvm/index.html
index 3b908aee..093133ee 100644
--- a/web/kvm/index.html
+++ b/web/kvm/index.html
@@ -437,6 +437,17 @@
</td>
</tr>
</table>
+ <table class="kv msd-rw feature-disabled">
+ <tr>
+ <td>Read-write mode:</td>
+ <td align="right">
+ <div class="switch-box">
+ <input disabled type="checkbox" id="msd-rw-switch">
+ <label for="msd-rw-switch"><span class="switch-inner"></span><span class="switch"></span></label>
+ </div>
+ </td>
+ </tr>
+ </table>
<div class="msd-multi-storage feature-disabled">
<hr>
<div class="text">
diff --git a/web/kvm/navbar-msd.pug b/web/kvm/navbar-msd.pug
index b2cd5b99..68d764c3 100644
--- a/web/kvm/navbar-msd.pug
+++ b/web/kvm/navbar-msd.pug
@@ -47,6 +47,9 @@ li(id="msd-dropdown" class="right feature-disabled")
label(for="msd-mode-radio-cdrom") CD-ROM
input(type="radio" id="msd-mode-radio-flash" name="msd-mode-radio" value="0")
label(for="msd-mode-radio-flash") Flash
+ table(class="kv msd-rw feature-disabled")
+ tr
+ +menu_switch_notable("msd-rw-switch", "Read-write mode", false, false)
div(class="msd-multi-storage feature-disabled")
hr
div(class="text")
diff --git a/web/share/js/kvm/msd.js b/web/share/js/kvm/msd.js
index 3575f0c4..aff901d5 100644
--- a/web/share/js/kvm/msd.js
+++ b/web/share/js/kvm/msd.js
@@ -43,6 +43,8 @@ export function Msd() {
tools.radio.setOnClick("msd-mode-radio", __clickModeRadio);
+ tools.el.setOnClick($("msd-rw-switch"), __clickRwSwitch);
+
tools.el.setOnClick($("msd-select-new-button"), __toggleSelectSub);
$("msd-new-file").onchange = __selectNewFile;
$("msd-new-url").oninput = __selectNewUrl;
@@ -88,6 +90,10 @@ export function Msd() {
__sendParam("cdrom", tools.radio.getValue("msd-mode-radio"));
};
+ var __clickRwSwitch = function() {
+ __sendParam("rw", $("msd-rw-switch").checked);
+ };
+
var __sendParam = function(name, value) {
let http = tools.makeRequest("POST", `/api/msd/set_params?${name}=${encodeURIComponent(value)}`, function() {
if (http.readyState === 4) {
@@ -243,6 +249,9 @@ export function Msd() {
tools.radio.setEnabled("msd-mode-radio", (online && s.features.cdrom && !s.drive.connected && !s.busy));
tools.radio.setValue("msd-mode-radio", `${Number(online && s.features.cdrom && s.drive.cdrom)}`);
+ tools.el.setEnabled($("msd-rw-switch"), (online && s.features.rw && !s.drive.connected && !s.busy));
+ $("msd-rw-switch").checked = (online && s.features.rw && s.drive.rw);
+
tools.el.setEnabled($("msd-connect-button"), (online && (!s.features.multi || s.drive.image) && !s.drive.connected && !s.busy));
tools.el.setEnabled($("msd-disconnect-button"), (online && s.drive.connected && !s.busy));
@@ -289,6 +298,9 @@ export function Msd() {
for (let el of $$$(".msd-cdrom-emulation")) {
tools.feature.setEnabled(el, s.features.cdrom);
}
+ for (let el of $$$(".msd-rw")) {
+ tools.feature.setEnabled(el, s.features.rw);
+ }
}
tools.hidden.setVisible($("msd-message-offline"), (s && !s.online));