Edge SDK

How to use the CHI@Edge Python SDK to enroll and manage devices on the testbed.

Prerequisites

To run the SDK, you'll need a computer with python3 installed, a terminal, and a microsd card writer. The SDK has only been tested with Linux and MacOS, and the Bash and ZSH shells.

Installing the SDK

We recommend installing the SDK in a python virtualenv. In your chosen installation directory, execute the following:

# create a virtualenv
python3 -m venv .venv

# activate it
source .venv/bin/activate

# install the SDK
pip install python-chi-edge

Using the SDK

Authenticating to CHI@Edge

To use the SDK, you'll need an application credential from CHI@Edge. This will be used both to authenticate the SDK, and to register each device.

Create one here, then download it as an openrc file. https://chi.edge.chameleoncloud.org/identity/application_credentials/.

Finally, source the openrc file by executing, e.g. source app-cred-edge-openrc.sh

Registering your device

The first step to enrollment is device registration. You can do this even if you don't have the device at-hand; it simply creates a record of a "shadow" device on CHI@Edge, which will then be automatically associated with your target physical device on first boot.

You should have a few pieces of information handy:

Device names must be unique across the testbed; this is another reason why prefixing the device name is handy.

  • Device name: what will your device be called? This is designed to be machine-readable (i.e., short, descriptive, no spaces or surprises), and we recommend that you prefix your device with its location or your project or institution. Including an indication of the device type is also helpful for quick scanning. For example:

    • uc-rpi4-03: a Raspberry Pi4 (third in a set) physically located at UChicago

    • pegasus-rpi4-01: a Raspberry Pi4 (first in a set) managed by a project called "Pegasus."

    • tacc-nano-10: a Jetson Nano located at TACC.

  • Device Type: currently CHI@Edge supports a few specific device types, so ensure yours is supported before continuing with the process. Currently, we support the following:

    • raspberrypi3-64

    • raspberrypi4-64

    • jetson-nano

    • jetson-xavier-nx-emmc

  • Contact email: this will be used if testbed operators would like to contact you about your device (e.g., to report power failure or disconnection of significant duration.)

  • Application credential: devices enrolled in the testbed use an application credential in order to sync their configuration with the central registration service. Currently this works via an application credential associated with some project you have an allocation on. You can reuse the same application credential for each device you enroll, or create device-specific credentials if you wish. Remember to save the secret somewhere as it is only presented to you once in the CLI or GUI upon generation.

To register the device, you'll need the id and secret from the chosen application credential.

Once you have the above information, registering each device is straightforward. Replace each <placeholder> below.

chi-edge device register \
  --contact-email <contact_email> \
  --application-credential-id <application_credential_id> \
  --application-credential-secret <application_credential_secret> \
  --machine-name <device_type> \
  <device_name>

If you're reusing a single application credential to both authenticate the SDK, and register each device, then you can save some time by using "$OS_APPLICATION_CREDENTIAL_ID" and "$OS_APPLICATION_CREDENTIAL_SECRET"

Viewing your registered devices

The SDK also supports listing and seeing details for any devices you have registered.

# List all devices
chi-edge device list

This will print a list of any devices registered under your Chameleon project. Notably, the "Health" column will indicate if the device has any issues w/ the testbed. There are multiple health checks that occur on the device and all of them should be up (i.e., it should read "3/3"). Health checks reset whenever you issue an update to the device, but should resolve shortly thereafter, once the changes have propagated through the testbed.

              ╷                                      ╷                           ╷        ╷                            
  Name        │ UUID                                 │ Registered at             │ Health │ Last seen                  
╺━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━╸
  iot-rpi3-03 │ 9b417c80-81ff-48b7-abdf-39dce659fbc7 │ 2022-02-08T13:29:59-06:00 │ 3/3    │ 2022-02-28T18:06:10-06:00  
  iot-rpi4-01 │ b3437b33-048d-4809-ad7e-7b8d186195a4 │ 2022-02-28T18:34:16-06:00 │ 1/3    │ --                         
  iot-rpi4-02 │ 4ece5ce4-6166-4d19-8de0-73819144b78c │ 2022-02-28T18:36:14-06:00 │ 1/3    │ --                

You can view a single device's details, which will display more information regarding the device's configuration and health:

# View details for a single device
chi-edge device show <uuid|name>

This will print a larger view with all user-customizable properties of the device, and the status of all health checks. When a check is in the "STEADY" state, everything is OK. "PENDING" indicates the check has not yet run, "IN_PROGRESS" similarly indicates the check is running, and failed checks go to an "ERROR" state. There is additionally a "DEFER" state, indicating that the check could not complete due to some dependency not being realized. This should resolve itself once testbed state converges.

╭─ iot-rpi3-03 ── 9b417c80-81ff-48b7-abdf-39dce659fbc7 ──────────────────────────────────────────────────────────────────────────────────────╮
│                                 ╷                                                                                                          │
│   Property                      │ Value                                                                                                    │
│ ╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸                                             │
│   application_credential_id     │ 20a809ecf24e4b48be51005f9ea678f2                                                                         │
│   application_credential_secret │ ************                                                                                             │
│   blazar_device_driver          │ k8s                                                                                                      │
│   channels                      │ user:                                                                                                    │
│                                 │   channel_type: wireguard                                                                                │
│                                 │   public_key: ZLflwhnDj/CS3c0j0Dn2smm2Ou/QZP1ZElhCTNOiRzU=                                               │
│   contact_email                 │ jasonanderson@uchicago.edu                                                                               │
│   machine_name                  │ raspberrypi3-64                                                                                          │
│                                 ╵                                                                                                          │
│ Health details                                                                                                                             │
│                 ╷                                       ╷                                        ╷                                         │
│                 │ balena                                │ blazar.device                          │ tunelo                                  │
│ ╺━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸ │
│   state         │ STEADY                                │ STEADY                                 │ STEADY                                  │
│   state_details │ device_api_key:                       │ blazar_resource_id:                    │ channels:                               │
│                 │ ********************************      │ 833e10f0-1e21-48b3-94fe-aa7e9652c680   │   user:                                 │
│                 │ device_id: 5879362                    │ message: Can not make resource         │     endpoint: null                      │
│                 │ fleet_id: 1883023                     │ reservable, as the underlying entity   │     ip: 10.0.3.167                      │
│                 │ last_seen: '2022-03-01T00:06:10Z'     │ could not be found.                    │     peers:                              │
│                 │                                       │ resource_created_at: '2022-02-25       │     - endpoint: 129.114.34.129:51821    │
│                 │                                       │ 23:48:56'                              │       ip: 10.0.3.2                      │
│                 │                                       │                                        │       public_key:                       │
│                 │                                       │                                        │ zgg29Urn5Wwcp9ennCchdGoYnPdWCHUfxzMC…   │
│                 │                                       │                                        │     uuid:                               │
│                 │                                       │                                        │ fb92b276-22be-4fbb-b498-defcfefdb27b    │
│                 ╵                                       ╵                                        ╵                                         │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

Imaging your device

Once you have registered the device, you can proceed to downloading an OS image and configuring it for your target device (a process we refer to as "baking" the image.)

Download an OS image

Depending on what type of device you are enrolling, download one of the Balena OS images here:

64-bit is required; the service images we will run on the Pi are built for aarch64.

make sure you unzip the downloaded image before flashing

Bake the image for your target device

Use the Edge SDK to "bake" the image for your target device. This adjusts a configuration file on the device to inform it to associate itself with the device record you already registered on the testbed.

chi-edge device bake --image <image> <device_uuid>

Image the Pi

Use some imaging tool (we recommend Balena Etcher) to transfer the disk image to a microSD card and insert into the Pi.

Once your device boots up, it should download the latest version of the edge services, establish communication with the central testbed control plane, and the health checks should flip over to a healthy state. Use the Edge SDK to investigate reasons why the device may not be coming up, and please reach out to the users group if you encounter difficulties.

Manage which projects can use your devices

By default, newly registered devices can be reserved by any CHI@Edge user. This may not be appropriate, for example, for devices which require physical access to be useful.

You can restrict which projects can reserve a device by using the following options:

# --authorized-projects TEXT      A list of Chameleon projects (names or IDs)
#                                 that will be allowed to reserve and use the
#                                 device. Specify as a comma-separated list.
# --authorized-projects-reason    TEXT
#                                 An optional display reason to explain why
#                                 the device has restrictions.

chi-edge device set \
    --authorized-projects <project_1>,<project_2> \
    --authorized-projects-reason "special reason here" \
    <device_name_or_uuid>

Prevent user containers from accessing your local network

We recommend that CHI@Edge devices be connected to a DMZ network, where nothing sensitive is at risk. While we do enforce a usage policy, CHI@Edge fundamentally allows users to execute arbitrary code on these devices.

If you need to prevent users from sending traffic to local IP adresses (say your devices are connected to the same network as classroom computers, smart TVs, printers, etc.), you can enforce this with the following command.

# --local-egress [allow|deny]     Can the device contact IPs on its local
#                                 network
chi-edge device set \
    --local-egress deny \
    <device_name_or_uuid>

This will not prevent traffic between containers on two CHI@Edge devices, only traffic exiting the device onto your network.

If set, traffic sent from the device to RFC1918 IP addresses will be blocked: 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16. Traffic can still be sent to public IP addresses via a gateway on your network, e.g reaching 8.8.8.8 via 192.168.0.1

Last updated