lot's of standardizing with the refacto

This commit is contained in:
Matthew Stobbs
2025-02-11 22:14:04 -07:00
parent 6d52cc6a4d
commit 9250145116
10 changed files with 384 additions and 209 deletions

View File

@@ -50,3 +50,60 @@ of precedence: `syspkgs`, `flatpkgs`, `snappkgs`, `appimages`.
In that order, `syspkgs` and `caskpkgs` have equal weight, as it applies
to macOS.
## Formatting rules
- Use indentation explicitness. Lists should be indented:
```yaml
# Good
my_good_list:
- my_list_item
# Bad
my_bad_list:
- my_list_item
```
- Variables should be in snake case, separating words
- Short names are fine if they are explicit. ie `vers` can be used instead of `version`
- If more then one variable starts with the same words, put it into a dict if it makes sense:
```yaml
# variables that should be a dict
cargo_locked: true
cargo_pkg: alacritty
# better to just be
cargo:
locked: true
pkg: alacritty
```
- Tasks **MUST** follow the convention in this example:
```yaml
- name: Capitalize first letter of name
when:
- each condition has it's own line
- (brackets around conditions with) or
(to show they are separate)
become: "{{ not use_local }}" # must be able to be used with use_local
become_user: # this should not be needed, but always follows become if it is
loop: "{{ my_loopable_list }}"
loop_control: # **MUST** always use at least loop_var for any loop
loop_var: my_item
ansible.builtin.set_fact: # always use the full module name
...
```
- `name`: Every task needs a name, and the first letter must be capitalized
- `when`: If a when clause exists, it follows the name
- Each clause must have it's own line, including and `or` clause, as seen above
- `become`: must follow the when clause if it exists, name otherwise
- Any other `become_` settings follow `become` in alphabetical order
- `loop`: must be defined just before the module invocation
- Every loop needs to rename the `loop_var` to something that makes sense
- `until` is consider the same as `loop` for the purposes of placement
- The last item must be the module invocation, using the fully qualified name
- For example, don't use `set_fact:`, use `ansible.builtin.set_fact:`

199
README.md
View File

@@ -1,5 +1,4 @@
Role Name
=========
# ansible_role_package
Manage package installation for a number of packages
that sometimes need special handling. Some are built from
@@ -11,60 +10,162 @@ special instructions to properly install and use. I decided to
simplify the management of those packages by creating a role with
special handling.
Included packages:
Order of precedence for package installation:
- Desktop applications: alacritty, firefox, ghostty, kitty, neovide
- Shell applications: btop, carapace, nushell, fzf, jq, neovim, pipx, ripgrep,
stow, tmux, zoxide
- Infrastructure applications: ansible, consul, nomad, packer, terraform
- Development tools: cmake, git, go, nodejs, hugo, rust, tidy
- Misc: editorconfig, hashicorp package repository, nerdfonts, pandoc,
pytho3-pip, terra repository for fedora, zfs
- Cargo packages: dotenv-linter, eza, htmx-lsp, starship
- Go packages: air, buf, checkmake, glow, lazygit, revive, templ, gopls
- NPM packages: ansible-language-server, commitlint-cli,
commitlint-config-conventional, markdownlint-cli, quobix-vacuum,
tailwindcss-languageserver
- Pipx packages: cmakelang, sqlfluff
1. System package manager (dnf, apt, homebrew, etc.)
2. Appimage (Linux only)
3. Flatpak (Linux only)
4. Snap (Linux only), takes precedence over flatpak on Ubuntu based systems
5. Language package manager (`cargo install`, `go install`, `npm install`, etc.)
6. Build and install from source
Requirements
------------
_This does not configure installed software, just installs it_
## Available Packages
- air
- alacritty
- ansible-language-server
- ansible-lint
- ansible
- bashls
- bat
- bitwarden
- blender
- broot
- btop
- buf
- bufls
- carapace
- cheat
- checkmake
- choose
- clangd
- cmake
- cmakelang
- commitlint-cli
- commitlint-config-conventional
- consul
- cssls
- curlie
- dbeaver
- dockerls
- dotenv-linter
- duf
- dust
- editorconfig
- eslint
- eza
- fd
- firefox
- flatpak
- fzf
- ghostty
- git
- glow
- go
- godot
- gopls
- gping
- heroic
- htmlls
- htmx-lsp
- httpie
- hugo
- hyperfine
- intelephense
- jinja-lsp
- jq
- jsonls
- kitty
- lazygit
- libreoffice
- lua-language-server
- markdownlint-cli
- mcfly
- neovide
- neovim
- nerdfonts
- nextcloud
- nginxls
- nodejs
- nomad
- nushell
- packer
- pandoc
- pgadmin
- pipx
- podman
- pyright
- python3-pip
- quobix-vacuum
- revive
- ripgrep
- rust
- sd
- sqlfluff
- sqlls
- starship
- stow
- tailscale
- tailwindcss-languageserver
- templ
- terra_repo
- terraform
- terraformls
- thunderbird
- tidy
- tldr
- tmux
- vault
- xh
- yamlls
- zfs
- zig
- zls
- zoxide
- zsh
## Requirements
-
## Role Variables
- `use_local`: Boolean, default `true`
- When `true`, uses the following paths:
- `$HOME/.local` as the install prefix, placing binaries in `$HOME/.local/bin`
- `$HOME/.local/appimage` for saved appimages, which are then linked to `$HOME/.local/bin`
- `$HOME/.local/archive` for extracted archives linking binaries to `$HOME/.local/bin`
- `$HOME/.cache` for caching downloads
- `$HOME/.cargo` for cargo installations, placing binaries in `$HOME/.cargo/bin`
- When `false`, uses the following system wide paths:
- `/usr/local` as the install prefix, placing binaries in `/usr/local/bin`
- `/opt/appimage` for saved appimages, which are then linked to `/usr/local/bin`
- `/opt/archive` for extracted archives, linking binaries to `/usr/local/bin`
- `/opt/cache` for caching downloads
- `/opt/cargo` for rust cargo installations, placing binaries in `/opt/cargo/bin`
- `packages`: List of strings
- List of packages to install from the `Available Packages` list
- `prefer_method`: String, default `system`
- The preferred method of installation an application when multiple options exist
- Valid options are:
- `flatpak` - Flatpak, Linux only
- `langtool` - Using language tools such as `cargo`, `go`, `npm` or `pipx`
- `snap` - Snap, Linux only
- `source` - Prefer building from source. **Not recommended**
- `system` - Default, system package manager (dnf, apt, homebrew, etc.)
## Dependencies
Role Variables
--------------
- packages:
- List of packages to install
- assume_missing_is_syspkg:
- Bool. Default `true`
- Handle non-supported packages as package manager packages
- full_upgrade:
- Bool. Default `false`
- Do a full package upgrade first if `true`
- install_state:
- String. Default `present`
- Set to `latest` to update packages
- Set to `absent` to remove packages
- *currently only supports remove package manager installed packages*
- Valid choices: `present`, `latest`, `absent`
- pkgconfig:
- specific configuration for individual packages
Dependencies
------------
## Example Playbook
Example Playbook
----------------
License
-------
## License
MIT
Author Information
------------------
## Author Information
- Matthew Stobbs
- Matthew Stobbs <matthew@stobbs.ca>

View File

@@ -1,43 +1,40 @@
---
argument_specs:
main:
short_description: install software easily
short_description: Install software using ansible
description:
- Make the installation of packages consistent on each platform.
- Installs for RedHat, Debian or Darwin based systems.
- Installs for RedHat, Debian and MacOS based systems.
author:
- Matthew Stobbs <matthew@stobbs.ca>
options:
use_local:
type: bool
default: true
required: false
description:
Install packages using the current users
`$HOME/.local` directory as the install prefix.
WHen `false`, uses the system wide `/usr/local`
as the install prefix, and stores other parts
(appimages, extracted archives, cache) in the
appropriate path starting with `/opt`.
packages:
type: "list"
elements: "str"
type: list
elements: str
required: true
description: |
The list of packages to install by name.
syspkglist:
type: "list"
elements: "str"
The list must contain only values that exist in
`Available Packages` in `README.md`
prefer_method:
type: str
required: false
description: |
Additional packages to install via the system
default package manager. Is combined with the
completed list of packages to install.
Only use this if you a package isn't available to the role.
install_state:
type: "str"
default: system
choices:
- "present"
- "latest"
- "absent"
required: false
default: present
description: |
Desired state of the packages to install.
full_upgrade:
type: "bool"
required: false
default: false
description: |
Do a full system upgrade before installing
additional packages. This does not handle
rebooting a machine that has been upgraded.
- flatpak
- langtool
- snap
- source
- system

View File

@@ -7,20 +7,20 @@ galaxy_info:
# issue_tracker_url: http://example.com/issue/tracker
license: MIT
min_ansible_version: 3.0
min_ansible_version: "3.0"
platforms:
- name: Fedora
versions:
- all
- 40+
- name: Enterprise Linux 9 (RHEL, rocky alma)
- "40"
- "41"
- name: EL
versions:
- 9.4
- 9.5
- "9"
- name: macOS
version:
- 14.2+
- ">=14.2"
galaxy_tags:
- linux
@@ -28,6 +28,6 @@ galaxy_info:
- package
- software
dependencies: []
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.
dependencies:
- ansible.builtin
- community.general

View File

@@ -1,4 +1,13 @@
# vim: set filetype=yaml.ansible :
---
version: 0.15.0
install_prefix: "{{ default_install_prefix }}"
- name: Set alacritty configuration
ansible.builtin.set_fact:
alacritty:
deps: "{{ pkgconfig.alacritty[ansible_os_family].build_deps }}"
ver: "{{ pkgconfig.alacritty.version }}"
repo: "{{ pkgconfig.alacritty.git_repo }}"
pkgs: "{{ pkgconfig.alacritty[ansible_os_family].pkgs | default(omit) }}"
bin: "{{ paths.install }}/bin/alacritty"
cargo:
locked: true
pkg: alacritty

View File

@@ -1,35 +1,56 @@
# vim: set filetype=yaml.ansible :
---
# create all the facts used throughout the role, but shouldn't be touched
# by the user
- name: Set installation facts
ansible.builtin.set_fact:
paths: "{% if use_local %}{{ localpaths }}{% else %}{{ syspaths }}{% endif %}"
appimages: [] # appimages to install
cargopkgs: [] # rust packages from cargo
cargoversioned: [] # versioned rust packages from cargo
caskpkgs: [] # homebrew casks
flatpkgs: [] # flatpaks
gopkgs: [] # go applications
npmpkgs: [] # npm commands
pipxpkgs: [] # pipx packages
srcpkgs: [] # packages built from source
syspkgs: [] # system package manager packages
tappkgs: [] # homebrew tap packages
brewtaps: [] # homebrew taps
fpremotes: # flatpak remotes
app_images: [] # app_images to install
cargo_pkgs: [] # rust packages from cargo
cask_pkgs: [] # homebrew casks
flatpaks: [] # flatpaks
go_pkgs: [] # go applications
npm_pkgs: [] # npm commands
pipx_pkgs: [] # pipx packages
src_pkgs: [] # packages built from source
sys_pkgs: [] # system package manager packages
tap_pkgs: [] # homebrew tap packages
brew_taps: [] # homebrew taps
flatpak_remotes: # flatpak remotes, includes flathub by default
- name: flathub
url: https://dl.flathub.org/repo/flathub.flatpakrepo
- name: Set facts based on use_local == true
when:
- use_local
ansible.builtin.set_fact:
paths: "{{ local_paths }}"
flatpak_method: user
- name: Set facts based on use_local == false
when:
- not use_local
ansible.builtin.set_fact:
paths: "{{ sys_paths }}"
flatpak_method: system
- name: Set macOS specific facts
when:
- ansible_distribution == 'MacOSX'
ansible.builtin.set_fact:
pipx_exec: /opt/homebrew/bin/pipx
- name: Determine OS and set facts for it
block:
- name: Set macOS facts
when: ansible_os_family == 'Darwin'
ansible.builtin.set_fact:
syspkg_become: false
sys_pkg_become: false
- name: Set Linux facts
when: ansible_system == 'Linux'
ansible.builtin.set_fact:
syspkg_become: true
sys_pkg_become: true
- name: Generate package installation lists
ansible.builtin.include_tasks:
@@ -38,10 +59,10 @@
loop_control:
loop_var: pkg
- name: Install syspkgs list
become: "{{ syspkg_become }}"
- name: Install sys_pkgs list
become: "{{ sys_pkg_become }}"
ansible.builtin.package:
name: "{{ syspkgs | unique }}"
name: "{{ sys_pkgs | unique }}"
state: present
- name: Redhat based OS
@@ -50,9 +71,9 @@
- name: Install dnf packages
become: true
when:
- syspkgs|length > 0
- sys_pkgs|length > 0
ansible.builtin.dnf:
name: "{{ syspkgs | unique }}"
name: "{{ sys_pkgs | unique }}"
state: present
- name: Debian based OS
@@ -60,11 +81,11 @@
block:
- name: Install apt packages
ansible.builtin.apt:
name: "{{ syspkgs | unique }}"
name: "{{ sys_pkgs | unique }}"
state: "{{ install_state }}"
become: true
when:
- syspkgs|length > 0
- sys_pkgs|length > 0
- name: Darwin/macOS based OS
when: ansible_os_family == 'Darwin'
@@ -77,62 +98,62 @@
- name: Tap homebrew taps
community.general.homebrew_tap:
name: "{{ brewtaps | unique }}"
name: "{{ brew_taps | unique }}"
state: present
when: brewtaps|length > 0
when: brew_taps|length > 0
- name: Install homebrew packages
community.general.homebrew:
name: "{{ syspkgs | unique }}"
name: "{{ sys_pkgs | unique }}"
state: "{{ install_state }}"
when: syspkgs|length > 0
when: sys_pkgs|length > 0
- name: Install homebrew casks
community.general.homebrew_cask:
name: "{{ caskpkgs | unique }}"
name: "{{ cask_pkgs | unique }}"
state: "{{ install_state }}"
when: caskpkgs|length > 0
when: cask_pkgs|length > 0
- name: Workaround to install homebrew taps
ansible.builtin.command:
cmd: "brew install {{ tappkg }}"
loop: "{{ tappkgs | unique }}"
cmd: "brew install {{ tap_pkg }}"
loop: "{{ tap_pkgs | unique }}"
loop_control:
loop_var: tappkg
loop_var: tap_pkg
# TODO: fix the need to have this workaround
- name: Install flatpaks on Linux Systems
when:
- ansible_system == 'Linux'
- flatpkgs|length > 0
- flatpaks|length > 0
block:
- name: Add flatpak repos
become: true
loop: "{{ fpremotes | unique }}"
when:
- flatpak_remotes|length > 0
- flatpaks|length > 0
become: "{{ not use_local }}"
loop: "{{ flatpak_remotes | unique }}"
loop_control:
loop_var: remote
when:
- fpremotes|length > 0
- flatpkgs|length > 0
community.general.flatpak_remote:
enabled: true
method: system
method: "{{ flatpak_method }}"
state: present
flatpakrepo_url: "{{ remote.url }}"
name: "{{ remote.name }}"
- name: Install flatpaks
become: true
loop: "{{ flatpkgs | unique }}"
loop: "{{ flatpaks | unique }}"
loop_control:
loop_var: flatpkg
loop_var: flatpak
when:
- flatpkgs|length > 0
- flatpaks|length > 0
community.general.flatpak:
state: latest
method: system
name: "{{ flatpkg.name }}"
remote: "{{ flatpkg.remote | default('flathub') }}"
method: "{{ flatpak_method }}"
name: "{{ flatpak.name }}"
remote: "{{ flatpak.remote | default('flathub') }}"
- name: Ensure /usr/local/bin exists
ansible.builtin.file:
@@ -142,64 +163,56 @@
mode: '0755'
become: true
- name: Install srcpkgs
- name: Install src_pkgs
ansible.builtin.include_tasks:
file: "src/{{ srcpkg }}.yml"
loop: "{{ srcpkgs | unique }}"
file: "src/{{ src_pkg }}.yml"
loop: "{{ src_pkgs | unique }}"
loop_control:
loop_var: srcpkg
when: srcpkgs|length > 0
loop_var: src_pkg
when: src_pkgs|length > 0
- name: Install cargo packages at specific version
community.general.cargo:
name: "{{ cargopkg.name }}"
version: "{{ cargopkg.version }}"
path: "{{ cargopkg.path | default(default_install_prefix) }}"
locked: "{{ cargopkg.locked | default(false) }}"
become: true
when: cargoversioned|length > 0
loop: "{{ cargoversioned | unique }}"
when:
- cargo_pkgs|length > 0
become: "{{ not use_local }}"
loop: "{{ cargo_pkgs | unique }}"
loop_control:
loop_var: cargopkg
- name: Install cargo packages at latest version
loop_var: cargo_pkg
community.general.cargo:
name: "{{ cargopkg }}"
state: latest
locked: "{{ cargopkg.locked | default(false) }}"
when: cargopkgs|length > 0
loop: "{{ cargopkgs | unique }}"
loop_control:
loop_var: cargopkg
name: "{{ cargo_pkg.cargo.pkg }}"
version: "{{ cargo_pkg.ver }}"
path: "{{ paths.cargo }}"
locked: "{{ cargo_pkg.cargo.locked }}"
- name: Install local go packages
loop: "{{ gopkgs | unique }}"
when:
- go_pkgs|length > 0
loop: "{{ go_pkgs | unique }}"
loop_control:
loop_var: gopkg
when: gopkgs|length > 0
loop_var: go_pkg
environment:
GOROOT: /usr/local/go
PATH: /usr/local/go/bin:$PATH
GOROOT: "{{ paths.install }}/go"
PATH: "{{ paths.install }}/go/bin:$PATH"
ansible.builtin.command:
cmd: "go install {{ gopkg }}"
#TODO: figure out how to check if the gopkg is already installed
cmd: "go install {{ go_pkg }}"
# TODO: figure out how to check if the go_pkg is already installed
- name: Install local npm packages
loop: "{{ npmpkgs | unique }}"
loop: "{{ npm_pkgs | unique }}"
loop_control:
loop_var: npmpkg
when: npmpkgs|length > 0
loop_var: npm_pkg
when: npm_pkgs|length > 0
community.general.npm:
global: true
name: "{{ npmpkg }}"
name: "{{ npm_pkg }}"
state: latest
- name: Install python pipx packages for user
loop: "{{ pipxpkgs | unique }}"
loop: "{{ pipx_pkgs | unique }}"
loop_control:
loop_var: pipxpkg
when: pipxpkgs|length > 0
loop_var: pipx_pkg
when: pipx_pkgs|length > 0
community.general.pipx:
executable: "{% if ansible_os_family == 'Darwin' %}/opt/homebrew/bin/pipx{% else %}/usr/bin/pipx{% endif %}"
name: "{{ pipxpkg }}"
executable: "{{ pipx_exec }}"
name: "{{ pipx_pkg }}"
state: latest

View File

@@ -1,25 +1,19 @@
# vim: set filetype=yaml.ansible :
---
- ansible.builtin.include_vars:
file: alacritty.yml
name: _alacritty
- ansible.builtin.set_fact:
pkgconfig_alacritty: "{{ _alacritty | ansible.builtin.combine(pkgconfig.alacritty) }}"
- name: linux based installation
- name: Linux based installation
when: ansible_system == 'Linux'
block:
- name: install rust and cargo
- name: Install rust and cargo
ansible.builtin.include_tasks:
file: "pkgs/rust.yml"
when: pkgconfig_rust is undefined
- name: append to pkgs
set_fact:
syspkgs: "{{ syspkgs + pkgconfig_alacritty.deps[ansible_distribution] }}"
srcpkgs: "{{ srcpkgs + [ 'alacritty' ] }}"
- name: append alacritty to caskpkgs
- name: Append to pkgs
ansible.builtin.set_fact:
caskpkgs: "{{ caskpkgs + [ 'alacritty' ] }}"
syspkgs: "{{ syspkgs + alacritty.deps }}"
srcpkgs: "{{ cargopkgs + [alacritty] }}"
- name: Append alacritty to caskpkgs
ansible.builtin.set_fact:
caskpkgs: "{{ caskpkgs + alacritty.pkgs }}"
when: ansible_system == 'Darwin'

View File

@@ -1,15 +1,7 @@
# vim: set filetype=yaml.ansible :
---
- name: Build and install alacritty
become: true
become: "{{ not use_local }}"
ansible.builtin.command:
creates: "{{ pkgconfig_alacritty.install_prefix }}/bin/alacritty"
cmd:
- cargo
- install
- --root
- "{{ pkgconfig_alacritty.install_prefix }}"
- --git
- "{{ pkgconfig_alacritty.git_repo }}"
- --tag
- "v{{ pkgconfig_alacritty.version }}"
creates: "{{ alacritty.bin }}"
cmd: "cargo install --root {{ paths.cargo }} alacritty@{{ alacritty.ver }}"

View File

@@ -1,24 +1,31 @@
# vim: set filetype=yaml.ansible :
# variables used in ansible_role_package
---
localpaths: # all localpaths are prefixed with the users $HOME directory
instrall: .local
appimage: .local/appimage
archive: .local/archive
cache: .cache
use_local: true
prefer_method: system
packages: [] # list of packages to install
syspaths: # if installing at a system level (default)
install: /usr/local # executables get linked to {{ default_install_prefix }}/bin
local_paths: # all localpaths are prefixed with the users $HOME directory
appimage: .local/appimage # keep appimages here
archive: .local/archive # extract archives here
cache: .cache # cache downloads here
cargo: .cargo # cargo install location
install: .local # installation prefix. Binaries are placed in `{{ install }}/bin`
sys_paths: # if installing at a system level (default)
appimage: /opt/appimage # appimages are installed to {{ apimage_install_prefix }}/<name>/
archive: /opt/archive # pre-compiled archives are extracted to {{ archive_install_prefix }}/
cache: /opt/archive/.cache # download archives here
cargo: /opt/cargo # cargo install location
install: /usr/local # executables get linked to {{ default_install_prefix }}/bin
packages: [] # list of packages to install
pkgconfig:
alacritty:
build_deps:
version: 0.15.0
RedHat:
pkgs: []
build_deps:
- cmake
- freetype-devel
- fontconfig-devel
@@ -26,6 +33,8 @@ pkgconfig:
- libxkbcommon-devel
- g++
Debian:
pkgs: []
build_deps:
- cmake
- pkg-config
- libfreetype6-dev
@@ -33,6 +42,9 @@ pkgconfig:
- libxcb-xfixes0-dev
- libxkbcommon-dev
- python3
Darwin:
pkgs:
- alacritty
git_repo: https://github.com/alacritty/alacritty.git
bitwarden:
flatpak: