206 lines
10 KiB
Markdown
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.
|