mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-13 02:26:37 +00:00
docs(scripts): monorepo workspace layout; fix_perms and install READMEs
MULTI_ROOT_WORKSPACE_SETUP described one sibling repository per plugin; setup_plugin_repos.py links ../ledmatrix-plugins/plugins/* into plugin-repos/ and update_plugin_repos.py pulls only the monorepo, and the workspace file opens LEDMatrix plus ../ledmatrix-plugins. scripts/fix_perms/README.md listed cache directories fix_cache_permissions.sh never touches and a 'ledmatrix' service user that doesn't exist (also in scripts/install/README.md); adds safe_pip_install.sh. install/README: install_service.sh installs the web and update-verify units too. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,169 +1,154 @@
|
|||||||
# Multi-Root Workspace Setup Guide
|
# Multi-Root Workspace Setup Guide
|
||||||
|
|
||||||
This document explains how the LEDMatrix project uses a multi-root workspace to manage plugins as separate Git repositories.
|
This document explains how to work on LEDMatrix and the official plugins side
|
||||||
|
by side, with one editor workspace and the plugins loaded straight from your
|
||||||
|
plugin checkout.
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
The LEDMatrix project has been migrated from a git submodule implementation to a **multi-root workspace** implementation for managing plugins. This allows:
|
Official plugins live in a single repository,
|
||||||
|
[ledmatrix-plugins](https://github.com/ChuckBuilds/ledmatrix-plugins), with one
|
||||||
|
directory per plugin under `plugins/`. There are no separate per-plugin
|
||||||
|
repositories. For development you clone that monorepo **next to** LEDMatrix
|
||||||
|
and symlink its plugin directories into LEDMatrix's `plugin-repos/`, which is
|
||||||
|
where the plugin loader looks by default.
|
||||||
|
|
||||||
- ✅ Plugins to exist as independent Git repositories
|
- ✅ Plugin code stays in the monorepo checkout, with its own git history
|
||||||
- ✅ Updates to plugins without modifying the LEDMatrix project
|
- ✅ LEDMatrix discovers the plugins through symlinks in `plugin-repos/`
|
||||||
- ✅ Easy development workflow with all repos in one workspace
|
- ✅ `LEDMatrix.code-workspace` opens both repositories in VS Code/Cursor
|
||||||
- ✅ Plugin system discovers plugins via symlinks in `plugin-repos/`
|
|
||||||
|
|
||||||
## Directory Structure
|
## Directory Structure
|
||||||
|
|
||||||
```text
|
```text
|
||||||
/home/chuck/Github/
|
~/Github/
|
||||||
├── LEDMatrix/ # Main project
|
├── LEDMatrix/ # Main project
|
||||||
│ ├── plugin-repos/ # Symlinks to actual repos (managed automatically)
|
│ ├── plugin-repos/ # Plugin directory the loader scans
|
||||||
│ │ ├── ledmatrix-clock-simple -> ../../ledmatrix-clock-simple
|
│ │ ├── starlark-apps/ # Bundled with LEDMatrix (tracked in git)
|
||||||
│ │ ├── ledmatrix-weather -> ../../ledmatrix-weather
|
│ │ ├── web-ui-info/ # Bundled with LEDMatrix (tracked in git)
|
||||||
|
│ │ ├── clock-simple -> ../../ledmatrix-plugins/plugins/clock-simple
|
||||||
|
│ │ ├── ledmatrix-weather -> ../../ledmatrix-plugins/plugins/ledmatrix-weather
|
||||||
│ │ └── ...
|
│ │ └── ...
|
||||||
│ ├── LEDMatrix.code-workspace # Multi-root workspace configuration
|
│ ├── LEDMatrix.code-workspace # Opens LEDMatrix and ../ledmatrix-plugins
|
||||||
│ └── ...
|
│ └── ...
|
||||||
├── ledmatrix-clock-simple/ # Plugin repository (actual git repo)
|
└── ledmatrix-plugins/ # Plugin monorepo (git repo)
|
||||||
├── ledmatrix-weather/ # Plugin repository (actual git repo)
|
├── plugins/
|
||||||
├── ledmatrix-football-scoreboard/ # Plugin repository (actual git repo)
|
│ ├── clock-simple/
|
||||||
└── ... # Other plugin repos
|
│ ├── ledmatrix-weather/
|
||||||
|
│ └── ...
|
||||||
|
├── plugins.json # Store registry
|
||||||
|
└── update_registry.py
|
||||||
```
|
```
|
||||||
|
|
||||||
## How It Works
|
## How It Works
|
||||||
|
|
||||||
### 1. Plugin Repositories
|
### 1. The plugin monorepo
|
||||||
|
|
||||||
All plugin repositories are cloned to `/home/chuck/Github/` (parent directory of LEDMatrix) as regular Git repositories:
|
Clone ledmatrix-plugins into the same parent directory as LEDMatrix (the
|
||||||
|
scripts below look for `../ledmatrix-plugins` relative to the LEDMatrix
|
||||||
|
root):
|
||||||
|
|
||||||
- `ledmatrix-clock-simple/`
|
```bash
|
||||||
- `ledmatrix-weather/`
|
cd ~/Github
|
||||||
- `ledmatrix-football-scoreboard/`
|
git clone https://github.com/ChuckBuilds/ledmatrix-plugins.git
|
||||||
- etc.
|
```
|
||||||
|
|
||||||
### 2. Symlinks in plugin-repos/
|
### 2. Symlinks in plugin-repos/
|
||||||
|
|
||||||
The `LEDMatrix/plugin-repos/` directory contains symlinks pointing to the actual repositories in the parent directory. This allows the plugin system to discover plugins without modifying the project structure.
|
`scripts/setup_plugin_repos.py` creates one symlink per plugin in
|
||||||
|
`LEDMatrix/plugin-repos/`, named after the plugin's manifest `id` and pointing
|
||||||
|
at `../ledmatrix-plugins/plugins/<dir>`.
|
||||||
|
|
||||||
### 3. Multi-Root Workspace
|
### 3. Multi-root workspace
|
||||||
|
|
||||||
The `LEDMatrix.code-workspace` file configures VS Code/Cursor to open all plugin repositories as separate workspace roots, allowing easy development across all repos.
|
`LEDMatrix.code-workspace` has two roots: LEDMatrix itself and
|
||||||
|
`../ledmatrix-plugins`.
|
||||||
|
|
||||||
## Setup Scripts
|
## Setup Scripts
|
||||||
|
|
||||||
### Initial Setup
|
### Initial Setup
|
||||||
|
|
||||||
If you already have plugin repositories cloned, use the setup script:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /home/chuck/Github/LEDMatrix
|
cd ~/Github/LEDMatrix
|
||||||
python3 scripts/setup_plugin_repos.py
|
python3 scripts/setup_plugin_repos.py
|
||||||
```
|
```
|
||||||
|
|
||||||
This script:
|
This script:
|
||||||
- Reads the workspace configuration
|
- Reads each `manifest.json` under `../ledmatrix-plugins/plugins/`
|
||||||
- Creates symlinks in `plugin-repos/` pointing to actual repos
|
- Creates `plugin-repos/<id>` symlinks (relative) to those directories
|
||||||
- Verifies all links are created correctly
|
- Leaves correct links alone, replaces links that point elsewhere, and skips
|
||||||
|
(does not overwrite) a real directory of the same name — for example a
|
||||||
|
plugin you installed from the Plugin Store. Remove that directory first if
|
||||||
|
you want the linked copy.
|
||||||
|
|
||||||
### Updating Plugins
|
### Updating Plugins
|
||||||
|
|
||||||
To update all plugin repositories:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /home/chuck/Github/LEDMatrix
|
cd ~/Github/LEDMatrix
|
||||||
python3 scripts/update_plugin_repos.py
|
python3 scripts/update_plugin_repos.py
|
||||||
```
|
```
|
||||||
|
|
||||||
This script:
|
This runs `git pull` in `../ledmatrix-plugins` and prints the result. The
|
||||||
- Finds all plugins in the workspace
|
symlinks pick up the new code; restart the display to load it.
|
||||||
- Runs `git pull` on each repository
|
|
||||||
- Reports which plugins were updated
|
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
The plugin system is configured in `config/config.json`:
|
The loader reads plugins from `plugin_system.plugins_directory` in
|
||||||
|
`config/config.json`. The default is already right for this setup:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"plugin_system": {
|
"plugin_system": {
|
||||||
"plugins_directory": "plugin-repos",
|
"plugins_directory": "plugin-repos"
|
||||||
"auto_discover": true,
|
|
||||||
"auto_load_enabled": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The `plugins_directory` points to `plugin-repos/`, which contains symlinks to the actual repositories.
|
|
||||||
|
|
||||||
## Workflow
|
## Workflow
|
||||||
|
|
||||||
### Daily Development
|
### Daily Development
|
||||||
|
|
||||||
1. **Open Workspace**: Open `LEDMatrix.code-workspace` in VS Code/Cursor
|
1. **Open Workspace**: Open `LEDMatrix.code-workspace` in VS Code/Cursor
|
||||||
2. **All Repos Available**: All plugin repos appear as separate folders in the workspace
|
2. **Edit Plugins**: Edit code under `ledmatrix-plugins/plugins/<plugin>/`
|
||||||
3. **Edit Plugins**: Edit plugin code directly in their repositories
|
3. **Test**: `python3 run.py -e` (emulator) or
|
||||||
4. **Update Plugins**: Run `update_plugin_repos.py` to pull latest changes
|
`python3 scripts/check_plugin.py --plugin <id>` from LEDMatrix
|
||||||
|
4. **Ship**: Bump `version` in the plugin's `manifest.json`, run
|
||||||
|
`python update_registry.py` in ledmatrix-plugins, commit there
|
||||||
|
|
||||||
### Adding New Plugins
|
### Adding New Plugins
|
||||||
|
|
||||||
1. **Clone Repository**: Clone the new plugin repo to `/home/chuck/Github/`
|
1. Create `plugins/<your-plugin-id>/` in the monorepo checkout
|
||||||
2. **Add to Workspace**: Add the plugin folder to `LEDMatrix.code-workspace`
|
2. Run `python3 scripts/setup_plugin_repos.py` in LEDMatrix to link it
|
||||||
3. **Create Symlink**: Run `setup_plugin_repos.py` to create the symlink
|
|
||||||
|
|
||||||
### Updating Individual Plugins
|
|
||||||
|
|
||||||
Since plugins are regular Git repositories, you can update them individually:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd /home/chuck/Github/ledmatrix-weather
|
|
||||||
git pull origin master
|
|
||||||
```
|
|
||||||
|
|
||||||
Or update all at once:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd /home/chuck/Github/LEDMatrix
|
|
||||||
python3 scripts/update_plugin_repos.py
|
|
||||||
```
|
|
||||||
|
|
||||||
## Benefits
|
|
||||||
|
|
||||||
1. **No Submodule Hassle**: No need to update `.gitmodules` or run `git submodule update`
|
|
||||||
2. **Independent Updates**: Update plugins independently without touching LEDMatrix
|
|
||||||
3. **Clean Separation**: Each plugin is a separate repository with its own history
|
|
||||||
4. **Easy Development**: Multi-root workspace makes it easy to work across repos
|
|
||||||
5. **Automatic Discovery**: Plugin system automatically discovers plugins via symlinks
|
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### Symlinks Not Working
|
### Plugins not discovered
|
||||||
|
|
||||||
If plugins aren't being discovered:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /home/chuck/Github/LEDMatrix
|
cd ~/Github/LEDMatrix
|
||||||
python3 scripts/setup_plugin_repos.py
|
ls -la plugin-repos/ # links present and not broken?
|
||||||
|
python3 scripts/setup_plugin_repos.py # recreate them
|
||||||
```
|
```
|
||||||
|
|
||||||
This will recreate all symlinks.
|
Also check that `plugin_system.plugins_directory` is `plugin-repos`.
|
||||||
|
|
||||||
### Missing Plugins
|
### "Monorepo plugins directory not found"
|
||||||
|
|
||||||
If a plugin is in the workspace but not found:
|
`setup_plugin_repos.py` expects the monorepo at `../ledmatrix-plugins`. Clone
|
||||||
|
it there (or symlink it there).
|
||||||
|
|
||||||
1. Check if the repo exists in `/home/chuck/Github/`
|
### Plugin updates not showing
|
||||||
2. Check if the symlink exists in `plugin-repos/`
|
|
||||||
3. Run `setup_plugin_repos.py` to recreate symlinks
|
|
||||||
|
|
||||||
### Plugin Updates Not Showing
|
1. Verify the link target: `ls -la plugin-repos/<id>`
|
||||||
|
2. Check that you're editing the monorepo checkout, not a store-installed copy
|
||||||
If changes to plugins aren't appearing:
|
3. Restart the LEDMatrix service (or `run.py`)
|
||||||
|
|
||||||
1. Verify the symlink points to the correct directory: `ls -la plugin-repos/ledmatrix-weather`
|
|
||||||
2. Check that you're editing in the actual repo, not a copy
|
|
||||||
3. Restart the LEDMatrix service if running
|
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
- The `plugin-repos/` directory is tracked in git, but only contains symlinks
|
- `plugin-repos/` is tracked in git only for the bundled plugins
|
||||||
- Actual plugin code lives in `/home/chuck/Github/ledmatrix-*/`
|
(`starlark-apps`, `web-ui-info`). The symlinks you create are untracked
|
||||||
- Each plugin repo can be updated independently via `git pull`
|
files; don't commit them.
|
||||||
- The LEDMatrix project doesn't need to be updated when plugins change
|
- For linking a single plugin into `plugins/` instead (without a sibling
|
||||||
|
checkout), see `scripts/dev/dev_plugin_setup.sh` in the
|
||||||
|
[Plugin Development Guide](PLUGIN_DEVELOPMENT_GUIDE.md).
|
||||||
|
- When changing a plugin in the monorepo, bump its manifest `version` and run
|
||||||
|
`python update_registry.py`, or users won't receive the update.
|
||||||
|
|||||||
@@ -7,8 +7,10 @@ install as the wrong user, after a manual file copy that didn't preserve
|
|||||||
ownership, or after a permissions-related error from the display or
|
ownership, or after a permissions-related error from the display or
|
||||||
web service.
|
web service.
|
||||||
|
|
||||||
Most of these scripts require `sudo` since they touch directories
|
Most of these scripts require `sudo` since they touch directories owned
|
||||||
owned by the `ledmatrix` service user or by `root`.
|
by `root` (the display service's user) or by the user you installed
|
||||||
|
LEDMatrix as (the web service's user). There is no dedicated `ledmatrix`
|
||||||
|
system user.
|
||||||
|
|
||||||
## Scripts
|
## Scripts
|
||||||
|
|
||||||
@@ -16,11 +18,12 @@ owned by the `ledmatrix` service user or by `root`.
|
|||||||
permissions on the `assets/` tree so plugins can download and cache
|
permissions on the `assets/` tree so plugins can download and cache
|
||||||
team logos, fonts, and other static content.
|
team logos, fonts, and other static content.
|
||||||
|
|
||||||
- **`fix_cache_permissions.sh`** — Fixes permissions on every cache
|
- **`fix_cache_permissions.sh`** — Creates (if missing) and fixes
|
||||||
directory the project may use (`/var/cache/ledmatrix/`,
|
permissions on `/var/cache/ledmatrix/` and `~/.ledmatrix_cache/` of the
|
||||||
`~/.cache/ledmatrix/`, `/opt/ledmatrix/cache/`, project-local
|
user running `sudo`, and creates
|
||||||
`cache/`). Also creates placeholder logo subdirectories used by the
|
`/var/cache/ledmatrix/placeholder_logos/` for the sports plugins. It does
|
||||||
sports plugins.
|
not touch the cache manager's other fallbacks (`/opt/ledmatrix/cache`,
|
||||||
|
`$TMPDIR/ledmatrix_cache`).
|
||||||
|
|
||||||
- **`fix_plugin_permissions.sh`** — Fixes ownership on the plugins
|
- **`fix_plugin_permissions.sh`** — Fixes ownership on the plugins
|
||||||
directory so both the root display service and the web service user
|
directory so both the root display service and the web service user
|
||||||
@@ -31,6 +34,11 @@ owned by the `ledmatrix` service user or by `root`.
|
|||||||
systemd journal access, and the sudoers entries the web interface
|
systemd journal access, and the sudoers entries the web interface
|
||||||
needs to control the display service.
|
needs to control the display service.
|
||||||
|
|
||||||
|
- **`safe_pip_install.sh`** — Installs a `requirements.txt` as root
|
||||||
|
after checking it is the project's own or one under `plugin-repos/` or
|
||||||
|
`plugins/`. Used by the web interface (via sudo) to install plugin
|
||||||
|
dependencies where `ledmatrix.service` can import them.
|
||||||
|
|
||||||
- **`safe_plugin_rm.sh`** — Validates that a plugin removal path is
|
- **`safe_plugin_rm.sh`** — Validates that a plugin removal path is
|
||||||
inside an allowed base directory before deleting it. Used by the web
|
inside an allowed base directory before deleting it. Used by the web
|
||||||
interface (via sudo) when a user clicks **Uninstall** on a plugin —
|
interface (via sudo) when a user clicks **Uninstall** on a plugin —
|
||||||
|
|||||||
@@ -7,14 +7,18 @@ This directory contains scripts for installing and configuring the LEDMatrix sys
|
|||||||
- **`one-shot-install.sh`** - Single-command installer; clones the
|
- **`one-shot-install.sh`** - Single-command installer; clones the
|
||||||
repo, checks prerequisites, then runs `first_time_install.sh`.
|
repo, checks prerequisites, then runs `first_time_install.sh`.
|
||||||
Invoked via `curl ... | bash` from the project root README.
|
Invoked via `curl ... | bash` from the project root README.
|
||||||
- **`install_service.sh`** - Installs the main LED Matrix display service (systemd)
|
- **`install_service.sh`** - Installs, enables and starts the display
|
||||||
- **`install_web_service.sh`** - Installs the web interface service (systemd)
|
service (`ledmatrix.service`), the web interface service
|
||||||
|
(`ledmatrix-web.service`) and the update-verify units (systemd)
|
||||||
|
- **`install_web_service.sh`** - Installs only the web interface service
|
||||||
|
and the update-verify units (systemd)
|
||||||
- **`install_wifi_monitor.sh`** - Installs the WiFi monitor daemon service
|
- **`install_wifi_monitor.sh`** - Installs the WiFi monitor daemon service
|
||||||
- **`setup_cache.sh`** - Sets up persistent cache directory with proper permissions
|
- **`setup_cache.sh`** - Sets up persistent cache directory with proper permissions
|
||||||
- **`configure_web_sudo.sh`** - Configures passwordless sudo access for web interface actions
|
- **`configure_web_sudo.sh`** - Configures passwordless sudo access for web interface actions
|
||||||
- **`configure_wifi_permissions.sh`** - Grants the `ledmatrix` user
|
- **`configure_wifi_permissions.sh`** - Grants the web interface's user
|
||||||
the WiFi management permissions needed by the web interface and
|
(the user who runs the script, i.e. the one you installed LEDMatrix as;
|
||||||
the WiFi monitor service
|
there is no `ledmatrix` system user) the passwordless `nmcli` and related
|
||||||
|
WiFi permissions the web interface needs
|
||||||
- **`migrate_config.sh`** - Migrates configuration files to new formats (if needed)
|
- **`migrate_config.sh`** - Migrates configuration files to new formats (if needed)
|
||||||
- **`debug_install.sh`** - Diagnostic helper used when an install
|
- **`debug_install.sh`** - Diagnostic helper used when an install
|
||||||
fails; collects environment info and recent logs
|
fails; collects environment info and recent logs
|
||||||
|
|||||||
Reference in New Issue
Block a user