Installing by hand¶
The project commands, such as alai add and alai sync, record what's
installed in alai.toml and alai.lock. When you want to install,
uninstall or list collections without recording them, use the
alai collection commands, which don't need an alai.lock.
Compared with alai sync¶
add, remove, lock, sync |
collection install, collection uninstall |
|
|---|---|---|
| Collection names from | alai.lock, resolved from alai.toml |
The command line |
| Recorded for the next person | Yes, in alai.toml and alai.lock |
No |
| Removes what wasn't asked for | Yes, as sync makes the directory match the lock |
Never, as only what's named is uninstalled |
| Versions already installed | Replaced if the lock says otherwise | Kept while they fit what's asked for |
| Needs a project | Yes, with an alai.toml |
An alai.toml, even an empty one, or --collections-dir |
Use the project commands for anything the project needs, so it's recorded and the same for everyone. Installing by hand suits trying a collection before deciding to add it. Installing by hand also suits a directory that isn't a project, such as a shared collections path or one that other tools also install to.
alai sync undoes them
In a project with an alai.lock, alai sync makes the collections
directory match the lock again, so it removes what was installed by hand
and puts back what was uninstalled. To keep a collection,
add it
instead.
Installing¶
alai collection install resolves what's
asked for and what that needs, keeps installed versions that still fit those
requirements, and removes nothing else:
Installing into a project's collections directory
-U upgrades everything it resolves to the newest versions that fit, and
-P NAME upgrades only NAME. --reinstall reinstalls everything it
resolves, including dependencies, whereas --reinstall-collection NAME
reinstalls only NAME. Requirements are in the same
format as in alai.toml, such as
'cisco.ios>=11'. See
Collection sources for the sources you can install
from and how to give them.
When there's an alai.toml, alai reads it for the collections_dir to
install into and any other settings that affect installing. Its [project] collections and alai.lock are neither used
nor changed.
Uninstalling¶
alai collection uninstall removes the
collections named, and only those collections. Their dependencies stay
installed. A collection that isn't installed is skipped with a warning.
Uninstalling from a project's collections directory
Listing¶
alai collection list lists every
collection in the collections directory, by name, with its version. A
collection installed from a directory, a tarball or a git repository also
shows where it came from.
In a project with an alai.lock, a marker shows whether each installed
collection matches its entry in the lock:
| Marker | Means | The row says |
|---|---|---|
✓ |
Installed as alai.lock has it |
Nothing more |
? |
alai.lock doesn't list it, such as one installed by hand |
not in alai.lock |
≠ |
Installed, but not as alai.lock has it |
What the lock has instead, such as another version, source or commit of the same repository, or that its source has changed since it was copied |
✗ |
Locked, but not installed | The locked version |
Listing a project's collections against its lock
alai sync makes the directory match the lock, which changes every row not
marked ✓. Without an alai.lock, there are no markers, only the collections
present.
For scripts¶
--output-format json gives the same as JSON, with each collection's path
and source in full and details of its lock status. The following is the
JSON output for the project above with corp.dev added as an editable
directory, trimmed to one collection of each status:
{
"v": 1,
"collections_dir": "/home/me/project/collections",
"lock": "/home/me/project/alai.lock",
"collections": [
{
"name": "ansible.posix",
"version": "2.1.0",
"path": "/home/me/project/collections/ansible_collections/ansible/posix",
"source": null,
"editable": false,
"lock": {
"status": "different",
"version": "2.2.2",
"source": {
"index": "https://index.alai.sh/"
}
}
},
{
"name": "ansible.utils",
"version": null,
"path": null,
"source": null,
"editable": false,
"lock": {
"status": "missing",
"version": "6.1.1",
"source": {
"index": "https://index.alai.sh/"
}
}
},
{
"name": "community.docker",
"version": "4.8.1",
"path": "/home/me/project/collections/ansible_collections/community/docker",
"source": null,
"editable": false,
"lock": {
"status": "unlocked",
"version": null,
"source": null
}
},
{
"name": "corp.dev",
"version": "0.3.0",
"path": "/home/me/project/collections/ansible_collections/corp/dev",
"source": {
"directory": "/home/me/corp.dev"
},
"editable": true,
"lock": {
"status": "locked",
"version": "0.3.0",
"source": {
"editable": "../corp.dev"
}
}
}
],
"namespace_links": []
}
| Field | |
|---|---|
v |
The format's version, which changes if a field is removed or changes meaning |
collections_dir |
The absolute path of the collections directory read, which holds the collections in ansible_collections/ |
lock |
The path of the alai.lock compared with, or null without one |
collections |
Every collection installed, and every one locked but not installed that a plain alai sync would install, sorted by name |
namespace_links |
Each namespace that's a link to somewhere else: its namespace, the link's path, and its target as the link gives it |
Each collection has:
| Field | |
|---|---|
name |
Its full name, namespace.name |
version |
Its version, or null if it isn't installed or its version can't be read |
path |
Its directory, absolute, or null if it isn't installed |
source |
Where it was installed from, or null for an index's or one alai can't read. A directory or tarball on disk has its absolute directory or path, and a tarball's URL has url. A git repository has git and commit, plus subdirectory if set. An editable link has its target's directory |
editable |
Whether it's a link to a directory, so edits there are seen |
lock |
How it compares with alai.lock, or null without one. It has the status, and the version and source the lock has for it, which are null when the lock doesn't list it |
lock.status is one of:
| Status | Marker | |
|---|---|---|
locked |
✓ |
Installed as alai.lock has it |
unlocked |
? |
alai.lock doesn't list it |
different |
≠ |
Installed, but at another version, from another source, or changed at its source since it was copied |
missing |
✗ |
Locked, but not installed |
Where they install¶
The alai collection ... commands work on the
collections directory of the
project alai finds from the current directory. See
Finding the project root for more
information.
In the following example, alai.toml is in the parent directory, so running
alai collection install ... from playbooks/ installs the collections in
the directory containing the alai.toml.
Installing from a directory inside the project
With no project, use --collections-dir to say which collections directory
to use.
Collections whose version can't be read¶
An installed collection's version is read from its MANIFEST.json. When
that file is missing, alai collection install treats the collection as not
installed, so it replaces the existing content even without --reinstall or
--reinstall-collection NAME.
To keep such a collection, --keep-unversioned leaves it as it is and
counts it as whatever version is asked for, as ansible-galaxy does without
--force.