Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/workflows/zizmor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: GitHub Actions Security Analysis with zizmor 🌈

on:
push:
branches: ["master"]
pull_request:
branches: ["**"]

permissions: {}

jobs:
zizmor:
name: Run zizmor 🌈
runs-on: ubuntu-latest
permissions:
security-events: write
contents: read
actions: read
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- name: Run zizmor 🌈
uses: zizmorcore/zizmor-action@0dce2577a4760a2749d8cfb7a84b7d5585ebcb7d # v0.5.0
259 changes: 125 additions & 134 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# GRiSP Mix plug-in

Mix plug-in to build and deploy GRiSP applications for the [GRiSP board][grisp].
Mix plug-in to scaffold and deploy GRiSP applications for the [GRiSP board][grisp].

## Summary

The package can be installed by adding `mix_grisp` to your list of dependencies
in `mix.exs`:
Add `mix_grisp` to your project dependencies:

```elixir
def deps do
Expand All @@ -15,172 +14,164 @@ def deps do
end
```

## New Project Step-By-Step

### Create New Project

Create a project using Elixir default project template:

```
$ mix new testex --module TestEx
$ cd testex
```

### Add Dependencies

Add the following dependencies in the project configuration `mix.exs`:

```
defp deps do
[
...
{:grisp, "~> 2.4"},
{:mix_grisp, "~> 0.2.0", only: :dev},
]
end
```
The plugin currently provides:

### Configure Grisp
- `mix grisp.configure`
- `mix grisp.deploy`

Add the following configuration to your project configuration `mix.exs`:
Implementation notes:

```
def project do
[
...
grisp: grisp(),
releases: releases()
]
end
- [CLI Flow](docs/cli_flow.md)

def grisp do
[
otp: [version: "27"],
deploy: [
# pre_script: "rm -rf /Volumes/GRISP/*",
# destination: "tmp/grisp"
# post_script: "diskutil unmount /Volumes/GRISP",
]
]
end
## Recommended Flow

def releases do
[
{:myapp,
[
overwrite: true,
cookie: "grisp",
include_erts: &MixGrisp.Release.erts/0,
steps: [&MixGrisp.Release.init/1, :assemble],
include_executables_for: [],
strip_beams: Mix.env() == :prod
]}
]
end
```
The best approach today is:

You can uncomment the lines in the `deploy` list after setting the proper mount
point for your SD card if you want to deploy directly to it. The destination can be
a normal path if you want to deploy to a local directory.
1. Start from a simple `mix new` project.
2. Add `mix_grisp` to `deps/0`.
3. Run `mix deps.get`.
4. Run `mix grisp.configure` before heavily customizing `mix.exs` or `config/config.exs`.
5. Review any printed manual steps after the command finishes.

Add the following boot configuration files after changing `GRISP_HOSTNAME` to
the hostname you want the grisp board to have, `WLAN_SSID` and `WLAN_PASSWORD`
to the ssid and password of the WiFi network the Grisp board should connect to.
`mix grisp.configure` is intentionally conservative:

* `grisp/grisp2/common/deploy/files/grisp.ini.mustache`
- it creates missing GRiSP files
- it patches simple `mix new`-style `mix.exs` files automatically
- it patches `config/config.exs` for GRiSP.io when possible
- if the file shape is not safe to rewrite, it prints exact manual steps instead

```
[erlang]
args = erl.rtems -C multi_time_warp -- -mode embedded -home . -pa . -root {{release_name}} -bindir {{release_name}}/erts-{{erts_vsn}}/bin -boot {{release_name}}/releases/{{release_version}}/start -boot_var RELEASE_LIB {{release_name}}/lib -config {{release_name}}/releases/{{release_version}}/sys.config -s elixir start_iex -extra --no-halt
shell = none
## Configure

[network]
ip_self=dhcp
wlan=enable
hostname=GRISP_HOSTNAME
wpa=wpa_supplicant.conf
```
Run the interactive flow:

```sh
mix grisp.configure
```

* `grisp/grisp2/common/deploy/files/wpa_supplicant.conf`
Or run it non-interactively with flags:

```
network={
ssid="WLAN_SSID"
key_mgmt=WPA-PSK
psk="WLAN_PASSWORD"
}
```
```sh
mix grisp.configure --interactive false --name demo --network true --network-type wifi
```

### Add Configuration
### Important Flags

If not generated bu Mix template, add the file `config/config.exs`:
- `--interactive true|false`
- `--name <otp_app>`
- `--otp-version <version>`
- `--network true|false`
- `--network-type ethernet|wifi`
- `--ssid <ssid>`
- `--psk <psk>`
- `--grisp-io true|false`
- `--grisp-io-linking true|false`
- `--token <linking_token>`
- `--epmd true|false`
- `--node-name <short_name>`
- `--cookie <cookie>`

```
import Config
```
### What It Generates

### Check OTP Version
Depending on the selected options, `mix grisp.configure` creates:

Verify that your default erlang version matches the one configured
(26 in the example).
- `config/config.exs` if it does not already exist
- `grisp/grisp2/common/deploy/files/grisp.ini.mustache`
- `grisp/grisp2/common/deploy/files/wpa_supplicant.conf` for Wi-Fi
- `grisp/grisp2/common/deploy/files/erl_inetrc` when GRiSP.io is not enabled

This is required because the beam files are compiled locally and need to be
compiled by the same version of the VM.
The base `grisp.ini.mustache` is kept canonical and then refined during rendering:

### Get Dependencies
- Wi-Fi adds `wpa=wpa_supplicant.conf`
- `epmd` adds:
- `-kernel inetrc "./erl_inetrc"`
- `-internal_epmd epmd_sup`
- `-sname <node_name>`
- `-setcookie <cookie>`

Get all the dependencies:

```
$ mix deps.get
```
### What It Patches Automatically

### Deploy The Project
For simple `mix new`-style projects, the plugin can patch `mix.exs` to add:

To deploy, use the grisp command provided by `mix_grisp`:
- `grisp: grisp()`
- `releases: releases()`
- `{:grisp, "~> 2.4"}`
- `{:epmd, git: "https://github.com/erlang/epmd", ref: "4d1a59", runtime: false}` when `epmd` is enabled
- `def grisp do`
- `def releases do`
- `included_applications: [:epmd]` in `application/0` when `epmd` is enabled

```
$ mix grisp.deploy
```
For GRiSP.io, the plugin can patch `config/config.exs` to add:

### Troubleshooting
- `:grisp_keychain`
- `:grisp_cryptoauth`
- `:grisp_connect`
- `:grisp_updater`

#### This BEAM file was compiled for a later version of the run-time system
If linking is enabled, the linking token is added to `config :grisp_connect`.

Some bema files were compiled with a newer version of OTP, delete `_build` and
`deps`, get the fresh dependencies (`mix deps.get`), and redeploy
(`mix grisp.deploy`).
### What Still Requires Review

[grisp]: https://www.grisp.org
The plugin may still print manual steps. This is expected when:

- `mix.exs` does not match a simple patchable shape
- GRiSP.io dependencies need to be added with versions that match your GRiSP stack
- additional app/runtime choices need review

## Enabling Erlang Distribution
In particular, GRiSP.io dependency versions are not auto-selected by the plugin.
You should choose versions that match your target GRiSP setup.

## Example Commands

1. Add the erlang epmd to your release to be able to run Erlang distribution on GRiSP
Wi-Fi project:

1. Add the following line in your deps, this will ship epmd without starting it at boot.
```sh
mix grisp.configure \
--interactive false \
--name demo \
--network true \
--network-type wifi \
--ssid mywifi \
--psk supersecret
```

```elixir
{:epmd, git: "https://github.com/erlang/epmd", ref: "4d1a59", runtime: false},
```
Ethernet + Erlang distribution:

```sh
mix grisp.configure \
--interactive false \
--name demo \
--network true \
--network-type ethernet \
--epmd true \
--node-name mynode \
--cookie mycookie
```

2. Add epmd to the included applications so its modules are loaded at runtime

```elixir
def application do
[
extra_applications: [:logger],
included_applications: [:epmd]
]
end
```
GRiSP.io with device linking:

```sh
mix grisp.configure \
--interactive false \
--name demo \
--network true \
--network-type wifi \
--grisp-io true \
--grisp-io-linking true \
--token link-token
```

2. Read the GRiSP.ini chapter of the [wiki](https://github.com/grisp/grisp/wiki/Connecting-over-WiFI-and-Ethernet#grisp-ini)
## Deploy

3. Your grisp.ini.mustache file `args` should terminate with the following flags, choose a nodename and cookie of your liking.
```
... -s elixir start_iex -kernel inetrc "./erl_inetrc" -internal_epmd epmd_sup -sname mynode -setcookie mycookie -extra --no-halt
```
After configuration and dependency setup, deploy with:

```sh
mix grisp.deploy
```

## Notes

- Use the same OTP version locally that you target in the generated GRiSP configuration.
- If you compiled dependencies with the wrong OTP version, remove `_build` and `deps`, run `mix deps.get`, and build again.
- Read the GRiSP networking chapter in the wiki for board-specific runtime details.

[grisp]: https://www.grisp.org
Loading