Skip to content

Commit

Permalink
Implement zapper_iot method (#233)
Browse files Browse the repository at this point in the history
* Implement zapper_iot method

Signed-off-by: ChunAn Wu <an.wu@canonical.com>

* 1. Rename validate_data function to validate_tplan
2. Rename LAUNCHER_SCHEMA to TPLAN_SCHEMA
3. using link instead lnk as variable name in validate_url function

Signed-off-by: ChunAn Wu <an.wu@canonical.com>

* Add zapper_iot to device-connector-types.rst

Signed-off-by: ChunAn Wu <an.wu@canonical.com>

---------

Signed-off-by: ChunAn Wu <an.wu@canonical.com>
  • Loading branch information
kiya956 authored Apr 5, 2024
1 parent 515de00 commit 2f3199b
Show file tree
Hide file tree
Showing 4 changed files with 223 additions and 3 deletions.
2 changes: 2 additions & 0 deletions device-connectors/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ dependencies = [
"PyYAML>=3.11",
"requests",
"rpyc~=5.3.1",
"validators",
"jsonschema",
]

[project.scripts]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,16 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""Zapper Connector for IOT provisioning."""

import logging
from typing import Any, Dict, Tuple

from testflinger_device_connectors.devices.zapper import ZapperConnector
from testflinger_device_connectors.devices import ProvisioningError
from testflinger_device_connectors.devices.zapper_iot.parser import (
validate_tplan,
validate_url,
)

logger = logging.getLogger(__name__)


class DeviceConnector(ZapperConnector):
Expand All @@ -31,4 +37,16 @@ def _validate_configuration(
Validate the job config and data and prepare the arguments
for the Zapper `provision` API.
"""
raise NotImplementedError
try:
tplan = self.job_data["provision_data"]["iot_provision"]["tplan"]
validate_tplan(tplan)
except KeyError as e:
raise ProvisioningError from e

try:
url = self.job_data["provision_data"]["iot_provision"]["url"]
validate_url(url)
except KeyError:
url = []

return ((tplan, url), {})
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
"""provision yaml verify"""

import logging
import validators
import jsonschema
from jsonschema import validate

logger = logging.getLogger(__name__)

TPLAN_SCHEMA = {
"type": "object",
"properties": {
"config": {
"type": "object",
"properties": {
"project_name": {"type": "string"},
"username": {"type": "string"},
"password": {"type": "string"},
"serial_console": {
"type": "object",
"properties": {
"port": {"type": "string"},
"baud_rate": {
"type": "integer",
"enum": [115200, 9600],
"default": 115200,
},
},
"required": ["port", "baud_rate"],
},
"network": {"type": "string"},
"recipients": {
"type": "array",
"items": {"$ref": "#/$defs/mail_format"},
},
"hostname": {"type": "string"},
},
"required": [
"project_name",
"username",
"password",
"serial_console",
"network",
],
},
"run_stage": {
"type": "array",
"minItems": 1,
"items": {
"oneOf": [
{
"type": "string",
"enum": ["login", "run_login", "reboot"],
},
{
"type": "object",
"properties": {
"deploy": {
"type": "object",
"properties": {
"utility": {
"type": "string",
"enum": [
"utp_com",
"uuu",
"uuu_bootloader",
"seed_override",
"seed_override_lk",
],
},
"method": {"$ref": "#/$defs/method"},
"timeout": {
"type": "integer",
"default": 600,
},
"update_boot_assets": {"type": "boolean"},
},
"required": ["utility", "method"],
},
"checkbox": {
"type": "object",
"properties": {
"snap_name": {"type": "string"},
"launcher": {"type": "string"},
"secure_id": {
"type": "string",
"pattern": "^[0-9a-zA-Z]{22}$",
},
"submission_description": {
"type": "string"
},
},
"required": [
"snap_name",
"launcher",
"secure_id",
],
},
"initial_login": {
"type": "object",
"properties": {
"method": {"$ref": "#/$defs/method"},
"timeout": {
"type": "integer",
"default": 600,
},
},
"required": ["method"],
},
"reboot_install": {
"type": "object",
"properties": {
"method": {"$ref": "#/$defs/method"},
"timeout": {
"type": "integer",
"default": 600,
},
},
"required": ["method"],
},
"sys_commands": {
"type": "array",
"items": {"type": "string"},
},
"eof_commands": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"properties": {
"cmd": {"type": "string"},
"expected": {"type": "string"},
},
},
},
},
},
]
},
},
"period": {
"type": "object",
"properties": {
"mode": {"$ref": "#/$defs/mode"},
"day": {"$ref": "#/$defs/day"},
"time": {"$ref": "#/$defs/time"},
},
"required": ["mode"],
"allOf": [
{
"if": {"properties": {"mode": {"enum": ["day"]}}},
"then": {"required": ["time"]},
},
{
"if": {"properties": {"mode": {"enum": ["week"]}}},
"then": {"required": ["time", "day"]},
},
],
},
},
"required": ["config", "run_stage"],
"$defs": {
"time": {"type": "string", "pattern": "^[0-2][0-9]:[0-5][0-9]$"},
"day": {
"type": "string",
"enum": ["mon", "tue", "wed", "thu", "fri", "sat", "sun"],
},
"mode": {"type": "string", "enum": ["hour", "day", "week", "test"]},
"mail_format": {
"type": "string",
"pattern": "^[a-zA-Z0-9.]+@[a-zA-Z0-9.]+$",
},
"method": {
"type": "string",
"enum": [
"cloud-init",
"console-conf",
"system-user",
],
},
},
}


def validate_tplan(data):
"""for verify provision yaml"""
try:
validate(instance=data, schema=TPLAN_SCHEMA)
logger.info("the JSON data is valid")
except jsonschema.exceptions.ValidationError as err:
raise ValueError("the JSON data is invalid") from err


def validate_url(url):
"""for verify url"""
for link in url:
if not validators.url(link):
raise ValueError("url format is not correct")
2 changes: 2 additions & 0 deletions docs/reference/device-connector-types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ To specify the commands to run by the device in each test phase, set the ``testf
- This device connector is used for Lenovo OEM devices running certain versions of OEM supported images that can use a recovery partition to recover not only the same image, but in some cases, other OEM image versions as well.
* - ``hp_oemscript``
- This device connector is used for HP OEM devices running certain versions of OEM supported images that can use a recovery partition to recover not only the same image, but in some cases, other OEM image versions as well.
* - ``zapper_iot``
- This device connector is used for provisioning ubuntu-core to ARM IoT devices. It could be provision by set device to download mode or override seed partition and do recovery.

.. _cm3:

Expand Down

0 comments on commit 2f3199b

Please sign in to comment.