233 lines
5 KiB
Markdown
233 lines
5 KiB
Markdown
|
|
---
|
||
|
|
marp: true
|
||
|
|
theme: gaia
|
||
|
|
class: invert
|
||
|
|
paginate: true
|
||
|
|
title: How to implement a TAPPaaS module
|
||
|
|
description: Walk-through of adding a new module to the TAPPaaS repository
|
||
|
|
---
|
||
|
|
|
||
|
|
<style>
|
||
|
|
section { font-size: 26px; }
|
||
|
|
h1 { font-size: 1.5em; }
|
||
|
|
h2 { font-size: 1.15em; }
|
||
|
|
pre { font-size: 0.72em; line-height: 1.35; }
|
||
|
|
table { font-size: 0.8em; }
|
||
|
|
th, td { padding: 0.25em 0.6em; }
|
||
|
|
/* Unfinished content, loud on purpose: an unfinished deck should never be
|
||
|
|
presented by accident. Written in the markdown as `TODO: ...`. */
|
||
|
|
code.todo { color: #ff8a80; font-weight: 600; }
|
||
|
|
div.mermaid { display: flex; justify-content: center; }
|
||
|
|
</style>
|
||
|
|
|
||
|
|
<!-- _paginate: false -->
|
||
|
|
|
||
|
|
# How to implement a TAPPaaS module
|
||
|
|
|
||
|
|
From empty directory to merged pull request
|
||
|
|
|
||
|
|
<!--
|
||
|
|
Speaker notes go in HTML comments; press `p` in the browser for presenter view.
|
||
|
|
TODO: 30-second framing — who is in the room, what they walk out able to do.
|
||
|
|
-->
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Who this is for
|
||
|
|
|
||
|
|
- You want to add an **app** or a **foundation** capability to TAPPaaS
|
||
|
|
- You can read shell, JSON, and a little Nix
|
||
|
|
- You have a TAPPaaS test environment you are allowed to break
|
||
|
|
|
||
|
|
**Prerequisites**
|
||
|
|
|
||
|
|
- A clone of `TAPPaaS/TAPPaaS`, branch `TODO: ADR007 or stable`
|
||
|
|
- SSH access to a test site
|
||
|
|
- `TODO: tooling list`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Vocabulary in 60 seconds
|
||
|
|
|
||
|
|
| Term | Means |
|
||
|
|
| --- | --- |
|
||
|
|
| **Module** | One installable unit under `src/apps/` or `src/foundation/` |
|
||
|
|
| **Service** | A part of a module with its own lifecycle scripts |
|
||
|
|
| **Manager** | Owns desired state for a domain |
|
||
|
|
| **Controller** | Applies desired state to one concrete technology |
|
||
|
|
|
||
|
|
`TODO: tighten against ADR-007 taxonomy; drop the terms that do not matter here`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Anatomy of a module
|
||
|
|
|
||
|
|
```text
|
||
|
|
src/apps/<module>/
|
||
|
|
├── README.md # what it is, why it exists
|
||
|
|
├── DESIGN.md # how it is put together
|
||
|
|
├── INSTALL.md # operator-facing install notes
|
||
|
|
├── UPGRADE.md # operator-facing upgrade notes
|
||
|
|
├── AUTHORS.md # who to ask
|
||
|
|
├── LICENSE
|
||
|
|
├── <module>.json # declaration: the module's contract
|
||
|
|
├── <module>.nix # runtime definition
|
||
|
|
├── install.sh # create it
|
||
|
|
├── update.sh # move it forward
|
||
|
|
├── test.sh # prove it works
|
||
|
|
└── services/<svc>/ # per-service install/update/test/delete
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## The path from nothing to merged
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
flowchart LR
|
||
|
|
A[Scaffold from<br/>00-Template] --> B[Declare<br/>module.json]
|
||
|
|
B --> C[Define runtime<br/>module.nix]
|
||
|
|
C --> D[install.sh]
|
||
|
|
D --> E[services/]
|
||
|
|
E --> F[update.sh]
|
||
|
|
F --> G[test.sh]
|
||
|
|
G --> H[Docs]
|
||
|
|
H --> I[PR + CI]
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Step 1 — Scaffold
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cp -r src/apps/00-Template src/apps/<module>
|
||
|
|
```
|
||
|
|
|
||
|
|
- Rename `template.json` → `<module>.json`, `template.nix` → `<module>.nix`
|
||
|
|
- Read `README-template.md`, then delete it
|
||
|
|
- `TODO: is there a scaffold script? if not, should there be?`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Step 2 — Declare the module
|
||
|
|
|
||
|
|
`<module>.json`
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"TODO": "smallest working declaration"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
- What the module *is*, not how it is built
|
||
|
|
- `TODO: required keys, optional keys, validation`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Step 3 — Define the runtime
|
||
|
|
|
||
|
|
`<module>.nix`
|
||
|
|
|
||
|
|
```nix
|
||
|
|
# TODO: minimal example
|
||
|
|
```
|
||
|
|
|
||
|
|
- `TODO: what belongs in nix vs. what belongs in install.sh`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Step 4 — `install.sh`
|
||
|
|
|
||
|
|
- Idempotent: safe to run twice
|
||
|
|
- Fails loudly, never half-way
|
||
|
|
- `pre-install.sh` when something must exist first
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# TODO: skeleton with the house conventions
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Step 5 — Services
|
||
|
|
|
||
|
|
```text
|
||
|
|
services/<svc>/install-service.sh
|
||
|
|
services/<svc>/update-service.sh
|
||
|
|
services/<svc>/test-service.sh
|
||
|
|
services/<svc>/delete-service.sh
|
||
|
|
```
|
||
|
|
|
||
|
|
- One service = one thing with its own lifecycle
|
||
|
|
- `TODO: when to split into services vs. keep it in the module`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Step 6 — `update.sh`
|
||
|
|
|
||
|
|
- Upgrade in place, no data loss
|
||
|
|
- Version pinning: `TODO`
|
||
|
|
- Rollback story: `TODO`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Step 7 — `test.sh`
|
||
|
|
|
||
|
|
- Runs against a real environment, not a mock
|
||
|
|
- Exit non-zero on failure, quiet on success
|
||
|
|
- `TODO: what CI runs, and what only a human can check`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Step 8 — Documentation
|
||
|
|
|
||
|
|
| File | Answers |
|
||
|
|
| --- | --- |
|
||
|
|
| `README.md` | What is this and why would I install it? |
|
||
|
|
| `DESIGN.md` | How is it built, what were the trade-offs? |
|
||
|
|
| `INSTALL.md` | How do I install it, step by step? |
|
||
|
|
| `UPGRADE.md` | What breaks between versions? |
|
||
|
|
|
||
|
|
Docs are synced to the docs site — a missing README is a missing page.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Try it on a test site
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# TODO: the real loop
|
||
|
|
```
|
||
|
|
|
||
|
|
1. Deploy to the test environment
|
||
|
|
2. Run `test.sh`
|
||
|
|
3. Break it on purpose, run it again
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Submit
|
||
|
|
|
||
|
|
- Branch: `TODO: naming convention`
|
||
|
|
- One module per pull request
|
||
|
|
- CI must be green
|
||
|
|
- Review checklist:
|
||
|
|
- [ ] Idempotent install
|
||
|
|
- [ ] `test.sh` passes on a clean site
|
||
|
|
- [ ] Docs complete
|
||
|
|
- [ ] `TODO`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Pitfalls
|
||
|
|
|
||
|
|
- `TODO: the three mistakes reviewers actually see`
|
||
|
|
- `TODO`
|
||
|
|
- `TODO`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Where to go next
|
||
|
|
|
||
|
|
- `src/apps/00-Template/` — the canonical starting point
|
||
|
|
- `docs/ADR/ADR-007 - TAPPaaS Taxonomy.md`
|
||
|
|
- `TODO: contribution guide link`
|
||
|
|
|
||
|
|
**Questions?**
|