Skip to content

Commit

Permalink
Use 'yaml' files for pod specifications. (#934)
Browse files Browse the repository at this point in the history
  • Loading branch information
floitsch authored Jan 24, 2024
1 parent 1f3bb7b commit 2206ad5
Show file tree
Hide file tree
Showing 79 changed files with 290 additions and 409 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ jobs:
mkdir fleet
export ARTEMIS_FLEET_ROOT=$PWD/fleet
build/bin/artemis fleet init
build/bin/artemis pod build -o test.pod fleet/my-pod.json
build/bin/artemis pod build -o test.pod fleet/my-pod.yaml
- name: Kill http-servers
if: matrix.arch == 'arm64'
Expand Down
45 changes: 20 additions & 25 deletions public/docs/fleet/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -115,40 +115,35 @@ an empty fleet in a suitable directory. Go to the directory and run:
artemis fleet init
```

This creates three files: `fleet.json`, `devices.json`, and `my-pod.json`.
This creates three files: `fleet.json`, `devices.json`, and `my-pod.yaml`.
The `fleet.json` file holds some metadata and the list of devices in `devices.json`
is empty. The `my-pod.json` file is the most interesting to get started.
is empty. The `my-pod.yaml` file is the most interesting to get started.

Artemis lets you describe the functionality and configuration of your devices
in [pods](pods), which is a set of containers and the configuration
of the environment they need to run in. Pods can be specified through version control friendly
[specification files](pods#specifications), so let's start with the simplest
possible specification by putting the following content into the `my-pod.json` file:

``` json
{
"version": 1,
"name": "my-pod",
"sdk-version": "SDK-VERSION",
"artemis-version": "ARTEMIS-VERSION",
"connections": [
{
"type": "wifi",
"ssid": "YOUR WIFI SSID",
"password": "YOUR WIFI PASSWORD"
}
],
"containers": {
}
}
possible specification by putting the following content into the `my-pod.yaml` file:

``` yaml
version: 1
name: my-pod
sdk-version: SDK-VERSION
artemis-version: ARTEMIS-VERSION
max-offline: 0s
connections:
- type: wifi
ssid: YOUR WIFI SSID
password: YOUR WIFI PASSWORD
containers: {}
```
If you fill in your WiFi credentials, you have a working specification for a pod
named `my-pod`. To make the pod available to your fleet, you will need to upload
it to your broker:

``` sh
artemis pod upload my-pod.json
artemis pod upload my-pod.yaml
```

This uploads `my-pod` and gives is a few useful tags, so we can find it later. The
Expand Down Expand Up @@ -251,7 +246,7 @@ The frequency at which they synchronize can be configured by the user.

Devices that connect frequently or all the time are easy
to interact with and manage, but they spend a lot of power on staying connected
all the time. The pod specification in the example `my-pod.json` does not specify
all the time. The pod specification in the example `my-pod.yaml` does not specify
how often to connect, so Artemis assumes that you want an interactive device.

If you don't need your device to stay connected all the time, you can
Expand Down Expand Up @@ -350,7 +345,7 @@ to reflect the state you want your device in, and then update it to
that through:

``` sh
artemis pod upload my-pod.json
artemis pod upload my-pod.yaml
artemis device update my-pod@latest
```

Expand All @@ -360,11 +355,11 @@ during flashing, or that can be set with `artemis device default`.

## Rolling out changes to a fleet

If you've modified the `my-pod.json` file and you want to make the changes available
If you've modified the `my-pod.yaml` file and you want to make the changes available
to your fleet of devices, you can upload the latest version of your pod using:

``` sh
artemis pod upload my-pod.json
artemis pod upload my-pod.yaml
```

If your `fleet.json` uses `my-pod@latest`, you can ask the fleet
Expand Down
81 changes: 35 additions & 46 deletions public/docs/fleet/pods.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ deployment and for archiving. To build a pod from a specification, you invoke
the `artemis pod build` command like this:

``` sh
artemis pod build -o my-pod.pod my-pod.json
artemis pod build -o my-pod.pod my-pod.yaml
```

Pods contain symbolic debug information, so it is useful to keep them around
Expand Down Expand Up @@ -95,34 +95,26 @@ artemis device update 0f587f04-a0e2-5354-ac3d-ceca41a60b63
## Specifications

You can find an example pod specification file in
[specification.json](https://github.com/toitware/artemis-releases/blob/main/examples/specification.json).
It is in JSON format and looks similar to this:

``` json
{
"version": 1,
"name": "my-pod",
"sdk-version": "SDK-VERSION",
"artemis-version": "ARTEMIS-VERSION",
"max-offline": "0s",
"connections": [
{
"type": "wifi",
"ssid": "YOUR WIFI SSID",
"password": "YOUR WIFI PASSWORD"
}
],
"containers": {
"hello": {
"entrypoint": "hello.toit"
},
"solar": {
"entrypoint": "examples/solar_example.toit",
"git": "https://github.com/toitware/toit-solar-position.git",
"branch": "v0.0.3"
}
}
}
[specification.yaml](https://github.com/toitware/artemis-releases/blob/main/examples/specification.yaml).
It is in YAML format and looks similar to this:

``` yaml
version: 1
name: example
sdk-version: SDK-VERSION
artemis-version: ARTEMIS-VERSION
max-offline: 0s
connections:
- type: wifi
ssid: YOUR-WIFI-SSID
password: YOUR-WIFI-PASSWORD
containers:
hello:
entrypoint: hello.toit
solar:
entrypoint: examples/solar_example.toit
git: https://github.com/toitware/toit-solar-position.git
branch: v0.0.3
```
The three version entries are for the specification format (always `1` for now) and the
Expand Down Expand Up @@ -152,27 +144,24 @@ run until no other container runs. For that to work, you can
make it a background container that is automatically terminated
when the device goes to sleep like this:

``` json
"containers": {
"cellular": {
"entrypoint": "src/modules/sequans/monarch.toit",
"git": "https://github.com/toitware/cellular.git",
"branch": "v2.1.12",
"background": true,
"critical": true
}
}
``` yaml
containers:
cellular:
entrypoint: src/modules/sequans/monarch.toit
git: https://github.com/toitware/cellular.git
branch: v2.1.12
background: true
critical: true
```

The `critical` flag makes the container run continuously. If you want your container
to run periodically, you can specify interval triggers in the `containers` section
like this:

``` json
"containers": {
"measure": {
"entrypoint": "measure.toit",
"triggers": [ { "interval": "20s" } ]
}
}
``` yaml
containers:
measure:
entrypoint: measure.toit
triggers:
- interval: 20s
```
24 changes: 0 additions & 24 deletions public/examples/specification.json

This file was deleted.

16 changes: 16 additions & 0 deletions public/examples/specification.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
version: 1
name: example
sdk-version: SDK-VERSION
artemis-version: ARTEMIS-VERSION
max-offline: 0s
connections:
- type: wifi
ssid: YOUR-WIFI-SSID
password: YOUR-WIFI-PASSWORD
containers:
hello:
entrypoint: hello.toit
solar:
entrypoint: examples/solar_example.toit
git: https://github.com/toitware/toit-solar-position.git
branch: v0.0.3
6 changes: 3 additions & 3 deletions src/cli/cmds/pod.toit
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import ..pod-specification
import ..pod-registry
import ..ui
import ..utils.names
import ..utils show json-encode-pretty read-json
import ..utils show json-encode-pretty read-json read-yaml

create-pod-commands config/Config cache/Cache ui/Ui -> List:
cmd := cli.Command "pod"
Expand Down Expand Up @@ -276,8 +276,8 @@ print parsed/cli.Parsed config/Config cache/Cache ui/Ui:
// This way we report errors in extended specifications.
json := PodSpecification.parse-json-hierarchy specification-path
if not flat:
// If we only want the non-flattened version read the json by hand.
json = read-json specification-path
// If we only want the non-flattened version read the json/yaml again by hand.
json = read-pod-spec-file specification-path

ui.do --kind=Ui.RESULT: | printer/Printer |
printer.emit-structured
Expand Down
4 changes: 2 additions & 2 deletions src/cli/fleet.toit
Original file line number Diff line number Diff line change
Expand Up @@ -249,9 +249,9 @@ class Fleet:
}
write-json-to-file --pretty "$fleet-root/$DEVICES-FILE_" {:}

default-specification-path := "$fleet-root/$(INITIAL-POD-NAME).json"
default-specification-path := "$fleet-root/$(INITIAL-POD-NAME).yaml"
if not file.is-file default-specification-path:
write-json-to-file --pretty default-specification-path INITIAL-POD-SPECIFICATION
write-yaml-to-file default-specification-path INITIAL-POD-SPECIFICATION

ui.info "Fleet root $fleet-root initialized."

Expand Down
10 changes: 8 additions & 2 deletions src/cli/pod-specification.toit
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright (C) 2023 Toitware ApS. All rights reserved.
import encoding.base64
import encoding.json
import encoding.url as url-encoding
import host.file
import fs
Expand Down Expand Up @@ -250,6 +249,13 @@ remove-null-values_ o/any -> none:
list.filter --in-place: it != null
list.do: remove-null-values_ it

read-pod-spec-file path/string -> any:
if path.ends-with ".json":
return read-json path
if path.ends-with ".yaml" or path.ends-with ".yml":
return read-yaml path
throw "Unknown file extension: $path"

/**
A specification of a pod.
Expand Down Expand Up @@ -336,7 +342,7 @@ class PodSpecification:

json := null
exception := catch:
json = read-json path
json = read-pod-spec-file path
if exception:
fail.call "Failed to read pod specification from $path: $exception."

Expand Down
10 changes: 9 additions & 1 deletion src/cli/utils/utils.toit
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import certificate-roots
import cli
import encoding.base64
import encoding.json
import encoding.ubjson
import encoding.tison
import encoding.ubjson
import encoding.yaml
import http
import host.directory
import host.file
Expand Down Expand Up @@ -41,6 +42,9 @@ write-json-to-file path/string value/any --pretty/bool=false -> none:
else:
write-blob-to-file path (json.encode value)

write-yaml-to-file path/string value/any -> none:
write-blob-to-file path (yaml.encode value)

write-ubjson-to-file path/string value/any -> none:
encoded := ubjson.encode value
write-blob-to-file path encoded
Expand All @@ -56,6 +60,10 @@ read-json path/string -> any:
finally:
stream.close

read-yaml path/string -> any:
content := file.read-content path
return yaml.decode content

read-ubjson path/string -> any:
data := file.read-content path
return ubjson.decode data
Expand Down
2 changes: 1 addition & 1 deletion tests/cmd-fleet-init-test.toit
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ run-test test-cli/TestCli:

expect (file.is-file "$fleet-tmp-dir/fleet.json")
expect (file.is-file "$fleet-tmp-dir/devices.json")
expect (file.is-file "$fleet-tmp-dir/my-pod.json")
expect (file.is-file "$fleet-tmp-dir/my-pod.yaml")

// We are not allowed to initialize a folder twice.
already-initialized-message := test-cli.run --expect-exit-1 [
Expand Down
Loading

0 comments on commit 2206ad5

Please sign in to comment.