I know this is probably far to late to help @Lucas out but hopefully someone else can get some value from it.
My team was in a situation recently that required us to push an update to a remote device that would shut down the unit or reboot it without physical access such that adding a script as suggested above was not doable.
The solution that worked for us was to us the dbus python library:
https://github.com/toradex/torizon-samples/tree/bullseye/dbus/python
In your module Dockerfile, add this:
RUN apt-get -q -y update && apt-get -q -y install dbus libdbus-1-dev build-essential libglib2.0 libglib2.0-dev && rm -rf /var/lib/apt/lists/*
RUN python3 -m pip install --upgrade pip && python3 -m pip install dbus-python
And it's important to add this to your deployment manifest:
"createOptions": {
"HostConfig": {
"Privileged": true,
"Binds": [
"/var/run/dbus:/var/run/dbus",
"/usr/share/dbus-1/services:/usr/share/dbus-1/services"
]
}
}
Finally, inside your Python module, you can reboot or shutdown like this:
def handle_event():
try:
bus = dbus.SystemBus()
proxy = bus.get_object('org.freedesktop.systemd1',
'/org/freedesktop/systemd1')
props = dbus.Interface(proxy, "org.freedesktop.DBus.Properties")
print(str(props.GetAll("org.freedesktop.systemd1.Manager")["Version"]))
manager = dbus.Interface(proxy, "org.freedesktop.systemd1.Manager")
manager.PowerOff() # or manager.Reboot()
except Exception as e:
print('Error handling reboot: ', e)
This worked for us as we couldn't find a os.system() based approach that would work.