| index c9a3f412f..c192e0149 100644 |
| --- a/docs/site/cli.md |
| +++ b/docs/site/cli.md |
| @@ -23,19 +23,13 @@ credentials gets their work done. With `CARLOS_DEPLOYMENT_BUCKET` or |
| `CARLOS_DEPLOYMENT_DIR` set, they write to the bucket directly, which is the |
| operator's path. Where a command only works one way, its section says so. |
| |
| -## carlos help |
| - |
| -Prints the command list, grouped the way this page is. It goes to stdout and |
| -exits 0, so `carlos help | less` works. A bare `carlos` with no arguments |
| -prints the same text on stderr and exits 2, because that one is a mistake. |
| - |
| ## Your apps |
| |
| Everything from claiming a name to watching a deploy land. None of it needs |
| access to a box, a cloud console, or the deployment's bucket; that is a rule |
| the platform holds itself to, and a command that broke it would be a bug. |
| |
| -## carlos auth |
| +### carlos auth |
| |
| Logs this terminal in to a console. `carlos auth login` prints a short code |
| that you approve in a browser already signed in to that console, and the |
| @@ -57,7 +51,7 @@ shows the console this machine talks to by default, and sets it when you give |
| it a URL. With `-project` it writes `./.carlos/config`, which you can commit |
| so a checkout pins its own deployment. |
| |
| -## carlos apps |
| +### carlos apps |
| |
| Claims an app name, moves an app onto a customer fleet, and deletes or |
| restores one. Creating goes through the same door the console's New app form |
| @@ -80,7 +74,7 @@ later, puts the app's routes and instances on a fleet your account owns. |
| in that empty spelling: leaving it off is a usage error, never a silent |
| clear. |
| |
| -## carlos ship |
| +### carlos ship |
| |
| Publishes a release. The artifact is hashed, stored under its content |
| address, and recorded in a manifest that never changes afterwards. Shipping |
| @@ -97,7 +91,7 @@ off is the point of having one: ship mints the next iteration under it. Use |
| is one line for humans and shows up in `carlos releases` and in the console, |
| so write it for the person doing a rollback at 2am. |
| |
| -## carlos promote |
| +### carlos promote |
| |
| Points a channel at a version you have already shipped. The ladder is |
| `canary → edge → beta → stable`: beta is entered from edge and stable from |
| @@ -113,7 +107,7 @@ Promoting the same version twice succeeds and does nothing. `-hotfix` skips |
| the ladder and is an operator act: it works on the direct-bucket path only, |
| and the console refuses it by name, so the flag never quietly does nothing. |
| |
| -## carlos deploy |
| +### carlos deploy |
| |
| Ship, promote, and then wait until the app's URL actually serves the new |
| build. It watches the `X-Carlos-Version` header on the live host and does not |
| @@ -125,9 +119,12 @@ between them. |
| carlos deploy -app hello ./hello |
| ``` |
| |
| -Signed-in only. In a project with saved defaults you can run `carlos deploy` |
| -with no arguments at all, and the first run at a terminal asks what to deploy |
| -and offers to remember the answer. `-channel` overrides the channel it picks |
| +Signed-in only. With saved project defaults you can run `carlos deploy` with |
| +no arguments and no questions. The first run at a terminal asks which |
| +artifact to ship, works out from what you point it at whether that is a |
| +binary or a site, and offers to save the answer as the project's default. |
| +With neither arguments nor defaults and no terminal to ask at — CI, usually — |
| +it refuses instead of guessing. `-channel` overrides the channel it picks |
| (normally the one the app's instances already follow), and `-host` scopes the |
| watch to a single instance. A static site needs that second flag, having no |
| instances to resolve a channel from. |
| @@ -136,7 +133,7 @@ instances to resolve a channel from. |
| carlos deploy -app website -kind static -host www.example.com ./dist |
| ``` |
| |
| -## carlos restart |
| +### carlos restart |
| |
| Cycles an app's processes with no new version and no config change. This is |
| the answer to a wedged instance. |
| @@ -152,7 +149,7 @@ stop within seconds and respawn on their next request, which for an idle app |
| may be a while. Nothing is stuck: the instance comes back with the next |
| request that needs it. Hibernating instances are left asleep. |
| |
| -## carlos rollback |
| +### carlos rollback |
| |
| Points a channel back at the version it was serving before. |
| |
| @@ -160,7 +157,7 @@ Points a channel back at the version it was serving before. |
| carlos rollback -app hello stable |
| ``` |
| |
| -## carlos channels |
| +### carlos channels |
| |
| What each of the app's channels is serving right now, with the tag if the |
| release earned one at stable. |
| @@ -169,7 +166,7 @@ release earned one at stable. |
| carlos channels -app hello |
| ``` |
| |
| -## carlos releases |
| +### carlos releases |
| |
| Every version shipped, newest first, with the label its author typed and the |
| tag it earned. Channels answer "what is running"; this answers "what is there |
| @@ -186,7 +183,7 @@ rollback history, tagged releases, anything inside the bake window, and each |
| box's own adopted versions are never pruned, so nothing promoted or recent |
| disappears by policy. `-off` goes back to keeping everything. |
| |
| -## carlos version |
| +### carlos version |
| |
| `carlos version` prints the build id of the binary in front of you. It is the |
| first thing to check when a command behaves unlike this page describes. |
| @@ -199,7 +196,7 @@ next one for you. |
| carlos version target -app hello 0.5.0 |
| ``` |
| |
| -## carlos env |
| +### carlos env |
| |
| Plain per-app config vars: `set`, `unset`, `list`. |
| |
| @@ -212,7 +209,7 @@ bundle instead, layered on top of the default when config is materialized, |
| and `carlos route -environment` is what binds a route to one. |
| `carlos env environments -app hello` lists the bundle names an app has. |
| |
| -## carlos secrets |
| +### carlos secrets |
| |
| The same shape as `carlos env`, sealed. `list` prints key names and never |
| values. |
| @@ -225,7 +222,7 @@ Sealing uses a public key; the private half lives on the box that decrypts |
| them and never leaves it, in either mode. `carlos secrets genkey` mints the |
| pair, and it is always local to your terminal. |
| |
| -## carlos instances |
| +### carlos instances |
| |
| An app's instances are the places it actually runs. `carlos instances enable` |
| is the app's opt-in to provisioning, and until it is set the API refuses to |
| @@ -247,7 +244,7 @@ it lists that box's own registry routes, backing and owning unit included. |
| Off the box, [carlos routes](/docs/cli#carlos-routes) answers the same |
| question through the console. |
| |
| -## carlos routes |
| +### carlos routes |
| |
| The app's routes on this deployment: where each one sends traffic, which |
| channel it follows, and which config environment it is bound to. That last |
| @@ -261,7 +258,7 @@ carlos routes -app hello |
| It reads the console's own box, so on a multi-box fleet a short answer is not |
| necessarily a complete one. The command says so every time it prints. |
| |
| -## carlos domains |
| +### carlos domains |
| |
| Attaches a customer's own hostname to one of the app's routes, detaches it, |
| or lists what is claimed. |
| @@ -276,7 +273,7 @@ that route at its next domains pass, certificate and all. The `list` verb |
| joins the claims to the fleet's own readings sweep, so DNS state, certificate |
| expiry and delegation are readable without leaving the terminal. |
| |
| -## carlos logs |
| +### carlos logs |
| |
| The app's own stdout and stderr, merged with the platform's events about it: |
| wakes, restarts, and failures with the reason. A site served from files has |
| @@ -290,7 +287,7 @@ carlos logs -app hello -since 1h -f |
| an RE2 pattern, `-stream app` drops the platform commentary, and `-host` |
| narrows to one instance. |
| |
| -## carlos store |
| +### carlos store |
| |
| Object storage for an app. `create` declares that the app wants a bucket, |
| which is a request and not a provision — nothing exists in any cloud account |
| @@ -304,25 +301,36 @@ carlos store status -app hello |
| |
| `carlos store rotate` mints a fresh credential and leaves the old one live |
| until you run it again with `-finish`, so the app has a window to pick the |
| -new one up. Granting needs a deployment operator; the other three are member |
| -verbs. |
| +new one up. Rotating, declaring and reading status are member verbs and want |
| +nothing but your bearer token. `grant` is the one that spends money in the |
| +deployment's own cloud account, so it also wants an address on |
| +`CARLOS_STORE_OPERATORS`; that check runs after the account gate, so a |
| +stranger still meets the same 404 as everyone else rather than a 403 that |
| +would confirm the app exists. |
| |
| -## carlos ledger |
| +### carlos ledger |
| |
| -Append-only hash-chained ledgers an app can publish: `append` adds an entry, |
| -`head` prints the chain's current head, `list` shows what the app has, and |
| -`publish` decides which of them it serves publicly. |
| +Append-only hash-chained ledgers an app can publish. `append` adds one JSON |
| +entry to a chain, `head` prints that chain's current head, `list` shows the |
| +app's ledgers and what it publishes, and `publish` decides which of them are |
| +served publicly. |
| |
| ```sh |
| -carlos ledger append -app hello events entry.json |
| +carlos ledger append -app hello carbon entry.json |
| ``` |
| |
| -`carlos ledger verify` walks a published chain over plain HTTPS and re-hashes |
| -every entry. It needs no credentials at all, which is the whole point: |
| +`blob` uploads files to a chain as content-addressed blobs and prints each |
| +one's sha, so an entry can point at it. Uploads are create-only and capped at |
| +4 MB a file, and re-uploading identical bytes does nothing. |
| + |
| +Ledgers have no direct-bucket mode at all: every sub-verb except `verify` |
| +goes through the console, because a contributor's machine is never given |
| +bucket credentials. `carlos ledger verify` walks a published chain over plain |
| +HTTPS and re-hashes every entry. It needs no credentials at all, which is the whole point: |
| anybody can check a ledger you publish, including you, from a machine that |
| has never been logged in. |
| |
| -## carlos vet |
| +### carlos vet |
| |
| Checks a shipped release against the platform contract before anyone promotes |
| it. The manifest has to exist and parse, and every artifact's stored bytes |
| @@ -337,7 +345,7 @@ serve HTTP on that socket, and answer `GET /healthz` with a 200 within ten |
| seconds. That is the entire app contract, and this is the cheapest place to |
| find out you have broken it. |
| |
| -## carlos update |
| +### carlos update |
| |
| Replaces the `carlos` binary on your workstation with the latest published |
| release, checking the signed checksums before it swaps anything. Where a |
| @@ -358,7 +366,7 @@ The verbs for the person who owns the boxes. Some of these run against a |
| console like the app commands above; others open a box's registry directly |
| and only make sense while you are standing on it. |
| |
| -## carlos bootstrap |
| +### carlos bootstrap |
| |
| Prepares a host to be a CARLOS box: the service user, the data directories, |
| the systemd units. Run it once per host, as root. |
| @@ -372,7 +380,7 @@ users and running no systemctl, which is how you read what it would do before |
| it does it. `-offcloud` is for a box outside EC2, where credentials come from |
| a staged 0600 file instead of an instance profile. |
| |
| -## carlos accounts |
| +### carlos accounts |
| |
| Accounts are the tenancy primitive: apps, fleets, credentials and bucket |
| prefixes all hang off one. `create` mints an account and prints the sqid |
| @@ -390,7 +398,7 @@ logged-in one, which is why it exists. |
| prefix and re-stamps its routes. Run it with `-dry-run` first; it prints the |
| plan and touches nothing. |
| |
| -## carlos fleets |
| +### carlos fleets |
| |
| A fleet is a group of remote boxes an account owns, dialing in to this |
| console over a channel named `<fleet>/<label>`. Create one against the |
| @@ -410,7 +418,7 @@ the old one, but it does not evict a channel the box is already holding. If a |
| credential may be compromised, `detach-box` is the command that actually |
| stops it. |
| |
| -## carlos services |
| +### carlos services |
| |
| Credentials a server holds rather than a person: a CI job that ships, a |
| sidecar that reads instances. Reach is fixed at mint, so adding you to |
| @@ -430,7 +438,7 @@ The secret prints once, same as a fleet token, and the same distinction |
| applies at the other end: `rotate` refuses the credential's next call with |
| the old secret, `revoke` stops it whatever secret it holds. |
| |
| -## carlos add |
| +### carlos add |
| |
| Writes a route straight into a box's registry: this hostname, served by this |
| app, following this channel. It is the box-local, operator-side counterpart |
| @@ -446,7 +454,7 @@ tenant. `-unit console.service` names the systemd unit that owns the route's |
| process, which is what lets adoption cycle it; leave it off for an ordinary |
| exec child. |
| |
| -## carlos remove |
| +### carlos remove |
| |
| Drops one of this box's routes. It stops routing the hostname and never |
| touches the instance's database. |
| @@ -455,7 +463,7 @@ touches the instance's database. |
| carlos remove hello.example.com |
| ``` |
| |
| -## carlos route |
| +### carlos route |
| |
| Changes one thing about a route that already exists. Each axis is its own |
| operation and the command refuses to combine them, because a capability grant |
| @@ -481,7 +489,7 @@ environment belong to its instance record: `carlos route` refuses both axes |
| on such a row and names the record, because the reconciler would revert you |
| within seconds anyway. |
| |
| -## carlos release-keygen |
| +### carlos release-keygen |
| |
| Mints the deployment's root signing key, or a scoped key that can sign only |
| certain rungs of the ladder. |
| @@ -496,7 +504,7 @@ a grant. The grant carries no secret material but has to travel with the key, |
| because a scoped key on its own signs pointers nothing will accept. Only the |
| root key can mint a grant, which is what stops a scoped key widening itself. |
| |
| -## carlos economics |
| +### carlos economics |
| |
| Records one month's AWS bill so the console's economics dashboard has a real |
| number to divide by. |
| @@ -509,7 +517,7 @@ Operator only, and the console answers everyone else with the same bare 404 |
| it gives an unknown route. A "not found" here almost always means your |
| account lacks the fleet-operator bit, not that you typed the path wrong. |
| |
| -## carlos status |
| +### carlos status |
| |
| `-live` prints what every box in the fleet last reported about itself: |
| release, tunnel state, memory, load, free disk. A box that has stopped |
| @@ -532,7 +540,7 @@ box's own agent tick. |
| These are what systemd starts. You will rarely type them, but knowing what |
| they do explains most of what happens between a promote and a URL changing. |
| |
| -## carlos edge |
| +### carlos edge |
| |
| The front door. TLS and ACME, and the proxy that maps a hostname to whatever |
| is serving it. One per box, started by `carlos-edge.service`. |
| @@ -545,13 +553,13 @@ carlos edge -dev -http :8080 |
| laptop. `-fallback` redirects unknown hostnames somewhere (an apex marketing |
| site, usually) instead of returning the plain 404. |
| |
| -## carlos agent |
| +### carlos agent |
| |
| Edge, the hibernation activator, release adoption and the status tick, in one |
| process per host. This is what a box actually runs; `carlos edge` alone is |
| the proxy without any of the rest. |
| |
| -## carlos adopt |
| +### carlos adopt |
| |
| One release-adoption pass: read each route's channel, resolve what that |
| channel points at, fetch it if the box does not have it, and swap the |
| @@ -573,7 +581,7 @@ build the process is not serving. |
| root-side unit to run for it, since the agent can request a pass but cannot |
| write to `/etc` or restart units itself. |
| |
| -## carlos ops |
| +### carlos ops |
| |
| Box operations, run by a timer or by an operator standing on the box. |
| `litestream` regenerates the replication config from the registry and the |
| @@ -588,7 +596,18 @@ the deployment bucket so you can read it off-box. |
| carlos ops restore-verify |
| ``` |
| |
| -## carlos canary |
| +## Everything else |
| + |
| +`carlos help` belongs to all three roles above; `carlos canary` belongs |
| +to none of them yet. |
| + |
| +### carlos help |
| + |
| +Prints the command list, grouped the way this page is. It goes to stdout and |
| +exits 0, so `carlos help | less` works. A bare `carlos` with no arguments |
| +prints the same text on stderr and exits 2, because that one is a mistake. |
| + |
| +### carlos canary |
| |
| Reserved, and not implemented: typing it exits with `not implemented`. |
| Canary releases today are ordinary channels named `canary/<something>`, |