From e27f14523a539f64b3c31e2c3229c53f22af26e9 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Fri, 26 Jan 2024 14:05:50 +0100 Subject: [PATCH] changed dhcpcd timer from cron to systemd. add seperate daemon service for wpa-supplicant handling --- installation/includes/01_default_config.sh | 3 +- installation/routines/setup_autohotspot.sh | 2 + .../setup_autohotspot_NetworkManager.sh | 20 +++---- .../routines/setup_autohotspot_dhcpcd.sh | 44 +++++++++------- .../autohotspot/NetworkManager/autohotspot | 2 +- resources/autohotspot/dhcpcd/autohotspot | 2 +- .../dhcpcd/autohotspot-daemon.service | 10 ++++ .../autohotspot/dhcpcd/autohotspot.service | 6 +-- .../autohotspot/dhcpcd/autohotspot.timer | 10 ++++ .../components/hostif/linux/__init__.py | 52 ++++++++----------- 10 files changed, 86 insertions(+), 65 deletions(-) create mode 100644 resources/autohotspot/dhcpcd/autohotspot-daemon.service create mode 100644 resources/autohotspot/dhcpcd/autohotspot.timer diff --git a/installation/includes/01_default_config.sh b/installation/includes/01_default_config.sh index dac28f036..ca11da74f 100644 --- a/installation/includes/01_default_config.sh +++ b/installation/includes/01_default_config.sh @@ -4,7 +4,8 @@ BUILD_LIBZMQ_WITH_DRAFTS_ON_DEVICE=${BUILD_LIBZMQ_WITH_DRAFTS_ON_DEVICE:-"false" ENABLE_STATIC_IP=true DISABLE_IPv6=true ENABLE_AUTOHOTSPOT=false -AUTOHOTSPOT_SSID="Phoniebox_Hotspot" +AUTOHOTSPOT_PROFILE="Phoniebox_Hotspot" +AUTOHOTSPOT_SSID="$AUTOHOTSPOT_PROFILE" AUTOHOTSPOT_PASSWORD="PlayItLoud!" AUTOHOTSPOT_IP="10.0.0.1" AUTOHOTSPOT_COUNTRYCODE="DE" diff --git a/installation/routines/setup_autohotspot.sh b/installation/routines/setup_autohotspot.sh index c2a7e334a..23288b681 100644 --- a/installation/routines/setup_autohotspot.sh +++ b/installation/routines/setup_autohotspot.sh @@ -4,6 +4,8 @@ AUTOHOTSPOT_INTERFACES_CONF_FILE="/etc/network/interfaces" AUTOHOTSPOT_TARGET_PATH="/usr/bin/autohotspot" AUTOHOTSPOT_SERVICE="autohotspot.service" AUTOHOTSPOT_SERVICE_PATH="${SYSTEMD_PATH}/${AUTOHOTSPOT_SERVICE}" +AUTOHOTSPOT_TIMER="autohotspot.timer" +AUTOHOTSPOT_TIMER_PATH="${SYSTEMD_PATH}/${AUTOHOTSPOT_TIMER}" _get_interface() { # interfaces may vary diff --git a/installation/routines/setup_autohotspot_NetworkManager.sh b/installation/routines/setup_autohotspot_NetworkManager.sh index d7959219f..7366f638a 100644 --- a/installation/routines/setup_autohotspot_NetworkManager.sh +++ b/installation/routines/setup_autohotspot_NetworkManager.sh @@ -1,8 +1,7 @@ #!/usr/bin/env bash -AUTOHOTSPOT_TIMER="autohotspot.timer" -AUTOHOTSPOT_TIMER_PATH="${SYSTEMD_PATH}/${AUTOHOTSPOT_TIMER}" AUTOHOTSPOT_NETWORKMANAGER_RESOURCES_PATH="${INSTALLATION_PATH}/resources/autohotspot/NetworkManager" +AUTOHOTSPOT_NETWORKMANAGER_CONNECTIONS_PATH="/etc/NetworkManager/system-connections" _install_packages_NetworkManager() { sudo apt-get -y install iw @@ -18,6 +17,7 @@ _install_autohotspot_NetworkManager() { local ip_without_last_segment=$(_get_last_ip_segment $AUTOHOTSPOT_IP) sudo cp "${AUTOHOTSPOT_NETWORKMANAGER_RESOURCES_PATH}"/autohotspot "${AUTOHOTSPOT_TARGET_PATH}" sudo sed -i "s|%%WIFI_INTERFACE%%|${WIFI_INTERFACE}|g" "${AUTOHOTSPOT_TARGET_PATH}" + sudo sed -i "s|%%AUTOHOTSPOT_PROFILE%%|${AUTOHOTSPOT_PROFILE}|g" "${AUTOHOTSPOT_TARGET_PATH}" sudo sed -i "s|%%AUTOHOTSPOT_SSID%%|${AUTOHOTSPOT_SSID}|g" "${AUTOHOTSPOT_TARGET_PATH}" sudo sed -i "s|%%AUTOHOTSPOT_PASSWORD%%|${AUTOHOTSPOT_PASSWORD}|g" "${AUTOHOTSPOT_TARGET_PATH}" sudo sed -i "s|%%AUTOHOTSPOT_IP%%|${AUTOHOTSPOT_IP}|g" "${AUTOHOTSPOT_TARGET_PATH}" @@ -34,10 +34,8 @@ _install_autohotspot_NetworkManager() { sudo systemctl unmask "${AUTOHOTSPOT_SERVICE}" sudo systemctl unmask "${AUTOHOTSPOT_TIMER}" - sudo systemctl enable "${AUTOHOTSPOT_SERVICE}" + sudo systemctl disable "${AUTOHOTSPOT_SERVICE}" sudo systemctl enable "${AUTOHOTSPOT_TIMER}" - - sudo systemctl start "${AUTOHOTSPOT_TIMER}" } _uninstall_autohotspot_NetworkManager() { @@ -45,10 +43,10 @@ _uninstall_autohotspot_NetworkManager() { # stop services and clear services if systemctl list-unit-files "${AUTOHOTSPOT_SERVICE}" >/dev/null 2>&1 ; then - sudo systemctl stop "${AUTOHOTSPOT_SERVICE}" sudo systemctl stop "${AUTOHOTSPOT_TIMER}" - sudo systemctl disable "${AUTOHOTSPOT_SERVICE}" sudo systemctl disable "${AUTOHOTSPOT_TIMER}" + sudo systemctl stop "${AUTOHOTSPOT_SERVICE}" + sudo systemctl disable "${AUTOHOTSPOT_SERVICE}" sudo rm "${AUTOHOTSPOT_SERVICE_PATH}" sudo rm "${AUTOHOTSPOT_TIMER_PATH}" fi @@ -57,6 +55,8 @@ _uninstall_autohotspot_NetworkManager() { sudo rm "${AUTOHOTSPOT_TARGET_PATH}" fi + sudo rm -f "${AUTOHOTSPOT_NETWORKMANAGER_CONNECTIONS_PATH}/${AUTOHOTSPOT_PROFILE}" + # remove config files _config_file_revert "${AUTOHOTSPOT_INTERFACES_CONF_FILE}" } @@ -66,13 +66,15 @@ _autohotspot_check_NetworkManager() { verify_apt_packages iw - verify_service_enablement "${AUTOHOTSPOT_SERVICE}" enabled + verify_service_enablement "${AUTOHOTSPOT_SERVICE}" disabled + verify_service_enablement "${AUTOHOTSPOT_TIMER}" enabled verify_files_exists "${AUTOHOTSPOT_INTERFACES_CONF_FILE}" local ip_without_last_segment=$(_get_last_ip_segment $AUTOHOTSPOT_IP) verify_files_exists "${AUTOHOTSPOT_TARGET_PATH}" verify_file_contains_string "wdev0='${WIFI_INTERFACE}'" "${AUTOHOTSPOT_TARGET_PATH}" + verify_file_contains_string "ap_profile_name='${AUTOHOTSPOT_PROFILE}'" "${AUTOHOTSPOT_TARGET_PATH}" verify_file_contains_string "ap_ssid='${AUTOHOTSPOT_SSID}'" "${AUTOHOTSPOT_TARGET_PATH}" verify_file_contains_string "ap_pw='${AUTOHOTSPOT_PASSWORD}'" "${AUTOHOTSPOT_TARGET_PATH}" verify_file_contains_string "ap_ip='${AUTOHOTSPOT_IP}" "${AUTOHOTSPOT_TARGET_PATH}" #intentional "open end" @@ -94,5 +96,3 @@ _run_setup_autohotspot_NetworkManager() { _install_autohotspot_NetworkManager _autohotspot_check_NetworkManager } - - diff --git a/installation/routines/setup_autohotspot_dhcpcd.sh b/installation/routines/setup_autohotspot_dhcpcd.sh index e8c94de75..e48711416 100644 --- a/installation/routines/setup_autohotspot_dhcpcd.sh +++ b/installation/routines/setup_autohotspot_dhcpcd.sh @@ -9,6 +9,9 @@ AUTOHOTSPOT_DNSMASQ_CONF_FILE="/etc/dnsmasq.conf" AUTOHOTSPOT_DHCPCD_CONF_FILE="/etc/dhcpcd.conf" AUTOHOTSPOT_DHCPCD_CONF_NOHOOK_WPA_SUPPLICANT="nohook wpa_supplicant" +AUTOHOTSPOT_SERVICE_DAEMON="autohotspot-daemon@.service" # the '@' is no mistake and important to allow passing parameter! +AUTOHOTSPOT_SERVICE_DAEMON_PATH="${SYSTEMD_PATH}/${AUTOHOTSPOT_SERVICE_DAEMON}" + AUTOHOTSPOT_DHCPCD_RESOURCES_PATH="${INSTALLATION_PATH}/resources/autohotspot/dhcpcd" _install_packages_dhcpcd() { @@ -74,36 +77,38 @@ _install_autohotspot_dhcpcd() { sudo sed -i "s|%%AUTOHOTSPOT_IP%%|${AUTOHOTSPOT_IP}|g" "${AUTOHOTSPOT_TARGET_PATH}" sudo chmod +x "${AUTOHOTSPOT_TARGET_PATH}" + sudo cp "${AUTOHOTSPOT_DHCPCD_RESOURCES_PATH}"/autohotspot-daemon.service "${AUTOHOTSPOT_SERVICE_DAEMON_PATH}" + sudo cp "${AUTOHOTSPOT_DHCPCD_RESOURCES_PATH}"/autohotspot.service "${AUTOHOTSPOT_SERVICE_PATH}" sudo sed -i "s|%%AUTOHOTSPOT_SCRIPT%%|${AUTOHOTSPOT_TARGET_PATH}|g" "${AUTOHOTSPOT_SERVICE_PATH}" - sudo systemctl enable "${AUTOHOTSPOT_SERVICE}" + sudo cp "${AUTOHOTSPOT_DHCPCD_RESOURCES_PATH}"/autohotspot.timer "${AUTOHOTSPOT_TIMER_PATH}" + sudo sed -i "s|%%AUTOHOTSPOT_SERVICE%%|${AUTOHOTSPOT_SERVICE}|g" "${AUTOHOTSPOT_TIMER_PATH}" - # create crontab entry - local crontab_user=$(crontab -l 2>/dev/null) - if [[ -z "${crontab_user}" || ! $(echo "${crontab_user}" | grep -w "${AUTOHOTSPOT_TARGET_PATH}") ]]; then - (echo "${crontab_user}"; echo "*/5 * * * * sudo ${AUTOHOTSPOT_TARGET_PATH} 2>&1 | logger -t autohotspot") | crontab - - (echo "${crontab_user}"; echo "@reboot sudo ${AUTOHOTSPOT_TARGET_PATH} 2>&1 | logger -t autohotspot") | crontab - - fi + sudo systemctl disable "${AUTOHOTSPOT_SERVICE}" + sudo systemctl enable "${AUTOHOTSPOT_TIMER}" } _uninstall_autohotspot_dhcpcd() { # clear autohotspot configurations made from past installation - # stop services and clear services + # remove old crontab entries from previous versions + local cron_autohotspot_file="/etc/cron.d/autohotspot" + if [ -f "${cron_autohotspot_file}" ]; then + sudo rm -f "${cron_autohotspot_file}" + fi + + # stop and clear services if systemctl list-unit-files "${AUTOHOTSPOT_SERVICE}" >/dev/null 2>&1 ; then sudo systemctl stop hostapd sudo systemctl stop dnsmasq + sudo systemctl stop "${AUTOHOTSPOT_TIMER}" + sudo systemctl disable "${AUTOHOTSPOT_TIMER}" sudo systemctl stop "${AUTOHOTSPOT_SERVICE}" sudo systemctl disable "${AUTOHOTSPOT_SERVICE}" sudo rm "${AUTOHOTSPOT_SERVICE_PATH}" - fi - - # remove crontab entry and script - local crontab_user=$(crontab -l 2>/dev/null) - if [[ ! -z "${crontab_user}" && $(echo "${crontab_user}" | grep -w "${AUTOHOTSPOT_TARGET_PATH}") ]]; then - echo "${crontab_user}" | sed "s|^.*\s${AUTOHOTSPOT_TARGET_PATH}\s.*$||g" | crontab - + sudo rm "${AUTOHOTSPOT_TIMER_PATH}" fi if [ -f "${AUTOHOTSPOT_TARGET_PATH}" ]; then @@ -126,7 +131,8 @@ _autohotspot_check_dhcpcd() { verify_service_enablement hostapd.service disabled verify_service_enablement dnsmasq.service disabled - verify_service_enablement "${AUTOHOTSPOT_SERVICE}" enabled + verify_service_enablement "${AUTOHOTSPOT_SERVICE}" disabled + verify_service_enablement "${AUTOHOTSPOT_TIMER}" enabled verify_files_exists "${AUTOHOTSPOT_INTERFACES_CONF_FILE}" @@ -151,13 +157,13 @@ _autohotspot_check_dhcpcd() { verify_file_contains_string "wifidev=\"${WIFI_INTERFACE}\"" "${AUTOHOTSPOT_TARGET_PATH}" verify_file_contains_string "hotspot_ip=${AUTOHOTSPOT_IP}" "${AUTOHOTSPOT_TARGET_PATH}" + verify_files_exists "${AUTOHOTSPOT_SERVICE_DAEMON_PATH}" + verify_files_exists "${AUTOHOTSPOT_SERVICE_PATH}" verify_file_contains_string "ExecStart=${AUTOHOTSPOT_TARGET_PATH}" "${AUTOHOTSPOT_SERVICE_PATH}" - local crontab_user=$(crontab -l 2>/dev/null) - if [[ ! $(echo "${crontab_user}" | grep -w "${AUTOHOTSPOT_TARGET_PATH}") ]]; then - exit_on_error "ERROR: crontab for user not installed" - fi + verify_files_exists "${AUTOHOTSPOT_TIMER_PATH}" + verify_file_contains_string "Unit=${AUTOHOTSPOT_SERVICE}" "${AUTOHOTSPOT_TIMER_PATH}" } _run_setup_autohotspot_dhcpcd() { diff --git a/resources/autohotspot/NetworkManager/autohotspot b/resources/autohotspot/NetworkManager/autohotspot index 14e4d014f..992190376 100644 --- a/resources/autohotspot/NetworkManager/autohotspot +++ b/resources/autohotspot/NetworkManager/autohotspot @@ -14,7 +14,7 @@ wdev0='%%WIFI_INTERFACE%%' #wifi device that AP will work on #AP setup -ap_profile_name='Phoniebox_Access_Point' +ap_profile_name='%%AUTOHOTSPOT_PROFILE%%' ap_ssid='%%AUTOHOTSPOT_SSID%%' ap_pw='%%AUTOHOTSPOT_PASSWORD%%' ap_ip='%%AUTOHOTSPOT_IP%%/24' diff --git a/resources/autohotspot/dhcpcd/autohotspot b/resources/autohotspot/dhcpcd/autohotspot index 4ef80ff6c..0cc351888 100644 --- a/resources/autohotspot/dhcpcd/autohotspot +++ b/resources/autohotspot/dhcpcd/autohotspot @@ -86,7 +86,7 @@ CheckWifiUp() } InitWPA() { - wpa_supplicant -B -i "$wifidev" -c /etc/wpa_supplicant/wpa_supplicant.conf >/dev/null 2>&1 + systemctl restart autohotspot-daemon@"$wifidev".service } CheckServices() diff --git a/resources/autohotspot/dhcpcd/autohotspot-daemon.service b/resources/autohotspot/dhcpcd/autohotspot-daemon.service new file mode 100644 index 000000000..08a97028f --- /dev/null +++ b/resources/autohotspot/dhcpcd/autohotspot-daemon.service @@ -0,0 +1,10 @@ +[Unit] +Description=Daemon for regular network connection if no hotspot is created +After=multi-user.target + +[Service] +Type=simple +ExecStart=wpa_supplicant -i "%i" -c /etc/wpa_supplicant/wpa_supplicant.conf + +[Install] +WantedBy=multi-user.target diff --git a/resources/autohotspot/dhcpcd/autohotspot.service b/resources/autohotspot/dhcpcd/autohotspot.service index 036314e45..ff808cd9e 100644 --- a/resources/autohotspot/dhcpcd/autohotspot.service +++ b/resources/autohotspot/dhcpcd/autohotspot.service @@ -1,10 +1,10 @@ [Unit] -Description=Automatically generates an wifi hotspot when a valid ssid is not in range +Description=Automatically generates an wifi hotspot when a valid SSID is not in range After=multi-user.target +Requires=network-online.target [Service] -Type=oneshot -RemainAfterExit=yes +Type=simple ExecStart=%%AUTOHOTSPOT_SCRIPT%% [Install] diff --git a/resources/autohotspot/dhcpcd/autohotspot.timer b/resources/autohotspot/dhcpcd/autohotspot.timer new file mode 100644 index 000000000..dc7427170 --- /dev/null +++ b/resources/autohotspot/dhcpcd/autohotspot.timer @@ -0,0 +1,10 @@ +[Unit] +Description=Timer to run the %%AUTOHOTSPOT_SERVICE%% every 2 mins + +[Timer] +OnBootSec=0min +OnCalendar=*:0/2 +Unit=%%AUTOHOTSPOT_SERVICE%% + +[Install] +WantedBy=timers.target diff --git a/src/jukebox/components/hostif/linux/__init__.py b/src/jukebox/components/hostif/linux/__init__.py index 32dfded08..6a6590ad6 100644 --- a/src/jukebox/components/hostif/linux/__init__.py +++ b/src/jukebox/components/hostif/linux/__init__.py @@ -238,7 +238,7 @@ def get_autohotspot_status(): if os.path.isfile("/etc/systemd/system/autohotspot.service"): status = 'inactive' - ret = subprocess.run(['systemctl', 'is-active', 'autohotspot'], + ret = subprocess.run(['systemctl', 'is-active', 'autohotspot.timer'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False, stdin=subprocess.DEVNULL) # 0 = active, 3 = inactive @@ -260,22 +260,21 @@ def get_autohotspot_status(): def stop_autohotspot(): """Stop auto hotspot functionality - Basically disabling the cronjob and running the script one last time manually + Stopping and disabling the timer and running the service one last time manually """ if os.path.isfile("/etc/systemd/system/autohotspot.service"): - cron_job = "/etc/cron.d/autohotspot" - subprocess.run(["sudo", "sed", "-i", r"s/^\*.*/#&/", cron_job], - stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False) - subprocess.run(['sudo', '/usr/bin/systemctl', 'stop', 'autohotspot'], - stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False) - subprocess.run(['sudo', '/usr/bin/systemctl', 'disable', 'autohotspot'], - stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False) - ret = subprocess.run(['sudo', 'autohotspot'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, - check=False) - if ret.returncode != 0: - msg = f"Error 'stop_autohotspot': {ret.stdout} (Code: {ret.returncode})" - logger.error(msg) - return {'error': {'code': -1, 'message': msg}} + # Stop timer + subprocess.run(['sudo', '/usr/bin/systemctl', 'stop', 'autohotspot.timer'], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False) + # Prevent start after system restart + subprocess.run(['sudo', '/usr/bin/systemctl', 'disable', 'autohotspot.timer'], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False) + # Prevent start after system restart (should always be disabled, but make sure) + subprocess.run(['sudo', '/usr/bin/systemctl', 'disable', 'autohotspot.service'], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False) + + subprocess.run(['sudo', '/usr/bin/systemctl', 'start', 'autohotspot.service'], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False) return 'inactive' else: @@ -285,24 +284,17 @@ def stop_autohotspot(): @plugin.register() def start_autohotspot(): - """start auto hotspot functionality + """Start auto hotspot functionality - Basically enabling the cronjob and running the script one time manually + Enabling and starting the timer (timer will start the service) """ if os.path.isfile("/etc/systemd/system/autohotspot.service"): - cron_job = "/etc/cron.d/autohotspot" - subprocess.run(["sudo", "sed", "-i", "-r", r"s/(^#)(\*[0-9]*)/\*/", cron_job], - stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False) - subprocess.run(['sudo', '/usr/bin/systemctl', 'start', 'autohotspot'], - stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False) - subprocess.run(['sudo', '/usr/bin/systemctl', 'enable', 'autohotspot'], - stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False) - ret = subprocess.run(['sudo', 'autohotspot'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, - check=False) - if ret.returncode != 0: - msg = f"Error 'start_autohotspot': {ret.stdout} (Code: {ret.returncode})" - logger.error(msg) - return {'error': {'code': -1, 'message': msg}} + # Enable start after system restart + subprocess.run(['sudo', '/usr/bin/systemctl', 'enable', 'autohotspot.timer'], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False) + # Start timer (starts the service immediately) + subprocess.run(['sudo', '/usr/bin/systemctl', 'start', 'autohotspot.timer'], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False) return 'active' else: