mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-02-01 02:21:53 +08:00
writable msd
This commit is contained in:
@@ -56,7 +56,6 @@ from .. import MsdDisconnectedError
|
|||||||
from .. import MsdImageNotSelected
|
from .. import MsdImageNotSelected
|
||||||
from .. import MsdUnknownImageError
|
from .. import MsdUnknownImageError
|
||||||
from .. import MsdImageExistsError
|
from .. import MsdImageExistsError
|
||||||
from .. import MsdRwNotSupported
|
|
||||||
from .. import BaseMsd
|
from .. import BaseMsd
|
||||||
from .. import MsdImageWriter
|
from .. import MsdImageWriter
|
||||||
|
|
||||||
@@ -95,6 +94,7 @@ class _VirtualDriveState:
|
|||||||
image: Optional[_DriveImage]
|
image: Optional[_DriveImage]
|
||||||
connected: bool
|
connected: bool
|
||||||
cdrom: bool
|
cdrom: bool
|
||||||
|
rw: bool
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_drive_state(cls, state: _DriveState) -> "_VirtualDriveState":
|
def from_drive_state(cls, state: _DriveState) -> "_VirtualDriveState":
|
||||||
@@ -102,6 +102,7 @@ class _VirtualDriveState:
|
|||||||
image=state.image,
|
image=state.image,
|
||||||
connected=bool(state.image),
|
connected=bool(state.image),
|
||||||
cdrom=state.cdrom,
|
cdrom=state.cdrom,
|
||||||
|
rw=state.rw,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -223,7 +224,7 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
|
|||||||
"features": {
|
"features": {
|
||||||
"multi": True,
|
"multi": True,
|
||||||
"cdrom": 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):
|
async with self.__state.busy(check_online=False):
|
||||||
try:
|
try:
|
||||||
self.__drive.set_image_path("")
|
self.__drive.set_image_path("")
|
||||||
self.__drive.set_rw_flag(False)
|
|
||||||
self.__drive.set_cdrom_flag(False)
|
self.__drive.set_cdrom_flag(False)
|
||||||
|
self.__drive.set_rw_flag(False)
|
||||||
|
await self.__remount_rw(False)
|
||||||
except Exception:
|
except Exception:
|
||||||
get_logger(0).exception("Can't reset MSD")
|
get_logger(0).exception("Can't reset MSD properly")
|
||||||
|
|
||||||
@aiotools.atomic
|
@aiotools.atomic
|
||||||
async def cleanup(self) -> None:
|
async def cleanup(self) -> None:
|
||||||
@@ -264,9 +266,6 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
|
|||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
async with self.__state.busy():
|
async with self.__state.busy():
|
||||||
if rw is not None:
|
|
||||||
raise MsdRwNotSupported()
|
|
||||||
|
|
||||||
assert self.__state.storage
|
assert self.__state.storage
|
||||||
assert self.__state.vd
|
assert self.__state.vd
|
||||||
|
|
||||||
@@ -286,6 +285,9 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
|
|||||||
if cdrom is not None:
|
if cdrom is not None:
|
||||||
self.__state.vd.cdrom = cdrom
|
self.__state.vd.cdrom = cdrom
|
||||||
|
|
||||||
|
if rw is not None:
|
||||||
|
self.__state.vd.rw = rw
|
||||||
|
|
||||||
@aiotools.atomic
|
@aiotools.atomic
|
||||||
async def set_connected(self, connected: bool) -> None:
|
async def set_connected(self, connected: bool) -> None:
|
||||||
async with self.__state.busy():
|
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):
|
if not os.path.exists(self.__state.vd.image.path):
|
||||||
raise MsdUnknownImageError()
|
raise MsdUnknownImageError()
|
||||||
|
|
||||||
|
self.__drive.set_rw_flag(self.__state.vd.rw)
|
||||||
self.__drive.set_cdrom_flag(self.__state.vd.cdrom)
|
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)
|
self.__drive.set_image_path(self.__state.vd.image.path)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if not (self.__state.vd.connected or self.__drive.get_image_path()):
|
if not (self.__state.vd.connected or self.__drive.get_image_path()):
|
||||||
raise MsdDisconnectedError()
|
raise MsdDisconnectedError()
|
||||||
self.__drive.set_image_path("")
|
self.__drive.set_image_path("")
|
||||||
|
await self.__remount_rw(False, fatal=False)
|
||||||
|
|
||||||
self.__state.vd.connected = connected
|
self.__state.vd.connected = connected
|
||||||
|
|
||||||
@@ -339,10 +345,7 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
|
|||||||
|
|
||||||
finally:
|
finally:
|
||||||
await self.__close_new_writer()
|
await self.__close_new_writer()
|
||||||
try:
|
await self.__remount_rw(False, fatal=False)
|
||||||
await self.__remount_rw(False)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
finally:
|
finally:
|
||||||
# Между закрытием файла и эвентом айнотифи состояние может быть не обновлено,
|
# Между закрытием файла и эвентом айнотифи состояние может быть не обновлено,
|
||||||
# так что форсим обновление вручную, чтобы получить актуальное состояние.
|
# так что форсим обновление вручную, чтобы получить актуальное состояние.
|
||||||
@@ -442,9 +445,6 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
|
|||||||
async with self.__state._lock: # pylint: disable=protected-access
|
async with self.__state._lock: # pylint: disable=protected-access
|
||||||
try:
|
try:
|
||||||
drive_state = self.__get_drive_state()
|
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:
|
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):
|
if os.path.exists(path):
|
||||||
logger.info("Setting up initial image %r ...", self.__initial_image)
|
logger.info("Setting up initial image %r ...", self.__initial_image)
|
||||||
try:
|
try:
|
||||||
|
self.__drive.set_rw_flag(False)
|
||||||
self.__drive.set_cdrom_flag(self.__initial_cdrom)
|
self.__drive.set_cdrom_flag(self.__initial_cdrom)
|
||||||
self.__drive.set_image_path(path)
|
self.__drive.set_image_path(path)
|
||||||
except Exception:
|
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)):
|
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")
|
||||||
|
|||||||
@@ -437,6 +437,17 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</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">
|
<div class="msd-multi-storage feature-disabled">
|
||||||
<hr>
|
<hr>
|
||||||
<div class="text">
|
<div class="text">
|
||||||
|
|||||||
@@ -47,6 +47,9 @@ li(id="msd-dropdown" class="right feature-disabled")
|
|||||||
label(for="msd-mode-radio-cdrom") CD-ROM
|
label(for="msd-mode-radio-cdrom") CD-ROM
|
||||||
input(type="radio" id="msd-mode-radio-flash" name="msd-mode-radio" value="0")
|
input(type="radio" id="msd-mode-radio-flash" name="msd-mode-radio" value="0")
|
||||||
label(for="msd-mode-radio-flash") Flash
|
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")
|
div(class="msd-multi-storage feature-disabled")
|
||||||
hr
|
hr
|
||||||
div(class="text")
|
div(class="text")
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ export function Msd() {
|
|||||||
|
|
||||||
tools.radio.setOnClick("msd-mode-radio", __clickModeRadio);
|
tools.radio.setOnClick("msd-mode-radio", __clickModeRadio);
|
||||||
|
|
||||||
|
tools.el.setOnClick($("msd-rw-switch"), __clickRwSwitch);
|
||||||
|
|
||||||
tools.el.setOnClick($("msd-select-new-button"), __toggleSelectSub);
|
tools.el.setOnClick($("msd-select-new-button"), __toggleSelectSub);
|
||||||
$("msd-new-file").onchange = __selectNewFile;
|
$("msd-new-file").onchange = __selectNewFile;
|
||||||
$("msd-new-url").oninput = __selectNewUrl;
|
$("msd-new-url").oninput = __selectNewUrl;
|
||||||
@@ -88,6 +90,10 @@ export function Msd() {
|
|||||||
__sendParam("cdrom", tools.radio.getValue("msd-mode-radio"));
|
__sendParam("cdrom", tools.radio.getValue("msd-mode-radio"));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var __clickRwSwitch = function() {
|
||||||
|
__sendParam("rw", $("msd-rw-switch").checked);
|
||||||
|
};
|
||||||
|
|
||||||
var __sendParam = function(name, value) {
|
var __sendParam = function(name, value) {
|
||||||
let http = tools.makeRequest("POST", `/api/msd/set_params?${name}=${encodeURIComponent(value)}`, function() {
|
let http = tools.makeRequest("POST", `/api/msd/set_params?${name}=${encodeURIComponent(value)}`, function() {
|
||||||
if (http.readyState === 4) {
|
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.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.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-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));
|
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")) {
|
for (let el of $$$(".msd-cdrom-emulation")) {
|
||||||
tools.feature.setEnabled(el, s.features.cdrom);
|
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));
|
tools.hidden.setVisible($("msd-message-offline"), (s && !s.online));
|
||||||
|
|||||||
Reference in New Issue
Block a user