Implement python virtual environment (#326)

* Implement python virtual environment

  * added venv instead of using system env pip
  * adjusted the unit file to startup the app from the venv
  * created a wrapper script to call the app from the venv
  * extended cleanup for venv and additional scripts
  * refactored the is_running() function to find the process now that it
    is called from a venv

* remove update_service_file since we changed the binary path to the venv location

* fix bug in argument handling; upgrade pip before installing python packages

* fix bug in syntax

* Renamed auto-cpufreq wrapper

* Change permissions to use --stats as user

* Changed init scripts to use wrapper

Co-authored-by: aroundthfur <velimir@foolcontrol.org>
This commit is contained in:
bobslept 2021-12-21 20:14:02 +01:00 committed by GitHub
parent dd5d871769
commit 6e3f45182b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 68 additions and 30 deletions

View File

@ -34,8 +34,14 @@ function root_check {
}
# python packages install
function pip_pkg_install {
python3 -m pip install -r requirements.txt
function setup_venv {
venv_dir=/opt/auto-cpufreq/venv
mkdir -p "${venv_dir}"
python3 -m venv "${venv_dir}"
source "${venv_dir}/bin/activate"
python3 -m pip install --upgrade pip
python3 -m pip install -r requirements.txt
}
# tool install
@ -43,12 +49,10 @@ function install {
python3 setup.py install --record files.txt
mkdir -p /usr/local/share/auto-cpufreq/
cp -r scripts/ /usr/local/share/auto-cpufreq/
}
function update_service_file {
echo -e "\nUpdating service file (/usr/local/bin/auto-cpufreq -> /usr/bin/auto-cpu-freq)"
sed -i 's|ExecStart=/usr/local/bin/auto-cpufreq|ExecStart=/usr/bin/auto-cpufreq|' \
/usr/local/share/auto-cpufreq/scripts/auto-cpufreq.service
# this is necessary since we need this script before we can run auto-cpufreq itself
cp scripts/auto-cpufreq-venv-wrapper /usr/local/bin/auto-cpufreq
chmod a+x /usr/local/bin/auto-cpufreq
}
# First argument is the distro
@ -61,7 +65,7 @@ function detected_distro() {
# merged functions pip - install - complete_msg, since it repeats
function completed () {
echo -e "\nInstalling necessary Python packages\n"
pip_pkg_install
setup_venv
separator
echo -e "\ninstalling auto-cpufreq tool\n"
install
@ -119,7 +123,6 @@ elif [ -f /etc/solus-release ]; then
eopkg install pip python3 python3-devel dmidecode
eopkg install -c system.devel
completed
update_service_file
complete_msg
elif [ -f /etc/os-release ];then
eval "$(cat /etc/os-release)"
@ -140,7 +143,6 @@ elif [ -f /etc/os-release ];then
detected_distro "Arch Linux based"
pacman -S --noconfirm --needed python python-pip python-setuptools base-devel dmidecode
completed
[ $ID != "artix" ] && update_service_file
;;
void)
detected_distro "Void Linux"
@ -164,7 +166,10 @@ function tool_remove {
srv_install="/usr/bin/auto-cpufreq-install"
srv_remove="/usr/bin/auto-cpufreq-remove"
stats_file="/var/run/auto-cpufreq.stats"
tool_proc_rm="auto-cpufreq --remove"
tool_proc_rm="/usr/local/bin/auto-cpufreq --remove"
wrapper_script="/usr/local/bin/auto-cpufreq"
unit_file="/etc/systemd/system/auto-cpufreq.service"
venv_path="/opt/auto-cpufreq"
# stop any running auto-cpufreq argument (daemon/live/monitor)
tool_arg_pids=($(pgrep -f "auto-cpufreq --"))
@ -187,6 +192,11 @@ function tool_remove {
[ -f $srv_install ] && rm $srv_install
[ -f $srv_remove ] && rm $srv_remove
[ -f $stats_file ] && rm $stats_file
[ -f $unit_file ] && rm $unit_file
[ -f $wrapper_script ] && rm $wrapper_script
# remove python virtual environment
rm -rf "${venv_path}"
separator
echo -e "\nauto-cpufreq tool and all its supporting files successfully removed."

View File

@ -1080,22 +1080,12 @@ def read_stats():
# check if program (argument) is running
def is_running(program, argument):
# iterate over all process id's found by psutil
for pid in psutil.pids():
try:
# requests the process information corresponding to each process id
proc = psutil.Process(pid)
# check if value of program-variable that was used to call the function
# matches the name field of the plutil.Process(pid) output
if program in proc.name():
# check output of p.name(), output name of program
# p.cmdline() - echo the exact command line via which p was called.
for arg in proc.cmdline():
if argument in str(arg):
return True
except Exception as e:
print(repr(e))
continue
# iterate over all processes found by psutil
# and find the one with name and args passed to the function
for p in psutil.process_iter():
for s in filter(lambda x: program in x, p.cmdline()):
if argument in p.cmdline():
return True
def daemon_running_msg():
print("\n" + "-" * 24 + " auto-cpufreq running " + "-" * 30 + "\n")

View File

@ -3,7 +3,7 @@
name=$RC_SVCNAME
description="auto-cpufreq - Automatic CPU speed & power optimizer for Linux"
supervisor="supervise-daemon"
command="/usr/bin/auto-cpufreq"
command="/usr/local/bin/auto-cpufreq"
command_args="--daemon"
command_user="root"

View File

@ -1,2 +1,2 @@
#!/bin/sh
exec /usr/bin/auto-cpufreq --daemon
exec /usr/local/bin/auto-cpufreq --daemon

View File

@ -0,0 +1,34 @@
#!/bin/sh
# Wrapper script around auto-cpufreq using the python virtual environment
set -eu
# get script name
PROGNAME=$(basename "${0}")
# bailout function
err_exit()
{
echo "${PROGNAME}: ${1:-wrong invocation. try --help for help.}" 1>&2
exit 1
}
# invocation handling
#
param=""
if [ "${#}" -ne 1 ];
then
err_exit
else
param="${1}"
fi
# load python virtual environment
venv_dir=/opt/auto-cpufreq/venv
. "${venv_dir}/bin/activate"
# run python code with venv loaded
PYTHONPATH=/opt/auto-cpufreq \
/opt/auto-cpufreq/venv/bin/python \
/opt/auto-cpufreq/venv/bin/auto-cpufreq \
"${param}"

View File

@ -5,6 +5,10 @@ After=network.target network-online.target
[Service]
Type=simple
User=root
ExecStart=/usr/local/bin/auto-cpufreq --daemon
WorkingDirectory=/opt/auto-cpufreq/venv
Environment=PYTHONPATH=/opt/auto-cpufreq
ExecStart=/opt/auto-cpufreq/venv/bin/python /opt/auto-cpufreq/venv/bin/auto-cpufreq --daemon
Restart=on-failure
[Install]
WantedBy=multi-user.target