更新脚本

This commit is contained in:
mofeng 2023-11-25 19:47:31 +08:00
parent fcbe1fb472
commit 4bcc60fcc8
10 changed files with 469 additions and 0 deletions

62
config/main.yaml Normal file
View File

@ -0,0 +1,62 @@
# Don't touch this file otherwise your device may stop working.
# Use override.yaml to modify required settings.
# You can find a working configuration in /usr/share/kvmd/configs.default/kvmd.
override: !include [override.d, override.yaml]
logging: !include logging.yaml
kvmd:
auth: !include auth.yaml
hid:
type: otg
mouse_alt:
device: /dev/kvmd-hid-mouse-alt
atx:
type: disabled
msd:
type: otg
streamer:
quality: 0
resolution:
default: 1280x720
available:
- 1920x1080
- 1600x1200
- 1360x768
- 1280x1024
- 1280x960
- 1280x720
- 1024x768
- 800x600
- 720x576
- 720x480
cmd:
- "/usr/bin/ustreamer"
- "--device=/dev/kvmd-video"
- "--persistent"
- "--format=mjpeg"
- "--encoder=cpu"
- "--resolution={resolution}"
- "--desired-fps={desired_fps}"
- "--drop-same-frames=30"
- "--last-as-blank=0"
- "--unix={unix}"
- "--unix-rm"
- "--unix-mode=0660"
- "--exit-on-parent-death"
- "--process-name-prefix={process_name_prefix}"
- "--notify-parent"
- "--no-log-colors"
- "--sink=kvmd::ustreamer::jpeg"
- "--sink-mode=0660"
vnc:
memsink:
jpeg:
sink: "kvmd::ustreamer::jpeg"

69
config/override.yaml Normal file
View File

@ -0,0 +1,69 @@
####################################################################
# #
# Override Pi-KVM system settings. This file uses the YAML syntax. #
# #
# https://github.com/pikvm/pikvm/blob/master/pages/config.md #
# #
# All overridden parameters will be applied AFTER other configs #
# and "!include" directives and BEFORE validation. #
# Not: Sections should be combined under shared keys. #
# #
####################################################################
#
#########
# Wrong #
#########
#kvmd:
# gpio:
# drivers: ...
#kvmd:
# gpio:
# scheme: ...
#
###########
# Correct #
###########
#kvmd:
# gpio:
# drivers: ...
# scheme: ...
#
###########
# Example #
###########
vnc:
# See https://github.com/pikvm/pikvm/blob/master/pages/vnc.md
keymap: /usr/share/kvmd/keymaps/ru # Set russian keymap
auth:
vncauth:
enabled: true # Enable auth via /etc/kvmd/vncpasswd
kvmd:
msd:
type: disabled
gpio:
drivers:
short_press:
type: cmd
cmd: [/usr/bin/sudo, short_press_gpio420]
long_press:
type: cmd
cmd: [/usr/bin/sudo, long_press_gpio420]
scheme:
short_button:
driver: short_press
pin: 0
mode: output
switch: false
long_button:
driver: long_press
pin: 0
mode: output
switch: false
view:
header:
title: ATX
table:
- ["#电源管理"]
- []
- ["#短按(开/关机):", short_button|按下]
- ["#长按(强制关机):", long_button|按下]

BIN
fruity-pikvm_0.2_armhf.deb Normal file

Binary file not shown.

28
install.sh Normal file
View File

@ -0,0 +1,28 @@
PYVER=$(python3 -V)
ARCH=$(uname -m)
CURRENTWD=$PWD
echo $PYVER
echo $ARCH
if [[ "$PYVER" != *"3.10"* && $(which python3.10) != *"python"* ]]; then
echo "你似乎没有安装 Python 3.10"
fi
mv ./patch/meson8b-onecloud.dtb /boot/dtb/meson8b-onecloud.dtb && echo "设备树文件覆盖成功"
gzip -dc ./patch/Boot_SkipUSBBurning.gz | dd of=/dev/mmcblk1 && echo "覆盖引导成功"
bash <(curl -sSL https://gitee.com/SuperManito/LinuxMirrors/raw/main/ChangeMirrors.sh) --source mirrors.tuna.tsinghua.edu.cn --updata-software false --web-protocol http && echo "换源成功!"
apt install -y nginx tesseract-ocr tesseract-ocr-eng janus libevent-dev libgpiod-dev tesseract-ocr-chi-sim
echo "正在安装PiKVM......"
dgkg -i ./fruity-pikvm_0.2_armhf.deb && echo "PiKVM安装成功" && systemctl enable kvmd-vnc
mv ./patch/chinese.patch /usr/share/kvmd/web/ && cd /usr/share/kvmd/web/ && patch -p0 < chinese.patch
mv ./patch/3.198msd.patch /usr/local/lib/python3.10/kvmd-packages/ && cd /usr/local/lib/python3.10/kvmd-packages/ && patch -s -p0 < 3.198msd.patch
echo "补丁应用成功!"
cd $CURRENTWD && mv ./patch/long_press_gpio420 /usr/bin && mv ./patch/short_press_gpio420 /usr/bin && echo "GPIO-420脚本移动成功"
mv ./config/main.yaml /etc/kvmd/ && mv ./config/override.yaml /etc/kvmd/ && echo "配置文件修改成功!"
kvmd -m && echo "请给玩客云重新上电然后就可以开始使用One-KVM了"

296
patch/3.198msd.patch Normal file
View File

@ -0,0 +1,296 @@
diff -ruN kvmd/aiohelpers.py kvmd/aiohelpers.py
--- kvmd/aiohelpers.py 2023-01-30 03:25:23.556804000 +0700
+++ kvmd/aiohelpers.py 2023-01-30 08:12:21.773899000 +0700
@@ -38,11 +38,26 @@
]
logger.info("Remounting %s storage to %s: %s ...", name, mode.upper(), tools.cmdfmt(cmd))
try:
- proc = await aioproc.log_process(cmd, logger)
- if proc.returncode != 0:
- assert proc.returncode is not None
- raise subprocess.CalledProcessError(proc.returncode, cmd)
- except Exception as err:
- logger.error("Can't remount %s storage: %s", name, tools.efmt(err))
- return False
- return True
+ await _run_helper(cmd)
+ except Exception:
+ logger.error("Can't remount internal storage")
+ raise
+
+
+async def unlock_drive(base_cmd: list[str]) -> None:
+ logger = get_logger(0)
+ logger.info("Unlocking the drive ...")
+ try:
+ await _run_helper(base_cmd)
+ except Exception:
+ logger.error("Can't unlock the drive")
+ raise
+
+
+# =====
+async def _run_helper(cmd: list[str]) -> None:
+ logger = get_logger(0)
+ logger.info("Executing helper %s ...", cmd)
+ proc = await aioproc.log_process(cmd, logger)
+ if proc.returncode != 0:
+ logger.error(f"Error while helper execution: pid={proc.pid}; retcode={proc.returncode}")
diff -ruN kvmd/apps/otg/__init__.py kvmd/apps/otg/__init__.py
--- kvmd/apps/otg/__init__.py 2022-12-22 10:01:48.000000000 +0700
+++ kvmd/apps/otg/__init__.py 2023-01-30 03:51:51.331539000 +0700
@@ -182,7 +182,6 @@
_chown(join(func_path, "lun.0/cdrom"), user)
_chown(join(func_path, "lun.0/ro"), user)
_chown(join(func_path, "lun.0/file"), user)
- _chown(join(func_path, "lun.0/forced_eject"), user)
_symlink(func_path, join(self.__profile_path, func))
name = ("Mass Storage Drive" if self.__msd_instance == 0 else f"Extra Drive #{self.__msd_instance}")
self.__create_meta(func, name)
@@ -291,7 +290,7 @@
logger.info("Disabling gadget %r ...", config.otg.gadget)
_write(join(gadget_path, "UDC"), "\n")
- _unlink(join(gadget_path, "os_desc", usb.G_PROFILE_NAME), optional=True)
+ _unlink(join(gadget_path, "os_desc", usb.G_PROFILE_NAME), True)
profile_path = join(gadget_path, usb.G_PROFILE)
for func in os.listdir(profile_path):
diff -ruN kvmd/apps/otgmsd/__init__.py kvmd/apps/otgmsd/__init__.py
--- kvmd/apps/otgmsd/__init__.py 2022-12-22 10:01:48.000000000 +0700
+++ kvmd/apps/otgmsd/__init__.py 2023-01-30 04:35:09.702576000 +0700
@@ -21,8 +21,10 @@
import os
+import signal
import errno
import argparse
+import psutil
from ...validators.basic import valid_bool
from ...validators.basic import valid_int_f0
@@ -53,6 +55,21 @@
raise
+def _unlock() -> None:
+ # https://github.com/torvalds/linux/blob/3039fad/drivers/usb/gadget/function/f_mass_storage.c#L2924
+ found = False
+ for proc in psutil.process_iter():
+ attrs = proc.as_dict(attrs=["name", "exe", "pid"])
+ if attrs.get("name") == "file-storage" and not attrs.get("exe"):
+ try:
+ proc.send_signal(signal.SIGUSR1)
+ found = True
+ except Exception as err:
+ raise SystemExit(f"Can't send SIGUSR1 to MSD kernel thread with pid={attrs['pid']}: {err}")
+ if not found:
+ raise SystemExit("Can't find MSD kernel thread")
+
+
# =====
def main(argv: (list[str] | None)=None) -> None:
(parent_parser, argv, config) = init(
@@ -77,7 +94,7 @@
parser.add_argument("--eject", action="store_true",
help="Eject the image")
parser.add_argument("--unlock", action="store_true",
- help="Does nothing, just for backward compatibility")
+ help="Send SIGUSR1 to MSD kernel thread")
options = parser.parse_args(argv[1:])
if config.kvmd.msd.type != "otg":
@@ -87,8 +104,11 @@
set_param = (lambda param, value: _set_param(config.otg.gadget, options.instance, param, value))
get_param = (lambda param: _get_param(config.otg.gadget, options.instance, param))
+ if options.unlock:
+ _unlock()
+
if options.eject:
- set_param("forced_eject", "")
+ set_param("file", "")
if options.set_cdrom is not None:
set_param("cdrom", str(int(options.set_cdrom)))
diff -ruN kvmd/helpers/unlock/__init__.py kvmd/helpers/unlock/__init__.py
--- kvmd/helpers/unlock/__init__.py 1970-01-01 07:00:00.000000000 +0700
+++ kvmd/helpers/unlock/__init__.py 2023-01-30 04:04:07.000000000 +0700
@@ -0,0 +1,58 @@
+# ========================================================================== #
+# #
+# KVMD - The main PiKVM daemon. #
+# #
+# Copyright (C) 2018-2022 Maxim Devaev <mdevaev@gmail.com> #
+# #
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program. If not, see <https://www.gnu.org/licenses/>. #
+# #
+# ========================================================================== #
+
+
+import sys
+import signal
+
+import psutil
+
+
+# =====
+_PROCESS_NAME = "file-storage"
+
+
+# =====
+def _log(msg: str) -> None:
+ print(msg, file=sys.stderr)
+
+
+def _unlock() -> None:
+ # https://github.com/torvalds/linux/blob/3039fad/drivers/usb/gadget/function/f_mass_storage.c#L2924
+ found = False
+ for proc in psutil.process_iter():
+ attrs = proc.as_dict(attrs=["name", "exe", "pid"])
+ if attrs.get("name") == _PROCESS_NAME and not attrs.get("exe"):
+ _log(f"Sending SIGUSR1 to MSD {_PROCESS_NAME!r} kernel thread with pid={attrs['pid']} ...")
+ try:
+ proc.send_signal(signal.SIGUSR1)
+ found = True
+ except Exception as err:
+ raise SystemExit(f"Can't send SIGUSR1 to MSD kernel thread with pid={attrs['pid']}: {err}")
+ if not found:
+ raise SystemExit(f"Can't find MSD kernel thread {_PROCESS_NAME!r}")
+
+
+# =====
+def main() -> None:
+ if len(sys.argv) != 2 or sys.argv[1] != "unlock":
+ raise SystemExit(f"Usage: {sys.argv[0]} [unlock]")
+ _unlock()
diff -ruN kvmd/helpers/unlock/__main__.py kvmd/helpers/unlock/__main__.py
--- kvmd/helpers/unlock/__main__.py 1970-01-01 07:00:00.000000000 +0700
+++ kvmd/helpers/unlock/__main__.py 2023-01-30 04:04:07.000000000 +0700
@@ -0,0 +1,24 @@
+# ========================================================================== #
+# #
+# KVMD - The main PiKVM daemon. #
+# #
+# Copyright (C) 2018-2022 Maxim Devaev <mdevaev@gmail.com> #
+# #
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program. If not, see <https://www.gnu.org/licenses/>. #
+# #
+# ========================================================================== #
+
+
+from . import main
+main()
diff -ruN kvmd/plugins/msd/otg/drive.py kvmd/plugins/msd/otg/drive.py
--- kvmd/plugins/msd/otg/drive.py 2022-12-22 10:01:48.000000000 +0700
+++ kvmd/plugins/msd/otg/drive.py 2023-01-30 06:31:13.923959000 +0700
@@ -51,10 +51,7 @@
# =====
def set_image_path(self, path: str) -> None:
- if path:
- self.__set_param("file", path)
- else:
- self.__set_param("forced_eject", "")
+ self.__set_param("file", path)
def get_image_path(self) -> str:
return self.__get_param("file")
diff -ruN kvmd/plugins/msd/otg/__init__.py kvmd/plugins/msd/otg/__init__.py
--- kvmd/plugins/msd/otg/__init__.py 2023-02-02 09:42:28.021418683 +0700
+++ kvmd/plugins/msd/otg/__init__.py 2023-02-02 09:50:38.774955045 +0700
@@ -129,6 +129,7 @@
sync_chunk_size: int,
remount_cmd: list[str],
+ unlock_cmd: list[str],
initial: dict,
@@ -140,6 +141,7 @@
self.__sync_chunk_size = sync_chunk_size
self.__remount_cmd = remount_cmd
+ self.__unlock_cmd = unlock_cmd
self.__initial_image: str = initial["image"]
self.__initial_cdrom: bool = initial["cdrom"]
@@ -169,6 +171,11 @@
"/usr/bin/kvmd-helper-otgmsd-remount", "{mode}",
], type=valid_command),
+ "unlock_cmd": Option([
+ "/usr/bin/sudo", "--non-interactive",
+ "/usr/bin/kvmd-helper-otgmsd-unlock", "unlock",
+ ], type=valid_command),
+
"initial": {
"image": Option("", type=valid_printable_filename, if_empty=""),
"cdrom": Option(False, type=valid_bool),
@@ -230,6 +237,7 @@
async def reset(self) -> None:
async with self.__state.busy(check_online=False):
try:
+ await self.__unlock_drive()
self.__drive.set_image_path("")
self.__drive.set_cdrom_flag(False)
self.__drive.set_rw_flag(False)
@@ -286,7 +294,7 @@
raise MsdUnknownImageError()
assert self.__state.vd.image.in_storage
-
+ await self.__unlock_drive()
self.__drive.set_rw_flag(self.__state.vd.rw)
self.__drive.set_cdrom_flag(self.__state.vd.cdrom)
if self.__state.vd.rw:
@@ -294,6 +302,7 @@
self.__drive.set_image_path(self.__state.vd.image.path)
else:
+ await self.__unlock_drive()
self.__state_check_connected()
self.__drive.set_image_path("")
await self.__remount_rw(False, fatal=False)
@@ -499,6 +508,7 @@
if image.exists():
logger.info("Setting up initial image %r ...", self.__initial_image)
try:
+ await self.__unlock_drive()
self.__drive.set_rw_flag(False)
self.__drive.set_cdrom_flag(self.__initial_cdrom)
self.__drive.set_image_path(image.path)
@@ -531,5 +541,8 @@
async def __remount_rw(self, rw: bool, fatal: bool=True) -> None:
if not (await aiohelpers.remount("MSD", self.__remount_cmd, rw)):
- if fatal:
- raise MsdError("Can't execute remount helper")
+ pass
+ #raise MsdError("Can't execute remount helper")
+
+ async def __unlock_drive(self) -> None:
+ await aiohelpers.unlock_drive(self.__unlock_cmd)

7
patch/long_press_gpio420 Normal file
View File

@ -0,0 +1,7 @@
#!/bin/bash
echo 420 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio420/direction
echo 0 > /sys/class/gpio/gpio420/value
sleep 5
echo 1 > /sys/class/gpio/gpio420/value
echo 420 > /sys/class/gpio/unexport

View File

@ -0,0 +1,7 @@
#!/bin/bash
echo 420 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio420/direction
echo 0 > /sys/class/gpio/gpio420/value
sleep 0.5
echo 1 > /sys/class/gpio/gpio420/value
echo 420 > /sys/class/gpio/unexport