Metadata-Version: 2.5
Name: catena-installer
Version: 0.11.3
Summary: Install a Catena server from this machine, and reach its panel
License: # Catena Community License
        
        Catena Sustainable Use License, Version 1.0
        
        Copyright (c) 2026 Marc-Antoine Lalonde. All rights reserved.
        
        This license adapts the n8n Sustainable Use License (fair-code) model.
        Catena Community is fair-code: the source is published and free to use
        for your own internal business purposes, with one boundary -- you may not
        offer Catena to third parties as a hosted or managed service. That
        managed offering is Catena Business, the commercial edition.
        
        ## Acceptance
        
        By using the software, you agree to all of the terms and conditions
        below.
        
        ## Copyright License
        
        The licensor grants you a non-exclusive, royalty-free, worldwide,
        non-sublicensable, non-transferable license to use, copy, distribute,
        make available, and prepare derivative works of the software, in each
        case subject to the limitations and conditions below.
        
        ## Limitations
        
        You may use or modify the software only for your own internal business
        purposes or for non-commercial or personal use. "Your own internal
        business purposes" means running the software for the benefit of you or
        your company; it does not include providing the software, or its
        functionality, to any third party.
        
        You may distribute the software or provide it to others only if you do so
        free of charge and for non-commercial purposes, and only together with a
        copy of these terms.
        
        You may not, whether for a fee or free of charge:
        
        1. offer or provide the software, modified or not, to third parties as a
           hosted or managed service, where that service gives a third party
           access to any substantial set of the features or functionality of the
           software; or
        2. operate, administer, or manage the software on behalf of a third
           party as a commercial offering.
        
        For the avoidance of doubt, the prohibitions in (1) and (2) apply
        regardless of who owns or controls the infrastructure the software runs
        on, including where a third party owns the server. Running the software
        for your own internal business purposes through a contractor acting
        solely on your behalf is permitted; using the software to deliver a
        service to third parties is not.
        
        You may not alter, remove, or obscure any licensing, copyright, or other
        notices of the licensor in the software. Any use of the licensor's
        trademarks is subject to the Trademarks section below and applicable law.
        
        ## Trademarks
        
        "Catena", the Catena name, and the Catena logo are trademarks of
        Marc-Antoine Lalonde. This license grants you no right to use them. You may make a
        nominative reference to Catena to identify the unmodified software. If
        you distribute a modified version of the software, you must remove all
        Catena trademarks and rename your version so that it is not confusingly
        similar to Catena, and you must not represent that your version is
        endorsed by or associated with the licensor.
        
        ## Enterprise (Business) modules
        
        The Catena Business (Enterprise) modules are not covered by this license.
        They are distributed separately as compiled, license-gated binaries from
        catenahq/catena-ee and are not published as source. Nothing in this
        license grants any right in or to those modules.
        
        ## Contributions
        
        Unless you state otherwise, any contribution you intentionally submit for
        inclusion in the software (a "contribution") is provided under the terms
        of this license. In addition, you grant Marc-Antoine Lalonde a perpetual,
        worldwide, non-exclusive, royalty-free, irrevocable license to use,
        reproduce, modify, distribute, sublicense, and relicense your
        contribution, in whole or in part, under this license and under any other
        license terms, including proprietary or commercial terms (such as the
        Catena Business modules). You represent that you are legally entitled to
        grant this license for each contribution you submit.
        
        ## Patents
        
        The licensor grants you a license, under any patent claims the licensor
        can license, or becomes able to license, to make, have made, use, sell,
        offer for sale, import, and have imported the software, in each case
        subject to the limitations and conditions in this license. This license
        does not cover any patent claims that you cause to be infringed by
        modifications or additions to the software. If you or your company make
        any written claim that the software infringes or contributes to
        infringement of any patent, your patent license for the software granted
        under these terms ends immediately. If your company makes such a claim,
        your patent license ends immediately for work on behalf of your company.
        
        ## Notices
        
        You must ensure that anyone who gets a copy of any part of the software
        from you also gets a copy of these terms. If you modify the software, you
        must include in any modified copies prominent notices stating that you
        have modified the software.
        
        ## No Other Rights
        
        These terms do not imply any licenses other than those expressly granted
        in these terms.
        
        ## Termination
        
        If you use the software in violation of these terms, such use is not
        licensed, and your licenses will automatically terminate. If the licensor
        provides you with a notice of your violation, and you cease all violation
        of this license no later than 30 days after you receive that notice, your
        licenses will be reinstated retroactively. However, if you violate these
        terms after such reinstatement, any additional violation of these terms
        will cause your licenses to terminate automatically and permanently.
        
        ## No Liability
        
        As far as the law allows, the software comes as is, without any warranty
        or condition, and the licensor will not be liable to you for any damages
        arising out of these terms or the use or nature of the software, under
        any kind of legal claim.
        
        ## Governing Law
        
        These terms are governed by the laws of the Province of Quebec and the
        federal laws of Canada applicable therein, without regard to conflict-of-
        law rules. The courts of the Province of Quebec (judicial district of
        Montreal) have exclusive jurisdiction over any dispute arising out of or
        relating to these terms or the software.
        
        ## No Conversion to Open Source
        
        Unlike a Business Source License, this license does not automatically
        convert to an OSI-approved open-source license after any period of time.
        The licensor may, at its sole discretion, release any version under
        other terms.
        
        ## Definitions
        
        The licensor is Marc-Antoine Lalonde, the entity offering these terms. The
        software is the software the licensor makes available under these terms,
        including any portion of it.
        
        "you" refers to the individual or entity agreeing to these terms.
        
        "your company" is any legal entity, sole proprietorship, or other kind of
        organization that you work for, plus all organizations that have control
        over, are under the control of, or are under common control with that
        organization. Control means ownership of substantially all the assets of
        an entity, or the power to direct its management and policies by vote,
        contract, or otherwise. Control can be direct or indirect.
        
        "your licenses" are all the licenses granted to you for the software
        under these terms.
        
        "use" means anything you do with the software requiring one of your
        licenses.
        
        "trademark" means trademarks, service marks, and similar rights.
        
        ---
        
        Upstream applications deployed by Catena each carry their own license
        (Nextcloud GPL, Rocket.Chat MIT, OnlyOffice AGPL, and so on); those are
        unaffected by this file.
License-File: LICENSE
Requires-Python: >=3.12
Requires-Dist: paramiko>=3.4
Requires-Dist: pyyaml>=6
Description-Content-Type: text/markdown

# catena-installer

`catena-installer` installs a Catena server from the client's machine and
opens its panel. With no arguments it serves a browser page on loopback; with
a verb it runs in the console.

```sh
uvx catena-installer                                   # the page
uvx catena-installer install --inventory clientco      # the console
uvx catena-installer install --inventory clientco --release vX.Y.Z
uvx catena-installer connect --inventory clientco      # open the panel here
```

From a checkout of catena-ce, `uv run catena-installer` runs this tree's copy:
the one operators and the test bench run.

## Where it runs, and what that decides

On the **client's own machine**, Windows, macOS or Linux, with
[uv](https://docs.astral.sh/uv/) the only thing to install. Whoever holds the
SSH private key reaches the server, so a hosted installer would make the
operator custodian of every client's server (ADR 0011).

It runs no Ansible itself. It reaches the server over SSH (paramiko), sends a
starter script and the image fetcher through that session, and the server
installs itself with the code of the release it fetched
([../ansible/install-host.sh](../ansible/install-host.sh)): the roles, the
engines and the panel the server ends up with are one version. What the
server prints comes back through the session, to the console or to the page.

The **console owns the job; the browser is a view**. Closing the browser
changes nothing. Closing the console stops the install with it; reopening its
inventory keeps every answer and offers the install again, as after a failed
one. Running the install again on an installed server re-applies the release
it runs, and repairs it.

## The install, step by step

1. Log in: as `ops` with the inventory's key on a server installed before,
   else as the provider's login with the key, else once with the provider's
   password to add the key there. A server presenting another host key than
   the one this machine trusts gets nothing until the client confirms it was
   reinstalled.
2. Leg `accounts`, through that login: the starter installs what the release
   needs to start, fetches the release image by digest and runs its
   install-host.sh, which creates `ops` and the forward-only `panel` account
   with this machine's public key. Nothing is closed yet.
3. Log in again, as `ops` with the key. That login is what the hardening
   waits for: the server checks sshd's record of this very session before its
   first role turns off every other login.
4. Leg `system`: bootstrap, the passwords (printed between two marker lines),
   the converge, the version recorded, the server's own checks.
5. The checks only another machine can make: a scan of every TCP port of the
   public IP against what the server declares, and the containers' network
   out of reach from here.
6. The page opens the `panel` account's forward and links the panel;
   `connect` does the same from the console.

`--release vX.Y.Z` moves the server to that release with that release's own
code and records it, the same end state as the panel's update. Without it the
server keeps the release it records, and a new server gets the newest one.

## What the package carries

The installer page and the console are one program (`catena_installer/`). It
carries a few files of the Ansible tree, which a wheel holds under
`catena_installer/tree/` and a checkout reads from `../ansible/`
(`catena_installer/tree.py`): `seed.py` and the knob registry, which write and
read an inventory's `.env`, and the files sent to the server before the
release is there, `helpers/fetch_release.py` and what it imports. The starter
script (`catena_installer/starter.sh`) has nothing version-specific in it, so
the newest installer can install or move a server to any release.

It lives beside `../ansible/` rather than in it because catena-admin's vendor
step copies the tracked `ansible/` tree into the public panel image, and the
installer does not belong there.

## It holds no knob knowledge

The sections, their explanations and the questions each asks come from
[`../ansible/helpers/knobs.yml`](../ansible/helpers/knobs.yml), the registry
the on-box store, the installer and the settings page all read. A knob that
declares a `step` appears in that section under its `label`, with its `help`
behind a `(?)` tooltip; one that does not is never asked. There is no list of
fields in this package, and a test refuses one.

Adding a question is therefore a registry edit. Adding a *proof* is a function
in `catena_installer/steps.py`, registered in its `PROBES` under the section it
checks. The one button verifies every section and starts the install only when
none of them blocks, with what the checks found under it.

The server's check is the one that matters: an SSH server has to answer, with
the host key this machine trusts for it, and the install has to be able to log
in. A server presenting another key gets no login and no password: its check
carries a box to tick when the server was reinstalled. Either the key already
opens the initial login -- most providers install it when the server is
ordered, and the key field suggests the pairs already in `~/.ssh`, or offers to
create the one it names -- or the provider's password does, and the install
uses it once to add the key. The password is the one field the section has
beside the registry's, held in memory only.

Fields the registry marks `required` block until filled; everything else is
labelled optional.

## English and French

Every page is in English or French. The switcher at the end of the tab bar
stores the choice in a cookie; without one, the browser's preferred language
decides, then English. A registry field carries its `label` and `help` in both
languages. The page's own words are in `catena_installer/translations/`, one
file per language with the same keys, which a test holds together. The
console reports in English.

## An inventory is the run

Inventories live in the user's data directory (`~/.local/share/catena/inventory`
on Linux, `~/Library/Application Support/catena/inventory` on macOS,
`%APPDATA%\catena\inventory` on Windows), in `../ansible/inventory/` when run
from a checkout, or under `CATENA_INVENTORY_ROOT`. The page has two tabs.
Inventory lists them, one per line, and creates new ones. Installation is one
page: the target and the configuration in one form, the button that verifies
and installs, the install's output, and then the server access section with
the passwords and the way into the panel. Every field starts from the
registry's default, and a knob that declares an `example` shows it as a
placeholder, never as a value. The button saves the whole form, whatever the
verification finds:

```
<inventory root>/<name>/
  .env                     the answers, written by seed.py's own writer: the
                           file the console reads. NOT the credentials.
  hosts.yml                the server's name.
  .catena-installer.json   the install's state and the installer that runs it. 0600.
```

The provider's password and an admin password pin are held in memory for the
life of the process. The pin reaches the server as a transient 0600 file for
the run, deleted when it ends; the provider's password never leaves this
machine. A reopened inventory asks for them again. That is the honest cost of
not writing them to a client's disk.

What the install prints goes to the console and to the page from memory, never
to a file: it carries the passwords the server shows once. The server prints
them as JSON between two marker lines; the page shows each one in the server
access section, and the console window does not.

## The console, for operators and the bench

```sh
catena-installer install --inventory clientco [-i FILE] [--release vX.Y.Z | --image REF]
                         [--address A] [--tags T] [--reinstalled] [--no-confirm]
                         [--keyset-json] [--ca-file F] [--insecure-http]
```

`-i FILE` installs a new server from one input file: the `.env` keys of the
registry, `host_name` (the server's name), `host_initial_password` (the
provider's password, used once) and an optional `admin_password` pin. Without
it the inventory's `.env` must exist (`init`, then fill it in). On a terminal
the console asks for the provider's password when no key opens the server,
and whether a server presenting a new host key was reinstalled;
`--no-confirm` asks nothing and stops instead. `--image` installs from any
catena-admin image reference, and `--ca-file` / `--insecure-http` reach a
private registry: the test bench serves the image it built that way.
`uninstall` takes the same three, and otherwise runs the uninstall of the
release the server records.

Exit statuses: 0 installed; 1 the install failed; 3 it finished and a check
failed; 4 the server refused the second leg's session.
