Compare commits

...

2 Commits

Author SHA1 Message Date
drew 6eaf83f808 Merge pull request 'Add CLI standardization' (#1) from dev/fish into main
Reviewed-on: #1
2026-05-22 19:43:17 +00:00
drew 11c13b788c Add CLI standardization 2026-05-18 16:28:09 -04:00
12 changed files with 596 additions and 17 deletions

View File

@ -52,4 +52,10 @@
- base_os - base_os
- firewall_base - firewall_base
- container_runtime - container_runtime
- matrix_synapse - matrix_synapse
- name: Configure RHEL machines
hosts: rhel
become: true
roles:
- cli_productivity

View File

@ -14,6 +14,7 @@ Volume={{ adguard_dir }}/conf:/opt/adguardhome/conf
PublishPort=53:53/tcp PublishPort=53:53/tcp
PublishPort=53:53/udp PublishPort=53:53/udp
PublishPort=3000:3000/tcp
[Service] [Service]
Restart=always Restart=always

View File

@ -1,7 +1,7 @@
# Adguard # Adguard
{{ adguard_domain }} { {{ adguard_domain }} {
tls internal tls internal
reverse_proxy {{ adguard_upstream }} reverse_proxy {{ adguad_upstream }}
} }
# QBittorrent # QBittorrent

View File

@ -0,0 +1,115 @@
---
# cli_productivity/defaults/main.yml
cli_user: "{{ container_user }}"
cli_group: "{{ cli_user }}"
cli_install_epel: true
cli_use_epel: "{{ cli_install_epel | bool and ansible_os_family == 'RedHat' and ansible_distribution != 'Fedora' }}"
cli_set_fish_as_default_shell: true
cli_enable_starship: true
cli_enable_fish_config: true
cli_enable_tmux_config: true
cli_enable_ssh_config: false
cli_enable_git_config: true
cli_editor: nano
cli_visual: nano
cli_config_home: "/home/{{ cli_user }}"
cli_fish_config_dir: "{{ cli_config_home }}/.config/fish"
cli_starship_config_dir: "{{ cli_config_home }}/.config"
cli_ssh_config_dir: "{{ cli_config_home }}/.ssh"
cli_base_packages:
- fish
- git
- curl
- wget
- unzip
- tar
- rsync
- tree
- tmux
- vim-enhanced
- nano
- jq
- bind-utils
- traceroute
- tcpdump
- lsof
- iotop
- htop
- ncdu
- mtr
- nmap-ncat
- python3
- python3-pip
cli_extra_packages:
- ripgrep
- fd-find
- bat
- fzf
- btop
cli_optional_packages:
- zoxide
- duf
- httpie
- yq
- direnv
- just
- git-delta
- lazygit
- eza
- procs
- dust
- bottom
- sd
- xh
- age
- sops
- shellcheck
- shfmt
cli_starship_install_method: "script"
cli_starship_bin_path: "/usr/local/bin/starship"
cli_git_user_name: ""
cli_git_user_email: ""
cli_fish_abbreviations:
- name: ll
expansion: "ls -lah"
- name: la
expansion: "ls -A"
- name: gs
expansion: "git status"
- name: ga
expansion: "git add"
- name: gc
expansion: "git commit"
- name: gp
expansion: "git push"
- name: gl
expansion: "git log --oneline --graph --decorate --all"
- name: k
expansion: "kubectl"
- name: tf
expansion: "terraform"
- name: dcu
expansion: "docker compose up -d"
- name: dcd
expansion: "docker compose down"
- name: pcu
expansion: "podman compose up -d"
- name: pcd
expansion: "podman compose down"
- name: ta
expansion: "tmux attach"
- name: tls
expansion: "tmux ls"
- name: tn
expansion: "tmux new -s"

View File

@ -0,0 +1,164 @@
---
# cli_productivity/tasks/main.yml
- name: Enable EPEL repository
become: true
ansible.builtin.dnf:
name: epel-release
state: latest
update_cache: true
when: cli_use_epel | bool
- name: Refresh DNF metadata after enabling EPEL
become: true
ansible.builtin.command: dnf makecache
changed_when: false
when: cli_use_epel | bool
- name: Install base CLI productivity packages
become: true
ansible.builtin.dnf:
name: "{{ cli_base_packages }}"
state: present
- name: Install common CLI productivity packages
become: true
ansible.builtin.dnf:
name: "{{ cli_extra_packages }}"
state: present
update_cache: true
- name: Install optional CLI productivity packages when available
become: true
ansible.builtin.dnf:
name: "{{ item }}"
state: present
loop: "{{ cli_optional_packages }}"
register: cli_optional_package_install
failed_when: false
- name: Report optional CLI packages that could not be installed
ansible.builtin.debug:
msg: "Optional package was not installed: {{ item.item }} - {{ item.failures | default(item.msg | default('unknown reason')) }}"
loop: "{{ cli_optional_package_install.results | default([]) }}"
when:
- item.rc is defined
- item.rc != 0
- name: Check whether Starship is installed
ansible.builtin.stat:
path: "{{ cli_starship_bin_path }}"
register: cli_starship_binary
when: cli_enable_starship | bool
- name: Install Starship prompt
become: true
ansible.builtin.shell: |
set -o pipefail
curl -fsSL https://starship.rs/install.sh | sh -s -- --yes --bin-dir "$(dirname {{ cli_starship_bin_path }})"
args:
executable: /bin/bash
when:
- cli_enable_starship | bool
- not cli_starship_binary.stat.exists
changed_when: true
- name: Ensure fish config directory exists
become: true
ansible.builtin.file:
path: "{{ cli_fish_config_dir }}"
state: directory
owner: "{{ cli_user }}"
group: "{{ cli_group }}"
mode: "0755"
when: cli_enable_fish_config | bool
- name: Ensure Starship config directory exists
become: true
ansible.builtin.file:
path: "{{ cli_starship_config_dir }}"
state: directory
owner: "{{ cli_user }}"
group: "{{ cli_group }}"
mode: "0755"
when: cli_enable_starship | bool
- name: Deploy Starship config
become: true
ansible.builtin.template:
src: starship.toml.j2
dest: "{{ cli_starship_config_dir }}/starship.toml"
owner: "{{ cli_user }}"
group: "{{ cli_group }}"
mode: "0644"
when: cli_enable_starship | bool
- name: Deploy fish config
become: true
ansible.builtin.template:
src: config.fish.j2
dest: "{{ cli_fish_config_dir }}/config.fish"
owner: "{{ cli_user }}"
group: "{{ cli_group }}"
mode: "0644"
when: cli_enable_fish_config | bool
- name: Deploy tmux config
become: true
ansible.builtin.template:
src: tmux.conf.j2
dest: "{{ cli_config_home }}/.tmux.conf"
owner: "{{ cli_user }}"
group: "{{ cli_group }}"
mode: "0644"
when: cli_enable_tmux_config | bool
- name: Ensure SSH config directory exists
become: true
ansible.builtin.file:
path: "{{ cli_ssh_config_dir }}"
state: directory
owner: "{{ cli_user }}"
group: "{{ cli_group }}"
mode: "0700"
when: cli_enable_ssh_config | bool
#- name: Deploy SSH client config
# become: true
# ansible.builtin.template:
# src: ssh_config.j2
# dest: "{{ cli_ssh_config_dir }}/config"
# owner: "{{ cli_user }}"
# group: "{{ cli_group }}"
# mode: "0600"
# when: cli_enable_ssh_config | bool
- name: Deploy Git config
become: true
ansible.builtin.template:
src: gitconfig.j2
dest: "{{ cli_config_home }}/.gitconfig"
owner: "{{ cli_user }}"
group: "{{ cli_group }}"
mode: "0644"
when: cli_enable_git_config | bool
- name: Get fish shell path
ansible.builtin.command: command -v fish
register: cli_fish_path
changed_when: false
when: cli_set_fish_as_default_shell | bool
- name: Ensure fish is listed in /etc/shells
become: true
ansible.builtin.lineinfile:
path: /etc/shells
line: "{{ cli_fish_path.stdout }}"
state: present
when: cli_set_fish_as_default_shell | bool
- name: Set fish as default shell
become: true
ansible.builtin.user:
name: "{{ cli_user }}"
shell: "{{ cli_fish_path.stdout }}"
when: cli_set_fish_as_default_shell | bool

View File

@ -0,0 +1,92 @@
# Managed by Ansible
set -gx EDITOR {{ cli_editor | quote }}
set -gx VISUAL {{ cli_visual | quote }}
set -gx PAGER less
# Better less defaults
set -gx LESS "-R --use-color -Dd+r -Du+b"
# Local user bin paths
fish_add_path $HOME/.local/bin
fish_add_path /usr/local/bin
# Starship prompt
if type -q starship
starship init fish | source
end
# Smarter cd
if type -q zoxide
zoxide init fish | source
end
# Direnv integration
if type -q direnv
direnv hook fish | source
end
# fzf key bindings
if type -q fzf
fzf --fish | source 2>/dev/null
end
# Prefer modern tools when available
if type -q eza
alias ls "eza --icons --group-directories-first"
alias ll "eza -lah --icons --group-directories-first --git"
alias tree "eza --tree --icons"
else if type -q exa
alias ls "exa --icons --group-directories-first"
alias ll "exa -lah --icons --group-directories-first --git"
else
alias ll "ls -lah"
alias la "ls -A"
end
if type -q bat
alias cat "bat --paging=never"
end
if type -q rg
alias grep "rg"
end
if type -q fd
alias find "fd"
else if type -q fdfind
alias fd "fdfind"
end
# Common navigation
alias .. "cd .."
alias ... "cd ../.."
alias .... "cd ../../.."
# Git helpers
alias gst "git status"
alias glog "git log --oneline --graph --decorate --all"
alias gd "git diff"
alias gds "git diff --staged"
# Tmux helpers
alias t "tmux"
alias ta "tmux attach"
alias tls "tmux ls"
alias tn "tmux new -s"
# Podman helpers
alias p "podman"
alias pc "podman compose"
{% raw %}
alias pps "podman ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'"
{% endraw %}
# System helpers
alias ports "ss -tulpn"
alias myip "curl -4 ifconfig.me"
# Fish abbreviations
{% for abbr in cli_fish_abbreviations %}
abbr --add {{ abbr.name | quote }} {{ abbr.expansion | quote }}
{% endfor %}

View File

@ -0,0 +1,43 @@
# Managed by Ansible
[user]
{% if cli_git_user_name | length > 0 %}
name = {{ cli_git_user_name }}
{% endif %}
{% if cli_git_user_email | length > 0 %}
email = {{ cli_git_user_email }}
{% endif %}
[init]
defaultBranch = main
[pull]
rebase = false
[push]
autoSetupRemote = true
[fetch]
prune = true
[diff]
colorMoved = default
[merge]
conflictstyle = zdiff3
[rerere]
enabled = true
[color]
ui = auto
[alias]
st = status
co = checkout
sw = switch
br = branch
ci = commit
lg = log --oneline --graph --decorate --all
last = log -1 HEAD --stat
unstage = restore --staged

View File

@ -0,0 +1,100 @@
# Managed by Ansible
add_newline = true
command_timeout = 1000
format = """
$username\
$hostname\
$directory\
$git_branch\
$git_status\
$container\
$docker_context\
$python\
$nodejs\
$golang\
$rust\
$terraform\
$kubernetes\
$cmd_duration\
$line_break\
$character"""
[character]
success_symbol = "[➜](bold green)"
error_symbol = "[➜](bold red)"
vimcmd_symbol = "[](bold green)"
[username]
show_always = false
style_user = "bold blue"
style_root = "bold red"
format = "[$user]($style) "
[hostname]
ssh_only = true
style = "bold dimmed green"
format = "on [$hostname]($style) "
[directory]
style = "bold cyan"
truncation_length = 4
truncate_to_repo = false
read_only = " 󰌾"
format = "[$path]($style)[$read_only]($read_only_style) "
[git_branch]
symbol = " "
style = "bold purple"
format = "on [$symbol$branch]($style) "
[git_status]
style = "bold yellow"
format = "[$all_status$ahead_behind]($style) "
[cmd_duration]
min_time = 1000
style = "bold yellow"
format = "took [$duration]($style) "
[container]
symbol = "⬢ "
style = "bold red"
format = "[$symbol$name]($style) "
[docker_context]
symbol = " "
style = "blue bold"
format = "via [$symbol$context]($style) "
[kubernetes]
disabled = false
symbol = "☸ "
style = "bold blue"
format = "[$symbol$context( \\($namespace\\))]($style) "
[python]
symbol = " "
style = "yellow bold"
format = "via [$symbol$pyenv_prefix$version( \\($virtualenv\\))]($style) "
[nodejs]
symbol = " "
style = "green bold"
format = "via [$symbol$version]($style) "
[golang]
symbol = " "
style = "cyan bold"
format = "via [$symbol$version]($style) "
[rust]
symbol = " "
style = "red bold"
format = "via [$symbol$version]($style) "
[terraform]
symbol = " "
style = "purple bold"
format = "via [$symbol$workspace]($style) "

View File

@ -0,0 +1,66 @@
# Managed by Ansible
# General quality of life
set -g mouse on
set -g history-limit 50000
set -g set-clipboard on
set -g renumber-windows on
set -g escape-time 10
set -g focus-events on
# Use 1-based indexes
set -g base-index 1
setw -g pane-base-index 1
# Better terminal/color support
set -g default-terminal "tmux-256color"
set -ga terminal-overrides ",xterm-256color:Tc"
# Vi-style copy mode
setw -g mode-keys vi
# Status bar
set -g status on
set -g status-interval 5
set -g status-position bottom
set -g status-style "bg=colour235,fg=colour250"
set -g status-left-length 80
set -g status-right-length 120
set -g status-left "#[fg=colour82,bold] #S #[fg=colour240]|#[default] "
set -g status-right "#[fg=colour245]%Y-%m-%d #[fg=colour82]%H:%M #[fg=colour240]| #[fg=colour39]#H "
setw -g window-status-format "#[fg=colour245] #I:#W "
setw -g window-status-current-format "#[fg=colour235,bg=colour82,bold] #I:#W "
# Pane borders
set -g pane-border-style "fg=colour240"
set -g pane-active-border-style "fg=colour82"
# Easier reload
bind r source-file ~/.tmux.conf \; display-message "Reloaded ~/.tmux.conf"
# Splits using current directory
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
# New windows keep current directory
bind c new-window -c "#{pane_current_path}"
# Vim-like pane movement
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
# Resize panes
bind -r H resize-pane -L 5
bind -r J resize-pane -D 5
bind -r K resize-pane -U 5
bind -r L resize-pane -R 5
# Copy mode bindings
bind-key -T copy-mode-vi v send-keys -X begin-selection
bind-key -T copy-mode-vi y send-keys -X copy-selection-and-cancel
bind-key -T copy-mode-vi Escape send-keys -X cancel

View File

@ -17,15 +17,6 @@
name: selinux_containers name: selinux_containers
tasks_from: labels tasks_from: labels
#- name: Ensure container app config directories are owned by container UID
# become: true
# file:
# path: "{{ synapse_config_dir }}"
# state: directory
# owner: "{{ container_user }}"
# group: "{{ container_group }}"
# recurse: true
- name: Deploy homesever configuration template - name: Deploy homesever configuration template
template: template:
src: homeserver.yaml.j2 src: homeserver.yaml.j2

View File

@ -1,15 +1,16 @@
[Unit] [Unit]
Description=Flaresolverr Cloudflare Solver Description=Byparr - Cloudflare Bypass Proxy
Requires=gluetun.service Requires=gluetun.service
After=gluetun.service After=gluetun.service
[Container] [Container]
ContainerName=flaresolverr ContainerName=byparr
Image=ghcr.io/flaresolverr/flaresolverr:latest Image=ghcr.io/thephaseless/byparr:latest
Environment=TZ=America/New_York Environment=TZ=America/New_York
Environment=LOG_LEVEL=info Environment=LOG_LEVEL=info
Network=container:gluetun Network=container:gluetun
Restart=always
[Install] [Install]
WantedBy=default.target WantedBy=multi-user.target

View File

@ -17,7 +17,7 @@ AddDevice=/dev/net/tun:/dev/net/tun
# 6767 Bazarr # 6767 Bazarr
# 7878 Radarr # 7878 Radarr
# 8080 qBittorrent # 8080 qBittorrent
# 8191 Flaresolverr # 8191 Byparr
# 8989 Sonarr # 8989 Sonarr
# 9696 Prowlarr # 9696 Prowlarr
@ -30,11 +30,11 @@ PublishPort=9696:9696
Environment=VPN_SERVICE_PROVIDER=mullvad Environment=VPN_SERVICE_PROVIDER=mullvad
Environment=VPN_TYPE=wireguard Environment=VPN_TYPE=wireguard
Environment=SERVER_COUNTRIES={{ vpn_countries }}
Environment=WIREGUARD_PRIVATE_KEY={{ vault_vpn_private_key }} Environment=WIREGUARD_PRIVATE_KEY={{ vault_vpn_private_key }}
Environment=WIREGUARD_ADDRESSES={{ vpn_addresses }} Environment=WIREGUARD_ADDRESSES={{ vpn_addresses }}
Environment=FIREWALL_ENABLED=on Environment=FIREWALL_ENABLED=on
#Environment=FIREWALL_ENABLED_DISABLING_IT_SHOOTS_YOU_IN_YOUR_FOOT=off
Environment=DNS_ENABLED=false Environment=DNS_ENABLED=false
Environment=FIREWALL_INPUT_PORTS=6767,7878,8080,8191,8989,9696 Environment=FIREWALL_INPUT_PORTS=6767,7878,8080,8191,8989,9696