Skip to content

Commit

Permalink
Add pd daemon service: using systemd to run pd daemon service
Browse files Browse the repository at this point in the history
  • Loading branch information
yangsong-cnyn committed Oct 31, 2024
1 parent 872a8cb commit dfa3c73
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 29 deletions.
70 changes: 61 additions & 9 deletions script/_dhcpv6_pd_ref
Original file line number Diff line number Diff line change
Expand Up @@ -30,28 +30,67 @@
# This script manipulates DHCPv6-PD-REF configuration.
#

customise_dhcpcd_conf()
DHCPCD_ENTER_HOOK="/etc/dhcpcd.enter-hook"
DHCPCD_EXIT_HOOK="/etc/dhcpcd.exit-hook"

PD_DAEMON_PATH="/opt/pd-daemon"
PD_DAEMON="${PD_DAEMON_PATH}/dhcp6_pd_daemon.py"
PD_DAEMON_SERVICE_NAME="dhcp6_pd_daemon.service"
PD_DAEMON_SERVICE="/etc/systemd/system/${PD_DAEMON_SERVICE_NAME}"

create_custom_dhcpcd_conf()
{
# This has to be run after script/_border_routing, and this will
# invalidate all changes to dhcpcd.conf made by script/_border_routing.
sudo tee /etc/dhcpcd.conf >/dev/null <<EOF
sudo tee /etc/dhcpcd.conf.custom >/dev/null <<EOF
noipv6rs # disable router solicitation
interface eth0
iaid 1
ia_pd 2/::/64 -
EOF
}

create_dhcp6_pd_daemon_service()
{
sudo tee ${PD_DAEMON_SERVICE} <<EOF
[Unit]
Description=Daemon call scripts on every PD state change
After=otbr-agent.service
ConditionPathExists=${PD_DAEMON}
[Service]
Type=simple
User=root
ExecStart=/usr/bin/python3 ${PD_DAEMON}
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
}

dhcpv6_pd_ref_uninstall()
{
with DHCPV6_PD_REF || return 0

if have systemctl; then
sudo systemctl disable ${PD_DAEMON_SERVICE_NAME} || true
sudo systemctl stop ${PD_DAEMON_SERVICE_NAME} || true
sudo rm -f ${PD_DAEMON_SERVICE} || true
fi

if [[ -f "/etc/dhcpcd.conf.orig" ]]; then
sudo mv /etc/dhcpcd.conf.orig /etc/dhcpcd.conf
fi
sudo systemctl restart dhcpcd
sudo rm -f /etc/dhcpcd.enter-hook /etc/dhcpcd.exit-hook

sudo rm -f ${DHCPCD_ENTER_HOOK} ${DHCPCD_EXIT_HOOK}
sudo rm -f ${PD_DAEMON}

if have systemctl; then
sudo systemctl daemon-reload

if systemctl is-active dhcpcd; then
sudo systemctl restart dhcpcd || true
fi
fi
}

dhcpv6_pd_ref_install()
Expand All @@ -60,9 +99,22 @@ dhcpv6_pd_ref_install()

if [[ -f "/etc/dhcpcd.conf" ]]; then
sudo mv /etc/dhcpcd.conf /etc/dhcpcd.conf.orig
else
sudo touch /etc/dhcpcd.conf.orig
fi
customise_dhcpcd_conf

# Add dhcpcd.hooks
sudo install -m 755 "$(dirname "$0")"/reference-device/dhcpcd.enter-hook /etc/dhcpcd.enter-hook
sudo install -m 755 "$(dirname "$0")"/reference-device/dhcpcd.exit-hook /etc/dhcpcd.exit-hook
sudo install -m 755 "$(dirname "$0")"/reference-device/dhcpcd.enter-hook ${DHCPCD_ENTER_HOOK}
sudo install -m 755 "$(dirname "$0")"/reference-device/dhcpcd.exit-hook ${DHCPCD_EXIT_HOOK}
sudo mkdir -p ${PD_DAEMON_PATH}
sudo install -m 755 "$(dirname "$0")"/reference-device/dhcp6_pd_daemon.py ${PD_DAEMON}

create_custom_dhcpcd_conf
create_dhcp6_pd_daemon_service

if have systemctl; then
sudo systemctl daemon-reload
sudo systemctl enable ${PD_DAEMON_SERVICE_NAME}
sudo systemctl start ${PD_DAEMON_SERVICE_NAME}
fi
}
59 changes: 39 additions & 20 deletions script/reference-device/dhcp6_pd_daemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import dbus
import gi.repository.GLib as GLib
import subprocess
import threading
import os

from dbus.mainloop.glib import DBusGMainLoop
Expand All @@ -41,30 +42,48 @@
bus = dbus.SystemBus()
thread_dbus_obj = None
iface = None
backup_dir = "/var/lib/ot-dhcpcd-backup"
intended_dhcp6pd_state = None

def restart_dhcpcd_with_custom_config():
global intended_dhcp6pd_state
if os.path.isfile("/etc/dhcpcd.conf.custom"):
try:
subprocess.run(["sudo", "cp", "/etc/dhcpcd.conf.custom", "/etc/dhcpcd.conf"], check=True)
subprocess.run(["sudo", "systemctl", "daemon-reload"], check=True)
subprocess.run(["sudo", "service", "dhcpcd", "restart"], check=True)
logging.info("Successfully restarted dhcpcd service.")
intended_dhcp6pd_state = None
except subprocess.CalledProcessError as e:
logging.error(f"Error restarting dhcpcd service: {e}")
intended_dhcp6pd_state = None
else:
logging.error("Customised configuration file not found. Cannot apply custom.")
intended_dhcp6pd_state = None

def restore_default_config():
if os.path.isfile("/etc/dhcpcd.conf.orig"):
try:
subprocess.run(["sudo", "cp", "/etc/dhcpcd.conf.orig", "/etc/dhcpcd.conf"], check=True)
subprocess.run(["sudo", "systemctl", "daemon-reload"], check=True)
subprocess.run(["sudo", "service", "dhcpcd", "restart"], check=True)
logging.info("Successfully restored default dhcpcd config.")
except subprocess.CalledProcessError as e:
logging.error(f"Error restoring dhcpcd config: {e}")
else:
logging.error("Backup configuration file not found. Cannot restore default.")

def properties_changed_handler(interface_name, changed_properties, invalidated_properties):
global intended_dhcp6pd_state
if "Dhcp6PdState" in changed_properties:
new_state = changed_properties["Dhcp6PdState"]
logging.info(f"Dhcp6PdState changed to: {new_state}")
if new_state == "running":
os.makedirs(backup_dir, exist_ok=True)
subprocess.run(["sudo", "cp", "/etc/dhcpcd.conf", f"{backup_dir}/dhcpcd.conf.orig"], check=True)
try:
subprocess.run(["sudo", "systemctl", "daemon-reload"], check=True)
subprocess.run(["sudo", "service", "dhcpcd", "restart"], check=True)
logging.info("Successfully restarted dhcpcd service.")
except subprocess.CalledProcessError as e:
logging.error(f"Error restarting dhcpcd service: {e}")
elif new_state == "stopped":
if os.path.isfile(f"{backup_dir}/dhcpcd.conf.orig"):
try:
subprocess.run(["sudo", "cp", f"{backup_dir}/dhcpcd.conf.orig", "/etc/dhcpcd.conf"], check=True)
logging.info("Successfully restored default dhcpcd config.")
except subprocess.CalledProcessError as e:
logging.error(f"Error restoring dhcpcd config: {e}")
else:
logging.error("Backup configuration file not found. Cannot restore default.")
if new_state == "running" and intended_dhcp6pd_state != "running":
logging.info(f"Dhcp6PdState changed to: {new_state}")
intended_dhcp6pd_state = "running"
thread = threading.Thread(target=restart_dhcpcd_with_custom_config)
thread.start()
elif new_state in ("stopped", "disabled") and intended_dhcp6pd_state is None:
logging.info(f"Dhcp6PdState changed to: {new_state}")
restore_default_config()

def connect_to_signal():
global thread_dbus_obj, thread_properties_dbus_iface
Expand Down

0 comments on commit dfa3c73

Please sign in to comment.