Metadata-Version: 2.5
Name: pyplines-installer
Version: 2026.10.4rc1
Summary: Install and diagnose Pyplines services and CLI tools from YAML
Requires-Python: >=3.12
Requires-Dist: pyplines[client]==2026.10.4rc1
Requires-Dist: pyyaml<7,>=6
Requires-Dist: rich<15,>=14
Requires-Dist: typer<1,>=0.24
Description-Content-Type: text/markdown

# Pyplines Installer

Configure, install, diagnose, and uninstall Pyplines from a versioned YAML document. Targets
include `pyplines-server`, `pyplines-runner`, `pyplines-action`, and `pyplines-cli`.
Python 3.12+ is required. Linux and macOS are supported; Windows is deferred.

```sh
pipx install pyplines-installer
pyplines-installer init
pyplines-installer validate installation.yml
pyplines-installer run installation.yml --dry-run
pyplines-installer run installation.yml
pyplines-installer status installation.yml
pyplines-installer doctor installation.yml
```

`init` writes a reviewable configuration without installing anything. Presets are
`local`, `server`, `runner`, `action`, and `custom`; use `--output` for another filename.
It never overwrites an existing file. Review endpoint/TLS placeholders in explicit
server and runner presets. Released installers default tooling versions to their
own release; development checkouts require an explicit published tooling version.

```yaml
apiVersion: pyplines.installer/v1
name: development
state_directory: ./development-state
profile: local
versions:
  platform: 2026.10.1rc17
  tooling: 2026.10.3rc2
credentials:
  administrator_password:
    env: PYPLINES_ADMIN_PASSWORD
targets:
  server:
    component: pyplines-server
  runner:
    component: pyplines-runner
    server:
      target: server
  operator:
    component: pyplines-cli
    directory: ~/.local/bin
```

Use published versions appropriate for your deployment. Server/runner targets use
the platform version; CLI targets use the tooling version. CLI-only documents do
not need a platform version or Docker. The local preset generates development TLS,
loopback ports 8443/4222, a control network, and enrolled/approved runners in pool
`local`. Operator installation uses an isolated environment and prints exact CA
configuration/login commands. System trust is not changed.

Service targets require Linux rootful Docker Engine or macOS Docker Desktop, a
Linux amd64/arm64 daemon (Engine 26+), and Compose 2.24+. Remote/rootless daemons
and alternative macOS VM providers are not supported. Docker context/daemon identity
is recorded and checked. Host file-sharing and runner VM-socket mounts are probed.

Action CLI targets download native release assets directly over HTTPS, verify
SHA-256 and the executable's version, then install atomically. No `gh` or curl is
needed. Private releases accept `PYPLINES_GITHUB_TOKEN`, `GITHUB_TOKEN`, or an explicit
`github_token` credential reference. Tokens are not forwarded to asset hosts on
redirects. Docker, uv, and Python requirements for authoring Actions are separate.

## Automation and state

`run` supports `--dry-run`, `--yes`, and repeatable `--target NAME`. Dependencies
are included in the plan. Global `--json` precedes the command. Exit codes: 0 for
success, 1 for operation/configuration failures, 2 for incomplete readiness or CLI
argument errors. `validate` does not contact Docker or download artifacts.

Credential values are never YAML settings: use `{env: NAME}` or `{file: PATH}`.
File credentials must be private (chmod 600), nonempty, and not symlinks. Interactive
runs can prompt when required values are unavailable. Relative paths resolve against
the YAML file's directory. Duplicate YAML keys, aliases, unknown settings, missing
references, cycles, and conflicting destinations are rejected.

Preserve the private state directory and named Docker volumes. Successful targets
are retained when another fails; dependents are blocked and independent targets can
finish. Reruns reuse verified CLI targets and resume service state. Removing a target
from YAML never uninstalls it. Saved target settings/versions cannot change in place;
service upgrades and rollback are not implemented. Uninstall is an explicit operation.
Commands default to `installation.yml`; explicit paths remain supported. Interactive
setup starts with your goal and writes commented YAML. Known credentials are
collected before mutation, new passwords are confirmed, and progress identifies
each component and its current operation. `--yes` never prompts.

To explicitly reference an existing managed server/runner installation:

```sh
pyplines-installer init --from-directory ./previous-installation --name imported --output imported.yml
pyplines-installer run imported.yml --dry-run
```

Keep original directories and TLS files. Compatibility `install server|runner|action`,
`install --config`, `local`, and `status/doctor --directory` remain available but are
hidden from primary help. They retain their original state layouts and share the
service, TLS, enrollment, and tool engines. They will be removed only in a documented
future release; no removal version has been scheduled.

## Cleanup

```sh
pyplines-installer uninstall --dry-run
pyplines-installer uninstall
pyplines-installer uninstall --purge
pyplines-installer uninstall --directory ./development-state --purge --dry-run
```

Ordinary uninstall removes managed containers/networks and CLI tools while retaining
persistent volumes, generated TLS, and service state for reinstall. `--purge` also
removes database/identity volumes and generated files. Interactive purge requires
the installation name; unattended purge requires `--purge --yes`.

Cleanup uses saved ownership, not edited YAML or server health. It includes retained
targets removed from YAML and supports original single-service/local directories.
Select targets with repeatable `--target`; dependents must be selected explicitly.
Failed removal preserves receipts and provides a retry command. Unknown files,
changed executable ownership, and different Docker daemons prevent destructive
cleanup. User YAML, supplied TLS/credentials, external networks, shared caches,
operator CLI settings, and the installer package remain. External runner registrations
require separate operator revocation. No global Docker prune is performed.

## Contracts and development

The new contract is `contracts/installer/v1/installation.schema.json`. The older
`contracts/installation/v1/installation.schema.json` describes individual Compose
installations. Both are authoritative, packaged, and included in release contract
bundles. Packaged YAML examples live in `src/pyplines_installer/data/examples/`.
Private state files are not public configuration contracts.

```sh
uv run --project pyplines-installer pyplines-installer --help
uv run --project pyplines-installer pyplines-installer init --preset local --tooling-version 2026.10.3rc2 --output development.yml
uv run --project pyplines-installer python -m unittest discover -s pyplines-installer/tests
uv run --project pyplines-installer python scripts/contracts.py check
uv build pyplines-installer
task installer:integration
```

Integration runs natively on Linux/macOS, building disposable candidate images and
operator/SDK wheels. It checks service bootstrap, TLS, enrollment/approval, real
Action execution, the YAML workflow, isolated operator login, external runner setup,
state-preserving retries, uninstall/reinstall, purge/fresh installation, and
preservation of unrelated resources. Ports 29443, 24222, and 25129 must be free. Unique test
containers/volumes/networks/directories are cleaned in `finally`; reusable image
build caches remain. The fixture version is not a published-release claim.

PyPI Trusted Publisher: project `pyplines-installer`, owner `pyplines`, repository
`pyplines`, workflow `publish-tooling.yml`, environment `pypi`.
