Skip to content

Commit

Permalink
Installation script adaptation for package maintainers (#37)
Browse files Browse the repository at this point in the history
* adapting the installation script and services to add options for package maintainers (--install-dir, --no-post-install), as well as extracting the post-install part in a separate script

* adapting the installation script and services to add options for package maintainers.
separating `--install-dir` (`/usr/bin`) into `--prefix-dir` (`/usr`) and `--dest-dir` (`/usr`).
adding the option to disable ectool installation (`--no-ectool`).
removing forgotten useless `sudo`

* moving sockets to `/run/fw-fanctrl` ([FHS standard](https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch03s15.html))

* adapting the installation script and services to add options for package maintainers
changes based on https://gist.github.com/icedream/567188afa09551e2bf63a83550406741
adding `--sysconf-dir` to specify default configuration directory
adding back legacy configuration transfer
fixing small issues
  • Loading branch information
leopoldhub committed May 23, 2024
1 parent 2f3accf commit fb4c933
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 60 deletions.
22 changes: 16 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ It is compatible with all kinds of 13" and 16" models, both AMD/Intel CPUs and w

## Dependancies

To communicate with the embedded controller the `ectool` is needed. You can either use the pre-compiled executable of `ectool` in this repo, or recompile one from [this repo](https://gitlab.howett.net/DHowett/ectool) and copy it in `./bin`.
To communicate with the embedded controller the `ectool` is required.
You can either use the precompiled executable of `ectool` in this repo or
disable its installation (`--no-ectool`) and add your own by recompiling it from [this repo](https://gitlab.howett.net/DHowett/ectool) and putting it in `[dest-dir(/)]/bin`.

You also need to disable secure boot of your device for `ectool` to work (more details about why [here](https://www.howett.net/posts/2021-12-framework-ec/#using-fw-ectool))

Expand All @@ -20,21 +22,29 @@ Then run:
sudo ./install.sh
```

This bash script is going to create and enable a service that runs this repo's main script, `fanctrl.py`.
It will copy `fanctrl.py` (to an executable file `fw-fanctrl`) and `./bin/ectool` to `/usr/local/bin` and create a config file in `/etc/fw-fanctrl/config.json`
This bash script will to create and activate a service that runs this repo's main script, `fanctrl.py`.
It will copy `fanctrl.py` (to an executable file `fw-fanctrl`) and `./bin/ectool` to `[dest-dir(/)]/bin` and create a config file
in `[dest-dir(/)][sysconf-dir(/etc)]/fw-fanctrl/config.json`

this script also includes options to:
- specify an installation destination directory (`--dest-dir <installation destination directory (defaults to /)>`).
- specify an installation prefix directory (`--prefix-dir <installation prefix directory (defaults to /usr)>`).
- specify a default configuration directory (`--sysconf-dir <system configuration destination directory (defaults to /etc)>`).
- disable ectool installation and service activation (`--no-ectool`)
- disable post-install process (`--no-post-install`)

# Update

To install an update, you can just pull the latest commit on the `main` branch of this repository, and run the install script again.
To install an update, you can pull the latest commit on the `main` branch of this repository, and run the install script again.

# Uninstall
```
sudo ./install.sh remove
sudo ./install.sh --remove
```

# Configuration

There is a single `config.json` file located at `/etc/fw-fanctrl/config.json`.
There is a single `config.json` file located at `[dest-dir(/)][sysconf-dir(/etc)]/fw-fanctrl/config.json`.

(You will need to reload the configuration with)
```
Expand Down
8 changes: 5 additions & 3 deletions fanctrl.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
import threading
from time import sleep

RESOURCE_FOLDER_PATH = "/etc/fw-fanctrl"
DEFAULT_CONFIGURATION_FILE_PATH = os.path.join(RESOURCE_FOLDER_PATH, "config.json")
COMMANDS_SOCKET_FILE_PATH = os.path.join(RESOURCE_FOLDER_PATH, ".fw-fanctrl.commands.sock")
DEFAULT_CONFIGURATION_FILE_PATH = "/etc/fw-fanctrl/config.json"
SOCKETS_FOLDER_PATH = "/run/fw-fanctrl"
COMMANDS_SOCKET_FILE_PATH = os.path.join(SOCKETS_FOLDER_PATH, ".fw-fanctrl.commands.sock")

parser = None

Expand Down Expand Up @@ -124,6 +124,8 @@ def bindSocket(self):
if os.path.exists(COMMANDS_SOCKET_FILE_PATH):
os.remove(COMMANDS_SOCKET_FILE_PATH)
try:
if not os.path.exists(SOCKETS_FOLDER_PATH):
os.makedirs(SOCKETS_FOLDER_PATH)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(COMMANDS_SOCKET_FILE_PATH)
os.chmod(COMMANDS_SOCKET_FILE_PATH, 0o777)
Expand Down
144 changes: 96 additions & 48 deletions install.sh
Original file line number Diff line number Diff line change
@@ -1,13 +1,61 @@
#!/bin/bash
set -e

if [ "$EUID" -ne 0 ]
then echo "This program requires root permissions"
exit 1
fi

LOGNAME="$(logname)"
USER="$LOGNAME"
HOME="$(eval echo "~$USER")"
# Argument parsing
SHORT=r,d:,p:,s:,h
LONG=remove,dest-dir:,prefix-dir:,sysconf-dir:,no-ectool,no-post-install,help
VALID_ARGS=$(getopt -a --options $SHORT --longoptions $LONG -- "$@")
if [[ $? -ne 0 ]]; then
exit 1;
fi

PREFIX_DIR="/usr"
DEST_DIR=""
SYSCONF_DIR="/etc"
SHOULD_INSTALL_ECTOOL=true
SHOULD_POST_INSTALL=true
SHOULD_REMOVE=false

eval set -- "$VALID_ARGS"
while true; do
case "$1" in
'--remove' | '-r')
SHOULD_REMOVE=true
;;
'--prefix-dir' | '-p')
PREFIX_DIR=$2
shift
;;
'--dest-dir' | '-d')
DEST_DIR=$2
shift
;;
'--sysconf-dir' | '-s')
SYSCONF_DIR=$2
shift
;;
'--no-ectool')
SHOULD_INSTALL_ECTOOL=false
;;
'--no-post-install')
SHOULD_POST_INSTALL=false
;;
'--help' | '-h')
echo "Usage: $0 [--remove,-r] [--dest-dir,-d <installation destination directory (defaults to $DEST_DIR)>] [--prefix-dir,-p <installation prefix directory (defaults to $PREFIX_DIR)>] [--sysconf-dir,-s system configuration destination directory (defaults to $SYSCONF_DIR)] [--no-ectool] [--no-post-install]" 1>&2
exit 0
;;
--)
break
;;
esac
shift
done
#

SERVICES_DIR="./services"
SERVICE_EXTENSION=".service"
Expand All @@ -25,22 +73,25 @@ function sanitizePath() {

# remove remaining legacy files
function uninstall_legacy() {
rm -rf "$HOME/.config/fw-fanctrl"
echo "removing legacy files"
rm "/usr/local/bin/fw-fanctrl" 2> "/dev/null" || true
rm "/usr/local/bin/ectool" 2> "/dev/null" || true
rm "/usr/local/bin/fanctrl.py" 2> "/dev/null" || true
rm "/etc/systemd/system/fw-fanctrl.service" 2> "/dev/null" || true
}

function uninstall() {
# remove program services based on the services present in the './services' folder
echo "removing services"
systemctl daemon-reload
for SERVICE in $SERVICES ; do
# be EXTRA CAREFUL about the validity of the paths (dont wanna delete something important, right?... O_O)
SERVICE=$(sanitizePath "$SERVICE")
sudo systemctl daemon-reload
echo "stopping [$SERVICE]"
sudo systemctl stop "$SERVICE"
systemctl stop "$SERVICE" 2> "/dev/null" || true
echo "disabling [$SERVICE]"
sudo systemctl disable "$SERVICE"
echo "removing '/etc/systemd/system/$SERVICE$SERVICE_EXTENSION'"
(cd "/etc/systemd/system/" && sudo rm -rf "$SERVICE$SERVICE_EXTENSION")
systemctl disable "$SERVICE" 2> "/dev/null" || true
rm -rf "$DEST_DIR$PREFIX_DIR/lib/systemd/system/$SERVICE$SERVICE_EXTENSION"
done

# remove program services sub-configurations based on the sub-configurations present in the './services' folder
Expand All @@ -51,52 +102,48 @@ function uninstall() {
SUBCONFIGS="$(cd "$SERVICES_DIR/$SERVICE" && find . -mindepth 1 -type f)"
for SUBCONFIG in $SUBCONFIGS ; do
SUBCONFIG=$(sanitizePath "$SUBCONFIG")
echo "removing '/usr/lib/systemd/$SERVICE/$SUBCONFIG'"
(cd "/usr/lib/systemd/" && cd "$SERVICE" && rm -rf "$SUBCONFIG")
echo "removing '$DEST_DIR$PREFIX_DIR/lib/systemd/$SERVICE/$SUBCONFIG'"
rm -rf "$DEST_DIR$PREFIX_DIR/lib/systemd/$SERVICE/$SUBCONFIG" 2> "/dev/null" || true
done
done

rm "/usr/local/bin/fw-fanctrl"
ectool autofanctrl # restore default fan manager
rm "/usr/local/bin/ectool"
rm -rf "/etc/fw-fanctrl"
rm "$DEST_DIR$PREFIX_DIR/bin/fw-fanctrl" 2> "/dev/null" || true
ectool autofanctrl 2> "/dev/null" || true # restore default fan manager
if [ "$SHOULD_INSTALL_ECTOOL" = true ]; then
rm "$DEST_DIR$PREFIX_DIR/bin/ectool" 2> "/dev/null" || true
fi
rm -rf "$DEST_DIR$SYSCONF_DIR/fw-fanctrl" 2> "/dev/null" || true
rm -rf "/run/fw-fanctrl" 2> "/dev/null" || true

uninstall_legacy
}

# move remaining legacy files
function move_legacy() {
rm "/usr/local/bin/fanctrl.py" 2> "/dev/null" || true
(cp "$HOME/.config/fw-fanctrl"/* "/etc/fw-fanctrl/" && rm -rf "$HOME/.config/fw-fanctrl") 2> "/dev/null" || true
}

function install() {
cp "./bin/ectool" "/usr/local/bin"
cp "./fanctrl.py" "/usr/local/bin/fw-fanctrl"
chmod +x "/usr/local/bin/fw-fanctrl"
chown "$LOGNAME:$LOGNAME" "/usr/local/bin/fw-fanctrl"
mkdir -p "$HOME/.config/fw-fanctrl"
mkdir -p "/etc/fw-fanctrl"
uninstall_legacy

cp -n "./config.json" "/etc/fw-fanctrl" 2> "/dev/null" || true
mkdir -p "$DEST_DIR$PREFIX_DIR/bin"
if [ "$SHOULD_INSTALL_ECTOOL" = true ]; then
cp "./bin/ectool" "$DEST_DIR$PREFIX_DIR/bin/ectool"
chmod +x "$DEST_DIR$PREFIX_DIR/bin/ectool"
fi
mkdir -p "$DEST_DIR$SYSCONF_DIR/fw-fanctrl"
cp "./fanctrl.py" "$DEST_DIR$PREFIX_DIR/bin/fw-fanctrl"
chmod +x "$DEST_DIR$PREFIX_DIR/bin/fw-fanctrl"

move_legacy
cp -n "./config.json" "$DEST_DIR$SYSCONF_DIR/fw-fanctrl" 2> "/dev/null" || true

# create program services based on the services present in the './services' folder
echo "creating '$DEST_DIR$PREFIX_DIR/lib/systemd/system'"
mkdir -p "$DEST_DIR$PREFIX_DIR/lib/systemd/system"
echo "creating services"
for SERVICE in $SERVICES ; do
SERVICE=$(sanitizePath "$SERVICE")
if [ "$(sudo systemctl is-active "$SERVICE")" == "active" ]; then
if [ "$(systemctl is-active "$SERVICE")" == "active" ]; then
echo "stopping [$SERVICE]"
sudo systemctl stop "$SERVICE"
systemctl stop "$SERVICE"
fi
echo "creating '/etc/systemd/system/$SERVICE$SERVICE_EXTENSION'"
sudo cp -f "$SERVICES_DIR/$SERVICE$SERVICE_EXTENSION" "/etc/systemd/system/$SERVICE$SERVICE_EXTENSION" > "/dev/null"
sudo systemctl daemon-reload
echo "enabling [$SERVICE]"
sudo systemctl enable "$SERVICE"
echo "starting [$SERVICE]"
sudo systemctl start "$SERVICE"
echo "creating '$DEST_DIR$PREFIX_DIR/lib/systemd/system/$SERVICE$SERVICE_EXTENSION'"
cat "$SERVICES_DIR/$SERVICE$SERVICE_EXTENSION" | sed -e "s/%PREFIX_DIRECTORY%/${PREFIX_DIR//\//\\/}/" | sed -e "s/%SYSCONF_DIRECTORY%/${SYSCONF_DIR//\//\\/}/" | tee "$DEST_DIR$PREFIX_DIR/lib/systemd/system/$SERVICE$SERVICE_EXTENSION" > "/dev/null"
done

# add program services sub-configurations based on the sub-configurations present in the './services' folder
Expand All @@ -106,28 +153,29 @@ function install() {
echo "adding sub-configurations for [$SERVICE]"
SUBCONFIG_FOLDERS="$(cd "$SERVICES_DIR/$SERVICE" && find . -mindepth 1 -maxdepth 1 -type d -exec basename {} \;)"
# ensure folders exists
mkdir -p "$DEST_DIR$PREFIX_DIR/lib/systemd/$SERVICE"
for SUBCONFIG_FOLDER in $SUBCONFIG_FOLDERS ; do
SUBCONFIG_FOLDER=$(sanitizePath "$SUBCONFIG_FOLDER")
echo "creating '/usr/lib/systemd/$SERVICE/$SUBCONFIG_FOLDER'"
(cd "/usr/lib/systemd/" && cd "$SERVICE" && sudo mkdir -p "$SUBCONFIG_FOLDER")
echo "creating '$DEST_DIR$PREFIX_DIR/lib/systemd/$SERVICE/$SUBCONFIG_FOLDER'"
mkdir -p "$DEST_DIR$PREFIX_DIR/lib/systemd/$SERVICE/$SUBCONFIG_FOLDER"
done
SUBCONFIGS="$(cd "$SERVICES_DIR/$SERVICE" && find . -mindepth 1 -type f)"
# add sub-configurations
for SUBCONFIG in $SUBCONFIGS ; do
SUBCONFIG=$(sanitizePath "$SUBCONFIG")
echo "adding '/usr/lib/systemd/$SERVICE/$SUBCONFIG'"
sudo cp -f "$SERVICES_DIR/$SERVICE/$SUBCONFIG" "/usr/lib/systemd/$SERVICE/$SUBCONFIG"
sudo chmod +x "/usr/lib/systemd/$SERVICE/$SUBCONFIG"
echo "adding '$DEST_DIR$PREFIX_DIR/lib/systemd/$SERVICE/$SUBCONFIG'"
cat "$SERVICES_DIR/$SERVICE/$SUBCONFIG" | sed -e "s/%PREFIX_DIRECTORY%/${PREFIX_DIR//\//\\/}/" | tee "$DEST_DIR$PREFIX_DIR/lib/systemd/$SERVICE/$SUBCONFIG" > "/dev/null"
chmod +x "$DEST_DIR$PREFIX_DIR/lib/systemd/$SERVICE/$SUBCONFIG"
done
done
if [ "$SHOULD_POST_INSTALL" = true ]; then
sh "./post-install.sh" --dest-dir "$DEST_DIR" --sysconf-dir "$SYSCONF_DIR"
fi
}

if [ "$1" = "remove" ]; then
if [ "$SHOULD_REMOVE" = true ]; then
uninstall
elif [[ "$1" =~ ^$|^-- ]]; then
install "$1"
else
echo "Unknown command '$1'"
exit 1
install
fi
exit 0
74 changes: 74 additions & 0 deletions post-install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/bin/bash
set -e

if [ "$EUID" -ne 0 ]
then echo "This program requires root permissions"
exit 1
fi

HOME_DIR="$(eval echo "~$(logname)")"

# Argument parsing
SHORT=d:,s:,h
LONG=dest-dir:,sysconf-dir:,help
VALID_ARGS=$(getopt -a --options $SHORT --longoptions $LONG -- "$@")
if [[ $? -ne 0 ]]; then
exit 1;
fi

DEST_DIR="/usr"
SYSCONF_DIR="/etc"

eval set -- "$VALID_ARGS"
while true; do
case "$1" in
'--dest-dir' | '-d')
DEST_DIR=$2
shift
;;
'--sysconf-dir' | '-s')
SYSCONF_DIR=$2
shift
;;
'--help' | '-h')
echo "Usage: $0 [--dest-dir,-d <installation destination directory (defaults to $DEST_DIR)>] [--sysconf-dir,-s system configuration destination directory (defaults to $SYSCONF_DIR)]" 1>&2
exit 0
;;
--)
break
;;
esac
shift
done
#

SERVICES_DIR="./services"
SERVICE_EXTENSION=".service"

SERVICES="$(cd "$SERVICES_DIR" && find . -maxdepth 1 -maxdepth 1 -type f -name "*$SERVICE_EXTENSION" -exec basename {} "$SERVICE_EXTENSION" \;)"

function sanitizePath() {
local SANITIZED_PATH="$1"
local SANITIZED_PATH=${SANITIZED_PATH//..\//}
local SANITIZED_PATH=${SANITIZED_PATH#./}
local SANITIZED_PATH=${SANITIZED_PATH#/}
echo "$SANITIZED_PATH"
}

# move remaining legacy files
function move_legacy() {
echo "moving legacy files to their new destination"
(cp "$HOME_DIR/.config/fw-fanctrl"/* "$DEST_DIR$SYSCONF_DIR/fw-fanctrl/" && rm -rf "$HOME_DIR/.config/fw-fanctrl") 2> "/dev/null" || true
}

move_legacy

echo "enabling services"
sudo systemctl daemon-reload
for SERVICE in $SERVICES ; do
SERVICE=$(sanitizePath "$SERVICE")
echo "enabling [$SERVICE]"
sudo systemctl enable "$SERVICE"
echo "starting [$SERVICE]"
sudo systemctl start "$SERVICE"
done
2 changes: 1 addition & 1 deletion services/fw-fanctrl.service
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ After=multi-user.target
[Service]
Type=simple
Restart=always
ExecStart=/usr/bin/python3 /usr/local/bin/fw-fanctrl --run --no-log
ExecStart=/usr/bin/python3 "%PREFIX_DIRECTORY%/bin/fw-fanctrl" --run --config "%SYSCONF_DIRECTORY%/fw-fanctrl/config.json" --no-log
ExecStopPost=/bin/sh -c "ectool autofanctrl"
[Install]
WantedBy=multi-user.target
4 changes: 2 additions & 2 deletions services/system-sleep/fw-fanctrl-suspend
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/sh

case $1 in
pre) /usr/bin/python3 /usr/local/bin/fw-fanctrl --pause ;;
post) /usr/bin/python3 /usr/local/bin/fw-fanctrl --resume ;;
pre) /usr/bin/python3 "%PREFIX_DIRECTORY%/bin/fw-fanctrl" --pause ;;
post) /usr/bin/python3 "%PREFIX_DIRECTORY%/bin/fw-fanctrl" --resume ;;
esac

0 comments on commit fb4c933

Please sign in to comment.