Files
Ansible/deploy/README.md
T
2026-09-22 19:23:17 +02:00

206 lines
10 KiB
Markdown

# AIM core ZIP deployment - 3.3.0rc8
This standard-library operational helper installs a complete source release and
its two source-bound command launchers. No Git, patch files, release manifest,
package installation, add-on inspection or account/group migration is used.
Python 3.11+ on Linux is required. Development validators are not distributed.
## Verify and preview
Obtain the ZIP and its SHA-256 sidecar through a trusted channel. The sidecar is an
integrity check, not a publisher signature. Stage outside the installation tree:
```bash
cd /var/tmp
sha256sum -c AIM-Ansible-3.3.0rc8.zip.sha256
unzip AIM-Ansible-3.3.0rc8.zip
cd aim-core-3.3.0rc8
sudo python3 deploy/deploy.py update --dry-run
```
The target defaults to `/etc/ansible`. `update` requires existing core source;
`install` is for a fresh tree. Preview is the default without `--apply`.
Do not extract over the live installation. Source and target must not overlap;
symlink paths and unexpected source files are rejected.
3.3.0rc8 checks the existing **AIM** Python interpreter before making changes. It can
infer it only from an unambiguous installed `aim` Python shebang. It does not assume
that `sudo python3`, the Ansible interpreter or an add-on environment contains AIM's
dependencies. It preserves a virtual environment's Python path without resolving
its symlink to the system Python.
When discovery is unavailable (for example sudo has a different PATH), provide the
already identified AIM interpreter explicitly. In the operator test session,
`AIM_PYTHON` is the interpreter that successfully ran `scripts/aimctl.py`:
```bash
test -x "$AIM_PYTHON" || { echo 'Set AIM_PYTHON to the existing AIM interpreter first.'; exit 1; }
sudo python3 deploy/deploy.py update --aim-python "$AIM_PYTHON" --dry-run
```
Shell wrappers and `#!/usr/bin/env ...` shebangs are not guessed. The interpreter
must be an absolute executable Python 3.11+ path with no spaces (up to 120 characters),
and must already contain the dependencies from `scripts/pyproject.toml`.
## Command directory and multiple installations
The preview prints the chosen interpreter, command directory, source operations
and `@launchers/aim` / `@launchers/aimctl` operations. `@launchers` is a journal
identifier, not a directory shipped in the source archive.
By default the command directory is the existing `aim` command's parent directory,
or `/usr/local/bin` when no command exists and an interpreter was supplied. Override
with `--bin-dir /absolute/command/directory`. A nondefault `--target` **requires** its
own explicit `--bin-dir` so development deployment cannot silently replace production
commands. Use the same chosen interpreter/directory on preview and apply.
Only recognized AIM Python entry scripts or AIM-managed launchers for this target
may be replaced. Unrelated programs, unsafe symlink command destinations and launchers for
another installation are refused. There is no automatic force-overwrite escape hatch.
Choose a reviewed unused command directory when the existing layout is nonstandard.
Ensure the selected directory is on the intended operator's PATH; aliases and another
installation earlier on PATH remain the operator's responsibility.
## Apply while quiesced
Stop new jobs and exit active AIM/Ansible sessions. `--quiesced` acknowledges that
source writers/runners have been stopped; it does not discover, kill or pause jobs.
```bash
sudo python3 deploy/deploy.py update --apply --quiesced
# Include the same --aim-python and --bin-dir options used in the preview, if any.
hash -r
command -v aim
command -v aimctl
aim --version
aimctl --version
aimctl capabilities
```
The helper verifies the installed `aim --version` and `aimctl capabilities` against
the source release before reporting success. It uses an explicit installed config
path for its capability check. It does not invoke Ansible or contact managed hosts.
Both launchers import the deployed `scripts/src/aim` source with the selected AIM
Python. Old launchers and core source are included in protected recovery data.
A stable deployment lock prevents another cooperating deployment. Each source file
is replaced atomically, preserving existing UID/GID/mode/extended attributes.
New source files use 0644; new launchers use 0755, and recognized existing launchers
retain their metadata with executable bits enabled. Directories use normal caller
ownership/inheritance. This is not a recursive ownership-policy migration.
Recovery defaults to `/var/backups/aim-core`; the helper prints the exact private
0700 recovery directory. `--backup-dir /private/path` selects another root outside
source and installation. Keep sufficient space and apply your retention policy.
Obsolete files inside `scripts/src/aim/` and the explicitly retired Core documents below are pruned. Unknown customer files in
other locations are retained. Add-on code must use its own namespace, not the core
Python namespace.
**Preserved when present:** operator `scripts/aim.yml`, customer `.aim.yml`, inventories,
Vaults, SSH keys, add-ons and their state/configuration, environments, external assets,
unknown playbooks/roles and staged agent files. No dependencies, services, accounts,
LDAP/local group memberships, remote credentials or add-on version gates are modified.
Missing new settings are not automatically inserted into an operator's existing YAML.
## Python package and runtime scope
These launchers are source-bound entry points, not a pip reinstall. The helper does
not change installed wheel/distribution metadata or upgrade packages. Machine clients
calling the installed `aimctl` reach the deployed source. In-process Python clients
must also resolve `aim` to this source (for example an existing editable installation
or an explicitly configured source import path), not an old separately installed
wheel. Verify `aim.__file__` and `aim.__version__` in that client's own environment.
No add-on's Python environment is changed by core deployment.
For a fresh installation, provision an AIM Python 3.11+ environment and its declared
`ruamel.yaml`/`rich` dependencies first, then pass that interpreter to `install`.
Provide the separate canonical Ansible Core **2.19.11** runtime and approved collections
from `requirements-controller.txt` / `requirements.yml` explicitly. The helper does
not install from the network or mutate a system-managed Ansible installation.
For a nondefault controller root, maintain that installation's operator configuration
and use `aimctl --config /absolute/root/scripts/aim.yml ...` when necessary. Existing
terminal configuration discovery is unchanged; creating another launcher does not
silently redirect a terminal's global configuration.
## Opt-in API execution
Follow `scripts/docs/SANITY.md` (historical evidence is in
`scripts/docs/VALIDATION.md`). External execution remains disabled by
default and is not enabled by deployment, readiness or the launcher smoke test.
Preserve the existing YAML and merge only deliberately approved settings:
```yaml
addons:
execution_enabled: true
runtime:
ansible_playbook: /usr/bin/ansible-playbook
```
The executable path is the operator's approved native runtime, not an assumption
for every installation. Worker authorization, filesystem/key access, collections,
connection dependencies and same-UID execution still apply. Do not make private keys
group-readable to bypass an unsupported cross-user deployment.
## Recovery and interruption
Ordinary application/launcher-check failures attempt to restore touched source and
launchers. The update is not a whole-tree atomic transaction: power loss or SIGKILL
can leave partial source. Keep jobs stopped until recovery/version checks complete.
Recovery journals contain intent, hashes and original metadata; they are local
recovery records, not a distributed release manifest or inventory backup.
Use this 3.3.0rc8 deployer and the printed recovery directory; include the same target
for a nondefault installation. Launcher paths are recorded in the journal.
```bash
sudo python3 deploy/deploy.py rollback --from-backup /var/backups/aim-core/RECOVERY-DIRECTORY --dry-run
sudo python3 deploy/deploy.py rollback --from-backup /var/backups/aim-core/RECOVERY-DIRECTORY --apply --quiesced
hash -r
aim --version
```
Rollback validates installed/recovery hashes and refuses to overwrite subsequently
modified source or launchers. Existing aim.yml is never rolled back or removed,
even after a fresh install. Empty directories may remain. A newly created aimctl
launcher is removed when restoring a previous release that had no such launcher.
No remote Ansible action, dependency installation, account/group change or add-on
state is reversed. Keep independent backups of runtime/customer data.
## Required executor staging (independently provisioned units)
Read `scripts/docs/EXECUTOR_STAGING.md` in the installed tree. New add-on executor
installers should provision owner-only staging and a narrow directory write
exception by default, then run `aimctl staging-check` inside the actual unit at
startup. Ordinary `sudo -u` success does not reproduce mount/syscall restrictions.
The source deployer does not inspect/edit/restart services. It preserves the
working exception already applied by the operator. The automatic Core preflight
is on by default, but cannot make a read-only mount writable. Do not remove the
exception, broaden home write access or recursively chown anything during this
update. The new startup command is available after the normal launcher refresh.
## Documentation consolidation in 3.3.0rc8
Current docs have stable topic names with one validation record and one acceptance
checklist. Upgrade removes only these explicitly retired Core filenames (with
protected rollback copies), including locally modified versions of those exact files:
- scripts/docs/RC19_HANDOFF.md
- scripts/docs/SANITY_3.2.0.md
- scripts/docs/SANITY_3.2.1rc2.md
- scripts/docs/VERIFICATION.md
- scripts/docs/LOCAL_VALIDATION.md
- scripts/docs/CONTROLLER_ACCEPTANCE.md
Review REMOVE entries before applying. Move any operator notes out of these retired
Core-owned names before deployment. Unknown Markdown files and other operator
documents are preserved. Rollback restores retired document bytes/metadata through
the existing recovery journal. No recursive docs purge or runtime deletion occurs.
The new playbooks/filter_plugins/*.py files and playbooks/schemas/*.yml files are
Core-owned reporting source. They are deployed with the playbooks; no add-on Python
environment or collection is modified.