A workstation installation suite.
The suite expects the target OS to be
- working and self-sufficient (e.g. in case of Arch the system is expected to be in post-Installation Guide state);
- connected to the Internet.
Distro/architecture support:
- ArchLinux on x86_64:
- full support (all roles);
- CentOS/AlmaLinux 8 on x86_64:
profile
;editors/vim
;shells/bash
;shell_basic
;shell_extras
;admin_network
;admin_system
;admin_tracing
.
The group_vars
directory contains basic configuration for
different device archetypes; currently only desktops are supported.
The inventories
directory contains host-specific inventories.
Run
ansible-playbook -i inventories/$DEVICE install.yml
to install system-wide stuff, configure all users and their environments.
To run unprivileged installation, use the user
tag:
ansible-playbook -i inventories/$DEVICE -t user install.yml
This mode does not affect system-wide configs and does not install packages.
NOTE: due to Ansible's support policy, there may be a need in older
Ansible version than the control host has. If the playbook fails due to
unknown reasons which seem to be Python-related, use ./ansible
instead of
ansible
and ./ansible-playbook
instead of ansible-playbook
: these
wrappers will install a specific legacy Ansible version (currently — the
latest release of 2.x branch) into local virtualenv and run this specific
version instead of system-wide one. Currently this may be required if the
target host is based on RHEL 8 and the control host has Ansible 3.x.
There are few global options.
If multiple users are configured for some host, there is a possibility to configure only
one of these users by passing a user
option and specifying the name of the desired user.
Combined with -t user
, this would allow to configure unprivileged users without any
privileges escalation (i. e. when the connection user has no right to use sudo
, etc.):
ansible-playbook -i inventories/$DEVICE -t user -e user=johndoe install.yml
Given that Ansible does not clean things whose state is not described in tasks explicitly, there may be need in additional cleanup of leftover files (e. g. deprecated drop-ins in Ansible-managed drop-ins directories).
Also, there are some applications which do not support drop-ins and manage large monolithic highly-mutalbe configurations which include some machine-specific or sensitive parameters, so these configurations may not be committed as-is. Such configurations are installed only once and then are intentionally left application-managed. There may be a need to reset such configurations to their basic state.
Mandatory clean_configs
parameter controls how such situations are handled:
no
— do not perform any extra cleanup;safe
(default) — clean Ansible-managed drop-ins directories. This is safe, because content of these directories is fully recreated during installation;all
— in addition to what is cleaned forsafe
mode, application-managed configurations are cleaned and re-installed from scratch too.
To simplify the playbook structure, all roles follow the same conventional parameters schema (which, well, somewhat violates Ansible conventions):
system:
laptop: [true | false]
hidpi: [true | false]
gui:
dm: $DM_NAME
users:
$USER_NAME: # user_config
profile_dropins_dir: $DIR
...
<basic user parameters>
shells:
$SHELL_NAME: # shell_config
config_dropins_dir: $DIR
...
<shell-specific params>
editors:
$EDITOR_NAME: # editor_config
default: [true | false]
config_dropins_dir: $DIR
plugins_dir: $DIR
...
<editor-specific params>
toolchains:
$TOOLCHAIN_NAME: # toolchain_config
<toolchain-specific params>
apps:
$APP_NAME: # app_config
<app-specific params>
gui:
de: $DE_NAME # de_config
<de-specific params>
This allows us to avoid passing lots of parameters downstream explicitly when importing the roles.
Each role has access to system-wide settings, provided in top-level system
dictionary, which describe the system itself (hardware, etc.). In addition
to this, each role providing some user-specific configuration (DE, shell,
editor or toolchain) receives a user_config
for current user.
Finally, as a shorthand for respective user_config
part,
- each shell role receives the associated
shell_config
; - each editor role receives the associated
editor_config
; - each toolchain receives the associated
toolchain_config
; - desktop environment receives the associated
de_config
.
These roles still have access to whole user_config
, but should use it directly
only when there is a need to access parts of user configuration outside of their
own scope: say, a toolchain installation role wanting to install some shell
configuration drop-ins (e. g. .bashrc
drop-ins) or editor plugins and/or
configurations (e. g. Vim plugins) could check whether the specific shell or editor
is available in the scope of current user and where these plugins/configurations
should be placed (by inspecting user_config[$SHELL_NAME]
and
user_config[$SHELL_NAME]["dropins_dir"]
values).
Each user-specific role may have its own, unique (but public and readable by
other roles) parameters — in this case, they should be placed under
respecive shell_config
, editor_config
or toolchain_config
. Only if this
is not applicable, the default Ansible convention must be followed and
role-specific parameter names must be prefixed with role name: this is
the case, for example, for role-private parameters like Vim plugins metadata.
See The Troubleshooting Guide.
- Custom Openbox-based environment with complete and highly custom keymap.
The recommended task attribute order is the following:
name
when
tags
become
become_user
loop
loop_control
vars
register
notify
changed_when
failed_when
args
environment
task / block