├── .bumpversion.cfg ├── .dockerignore ├── .editorconfig ├── .github ├── FUNDING.yml └── workflows │ ├── build_img.yaml │ └── docker-build.yaml ├── .gitignore ├── .vscode └── settings.json ├── LICENSE ├── Makefile ├── PKGBUILD ├── README.md ├── build ├── Dockerfile ├── Dockerfile-stage-0 ├── build_img.sh ├── cargo_config ├── functions │ ├── common.sh │ ├── devices.sh │ ├── install.sh │ └── packaging.sh ├── init.sh ├── platform │ ├── chainedbox │ ├── cumebox2 │ ├── docker │ ├── e900v22c │ ├── octopus-flanet │ ├── onecloud │ └── vm ├── scripts │ ├── generate-random-mac.sh │ └── kvmd-firstrun.sh └── services │ ├── kvmd-firstrun.service │ └── kvmd-generate-mac.service ├── configs ├── hw_info │ ├── model │ └── serial-number ├── janus │ ├── janus.jcfg │ ├── janus.plugin.ustreamer.jcfg │ └── janus.transport.websockets.jcfg ├── kvmd │ ├── armbain-motd │ ├── atx.sh │ ├── auth.yaml │ ├── clean_when_exit.sh │ ├── custom_atx │ │ ├── gpio.sh │ │ ├── usbrelay_hid.py │ │ └── usbrelay_hid.sh │ ├── htpasswd │ ├── ipmipasswd │ ├── kvm_input.sh │ ├── logging.yaml │ ├── main.yaml │ ├── main │ │ └── v4plus-hdmi-rpi4.yaml │ ├── meta.yaml │ ├── override.yaml │ ├── supervisord.conf │ ├── totp.secret │ ├── vncpasswd │ └── web.css ├── nginx │ ├── certbot.ctx-server.conf │ ├── kvmd.ctx-http.conf │ ├── kvmd.ctx-server.conf │ ├── loc-bigpost.conf │ ├── loc-login.conf │ ├── loc-nobuffering.conf │ ├── loc-nocache.conf │ ├── loc-proxy.conf │ ├── loc-websocket.conf │ ├── mime-types.conf │ ├── nginx.conf.mako │ └── ssl.conf └── os │ ├── boot-config │ ├── v0-hdmi-rpi2.txt │ ├── v0-hdmi-rpi3.txt │ ├── v0-hdmi-zero2w.txt │ ├── v0-hdmiusb-rpi2.txt │ ├── v0-hdmiusb-rpi3.txt │ ├── v0-hdmiusb-zero2w.txt │ ├── v1-hdmi-rpi2.txt │ ├── v1-hdmi-rpi3.txt │ ├── v1-hdmi-zero2w.txt │ ├── v1-hdmiusb-rpi2.txt │ ├── v1-hdmiusb-rpi3.txt │ ├── v1-hdmiusb-zero2w.txt │ ├── v2-hdmi-rpi3.txt │ ├── v2-hdmi-rpi4.txt │ ├── v2-hdmi-zero2w.txt │ ├── v2-hdmiusb-rpi4.txt │ ├── v3-hdmi-rpi4.txt │ ├── v4mini-hdmi-rpi4.txt │ └── v4plus-hdmi-rpi4.txt │ ├── cmdline │ ├── v0-hdmi-rpi2.sed │ ├── v0-hdmi-rpi3.sed │ ├── v0-hdmi-zero2w.sed │ ├── v0-hdmiusb-rpi2.sed │ ├── v0-hdmiusb-rpi3.sed │ ├── v0-hdmiusb-zero2w.sed │ ├── v1-hdmi-rpi2.sed │ ├── v1-hdmi-rpi3.sed │ ├── v1-hdmi-zero2w.sed │ ├── v1-hdmiusb-rpi2.sed │ ├── v1-hdmiusb-rpi3.sed │ ├── v1-hdmiusb-zero2w.sed │ ├── v2-hdmi-rpi3.sed │ ├── v2-hdmi-rpi4.sed │ ├── v2-hdmi-zero2w.sed │ ├── v2-hdmiusb-rpi4.sed │ ├── v3-hdmi-rpi4.sed │ ├── v4mini-hdmi-rpi4.sed │ └── v4plus-hdmi-rpi4.sed │ ├── kvmd-webterm.conf │ ├── modules-load │ ├── v0-hdmi.conf │ ├── v1-hdmi.conf │ ├── v2-hdmi.conf │ ├── v2-hdmiusb.conf │ ├── v3-hdmi.conf │ ├── v4mini-hdmi.conf │ └── v4plus-hdmi.conf │ ├── services │ ├── kvmd-bootconfig.service │ ├── kvmd-certbot.service │ ├── kvmd-certbot.timer │ ├── kvmd-ipmi.service │ ├── kvmd-janus-static.service │ ├── kvmd-janus.service │ ├── kvmd-media.service │ ├── kvmd-nginx.service │ ├── kvmd-oled-reboot.service │ ├── kvmd-oled-shutdown.service │ ├── kvmd-oled.service │ ├── kvmd-otg.service │ ├── kvmd-otgnet.service │ ├── kvmd-pst.service │ ├── kvmd-tc358743.service │ ├── kvmd-vnc.service │ ├── kvmd-watchdog.service │ ├── kvmd-webterm.service │ └── kvmd.service │ ├── sudoers │ ├── v0-hdmi │ ├── v0-hdmiusb │ ├── v1-hdmi │ ├── v1-hdmiusb │ ├── v2-hdmi │ ├── v2-hdmiusb │ ├── v3-hdmi │ ├── v4mini-hdmi │ └── v4plus-hdmi │ ├── sysctl.conf │ ├── sysusers.conf │ ├── tmpfiles.conf │ └── udev │ ├── common.rules │ ├── v0-hdmi-rpi2.rules │ ├── v0-hdmi-rpi3.rules │ ├── v0-hdmi-zero2w.rules │ ├── v0-hdmiusb-rpi2.rules │ ├── v0-hdmiusb-rpi3.rules │ ├── v0-hdmiusb-zero2w.rules │ ├── v1-hdmi-rpi2.rules │ ├── v1-hdmi-rpi3.rules │ ├── v1-hdmi-zero2w.rules │ ├── v1-hdmiusb-rpi2.rules │ ├── v1-hdmiusb-rpi3.rules │ ├── v1-hdmiusb-zero2w.rules │ ├── v2-hdmi-rpi3.rules │ ├── v2-hdmi-rpi4.rules │ ├── v2-hdmi-zero2w.rules │ ├── v2-hdmiusb-rpi4.rules │ ├── v3-hdmi-rpi4.rules │ ├── v4mini-hdmi-rpi4.rules │ └── v4plus-hdmi-rpi4.rules ├── contrib ├── README └── keymaps │ ├── ar │ ├── bepo │ ├── cz │ ├── da │ ├── de │ ├── de-ch │ ├── en-gb │ ├── en-us │ ├── en-us-altgr-intl │ ├── es │ ├── et │ ├── fi │ ├── fo │ ├── fr │ ├── fr-be │ ├── fr-ca │ ├── fr-ch │ ├── hr │ ├── hu │ ├── is │ ├── it │ ├── ja │ ├── lt │ ├── lv │ ├── mk │ ├── nl │ ├── no │ ├── pl │ ├── pt │ ├── pt-br │ ├── ru │ ├── sl │ ├── sv │ ├── th │ └── tr ├── extras ├── ipmi │ └── manifest.yaml ├── janus-static │ └── manifest.yaml ├── janus │ ├── manifest.yaml │ ├── nginx.ctx-http.conf │ └── nginx.ctx-server.conf ├── media │ ├── manifest.yaml │ ├── nginx.ctx-http.conf │ └── nginx.ctx-server.conf ├── vnc │ └── manifest.yaml └── webterm │ ├── manifest.yaml │ ├── nginx.ctx-http.conf │ └── nginx.ctx-server.conf ├── genmap.py ├── hid ├── arduino │ ├── .gitignore │ ├── Makefile │ ├── avrdude-rpi.conf │ ├── avrdude.py │ ├── lib │ │ ├── .gitignore │ │ ├── drivers-avr │ │ │ ├── eeprom.h │ │ │ ├── factory.cpp │ │ │ ├── ps2 │ │ │ │ ├── hid.h │ │ │ │ ├── keymap.h │ │ │ │ └── keymap.h.mako │ │ │ ├── spi.cpp │ │ │ ├── spi.h │ │ │ └── usb │ │ │ │ └── hid.h │ │ ├── drivers-stm32 │ │ │ ├── README.md │ │ │ ├── backup-register.h │ │ │ ├── bluepill_sch.png │ │ │ ├── board-stm32.h │ │ │ ├── factory.cpp │ │ │ └── usb │ │ │ │ ├── hid-wrapper-stm32.h │ │ │ │ ├── keyboard-stm32.h │ │ │ │ ├── mouse-absolute-stm32.h │ │ │ │ └── mouse-relative-stm32.h │ │ └── drivers │ │ │ ├── aum.h │ │ │ ├── board.h │ │ │ ├── connection.h │ │ │ ├── driver.h │ │ │ ├── factory.h │ │ │ ├── keyboard.h │ │ │ ├── mouse.h │ │ │ ├── serial.h │ │ │ ├── storage.h │ │ │ ├── tools.cpp │ │ │ ├── tools.h │ │ │ ├── usb-keymap.h │ │ │ └── usb-keymap.h.mako │ ├── patch.py │ ├── patches │ │ ├── arduino-get-plugged-endpoint.patch │ │ ├── arduino-main-no-usb.patch │ │ ├── arduino-optional-cdc.patch │ │ ├── hid-no-singletones.patch │ │ ├── hid-shut-up.patch │ │ ├── hid-win98.patch │ │ └── platformio-stm32f1-no-serial-usb.patch │ ├── platformio-avr.ini │ ├── platformio-stm32.ini │ └── src │ │ ├── main.cpp │ │ ├── outputs.h │ │ └── proto.h └── pico │ ├── .gitignore │ ├── CMakeLists.txt │ ├── Makefile │ └── src │ ├── CMakeLists.txt │ ├── main.c │ ├── ph_cmds.c │ ├── ph_cmds.h │ ├── ph_com.c │ ├── ph_com.h │ ├── ph_com_bridge.c │ ├── ph_com_bridge.h │ ├── ph_com_spi.c │ ├── ph_com_spi.h │ ├── ph_com_uart.c │ ├── ph_com_uart.h │ ├── ph_debug.c │ ├── ph_debug.h │ ├── ph_outputs.c │ ├── ph_outputs.h │ ├── ph_proto.h │ ├── ph_ps2.c │ ├── ph_ps2.h │ ├── ph_tools.h │ ├── ph_types.h │ ├── ph_usb.c │ ├── ph_usb.h │ ├── ph_usb_kbd.c │ ├── ph_usb_kbd.h │ ├── ph_usb_keymap.h │ ├── ph_usb_keymap.h.mako │ ├── ph_usb_mouse.c │ ├── ph_usb_mouse.h │ └── tusb_config.h ├── keymap.csv ├── kvmd.install ├── kvmd ├── __init__.py ├── aiogp.py ├── aiohelpers.py ├── aiomulti.py ├── aioproc.py ├── aiotools.py ├── apps │ ├── __init__.py │ ├── edidconf │ │ ├── __init__.py │ │ └── __main__.py │ ├── htpasswd │ │ ├── __init__.py │ │ └── __main__.py │ ├── ipmi │ │ ├── __init__.py │ │ ├── __main__.py │ │ ├── auth.py │ │ └── server.py │ ├── janus │ │ ├── __init__.py │ │ ├── __main__.py │ │ ├── runner.py │ │ └── stun.py │ ├── kvmd │ │ ├── __init__.py │ │ ├── __main__.py │ │ ├── api │ │ │ ├── __init__.py │ │ │ ├── atx.py │ │ │ ├── auth.py │ │ │ ├── export.py │ │ │ ├── hid.py │ │ │ ├── info.py │ │ │ ├── log.py │ │ │ ├── msd.py │ │ │ ├── redfish.py │ │ │ ├── streamer.py │ │ │ ├── switch.py │ │ │ └── ugpio.py │ │ ├── auth.py │ │ ├── info │ │ │ ├── __init__.py │ │ │ ├── auth.py │ │ │ ├── base.py │ │ │ ├── extras.py │ │ │ ├── fan.py │ │ │ ├── hw.py │ │ │ ├── meta.py │ │ │ └── system.py │ │ ├── logreader.py │ │ ├── ocr.py │ │ ├── server.py │ │ ├── snapshoter.py │ │ ├── streamer.py │ │ ├── switch │ │ │ ├── __init__.py │ │ │ ├── chain.py │ │ │ ├── device.py │ │ │ ├── lib.py │ │ │ ├── proto.py │ │ │ ├── state.py │ │ │ ├── storage.py │ │ │ └── types.py │ │ ├── sysunit.py │ │ └── ugpio.py │ ├── media │ │ ├── __init__.py │ │ ├── __main__.py │ │ └── server.py │ ├── ngxmkconf │ │ ├── __init__.py │ │ └── __main__.py │ ├── oled │ │ ├── __init__.py │ │ ├── __main__.py │ │ ├── fonts │ │ │ └── ProggySquare.ttf │ │ ├── pics │ │ │ ├── hello.ppm │ │ │ └── pikvm.ppm │ │ ├── screen.py │ │ └── sensors.py │ ├── otg │ │ ├── __init__.py │ │ ├── __main__.py │ │ └── hid │ │ │ ├── __init__.py │ │ │ ├── keyboard.py │ │ │ └── mouse.py │ ├── otgconf │ │ ├── __init__.py │ │ └── __main__.py │ ├── otgmsd │ │ ├── __init__.py │ │ └── __main__.py │ ├── otgnet │ │ ├── __init__.py │ │ ├── __main__.py │ │ └── netctl.py │ ├── pst │ │ ├── __init__.py │ │ ├── __main__.py │ │ └── server.py │ ├── pstrun │ │ ├── __init__.py │ │ └── __main__.py │ ├── swctl │ │ ├── __init__.py │ │ └── __main__.py │ ├── totp │ │ ├── __init__.py │ │ └── __main__.py │ ├── vnc │ │ ├── __init__.py │ │ ├── __main__.py │ │ ├── fonts │ │ │ └── Azbuka04.ttf │ │ ├── render.py │ │ ├── rfb │ │ │ ├── __init__.py │ │ │ ├── crypto.py │ │ │ ├── encodings.py │ │ │ ├── errors.py │ │ │ └── stream.py │ │ ├── server.py │ │ └── vncauth.py │ └── watchdog │ │ ├── __init__.py │ │ └── __main__.py ├── bitbang.py ├── clients │ ├── __init__.py │ ├── kvmd.py │ ├── pst.py │ └── streamer.py ├── edid.py ├── env.py ├── errors.py ├── fstab.py ├── helpers │ ├── __init__.py │ ├── remount │ │ ├── __init__.py │ │ └── __main__.py │ └── swapfiles │ │ ├── __init__.py │ │ └── __main__.py ├── htclient.py ├── htserver.py ├── inotify.py ├── keyboard │ ├── __init__.py │ ├── keysym.py │ ├── mappings.py │ ├── mappings.py.mako │ └── printer.py ├── libc.py ├── logging.py ├── mouse.py ├── network.py ├── plugins │ ├── __init__.py │ ├── atx │ │ ├── __init__.py │ │ ├── disabled.py │ │ └── gpio.py │ ├── auth │ │ ├── __init__.py │ │ ├── htpasswd.py │ │ ├── http.py │ │ ├── ldap.py │ │ ├── pam.py │ │ └── radius.py │ ├── hid │ │ ├── __init__.py │ │ ├── _mcu │ │ │ ├── __init__.py │ │ │ ├── gpio.py │ │ │ └── proto.py │ │ ├── bt │ │ │ ├── __init__.py │ │ │ ├── bluez.py │ │ │ ├── sdp.py │ │ │ └── server.py │ │ ├── ch9329 │ │ │ ├── __init__.py │ │ │ ├── chip.py │ │ │ ├── keyboard.py │ │ │ └── mouse.py │ │ ├── otg │ │ │ ├── __init__.py │ │ │ ├── device.py │ │ │ ├── events.py │ │ │ ├── keyboard.py │ │ │ └── mouse.py │ │ ├── serial.py │ │ └── spi.py │ ├── msd │ │ ├── __init__.py │ │ ├── disabled.py │ │ └── otg │ │ │ ├── __init__.py │ │ │ ├── drive.py │ │ │ └── storage.py │ └── ugpio │ │ ├── __init__.py │ │ ├── anelpwr.py │ │ ├── cmd.py │ │ ├── cmdret.py │ │ ├── extron.py │ │ ├── ezcoo.py │ │ ├── gpio.py │ │ ├── hidrelay.py │ │ ├── hue.py │ │ ├── ipmi.py │ │ ├── locator.py │ │ ├── noyito.py │ │ ├── otgconf.py │ │ ├── pway.py │ │ ├── pwm.py │ │ ├── servo.py │ │ ├── tesmart.py │ │ ├── wol.py │ │ └── xh_hk4401.py ├── tools.py ├── usb.py ├── validators │ ├── __init__.py │ ├── auth.py │ ├── basic.py │ ├── hid.py │ ├── hw.py │ ├── kvm.py │ ├── net.py │ ├── os.py │ ├── switch.py │ └── ugpio.py └── yamlconf │ ├── __init__.py │ ├── dumper.py │ ├── loader.py │ └── merger.py ├── quick_start.sh ├── scripts ├── kvmd ├── kvmd-bootconfig ├── kvmd-certbot ├── kvmd-gencert ├── kvmd-htpasswd ├── kvmd-media ├── kvmd-otg ├── kvmd-otgconf ├── kvmd-totp ├── kvmd-udev-hdmiusb-check ├── kvmd-udev-restart-pass └── kvmd-vnc ├── setup.py ├── supervisord.conf ├── switch ├── LICENSE ├── Makefile ├── mnt │ └── README └── switch.uf2 ├── testenv ├── Dockerfile ├── env.py ├── fakes │ ├── etc │ │ └── fstab │ ├── proc │ │ └── device-tree │ │ │ ├── model │ │ │ └── serial-number │ ├── sys │ │ ├── bus │ │ │ └── platform │ │ │ │ └── drivers │ │ │ │ └── dwc2 │ │ │ │ └── .gitignore │ │ ├── class │ │ │ ├── thermal │ │ │ │ └── thermal_zone0 │ │ │ │ │ └── temp │ │ │ └── udc │ │ │ │ └── fe980000.usb │ │ │ │ ├── device │ │ │ │ └── driver │ │ │ │ └── state │ │ └── kernel │ │ │ └── config │ │ │ └── usb_gadget │ │ │ └── kvmd │ │ │ ├── configs │ │ │ └── c.1 │ │ │ │ └── mass_storage.usb0 │ │ │ └── functions │ │ │ └── mass_storage.usb0 │ │ │ └── lun.0 │ │ │ ├── cdrom │ │ │ ├── file │ │ │ ├── forced_eject │ │ │ └── ro │ └── vcgencmd ├── js │ ├── adapter.js │ └── janus.js ├── linters │ ├── coverage.ini │ ├── eslintrc.js │ ├── flake8.ini │ ├── htmlhint.json │ ├── mypy.ini │ ├── pylint.ini │ └── vulture-wl.py ├── platform ├── requirements.txt ├── run │ └── .gitignore ├── tests │ ├── __init__.py │ ├── apps │ │ ├── __init__.py │ │ ├── htpasswd │ │ │ ├── __init__.py │ │ │ └── test_main.py │ │ └── kvmd │ │ │ ├── __init__.py │ │ │ └── test_auth.py │ ├── keyboard │ │ ├── __init__.py │ │ └── test_keymap.py │ ├── plugins │ │ ├── __init__.py │ │ └── auth │ │ │ ├── __init__.py │ │ │ ├── test_htpasswd.py │ │ │ ├── test_http.py │ │ │ └── test_pam.py │ ├── test_aiotools.py │ ├── test_logging.py │ ├── test_yamlconf.py │ ├── validators │ │ ├── __init__.py │ │ ├── test_auth.py │ │ ├── test_basic.py │ │ ├── test_hid.py │ │ ├── test_hw.py │ │ ├── test_kvm.py │ │ ├── test_net.py │ │ ├── test_os.py │ │ ├── test_switch.py │ │ └── test_ugpio.py │ └── yamlconf │ │ └── test_merger.py ├── tox.ini ├── v2-hdmi-rpi4.override.yaml ├── v2-hdmiusb-rpi4.override.yaml └── web.css └── web ├── base.pug ├── extras ├── .gitignore └── webterm │ └── terminal.svg ├── favicon.ico ├── index.html ├── index.pug ├── ipmi ├── index.html └── index.pug ├── kvm ├── index.html ├── index.pug ├── navbar-atx.pug ├── navbar-gpio.pug ├── navbar-health.pug ├── navbar-macro.pug ├── navbar-msd.pug ├── navbar-shortcuts.pug ├── navbar-switch.pug ├── navbar-system.pug ├── navbar-text.pug ├── navbar.pug ├── window-about.pug ├── window-keyboard.pug ├── window-stream.pug ├── window-switch.pug ├── window-webterm.pug └── windows.pug ├── login ├── index.html └── index.pug ├── robots.txt ├── share ├── android-chrome-192x192.png ├── apple-touch-icon.png ├── css │ ├── index │ │ └── index.css │ ├── keypad.css │ ├── kvm │ │ ├── about.css │ │ ├── hid.css │ │ ├── keyboard.css │ │ ├── msd.css │ │ ├── stream.css │ │ ├── system.css │ │ └── x-mobile.css │ ├── led.css │ ├── login │ │ └── login.css │ ├── main.css │ ├── modal.css │ ├── navbar.css │ ├── progress.css │ ├── radio.css │ ├── slider.css │ ├── start.css │ ├── switch.css │ ├── tabs.css │ ├── vars.css │ ├── window.css │ ├── x-desktop.css │ └── x-mobile.css ├── favicon-16x16.png ├── favicon-32x32.png ├── i18n │ ├── i18n_en.json │ └── i18n_zh.json ├── js │ ├── bb.js │ ├── i18n │ │ ├── i18n.js │ │ ├── jquery-3.7.1.min.js │ │ └── jquery.i18n.min.js │ ├── index │ │ └── main.js │ ├── ipmi │ │ └── main.js │ ├── keypad.js │ ├── kvm │ │ ├── atx.js │ │ ├── gpio.js │ │ ├── hid.js │ │ ├── keyboard.js │ │ ├── main.js │ │ ├── mouse.js │ │ ├── msd.js │ │ ├── ocr.js │ │ ├── paste.js │ │ ├── recorder.js │ │ ├── session.js │ │ ├── stream.js │ │ ├── stream_janus.js │ │ ├── stream_media.js │ │ ├── stream_mjpeg.js │ │ └── switch.js │ ├── login │ │ └── main.js │ ├── tools.js │ ├── vnc │ │ └── main.js │ └── wm.js ├── png │ └── blank-stream.png ├── safari-pinned-tab.svg ├── site.webmanifest └── svg │ ├── favicon.svg │ ├── info.svg │ ├── ipmi.svg │ ├── kvm.svg │ ├── led-atx-hdd.svg │ ├── led-atx-power.svg │ ├── led-beacon.svg │ ├── led-circle.svg │ ├── led-fan.svg │ ├── led-gear.svg │ ├── led-hid-keyboard.svg │ ├── led-hid-mouse.svg │ ├── led-link.svg │ ├── led-loading.svg │ ├── led-msd.svg │ ├── led-overheating.svg │ ├── led-square.svg │ ├── led-undervoltage.svg │ ├── led-usb.svg │ ├── led-video.svg │ ├── logo.svg │ ├── logout.svg │ ├── select-arrow-inactive.svg │ ├── select-arrow-intensive.svg │ ├── select-arrow-normal.svg │ ├── stream-mouse-cursor.svg │ ├── vnc.svg │ └── warning.svg ├── start.pug └── vnc ├── index.html └── index.pug /.bumpversion.cfg: -------------------------------------------------------------------------------- 1 | [bumpversion] 2 | commit = True 3 | tag = True 4 | current_version = 4.49 5 | parse = (?P\d+)\.(?P\d+)(\.(?P\d+)(\-(?P[a-z]+))?)? 6 | serialize = 7 | {major}.{minor} 8 | 9 | [bumpversion:file:kvmd/__init__.py] 10 | search = __version__ = "{current_version}" 11 | replace = __version__ = "{new_version}" 12 | 13 | [bumpversion:file:setup.py] 14 | search = version="{current_version}" 15 | replace = version="{new_version}" 16 | 17 | [bumpversion:file:PKGBUILD] 18 | search = pkgver={current_version} 19 | replace = pkgver={new_version} 20 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | /pkg/ 2 | /src/ 3 | /site/ 4 | /dist/ 5 | /kvmd.egg-info/ 6 | /testenv/run/ 7 | /testenv/.tox/ 8 | /testenv/.mypy_cache/ 9 | /testenv/.ssl/ 10 | /hid/arduino/.pio/ 11 | /hid/arduino/.platformio/ 12 | /hid/pico/.pico-sdk.tmp/ 13 | /hid/pico/.pico-sdk/ 14 | /hid/pico/.tinyusb.tmp/ 15 | /hid/pico/.tinyusb/ 16 | /hid/pico/.build/ 17 | /hid/pico/*.uf2 18 | /.git/ 19 | /v*.tar.gz 20 | /*.pkg.tar.xz 21 | /*.pkg.tar.zst 22 | /*.egg-info 23 | /*kvmd-*.tar.gz 24 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_file = lf 5 | indent_style = tab 6 | indent_size = 4 7 | 8 | [*.{py,yaml}] 9 | indent_style = space 10 | indent_size = 4 11 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | custom: https://afdian.com/a/silentwind 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /pkg/ 2 | /src/**/*.img 3 | /src/tmp 4 | /site/ 5 | /dist/ 6 | /kvmd.egg-info/ 7 | /config.mk 8 | /testenv/.tox/ 9 | /testenv/.mypy_cache/ 10 | /testenv/.coverage* 11 | /testenv/run/*.sock 12 | /testenv/run/*.pid 13 | /testenv/.ssl/ 14 | /v*.tar.gz 15 | /*.pkg.tar.xz 16 | /*.pkg.tar.zst 17 | /*.egg-info 18 | /*kvmd-*.tar.gz 19 | *.pyc 20 | *.swp 21 | /venv/ 22 | .vscode/settings.j/son 23 | kvmd_config/ 24 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cmake.ignoreCMakeListsMissing": true, 3 | "makefile.configureOnOpen": false 4 | } -------------------------------------------------------------------------------- /build/cargo_config: -------------------------------------------------------------------------------- 1 | [source.crates-io] 2 | replace-with = 'ustc' 3 | 4 | [source.ustc] 5 | registry = "sparse+https://mirrors.ustc.edu.cn/crates.io-index/" -------------------------------------------------------------------------------- /build/platform/chainedbox: -------------------------------------------------------------------------------- 1 | PIKVM_MODEL=v2_model 2 | PIKVM_VIDEO=usb_video 3 | PIKVM_BOARD=chainedbox -------------------------------------------------------------------------------- /build/platform/cumebox2: -------------------------------------------------------------------------------- 1 | PIKVM_MODEL=v2_model 2 | PIKVM_VIDEO=usb_video 3 | PIKVM_BOARD=cumebox2 -------------------------------------------------------------------------------- /build/platform/docker: -------------------------------------------------------------------------------- 1 | PIKVM_MODEL=docker_model 2 | PIKVM_VIDEO=docker_video 3 | PIKVM_BOARD=docker_board 4 | -------------------------------------------------------------------------------- /build/platform/e900v22c: -------------------------------------------------------------------------------- 1 | PIKVM_MODEL=v2_model 2 | PIKVM_VIDEO=usb_video 3 | PIKVM_BOARD=e900v22c -------------------------------------------------------------------------------- /build/platform/octopus-flanet: -------------------------------------------------------------------------------- 1 | PIKVM_MODEL=v2_model 2 | PIKVM_VIDEO=usb_video 3 | PIKVM_BOARD=octopus-flanet -------------------------------------------------------------------------------- /build/platform/onecloud: -------------------------------------------------------------------------------- 1 | PIKVM_MODEL=v2_model 2 | PIKVM_VIDEO=usb_video 3 | PIKVM_BOARD=onecloud 4 | -------------------------------------------------------------------------------- /build/platform/vm: -------------------------------------------------------------------------------- 1 | PIKVM_MODEL=v2_model 2 | PIKVM_VIDEO=usb_video 3 | PIKVM_BOARD=vm -------------------------------------------------------------------------------- /build/scripts/generate-random-mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 为onecloud平台生成随机MAC地址的一次性脚本 4 | # 此脚本在首次开机时执行,为eth0网卡生成并应用随机MAC地址 5 | 6 | set -e 7 | 8 | NETWORK_CONFIG="/etc/systemd/network/99-eth0.network" 9 | LOCK_FILE="/var/lib/kvmd/.mac-generated" 10 | 11 | # 检查是否已经执行过 12 | if [ -f "$LOCK_FILE" ]; then 13 | echo "MAC地址已经生成过,跳过执行" 14 | exit 0 15 | fi 16 | 17 | # 生成随机MAC地址 (使用本地管理的MAC地址前缀) 18 | generate_random_mac() { 19 | # 使用本地管理的MAC地址前缀 (第二位设为2、6、A、E中的一个) 20 | # 这样可以避免与真实硬件MAC地址冲突 21 | printf "02:%02x:%02x:%02x:%02x:%02x\n" \ 22 | $((RANDOM % 256)) \ 23 | $((RANDOM % 256)) \ 24 | $((RANDOM % 256)) \ 25 | $((RANDOM % 256)) \ 26 | $((RANDOM % 256)) 27 | } 28 | 29 | echo "正在为onecloud生成随机MAC地址..." 30 | 31 | # 生成新的MAC地址 32 | NEW_MAC=$(generate_random_mac) 33 | echo "生成的MAC地址: $NEW_MAC" 34 | 35 | # 备份原配置文件 36 | if [ -f "$NETWORK_CONFIG" ]; then 37 | cp "$NETWORK_CONFIG" "${NETWORK_CONFIG}.backup" 38 | fi 39 | 40 | # 更新网络配置文件 41 | cat > "$NETWORK_CONFIG" << EOF 42 | [Match] 43 | Name=eth0 44 | 45 | [Network] 46 | DHCP=yes 47 | 48 | [Link] 49 | MACAddress=$NEW_MAC 50 | EOF 51 | 52 | echo "已更新网络配置文件: $NETWORK_CONFIG" 53 | 54 | # 创建锁定文件,防止重复执行 55 | mkdir -p "$(dirname "$LOCK_FILE")" 56 | echo "MAC地址生成时间: $(date)" > "$LOCK_FILE" 57 | 58 | # 禁用此服务,确保只运行一次 59 | systemctl disable kvmd-generate-mac.service 60 | 61 | echo "随机MAC地址生成完成: $NEW_MAC" 62 | echo "服务已自动禁用,下次开机不会再执行" 63 | 64 | exit 0 -------------------------------------------------------------------------------- /build/scripts/kvmd-firstrun.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # KVMD首次运行初始化脚本 4 | # 在首次开机时执行KVMD服务启动前的必要初始化操作 5 | 6 | set -e 7 | 8 | LOCK_FILE="/var/lib/kvmd/.kvmd-firstrun-completed" 9 | 10 | # 检查是否已经执行过 11 | [ -f "$LOCK_FILE" ] && { echo "[KVMD-FirstRun] 初始化已完成,跳过执行"; exit 0; } 12 | 13 | echo "[KVMD-FirstRun] 开始KVMD首次运行初始化..." 14 | 15 | # 1. 生成KVMD主证书 16 | echo "[KVMD-FirstRun] 生成KVMD主证书..." 17 | kvmd-gencert --do-the-thing 18 | 19 | # 2. 生成VNC证书 20 | echo "[KVMD-FirstRun] 生成VNC证书..." 21 | kvmd-gencert --do-the-thing --vnc 22 | 23 | # 3. 生成nginx配置文件 24 | echo "[KVMD-FirstRun] 生成nginx配置文件..." 25 | kvmd-nginx-mkconf /etc/kvmd/nginx/nginx.conf.mako /etc/kvmd/nginx/nginx.conf || echo "[KVMD-FirstRun] 警告: nginx配置生成失败" 26 | 27 | # 创建锁定文件 28 | mkdir -p "$(dirname "$LOCK_FILE")" 29 | echo "KVMD首次运行初始化完成 - $(date)" > "$LOCK_FILE" 30 | 31 | # 禁用服务 32 | systemctl disable kvmd-firstrun.service || echo "[KVMD-FirstRun] 警告: 服务禁用失败" 33 | 34 | echo "[KVMD-FirstRun] 初始化完成!" -------------------------------------------------------------------------------- /build/services/kvmd-firstrun.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=KVMD First Run Initialization (One-time) 3 | Documentation=https://github.com/your-repo/One-KVM 4 | Before=kvmd.service 5 | Before=kvmd-nginx.service 6 | Before=kvmd-otg.service 7 | Before=kvmd-vnc.service 8 | Before=kvmd-ipmi.service 9 | Before=kvmd-webterm.service 10 | Before=kvmd-janus.service 11 | Before=kvmd-media.service 12 | After=local-fs.target 13 | After=network.target 14 | Wants=local-fs.target 15 | ConditionPathExists=!/var/lib/kvmd/.kvmd-firstrun-completed 16 | 17 | [Service] 18 | Type=oneshot 19 | ExecStart=/usr/bin/kvmd-firstrun.sh 20 | RemainAfterExit=yes 21 | StandardOutput=journal 22 | StandardError=journal 23 | TimeoutStartSec=300 24 | 25 | [Install] 26 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /build/services/kvmd-generate-mac.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Generate Random MAC Address for OneCloud (One-time) 3 | Documentation=https://github.com/your-repo/One-KVM 4 | Before=systemd-networkd.service 5 | Before=network-pre.target 6 | Wants=network-pre.target 7 | After=local-fs.target 8 | ConditionPathExists=!/var/lib/kvmd/.mac-generated 9 | 10 | [Service] 11 | Type=oneshot 12 | ExecStart=/usr/local/bin/generate-random-mac.sh 13 | RemainAfterExit=yes 14 | StandardOutput=journal 15 | StandardError=journal 16 | 17 | [Install] 18 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /configs/hw_info/model: -------------------------------------------------------------------------------- 1 | Docker 2 | -------------------------------------------------------------------------------- /configs/hw_info/serial-number: -------------------------------------------------------------------------------- 1 | docker1000000000 -------------------------------------------------------------------------------- /configs/janus/janus.jcfg: -------------------------------------------------------------------------------- 1 | general: { 2 | debug_level = 4 3 | } 4 | nat: { 5 | nice_debug = false 6 | ignore_mdns = true 7 | } 8 | media: { 9 | ipv6 = true 10 | ipv6_linklocal = true 11 | min_nack_queue = 2000 12 | rtp_port_range = "20000-40000" 13 | no_media_timer = 0 14 | slowlink_threshold = 10 15 | twcc_period = 100 16 | dtls_timeout = 1000 17 | nack_optimizations = true 18 | } 19 | -------------------------------------------------------------------------------- /configs/janus/janus.plugin.ustreamer.jcfg: -------------------------------------------------------------------------------- 1 | video: { 2 | sink = "kvmd::ustreamer::h264" 3 | } 4 | acap: { 5 | device = "hw:0" 6 | tc358743 = "/dev/video0" 7 | } 8 | -------------------------------------------------------------------------------- /configs/janus/janus.transport.websockets.jcfg: -------------------------------------------------------------------------------- 1 | general: { 2 | ws = true 3 | ws_unix = "/run/kvmd/janus-ws.sock" 4 | } 5 | -------------------------------------------------------------------------------- /configs/kvmd/atx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # ========================================================================== # 3 | # # 4 | # KVMD - The main PiKVM daemon. # 5 | # # 6 | # Copyright (C) 2023-2025 SilentWind # 7 | # # 8 | # This program is free software: you can redistribute it and/or modify # 9 | # it under the terms of the GNU General Public License as published by # 10 | # the Free Software Foundation, either version 3 of the License, or # 11 | # (at your option) any later version. # 12 | # # 13 | # This program is distributed in the hope that it will be useful, # 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 16 | # GNU General Public License for more details. # 17 | # # 18 | # You should have received a copy of the GNU General Public License # 19 | # along with this program. If not, see . # 20 | # # 21 | # ========================================================================== # 22 | 23 | echo $ATX 24 | case $ATX in 25 | GPIO) 26 | sudo /etc/kvmd/custom_atx/gpio.sh $1 27 | ;; 28 | USBRELAY_HID) 29 | sudo /etc/kvmd/custom_atx/usbrelay_hid.sh $1 30 | ;; 31 | *) 32 | echo "No thing." 33 | exit -1 34 | esac -------------------------------------------------------------------------------- /configs/kvmd/auth.yaml: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /configs/kvmd/htpasswd: -------------------------------------------------------------------------------- 1 | admin:$apr1$.6mu9N8n$xOuGesr4JZZkdiZo/j318. 2 | -------------------------------------------------------------------------------- /configs/kvmd/ipmipasswd: -------------------------------------------------------------------------------- 1 | # This file describes the credentials for IPMI users. The first pair separated by colon 2 | # is the login and password with which the user can access to IPMI. The second pair 3 | # is the name and password with which the user can access to KVMD API. The arrow is used 4 | # as a separator and shows the direction of user registration in the system. 5 | # 6 | # WARNING! IPMI protocol is completely unsafe by design. In short, the authentication 7 | # process for IPMI 2.0 mandates that the server send a salted SHA1 or MD5 hash of the 8 | # requested user's password to the client, prior to the client authenticating. Never use 9 | # the same passwords for KVMD and IPMI users. This default configuration is shown here 10 | # for example only. 11 | # 12 | # And even better not to use IPMI. Instead, you can directly use KVMD API via curl. 13 | 14 | admin:admin -> admin:admin 15 | -------------------------------------------------------------------------------- /configs/kvmd/kvm_input.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Written by @srepac FILENAME: input.sh 3 | # Input switcher script for use with KVM switches that use CTRL+CTRL+# 4 | # ... pass in # into the script 5 | # 6 | usage() { 7 | echo "usage: $0 <#> where # is the input number on the KVM switch" 8 | exit 1 9 | } 10 | password=admin 11 | 12 | #HOTKEY="ScrollLock" 13 | HOTKEY="ControlLeft" 14 | 15 | if [[ "$1" == "" ]]; then 16 | usage 17 | else 18 | NUM="$1" 19 | fi 20 | 21 | if [[ "$2" == "" ]]; then 22 | IP="localhost" 23 | else 24 | IP="$2" 25 | fi 26 | 27 | OSD=$( echo $HOTKEY | sed -e 's/ControlLeft/CTRL/g' ) 28 | echo "Sending $OSD + $OSD + $NUM to $IP" 29 | 30 | curl -X POST -k -u admin:$password "https://$IP/api/hid/events/send_key?key=$HOTKEY" 2> /dev/null 31 | curl -X POST -k -u admin:$password "https://$IP/api/hid/events/send_key?key=$HOTKEY" 2> /dev/null 32 | curl -X POST -k -u admin:$password "https://$IP/api/hid/events/send_key?key=Digit${NUM}" 2> /dev/null -------------------------------------------------------------------------------- /configs/kvmd/logging.yaml: -------------------------------------------------------------------------------- 1 | version: 1 2 | disable_existing_loggers: false 3 | 4 | formatters: 5 | console: 6 | (): logging.Formatter 7 | style: "{" 8 | format: "{name:30.30} {levelname:>7} --- {message}" 9 | 10 | handlers: 11 | console: 12 | level: DEBUG 13 | class: logging.StreamHandler 14 | stream: ext://sys.stderr 15 | formatter: console 16 | 17 | root: 18 | level: INFO 19 | handlers: 20 | - console 21 | -------------------------------------------------------------------------------- /configs/kvmd/main.yaml: -------------------------------------------------------------------------------- 1 | # Don't touch this file otherwise your device may stop working. 2 | # Use override.yaml to modify required settings. 3 | # You can find a working configuration in /usr/share/kvmd/configs.default/kvmd. 4 | 5 | override: !include [override.d, override.yaml] 6 | 7 | logging: !include logging.yaml 8 | 9 | kvmd: 10 | auth: !include auth.yaml 11 | 12 | hid: 13 | type: otg 14 | 15 | atx: 16 | type: gpio 17 | 18 | msd: 19 | type: disabled 20 | 21 | streamer: 22 | quality: 0 23 | resolution: 24 | default: 1920x1080 25 | available: 26 | - 1920x1080 27 | - 1600x1200 28 | - 1360x768 29 | - 1280x1024 30 | - 1280x960 31 | - 1280x720 32 | - 1024x768 33 | - 800x600 34 | - 720x576 35 | - 720x480 36 | - 640x480 37 | cmd: 38 | - "/usr/bin/ustreamer" 39 | - "--device=/dev/kvmd-video" 40 | - "--persistent" 41 | - "--format=mjpeg" 42 | - "--resolution={resolution}" 43 | - "--desired-fps={desired_fps}" 44 | - "--drop-same-frames=30" 45 | - "--unix={unix}" 46 | - "--unix-rm" 47 | - "--unix-mode=0660" 48 | - "--exit-on-parent-death" 49 | - "--process-name-prefix={process_name_prefix}" 50 | - "--notify-parent" 51 | - "--no-log-colors" 52 | - "--jpeg-sink=kvmd::ustreamer::jpeg" 53 | - "--jpeg-sink-mode=0660" 54 | 55 | 56 | vnc: 57 | memsink: 58 | jpeg: 59 | sink: "kvmd::ustreamer::jpeg" 60 | -------------------------------------------------------------------------------- /configs/kvmd/meta.yaml: -------------------------------------------------------------------------------- 1 | # You can write down any information and it will be available 2 | # at the address /api/info (if you use default nginx config). 3 | # If server.host (str) will be defined then this value 4 | # will be displayed in the web interface. 5 | 6 | server: 7 | host: localhost.localdomain 8 | 9 | kvm: { 10 | base_on: PiKVM, 11 | app_name: One-KVM, 12 | main_version: 241204, 13 | author: SilentWind 14 | } 15 | -------------------------------------------------------------------------------- /configs/kvmd/supervisord.conf: -------------------------------------------------------------------------------- 1 | [unix_http_server] 2 | file=/tmp/supervisor.sock 3 | 4 | [supervisord] 5 | nodaemon=true 6 | user=root 7 | 8 | [rpcinterface:supervisor] 9 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface 10 | 11 | [supervisorctl] 12 | serverurl=unix:///tmp/supervisor.sock 13 | 14 | [program:kvmd] 15 | command=python -m kvmd.apps.kvmd --run 16 | directory=/ 17 | autostart=true 18 | autorestart=true 19 | priority=10 20 | stopasgroup=true 21 | stdout_logfile=/dev/stdout 22 | stdout_logfile_maxbytes = 0 23 | redirect_stderr=true 24 | 25 | [program:kvmd-janus] 26 | command=python -m kvmd.apps.janus --run 27 | autostart=true 28 | autorestart=true 29 | priority=13 30 | stopasgroup=true 31 | stdout_logfile=/dev/stdout 32 | stdout_logfile_maxbytes = 0 33 | redirect_stderr=true 34 | 35 | [program:kvmd-media] 36 | command=python -m kvmd.apps.media --run 37 | autostart=true 38 | autorestart=true 39 | priority=13 40 | stopasgroup=true 41 | stdout_logfile=/dev/stdout 42 | stdout_logfile_maxbytes = 0 43 | redirect_stderr=true 44 | 45 | [program:kvmd-nginx] 46 | command=nginx -c /etc/kvmd/nginx/nginx.conf -g 'daemon off;user root; error_log stderr;' 47 | autostart=true 48 | autorestart=true 49 | startsecs=10 50 | priority=100 51 | stopasgroup=true 52 | stdout_logfile=/dev/stdout 53 | stdout_logfile_maxbytes = 0 54 | redirect_stderr=true 55 | 56 | [program:clean_when_exit] 57 | command=/etc/kvmd/clean_when_exit.sh 58 | autostart=true 59 | autorestart=true 60 | startsecs=10 61 | priority=200 62 | stopasgroup=true 63 | stdout_logfile=/dev/stdout 64 | stdout_logfile_maxbytes = 0 65 | redirect_stderr=true 66 | 67 | -------------------------------------------------------------------------------- /configs/kvmd/totp.secret: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mofeng-git/One-KVM/10fb78abe6117894556573acd661c266df74efde/configs/kvmd/totp.secret -------------------------------------------------------------------------------- /configs/kvmd/vncpasswd: -------------------------------------------------------------------------------- 1 | # This file describes the credentials for VNCAuth. The left part before arrow is a passphrase 2 | # for VNCAuth. The right part is username and password with which the user can access to KVMD API. 3 | # The arrow is used as a separator and shows the relationship of user registrations on the system. 4 | # 5 | # Never use the same passwords for VNC and IPMI users. This default configuration is shown here 6 | # for example only. 7 | # 8 | # If this file does not contain any entries, VNCAuth will be disabled and you will only be able 9 | # to login in using your KVMD username and password using VeNCrypt methods. 10 | 11 | # pa$$phr@se -> admin:password 12 | admin -> admin:admin 13 | -------------------------------------------------------------------------------- /configs/kvmd/web.css: -------------------------------------------------------------------------------- 1 | /* Here you can customize the Web UI */ 2 | -------------------------------------------------------------------------------- /configs/nginx/certbot.ctx-server.conf: -------------------------------------------------------------------------------- 1 | location /.well-known/acme-challenge { 2 | root /run/kvmd-certbot/webroot; 3 | include /etc/kvmd/nginx/loc-nocache.conf; 4 | auth_request off; 5 | } 6 | -------------------------------------------------------------------------------- /configs/nginx/kvmd.ctx-http.conf: -------------------------------------------------------------------------------- 1 | upstream kvmd { 2 | server unix:/run/kvmd/kvmd.sock fail_timeout=0s max_fails=0; 3 | } 4 | 5 | upstream ustreamer { 6 | server unix:/run/kvmd/ustreamer.sock fail_timeout=0s max_fails=0; 7 | } 8 | -------------------------------------------------------------------------------- /configs/nginx/loc-bigpost.conf: -------------------------------------------------------------------------------- 1 | limit_rate 6250k; 2 | limit_rate_after 50k; 3 | client_max_body_size 0; 4 | proxy_request_buffering off; 5 | -------------------------------------------------------------------------------- /configs/nginx/loc-login.conf: -------------------------------------------------------------------------------- 1 | error_page 401 = @login; 2 | error_page 403 = @login; 3 | -------------------------------------------------------------------------------- /configs/nginx/loc-nobuffering.conf: -------------------------------------------------------------------------------- 1 | postpone_output 0; 2 | proxy_buffering off; 3 | proxy_ignore_headers X-Accel-Buffering; 4 | -------------------------------------------------------------------------------- /configs/nginx/loc-nocache.conf: -------------------------------------------------------------------------------- 1 | add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, pre-check=0, post-check=0, max-age=0"; 2 | expires -1; 3 | -------------------------------------------------------------------------------- /configs/nginx/loc-proxy.conf: -------------------------------------------------------------------------------- 1 | proxy_set_header Host $host; 2 | proxy_set_header X-Real-IP $remote_addr; 3 | proxy_set_header X-Scheme $scheme; 4 | proxy_set_header X-Forwarded-Proto $scheme; 5 | proxy_set_header X-Forwarded-Port $server_port; 6 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 7 | -------------------------------------------------------------------------------- /configs/nginx/loc-websocket.conf: -------------------------------------------------------------------------------- 1 | proxy_set_header Upgrade $http_upgrade; 2 | proxy_set_header Connection "upgrade"; 3 | proxy_connect_timeout 7d; 4 | proxy_send_timeout 7d; 5 | proxy_read_timeout 7d; 6 | -------------------------------------------------------------------------------- /configs/nginx/ssl.conf: -------------------------------------------------------------------------------- 1 | ssl_protocols TLSv1.3 TLSv1.2 TLSv1.1 TLSv1; 2 | ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; 3 | ssl_certificate /etc/kvmd/nginx/ssl/server.crt; 4 | ssl_certificate_key /etc/kvmd/nginx/ssl/server.key; 5 | add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; 6 | -------------------------------------------------------------------------------- /configs/os/boot-config/v0-hdmi-rpi2.txt: -------------------------------------------------------------------------------- 1 | # See /boot/overlays/README for all available options 2 | initramfs initramfs-linux.img followkernel 3 | 4 | hdmi_force_hotplug=1 5 | gpu_mem=128 6 | enable_uart=1 7 | dtoverlay=tc358743,i2c_pins_28_29=1 8 | -------------------------------------------------------------------------------- /configs/os/boot-config/v0-hdmi-rpi3.txt: -------------------------------------------------------------------------------- 1 | # See /boot/overlays/README for all available options 2 | initramfs initramfs-linux.img followkernel 3 | 4 | hdmi_force_hotplug=1 5 | gpu_mem=128 6 | enable_uart=1 7 | dtoverlay=tc358743 8 | dtoverlay=disable-bt 9 | -------------------------------------------------------------------------------- /configs/os/boot-config/v0-hdmi-zero2w.txt: -------------------------------------------------------------------------------- 1 | # See /boot/overlays/README for all available options 2 | initramfs initramfs-linux.img followkernel 3 | 4 | hdmi_force_hotplug=1 5 | gpu_mem=96 6 | enable_uart=1 7 | dtoverlay=tc358743,i2c_pins_28_29=1 8 | dtoverlay=disable-bt 9 | -------------------------------------------------------------------------------- /configs/os/boot-config/v0-hdmiusb-rpi2.txt: -------------------------------------------------------------------------------- 1 | # See /boot/overlays/README for all available options 2 | initramfs initramfs-linux.img followkernel 3 | 4 | hdmi_force_hotplug=1 5 | gpu_mem=16 6 | enable_uart=1 7 | -------------------------------------------------------------------------------- /configs/os/boot-config/v0-hdmiusb-rpi3.txt: -------------------------------------------------------------------------------- 1 | # See /boot/overlays/README for all available options 2 | initramfs initramfs-linux.img followkernel 3 | 4 | hdmi_force_hotplug=1 5 | gpu_mem=16 6 | enable_uart=1 7 | dtoverlay=disable-bt 8 | -------------------------------------------------------------------------------- /configs/os/boot-config/v0-hdmiusb-zero2w.txt: -------------------------------------------------------------------------------- 1 | # See /boot/overlays/README for all available options 2 | initramfs initramfs-linux.img followkernel 3 | 4 | hdmi_force_hotplug=1 5 | gpu_mem=16 6 | enable_uart=1 7 | dtoverlay=disable-bt 8 | -------------------------------------------------------------------------------- /configs/os/boot-config/v1-hdmi-rpi2.txt: -------------------------------------------------------------------------------- 1 | # See /boot/overlays/README for all available options 2 | initramfs initramfs-linux.img followkernel 3 | 4 | hdmi_force_hotplug=1 5 | gpu_mem=128 6 | enable_uart=1 7 | dtoverlay=tc358743,i2c_pins_28_29=1 8 | dtoverlay=spi0-1cs 9 | -------------------------------------------------------------------------------- /configs/os/boot-config/v1-hdmi-rpi3.txt: -------------------------------------------------------------------------------- 1 | # See /boot/overlays/README for all available options 2 | initramfs initramfs-linux.img followkernel 3 | 4 | hdmi_force_hotplug=1 5 | gpu_mem=128 6 | enable_uart=1 7 | dtoverlay=tc358743 8 | dtoverlay=disable-bt 9 | dtoverlay=spi0-1cs 10 | -------------------------------------------------------------------------------- /configs/os/boot-config/v1-hdmi-zero2w.txt: -------------------------------------------------------------------------------- 1 | # See /boot/overlays/README for all available options 2 | initramfs initramfs-linux.img followkernel 3 | 4 | hdmi_force_hotplug=1 5 | gpu_mem=96 6 | enable_uart=1 7 | dtoverlay=tc358743,i2c_pins_28_29=1 8 | dtoverlay=disable-bt 9 | dtoverlay=spi0-1cs 10 | -------------------------------------------------------------------------------- /configs/os/boot-config/v1-hdmiusb-rpi2.txt: -------------------------------------------------------------------------------- 1 | # See /boot/overlays/README for all available options 2 | initramfs initramfs-linux.img followkernel 3 | 4 | hdmi_force_hotplug=1 5 | gpu_mem=16 6 | enable_uart=1 7 | dtoverlay=spi0-1cs 8 | -------------------------------------------------------------------------------- /configs/os/boot-config/v1-hdmiusb-rpi3.txt: -------------------------------------------------------------------------------- 1 | # See /boot/overlays/README for all available options 2 | initramfs initramfs-linux.img followkernel 3 | 4 | hdmi_force_hotplug=1 5 | gpu_mem=16 6 | enable_uart=1 7 | dtoverlay=disable-bt 8 | dtoverlay=spi0-1cs 9 | -------------------------------------------------------------------------------- /configs/os/boot-config/v1-hdmiusb-zero2w.txt: -------------------------------------------------------------------------------- 1 | # See /boot/overlays/README for all available options 2 | initramfs initramfs-linux.img followkernel 3 | 4 | hdmi_force_hotplug=1 5 | gpu_mem=16 6 | enable_uart=1 7 | dtoverlay=disable-bt 8 | dtoverlay=spi0-1cs 9 | -------------------------------------------------------------------------------- /configs/os/boot-config/v2-hdmi-rpi3.txt: -------------------------------------------------------------------------------- 1 | # See /boot/overlays/README for all available options 2 | initramfs initramfs-linux.img followkernel 3 | 4 | hdmi_force_hotplug=1 5 | gpu_mem=128 6 | enable_uart=1 7 | dtoverlay=tc358743 8 | dtoverlay=disable-bt 9 | dtoverlay=dwc2,dr_mode=peripheral 10 | -------------------------------------------------------------------------------- /configs/os/boot-config/v2-hdmi-rpi4.txt: -------------------------------------------------------------------------------- 1 | # See /boot/overlays/README for all available options 2 | initramfs initramfs-linux.img followkernel 3 | 4 | hdmi_force_hotplug=1 5 | gpu_mem=128 6 | enable_uart=1 7 | dtoverlay=tc358743 8 | dtoverlay=disable-bt 9 | dtoverlay=dwc2,dr_mode=peripheral 10 | -------------------------------------------------------------------------------- /configs/os/boot-config/v2-hdmi-zero2w.txt: -------------------------------------------------------------------------------- 1 | # See /boot/overlays/README for all available options 2 | initramfs initramfs-linux.img followkernel 3 | 4 | hdmi_force_hotplug=1 5 | gpu_mem=96 6 | enable_uart=1 7 | dtoverlay=tc358743,i2c_pins_28_29=1 8 | dtoverlay=disable-bt 9 | dtoverlay=dwc2,dr_mode=peripheral 10 | -------------------------------------------------------------------------------- /configs/os/boot-config/v2-hdmiusb-rpi4.txt: -------------------------------------------------------------------------------- 1 | # See /boot/overlays/README for all available options 2 | initramfs initramfs-linux.img followkernel 3 | 4 | hdmi_force_hotplug=1 5 | gpu_mem=16 6 | enable_uart=1 7 | dtoverlay=disable-bt 8 | dtoverlay=dwc2,dr_mode=peripheral 9 | -------------------------------------------------------------------------------- /configs/os/boot-config/v3-hdmi-rpi4.txt: -------------------------------------------------------------------------------- 1 | # See /boot/overlays/README for all available options 2 | initramfs initramfs-linux.img followkernel 3 | 4 | hdmi_force_hotplug=1 5 | gpu_mem=128 6 | enable_uart=1 7 | dtoverlay=tc358743 8 | dtoverlay=disable-bt 9 | dtoverlay=dwc2,dr_mode=peripheral 10 | dtparam=act_led_gpio=13 11 | 12 | # HDMI audio capture 13 | dtoverlay=tc358743-audio 14 | 15 | # SPI (AUM) 16 | dtoverlay=spi0-1cs 17 | 18 | # I2C (display) 19 | dtparam=i2c_arm=on 20 | 21 | # Clock 22 | dtoverlay=i2c-rtc,pcf8563,wakeup-source 23 | -------------------------------------------------------------------------------- /configs/os/boot-config/v4mini-hdmi-rpi4.txt: -------------------------------------------------------------------------------- 1 | # PiKVM 2 | # See /boot/overlays/README for all available options 3 | initramfs initramfs-linux.img followkernel 4 | 5 | hdmi_force_hotplug=1 6 | gpu_mem=128 7 | enable_uart=1 8 | dtoverlay=disable-bt 9 | 10 | # USB emulation 11 | dtoverlay=dwc2,dr_mode=peripheral 12 | 13 | # Video and audio 14 | dtoverlay=tc358743,4lane=1 15 | dtoverlay=tc358743-audio 16 | 17 | # I2C (display) 18 | dtparam=i2c_arm=on 19 | 20 | # Clock 21 | dtoverlay=i2c-rtc,pcf8563,wakeup-source 22 | -------------------------------------------------------------------------------- /configs/os/boot-config/v4plus-hdmi-rpi4.txt: -------------------------------------------------------------------------------- 1 | # PiKVM 2 | # See /boot/overlays/README for all available options 3 | initramfs initramfs-linux.img followkernel 4 | 5 | hdmi_force_hotplug=1 6 | gpu_mem=128 7 | enable_uart=1 8 | dtoverlay=disable-bt 9 | 10 | # USB emulation 11 | dtoverlay=dwc2,dr_mode=peripheral 12 | 13 | # Video and audio 14 | dtoverlay=tc358743,4lane=1 15 | dtoverlay=tc358743-audio 16 | 17 | # Passthrough 18 | dtoverlay=vc4-kms-v3d 19 | disable_overscan=1 20 | 21 | # I2C (display) 22 | dtparam=i2c_arm=on 23 | 24 | # Clock 25 | dtoverlay=i2c-rtc,pcf8563,wakeup-source 26 | 27 | # Passthrough 28 | dtoverlay=vc4-kms-v3d 29 | disable_overscan=1 30 | -------------------------------------------------------------------------------- /configs/os/cmdline/v0-hdmi-rpi2.sed: -------------------------------------------------------------------------------- 1 | s/console=ttyAMA0\,115200//g 2 | s/kgdboc=ttyAMA0\,115200//g 3 | s/console=serial0\,115200//g 4 | s/kgdboc=serial0\,115200//g 5 | s/rootwait/rootwait cma=128M/g 6 | -------------------------------------------------------------------------------- /configs/os/cmdline/v0-hdmi-rpi3.sed: -------------------------------------------------------------------------------- 1 | s/console=ttyAMA0\,115200//g 2 | s/kgdboc=ttyAMA0\,115200//g 3 | s/console=serial0\,115200//g 4 | s/kgdboc=serial0\,115200//g 5 | s/rootwait/rootwait cma=128M/g 6 | -------------------------------------------------------------------------------- /configs/os/cmdline/v0-hdmi-zero2w.sed: -------------------------------------------------------------------------------- 1 | s/console=ttyAMA0\,115200//g 2 | s/kgdboc=ttyAMA0\,115200//g 3 | s/console=serial0\,115200//g 4 | s/kgdboc=serial0\,115200//g 5 | s/rootwait/rootwait cma=96M/g 6 | -------------------------------------------------------------------------------- /configs/os/cmdline/v0-hdmiusb-rpi2.sed: -------------------------------------------------------------------------------- 1 | s/console=ttyAMA0\,115200//g 2 | s/kgdboc=ttyAMA0\,115200//g 3 | s/console=serial0\,115200//g 4 | s/kgdboc=serial0\,115200//g 5 | -------------------------------------------------------------------------------- /configs/os/cmdline/v0-hdmiusb-rpi3.sed: -------------------------------------------------------------------------------- 1 | s/console=ttyAMA0\,115200//g 2 | s/kgdboc=ttyAMA0\,115200//g 3 | s/console=serial0\,115200//g 4 | s/kgdboc=serial0\,115200//g 5 | -------------------------------------------------------------------------------- /configs/os/cmdline/v0-hdmiusb-zero2w.sed: -------------------------------------------------------------------------------- 1 | s/console=ttyAMA0\,115200//g 2 | s/kgdboc=ttyAMA0\,115200//g 3 | s/console=serial0\,115200//g 4 | s/kgdboc=serial0\,115200//g 5 | -------------------------------------------------------------------------------- /configs/os/cmdline/v1-hdmi-rpi2.sed: -------------------------------------------------------------------------------- 1 | s/rootwait/rootwait cma=128M/g 2 | -------------------------------------------------------------------------------- /configs/os/cmdline/v1-hdmi-rpi3.sed: -------------------------------------------------------------------------------- 1 | s/rootwait/rootwait cma=128M/g 2 | -------------------------------------------------------------------------------- /configs/os/cmdline/v1-hdmi-zero2w.sed: -------------------------------------------------------------------------------- 1 | s/rootwait/rootwait cma=96M/g 2 | -------------------------------------------------------------------------------- /configs/os/cmdline/v1-hdmiusb-rpi2.sed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mofeng-git/One-KVM/10fb78abe6117894556573acd661c266df74efde/configs/os/cmdline/v1-hdmiusb-rpi2.sed -------------------------------------------------------------------------------- /configs/os/cmdline/v1-hdmiusb-rpi3.sed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mofeng-git/One-KVM/10fb78abe6117894556573acd661c266df74efde/configs/os/cmdline/v1-hdmiusb-rpi3.sed -------------------------------------------------------------------------------- /configs/os/cmdline/v1-hdmiusb-zero2w.sed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mofeng-git/One-KVM/10fb78abe6117894556573acd661c266df74efde/configs/os/cmdline/v1-hdmiusb-zero2w.sed -------------------------------------------------------------------------------- /configs/os/cmdline/v2-hdmi-rpi3.sed: -------------------------------------------------------------------------------- 1 | s/rootwait/rootwait cma=128M/g 2 | -------------------------------------------------------------------------------- /configs/os/cmdline/v2-hdmi-rpi4.sed: -------------------------------------------------------------------------------- 1 | s/rootwait/rootwait cma=128M/g 2 | -------------------------------------------------------------------------------- /configs/os/cmdline/v2-hdmi-zero2w.sed: -------------------------------------------------------------------------------- 1 | s/rootwait/rootwait cma=96M/g 2 | -------------------------------------------------------------------------------- /configs/os/cmdline/v2-hdmiusb-rpi4.sed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mofeng-git/One-KVM/10fb78abe6117894556573acd661c266df74efde/configs/os/cmdline/v2-hdmiusb-rpi4.sed -------------------------------------------------------------------------------- /configs/os/cmdline/v3-hdmi-rpi4.sed: -------------------------------------------------------------------------------- 1 | s/rootwait/rootwait cma=128M/g 2 | -------------------------------------------------------------------------------- /configs/os/cmdline/v4mini-hdmi-rpi4.sed: -------------------------------------------------------------------------------- 1 | s/rootwait/rootwait cma=128M/g 2 | -------------------------------------------------------------------------------- /configs/os/cmdline/v4plus-hdmi-rpi4.sed: -------------------------------------------------------------------------------- 1 | s/rootwait/rootwait cma=128M/g 2 | -------------------------------------------------------------------------------- /configs/os/kvmd-webterm.conf: -------------------------------------------------------------------------------- 1 | g kvmd-webterm - - 2 | 3 | u kvmd-webterm - "Pi-KVM - Web terminal" /home/kvmd-webterm 4 | 5 | m kvmd-webterm kvmd 6 | m kvmd-nginx kvmd-webterm 7 | -------------------------------------------------------------------------------- /configs/os/modules-load/v0-hdmi.conf: -------------------------------------------------------------------------------- 1 | tc358743 2 | -------------------------------------------------------------------------------- /configs/os/modules-load/v1-hdmi.conf: -------------------------------------------------------------------------------- 1 | tc358743 2 | -------------------------------------------------------------------------------- /configs/os/modules-load/v2-hdmi.conf: -------------------------------------------------------------------------------- 1 | dwc2 2 | libcomposite 3 | tc358743 4 | -------------------------------------------------------------------------------- /configs/os/modules-load/v2-hdmiusb.conf: -------------------------------------------------------------------------------- 1 | dwc2 2 | libcomposite 3 | -------------------------------------------------------------------------------- /configs/os/modules-load/v3-hdmi.conf: -------------------------------------------------------------------------------- 1 | dwc2 2 | libcomposite 3 | tc358743 4 | i2c-dev 5 | -------------------------------------------------------------------------------- /configs/os/modules-load/v4mini-hdmi.conf: -------------------------------------------------------------------------------- 1 | dwc2 2 | libcomposite 3 | tc358743 4 | i2c-dev 5 | -------------------------------------------------------------------------------- /configs/os/modules-load/v4plus-hdmi.conf: -------------------------------------------------------------------------------- 1 | dwc2 2 | libcomposite 3 | tc358743 4 | i2c-dev 5 | -------------------------------------------------------------------------------- /configs/os/services/kvmd-bootconfig.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=PiKVM - Boot configuration 3 | After=systemd-modules-load.service kvmd-oled.service 4 | Before=\ 5 | kvmd-webterm.service \ 6 | kvmd-certbot.service \ 7 | kvmd-ipmi.service \ 8 | kvmd-janus-static.service \ 9 | kvmd-janus.service \ 10 | kvmd-nginx.service \ 11 | kvmd-otg.service \ 12 | kvmd-otgnet.service \ 13 | kvmd-pst.service \ 14 | kvmd-tc358743.service \ 15 | kvmd-vnc.service \ 16 | kvmd-watchdog.service \ 17 | kvmd.service \ 18 | pikvm-bootconfig.service \ 19 | sshd.service \ 20 | network-pre.target 21 | 22 | [Service] 23 | Type=oneshot 24 | ExecStart=/usr/bin/kvmd-bootconfig --do-the-thing 25 | ExecStop=/bin/true 26 | RemainAfterExit=true 27 | 28 | [Install] 29 | WantedBy=multi-user.target 30 | -------------------------------------------------------------------------------- /configs/os/services/kvmd-certbot.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=PiKVM - Certbot-Renew for KVMD-Nginx 3 | 4 | [Service] 5 | Type=oneshot 6 | EnvironmentFile=-/etc/conf.d/kvmd-certbot 7 | ExecStart=/usr/bin/kvmd-certbot renew --quiet 8 | # Should we?.. 9 | # PrivateTmp=true 10 | -------------------------------------------------------------------------------- /configs/os/services/kvmd-certbot.timer: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Run KVMD-Certbot twice daily 3 | 4 | [Timer] 5 | OnCalendar=*-*-* 00/12:00:00 6 | RandomizedDelaySec=12h 7 | Persistent=true 8 | 9 | [Install] 10 | WantedBy=timers.target 11 | -------------------------------------------------------------------------------- /configs/os/services/kvmd-ipmi.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=One-KVM - IPMI to KVMD proxy 3 | After=kvmd.service 4 | 5 | [Service] 6 | User=kvmd-ipmi 7 | Group=kvmd-ipmi 8 | Type=simple 9 | Restart=always 10 | RestartSec=3 11 | AmbientCapabilities=CAP_NET_BIND_SERVICE 12 | 13 | ExecStart=/usr/bin/kvmd-ipmi --run 14 | TimeoutStopSec=3 15 | 16 | [Install] 17 | WantedBy=multi-user.target 18 | -------------------------------------------------------------------------------- /configs/os/services/kvmd-janus-static.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=PiKVM - Janus WebRTC Gateway (Static Config) 3 | After=network.target network-online.target nss-lookup.target kvmd.service 4 | 5 | [Service] 6 | User=kvmd-janus 7 | Group=kvmd-janus 8 | Type=simple 9 | Restart=always 10 | RestartSec=3 11 | AmbientCapabilities=CAP_NET_RAW 12 | LimitNOFILE=65536 13 | 14 | # Crutch for UNIX socket perms 15 | UMask=0117 16 | 17 | ExecStart=/usr/bin/janus --disable-colors --plugins-folder=/usr/lib/ustreamer/janus --configs-folder=/etc/kvmd/janus 18 | TimeoutStopSec=10 19 | KillMode=mixed 20 | 21 | [Install] 22 | WantedBy=multi-user.target 23 | -------------------------------------------------------------------------------- /configs/os/services/kvmd-janus.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=One-KVM - Janus WebRTC Gateway 3 | After=network.target network-online.target nss-lookup.target kvmd.service 4 | 5 | [Service] 6 | User=kvmd-janus 7 | Group=kvmd-janus 8 | Type=simple 9 | Restart=always 10 | RestartSec=3 11 | AmbientCapabilities=CAP_NET_RAW 12 | LimitNOFILE=65536 13 | 14 | # Crutch for UNIX socket perms 15 | UMask=0117 16 | 17 | ExecStart=/usr/bin/kvmd-janus --run 18 | TimeoutStopSec=10 19 | KillMode=mixed 20 | 21 | [Install] 22 | WantedBy=multi-user.target 23 | -------------------------------------------------------------------------------- /configs/os/services/kvmd-media.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=PiKVM - Media proxy server 3 | After=kvmd.service 4 | 5 | [Service] 6 | User=kvmd-media 7 | Group=kvmd-media 8 | Type=simple 9 | Restart=always 10 | RestartSec=3 11 | 12 | ExecStart=/usr/bin/kvmd-media --run 13 | TimeoutStopSec=3 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /configs/os/services/kvmd-nginx.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=One-KVM - HTTP entrypoint 3 | After=network.target network-online.target nss-lookup.target kvmd.service 4 | 5 | [Service] 6 | Type=forking 7 | PIDFile=/run/kvmd/nginx.pid 8 | PrivateDevices=yes 9 | SyslogLevel=err 10 | Restart=always 11 | RestartSec=3 12 | 13 | ExecStartPre=/usr/bin/kvmd-nginx-mkconf /etc/kvmd/nginx/nginx.conf.mako /run/kvmd/nginx.conf 14 | ExecStart=/usr/sbin/nginx -p /etc/kvmd/nginx -c /run/kvmd/nginx.conf -g 'pid /run/kvmd/nginx.pid; user kvmd-nginx; error_log stderr;' 15 | ExecReload=/usr/sbin/nginx -s reload -p /etc/kvmd/nginx -c /run/kvmd/nginx.conf -g 'pid /run/kvmd/nginx.pid; user kvmd-nginx; error_log stderr;' 16 | KillSignal=SIGQUIT 17 | KillMode=mixed 18 | TimeoutStopSec=3 19 | 20 | [Install] 21 | WantedBy=multi-user.target 22 | -------------------------------------------------------------------------------- /configs/os/services/kvmd-oled-reboot.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=PiKVM - Display reboot message on the OLED 3 | DefaultDependencies=no 4 | 5 | [Service] 6 | Type=oneshot 7 | ExecStart=/bin/bash -c "kill -USR1 `systemctl show -P MainPID kvmd-oled`" 8 | ExecStop=/bin/true 9 | RemainAfterExit=yes 10 | 11 | [Install] 12 | WantedBy=reboot.target 13 | -------------------------------------------------------------------------------- /configs/os/services/kvmd-oled-shutdown.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=PiKVM - Display shutdown message on the OLED 3 | Conflicts=reboot.target 4 | Before=shutdown.target poweroff.target halt.target 5 | DefaultDependencies=no 6 | 7 | [Service] 8 | Type=oneshot 9 | ExecStart=/bin/bash -c "kill -USR2 `systemctl show -P MainPID kvmd-oled`" 10 | ExecStop=/bin/true 11 | RemainAfterExit=yes 12 | 13 | [Install] 14 | WantedBy=shutdown.target 15 | -------------------------------------------------------------------------------- /configs/os/services/kvmd-oled.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=PiKVM - A small OLED daemon 3 | After=systemd-modules-load.service 4 | ConditionPathExists=/dev/i2c-1 5 | 6 | [Service] 7 | Type=simple 8 | Restart=always 9 | RestartSec=3 10 | ExecStartPre=/usr/bin/kvmd-oled --interval=3 --clear-on-exit --image=@hello.ppm 11 | ExecStart=/usr/bin/kvmd-oled 12 | TimeoutStopSec=3 13 | 14 | [Install] 15 | WantedBy=multi-user.target 16 | -------------------------------------------------------------------------------- /configs/os/services/kvmd-otg.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=One-KVM- OTG setup 3 | After=systemd-modules-load.service 4 | Before=kvmd.service 5 | 6 | [Service] 7 | Type=oneshot 8 | ExecStart=/usr/bin/kvmd-otg start 9 | ExecStop=/usr/bin/kvmd-otg stop 10 | RemainAfterExit=true 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | -------------------------------------------------------------------------------- /configs/os/services/kvmd-otgnet.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=PiKVM - OTG network service 3 | After=kvmd-otg.service 4 | Wants=network-pre.target 5 | After=network-pre.target 6 | 7 | [Service] 8 | Type=oneshot 9 | ExecStart=/usr/bin/kvmd-otgnet start 10 | ExecStop=/usr/bin/kvmd-otgnet stop 11 | RemainAfterExit=true 12 | 13 | [Install] 14 | WantedBy=multi-user.target 15 | -------------------------------------------------------------------------------- /configs/os/services/kvmd-pst.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=PiKVM - The KVMD persistent storage manager 3 | Before=kvmd.service 4 | 5 | [Service] 6 | User=kvmd-pst 7 | Group=kvmd-pst 8 | Type=simple 9 | Restart=always 10 | RestartSec=3 11 | 12 | ExecStart=/usr/bin/kvmd-pst --run 13 | TimeoutStopSec=5 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /configs/os/services/kvmd-tc358743.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=PiKVM - EDID loader for TC358743 3 | Wants=dev-kvmd\x2dvideo.device 4 | After=dev-kvmd\x2dvideo.device systemd-modules-load.service 5 | Before=kvmd.service 6 | 7 | [Service] 8 | Type=oneshot 9 | ExecStart=/usr/bin/v4l2-ctl --device=/dev/kvmd-video --set-edid=file=/etc/kvmd/tc358743-edid.hex --info-edid 10 | ExecStop=/usr/bin/v4l2-ctl --device=/dev/kvmd-video --clear-edid 11 | RemainAfterExit=true 12 | 13 | [Install] 14 | WantedBy=multi-user.target 15 | -------------------------------------------------------------------------------- /configs/os/services/kvmd-vnc.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=One-KVM - VNC to KVMD/Streamer proxy 3 | After=kvmd.service 4 | 5 | [Service] 6 | User=kvmd-vnc 7 | Group=kvmd-vnc 8 | Type=simple 9 | Restart=always 10 | RestartSec=3 11 | 12 | ExecStart=/usr/bin/kvmd-vnc --run 13 | TimeoutStopSec=3 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /configs/os/services/kvmd-watchdog.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=PiKVM - RTC-based hardware watchdog 3 | After=systemd-modules-load.service 4 | 5 | [Service] 6 | Type=simple 7 | Restart=always 8 | RestartSec=3 9 | 10 | ExecStart=/usr/bin/kvmd-watchdog run 11 | TimeoutStopSec=3 12 | 13 | [Install] 14 | WantedBy=multi-user.target 15 | -------------------------------------------------------------------------------- /configs/os/services/kvmd-webterm.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=One-KVM - Web terminal (ttyd) 3 | After=network.target 4 | 5 | [Service] 6 | User=kvmd-webterm 7 | Group=kvmd-webterm 8 | WorkingDirectory=/home/kvmd-webterm 9 | Restart=always 10 | RestartSec=1 11 | 12 | # Crutch for UNIX socket perms 13 | UMask=0117 14 | 15 | EnvironmentFile=-/etc/conf.d/kvmd-webterm 16 | ExecStart=/usr/bin/ttyd \ 17 | -W \ 18 | --interface=/run/kvmd/ttyd.sock \ 19 | --port=0 \ 20 | $KVMD_WEBTERM_ARGS \ 21 | /bin/bash -c 'echo -ne "\033]0;One-KVM Terminal: `hostname -f` (ttyd)\007"; bash /etc/kvmd/armbain-motd; export TERM=linux; umask 0022; bash' 22 | 23 | [Install] 24 | WantedBy=multi-user.target 25 | -------------------------------------------------------------------------------- /configs/os/services/kvmd.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=One-KVM - The main daemon 3 | After=network.target network-online.target nss-lookup.target 4 | 5 | [Service] 6 | User=kvmd 7 | Group=kvmd 8 | Type=simple 9 | Restart=always 10 | RestartSec=3 11 | AmbientCapabilities=CAP_NET_RAW 12 | 13 | ExecStart=/usr/bin/kvmd --run 14 | TimeoutStopSec=10 15 | KillMode=mixed 16 | 17 | [Install] 18 | WantedBy=multi-user.target 19 | -------------------------------------------------------------------------------- /configs/os/sudoers/v0-hdmi: -------------------------------------------------------------------------------- 1 | kvmd-pst ALL=(ALL) NOPASSWD: /usr/bin/kvmd-helper-pst-remount 2 | -------------------------------------------------------------------------------- /configs/os/sudoers/v0-hdmiusb: -------------------------------------------------------------------------------- 1 | kvmd-pst ALL=(ALL) NOPASSWD: /usr/bin/kvmd-helper-pst-remount 2 | -------------------------------------------------------------------------------- /configs/os/sudoers/v1-hdmi: -------------------------------------------------------------------------------- 1 | kvmd-pst ALL=(ALL) NOPASSWD: /usr/bin/kvmd-helper-pst-remount 2 | -------------------------------------------------------------------------------- /configs/os/sudoers/v1-hdmiusb: -------------------------------------------------------------------------------- 1 | kvmd-pst ALL=(ALL) NOPASSWD: /usr/bin/kvmd-helper-pst-remount 2 | -------------------------------------------------------------------------------- /configs/os/sudoers/v2-hdmi: -------------------------------------------------------------------------------- 1 | kvmd ALL=(ALL) NOPASSWD: /usr/bin/kvmd-helper-otgmsd-remount 2 | kvmd-pst ALL=(ALL) NOPASSWD: /usr/bin/kvmd-helper-pst-remount 3 | -------------------------------------------------------------------------------- /configs/os/sudoers/v2-hdmiusb: -------------------------------------------------------------------------------- 1 | kvmd ALL=(ALL) NOPASSWD: /usr/bin/kvmd-helper-otgmsd-remount 2 | kvmd-pst ALL=(ALL) NOPASSWD: /usr/bin/kvmd-helper-pst-remount 3 | -------------------------------------------------------------------------------- /configs/os/sudoers/v3-hdmi: -------------------------------------------------------------------------------- 1 | kvmd ALL=(ALL) NOPASSWD: /usr/bin/kvmd-helper-otgmsd-remount 2 | kvmd-pst ALL=(ALL) NOPASSWD: /usr/bin/kvmd-helper-pst-remount 3 | -------------------------------------------------------------------------------- /configs/os/sudoers/v4mini-hdmi: -------------------------------------------------------------------------------- 1 | kvmd ALL=(ALL) NOPASSWD: /usr/bin/kvmd-helper-otgmsd-remount 2 | kvmd-pst ALL=(ALL) NOPASSWD: /usr/bin/kvmd-helper-pst-remount 3 | -------------------------------------------------------------------------------- /configs/os/sudoers/v4plus-hdmi: -------------------------------------------------------------------------------- 1 | kvmd ALL=(ALL) NOPASSWD: /usr/bin/kvmd-helper-otgmsd-remount 2 | kvmd-pst ALL=(ALL) NOPASSWD: /usr/bin/kvmd-helper-pst-remount 3 | -------------------------------------------------------------------------------- /configs/os/sysctl.conf: -------------------------------------------------------------------------------- 1 | # Overly-aggressive data writeback policies to minimize the chance of data corruption 2 | # Start dirty data writeback when it exceeds 256 KiB or 1s has passed 3 | vm.dirty_background_bytes = 262144 4 | vm.dirty_writeback_centisecs = 100 5 | 6 | # https://groups.google.com/g/meetecho-janus/c/xoWIQfaoJm8 7 | net.core.rmem_default = 500000 8 | net.core.wmem_default = 500000 9 | net.core.rmem_max = 1000000 10 | net.core.wmem_max = 1000000 11 | -------------------------------------------------------------------------------- /configs/os/sysusers.conf: -------------------------------------------------------------------------------- 1 | g kvmd - - 2 | g kvmd-media - - 3 | g kvmd-pst - - 4 | g kvmd-ipmi - - 5 | g kvmd-vnc - - 6 | g kvmd-nginx - - 7 | g kvmd-janus - - 8 | g kvmd-certbot - - 9 | 10 | u kvmd - "PiKVM - The main daemon" - 11 | u kvmd-media - "PiKVM - The media proxy" 12 | u kvmd-pst - "PiKVM - Persistent storage" - 13 | u kvmd-ipmi - "PiKVM - IPMI to KVMD proxy" - 14 | u kvmd-vnc - "PiKVM - VNC to KVMD/Streamer proxy" - 15 | u kvmd-nginx - "PiKVM - HTTP entrypoint" - 16 | u kvmd-janus - "PiKVM - Janus WebRTC Gateway" - 17 | u kvmd-certbot - "PiKVM - Certbot-Renew for KVMD-Nginx" 18 | 19 | m kvmd video 20 | m kvmd gpio 21 | m kvmd uucp 22 | m kvmd spi 23 | m kvmd systemd-journal 24 | m kvmd kvmd-media 25 | m kvmd kvmd-pst 26 | 27 | m kvmd-media kvmd 28 | 29 | m kvmd-pst kvmd 30 | 31 | m kvmd-ipmi kvmd 32 | 33 | m kvmd-vnc kvmd 34 | m kvmd-vnc kvmd-certbot 35 | 36 | m kvmd-janus kvmd 37 | m kvmd-janus audio 38 | 39 | m kvmd-nginx kvmd 40 | m kvmd-nginx kvmd-media 41 | m kvmd-nginx kvmd-janus 42 | m kvmd-nginx kvmd-certbot 43 | 44 | m kvmd-certbot kvmd-pst 45 | -------------------------------------------------------------------------------- /configs/os/tmpfiles.conf: -------------------------------------------------------------------------------- 1 | D /run/kvmd 0775 kvmd kvmd - 2 | D /run/kvmd-certbot 0755 root root - 3 | D /run/kvmd-certbot/webroot 0755 kvmd-certbot kvmd-certbot - 4 | 5 | D /tmp/kvmd 0775 kvmd kvmd - 6 | D /tmp/kvmd-nginx 0700 kvmd-nginx root - 7 | D /tmp/kvmd-certbot 0755 kvmd-certbot kvmd-certbot - 8 | -------------------------------------------------------------------------------- /configs/os/udev/common.rules: -------------------------------------------------------------------------------- 1 | # Here are described some bindings for PiKVM devices. 2 | # Do not edit this file. 3 | KERNEL=="ttyACM[0-9]*", SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="eda3", SYMLINK+="kvmd-hid-bridge" 4 | KERNEL=="ttyACM[0-9]*", SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="1080", SYMLINK+="kvmd-switch" 5 | -------------------------------------------------------------------------------- /configs/os/udev/v0-hdmi-rpi2.rules: -------------------------------------------------------------------------------- 1 | # https://unix.stackexchange.com/questions/66901/how-to-bind-usb-device-under-a-static-name 2 | # https://wiki.archlinux.org/index.php/Udev#Setting_static_device_names 3 | KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", KERNELS=="3f801000.csi|3f801000.csi1", ATTR{name}=="unicam-image", GROUP="kvmd", SYMLINK+="kvmd-video", TAG+="systemd" 4 | KERNEL=="ttyAMA0", SYMLINK+="kvmd-hid" 5 | -------------------------------------------------------------------------------- /configs/os/udev/v0-hdmi-rpi3.rules: -------------------------------------------------------------------------------- 1 | # https://unix.stackexchange.com/questions/66901/how-to-bind-usb-device-under-a-static-name 2 | # https://wiki.archlinux.org/index.php/Udev#Setting_static_device_names 3 | KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", KERNELS=="3f801000.csi|3f801000.csi1", ATTR{name}=="unicam-image", GROUP="kvmd", SYMLINK+="kvmd-video", TAG+="systemd" 4 | KERNEL=="ttyAMA0", SYMLINK+="kvmd-hid" 5 | -------------------------------------------------------------------------------- /configs/os/udev/v0-hdmi-zero2w.rules: -------------------------------------------------------------------------------- 1 | # https://unix.stackexchange.com/questions/66901/how-to-bind-usb-device-under-a-static-name 2 | # https://wiki.archlinux.org/index.php/Udev#Setting_static_device_names 3 | KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", KERNELS=="3f801000.csi|3f801000.csi1", ATTR{name}=="unicam-image", GROUP="kvmd", SYMLINK+="kvmd-video", TAG+="systemd" 4 | KERNEL=="ttyAMA0", SYMLINK+="kvmd-hid" 5 | -------------------------------------------------------------------------------- /configs/os/udev/v0-hdmiusb-rpi2.rules: -------------------------------------------------------------------------------- 1 | # https://unix.stackexchange.com/questions/66901/how-to-bind-usb-device-under-a-static-name 2 | # https://wiki.archlinux.org/index.php/Udev#Setting_static_device_names 3 | KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", PROGRAM="/usr/bin/kvmd-udev-hdmiusb-check rpi2 %b", ATTR{index}=="0", GROUP="kvmd", SYMLINK+="kvmd-video" 4 | KERNEL=="ttyAMA0", SYMLINK+="kvmd-hid" 5 | -------------------------------------------------------------------------------- /configs/os/udev/v0-hdmiusb-rpi3.rules: -------------------------------------------------------------------------------- 1 | # https://unix.stackexchange.com/questions/66901/how-to-bind-usb-device-under-a-static-name 2 | # https://wiki.archlinux.org/index.php/Udev#Setting_static_device_names 3 | KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", PROGRAM="/usr/bin/kvmd-udev-hdmiusb-check rpi3 %b", ATTR{index}=="0", GROUP="kvmd", SYMLINK+="kvmd-video" 4 | KERNEL=="ttyAMA0", SYMLINK+="kvmd-hid" 5 | -------------------------------------------------------------------------------- /configs/os/udev/v0-hdmiusb-zero2w.rules: -------------------------------------------------------------------------------- 1 | # https://unix.stackexchange.com/questions/66901/how-to-bind-usb-device-under-a-static-name 2 | # https://wiki.archlinux.org/index.php/Udev#Setting_static_device_names 3 | KERNEL=="video0", SUBSYSTEM=="video4linux", GROUP="kvmd", SYMLINK+="kvmd-video" 4 | KERNEL=="ttyAMA0", SYMLINK+="kvmd-hid" 5 | -------------------------------------------------------------------------------- /configs/os/udev/v1-hdmi-rpi2.rules: -------------------------------------------------------------------------------- 1 | # https://unix.stackexchange.com/questions/66901/how-to-bind-usb-device-under-a-static-name 2 | # https://wiki.archlinux.org/index.php/Udev#Setting_static_device_names 3 | KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", KERNELS=="3f801000.csi|3f801000.csi1", ATTR{name}=="unicam-image", GROUP="kvmd", SYMLINK+="kvmd-video", TAG+="systemd" 4 | -------------------------------------------------------------------------------- /configs/os/udev/v1-hdmi-rpi3.rules: -------------------------------------------------------------------------------- 1 | # https://unix.stackexchange.com/questions/66901/how-to-bind-usb-device-under-a-static-name 2 | # https://wiki.archlinux.org/index.php/Udev#Setting_static_device_names 3 | KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", KERNELS=="3f801000.csi|3f801000.csi1", ATTR{name}=="unicam-image", GROUP="kvmd", SYMLINK+="kvmd-video", TAG+="systemd" 4 | -------------------------------------------------------------------------------- /configs/os/udev/v1-hdmi-zero2w.rules: -------------------------------------------------------------------------------- 1 | # https://unix.stackexchange.com/questions/66901/how-to-bind-usb-device-under-a-static-name 2 | # https://wiki.archlinux.org/index.php/Udev#Setting_static_device_names 3 | KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", KERNELS=="3f801000.csi|3f801000.csi1", ATTR{name}=="unicam-image", GROUP="kvmd", SYMLINK+="kvmd-video", TAG+="systemd" 4 | -------------------------------------------------------------------------------- /configs/os/udev/v1-hdmiusb-rpi2.rules: -------------------------------------------------------------------------------- 1 | # https://unix.stackexchange.com/questions/66901/how-to-bind-usb-device-under-a-static-name 2 | # https://wiki.archlinux.org/index.php/Udev#Setting_static_device_names 3 | KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", PROGRAM="/usr/bin/kvmd-udev-hdmiusb-check rpi2 %b", ATTR{index}=="0", GROUP="kvmd", SYMLINK+="kvmd-video" 4 | -------------------------------------------------------------------------------- /configs/os/udev/v1-hdmiusb-rpi3.rules: -------------------------------------------------------------------------------- 1 | # https://unix.stackexchange.com/questions/66901/how-to-bind-usb-device-under-a-static-name 2 | # https://wiki.archlinux.org/index.php/Udev#Setting_static_device_names 3 | KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", PROGRAM="/usr/bin/kvmd-udev-hdmiusb-check rpi3 %b", ATTR{index}=="0", GROUP="kvmd", SYMLINK+="kvmd-video" 4 | -------------------------------------------------------------------------------- /configs/os/udev/v1-hdmiusb-zero2w.rules: -------------------------------------------------------------------------------- 1 | # https://unix.stackexchange.com/questions/66901/how-to-bind-usb-device-under-a-static-name 2 | # https://wiki.archlinux.org/index.php/Udev#Setting_static_device_names 3 | KERNEL=="video0", SUBSYSTEM=="video4linux", GROUP="kvmd", SYMLINK+="kvmd-video" 4 | -------------------------------------------------------------------------------- /configs/os/udev/v2-hdmi-rpi3.rules: -------------------------------------------------------------------------------- 1 | # https://unix.stackexchange.com/questions/66901/how-to-bind-usb-device-under-a-static-name 2 | # https://wiki.archlinux.org/index.php/Udev#Setting_static_device_names 3 | KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", KERNELS=="3f801000.csi|3f801000.csi1", ATTR{name}=="unicam-image", GROUP="kvmd", SYMLINK+="kvmd-video", TAG+="systemd" 4 | KERNEL=="hidg0", GROUP="kvmd", SYMLINK+="kvmd-hid-keyboard" 5 | KERNEL=="hidg1", GROUP="kvmd", SYMLINK+="kvmd-hid-mouse" 6 | KERNEL=="hidg2", GROUP="kvmd", SYMLINK+="kvmd-hid-mouse-alt" 7 | -------------------------------------------------------------------------------- /configs/os/udev/v2-hdmi-rpi4.rules: -------------------------------------------------------------------------------- 1 | # https://unix.stackexchange.com/questions/66901/how-to-bind-usb-device-under-a-static-name 2 | # https://wiki.archlinux.org/index.php/Udev#Setting_static_device_names 3 | KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", KERNELS=="fe801000.csi|fe801000.csi1", ATTR{name}=="unicam-image", GROUP="kvmd", SYMLINK+="kvmd-video", TAG+="systemd" 4 | KERNEL=="hidg0", GROUP="kvmd", SYMLINK+="kvmd-hid-keyboard" 5 | KERNEL=="hidg1", GROUP="kvmd", SYMLINK+="kvmd-hid-mouse" 6 | KERNEL=="hidg2", GROUP="kvmd", SYMLINK+="kvmd-hid-mouse-alt" 7 | -------------------------------------------------------------------------------- /configs/os/udev/v2-hdmi-zero2w.rules: -------------------------------------------------------------------------------- 1 | # https://unix.stackexchange.com/questions/66901/how-to-bind-usb-device-under-a-static-name 2 | # https://wiki.archlinux.org/index.php/Udev#Setting_static_device_names 3 | KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", KERNELS=="3f801000.csi|3f801000.csi1", ATTR{name}=="unicam-image", GROUP="kvmd", SYMLINK+="kvmd-video", TAG+="systemd" 4 | KERNEL=="hidg0", GROUP="kvmd", SYMLINK+="kvmd-hid-keyboard" 5 | KERNEL=="hidg1", GROUP="kvmd", SYMLINK+="kvmd-hid-mouse" 6 | KERNEL=="hidg2", GROUP="kvmd", SYMLINK+="kvmd-hid-mouse-alt" 7 | -------------------------------------------------------------------------------- /configs/os/udev/v2-hdmiusb-rpi4.rules: -------------------------------------------------------------------------------- 1 | # https://unix.stackexchange.com/questions/66901/how-to-bind-usb-device-under-a-static-name 2 | # https://wiki.archlinux.org/index.php/Udev#Setting_static_device_names 3 | KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", PROGRAM="/usr/bin/kvmd-udev-hdmiusb-check rpi4 %b", ATTR{index}=="0", GROUP="kvmd", SYMLINK+="kvmd-video" 4 | KERNEL=="hidg0", GROUP="kvmd", SYMLINK+="kvmd-hid-keyboard" 5 | KERNEL=="hidg1", GROUP="kvmd", SYMLINK+="kvmd-hid-mouse" 6 | KERNEL=="hidg2", GROUP="kvmd", SYMLINK+="kvmd-hid-mouse-alt" 7 | -------------------------------------------------------------------------------- /configs/os/udev/v3-hdmi-rpi4.rules: -------------------------------------------------------------------------------- 1 | # https://unix.stackexchange.com/questions/66901/how-to-bind-usb-device-under-a-static-name 2 | # https://wiki.archlinux.org/index.php/Udev#Setting_static_device_names 3 | KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", KERNELS=="fe801000.csi|fe801000.csi1", ATTR{name}=="unicam-image", GROUP="kvmd", SYMLINK+="kvmd-video", TAG+="systemd" 4 | KERNEL=="hidg0", GROUP="kvmd", SYMLINK+="kvmd-hid-keyboard" 5 | KERNEL=="hidg1", GROUP="kvmd", SYMLINK+="kvmd-hid-mouse" 6 | KERNEL=="hidg2", GROUP="kvmd", SYMLINK+="kvmd-hid-mouse-alt" 7 | -------------------------------------------------------------------------------- /configs/os/udev/v4mini-hdmi-rpi4.rules: -------------------------------------------------------------------------------- 1 | # https://unix.stackexchange.com/questions/66901/how-to-bind-usb-device-under-a-static-name 2 | # https://wiki.archlinux.org/index.php/Udev#Setting_static_device_names 3 | KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", KERNELS=="fe801000.csi|fe801000.csi1", ATTR{name}=="unicam-image", GROUP="kvmd", SYMLINK+="kvmd-video", TAG+="systemd" 4 | KERNEL=="hidg0", GROUP="kvmd", SYMLINK+="kvmd-hid-keyboard" 5 | KERNEL=="hidg1", GROUP="kvmd", SYMLINK+="kvmd-hid-mouse" 6 | KERNEL=="hidg2", GROUP="kvmd", SYMLINK+="kvmd-hid-mouse-alt" 7 | -------------------------------------------------------------------------------- /configs/os/udev/v4plus-hdmi-rpi4.rules: -------------------------------------------------------------------------------- 1 | # https://unix.stackexchange.com/questions/66901/how-to-bind-usb-device-under-a-static-name 2 | # https://wiki.archlinux.org/index.php/Udev#Setting_static_device_names 3 | KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", KERNELS=="fe801000.csi|fe801000.csi1", ATTR{name}=="unicam-image", GROUP="kvmd", SYMLINK+="kvmd-video", TAG+="systemd" 4 | KERNEL=="hidg0", GROUP="kvmd", SYMLINK+="kvmd-hid-keyboard" 5 | KERNEL=="hidg1", GROUP="kvmd", SYMLINK+="kvmd-hid-mouse" 6 | KERNEL=="hidg2", GROUP="kvmd", SYMLINK+="kvmd-hid-mouse-alt" 7 | SUBSYSTEM=="drm", ACTION=="change", ENV{DEVLINKS}=="/dev/dri/by-path/platform-gpu-card", RUN+="/usr/bin/kvmd-udev-restart-pass %k %E{CONNECTOR}" 8 | -------------------------------------------------------------------------------- /contrib/README: -------------------------------------------------------------------------------- 1 | * keymaps: 2 | - https://github.com/qemu/qemu/blob/master/pc-bios/keymaps 3 | - https://github.com/j0xaf/keymap-us-altgr-intl/blob/main/keymap-us-altgr-intl 4 | -------------------------------------------------------------------------------- /extras/ipmi/manifest.yaml: -------------------------------------------------------------------------------- 1 | name: IPMI 2 | description: Show IPMI information 3 | icon: share/svg/ipmi.svg 4 | path: ipmi 5 | daemon: kvmd-ipmi 6 | port: ipmi/server/port 7 | place: 21 8 | -------------------------------------------------------------------------------- /extras/janus-static/manifest.yaml: -------------------------------------------------------------------------------- 1 | name: Janus Static 2 | description: Janus WebRTC Gateway (Static Config) 3 | path: janus 4 | daemon: kvmd-janus-static 5 | place: -1 6 | -------------------------------------------------------------------------------- /extras/janus/manifest.yaml: -------------------------------------------------------------------------------- 1 | name: Janus 2 | description: Janus WebRTC Gateway 3 | path: janus 4 | daemon: kvmd-janus 5 | place: -1 6 | -------------------------------------------------------------------------------- /extras/janus/nginx.ctx-http.conf: -------------------------------------------------------------------------------- 1 | upstream janus-ws { 2 | server unix:/run/kvmd/janus-ws.sock fail_timeout=0s max_fails=0; 3 | } 4 | -------------------------------------------------------------------------------- /extras/janus/nginx.ctx-server.conf: -------------------------------------------------------------------------------- 1 | location /janus/ws { 2 | rewrite ^/janus/ws$ / break; 3 | rewrite ^/janus/ws\?(.*)$ /?$1 break; 4 | proxy_pass http://janus-ws; 5 | include /etc/kvmd/nginx/loc-proxy.conf; 6 | include /etc/kvmd/nginx/loc-websocket.conf; 7 | } 8 | 9 | location = /share/js/kvm/janus.js { 10 | alias /usr/share/janus/javascript/janus.js; 11 | include /etc/kvmd/nginx/loc-nocache.conf; 12 | } 13 | 14 | location = /share/js/kvm/adapter.js { 15 | alias /usr/share/janus/javascript/adapter.js; 16 | include /etc/kvmd/nginx/loc-nocache.conf; 17 | } 18 | -------------------------------------------------------------------------------- /extras/media/manifest.yaml: -------------------------------------------------------------------------------- 1 | name: Media 2 | description: KVMD Media Proxy 3 | path: media 4 | daemon: kvmd-media 5 | place: -1 6 | -------------------------------------------------------------------------------- /extras/media/nginx.ctx-http.conf: -------------------------------------------------------------------------------- 1 | upstream media { 2 | server unix:/run/kvmd/media.sock fail_timeout=0s max_fails=0; 3 | } 4 | -------------------------------------------------------------------------------- /extras/media/nginx.ctx-server.conf: -------------------------------------------------------------------------------- 1 | location /api/media/ws { 2 | rewrite ^/api/media/ws$ /ws break; 3 | rewrite ^/api/media/ws\?(.*)$ /ws?$1 break; 4 | proxy_pass http://media; 5 | include /etc/kvmd/nginx/loc-proxy.conf; 6 | include /etc/kvmd/nginx/loc-websocket.conf; 7 | } 8 | -------------------------------------------------------------------------------- /extras/vnc/manifest.yaml: -------------------------------------------------------------------------------- 1 | name: VNC 2 | description: Show VNC information 3 | icon: share/svg/vnc.svg 4 | path: vnc 5 | daemon: kvmd-vnc 6 | port: vnc/server/port 7 | place: 20 8 | -------------------------------------------------------------------------------- /extras/webterm/manifest.yaml: -------------------------------------------------------------------------------- 1 | name: Terminal 2 | description: Open terminal in a web browser 3 | icon: extras/webterm/terminal.svg 4 | path: extras/webterm/ttyd 5 | daemon: kvmd-webterm 6 | place: 10 7 | -------------------------------------------------------------------------------- /extras/webterm/nginx.ctx-http.conf: -------------------------------------------------------------------------------- 1 | upstream ttyd { 2 | server unix:/run/kvmd/ttyd.sock fail_timeout=0s max_fails=0; 3 | } 4 | -------------------------------------------------------------------------------- /extras/webterm/nginx.ctx-server.conf: -------------------------------------------------------------------------------- 1 | location /extras/webterm/ttyd { 2 | rewrite ^([^.\?]*[^/(/ws)])$ $1/ permanent; 3 | rewrite ^/extras/webterm/ttyd$ / break; 4 | rewrite ^/extras/webterm/ttyd\?(.*)$ ?$1 break; 5 | rewrite ^/extras/webterm/ttyd/(.*)$ /$1 break; 6 | proxy_pass http://ttyd; 7 | include /etc/kvmd/nginx/loc-proxy.conf; 8 | include /etc/kvmd/nginx/loc-websocket.conf; 9 | include /etc/kvmd/nginx/loc-login.conf; 10 | include /etc/kvmd/nginx/loc-nocache.conf; 11 | } 12 | -------------------------------------------------------------------------------- /hid/arduino/.gitignore: -------------------------------------------------------------------------------- 1 | /.platformio/ 2 | /.pio/ 3 | /.current 4 | /.vscode/ 5 | /.config 6 | /platformio.ini 7 | -------------------------------------------------------------------------------- /hid/arduino/Makefile: -------------------------------------------------------------------------------- 1 | serial: 2 | make _build E=serial C=avr 3 | spi: 4 | make _build E=spi C=avr 5 | aum: 6 | make _build E=aum C=avr 7 | stm32: 8 | platformio run --environment patch --project-conf platformio-stm32.ini 9 | make _build E=serial C=stm32 10 | _build: 11 | rm -f .current .config 12 | platformio run --environment $(E) --project-conf platformio-$(C).ini 13 | echo -n $(E) > .current 14 | echo -n $(C) > .config 15 | 16 | # Added to easy test all builds 17 | _build_all: aum spi serial stm32 18 | rm -f .current .config 19 | 20 | install: upload 21 | upload: 22 | $(eval $@_CURRENT := $(shell cat .current)) 23 | $(eval $@_CONFIG := $(shell cat .config)) 24 | bash -ex -c " \ 25 | current=`cat .current`; \ 26 | if [ '$($@_CURRENT)' == 'spi' ] || [ '$($@_CURRENT)' == 'aum' ]; then \ 27 | gpioset 0 25=1; \ 28 | gpioset 0 25=0; \ 29 | fi \ 30 | " 31 | platformio run --environment '$($@_CURRENT)' --project-conf 'platformio-$($@_CONFIG).ini' --target upload 32 | 33 | 34 | bootloader-spi: install-bootloader-spi 35 | install-bootloader-spi: upload-bootloader-spi 36 | upload-bootloader-spi: 37 | platformio run --environment bootloader_spi --project-conf platformio-avr.ini --target bootloader 38 | 39 | 40 | update: 41 | platformio platform update 42 | 43 | 44 | clean-all: clean 45 | rm -rf .platformio 46 | clean: 47 | rm -rf .pio .current .config platformio.ini 48 | 49 | 50 | help: 51 | @ cat Makefile 52 | -------------------------------------------------------------------------------- /hid/arduino/avrdude-rpi.conf: -------------------------------------------------------------------------------- 1 | programmer 2 | id = "rpi"; 3 | desc = "RPi SPI programmer"; 4 | type = "linuxspi"; 5 | reset = 25; 6 | baudrate = 400000; 7 | ; 8 | -------------------------------------------------------------------------------- /hid/arduino/avrdude.py: -------------------------------------------------------------------------------- 1 | # https://docs.platformio.org/en/latest/projectconf/advanced_scripting.html 2 | 3 | 4 | from os import rename 5 | from os import symlink 6 | from os.path import exists 7 | from os.path import join 8 | 9 | import platform 10 | 11 | Import("env") 12 | 13 | 14 | # ===== 15 | def _get_tool_path() -> str: 16 | path = env.PioPlatform().get_package_dir("tool-avrdude") 17 | assert exists(path) 18 | return path 19 | 20 | 21 | def _fix_ld_arm() -> None: 22 | tool_path = _get_tool_path() 23 | flag_path = join(tool_path, ".fix-ld-arm.done") 24 | 25 | if not exists(flag_path): 26 | def patch(*_, **__) -> None: 27 | symlink("/usr/lib/libtinfo.so.6", join(tool_path, "libtinfo.so.5")) 28 | open(flag_path, "w").close() 29 | 30 | env.Execute(patch) 31 | 32 | 33 | def _replace_to_system(new_path: str) -> None: 34 | tool_path = _get_tool_path() 35 | flag_path = join(tool_path, ".replace-to-system.done") 36 | 37 | if not exists(flag_path): 38 | def patch(*_, **__) -> None: 39 | old_path = join(tool_path, "avrdude") 40 | bak_path = join(tool_path, "_avrdude_bak") 41 | rename(old_path, bak_path) 42 | symlink(new_path, old_path) 43 | open(flag_path, "w").close() 44 | 45 | env.Execute(patch) 46 | 47 | 48 | # ===== 49 | if "arm" in platform.machine(): 50 | _fix_ld_arm() 51 | 52 | _path = "/usr/bin/avrdude" 53 | if exists(_path): 54 | _replace_to_system(_path) 55 | -------------------------------------------------------------------------------- /hid/arduino/lib/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mofeng-git/One-KVM/10fb78abe6117894556573acd661c266df74efde/hid/arduino/lib/.gitignore -------------------------------------------------------------------------------- /hid/arduino/lib/drivers-stm32/README.md: -------------------------------------------------------------------------------- 1 | This is WIP. Use AVR version as reference. 2 | 3 | It was tested with bluepill. Most boards are clones. 4 | If you have problem with USB please check https://stm32duinoforum.com/forum/wiki_subdomain/index_title_Blue_Pill.html for pull up resistor. If it still does not work check another board or cable. 5 | 6 | TODO: 7 | - [x] Serial communication 8 | - [x] USB keyboard 9 | - [x] USB keyboard - add scroll status 10 | - [x] USB keyboard - key sending 11 | - [x] USB keyboard - test key mapping 12 | - [x] Persistent storage 13 | - [ ] SPI communication 14 | - [ ] PS2 keyboard 15 | - [x] USB absolute mouse 16 | - [x] USB absolute mouse - add whele 17 | - [x] USB relative mouse 18 | - [x] USB relative mouse - add whele 19 | - [ ] USB mouses - up down button 20 | - [ ] WIN98 USB mouse 21 | - [x] undefine SERIAL_USB 22 | - [ ] boot keyboard 23 | -------------------------------------------------------------------------------- /hid/arduino/lib/drivers-stm32/bluepill_sch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mofeng-git/One-KVM/10fb78abe6117894556573acd661c266df74efde/hid/arduino/lib/drivers-stm32/bluepill_sch.png -------------------------------------------------------------------------------- /hid/arduino/lib/drivers/tools.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | *****************************************************************************/ 21 | 22 | 23 | #pragma once 24 | 25 | #include 26 | 27 | 28 | bool is_micros_timed_out(unsigned long start_ts, unsigned long timeout); 29 | -------------------------------------------------------------------------------- /hid/arduino/patch.py: -------------------------------------------------------------------------------- 1 | # https://docs.platformio.org/en/latest/projectconf/advanced_scripting.html 2 | 3 | 4 | from os.path import exists 5 | from os.path import join 6 | from os.path import basename 7 | 8 | from typing import Dict 9 | 10 | Import("env") 11 | 12 | 13 | # ===== 14 | def _get_pkg_path(name: str) -> str: 15 | path = env.PioPlatform().get_package_dir(name) 16 | assert exists(path) 17 | return path 18 | 19 | 20 | def _get_libs() -> Dict[str, str]: 21 | return { 22 | builder.name: builder.path 23 | for builder in env.GetLibBuilders() 24 | } 25 | 26 | 27 | def _patch(path: str, patch_path: str) -> None: 28 | assert exists(path) 29 | flag_path: str = join(path, f".{basename(patch_path)}.done") 30 | if not exists(flag_path): 31 | # TODO check for failure 32 | env.Execute(f"patch -p1 -d {path} < {patch_path}") 33 | env.Execute(lambda *_, **__: open(flag_path, "w").close()) 34 | 35 | 36 | # ===== 37 | if env.GetProjectOption("platform") == "ststm32": 38 | _patch(_get_pkg_path("framework-arduinoststm32-maple"), "patches/platformio-stm32f1-no-serial-usb.patch") 39 | elif env.GetProjectOption("platform") == "atmelavr": 40 | _patch(_get_pkg_path("framework-arduino-avr"), "patches/arduino-main-no-usb.patch") 41 | _patch(_get_pkg_path("framework-arduino-avr"), "patches/arduino-optional-cdc.patch") 42 | _patch(_get_pkg_path("framework-arduino-avr"), "patches/arduino-get-plugged-endpoint.patch") 43 | 44 | _libs = _get_libs() 45 | _patch(_libs["HID-Project"], "patches/hid-shut-up.patch") 46 | _patch(_libs["HID-Project"], "patches/hid-no-singletones.patch") 47 | _patch(_libs["HID-Project"], "patches/hid-win98.patch") 48 | else: 49 | assert(False) 50 | -------------------------------------------------------------------------------- /hid/arduino/patches/arduino-get-plugged-endpoint.patch: -------------------------------------------------------------------------------- 1 | --- a/cores/arduino/PluggableUSB.h 2019-05-16 15:52:01.000000000 +0300 2 | +++ b/cores/arduino/PluggableUSB.h 2020-11-14 20:57:30.942432544 +0300 3 | @@ -31,6 +31,8 @@ 4 | numEndpoints(numEps), numInterfaces(numIfs), endpointType(epType) 5 | { } 6 | 7 | + uint8_t getPluggedEndpoint() { return pluggedEndpoint; } 8 | + 9 | protected: 10 | virtual bool setup(USBSetup& setup) = 0; 11 | virtual int getInterface(uint8_t* interfaceCount) = 0; 12 | -------------------------------------------------------------------------------- /hid/arduino/patches/arduino-main-no-usb.patch: -------------------------------------------------------------------------------- 1 | diff --git a/cores/arduino/main.cpp b/cores/arduino/main.cpp 2 | index 434cd40..7aba76f 100644 3 | --- a/cores/arduino/main.cpp 4 | +++ b/cores/arduino/main.cpp 5 | @@ -36,15 +36,15 @@ int main(void) 6 | 7 | initVariant(); 8 | 9 | -#if defined(USBCON) 10 | - USBDevice.attach(); 11 | -#endif 12 | +// #if defined(USBCON) 13 | +// USBDevice.attach(); 14 | +// #endif 15 | 16 | setup(); 17 | 18 | for (;;) { 19 | loop(); 20 | - if (serialEventRun) serialEventRun(); 21 | + // if (serialEventRun) serialEventRun(); 22 | } 23 | 24 | return 0; 25 | -------------------------------------------------------------------------------- /hid/arduino/patches/hid-shut-up.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/KeyboardLayouts/ImprovedKeylayouts.h b/src/KeyboardLayouts/ImprovedKeylayouts.h 2 | index 03b92a0..ee0bab4 100644 3 | --- a/src/KeyboardLayouts/ImprovedKeylayouts.h 4 | +++ b/src/KeyboardLayouts/ImprovedKeylayouts.h 5 | @@ -51,9 +51,9 @@ enum KeyboardLeds : uint8_t { 6 | #ifndef HID_CUSTOM_LAYOUT 7 | #define HID_CUSTOM_LAYOUT 8 | #define LAYOUT_US_ENGLISH 9 | - #pragma message "Using default ASCII layout for keyboard modules" 10 | + //#pragma message "Using default ASCII layout for keyboard modules" 11 | #else 12 | - #pragma message "Using custom layout for keyboard modules" 13 | + //#pragma message "Using custom layout for keyboard modules" 14 | #endif 15 | 16 | // Hut1_12v2.pdf 17 | -------------------------------------------------------------------------------- /hid/arduino/patches/platformio-stm32f1-no-serial-usb.patch: -------------------------------------------------------------------------------- 1 | --- aaa/tools/platformio-build-stm32f1.py 2022-07-16 18:54:42.536695468 +0200 2 | +++ bbb/tools/platformio-build-stm32f1.py 2022-07-16 19:03:10.988056751 +0200 3 | @@ -121,7 +121,7 @@ 4 | env.Append( 5 | CPPDEFINES=[ 6 | ("CONFIG_MAPLE_MINI_NO_DISABLE_DEBUG", 1), 7 | - "SERIAL_USB" 8 | + # "SERIAL_USB" 9 | ]) 10 | 11 | is_generic = board.startswith("generic") or board == "hytiny_stm32f103t" 12 | -------------------------------------------------------------------------------- /hid/arduino/platformio-stm32.ini: -------------------------------------------------------------------------------- 1 | # http://docs.platformio.org/page/projectconf.html 2 | [platformio] 3 | core_dir = ./.platformio/ 4 | 5 | [env] 6 | framework = arduino 7 | platform = ststm32 8 | board = genericSTM32F103C8 9 | board_build.core = maple 10 | extra_scripts = 11 | post:patch.py 12 | 13 | [_common] 14 | lib_deps = 15 | git+https://github.com/ZulNs/STM32F1_RTC#v1.1.0 16 | git+https://github.com/arpruss/USBComposite_stm32f1#3c58f97eb006ee9cd1fb4fd55ac4faeeaead0974 17 | drivers-stm32 18 | build_flags = 19 | # ----- The default config with dynamic switching ----- 20 | -DHID_DYNAMIC 21 | -DHID_WITH_USB 22 | -DHID_SET_USB_KBD 23 | -DHID_SET_USB_MOUSE_ABS 24 | 25 | [_serial] 26 | extends = 27 | _common 28 | build_flags = 29 | ${_common.build_flags} 30 | -DCMD_SERIAL=Serial1 31 | -DCMD_SERIAL_SPEED=115200 32 | -DCMD_SERIAL_TIMEOUT=100000 33 | # ===== Serial ===== 34 | [env:serial] 35 | extends = 36 | _serial 37 | upload_flags = -c set CPUTAPID 0x2ba01477 38 | debug_tool= stlink 39 | debug_build_flags = -Og -ggdb3 -g3 40 | debug_server = 41 | .platformio/packages/tool-openocd/bin/openocd 42 | -s .platformio/packages/tool-openocd/scripts 43 | -f interface/stlink.cfg 44 | -c "transport select hla_swd" 45 | -c "set CPUTAPID 0x2ba01477" 46 | -f target/stm32f1x.cfg 47 | -c "reset_config none" 48 | ; build_type = debug 49 | [env:patch] 50 | ; platformio-stm32f1-no-serial-usb.patch requires to running build again 51 | ; fake target was added to avoid error during first build 52 | src_filter = - 53 | -------------------------------------------------------------------------------- /hid/pico/.gitignore: -------------------------------------------------------------------------------- 1 | /.pico-sdk* 2 | /.tinyusb* 3 | /.ps2x2pico* 4 | /.build/ 5 | /*.uf2 6 | -------------------------------------------------------------------------------- /hid/pico/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | set(PICO_SDK_PATH ${CMAKE_CURRENT_LIST_DIR}/.pico-sdk) 4 | set(PICO_TINYUSB_PATH ${CMAKE_CURRENT_LIST_DIR}/.tinyusb) 5 | set(PS2_PATH ${CMAKE_CURRENT_LIST_DIR}/.ps2x2pico/src) 6 | 7 | # For TinyUSB 8 | set(FAMILY rp2040) 9 | 10 | # Include pico_sdk_import.cmake from pico-sdk (instead of copying) 11 | include(${PICO_SDK_PATH}/external/pico_sdk_import.cmake) 12 | 13 | # Generic setup 14 | set(PROJECT hid) 15 | project(${PROJECT}) 16 | 17 | # Initialize Pico-SDK 18 | pico_sdk_init() 19 | 20 | # Set the path to the source code to build 21 | set(SRC_TO_BUILD_PATH ${CMAKE_CURRENT_LIST_DIR}/src) 22 | add_subdirectory(${SRC_TO_BUILD_PATH}) 23 | -------------------------------------------------------------------------------- /hid/pico/Makefile: -------------------------------------------------------------------------------- 1 | all: deps 2 | rm -f hid.uf2 3 | cmake -B .build 4 | cmake --build .build --config Release -- -j 5 | ln .build/src/hid.uf2 . 6 | 7 | 8 | upload: install 9 | install: all 10 | sudo mount /dev/sda1 /mnt 11 | sudo cp hid.uf2 /mnt 12 | sudo umount /mnt 13 | 14 | 15 | clean: 16 | rm -rf .build hid.uf2 17 | clean-all: clean 18 | rm -rf .pico-sdk* .tinyusb* .ps2x2pico 19 | 20 | 21 | define libdep 22 | rm -rf .$(1).tmp 23 | git clone https://github.com/$(2) .$(1).tmp 24 | cd .$(1).tmp \ 25 | && git checkout $(3) \ 26 | && (test ! -f .gitmodules || git submodule update --init) 27 | mv .$(1).tmp .$(1) 28 | endef 29 | .pico-sdk: 30 | $(call libdep,pico-sdk,raspberrypi/pico-sdk,6a7db34ff63345a7badec79ebea3aaef1712f374) 31 | .tinyusb: 32 | $(call libdep,tinyusb,hathach/tinyusb,d713571cd44f05d2fc72efc09c670787b74106e0) 33 | .ps2x2pico: 34 | $(call libdep,ps2x2pico,No0ne/ps2x2pico,26ce89d597e598bb0ac636622e064202d91a9efc) 35 | deps: .pico-sdk .tinyusb .ps2x2pico 36 | 37 | 38 | .PHONY: deps 39 | -------------------------------------------------------------------------------- /hid/pico/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(target_name hid) 2 | add_executable(${target_name}) 3 | 4 | target_sources(${target_name} PRIVATE 5 | main.c 6 | ph_outputs.c 7 | ph_usb.c 8 | ph_usb_kbd.c 9 | ph_usb_mouse.c 10 | ph_ps2.c 11 | ph_cmds.c 12 | ph_com.c 13 | ph_com_bridge.c 14 | ph_com_spi.c 15 | ph_com_uart.c 16 | ph_debug.c 17 | 18 | ${PS2_PATH}/ps2out.c 19 | ${PS2_PATH}/ps2in.c 20 | ${PS2_PATH}/ps2kb.c 21 | ${PS2_PATH}/ps2ms.c 22 | ${PS2_PATH}/scancodes.c 23 | ) 24 | target_link_options(${target_name} PRIVATE -Xlinker --print-memory-usage) 25 | target_compile_options(${target_name} PRIVATE -Wall -Wextra) 26 | target_include_directories(${target_name} PRIVATE ${CMAKE_CURRENT_LIST_DIR} ${PS2_PATH}) 27 | 28 | pico_generate_pio_header(${target_name} ${PS2_PATH}/ps2out.pio) 29 | pico_generate_pio_header(${target_name} ${PS2_PATH}/ps2in.pio) 30 | 31 | target_link_libraries(${target_name} PRIVATE 32 | pico_stdlib 33 | pico_unique_id 34 | hardware_pio 35 | hardware_spi 36 | hardware_watchdog 37 | tinyusb_device 38 | ) 39 | pico_add_extra_outputs(${target_name}) 40 | -------------------------------------------------------------------------------- /hid/pico/src/ph_com.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | *****************************************************************************/ 21 | 22 | 23 | #pragma once 24 | 25 | #include "ph_types.h" 26 | 27 | 28 | void ph_com_init(void (*data_cb)(const u8 *), void (*timeout_cb)(void)); 29 | void ph_com_task(void); 30 | void ph_com_write(const u8 *data); 31 | -------------------------------------------------------------------------------- /hid/pico/src/ph_com_bridge.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | *****************************************************************************/ 21 | 22 | 23 | #pragma once 24 | 25 | #include "ph_types.h" 26 | 27 | 28 | void ph_com_bridge_init(void (*data_cb)(const u8 *), void (*timeout_cb)(void)); 29 | void ph_com_bridge_task(void); 30 | void ph_com_bridge_write(const u8 *data); 31 | -------------------------------------------------------------------------------- /hid/pico/src/ph_com_spi.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | *****************************************************************************/ 21 | 22 | 23 | #pragma once 24 | 25 | #include "ph_types.h" 26 | 27 | 28 | void ph_com_spi_init(void (*data_cb)(const u8 *), void (*timeout_cb)(void)); 29 | void ph_com_spi_task(void); 30 | void ph_com_spi_write(const u8 *data); 31 | -------------------------------------------------------------------------------- /hid/pico/src/ph_com_uart.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | *****************************************************************************/ 21 | 22 | 23 | #pragma once 24 | 25 | #include "ph_types.h" 26 | 27 | 28 | void ph_com_uart_init(void (*data_cb)(const u8 *), void (*timeout_cb)(void)); 29 | void ph_com_uart_task(void); 30 | void ph_com_uart_write(const u8 *data); 31 | -------------------------------------------------------------------------------- /hid/pico/src/ph_debug.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | *****************************************************************************/ 21 | 22 | 23 | #pragma once 24 | 25 | #include "ph_types.h" 26 | 27 | 28 | void ph_debug_uart_init(); 29 | void ph_debug_act_init(); 30 | void ph_debug_act(bool flag); 31 | void ph_debug_act_pulse(u64 delay_ms); 32 | -------------------------------------------------------------------------------- /hid/pico/src/ph_usb_kbd.h: -------------------------------------------------------------------------------- 1 | /* ========================================================================= # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================= */ 21 | 22 | 23 | #pragma once 24 | 25 | #include "ph_types.h" 26 | 27 | 28 | extern const u8 PH_USB_KBD_DESC[]; 29 | extern const uz PH_USB_KBD_DESC_LEN; 30 | -------------------------------------------------------------------------------- /hid/pico/src/ph_usb_mouse.h: -------------------------------------------------------------------------------- 1 | /* ========================================================================= # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================= */ 21 | 22 | 23 | #pragma once 24 | 25 | #include "ph_types.h" 26 | 27 | 28 | extern const u8 PH_USB_MOUSE_ABS_DESC[]; 29 | extern const uz PH_USB_MOUSE_ABS_DESC_LEN; 30 | 31 | extern const u8 PH_USB_MOUSE_REL_DESC[]; 32 | extern const uz PH_USB_MOUSE_REL_DESC_LEN; 33 | -------------------------------------------------------------------------------- /kvmd/__init__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | __version__ = "4.49" 24 | -------------------------------------------------------------------------------- /kvmd/apps/edidconf/__main__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | from . import main 24 | main() 25 | -------------------------------------------------------------------------------- /kvmd/apps/htpasswd/__main__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | from . import main 24 | main() 25 | -------------------------------------------------------------------------------- /kvmd/apps/ipmi/__main__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | from . import main 24 | main() 25 | -------------------------------------------------------------------------------- /kvmd/apps/janus/__main__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | from . import main 24 | main() 25 | -------------------------------------------------------------------------------- /kvmd/apps/kvmd/__main__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | from . import main 24 | main() 25 | -------------------------------------------------------------------------------- /kvmd/apps/kvmd/api/__init__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | -------------------------------------------------------------------------------- /kvmd/apps/media/__main__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2020 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | from . import main 24 | main() 25 | -------------------------------------------------------------------------------- /kvmd/apps/ngxmkconf/__main__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | from . import main 24 | main() 25 | -------------------------------------------------------------------------------- /kvmd/apps/oled/__main__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | from . import main 24 | main() 25 | -------------------------------------------------------------------------------- /kvmd/apps/oled/fonts/ProggySquare.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mofeng-git/One-KVM/10fb78abe6117894556573acd661c266df74efde/kvmd/apps/oled/fonts/ProggySquare.ttf -------------------------------------------------------------------------------- /kvmd/apps/oled/pics/hello.ppm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mofeng-git/One-KVM/10fb78abe6117894556573acd661c266df74efde/kvmd/apps/oled/pics/hello.ppm -------------------------------------------------------------------------------- /kvmd/apps/oled/pics/pikvm.ppm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mofeng-git/One-KVM/10fb78abe6117894556573acd661c266df74efde/kvmd/apps/oled/pics/pikvm.ppm -------------------------------------------------------------------------------- /kvmd/apps/otg/__main__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | from . import main 24 | main() 25 | -------------------------------------------------------------------------------- /kvmd/apps/otg/hid/__init__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | import dataclasses 24 | 25 | 26 | # ===== 27 | @dataclasses.dataclass(frozen=True) 28 | class Hid: 29 | protocol: int 30 | subclass: int 31 | report_length: int 32 | report_descriptor: bytes 33 | -------------------------------------------------------------------------------- /kvmd/apps/otgconf/__main__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | from . import main 24 | main() 25 | -------------------------------------------------------------------------------- /kvmd/apps/otgmsd/__main__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | from . import main 24 | main() 25 | -------------------------------------------------------------------------------- /kvmd/apps/otgnet/__main__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | from . import main 24 | main() 25 | -------------------------------------------------------------------------------- /kvmd/apps/pst/__main__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | from . import main 24 | main() 25 | -------------------------------------------------------------------------------- /kvmd/apps/pstrun/__main__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | from . import main 24 | main() 25 | -------------------------------------------------------------------------------- /kvmd/apps/swctl/__main__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | from . import main 24 | main() 25 | -------------------------------------------------------------------------------- /kvmd/apps/totp/__main__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | from . import main 24 | main() 25 | -------------------------------------------------------------------------------- /kvmd/apps/vnc/__main__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2020 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | from . import main 24 | main() 25 | -------------------------------------------------------------------------------- /kvmd/apps/vnc/fonts/Azbuka04.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mofeng-git/One-KVM/10fb78abe6117894556573acd661c266df74efde/kvmd/apps/vnc/fonts/Azbuka04.ttf -------------------------------------------------------------------------------- /kvmd/apps/vnc/rfb/errors.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2020 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | from .... import tools 24 | 25 | 26 | # ===== 27 | class RfbError(Exception): 28 | pass 29 | 30 | 31 | class RfbConnectionError(RfbError): 32 | def __init__(self, msg: str, ex: Exception) -> None: 33 | super().__init__(f"{msg}: {tools.efmt(ex)}") 34 | -------------------------------------------------------------------------------- /kvmd/apps/watchdog/__main__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | from . import main 24 | main() 25 | -------------------------------------------------------------------------------- /kvmd/env.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | # ===== 24 | ETC_PREFIX = "" 25 | SYSFS_PREFIX = "" 26 | PROCFS_PREFIX = "" 27 | -------------------------------------------------------------------------------- /kvmd/errors.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | class OperationError(Exception): 24 | pass 25 | 26 | 27 | class IsBusyError(Exception): 28 | pass 29 | -------------------------------------------------------------------------------- /kvmd/helpers/__init__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | -------------------------------------------------------------------------------- /kvmd/helpers/remount/__main__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | from . import main 24 | main() 25 | -------------------------------------------------------------------------------- /kvmd/helpers/swapfiles/__main__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | from . import main 24 | main() 25 | -------------------------------------------------------------------------------- /kvmd/keyboard/__init__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | -------------------------------------------------------------------------------- /scripts/kvmd: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # ========================================================================== # 3 | # # 4 | # KVMD - The main PiKVM daemon. # 5 | # # 6 | # Copyright (C) 2023-2025 SilentWind # 7 | # # 8 | # This program is free software: you can redistribute it and/or modify # 9 | # it under the terms of the GNU General Public License as published by # 10 | # the Free Software Foundation, either version 3 of the License, or # 11 | # (at your option) any later version. # 12 | # # 13 | # This program is distributed in the hope that it will be useful, # 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 16 | # GNU General Public License for more details. # 17 | # # 18 | # You should have received a copy of the GNU General Public License # 19 | # along with this program. If not, see . # 20 | # # 21 | # ========================================================================== # 22 | 23 | cd / && python3 -m kvmd.apps.kvmd "$@" -------------------------------------------------------------------------------- /scripts/kvmd-htpasswd: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # ========================================================================== # 3 | # # 4 | # KVMD - The main PiKVM daemon. # 5 | # # 6 | # Copyright (C) 2023-2025 SilentWind # 7 | # # 8 | # This program is free software: you can redistribute it and/or modify # 9 | # it under the terms of the GNU General Public License as published by # 10 | # the Free Software Foundation, either version 3 of the License, or # 11 | # (at your option) any later version. # 12 | # # 13 | # This program is distributed in the hope that it will be useful, # 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 16 | # GNU General Public License for more details. # 17 | # # 18 | # You should have received a copy of the GNU General Public License # 19 | # along with this program. If not, see . # 20 | # # 21 | # ========================================================================== # 22 | 23 | cd / && python3 -m kvmd.apps.htpasswd "$@" -------------------------------------------------------------------------------- /scripts/kvmd-media: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # ========================================================================== # 3 | # # 4 | # KVMD - The main PiKVM daemon. # 5 | # # 6 | # Copyright (C) 2023-2025 SilentWind # 7 | # # 8 | # This program is free software: you can redistribute it and/or modify # 9 | # it under the terms of the GNU General Public License as published by # 10 | # the Free Software Foundation, either version 3 of the License, or # 11 | # (at your option) any later version. # 12 | # # 13 | # This program is distributed in the hope that it will be useful, # 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 16 | # GNU General Public License for more details. # 17 | # # 18 | # You should have received a copy of the GNU General Public License # 19 | # along with this program. If not, see . # 20 | # # 21 | # ========================================================================== # 22 | 23 | cd / && python3 -m kvmd.apps.media "$@" 24 | -------------------------------------------------------------------------------- /scripts/kvmd-otg: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # ========================================================================== # 3 | # # 4 | # KVMD - The main PiKVM daemon. # 5 | # # 6 | # Copyright (C) 2023-2025 SilentWind # 7 | # # 8 | # This program is free software: you can redistribute it and/or modify # 9 | # it under the terms of the GNU General Public License as published by # 10 | # the Free Software Foundation, either version 3 of the License, or # 11 | # (at your option) any later version. # 12 | # # 13 | # This program is distributed in the hope that it will be useful, # 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 16 | # GNU General Public License for more details. # 17 | # # 18 | # You should have received a copy of the GNU General Public License # 19 | # along with this program. If not, see . # 20 | # # 21 | # ========================================================================== # 22 | 23 | cd / && python3 -m kvmd.apps.otg "$@" -------------------------------------------------------------------------------- /scripts/kvmd-otgconf: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # ========================================================================== # 3 | # # 4 | # KVMD - The main PiKVM daemon. # 5 | # # 6 | # Copyright (C) 2023-2025 SilentWind # 7 | # # 8 | # This program is free software: you can redistribute it and/or modify # 9 | # it under the terms of the GNU General Public License as published by # 10 | # the Free Software Foundation, either version 3 of the License, or # 11 | # (at your option) any later version. # 12 | # # 13 | # This program is distributed in the hope that it will be useful, # 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 16 | # GNU General Public License for more details. # 17 | # # 18 | # You should have received a copy of the GNU General Public License # 19 | # along with this program. If not, see . # 20 | # # 21 | # ========================================================================== # 22 | 23 | cd / && python3 -m kvmd.apps.otgconf "$@" -------------------------------------------------------------------------------- /scripts/kvmd-totp: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # ========================================================================== # 3 | # # 4 | # KVMD - The main PiKVM daemon. # 5 | # # 6 | # Copyright (C) 2023-2025 SilentWind # 7 | # # 8 | # This program is free software: you can redistribute it and/or modify # 9 | # it under the terms of the GNU General Public License as published by # 10 | # the Free Software Foundation, either version 3 of the License, or # 11 | # (at your option) any later version. # 12 | # # 13 | # This program is distributed in the hope that it will be useful, # 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 16 | # GNU General Public License for more details. # 17 | # # 18 | # You should have received a copy of the GNU General Public License # 19 | # along with this program. If not, see . # 20 | # # 21 | # ========================================================================== # 22 | 23 | cd / && python3 -m kvmd.apps.totp "$@" -------------------------------------------------------------------------------- /scripts/kvmd-vnc: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # ========================================================================== # 3 | # # 4 | # KVMD - The main PiKVM daemon. # 5 | # # 6 | # Copyright (C) 2023-2025 SilentWind # 7 | # # 8 | # This program is free software: you can redistribute it and/or modify # 9 | # it under the terms of the GNU General Public License as published by # 10 | # the Free Software Foundation, either version 3 of the License, or # 11 | # (at your option) any later version. # 12 | # # 13 | # This program is distributed in the hope that it will be useful, # 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 16 | # GNU General Public License for more details. # 17 | # # 18 | # You should have received a copy of the GNU General Public License # 19 | # along with this program. If not, see . # 20 | # # 21 | # ========================================================================== # 22 | 23 | cd / && python3 -m kvmd.apps.vnc "$@" -------------------------------------------------------------------------------- /supervisord.conf: -------------------------------------------------------------------------------- 1 | 2 | [program:kvmd-webterm] 3 | command=/usr/local/bin/ttyd --interface=/run/kvmd/ttyd.sock --port=0 --writable /bin/bash -c '/etc/kvmd/armbain-motd; bash' 4 | directory=/ 5 | autostart=true 6 | autorestart=true 7 | priority=14 8 | stopasgroup=true 9 | stdout_logfile=/dev/stdout 10 | stdout_logfile_maxbytes = 0 11 | redirect_stderr=true 12 | 13 | [program:kvmd-vnc] 14 | command=python -m kvmd.apps.vnc --run 15 | directory=/ 16 | autostart=true 17 | autorestart=true 18 | priority=11 19 | stopasgroup=true 20 | stdout_logfile=/dev/stdout 21 | stdout_logfile_maxbytes = 0 22 | redirect_stderr=true 23 | 24 | [program:kvmd-ipmi] 25 | command=python -m kvmd.apps.ipmi --run 26 | directory=/ 27 | autostart=true 28 | autorestart=true 29 | priority=12 30 | stopasgroup=true 31 | stdout_logfile=/dev/stdout 32 | stdout_logfile_maxbytes = 0 33 | redirect_stderr=true 34 | -------------------------------------------------------------------------------- /switch/LICENSE: -------------------------------------------------------------------------------- 1 | The PiKVM Switch Firmware 2 | Copyright (C) 2024-2025 3 | 4 | This software is distributed in binary form and is allowed for run only on original PiKVM Switch hardware. 5 | 6 | Modifications are not allowed. 7 | 8 | One day we will publish the source code, but not today. 9 | 10 | ===== 11 | Includes other software related under other licenses: 12 | - MIT: TinyUSB - Copyright (c) 2018, hathach (tinyusb.org). 13 | - MIT: Pico-PIO-USB - Copyright (c) 2021 sekigon-gonnoc. 14 | - BSD: Pico-SDK - Copyright 2020 (c) 2020 Raspberry Pi (Trading) Ltd. 15 | - BSD: FatFS - Copyright (C) 20xx, ChaN, all right reserved. 16 | -------------------------------------------------------------------------------- /switch/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | @echo "Run 'make install'" 3 | 4 | upload: install 5 | install: 6 | mount `python -m kvmd.apps.swctl bootloader 0` mnt 7 | cp switch.uf2 mnt 8 | umount mnt 9 | -------------------------------------------------------------------------------- /switch/mnt/README: -------------------------------------------------------------------------------- 1 | This is a mount point for the switch. 2 | -------------------------------------------------------------------------------- /switch/switch.uf2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mofeng-git/One-KVM/10fb78abe6117894556573acd661c266df74efde/switch/switch.uf2 -------------------------------------------------------------------------------- /testenv/env.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | 22 | 23 | # ===== 24 | ETC_PREFIX = "/fake_etc" 25 | SYSFS_PREFIX = "/fake_sysfs" 26 | PROCFS_PREFIX = "/fake_procfs" 27 | -------------------------------------------------------------------------------- /testenv/fakes/etc/fstab: -------------------------------------------------------------------------------- 1 | LABEL=PIPST /var/lib/kvmd/pst ext4 nodev,nosuid,noexec,ro,errors=remount-ro,data=journal,X-kvmd.pst-user=kvmd-pst 0 0 2 | LABEL=PIMSD /var/lib/kvmd/msd ext4 nodev,nosuid,noexec,ro,errors=remount-ro,data=journal,X-kvmd.otgmsd-user=kvmd 0 0 3 | -------------------------------------------------------------------------------- /testenv/fakes/proc/device-tree/model: -------------------------------------------------------------------------------- 1 | Virtual Raspberry Pi 2 | -------------------------------------------------------------------------------- /testenv/fakes/proc/device-tree/serial-number: -------------------------------------------------------------------------------- 1 | 0000000000000000 2 | -------------------------------------------------------------------------------- /testenv/fakes/sys/bus/platform/drivers/dwc2/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mofeng-git/One-KVM/10fb78abe6117894556573acd661c266df74efde/testenv/fakes/sys/bus/platform/drivers/dwc2/.gitignore -------------------------------------------------------------------------------- /testenv/fakes/sys/class/thermal/thermal_zone0/temp: -------------------------------------------------------------------------------- 1 | 36511 2 | -------------------------------------------------------------------------------- /testenv/fakes/sys/class/udc/fe980000.usb/device/driver: -------------------------------------------------------------------------------- 1 | ../../../../bus/platform/drivers/dwc2 -------------------------------------------------------------------------------- /testenv/fakes/sys/class/udc/fe980000.usb/state: -------------------------------------------------------------------------------- 1 | configured 2 | -------------------------------------------------------------------------------- /testenv/fakes/sys/kernel/config/usb_gadget/kvmd/configs/c.1/mass_storage.usb0: -------------------------------------------------------------------------------- 1 | ../../functions/mass_storage.usb0 -------------------------------------------------------------------------------- /testenv/fakes/sys/kernel/config/usb_gadget/kvmd/functions/mass_storage.usb0/lun.0/cdrom: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /testenv/fakes/sys/kernel/config/usb_gadget/kvmd/functions/mass_storage.usb0/lun.0/file: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mofeng-git/One-KVM/10fb78abe6117894556573acd661c266df74efde/testenv/fakes/sys/kernel/config/usb_gadget/kvmd/functions/mass_storage.usb0/lun.0/file -------------------------------------------------------------------------------- /testenv/fakes/sys/kernel/config/usb_gadget/kvmd/functions/mass_storage.usb0/lun.0/forced_eject: -------------------------------------------------------------------------------- 1 | file -------------------------------------------------------------------------------- /testenv/fakes/sys/kernel/config/usb_gadget/kvmd/functions/mass_storage.usb0/lun.0/ro: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /testenv/fakes/vcgencmd: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | case $1 in 3 | get_throttled) echo "throttled=0x0";; 4 | esac 5 | -------------------------------------------------------------------------------- /testenv/linters/coverage.ini: -------------------------------------------------------------------------------- 1 | [run] 2 | data_file = testenv/.coverage 3 | omit = 4 | */__main__.py, 5 | -------------------------------------------------------------------------------- /testenv/linters/eslintrc.js: -------------------------------------------------------------------------------- 1 | const js = require("/usr/lib/node_modules/eslint/node_modules/@eslint/js/src/index.js"); 2 | const globals = require("/usr/lib/node_modules/eslint/node_modules/@eslint/eslintrc/node_modules/globals/index.js"); 3 | const parser = require("/usr/lib/node_modules/@babel/eslint-parser/lib/index.cjs"); 4 | 5 | module.exports = [ 6 | js.configs.recommended, 7 | 8 | { 9 | files: ["**/*.js"], 10 | languageOptions: { 11 | globals: globals.browser, 12 | ecmaVersion: 2015, 13 | parser: parser, 14 | parserOptions: { 15 | ecmaVersion: 2025, 16 | sourceType: "module", 17 | allowImportExportEverywhere: true, 18 | requireConfigFile: false, 19 | }, 20 | }, 21 | }, 22 | 23 | { 24 | rules: { 25 | indent: [ 26 | "error", 27 | "tab", 28 | {SwitchCase: 1}, 29 | ], 30 | "linebreak-style": [ 31 | "error", 32 | "unix", 33 | ], 34 | quotes: [ 35 | "error", 36 | "double", 37 | ], 38 | "quote-props": [ 39 | "error", 40 | "always", 41 | ], 42 | "semi": [ 43 | "error", 44 | "always", 45 | ], 46 | "comma-dangle": [ 47 | "error", 48 | "always-multiline", 49 | ], 50 | "no-unused-vars": [ 51 | "error", 52 | {vars: "local", args: "after-used"}, 53 | ], 54 | }, 55 | }, 56 | 57 | ]; 58 | -------------------------------------------------------------------------------- /testenv/linters/flake8.ini: -------------------------------------------------------------------------------- 1 | [flake8] 2 | inline-quotes = double 3 | max-line-length = 160 4 | ignore = W503, E221, E227, E241, E252, Q003 5 | # W503 line break before binary operator 6 | # E221 multiple spaces before operator 7 | # E227 missing whitespace around bitwise or shift operator 8 | # E241 multiple spaces after 9 | # E252 missing whitespace around parameter equals 10 | # Q003 Change outer quotes to avoid escaping inner quotes 11 | -------------------------------------------------------------------------------- /testenv/linters/htmlhint.json: -------------------------------------------------------------------------------- 1 | { 2 | "src-not-empty": false 3 | } 4 | -------------------------------------------------------------------------------- /testenv/linters/mypy.ini: -------------------------------------------------------------------------------- 1 | [mypy] 2 | python_version = 3.11 3 | ignore_missing_imports = true 4 | disallow_untyped_defs = true 5 | strict_optional = true 6 | -------------------------------------------------------------------------------- /testenv/linters/pylint.ini: -------------------------------------------------------------------------------- 1 | [MASTER] 2 | ignore = .git 3 | extension-pkg-whitelist = 4 | setproctitle, 5 | gpiod, 6 | spidev, 7 | netifaces, 8 | _ldap, 9 | ustreamer, 10 | hid, 11 | 12 | [DESIGN] 13 | min-public-methods = 0 14 | max-args = 10 15 | 16 | [TYPECHECK] 17 | ignored-classes= 18 | AioQueue, 19 | 20 | [MESSAGES CONTROL] 21 | disable = 22 | file-ignored, 23 | locally-disabled, 24 | fixme, 25 | missing-docstring, 26 | superfluous-parens, 27 | duplicate-code, 28 | broad-except, 29 | redundant-keyword-arg, 30 | wrong-import-order, 31 | too-many-ancestors, 32 | no-else-return, 33 | len-as-condition, 34 | raise-missing-from, 35 | consider-using-in, 36 | unsubscriptable-object, 37 | unused-private-member, 38 | unspecified-encoding, 39 | consider-using-f-string, 40 | unnecessary-lambda-assignment, 41 | too-many-positional-arguments, 42 | no-else-continue, 43 | # https://github.com/PyCQA/pylint/issues/3882 44 | 45 | [CLASSES] 46 | exclude-protected = 47 | _unpack, 48 | 49 | [REPORTS] 50 | msg-template = {symbol} -- {path}:{line}({obj}): {msg} 51 | 52 | [FORMAT] 53 | max-line-length = 160 54 | 55 | [BASIC] 56 | # Good variable names which should always be accepted, separated by a comma 57 | good-names = _, __, x, y, ws 58 | 59 | # Regular expression matching correct method names 60 | method-rgx = [a-z_][a-z0-9_]{2,50}$ 61 | 62 | # Regular expression matching correct function names 63 | function-rgx = [a-z_][a-z0-9_]{2,50}$ 64 | 65 | # Regular expression which should only match correct module level names 66 | const-rgx = ([a-zA-Z_][a-zA-Z0-9_]*)$ 67 | 68 | # Regular expression which should only match correct argument names 69 | argument-rgx = [a-z_][a-z0-9_]{1,30}$ 70 | 71 | # Regular expression which should only match correct variable names 72 | variable-rgx = [a-z_][a-z0-9_]{1,30}$ 73 | 74 | # Regular expression which should only match correct instance attribute names 75 | attr-rgx = [a-z_][a-z0-9_]{1,30}$ 76 | -------------------------------------------------------------------------------- /testenv/platform: -------------------------------------------------------------------------------- 1 | PIKVM_MODEL=test_model 2 | PIKVM_VIDEO=test_video 3 | PIKVM_BOARD=test_board 4 | -------------------------------------------------------------------------------- /testenv/requirements.txt: -------------------------------------------------------------------------------- 1 | python-periphery 2 | pyserial-asyncio 3 | pyghmi 4 | spidev 5 | pyrad 6 | types-PyYAML 7 | types-aiofiles 8 | luma.oled 9 | pyfatfs 10 | -------------------------------------------------------------------------------- /testenv/run/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mofeng-git/One-KVM/10fb78abe6117894556573acd661c266df74efde/testenv/run/.gitignore -------------------------------------------------------------------------------- /testenv/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | -------------------------------------------------------------------------------- /testenv/tests/apps/__init__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | -------------------------------------------------------------------------------- /testenv/tests/apps/htpasswd/__init__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | -------------------------------------------------------------------------------- /testenv/tests/apps/kvmd/__init__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | -------------------------------------------------------------------------------- /testenv/tests/keyboard/__init__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | -------------------------------------------------------------------------------- /testenv/tests/plugins/__init__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | -------------------------------------------------------------------------------- /testenv/tests/validators/__init__.py: -------------------------------------------------------------------------------- 1 | # ========================================================================== # 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | # ========================================================================== # 21 | -------------------------------------------------------------------------------- /testenv/v2-hdmiusb-rpi4.override.yaml: -------------------------------------------------------------------------------- 1 | kvmd: 2 | server: 3 | unix_mode: 0666 4 | 5 | atx: 6 | type: disabled 7 | 8 | hid: 9 | keyboard: 10 | device: /dev/null 11 | mouse: 12 | device: /dev/null 13 | noop: true 14 | 15 | mouse_alt: 16 | device: /dev/null 17 | 18 | 19 | wol: 20 | mac: 00:00:00:00:00:00 21 | 22 | msd: 23 | type: otg 24 | remount_cmd: /bin/true 25 | msd_path: /var/lib/kvmd/msd 26 | normalfiles_path: NormalFiles 27 | normalfiles_size: 64 28 | 29 | streamer: 30 | cmd: 31 | - "/usr/bin/ustreamer" 32 | - "--device=/dev/video0" 33 | - "--persistent" 34 | - "--format=mjpeg" 35 | - "--resolution={resolution}" 36 | - "--desired-fps={desired_fps}" 37 | - "--drop-same-frames=30" 38 | - "--last-as-blank=0" 39 | - "--unix={unix}" 40 | - "--unix-rm" 41 | - "--unix-mode=0666" 42 | - "--exit-on-parent-death" 43 | - "--process-name-prefix={process_name_prefix}" 44 | - "--notify-parent" 45 | - "--no-log-colors" 46 | 47 | pst: 48 | remount_cmd: /bin/true 49 | 50 | vnc: 51 | keymap: /usr/share/kvmd/keymaps/ru 52 | 53 | auth: 54 | vncauth: 55 | enabled: true 56 | 57 | memsink: 58 | jpeg: 59 | sink: "" 60 | h264: 61 | sink: "" 62 | 63 | otgnet: 64 | commands: 65 | post_start_cmd: 66 | - "/bin/true" 67 | pre_stop_cmd: 68 | - "/bin/true" 69 | 70 | nginx: 71 | http: 72 | port: 8080 73 | https: 74 | port: 4430 75 | 76 | janus: 77 | cmd: 78 | - "/bin/true" 79 | -------------------------------------------------------------------------------- /testenv/web.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mofeng-git/One-KVM/10fb78abe6117894556573acd661c266df74efde/testenv/web.css -------------------------------------------------------------------------------- /web/extras/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mofeng-git/One-KVM/10fb78abe6117894556573acd661c266df74efde/web/extras/.gitignore -------------------------------------------------------------------------------- /web/extras/webterm/terminal.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /web/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mofeng-git/One-KVM/10fb78abe6117894556573acd661c266df74efde/web/favicon.ico -------------------------------------------------------------------------------- /web/index.pug: -------------------------------------------------------------------------------- 1 | extends start.pug 2 | 3 | append vars 4 | - title = "One-KVM Index" 5 | - main_js = "index/main" 6 | - css_list = css_list.concat(["window", "modal", "index/index"]) 7 | 8 | block start 9 | table 10 | tr 11 | td(class="logo") 12 | a(href="https://pikvm.org" target="_blank") 13 | img(class="svg-gray" src=`${svg_dir}/logo.svg` alt="PiKVM" height="40") 14 | td 15 | table 16 | tr #[td(colspan="2" class="title" i18n="index_title") The Open Source KVM over IP] 17 | tr 18 | td(colspan="2" class="copyright" i18n="copyright") 19 | | Copyright © 2018-2024 Maxim Devaev | Modified by SilentWind 20 | 21 | hr 22 | 23 | div(id="apps-box") 24 | h4 Loading ... 25 | 26 | hr 27 | table 28 | td(class="server") 29 | td(i18n="serve_name") Server: 30 | td #[a(id="kvmd-meta-server-host" target="_blank" href="/api/info")] 31 | 32 | div(id="app-keyboard-warning") 33 | p(class="text" i18n="index_text_1") 34 | | Please note that when you are working with a KVM session or another application that captures the keyboard, 35 | | you can't use some keyboard shortcuts such as Ctrl+Alt+Del (which will be caught by your OS) or Ctrl+W (caught by your browser). 36 | p(class="text" i18n="index_text_2") 37 | | To override this limitation you can use #[a(target="_blank" href="https://google.com/chrome") Google Chrome] 38 | | or #[a(target="_blank" href="https://chromium.org/Home") Chromium] in application mode. 39 | 40 | hr 41 | p(class="text credits") 42 | a(target="_blank" href="https://github.com/mofeng-git/One-KVM" i18n="index_text_12") One-KVM Project 43 | |   |   44 | a(target="_blank" href="https://one-kvm.mofeng.run" i18n="index_text_13") One-KVM Documentation -------------------------------------------------------------------------------- /web/ipmi/index.pug: -------------------------------------------------------------------------------- 1 | extends ../start.pug 2 | 3 | append vars 4 | - title = "One-KVM IPMI Info" 5 | - main_js = "ipmi/main" 6 | - index_link = true 7 | 8 | block start 9 | p(class="text" i18n="ipmi_text1") 10 | | This PiKVM device has running #[b kvmd-ipmi] daemon and provides IPMI 2.0 interface for some basic 11 | | BMC operations like on/off/reset the server. 12 | p(class="text" i18n="ipmi_text2") 13 | | #[b WARNING!] We strongly don't recommend you to use IPMI in untrusted networks because 14 | | this protocol is completely unsafe by design. In short, the authentication process for IPMI mandates 15 | | that the server send a salted SHA1 or MD5 hash of the requested user's password to the client, 16 | | prior to the client authenticating. 17 | p(class="text" i18n="ipmi_text3") 18 | | #[b NEVER] use the same passwords for KVMD and IPMI users. And even better not to use IPMI. 19 | | Instead, you can directly use KVMD API via curl. Here some examples: 20 | div(id="ipmi-text" class="code" style="max-height:200px") 21 | -------------------------------------------------------------------------------- /web/kvm/index.pug: -------------------------------------------------------------------------------- 1 | extends ../base.pug 2 | 3 | append vars 4 | - title = "One-KVM Session" 5 | - main_js = "kvm/main" 6 | - body_class = "body-no-select" 7 | - css_list = css_list.concat(["navbar", "window", "modal", "led", "slider", "switch", "radio", "progress", "keypad", "tabs"]) 8 | - css_list = css_list.concat(["kvm/stream", "kvm/hid", "kvm/msd", "kvm/system", "kvm/keyboard", "kvm/about"]) 9 | 10 | block body 11 | include navbar.pug 12 | include windows.pug 13 | 14 | ul(class="navbar-bg-tips") 15 | li(class="left") 16 | pre(id="kvmd-meta-tips-left") 17 | li(class="right") 18 | pre(id="kvmd-meta-tips-right") 19 | 20 | ul(class="footer") 21 | li(class="left") 22 | span(id="kvmd-meta-server-host" title="Server name (see System/About)") 23 | |   |   24 | span(id="kvmd-version-kvmd" title="KVMD version") 25 | |   |   26 | span(id="kvmd-version-streamer" title="Streamer version") 27 | li(class="right") 28 | a(target="_blank" href="https://github.com/mofeng-git/One-KVM" i18n="index_text_12") One-KVM Project 29 | |   |   30 | a(target="_blank" href="https://one-kvm.mofeng.run" i18n="index_text_13") One-KVM Documentation 31 | -------------------------------------------------------------------------------- /web/kvm/navbar-atx.pug: -------------------------------------------------------------------------------- 1 | li(id="atx-dropdown" class="right feature-disabled") 2 | a(class="menu-button" href="#") 3 | +navbar_led("atx-power-led", "led-atx-power") 4 | +navbar_led("atx-hdd-led", "led-atx-hdd") 5 | span ATX 6 | div(class="menu") 7 | div(class="text") 8 | b Control the server's power#[br] 9 | sub Use the short click for ACPI shutdown 10 | hr 11 | +menu_switch("atx-ask-switch", "Ask click confirmation", true, true,"atx-ask-switch") 12 | hr 13 | div(class="buttons") 14 | button(disabled data-force-hide-menu id="atx-power-button") • Click Power #[sup #[i short]] 15 | button(disabled data-force-hide-menu id="atx-power-button-long") • Click Power #[sup #[i long]] 16 | hr 17 | button(disabled data-force-hide-menu id="atx-reset-button") • Click Reset 18 | -------------------------------------------------------------------------------- /web/kvm/navbar-gpio.pug: -------------------------------------------------------------------------------- 1 | li(id="gpio-dropdown" class="right feature-disabled") 2 | a(class="menu-button" id="gpio-menu-button" href="#") 3 | span GPIO 4 | div(id="gpio-menu" class="menu") 5 | -------------------------------------------------------------------------------- /web/kvm/navbar-health.pug: -------------------------------------------------------------------------------- 1 | div(id="hw-health-dropdown" class="hidden") 2 | li(class="left") 3 | a(class="menu-button" href="#") 4 | +navbar_led("hw-health-undervoltage-led", "led-undervoltage", "hidden") 5 | +navbar_led("hw-health-overheating-led", "led-overheating", "hidden") 6 | div(class="menu") 7 | +menu_message("warning", "Raspberry Pi's health is at risk") 8 | | This is not a drill! A red icon indicates a current issue,#[br] 9 | | a yellow one that was observed since the device booted up 10 | div(id="hw-health-message-undervoltage" class="hidden") 11 | hr 12 | +menu_message("led-undervoltage", "Undervoltage detected", "led-gray") 13 | | Make sure your power supply and cabling are providing#[br] 14 | | enough power to the Raspberry Pi (3A minimum) 15 | div(id="hw-health-message-overheating" class="hidden") 16 | hr 17 | +menu_message("led-overheating", "Overheating detected", "led-gray") 18 | | Frequency capping due to overheating,#[br] 19 | | please improve cooling of the Raspberry Pi 20 | 21 | div(id="fan-health-dropdown" class="hidden") 22 | li(class="left") 23 | a(class="menu-button" href="#") 24 | +navbar_led("fan-health-led", "led-fan", "hidden") 25 | div(class="menu") 26 | +menu_message("warning", "Raspberry Pi's health is at risk") 27 | | This is not a drill! A red icon indicates a current issue,#[br] 28 | | a yellow one that was observed in the past 29 | div(id="fan-health-message-fail") 30 | hr 31 | +menu_message("led-fan", "Fan failed", "led-gray") 32 | | A fan error occured, please #[a(href="/api/log?seek=3600&follow=1" target="_blank") check the log] 33 | -------------------------------------------------------------------------------- /web/kvm/navbar-macro.pug: -------------------------------------------------------------------------------- 1 | li(id="macro-dropdown" class="right") 2 | a(class="menu-button" href="#") 3 | +navbar_led("hid-recorder-led", "led-gear") 4 | span(i18n="kvm_text32") Macro 5 | div(class="menu") 6 | div(class="text") 7 | b(i18n="kvm_text33") Record and play HID/ATX/GPIO actions#[br] 8 | sub(i18n="kvm_text34") For security reasons, the record will not be saved on the PiKVM 9 | hr 10 | div(class="buttons buttons-row") 11 | button(disabled data-force-hide-menu id="hid-recorder-record" class="row25" i18n="kvm_text35") • Rec 12 | button(disabled id="hid-recorder-stop" class="row25" i18n="kvm_text36") Stop 13 | button(disabled id="hid-recorder-play" class="row25" i18n="kvm_text37") Play 14 | button(disabled id="hid-recorder-clear" class="row25" i18n="kvm_text38") Clear 15 | hr 16 | table(class="kv") 17 | tr 18 | td(i18n="kvm_text39") Script time: 19 | td(colspan="2" id="hid-recorder-time" class="value") 00:00:00.0 20 | tr 21 | td(i18n="kvm_text40") Scripted events: 22 | td(id="hid-recorder-events-count" class="value") 0 23 | td #[sup #[i(i18n="kvm_text41") include delays]] 24 | hr 25 | +menu_switch("hid-recorder-loop-switch", "Infinite loop playback", false, false, "hid-recorder-loop-switch") 26 | hr 27 | input(type="file" id="hid-recorder-new-script-file") 28 | div(class="buttons buttons-row") 29 | button(disabled id="hid-recorder-upload" class="row50" i18n="kvm_text42") Upload script 30 | button(disabled id="hid-recorder-download" class="row50" i18n="kvm_text43") Download script 31 | -------------------------------------------------------------------------------- /web/kvm/navbar-switch.pug: -------------------------------------------------------------------------------- 1 | li(id="switch-dropdown" class="right feature-disabled") 2 | a(class="menu-button" id="switch-menu-button" href="#") 3 | +navbar_led("switch-atx-power-led", "led-atx-power") 4 | +navbar_led("switch-atx-hdd-led", "led-atx-hdd") 5 | span Switch #[i #[sub(id="switch-active-port") ]] 6 | div(id="switch-menu" class="menu") 7 | table(style="border-spacing: 0px;") 8 | tr 9 | td 10 | div(class="text") 11 | b #[a(target="_blank" href="https://docs.pikvm.org/switch") PiKVM Switch] is attached#[br] 12 | sub Select a port or perform any available action like ATX click 13 | td 14 | div(class="text") 15 | button(data-force-hide-menu data-show-window="switch-window" class="small") • Settings 16 | hr 17 | div(id="switch-message-update" class="hidden") 18 | +menu_message("info", "Good news! Your switch is ready to get the firmware update") 19 | | Please #[a(target="_blank" href="https://docs.pikvm.org/switch/#firmware-updating") follow the instructions] when you decide to install it. 20 | hr 21 | +menu_switch("switch-atx-ask-switch", "Ask ATX click confirmation", true, true) 22 | hr 23 | table(id="switch-chain" class="kv") 24 | -------------------------------------------------------------------------------- /web/kvm/navbar.pug: -------------------------------------------------------------------------------- 1 | mixin navbar_led(id, icon, cls="led-gray") 2 | img(id=id, class=cls src=`${svg_dir}/${icon}.svg`) 3 | 4 | mixin menu_message(icon, short, classes="", i18nid) 5 | div(class="text") 6 | table 7 | tr 8 | td(rowspan="2") #[img(class=`sign ${classes}` src=`${svg_dir}/${icon}.svg`)] 9 | td(style="line-height:1.5") #[b(i18n=i18nid) #{short}] 10 | if block 11 | tr 12 | td 13 | sup(style="line-height:1") 14 | block 15 | 16 | mixin menu_switch_notable_gpio(channel, title, confirm_off="") 17 | td !{title}: 18 | td(align="right") 19 | div(class="switch-box") 20 | input(disabled type="checkbox" id=`__gpio-switch-${channel}` class=`__gpio-switch-${channel} gpio-switch` 21 | data-channel=channel data-confirm-off=confirm_off) 22 | label(for=`__gpio-switch-${channel}`) 23 | span(class="switch-inner") 24 | span(class="switch") 25 | 26 | mixin menu_switch_notable(id, title, enabled, checked, i18nid) 27 | td(i18n=i18nid) !{title}: 28 | td(align="right") 29 | div(class="switch-box") 30 | input(checked=checked disabled=!enabled type="checkbox" id=id) 31 | label(for=id) 32 | span(class="switch-inner") 33 | span(class="switch") 34 | 35 | mixin menu_switch(id, title, enabled, checked, i18nid) 36 | table(class="kv") 37 | tr 38 | +menu_switch_notable(id, title, enabled, checked, i18nid) 39 | 40 | ul(id="navbar") 41 | li(class="left") 42 | a(id="logo" href="/") ←   43 | img(class="svg-gray" src=`${svg_dir}/logo.svg` alt="π-kvm") 44 | 45 | include navbar-health.pug 46 | 47 | include navbar-system.pug 48 | include navbar-atx.pug 49 | include navbar-msd.pug 50 | include navbar-macro.pug 51 | include navbar-text.pug 52 | include navbar-shortcuts.pug 53 | include navbar-gpio.pug 54 | include navbar-switch.pug 55 | -------------------------------------------------------------------------------- /web/kvm/window-webterm.pug: -------------------------------------------------------------------------------- 1 | div(id="webterm-window" class="window window-resizable" style="width: 640px; height: 480px") 2 | div(class="window-header") 3 | div(class="window-grab" i18n="kvm_text16") Terminal 4 | button(class="window-button-close") #[b ×] 5 | button(class="window-button-maximize") ☐ 6 | // Терминал глючит из-за зажимаемой клавиши ESC для выхода 7 | // button(class="window-button-full-screen") ⤢ 8 | iframe(id="webterm-iframe" src="" style="width: 100%; height: 100%") 9 | -------------------------------------------------------------------------------- /web/kvm/windows.pug: -------------------------------------------------------------------------------- 1 | include window-stream.pug 2 | include window-keyboard.pug 3 | include window-switch.pug 4 | include window-about.pug 5 | include window-webterm.pug 6 | -------------------------------------------------------------------------------- /web/login/index.pug: -------------------------------------------------------------------------------- 1 | extends ../base.pug 2 | 3 | append vars 4 | - title = "One-KVM Login" 5 | - main_js = "login/main" 6 | - css_list = css_list.concat(["window", "modal", "login/login"]) 7 | 8 | block body 9 | form(action="javascript:void(0)") 10 | div(id="login-box") 11 | div(id="login") 12 | table 13 | tr 14 | td(i18n="username") Username:  15 | td #[input(type="text" id="user-input" autocapitalize="off")] 16 | tr 17 | td(i18n="password") Password:  18 | td #[input(type="password" id="passwd-input" autocapitalize="off")] 19 | tr 20 | td(i18n="2fa_code") 2FA code:  21 | td #[input(type="text" id="code-input" placeholder="if enabled" i18n="if_enabled")] 22 | tr 23 | td(colspan=2) 24 | hr 25 | tr 26 | td(i18n="select_language") Select language:  27 | td 28 | select(id="selectLanguage" style="width:100%") 29 | option(id='zh', selected="selected" i18n="chinese") Simplified Chinese 30 | option(id='en' i18n="english") English 31 | tr 32 | td 33 | td #[button(id="login-button" class="key" style="width:100%" i18n="login") Login] 34 | 35 | ul(class="footer") 36 | li(class="left" i18n="footer-left") 37 | | This site is actively using JavaScript.#[br] 38 | | It doesn't contain ads, but is blocked by some ad filters.#[br] 39 | | Please turn it off to continue and reload the page. 40 | -------------------------------------------------------------------------------- /web/robots.txt: -------------------------------------------------------------------------------- 1 | User-Agent: * 2 | Disallow: / 3 | -------------------------------------------------------------------------------- /web/share/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mofeng-git/One-KVM/10fb78abe6117894556573acd661c266df74efde/web/share/android-chrome-192x192.png -------------------------------------------------------------------------------- /web/share/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mofeng-git/One-KVM/10fb78abe6117894556573acd661c266df74efde/web/share/apple-touch-icon.png -------------------------------------------------------------------------------- /web/share/css/kvm/hid.css: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | *****************************************************************************/ 21 | 22 | 23 | div#text-menu { 24 | width: 340px; 25 | } 26 | 27 | input#hid-recorder-new-script-file { 28 | display: none; 29 | } 30 | -------------------------------------------------------------------------------- /web/share/css/kvm/keyboard.css: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | *****************************************************************************/ 21 | 22 | 23 | div#keyboard-desktop { 24 | display: block; 25 | } 26 | div#keyboard-mobile { 27 | display: none; 28 | } 29 | -------------------------------------------------------------------------------- /web/share/css/kvm/msd.css: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | *****************************************************************************/ 21 | 22 | 23 | div#msd-menu { 24 | width: 450px; 25 | } 26 | 27 | div#msd-menu div.msd-message, 28 | div#msd-menu input.msd-message { 29 | display: none; 30 | } 31 | 32 | div#msd-menu select#msd-image-selector { 33 | width: 100%; 34 | } 35 | -------------------------------------------------------------------------------- /web/share/css/kvm/system.css: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | # # 3 | # KVMD - The main PiKVM daemon. # 4 | # # 5 | # Copyright (C) 2018-2024 Maxim Devaev # 6 | # # 7 | # This program is free software: you can redistribute it and/or modify # 8 | # it under the terms of the GNU General Public License as published by # 9 | # the Free Software Foundation, either version 3 of the License, or # 10 | # (at your option) any later version. # 11 | # # 12 | # This program is distributed in the hope that it will be useful, # 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 15 | # GNU General Public License for more details. # 16 | # # 17 | # You should have received a copy of the GNU General Public License # 18 | # along with this program. If not, see . # 19 | # # 20 | *****************************************************************************/ 21 | 22 | 23 | div#system-menu { 24 | min-width: 400px; 25 | max-width: 400px; 26 | } 27 | -------------------------------------------------------------------------------- /web/share/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mofeng-git/One-KVM/10fb78abe6117894556573acd661c266df74efde/web/share/favicon-16x16.png -------------------------------------------------------------------------------- /web/share/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mofeng-git/One-KVM/10fb78abe6117894556573acd661c266df74efde/web/share/favicon-32x32.png -------------------------------------------------------------------------------- /web/share/js/i18n/jquery.i18n.min.js: -------------------------------------------------------------------------------- 1 | (function($){$.fn.extend({i18n:function(options){var defaults={lang:"",defaultLang:"",filePath:"/i18n/",filePrefix:"i18n_",fileSuffix:"",forever:true,callback:function(){}};function getCookie(name){var arr=document.cookie.split('; ');for(var i=0;i 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /web/share/svg/led-beacon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /web/share/svg/led-usb.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /web/start.pug: -------------------------------------------------------------------------------- 1 | extends base.pug 2 | 3 | append vars 4 | - css_list.push("start") 5 | - var index_link = false 6 | 7 | block body 8 | div(class="start-box") 9 | div(class="start") 10 | if index_link 11 | a(style="display:inline-block; margin-top:4px; color:#5c90bc; text-decoration:none" href="/" i18n="index") 12 | |   ←   [ One-KVM Index ] 13 | hr 14 | block start 15 | -------------------------------------------------------------------------------- /web/vnc/index.pug: -------------------------------------------------------------------------------- 1 | extends ../start.pug 2 | 3 | append vars 4 | - title = "One-KVM VNC info" 5 | - main_js = "vnc/main" 6 | - index_link = true 7 | 8 | block start 9 | p(class="text" i18n="vnc_text1") 10 | | This PiKVM device has running #[b kvmd-vnc] daemon and provides VNC access to the server. 11 | p(class="text" i18n="vnc_text2") 12 | | #[b WARNING!] We strongly don't recommend you to use VNC in untrusted networks without 13 | | enabled X.509 or TLS encryption. Otherwise your passwords are transmitted in a plain text 14 | | over the network. 15 | p(class="text" i18n="vnc_text3") 16 | | Your VNC client must support Tight JPEG compression and password authentication. 17 | | #[a(href="https://tigervnc.org") TigerVNC] is a good choice. 18 | | On Linux, this client will most likely be available for installation from the repository. 19 | | It can also be called vncviewer. 20 | div(id="vnc-text" class="code" style="max-height:200px") 21 | --------------------------------------------------------------------------------