Skip to content

Commit

Permalink
Add build python-fuse
Browse files Browse the repository at this point in the history
  • Loading branch information
honjow committed Jan 10, 2025
1 parent dcaf000 commit 1060b65
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 35 deletions.
16 changes: 15 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
steps:
- name: set git global safe directory
run: |
pacman -Syu git npm --noconfirm
pacman -Syu git npm tree --noconfirm
git config --global --add safe.directory $(realpath .)
- uses: actions/checkout@v3
Expand All @@ -36,6 +36,20 @@ jobs:
make
cp -f ryzenadj ../../../bin
- name: build python-fuse
run: |
PWD=$(pwd)
echo "PWD: $PWD"
mkdir -p py_modules/site-packages
pacman -S python-fuse python-setuptools python-wheel python-installer --noconfirm --needed --overwrite='*'
cd ${PWD}/submodule/python-fuse && \
PYTHONPATH=${PWD}/py_modules/site-packages \
python3 setup.py install --prefix=${PWD} --install-lib=install
cd ${PWD}
ls -R ${PWD}
cp -a submodule/python-fuse/install/fuse*/fuse* py_modules/site-packages/
- name: change log level
run: |
sed -i 's/logging.DEBUG/logging.INFO/' py_modules/config.py
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ coverage
node_modules
bower_components
# py_modules
py_modules/site-packages

# Editors
.idea
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "submodule/RyzenAdj"]
path = submodule/RyzenAdj
url = https://github.com/FlyGoat/RyzenAdj.git
[submodule "submodule/python-fuse"]
path = submodule/python-fuse
url = https://github.com/libfuse/python-fuse.git
13 changes: 13 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ deploy-steamdeck: ## Deploy plugin build to steamdeck
@rsync -azp --delete --progress -e "ssh -p $(DECK_PORT) -i $(DECK_KEY)" \
--chmod=Du=rwx,Dg=rx,Do=rx,Fu=rwx,Fg=rx,Fo=rx \
--exclude='.git/' \
--exclude='*.pyc' \
--exclude='.github/' \
--exclude='.vscode/' \
--exclude='node_modules/' \
Expand All @@ -79,6 +80,18 @@ deploy-steamdeck: ## Deploy plugin build to steamdeck
@ssh $(DECK_USER)@$(DECK_HOST) -p $(DECK_PORT) -i $(DECK_KEY) \
'chmod -v 755 $(DECK_HOME)/homebrew/plugins/'

local-fuse: ## Copy fuse module to local site-packages
@echo "+ $@"
@mkdir -p ./py_modules/site-packages
@rm -rf ./py_modules/site-packages/fuse* ./py_modules/site-packages/fuseparts
@rm -rf ./submodule/python-fuse/build
@cd ./submodule/python-fuse && \
PYTHONPATH=$(PWD)/py_modules/site-packages \
python3 setup.py install --prefix=$(PWD) --install-lib=install && \
cp -r ./install/fuse*/fuse* $(PWD)/py_modules/site-packages/
@rm -rf $(PWD)/submodule/python-fuse/build


restart-decky: ## Restart Decky on remote steamdeck
@echo "+ $@"
@ssh -t $(DECK_USER)@$(DECK_HOST) -p $(DECK_PORT) -i $(DECK_KEY) \
Expand Down
2 changes: 2 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import decky
import sys

try:
import update
Expand All @@ -9,6 +10,7 @@
from fuse_manager import FuseManager
from gpu import gpuManager
from sysInfo import sysInfoManager
sys.path.append(f"{decky.DECKY_PLUGIN_DIR}/py_modules/site-packages")
except Exception as e:
decky.logger.error(e, exc_info=True)

Expand Down
49 changes: 25 additions & 24 deletions py_modules/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

import decky
import yaml
from helpers import get_homebrew_path
from logging_handler import SystemdHandler

# 日志配置
Expand Down Expand Up @@ -41,18 +40,33 @@ def setup_logger():
# 初始化 logger
logger = setup_logger()


DECKY_PLUGIN_DIR = decky.DECKY_PLUGIN_DIR
DECKY_PLUGIN_PY_DIR = f"{DECKY_PLUGIN_DIR}/py_modules"
SH_PATH = "{}/backend/sh_tools.sh".format(DECKY_PLUGIN_DIR)
RYZENADJ_PATH = "{}/bin/ryzenadj".format(DECKY_PLUGIN_DIR)
# AMD_GPU_DEVICE_PATH = glob.glob("/sys/class/drm/card?/device")[0]
# AMD_GPUFREQ_PATH = "{}/pp_od_clk_voltage".format(AMD_GPU_DEVICE_PATH)
# AMD_GPULEVEL_PATH = "{}/power_dpm_force_performance_level".format(AMD_GPU_DEVICE_PATH)
PLATFORM_PROFILE_PATH = "/sys/firmware/acpi/platform_profile"
PLATFORM_PROFILE_CHOICES_PATH = "/sys/firmware/acpi/platform_profile_choices"

FAN_CONFIG_DIR = f"{DECKY_PLUGIN_PY_DIR}/fan_config"
FAN_HWMON_CONFIG_DIR = f"{FAN_CONFIG_DIR}/hwmon"
FAN_EC_CONFIG_DIR = f"{FAN_CONFIG_DIR}/ec"

HWMON_CONFS = glob.glob(f"{FAN_HWMON_CONFIG_DIR}/*.yml")
EC_CONFS = glob.glob(f"{FAN_EC_CONFIG_DIR}/*.yml")

HWMON_SCHEMA = f"{FAN_CONFIG_DIR}/schema/hwmon.json"
EC_SCHEMA = f"{FAN_CONFIG_DIR}/schema/ec.json"

API_URL = "https://api.github.com/repos/mengmeet/PowerControl/releases/latest"

CONFIG_KEY = "PowerControl"

# 路径配置
try:
HOMEBREW_PATH = get_homebrew_path()
DECKY_PLUGIN_DIR = decky.DECKY_PLUGIN_DIR
SH_PATH = "{}/backend/sh_tools.sh".format(DECKY_PLUGIN_DIR)
RYZENADJ_PATH = "{}/bin/ryzenadj".format(DECKY_PLUGIN_DIR)
# AMD_GPU_DEVICE_PATH = glob.glob("/sys/class/drm/card?/device")[0]
# AMD_GPUFREQ_PATH = "{}/pp_od_clk_voltage".format(AMD_GPU_DEVICE_PATH)
# AMD_GPULEVEL_PATH = "{}/power_dpm_force_performance_level".format(AMD_GPU_DEVICE_PATH)
PLATFORM_PROFILE_PATH = "/sys/firmware/acpi/platform_profile"
PLATFORM_PROFILE_CHOICES_PATH = "/sys/firmware/acpi/platform_profile_choices"

for p in glob.glob("/sys/class/drm/card?"):
if os.path.exists(f"{p}/device/enable"):
with open(f"{p}/device/enable", "r") as f:
Expand All @@ -74,9 +88,6 @@ def setup_logger():
INTEL_GPU_MIN_LIMIT = f"{p}/gt_RPn_freq_mhz"
INTEL_GPU_CUR_FREQ = f"{p}/gt_cur_freq_mhz"
break

FAN_HWMON_CONFIG_DIR = f"{DECKY_PLUGIN_DIR}/backend/fan_config/hwmon"
FAN_EC_CONFIG_DIR = f"{DECKY_PLUGIN_DIR}/backend/fan_config/ec"
except Exception as e:
logger.error(f"路径配置异常|{e}", exc_info=True)

Expand All @@ -96,9 +107,6 @@ def setup_logger():
except Exception as e:
logger.error(f"设备信息配置异常|{e}", exc_info=True)

API_URL = "https://api.github.com/repos/mengmeet/PowerControl/releases/latest"

CONFIG_KEY = "PowerControl"

# 是否验证 yml 配置文件
VERIFY_YML = False
Expand Down Expand Up @@ -178,13 +186,6 @@ def load_yaml(file_path: str, chk_schema=None) -> dict:
return data


HWMON_CONFS = glob.glob(f"{FAN_HWMON_CONFIG_DIR}/*.yml")
EC_CONFS = glob.glob(f"{FAN_EC_CONFIG_DIR}/*.yml")

HWMON_SCHEMA = f"{DECKY_PLUGIN_DIR}/py_modules/fan_config/schema/hwmon.json"
EC_SCHEMA = f"{DECKY_PLUGIN_DIR}/py_modules/fan_config/schema/ec.json"


def get_all_howmon_fans():
with open(HWMON_SCHEMA, "r") as f:
hwmon_schema = json.load(f)
Expand Down
20 changes: 16 additions & 4 deletions py_modules/fan.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import json

from conf_manager import confManager
from config import FAN_EC_CONFIG, FAN_HWMON_LIST, PRODUCT_NAME, PRODUCT_VERSION, logger
Expand Down Expand Up @@ -76,7 +77,9 @@ def update_fan_max_value(self, cpu_temp: int):

# 解析处理 HWMON 风扇配置
def __parse_fan_configuration_HWMON(self, name_path_map):
logger.info(f"解析 HWMON 风扇配置, len:{len(FAN_HWMON_LIST)}")
for hwmon_name in FAN_HWMON_LIST:
logger.debug(f"解析 HWMON 风扇配置, hwmon_name:{hwmon_name}")
if hwmon_name not in name_path_map:
continue
for hwmon_config in FAN_HWMON_LIST[hwmon_name]:
Expand Down Expand Up @@ -304,15 +307,20 @@ def __parse_fan_configuration_EC(self):
# 转化风扇配置
def parse_fan_configuration(self):
hwmon_path = "/sys/class/hwmon"
hwmon_files = os.listdir(hwmon_path)
hwmon_dirs = os.listdir(hwmon_path)
logger.info(f"解析 HWMON 风扇配置, hwmon_dirs:{hwmon_dirs}")
name_path_map = {}

umount_fuse_igpu()
try:
umount_fuse_igpu()
except Exception:
logger.error("umount_fuse_igpu error", exc_info=True)

# 转化hwmon信息
for file in hwmon_files:
path = hwmon_path + "/" + file
for dir in hwmon_dirs:
path = hwmon_path + "/" + dir
name = open(path + "/name").read().strip()
logger.debug(f">>> name:{name}, path:{path}")
name_path_map[name] = path
if name == "amdgpu":
self.gpu_temp_path = path + "/temp1_input"
Expand All @@ -325,6 +333,10 @@ def parse_fan_configuration(self):
if not self.cpu_temp_path and name == "acpitz":
self.cpu_temp_path = path + "/temp1_input"

logger.info(
f">>> name_path_map {json.dumps(name_path_map, indent=4, ensure_ascii=False)}"
)

# 解析 hwmon 信息
self.__parse_fan_configuration_HWMON(name_path_map)

Expand Down
39 changes: 33 additions & 6 deletions py_modules/pfuse/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
import os
import time
from threading import Event, Thread
import subprocess

from config import logger
import decky

TDP_MOUNT = "/run/powercontrol/hwmon"
FUSE_MOUNT_SOCKET = "/run/powercontrol/socket"
Expand Down Expand Up @@ -98,12 +100,25 @@ def prepare_tdp_mount(debug: bool = False, passhtrough: bool = False):
if not os.path.ismount(TDP_MOUNT):
logger.info(f"Creating bind mount for:\n'{gpu}'\nto:\n'{TDP_MOUNT}'")
cmd = f"mount --bind '{gpu}' '{TDP_MOUNT}'"
r = os.system(cmd)
assert not r, f"Failed:\n{cmd}"
try:
result = subprocess.run(
cmd, shell=True, capture_output=True, text=True, check=True
)
except subprocess.CalledProcessError as e:
error_msg = f"Failed to create bind mount:\nCommand: {cmd}\nReturn code: {e.returncode}\nError: {e.stderr}"
logger.error(error_msg)
raise RuntimeError(error_msg)

logger.info("Making bind mount private.")
cmd = f"mount --make-private '{TDP_MOUNT}'"
r = os.system(cmd)
assert not r, f"Failed:\n{cmd}"
try:
result = subprocess.run(
cmd, shell=True, capture_output=True, text=True, check=True
)
except subprocess.CalledProcessError as e:
error_msg = f"Failed to make mount private:\nCommand: {cmd}\nReturn code: {e.returncode}\nError: {e.stderr}"
logger.error(error_msg)
raise RuntimeError(error_msg)
else:
logger.info(f"Bind mount already exists at:\n'{TDP_MOUNT}'")

Expand All @@ -116,6 +131,11 @@ def prepare_tdp_mount(debug: bool = False, passhtrough: bool = False):
logger.info(f"Using Python: '{exe_python}'")
# get this file's directory
thisdir = os.path.dirname(os.path.abspath(__file__))

# add py_modules/site-packages to PYTHONPATH
custom_python_path = os.environ.get("PYTHONPATH", "")
custom_python_path += f":{decky.DECKY_PLUGIN_DIR}/py_modules/site-packages"
os.environ["PYTHONPATH"] = custom_python_path
cmd = (
f"{exe_python} {thisdir}/driver.py '{gpu}'"
+ f" -o root={TDP_MOUNT} -o nonempty -o allow_other"
Expand All @@ -125,8 +145,15 @@ def prepare_tdp_mount(debug: bool = False, passhtrough: bool = False):
if debug:
cmd += " -f"
logger.info(f"Executing:\n'{cmd}'")
r = os.system(cmd)
assert not r, f"Failed:\n{cmd}"
try:
result = subprocess.run(
cmd, shell=True, capture_output=True, text=True, check=True
)
logger.debug(f"Command output:\n{result.stdout}")
except subprocess.CalledProcessError as e:
error_msg = f"Failed to launch FUSE mount:\nCommand: {cmd}\nReturn code: {e.returncode}\nError: {e.stderr}"
logger.error(error_msg)
raise RuntimeError(error_msg)
except Exception:
logger.error("Error preparing fuse mount.", exc_info=True)
return False
Expand Down
1 change: 1 addition & 0 deletions submodule/python-fuse
Submodule python-fuse added at c4169e

0 comments on commit 1060b65

Please sign in to comment.