diff --git a/riocli/apply/manifests/device.yaml b/riocli/apply/manifests/device.yaml index 5a824266..7e57b8b0 100644 --- a/riocli/apply/manifests/device.yaml +++ b/riocli/apply/manifests/device.yaml @@ -69,6 +69,7 @@ spec: os: "ubuntu" # Options: ["ubuntu" (default), "debian" ] codename: "focal" # Options: ["bionic", "focal" (default), "jammy", "bullseye"] highperf: False # Optional [True, False (default)] + wait: True # Optional [True, False (default)] Wait until the device is ready. docker: enabled: True # Required rosbagMountPath: "/opt/rapyuta/volumes/rosbag" diff --git a/riocli/device/model.py b/riocli/device/model.py index 7c1a0ece..be800660 100644 --- a/riocli/device/model.py +++ b/riocli/device/model.py @@ -18,6 +18,7 @@ from riocli.constants import ApplyResult from riocli.device.util import (DeviceNotFound, create_hwil_device, delete_hwil_device, execute_onboard_command, find_device_by_name, make_device_labels_from_hwil_device) +from riocli.device.util import wait_until_online from riocli.exceptions import ResourceNotFound from riocli.model import Model @@ -79,6 +80,9 @@ def apply(self, *args, **kwargs) -> ApplyResult: onboard_command = onboard_script.full_command() execute_onboard_command(hwil_response.id, onboard_command) + if self.spec.get('virtual', {}).get('wait', False): + wait_until_online(device) + return result def delete(self, *args, **kwargs) -> None: diff --git a/riocli/device/util.py b/riocli/device/util.py index 3e7a5723..773194b4 100644 --- a/riocli/device/util.py +++ b/riocli/device/util.py @@ -14,6 +14,7 @@ import functools import json import re +import time import typing from pathlib import Path @@ -22,6 +23,7 @@ from rapyuta_io import Client from rapyuta_io.clients import LogUploads from rapyuta_io.clients.device import Device +from rapyuta_io.clients.device import DeviceStatus from rapyuta_io.utils import RestClient from rapyuta_io.utils.rest_client import HttpMethod @@ -85,6 +87,7 @@ def find_device_guid(client: Client, name: str) -> str: raise DeviceNotFound() + def find_device_by_name(client: Client, name: str) -> Device: devices = client.get_all_devices(device_name=name) if devices: @@ -290,3 +293,23 @@ def sanitize_hwil_device_name(name): r = r + c return r + + +def wait_until_online(device: Device, timeout: int = 600) -> None: + """Wait until the device is online. + + This is a helper method that waits until the device is online. + Or, until the timeout is reached. The default timeout is 600 seconds. + """ + counter, interval = 0, 20 + failed_states = (DeviceStatus.FAILED, DeviceStatus.REJECTED) + + device.refresh() + + while not device.is_online() and device.status not in failed_states and counter < timeout: + counter += interval + time.sleep(interval) + device.refresh() + + if not device.is_online() and counter >= timeout: + raise Exception('timeout reached while waiting for the device to be online') diff --git a/riocli/jsonschema/schemas/device-schema.yaml b/riocli/jsonschema/schemas/device-schema.yaml index 5dd27dda..dee79ade 100644 --- a/riocli/jsonschema/schemas/device-schema.yaml +++ b/riocli/jsonschema/schemas/device-schema.yaml @@ -67,6 +67,9 @@ definitions: enabled: enum: - True + wait: + type: boolean + default: False product: type: string enum: