Rebooting Edge Device Remotely

Lucas 41 Reputation points
2020-06-26T20:12:23.81+00:00

Hello, my team and I would like to be able to reboot an edge device remotely once it is out in the field. Due to the devices' architecture (Jetson Nano/Xavier), we are unable to utilize the Remote Desktop applications we typically use for our Windows machines. This means that we are unable to access the device's terminal once it is out in the field in order to run any rebooting functions. Our next step was to try and create a module that we can activate in order to reboot the device for us whenever we need it to. However, we ran into two main issues when doing so:

1) We are unable to run any rebooting operations from the Docker container. For example: python's os.system('reboot'), systemctl reboot, reboot, shutdown -r now. We have tried both executing shell scripts with those commands and doing it directly from the python script using Popen(). We understand those are all pointing to the same command, but since systemctl is not found inside the Docker container, we are unable to access its functions.

2) Even if we were to able to restart from within the module, we are unsure on how to be able to communicate with it for it to reboot on command. We know modules are able to be triggered based on loops, delays, and other modules' messages, but we do not know how to communicate with it remotely.

I appreciate any advice on how to do this, even if it is not exactly related to creating a module to do so.

Azure IoT Edge
Azure IoT Edge
An Azure service that is used to deploy cloud workloads to run on internet of things (IoT) edge devices via standard containers.
552 questions
{count} votes

Accepted answer
  1. Sander van de Velde | MVP 30,396 Reputation points MVP
    2020-06-29T21:52:03.357+00:00

    With running a script I mean a service/daemon.

    This daemon starts when the device boots and interacts with the IoT Edge module.

    Two possible scenarios are:

    1. start a socket.io service and let the IoT edge module interact (send a reboot command) using socket io.
    2. the daemon checks a folder shared for a certain file (content) which is set by the IoT edge module (do not forget to deprecate the file :-))

    The solution with the file feels a bit old school but is simple to protect against 'hacking' due to limited access to the folder.

    Other scenarios with other ways of communication could apply too!

    (Please accept helpful responses as 'Answer', which will be helpful to other members as well)

    1 person found this answer helpful.
    0 comments No comments

4 additional answers

Sort by: Most helpful
  1. Christian Eder 0 Reputation points
    2023-01-25T14:40:07.21+00:00

    You may want to look into OSConfig

    this requires you to install the OSConfig agent on the device, which will automatically add another module (the OSCOnfig module) to the devices module list, which you can use to do these kinds of things: reboot, issue custom linux commands, read and change host configuration...


  2. Marc 36 Reputation points
    2021-07-29T19:49:48.057+00:00

    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.

    1 person found this answer helpful.
    0 comments No comments

  3. Sander van de Velde | MVP 30,396 Reputation points MVP
    2020-06-28T21:25:17.85+00:00

    Docker containers in general are running sandboxed. This means the logic within the container is not able to do more than allowed by docker settings.

    You can see this when folders or files from the file system have to be shared (bindings, volumes) or ports have to be opened.

    It is possible to elevate rights of containers but this is not recommended, especially when rebooting...

    I recommend to run some script on the host system witch elevated rights which works in pair with your own containers.

    For example, with the script, you can create an endpoint which can be called by the IoT Edge module when you want to reboot the device.

    To prevent other logic from starting rebooting your device, you can limit the 'attack vector' to go for a local folder/file with just enough rights to rite a 'trigger'.

    Either way, the reboot has to be performed outside your container.

    0 comments No comments

  4. Lucas 41 Reputation points
    2020-06-29T21:25:09.887+00:00

    Thank you for the response!

    So to my understanding, I am creating a local script that does the rebooting for me. Something like a shell script that reboots. That makes sense, but how do I interact with that script from the container. I know I can place the script in the bind point so that the container can see/access it, but whenever I run said script it runs it within the container instead of on the host. Also, how am able to communicate with the module remotely so that it triggers said script.

    Thank you again, and apologies for the lack of experience!

    0 comments No comments