fix git error and added arch and laptop custom project file

This commit is contained in:
trucktrav 2026-05-02 18:23:49 -04:00
parent 93af88ec8a
commit 4a83ebee49
75 changed files with 19667 additions and 2 deletions

@ -1 +0,0 @@
Subproject commit 6c9df464ed8aea84a40817723da38ebcb9917605

View File

@ -0,0 +1,10 @@
# Python-generated files
__pycache__/
*.py[oc]
build/
dist/
wheels/
*.egg-info
# Virtual environments
.venv

View File

@ -0,0 +1 @@
3.13

View File

@ -0,0 +1,3 @@
{
"ansible.python.interpreterPath": "/bin/python"
}

View File

@ -0,0 +1,527 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Overview
This is an Ansible playbook repository for automating Arch Linux development environment setup. It configures a local workstation with development tools, window managers, shells, and productivity applications. The playbooks are designed to run locally (not against remote hosts) using `localhost` as the target.
The project has evolved from monolithic playbooks to a modular, role-based architecture with feature flags for flexible deployments.
## Project Structure
```
arch_custom/
├── playbooks/
│ ├── local_setup.yml # MAIN PLAYBOOK (production)
│ └── debug/ # Archived legacy playbooks
│ ├── playbook.yml # Original monolithic version
│ ├── playbook-2.yml # Iteration attempt
│ └── local_setups.yml # Incomplete test version
├── roles/
│ ├── custom/ # Core system setup (modular)
│ │ ├── tasks/
│ │ │ ├── main.yml # Base packages, yay, UV, Hyprland, productivity tools
│ │ │ ├── capps.yml # Development apps (PyCharm, R/RStudio, databases)
│ │ │ └── terms.yml # Terminal setup (Alacritty, TMUX with TPM)
│ │ └── files/
│ │ └── alacritty.yml # Alacritty configuration file
│ ├── manage_zsh/ # Zsh with optional Powerlevel10k (modular)
│ │ ├── tasks/
│ │ │ ├── main.yml # Install packages via pacman, copy .zshrc, fastfetch
│ │ │ ├── zsh-plugin.yml # Git clone method for plugins (conditional)
│ │ │ └── zsh-p10k.yml # Oh My Zsh + Powerlevel10k (conditional)
│ │ ├── files/
│ │ │ ├── .zshrc # Zsh configuration for Powerlevel10k
│ │ │ └── .p10k.zsh # Powerlevel10k theme configuration
│ │ ├── defaults/
│ │ ├── handlers/
│ │ └── vars/
│ ├── starship/ # Starship prompt (production-ready)
│ │ ├── tasks/
│ │ │ └── main.yml # Install Starship + modern CLI tools
│ │ └── files/
│ │ ├── starship.toml # Starship prompt configuration
│ │ └── zshrc # Zsh config optimized for Starship
│ └── geerlingguy.docker/ # External Galaxy role for Docker
├── inventories/
│ └── hosts # Localhost inventory with groups
├── requirement.yml # Ansible Galaxy role dependencies
├── ansible.cfg # Ansible configuration (local connection, logging, facts cache)
├── pyproject.toml # Python dependencies (ansible, ansible-lint, yamllint)
├── README.md # User-facing documentation
└── CLAUDE.md # This file (developer documentation)
```
## Key Architecture Decisions
### Execution Model
- All playbooks target `localhost` with `connection: local`
- Uses privilege escalation (`become: yes`) for system package installation
- Switches to non-root (`become: false` or `become_user: "{{ user }}"`) for user-specific configurations
- Variables `username` and `user_home` are derived from the executing user's environment
### Modular Role Architecture
The project has evolved significantly:
- **Legacy**: Monolithic playbooks (now in `playbooks/debug/`)
- **Current**: Modular roles with sub-task files and feature flags
**Custom Role Modularity:**
- `main.yml`: Core system setup (packages, yay, UV, system tools)
- `capps.yml`: Development applications (PyCharm, R, RStudio, databases)
- `terms.yml`: Terminal emulators and multiplexers (Alacritty, TMUX with TPM)
**Manage_zsh Role Modularity:**
- `main.yml`: Package installation via pacman, .zshrc deployment, fastfetch setup
- `zsh-plugin.yml`: Git clone method for plugins (used when not using pacman)
- `zsh-p10k.yml`: Oh My Zsh + Powerlevel10k installation (conditional on `USE_P10K`)
**Shell Configuration Strategy:**
- Two mutually exclusive shell prompt options controlled by feature flags
- `USE_STARSHIP: true` → Modern, fast, Rust-based prompt (current default)
- `USE_P10K: true` → Feature-rich, customizable prompt with Oh My Zsh
- Only one should be enabled at a time to avoid conflicts
### Feature Flags
The playbook uses boolean variables for conditional component installation:
```yaml
USE_STARSHIP: true # Enable Starship prompt (recommended)
USE_P10K: false # Enable Powerlevel10k with Oh My Zsh
USE_ALACRITTY: false # Set Alacritty as default terminal
INSTALL_CUSTOM_APPS: false # Install development apps (PyCharm, R, databases)
install_tiling_wm: true # Install tiling window manager
```
These allow users to customize their installation without modifying role code.
### Package Management Strategy
- **Official Arch packages**: `community.general.pacman` module
- **AUR packages**:
- Method 1: `ansible.builtin.command` with `yay -S --noconfirm <package>`
- Method 2: `community.general.pacman` with `executable: yay`
- **Yay installation**: Handled conditionally (checks if already installed before building)
- **Ansible Galaxy roles**: Installed via `ansible-galaxy install -r requirement.yml`
**Zsh Plugin Management:**
- **Default approach (manage_zsh)**: Install via pacman system packages
- `zsh-autosuggestions`, `zsh-syntax-highlighting`, `zsh-completions`, `zsh-transient-prompt`
- Source from `/usr/share/zsh/plugins/` paths
- Benefits: Automatic updates with `pacman -Syu`, clean uninstall
- **Alternative approach (starship)**: Git clone to `~/.zsh/` directory
- Used for cross-distro compatibility in dotfiles
- Manual updates required
### User Context Switching Pattern
Tasks frequently switch between root and user contexts:
```yaml
# System package installation (as root)
- name: Install packages
community.general.pacman:
name: package-name
state: present
# Implicit: become: yes (from playbook level)
# User-specific configuration (as non-root)
- name: Copy config file
become: false
ansible.builtin.copy:
src: config.yml
dest: "{{ user_home }}/.config/app/config.yml"
# Explicit user context
- name: Install AUR package
become: false
ansible.builtin.command: yay -S --noconfirm package-name
```
### External Role Dependencies
The project uses `geerlingguy.docker` role from Ansible Galaxy:
- Professional, well-maintained role for Docker installation
- Handles Docker service management and user group setup
- Version pinned in `requirement.yml`: `7.3.0`
- Install before running playbook: `ansible-galaxy install -r requirement.yml`
## Configuration Variables
### Required Variables (set in playbooks/local_setup.yml)
```yaml
username: "{{ lookup('env', 'USER') }}" # Auto-detected from environment
user_home: "/home/{{ username }}" # User's home directory
user: "{{ username }}" # Alias for role compatibility
home: "{{ user_home }}" # Alias for role compatibility
```
### Feature Flags
```yaml
USE_STARSHIP: true # Enable Starship shell prompt
USE_P10K: false # Enable Powerlevel10k (don't enable with Starship)
USE_ALACRITTY: false # Set Alacritty as default terminal emulator
INSTALL_CUSTOM_APPS: false # Install PyCharm, R/RStudio, databases
install_tiling_wm: true # Install tiling window manager
tiling_wm: "i3-gaps" # Which tiling WM (i3-gaps, sway, awesome, qtile, bspwm)
git_server_port: 3000 # Port for local Git server (if enabled)
```
## Common Commands
### First-Time Setup
```bash
# Install Ansible on Arch Linux
sudo pacman -S ansible
# Set up Python environment for linting (optional)
uv sync
source .venv/bin/activate
# Install Galaxy role dependencies
ansible-galaxy install -r requirement.yml
# Run the main playbook
ansible-playbook playbooks/local_setup.yml
```
### Run with Specific Tags
```bash
# Only setup core packages and tools
ansible-playbook playbooks/local_setup.yml --tags custom
# Only setup Zsh environment
ansible-playbook playbooks/local_setup.yml --tags manage_zsh
# Only setup Starship prompt
ansible-playbook playbooks/local_setup.yml --tags starship
# Only setup Docker
ansible-playbook playbooks/local_setup.yml --tags docker
# Run all base setup tasks (custom + manage_zsh + starship + docker)
ansible-playbook playbooks/local_setup.yml --tags base_setup
# Skip Docker installation
ansible-playbook playbooks/local_setup.yml --skip-tags docker
```
### Validation and Testing
```bash
# Syntax check
ansible-playbook playbooks/local_setup.yml --syntax-check
# Dry run (check mode)
ansible-playbook playbooks/local_setup.yml --check
# Run with verbose output
ansible-playbook playbooks/local_setup.yml -vv
# Linting (requires uv environment)
uv sync && source .venv/bin/activate
ansible-lint playbooks/local_setup.yml
yamllint .
```
### Inventory Management
```bash
# View inventory structure
ansible-inventory --list
# View inventory graph
ansible-inventory --graph
```
## Development Workflow
### Adding New Roles
1. Create role structure: `ansible-galaxy init roles/<role-name>`
2. Add tasks to `roles/<role-name>/tasks/main.yml`
3. Define defaults in `roles/<role-name>/defaults/main.yml` if needed
4. Store config files in `roles/<role-name>/files/` for the `copy` module
5. Include role in `playbooks/local_setup.yml`:
```yaml
roles:
- role: <role-name>
tags:
- <role-name>
- base_setup # Optional: include in base setup
```
### Modularizing Existing Roles
When a role's `main.yml` becomes too large, split into focused sub-task files:
**Example: Custom role structure**
```yaml
# roles/custom/tasks/main.yml
---
- name: Base system setup
# Core tasks...
- name: Include development apps
include_tasks: capps.yml
when: INSTALL_CUSTOM_APPS
- name: Include terminal setup
include_tasks: terms.yml
```
**Sub-task files:**
- `capps.yml`: Development applications (PyCharm, R, databases)
- `terms.yml`: Terminal emulators and configurations
This pattern keeps files focused (< 200 lines) and improves readability.
### Adding Configuration Files
Store configuration files in `roles/<role-name>/files/`:
```yaml
# Reference file in copy task
- name: Configure application
ansible.builtin.copy:
src: config.yml # Looks in roles/<role-name>/files/config.yml
dest: "{{ user_home }}/.config/app/config.yml"
mode: '0644'
```
For inline content, use `content` parameter:
```yaml
- name: Create config file
ansible.builtin.copy:
dest: "{{ user_home }}/.config/app/config.yml"
content: |
key: value
setting: true
mode: '0644'
```
### Handling AUR Packages
Standard pattern for AUR packages:
```yaml
- name: Install AUR package
become: false
ansible.builtin.command: yay -S --noconfirm <package-name>
register: result
changed_when: result.rc == 0
failed_when: result.rc != 0 and 'error' in result.stderr
```
Alternative using pacman module:
```yaml
- name: Install AUR package
become: false
community.general.pacman:
name: <package-name>
state: present
executable: yay
extra_args: "--builddir /tmp/yay"
```
### Managing Shell Plugins
**For Powerlevel10k (manage_zsh role):**
- Plugins installed via pacman: Edit `roles/manage_zsh/tasks/main.yml`
- Add package to the pacman task list
- Source in `.zshrc` from `/usr/share/zsh/plugins/<plugin-name>/`
**For Starship (starship role):**
- Plugins cloned via git: Edit `roles/starship/tasks/main.yml`
- Add git clone task for the plugin
- Source in `zshrc` from `~/.zsh/<plugin-name>/`
### Conditional Role Execution
Use `when` clauses with feature flags:
```yaml
roles:
- role: starship
when: USE_STARSHIP
tags:
- starship
- base_setup
- role: manage_zsh
when: USE_P10K
tags:
- manage_zsh
- base_setup
```
Internal conditionals in roles:
```yaml
# In manage_zsh/tasks/main.yml
roles:
- role: zsh-plugin
when: USE_P10K
- role: zsh-p10k
when: USE_P10K
```
### Facts Caching
Facts are cached to `./facts_cache/` with a 2-hour timeout:
```bash
# Clear cache if needed
rm -rf facts_cache/*
# Disable cache for testing
ansible-playbook playbooks/local_setup.yml --flush-cache
```
## Important Patterns and Conventions
### Variable Naming
- Feature flags: `USE_<FEATURE>` or `INSTALL_<FEATURE>` (boolean)
- User variables: `username`, `user_home`, `user`, `home`
- Role-specific: Prefix with role name (`manage_zsh_user`)
### Task Naming
- Prefix with role name: `Manage_zsh | Install required packages`
- Use descriptive, action-oriented names
- Follow pattern: `<Role> | <Action> <Target>`
### File Organization
- Keep `main.yml` under 200 lines
- Split into logical sub-task files when needed
- Use `include_tasks` for conditional sub-tasks
- Store static files in `files/` directory
- Use `templates/` for Jinja2 templates (if needed)
### Idempotency
Ensure tasks can be run multiple times safely:
```yaml
# Check before creating
- name: Check if exists
ansible.builtin.stat:
path: /path/to/resource
register: resource_check
- name: Create resource
when: not resource_check.stat.exists
# ... creation task
# Use creates argument
- name: Build and install
ansible.builtin.command: makepkg -si --noconfirm
args:
creates: /usr/bin/executable
```
### Error Handling
```yaml
# Allow task to fail without stopping playbook
- name: Optional task
ansible.builtin.command: some-command
failed_when: false
# Define specific failure conditions
- name: Install package
ansible.builtin.command: yay -S --noconfirm package
register: result
failed_when: result.rc != 0 and 'error' in result.stderr
# Ignore specific return codes
- name: Check for resource
ansible.builtin.command: which program
register: check
changed_when: false
failed_when: check.rc not in [0, 1]
```
## Logs and Debugging
### Log Files
- Ansible logs: `./ansible.log` (configured in `ansible.cfg`)
- Location: Project root directory
- Persistent across runs (appends)
### Verbosity Levels
```bash
# Standard output
ansible-playbook playbooks/local_setup.yml
# Show task results (-v)
ansible-playbook playbooks/local_setup.yml -v
# Show task inputs and outputs (-vv)
ansible-playbook playbooks/local_setup.yml -vv
# Debug level (-vvv)
ansible-playbook playbooks/local_setup.yml -vvv
# Connection debug level (-vvvv)
ansible-playbook playbooks/local_setup.yml -vvvv
```
### Debugging Specific Tasks
```bash
# Start at specific task
ansible-playbook playbooks/local_setup.yml --start-at-task="Task Name"
# Run single task using tags
ansible-playbook playbooks/local_setup.yml --tags custom -vv
# Step through tasks interactively
ansible-playbook playbooks/local_setup.yml --step
```
### Debug Tasks
Add debug tasks to troubleshoot:
```yaml
- name: Debug user variables
ansible.builtin.debug:
msg:
- "Username: {{ username }}"
- "Home: {{ user_home }}"
- "Variable: {{ my_var | default('NOT SET') }}"
```
## Post-Installation Manual Steps
Document these for users in README.md:
1. **Docker group**: Log out and back in for group changes
2. **TMUX plugins**: Run `tmux` then press `Ctrl+Space + I`
3. **Starship config**: Edit `~/.config/starship.toml` for customization
4. **Powerlevel10k**: Run `p10k configure` for initial setup
5. **Python venvs**: Set up per-project environments with `uv venv`
## Testing Recommendations
1. **Test in VM**: Use Arch Linux VM for testing before deploying to main system
2. **Use check mode**: Always run with `--check` first
3. **Tag-based testing**: Test individual roles before full run
4. **Incremental approach**: Add new features behind feature flags
5. **Version control**: Commit working states before major changes
## Common Issues and Solutions
### Yay build failures
- Ensure `base-devel` is installed
- Check disk space for build directory
- Clear yay cache: `yay -Sc`
### Plugin sourcing errors
- Verify plugin path exists: `ls -la ~/.zsh/` or `/usr/share/zsh/plugins/`
- Check .zshrc syntax: `zsh -n ~/.zshrc`
- Ensure plugin installed before sourcing
### Permission errors
- Verify `become: false` for user-specific tasks
- Check file ownership: `ls -la ~/.config/`
- Use `become_user` for explicit user context
### Role not found
- Install Galaxy dependencies: `ansible-galaxy install -r requirement.yml`
- Check role path in `ansible.cfg`: `roles_path = ./roles`
- Verify role directory structure exists
## Migration Notes
If working with older versions of this playbook:
1. **Legacy playbooks** are in `playbooks/debug/` (archived, not deleted)
2. **Old monolithic custom role** has been split into modular sub-tasks
3. **Plugin installation** migrated from git clone to pacman packages (where possible)
4. **Feature flags** introduced for conditional installations
5. **geerlingguy.docker** replaced inline Docker tasks
When updating from old versions:
- Review feature flags in `playbooks/local_setup.yml`
- Run `ansible-galaxy install -r requirement.yml` for new dependencies
- Check README.md for updated configuration variables
- to memorize

View File

@ -0,0 +1,358 @@
# Arch Linux Development Environment Setup
Ansible playbook for automated setup of a complete Arch Linux development workstation. Configures shell environments, development tools, window managers, and system utilities in a modular, reproducible way.
## Features
- **Shell Environments**: Choose between Starship (modern, fast) or Powerlevel10k (feature-rich)
- **Development Tools**: PyCharm Professional, R/RStudio, UV package manager
- **Terminal Emulators**: Alacritty with custom config, TMUX with TPM plugin manager
- **Containerization**: Docker and Docker Compose via geerlingguy.docker role
- **Databases**: PostgreSQL, MariaDB (MongoDB optional)
- **Desktop Environment**: Hyprland, i3-gaps, and tiling window managers
- **Productivity Tools**: flameshot, meld, btop, ranger, timeshift, syncthing, keepassxc
- **ML/AI Support**: Automatic NVIDIA CUDA/cuDNN installation if GPU detected
- **Shell Plugins**: zsh-autosuggestions, zsh-syntax-highlighting, fzf, fastfetch
## Prerequisites
```bash
# Install Ansible
sudo pacman -S ansible git
# Clone this repository
git clone <your-repo-url> ~/Projects/ansible/arch_custom
cd ~/Projects/ansible/arch_custom
```
## Quick Start
```bash
# 1. Set up Python environment (optional, for ansible-lint)
uv sync
source .venv/bin/activate
# 2. Install Galaxy role dependencies
ansible-galaxy install -r requirement.yml
# 3. Run the playbook
ansible-playbook playbooks/local_setup.yml
# Run specific components only
ansible-playbook playbooks/local_setup.yml --tags custom
ansible-playbook playbooks/local_setup.yml --tags starship
ansible-playbook playbooks/local_setup.yml --tags docker
ansible-playbook playbooks/local_setup.yml --tags claude_code
```
## Configuration Variables
Edit `playbooks/local_setup.yml` to customize your installation:
### Shell Configuration
```yaml
USE_STARSHIP: true # Enable Starship prompt (modern, minimal)
USE_P10K: false # Enable Powerlevel10k (feature-rich, Oh My Zsh)
INSTALL_CUSTOM_APPS: false # installs a bunch of custom apps for dev
INSTALL_CLAUDE_CODE: true # Install Claude Code CLI (requires Node.js)
```
**Note**: Only enable one shell prompt at a time to avoid conflicts.
### Terminal Configuration
```yaml
USE_ALACRITTY: false # Set Alacritty as default terminal emulator
```
### Window Manager
```yaml
install_tiling_wm: true # Install tiling window manager
tiling_wm: "i3-gaps" # Options: i3-gaps, sway, awesome, qtile, bspwm
```
### User Settings
```yaml
username: "{{ lookup('env', 'USER') }}" # Auto-detected from environment
user_home: "/home/{{ username }}" # Home directory path
git_server_port: 3000 # Local Git server port (if enabled)
```
## What Gets Installed
### Core System Packages
- Base development tools (base-devel, git, curl, wget, openssh)
- Python 3 and pip
- Node.js and npm (for Claude Code CLI)
- yay (AUR helper)
- UV (modern Python package manager)
- Hyprland compositor
### Development Applications
- **PyCharm Professional** (via AUR)
- **R and RStudio Desktop** (data science stack)
- **PostgreSQL and MariaDB** (databases)
- **Docker and Docker Compose** (containerization)
- **Claude Code CLI** (AI coding assistant, optional)
### Terminal & Shell
- **Alacritty** terminal with custom configuration
- **TMUX** with TPM (Tmux Plugin Manager)
- **Zsh** with choice of:
- **Starship** prompt (Rust-based, fast, modern)
- **Powerlevel10k** with Oh My Zsh (customizable, feature-rich)
- **Fish** shell (alternative)
- **fastfetch** (system info display)
### Shell Plugins & Tools
- zsh-autosuggestions
- zsh-syntax-highlighting
- zsh-completions
- zsh-transient-prompt
- fzf (fuzzy finder)
- eza (modern ls replacement)
- bat (modern cat replacement)
- zoxide (smart cd command)
### Desktop Environment
- Tiling window manager (i3-gaps/sway/etc.)
- rofi (application launcher)
- dunst (notifications)
- picom (compositor)
- feh (wallpaper manager)
- Additional fonts (Nerd Fonts, Noto, etc.)
### Productivity Tools
- flameshot (screenshots)
- meld (diff viewer)
- zeal (offline documentation)
- btop (system monitor)
- ranger (file manager)
- timeshift (system backups)
- syncthing (file sync)
- keepassxc (password manager)
### GPU/ML Support
If NVIDIA GPU is detected:
- CUDA toolkit
- cuDNN (deep learning library)
## Post-Installation Steps
After running the playbook, complete these manual steps:
### 1. Docker Group Permissions
```bash
# Log out and log back in for docker group changes to take effect
# Or run: newgrp docker
```
### 2. TMUX Plugin Installation
```bash
# Start tmux
tmux
# Inside tmux, install plugins
# Press: Ctrl+Space + I (capital I)
# Or manually run:
~/.config/tmux/plugins/tpm/bin/install_plugins
```
### 3. Python Virtual Environments (Optional)
If you need Python environments for development:
```bash
# For LLM development
cd ~/Projects/llm-dev
uv venv
source .venv/bin/activate
uv pip install torch transformers datasets huggingface_hub
# For general app development
cd ~/Projects/app-dev
uv venv
source .venv/bin/activate
uv pip install <your-packages>
# For data analysis
cd ~/Projects/data-analysis
uv venv
source .venv/bin/activate
uv pip install pandas numpy matplotlib jupyter
```
### 4. Starship Configuration
If using Starship (`USE_STARSHIP: true`):
```bash
# Starship config is installed to: ~/.config/starship.toml
# ZSH config is installed to: ~/.zshrc
# Customize as needed by editing these files
```
### 5. Powerlevel10k Configuration
If using Powerlevel10k (`USE_P10K: true`):
```bash
# Run the configuration wizard
p10k configure
# Or manually edit: ~/.p10k.zsh
```
### 6. Switch Default Shell
```bash
# If you want to change your default shell (already done by playbook for zsh)
chsh -s /bin/zsh # For Zsh
chsh -s /bin/fish # For Fish
```
### 7. Claude Code Setup (Optional)
If you installed Claude Code (`INSTALL_CLAUDE_CODE: true`):
```bash
# Restart your terminal to load the updated PATH
# Or source your shell config:
source ~/.zshrc
# Set your Anthropic API key
export ANTHROPIC_API_KEY='your-api-key-here'
# Add to your shell config for persistence:
echo 'export ANTHROPIC_API_KEY="your-api-key-here"' >> ~/.zshrc
# Test Claude Code installation
claude --version
# Start using Claude Code
claude
```
For more information, visit: https://docs.claude.com/claude-code
## Project Structure
```
arch_custom/
├── playbooks/
│ ├── local_setup.yml # Main playbook (PRODUCTION)
│ └── debug/ # Archived legacy playbooks
├── roles/
│ ├── custom/ # Core system setup
│ │ ├── tasks/
│ │ │ ├── main.yml # Base packages, yay, UV, Hyprland
│ │ │ ├── capps.yml # Development apps (PyCharm, R, DBs)
│ │ │ └── terms.yml # Terminal setup (Alacritty, TMUX)
│ │ └── files/
│ │ └── alacritty.yml # Alacritty configuration
│ ├── manage_zsh/ # Zsh with Powerlevel10k
│ │ ├── tasks/
│ │ │ ├── main.yml # Main setup (packages, fastfetch)
│ │ │ ├── zsh-plugin.yml # Plugin installation (git clone)
│ │ │ └── zsh-p10k.yml # Oh My Zsh + Powerlevel10k
│ │ └── files/
│ │ ├── .zshrc # Zsh configuration
│ │ └── .p10k.zsh # Powerlevel10k theme
│ ├── starship/ # Starship prompt
│ │ ├── tasks/
│ │ │ └── main.yml # Starship + modern CLI tools
│ │ └── files/
│ │ ├── starship.toml # Starship configuration
│ │ └── zshrc # Zsh config for Starship
│ ├── claude_code/ # Claude Code CLI
│ │ └── tasks/
│ │ └── main.yml # Install Node.js, npm, Claude Code
│ └── geerlingguy.docker/ # Docker role (Galaxy)
├── inventories/
│ └── hosts # Localhost inventory
├── requirement.yml # Ansible Galaxy dependencies
├── ansible.cfg # Ansible configuration
├── pyproject.toml # Python dependencies
└── CLAUDE.md # Development guide
```
## Tags Reference
Use tags to run specific parts of the playbook:
- `custom` - Core system packages and tools
- `manage_zsh` - Zsh with Powerlevel10k setup
- `starship` - Starship prompt installation
- `docker` - Docker and Docker Compose
- `claude_code` - Claude Code CLI installation
- `dev_tools` - Development tools (includes Claude Code)
- `base_setup` - All base components (custom + manage_zsh + starship + docker + claude_code)
Example:
```bash
# Install only Docker
ansible-playbook playbooks/local_setup.yml --tags docker
# Install only Claude Code
ansible-playbook playbooks/local_setup.yml --tags claude_code
# Install everything except Docker
ansible-playbook playbooks/local_setup.yml --skip-tags docker
```
## Customization
### Adding New Packages
Edit `roles/custom/tasks/main.yml` and add to the appropriate pacman task:
```yaml
- name: Install development essentials
community.general.pacman:
name:
- existing-package
- your-new-package # Add here
state: present
```
### Adding AUR Packages
For AUR packages, add a task using yay:
```yaml
- name: Install your AUR package
become: false
ansible.builtin.command: yay -S --noconfirm your-package-name
register: result
changed_when: result.rc == 0
failed_when: result.rc != 0 and 'error' in result.stderr
```
### Switching Shell Themes
1. Edit `playbooks/local_setup.yml`
2. Set `USE_STARSHIP: true` OR `USE_P10K: true` (not both)
3. Re-run playbook
## Troubleshooting
### Yay installation fails
```bash
# Manually install yay
cd /tmp
git clone https://aur.archlinux.org/yay.git
cd yay
makepkg -si
```
### Docker permission denied
```bash
# Add yourself to docker group and reload
sudo usermod -aG docker $USER
newgrp docker
```
### Starship not showing
```bash
# Check if Starship is initialized in .zshrc
grep "starship init" ~/.zshrc
# Manually add if missing
echo 'eval "$(starship init zsh)"' >> ~/.zshrc
```
## Contributing
1. Test changes in a VM or on a non-production system
2. Use `--check` mode for dry runs: `ansible-playbook playbooks/local_setup.yml --check`
3. Run linting: `ansible-lint playbooks/local_setup.yml`
4. Update CLAUDE.md if adding new architectural patterns
## License
This is a personal configuration repository. Use at your own risk and customize to your needs.

View File

@ -0,0 +1,51 @@
[defaults]
# Inventory file location
inventory = ./inventories/hosts
# Disable host key checking for easier local development
host_key_checking = False
# Increase parallelism
forks = 10
# Path to roles directory
roles_path = ./roles
# Enable color output
color = true
# Facts caching
gathering = smart
fact_caching = jsonfile
fact_caching_connection = ./facts_cache
fact_caching_timeout = 7200
# Log path
log_path = ./ansible.log
# Default connection type
transport = local
# Default user to use for playbooks
remote_user = root
# Disable creation of .retry files
retry_files_enabled = False
# Callback plugins
result_format = yaml
# Setting to execute against localhost by default
inventory_localhost_enabled = true
[privilege_escalation]
# Privilege escalation settings
become = True
become_method = sudo
become_user = root
become_ask_pass = False
[ssh_connection]
# SSH connection settings
pipelining = True
control_path = /tmp/ansible-ssh-%%h-%%p-%%r

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,745 @@
{
"_ansible_facts_gathered": true,
"ansible_all_ipv4_addresses": [
"10.0.31.219"
],
"ansible_all_ipv6_addresses": [
"fe80::54f:797b:bb10:dc20"
],
"ansible_apparmor": {
"status": "disabled"
},
"ansible_architecture": "x86_64",
"ansible_bios_date": "06/09/2021",
"ansible_bios_vendor": "Dell Inc.",
"ansible_bios_version": "2.16.0",
"ansible_board_asset_tag": "NA",
"ansible_board_name": "08CDD2",
"ansible_board_serial": "/CRMCBH2/CN1296378F0003/",
"ansible_board_vendor": "Dell Inc.",
"ansible_board_version": "A00",
"ansible_chassis_asset_tag": "NA",
"ansible_chassis_serial": "CRMCBH2",
"ansible_chassis_vendor": "Dell Inc.",
"ansible_chassis_version": "NA",
"ansible_cmdline": {
"BOOT_IMAGE": "/boot/vmlinuz-linux",
"loglevel": "3",
"nowatchdog": true,
"nvme_load": "YES",
"resume": "UUID=f5d53529-4dc1-4763-9dda-d4c09a0366dc",
"root": "UUID=722ed9b2-2c94-46a5-873f-5c0b1cd2c16e",
"rw": true
},
"ansible_date_time": {
"date": "2025-05-22",
"day": "22",
"epoch": "1747965849",
"epoch_int": "1747965849",
"hour": "20",
"iso8601": "2025-05-23T02:04:09Z",
"iso8601_basic": "20250522T200409482181",
"iso8601_basic_short": "20250522T200409",
"iso8601_micro": "2025-05-23T02:04:09.482181Z",
"minute": "04",
"month": "05",
"second": "09",
"time": "20:04:09",
"tz": "MDT",
"tz_dst": "MDT",
"tz_offset": "-0600",
"weekday": "Thursday",
"weekday_number": "4",
"weeknumber": "20",
"year": "2025"
},
"ansible_default_ipv4": {
"address": "10.0.31.219",
"alias": "wlan0",
"broadcast": "10.0.31.255",
"gateway": "10.0.31.1",
"interface": "wlan0",
"macaddress": "9c:b6:d0:e8:1a:6d",
"mtu": 1500,
"netmask": "255.255.255.0",
"network": "10.0.31.0",
"prefix": "24",
"type": "ether"
},
"ansible_default_ipv6": {},
"ansible_device_links": {
"ids": {
"nvme0n1": [
"nvme-CT500P3PSSD8_24144849646C",
"nvme-CT500P3PSSD8_24144849646C_1",
"nvme-eui.000000000000000100a075244849646c"
],
"nvme0n1p1": [
"nvme-CT500P3PSSD8_24144849646C-part1",
"nvme-CT500P3PSSD8_24144849646C_1-part1",
"nvme-eui.000000000000000100a075244849646c-part1"
],
"nvme0n1p2": [
"nvme-CT500P3PSSD8_24144849646C-part2",
"nvme-CT500P3PSSD8_24144849646C_1-part2",
"nvme-eui.000000000000000100a075244849646c-part2"
],
"nvme0n1p3": [
"nvme-CT500P3PSSD8_24144849646C-part3",
"nvme-CT500P3PSSD8_24144849646C_1-part3",
"nvme-eui.000000000000000100a075244849646c-part3"
]
},
"labels": {
"nvme0n1p2": [
"endeavouros"
],
"nvme0n1p3": [
"swap"
]
},
"masters": {},
"uuids": {
"nvme0n1p1": [
"172B-BCBB"
],
"nvme0n1p2": [
"722ed9b2-2c94-46a5-873f-5c0b1cd2c16e"
],
"nvme0n1p3": [
"f5d53529-4dc1-4763-9dda-d4c09a0366dc"
]
}
},
"ansible_devices": {
"nvme0n1": {
"holders": [],
"host": "Non-Volatile memory controller: Micron Technology Inc 2550 NVMe SSD (DRAM-less) (rev 01)",
"links": {
"ids": [
"nvme-CT500P3PSSD8_24144849646C",
"nvme-CT500P3PSSD8_24144849646C_1",
"nvme-eui.000000000000000100a075244849646c"
],
"labels": [],
"masters": [],
"uuids": []
},
"model": "CT500P3PSSD8",
"partitions": {
"nvme0n1p1": {
"holders": [],
"links": {
"ids": [
"nvme-CT500P3PSSD8_24144849646C-part1",
"nvme-CT500P3PSSD8_24144849646C_1-part1",
"nvme-eui.000000000000000100a075244849646c-part1"
],
"labels": [],
"masters": [],
"uuids": [
"172B-BCBB"
]
},
"sectors": 4194304,
"sectorsize": 512,
"size": "2.00 GB",
"start": "4096",
"uuid": "172B-BCBB"
},
"nvme0n1p2": {
"holders": [],
"links": {
"ids": [
"nvme-CT500P3PSSD8_24144849646C-part2",
"nvme-CT500P3PSSD8_24144849646C_1-part2",
"nvme-eui.000000000000000100a075244849646c-part2"
],
"labels": [
"endeavouros"
],
"masters": [],
"uuids": [
"722ed9b2-2c94-46a5-873f-5c0b1cd2c16e"
]
},
"sectors": 956167383,
"sectorsize": 512,
"size": "455.94 GB",
"start": "4198400",
"uuid": "722ed9b2-2c94-46a5-873f-5c0b1cd2c16e"
},
"nvme0n1p3": {
"holders": [],
"links": {
"ids": [
"nvme-CT500P3PSSD8_24144849646C-part3",
"nvme-CT500P3PSSD8_24144849646C_1-part3",
"nvme-eui.000000000000000100a075244849646c-part3"
],
"labels": [
"swap"
],
"masters": [],
"uuids": [
"f5d53529-4dc1-4763-9dda-d4c09a0366dc"
]
},
"sectors": 16407319,
"sectorsize": 512,
"size": "7.82 GB",
"start": "960365783",
"uuid": "f5d53529-4dc1-4763-9dda-d4c09a0366dc"
}
},
"removable": "0",
"rotational": "0",
"sas_address": null,
"sas_device_handle": null,
"scheduler_mode": "none",
"sectors": 976773168,
"sectorsize": "512",
"serial": "24144849646C",
"size": "465.76 GB",
"support_discard": "512",
"vendor": null,
"virtual": 1
}
},
"ansible_distribution": "Archlinux",
"ansible_distribution_file_path": "/etc/arch-release",
"ansible_distribution_file_variety": "Archlinux",
"ansible_distribution_major_version": "rolling",
"ansible_distribution_release": "rolling",
"ansible_distribution_version": "rolling",
"ansible_dns": {
"nameservers": [
"10.0.31.1"
]
},
"ansible_domain": "",
"ansible_effective_group_id": 0,
"ansible_effective_user_id": 0,
"ansible_env": {
"BROWSER": "firefox",
"COLORTERM": "truecolor",
"DISPLAY": ":1",
"EDITOR": "nano",
"HOME": "/root",
"LANG": "en_US.UTF-8",
"LC_ADDRESS": "en_US.UTF-8",
"LC_IDENTIFICATION": "en_US.UTF-8",
"LC_MEASUREMENT": "en_US.UTF-8",
"LC_MONETARY": "en_US.UTF-8",
"LC_NAME": "en_US.UTF-8",
"LC_NUMERIC": "en_US.UTF-8",
"LC_PAPER": "en_US.UTF-8",
"LC_TELEPHONE": "en_US.UTF-8",
"LC_TIME": "en_US.UTF-8",
"LOGNAME": "root",
"MAIL": "/var/mail/root",
"PATH": "/usr/local/sbin:/usr/local/bin:/usr/bin",
"PWD": "/home/trucktrav/Projects/ansible/arch_custom/playbooks",
"SHELL": "/usr/bin/bash",
"SHLVL": "0",
"SUDO_COMMAND": "/bin/sh -c echo BECOME-SUCCESS-qnckahmfwrvyrovsvnmyukzdanhunvnp ; /usr/bin/python3 /home/trucktrav/.ansible/tmp/ansible-tmp-1747965848.662878-81371-191757208407794/AnsiballZ_setup.py",
"SUDO_GID": "1000",
"SUDO_HOME": "/home/trucktrav",
"SUDO_UID": "1000",
"SUDO_USER": "trucktrav",
"TERM": "xterm-256color",
"USER": "root",
"XAUTHORITY": "/run/user/1000/xauth_LxhxpK",
"XDG_CURRENT_DESKTOP": "KDE",
"_": "/usr/bin/python3"
},
"ansible_fibre_channel_wwn": [],
"ansible_fips": false,
"ansible_flags": [
"fpu",
"vme",
"de",
"pse",
"tsc",
"msr",
"pae",
"mce",
"cx8",
"apic",
"sep",
"mtrr",
"pge",
"mca",
"cmov",
"pat",
"pse36",
"clflush",
"dts",
"acpi",
"mmx",
"fxsr",
"sse",
"sse2",
"ss",
"ht",
"tm",
"pbe",
"syscall",
"nx",
"pdpe1gb",
"rdtscp",
"lm",
"constant_tsc",
"art",
"arch_perfmon",
"pebs",
"bts",
"rep_good",
"nopl",
"xtopology",
"nonstop_tsc",
"cpuid",
"aperfmperf",
"pni",
"pclmulqdq",
"dtes64",
"monitor",
"ds_cpl",
"vmx",
"est",
"tm2",
"ssse3",
"sdbg",
"fma",
"cx16",
"xtpr",
"pdcm",
"pcid",
"sse4_1",
"sse4_2",
"x2apic",
"movbe",
"popcnt",
"tsc_deadline_timer",
"aes",
"xsave",
"avx",
"f16c",
"rdrand",
"lahf_lm",
"abm",
"3dnowprefetch",
"cpuid_fault",
"epb",
"pti",
"ssbd",
"ibrs",
"ibpb",
"stibp",
"tpr_shadow",
"flexpriority",
"ept",
"vpid",
"ept_ad",
"fsgsbase",
"tsc_adjust",
"bmi1",
"avx2",
"smep",
"bmi2",
"erms",
"invpcid",
"mpx",
"rdseed",
"adx",
"smap",
"clflushopt",
"intel_pt",
"xsaveopt",
"xsavec",
"xgetbv1",
"xsaves",
"dtherm",
"arat",
"pln",
"pts",
"hwp",
"hwp_notify",
"hwp_act_window",
"hwp_epp",
"vnmi",
"md_clear",
"flush_l1d",
"arch_capabilities"
],
"ansible_form_factor": "Laptop",
"ansible_fqdn": "travis-xps139360",
"ansible_hostname": "travis-xps139360",
"ansible_hostnqn": "",
"ansible_interfaces": [
"lo",
"wlan0"
],
"ansible_is_chroot": false,
"ansible_iscsi_iqn": "",
"ansible_kernel": "6.14.6-arch1-1",
"ansible_kernel_version": "#1 SMP PREEMPT_DYNAMIC Fri, 09 May 2025 17:36:18 +0000",
"ansible_lo": {
"active": true,
"device": "lo",
"features": {
"esp_hw_offload": "off [fixed]",
"esp_tx_csum_hw_offload": "off [fixed]",
"generic_receive_offload": "on",
"generic_segmentation_offload": "on",
"highdma": "on [fixed]",
"hsr_dup_offload": "off [fixed]",
"hsr_fwd_offload": "off [fixed]",
"hsr_tag_ins_offload": "off [fixed]",
"hsr_tag_rm_offload": "off [fixed]",
"hw_tc_offload": "off [fixed]",
"l2_fwd_offload": "off [fixed]",
"large_receive_offload": "off [fixed]",
"loopback": "on [fixed]",
"macsec_hw_offload": "off [fixed]",
"ntuple_filters": "off [fixed]",
"receive_hashing": "off [fixed]",
"rx_all": "off [fixed]",
"rx_checksumming": "on [fixed]",
"rx_fcs": "off [fixed]",
"rx_gro_hw": "off [fixed]",
"rx_gro_list": "off",
"rx_udp_gro_forwarding": "off",
"rx_udp_tunnel_port_offload": "off [fixed]",
"rx_vlan_filter": "off [fixed]",
"rx_vlan_offload": "off [fixed]",
"rx_vlan_stag_filter": "off [fixed]",
"rx_vlan_stag_hw_parse": "off [fixed]",
"scatter_gather": "on",
"tcp_segmentation_offload": "on",
"tls_hw_record": "off [fixed]",
"tls_hw_rx_offload": "off [fixed]",
"tls_hw_tx_offload": "off [fixed]",
"tx_checksum_fcoe_crc": "off [fixed]",
"tx_checksum_ip_generic": "on [fixed]",
"tx_checksum_ipv4": "off [fixed]",
"tx_checksum_ipv6": "off [fixed]",
"tx_checksum_sctp": "on [fixed]",
"tx_checksumming": "on",
"tx_esp_segmentation": "off [fixed]",
"tx_fcoe_segmentation": "off [fixed]",
"tx_gre_csum_segmentation": "off [fixed]",
"tx_gre_segmentation": "off [fixed]",
"tx_gso_list": "on",
"tx_gso_partial": "off [fixed]",
"tx_gso_robust": "off [fixed]",
"tx_ipxip4_segmentation": "off [fixed]",
"tx_ipxip6_segmentation": "off [fixed]",
"tx_nocache_copy": "off [fixed]",
"tx_scatter_gather": "on [fixed]",
"tx_scatter_gather_fraglist": "on [fixed]",
"tx_sctp_segmentation": "on",
"tx_tcp6_segmentation": "on",
"tx_tcp_ecn_segmentation": "on",
"tx_tcp_mangleid_segmentation": "on",
"tx_tcp_segmentation": "on",
"tx_tunnel_remcsum_segmentation": "off [fixed]",
"tx_udp_segmentation": "on",
"tx_udp_tnl_csum_segmentation": "off [fixed]",
"tx_udp_tnl_segmentation": "off [fixed]",
"tx_vlan_offload": "off [fixed]",
"tx_vlan_stag_hw_insert": "off [fixed]",
"vlan_challenged": "on [fixed]"
},
"hw_timestamp_filters": [],
"ipv4": {
"address": "127.0.0.1",
"broadcast": "",
"netmask": "255.0.0.0",
"network": "127.0.0.0",
"prefix": "8"
},
"ipv6": [
{
"address": "::1",
"prefix": "128",
"scope": "host"
}
],
"mtu": 65536,
"promisc": false,
"timestamping": [],
"type": "loopback"
},
"ansible_loadavg": {
"15m": 0.88623046875,
"1m": 1.02099609375,
"5m": 0.880859375
},
"ansible_local": {},
"ansible_locally_reachable_ips": {
"ipv4": [
"10.0.31.219",
"127.0.0.0/8",
"127.0.0.1"
],
"ipv6": [
"::1",
"fe80::54f:797b:bb10:dc20"
]
},
"ansible_lsb": {
"codename": "rolling",
"description": "EndeavourOS Linux",
"id": "EndeavourOS",
"major_release": "rolling",
"release": "rolling"
},
"ansible_lvm": {
"lvs": {},
"pvs": {},
"vgs": {}
},
"ansible_machine": "x86_64",
"ansible_machine_id": "582b5fd93d8d4272bd5b87cbf24f0d8a",
"ansible_memfree_mb": 206,
"ansible_memory_mb": {
"nocache": {
"free": 1393,
"used": 2244
},
"real": {
"free": 206,
"total": 3637,
"used": 3431
},
"swap": {
"cached": 93,
"free": 3926,
"total": 8011,
"used": 4085
}
},
"ansible_memtotal_mb": 3637,
"ansible_mounts": [
{
"block_available": 104364857,
"block_size": 4096,
"block_total": 117364230,
"block_used": 12999373,
"device": "/dev/nvme0n1p2",
"dump": 0,
"fstype": "ext4",
"inode_available": 29376418,
"inode_total": 29884416,
"inode_used": 507998,
"mount": "/",
"options": "rw,noatime",
"passno": 0,
"size_available": 427478454272,
"size_total": 480723886080,
"uuid": "722ed9b2-2c94-46a5-873f-5c0b1cd2c16e"
},
{
"block_available": 523182,
"block_size": 4096,
"block_total": 523262,
"block_used": 80,
"device": "/dev/nvme0n1p1",
"dump": 0,
"fstype": "vfat",
"inode_available": 0,
"inode_total": 0,
"inode_used": 0,
"mount": "/boot/efi",
"options": "rw,relatime,fmask=0137,dmask=0027,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro",
"passno": 0,
"size_available": 2142953472,
"size_total": 2143281152,
"uuid": "172B-BCBB"
}
],
"ansible_nodename": "travis-xps139360",
"ansible_os_family": "Archlinux",
"ansible_pkg_mgr": "pacman",
"ansible_proc_cmdline": {
"BOOT_IMAGE": "/boot/vmlinuz-linux",
"loglevel": "3",
"nowatchdog": true,
"nvme_load": "YES",
"resume": "UUID=f5d53529-4dc1-4763-9dda-d4c09a0366dc",
"root": "UUID=722ed9b2-2c94-46a5-873f-5c0b1cd2c16e",
"rw": true
},
"ansible_processor": [
"0",
"GenuineIntel",
"Intel(R) Core(TM) i3-7100U CPU @ 2.40GHz",
"1",
"GenuineIntel",
"Intel(R) Core(TM) i3-7100U CPU @ 2.40GHz",
"2",
"GenuineIntel",
"Intel(R) Core(TM) i3-7100U CPU @ 2.40GHz",
"3",
"GenuineIntel",
"Intel(R) Core(TM) i3-7100U CPU @ 2.40GHz"
],
"ansible_processor_cores": 2,
"ansible_processor_count": 1,
"ansible_processor_nproc": 4,
"ansible_processor_threads_per_core": 2,
"ansible_processor_vcpus": 4,
"ansible_product_name": "XPS 13 9360",
"ansible_product_serial": "CRMCBH2",
"ansible_product_uuid": "4c4c4544-0052-4d10-8043-c3c04f424832",
"ansible_product_version": "NA",
"ansible_python": {
"executable": "/usr/bin/python3",
"has_sslcontext": true,
"type": "cpython",
"version": {
"major": 3,
"micro": 3,
"minor": 13,
"releaselevel": "final",
"serial": 0
},
"version_info": [
3,
13,
3,
"final",
0
]
},
"ansible_python_version": "3.13.3",
"ansible_real_group_id": 0,
"ansible_real_user_id": 0,
"ansible_selinux": {
"status": "Missing selinux Python library"
},
"ansible_selinux_python_present": false,
"ansible_service_mgr": "systemd",
"ansible_swapfree_mb": 3926,
"ansible_swaptotal_mb": 8011,
"ansible_system": "Linux",
"ansible_system_capabilities": [
"ep cap_wake_alarm+i"
],
"ansible_system_capabilities_enforced": "True",
"ansible_system_vendor": "Dell Inc.",
"ansible_systemd": {
"features": "+PAM +AUDIT -SELINUX -APPARMOR -IMA +IPE +SMACK +SECCOMP +GCRYPT +GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBCRYPTSETUP_PLUGINS +LIBFDISK +PCRE2 +PWQUALITY +P11KIT +QRENCODE +TPM2 +BZIP2 +LZ4 +XZ +ZLIB +ZSTD +BPF_FRAMEWORK +BTF +XKBCOMMON +UTMP -SYSVINIT +LIBARCHIVE",
"version": 257
},
"ansible_uptime_seconds": 6690,
"ansible_user_dir": "/root",
"ansible_user_gecos": "",
"ansible_user_gid": 0,
"ansible_user_id": "root",
"ansible_user_shell": "/usr/bin/bash",
"ansible_user_uid": 0,
"ansible_userspace_architecture": "x86_64",
"ansible_userspace_bits": "64",
"ansible_virtualization_role": "host",
"ansible_virtualization_tech_guest": [],
"ansible_virtualization_tech_host": [
"kvm"
],
"ansible_virtualization_type": "kvm",
"ansible_wlan0": {
"active": true,
"device": "wlan0",
"features": {
"esp_hw_offload": "off [fixed]",
"esp_tx_csum_hw_offload": "off [fixed]",
"generic_receive_offload": "on",
"generic_segmentation_offload": "off [requested on]",
"highdma": "off [fixed]",
"hsr_dup_offload": "off [fixed]",
"hsr_fwd_offload": "off [fixed]",
"hsr_tag_ins_offload": "off [fixed]",
"hsr_tag_rm_offload": "off [fixed]",
"hw_tc_offload": "off [fixed]",
"l2_fwd_offload": "off [fixed]",
"large_receive_offload": "off [fixed]",
"loopback": "off [fixed]",
"macsec_hw_offload": "off [fixed]",
"ntuple_filters": "off [fixed]",
"receive_hashing": "off [fixed]",
"rx_all": "off [fixed]",
"rx_checksumming": "off [fixed]",
"rx_fcs": "off [fixed]",
"rx_gro_hw": "off [fixed]",
"rx_gro_list": "off",
"rx_udp_gro_forwarding": "off",
"rx_udp_tunnel_port_offload": "off [fixed]",
"rx_vlan_filter": "off [fixed]",
"rx_vlan_offload": "off [fixed]",
"rx_vlan_stag_filter": "off [fixed]",
"rx_vlan_stag_hw_parse": "off [fixed]",
"scatter_gather": "off",
"tcp_segmentation_offload": "off",
"tls_hw_record": "off [fixed]",
"tls_hw_rx_offload": "off [fixed]",
"tls_hw_tx_offload": "off [fixed]",
"tx_checksum_fcoe_crc": "off [fixed]",
"tx_checksum_ip_generic": "on",
"tx_checksum_ipv4": "off [fixed]",
"tx_checksum_ipv6": "off [fixed]",
"tx_checksum_sctp": "off [fixed]",
"tx_checksumming": "on",
"tx_esp_segmentation": "off [fixed]",
"tx_fcoe_segmentation": "off [fixed]",
"tx_gre_csum_segmentation": "off [fixed]",
"tx_gre_segmentation": "off [fixed]",
"tx_gso_list": "off [fixed]",
"tx_gso_partial": "off [fixed]",
"tx_gso_robust": "off [fixed]",
"tx_ipxip4_segmentation": "off [fixed]",
"tx_ipxip6_segmentation": "off [fixed]",
"tx_nocache_copy": "off",
"tx_scatter_gather": "off [fixed]",
"tx_scatter_gather_fraglist": "off [fixed]",
"tx_sctp_segmentation": "off [fixed]",
"tx_tcp6_segmentation": "off [fixed]",
"tx_tcp_ecn_segmentation": "off [fixed]",
"tx_tcp_mangleid_segmentation": "off [fixed]",
"tx_tcp_segmentation": "off [fixed]",
"tx_tunnel_remcsum_segmentation": "off [fixed]",
"tx_udp_segmentation": "off [fixed]",
"tx_udp_tnl_csum_segmentation": "off [fixed]",
"tx_udp_tnl_segmentation": "off [fixed]",
"tx_vlan_offload": "off [fixed]",
"tx_vlan_stag_hw_insert": "off [fixed]",
"vlan_challenged": "off [fixed]"
},
"hw_timestamp_filters": [],
"ipv4": {
"address": "10.0.31.219",
"broadcast": "10.0.31.255",
"netmask": "255.255.255.0",
"network": "10.0.31.0",
"prefix": "24"
},
"ipv6": [
{
"address": "fe80::54f:797b:bb10:dc20",
"prefix": "64",
"scope": "link"
}
],
"macaddress": "9c:b6:d0:e8:1a:6d",
"module": "ath10k_pci",
"mtu": 1500,
"pciid": "0000:3a:00.0",
"promisc": false,
"timestamping": [],
"type": "ether"
},
"gather_subset": [
"all"
],
"module_setup": true
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,37 @@
# Inventory file defining localhost
# Define the localhost specifically
localhost ansible_connection=local
# Group for local development
[local]
localhost
# Group for development environment
[development]
localhost
# Group variables for local hosts
[local:vars]
ansible_python_interpreter=/usr/bin/python3
ansible_connection=local
# You can create additional groups as needed
[webservers]
# For future use
# web1.example.com
# web2.example.com
[databases]
# For future use
# db1.example.com
# Example of group hierarchy
[development:children]
local
webservers
[production:children]
# For future use
# webservers
# databases

View File

@ -0,0 +1,6 @@
def main():
print("Hello from arch-custom!")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,25 @@
---
- name: Local Setup
hosts: localhost
gather_facts: true
vars:
username: "{{ lookup('env', 'USER') }}"
user_home: "/home/{{ username }}"
git_server_port: 3000
install_tiling_wm: true # Set to false if you don't want a tiling WM
tiling_wm: "i3-gaps" # Options: i3-gaps, sway, awesome, qtile, bspwm
home: "{{ user_home }}"
user: "{{ username }}"
tasks:
- name: Manage_zsh | Install Oh My ZSH plugins
ansible.builtin.git:
repo: "{{ manage_zsh_item.repo }}"
dest: "/home/{{ user }}/.oh-my-zsh/plugins/{{ manage_zsh_item.name }}"
version: master
force: true
loop:
- { name: zsh-autosuggestions, repo: https://github.com/zsh-users/zsh-autosuggestions }
- { name: zsh-syntax-highlighting, repo: https://github.com/zsh-users/zsh-syntax-highlighting }
loop_control:
loop_var: manage_zsh_item

View File

@ -0,0 +1,491 @@
---
# playbook.yml - Ansible playbook for Arch Linux development environment setup
- name: Arch Linux Development Environment Setup
hosts: localhost
gather_facts: yes
connection: local
become: yes
vars:
username: "{{ lookup('env', 'USER') }}"
user_home: "/home/{{ username }}"
git_server_port: 3000
install_tiling_wm: true # Set to false if you don't want a tiling WM
tiling_wm: "i3-gaps" # Options: i3-gaps, sway, awesome, qtile, bspwm
HOME: "{{ user_home }}"
USER: "{{ username` }}"
# DISPLAY: "{{ ansible_env.DISPLAY | default('') }}"
# XDG_CONFIG_HOME: "{{ ansible_env.XDG_CONFIG_HOME | default(user_home + '/.config') }}"
# XDG_DATA_HOME: "{{ ansible_env.XDG_DATA_HOME | default(user_home + '/.local/share') }}"
# PATH: "{{ ansible_env.PATH }}"
tasks:
- name: Debug user variables
debug:
msg:
- "ansible_user_id: {{ ansible_user_id | default('NOT SET') }}"
- "ansible_env.USER: {{ ansible_env.USER | default('NOT SET') }}"
- "Current user from whoami: {{ ansible_facts['user_id'] | default('NOT SET') }}"
- " username {{ username }}"
- " userhome {{ user_home }}"
# - name: Compare environments
# shell: |
# echo "=== Terminal environment ==="
# bash -l -c 'env | sort' > /tmp/terminal_env.txt
# echo "=== Ansible environment ==="
# env | sort > /tmp/ansible_env.txt
# echo "=== Differences ==="
# diff /tmp/terminal_env.txt /tmp/ansible_env.txt || true
# register: env_diff
# Update system packages
- name: Update system packages
pacman:
update_cache: yes
upgrade: yes
# Install essential development packages
- name: Install development essentials
pacman:
name:
- base-devel
- git
- curl
- wget
- openssh
- python
- python-pip
- hyprland
state: present
# Install AUR helper (yay)
- name: Check if yay is installedstdout_callback
command: which yay
register: yay_installed
changed_when: false
failed_when: false
- name: Install yay (AUR helper)
when: yay_installed.rc != 0
become: no
block:
- name: Clone yay repository
git:
repo: https://aur.archlinux.org/yay.git
dest: "{{ user_home }}/yay"
- name: Build and install yay
command: makepkg -si --noconfirm
args:
chdir: "{{ user_home }}/yay"
- name: Clean up yay build directory
file:
path: "{{ user_home }}/yay"
state: absent
# Install terminal emulator - Alacritty
- name: Install Alacritty terminal
pacman:
name:
- alacritty
state: present
# Configure Alacritty
- name: Create Alacritty config directory
become: no
file:
path: "{{ user_home }}/.config/alacritty"
state: directory
mode: '0755'
- name: Install Nerd Font for Alacritty
become: no
command: yay -S --noconfirm ttf-firacode-nerd
register: font_result
changed_when: font_result.rc == 0
failed_when: font_result.rc != 0 and 'error' in font_result.stderr
- name: Configure Alacritty
become: no
copy:
dest: "{{ user_home }}/.config/alacritty/alacritty.yml"
content: |
# Performance
env:
TERM: xterm-256color
# Appearance
window:
padding:
x: 10
y: 10
dynamic_padding: true
decorations: full
opacity: 0.95 # Slight transparency
# Font configuration
font:
normal:
family: FiraCode Nerd Font
style: Regular
bold:
style: Bold
italic:
style: Italic
size: 12.0
offset:
x: 0
y: 0
glyph_offset:
x: 0
y: 0
use_thin_strokes: true
# Colors (Dracula theme)
colors:
primary:
background: '#282a36'
foreground: '#f8f8f2'
cursor:
text: '#44475a'
cursor: '#f8f8f2'
selection:
text: '#f8f8f2'
background: '#44475a'
# Shell integration
shell:
program: /bin/zsh
# Keybindings for productivity
key_bindings:
- { key: V, mods: Control|Shift, action: Paste }
- { key: C, mods: Control|Shift, action: Copy }
- { key: N, mods: Control|Shift, action: SpawnNewInstance }
- { key: Key0, mods: Control, action: ResetFontSize }
- { key: Plus, mods: Control, action: IncreaseFontSize }
- { key: Minus, mods: Control, action: DecreaseFontSize }
mode: '0644'
# # Install VS Code
# - name: Install VS Code
# community.general.pacman:
# name: visual-studio-code-bin
# state: present
# executable: yay
# extra_args: "--builddir /tmp/yay"
# become: no
# Install VS Code extensions
# - name: Install VS Code extensions
# become: false # Explicitly don't use sudo
# become_user: "{{ ansible_user_id }}"
# # raw: code --install-extension {{ item }}
# ansible.builtin.shell: 'code --install-extension {{ item }}'
# args:
# executable: /bin/bash
# environment:
# PATH: "/usr/bin:/usr/local/bin:{{ user_home }}/.vscode/bin:$PATH"
# DISPLAY: "{{ ansible_env.DISPLAY | default('') }}"
# XDG_CONFIG_HOME: "{{ ansible_env.XDG_CONFIG_HOME | default(user_home + '/.config') }}"
# XDG_DATA_HOME: "{{ ansible_env.XDG_DATA_HOME | default(user_home + '/.local/share') }}"
# loop:
# - redhat.ansible
# - ms-azuretools.vscode-docker
# - ms-kubernetes-tools.vscode-kubernetes-tools
# - hashicorp.terraform
# register: vscode_ext_result
# changed_when: "'already installed' not in vscode_ext_result.stdout"
# Install PyCharm Professional
- name: Install PyCharm Professional
become: no
community.general.pacman:
name: pycharm-professional
state: present
executable: yay
extra_args: "--builddir /tmp/yay"
register: pycharm_result
# - name: Install VS Code
# community.general.pacman:
# name: visual-studio-code-bin
# state: present
# executable: yay
# extra_args: "--builddir /tmp/yay"
# become: no
# Install UV package manager
- name: Install UV package manager
become: no
command: yay -S --noconfirm uv
register: uv_result
changed_when: uv_result.rc == 0
failed_when: uv_result.rc != 0 and 'error' in uv_result.stderr
# Configure UV
- name: Create UV config directory
become: no
file:
path: "{{ user_home }}/.config/uv"
state: directory
mode: '0755'
# - name: Create UV config file
# become: no
# copy:
# dest: "{{ user_home }}/.config/uv/uv.toml"
# content: |
# default-python = "python3"
# mode: '0644'
# Install Gitea for local Git server
# - name: Install Gitea
# pacman:
# name:
# - gitea
# state: present
# - name: Create Gitea config directory
# file:
# path: /etc/gitea
# state: directory
# mode: '0755'
# - name: Configure Gitea
# copy:
# remote_src: yes
# src: /etc/gitea/app.example.ini
# dest: /etc/gitea/app.ini
# force: no
# - name: Update Gitea configuration
# lineinfile:
# path: /etc/gitea/app.ini
# regexp: '^HTTP_PORT'
# line: 'HTTP_PORT = {{ git_server_port }}'
# - name: Enable and start Gitea service
# systemd:
# name: gitea
# enabled: yes
# state: started
# Install Docker
- name: Install Docker
pacman:
name:
- docker
- docker-compose
state: present
# - name: Enable and start Docker service
# systemd:
# name: docker.service
# enabled: yes
# state: started
# - name: Add user to docker group
# user:
# name: "{{ username }}"
# groups: docker
# append: yes
# Install additional data analysis tools
- name: Install R (optional)
pacman:
name:
- r
state: present
- name: Install RStudio (optional)
become: no
command: yay -S --noconfirm rstudio-desktop-bin
register: rstudio_result
changed_when: rstudio_result.rc == 0
failed_when: rstudio_result.rc != 0 and 'error' in rstudio_result.stderr
# Install database tools
- name: Install database tools
community.general.pacman:
name:
- postgresql
- mariadb
# - mongodb
state: present
# - name: Install mongodb
# community.general.pacman:
# name: mongodb
# state: present
# executable: yay
# extra_args: "--builddir /tmp/yay"
# become: no
- name: Install hyprland starter
become: no
git:
repo: https://github.com/mylinuxforwork/hyprland-starter
dest: "{{ user_home }}/hyprland-started"
depth: 1
# register: hyprland-starter_installed
# Install Zsh and Oh My Zsh
- name: Install Zsh
pacman:
name:
- zsh
state: present
- name: Create Zsh config directory
become: no
file:
path: "{{ user_home }}/.zshrc"
state: directory
mode: '0755'
register: zsh_config_dir
# Install Fish shell
- name: Install Fish shell
pacman:
name:
- fish
state: present
# Install powerlevel10k
- name: Install powerlevel10k theme
become: no
git:
repo: https://github.com/romkatv/powerlevel10k.git
dest: "{{ user_home }}/.oh-my-zsh/custom/themes/powerlevel10k"
depth: 1
register: p10k_installed
- name: Check if Oh My Zsh is installed
become: no
stat:
path: "{{ user_home }}/.oh-my-zsh"
register: oh_my_zsh_installed
- name: Install Oh My Zsh
become: no
when: not oh_my_zsh_installed.stat.exists
shell: curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh | sh
args:
creates: "{{ user_home }}/.oh-my-zsh"
- name: Configure powerlevel10k theme in zshrc
become: no
lineinfile:
path: "{{ user_home }}/.zshrc"
regexp: '^ZSH_THEME='
line: 'ZSH_THEME="powerlevel10k/powerlevel10k"'
# Install tiling window manager if enabled
- name: Install tiling window manager
when: install_tiling_wm
pacman:
name:
- "{{ tiling_wm }}"
- rofi # Application launcher
- dunst # Notifications
- picom # Compositor
- feh # Wallpaper manager
- sxhkd # Hotkey daemon
- lxappearance
- i3status
- i3clock
- dmenu
- i3status
- i3lock
- dmenu
- i3-gaps
state: present
# Install common development tools
- name: Install productivity tools
pacman:
name:
- flameshot # Screenshot tool
- meld # Diff tool
- zeal # Offline documentation
- tmux # Terminal multiplexer
- btop # System monitoring
- ranger # File manager
- timeshift # System backups
- syncthing # File synchronization
- keepassxc # Password manager
state: present
# Install common fonts
- name: Install additional fonts
pacman:
name:
- ttf-dejavu
- ttf-liberation
- noto-fonts
- noto-fonts-emoji
state: present
# Add GPU support for ML/LLM (NVIDIA)
- name: Check for NVIDIA GPU
shell: lspci | grep -i nvidia
register: has_nvidia
changed_when: false
failed_when: false
- name: Install NVIDIA CUDA support
when: has_nvidia.rc == 0
pacman:
name:
- cuda
- cudnn
state: present
# Create projects directory structure
- name: Create project directories
become: no
file:
path: "{{ user_home }}/Projects/{{ item }}"
state: directory
mode: '0755'
loop:
- llm-dev
- app-dev
- data-analysis
# Set Alacritty as default terminal (if installed)
- name: Set Alacritty as default terminal
become: no
command: xdg-mime default alacritty.desktop x-scheme-handler/terminal
changed_when: false
failed_when: false
# Notify user about completion
- name: Display completion message
debug:
msg: |
Development environment setup complete!
Access your local Git server at: http://localhost:{{ git_server_port }}
Remember to log out and back in for the docker group changes to take effect.
Python environments were not created as requested - use the following commands to set them up:
cd ~/projects/llm-dev
uv venv
source .venv/bin/activate
uv pip install torch transformers datasets huggingface_hub
Shells setup:
- ZSH with Powerlevel10k theme is installed
- Fish shell is also available, switch to it by typing 'fish'
Terminal:
- Alacritty has been configured as your terminal emulator
{% if install_tiling_wm %}
Window Manager:
- {{ tiling_wm }} has been installed as your tiling window manager
{% endif %}

View File

@ -0,0 +1,432 @@
---
# playbook.yml - Ansible playbook for Arch Linux development environment setup
- name: Arch Linux Development Environment Setup
hosts: localhost
gather_facts: yes
connection: local
become: yes
vars:
username: "{{ lookup('env', 'USER') }}"
user_home: "/home/{{ username }}"
git_server_port: 3000
install_tiling_wm: true # Set to false if you don't want a tiling WM
tiling_wm: "i3-gaps" # Options: i3-gaps, sway, awesome, qtile, bspwm
tasks:
# Update system packages
- name: Update system packages
pacman:
update_cache: yes
upgrade: yes
# Install essential development packages
- name: Install development essentials
pacman:
name:
- base-devel
- git
- curl
- wget
- openssh
- python
- python-pip
- hyprland
state: present
# Install AUR helper (yay)
- name: Check if yay is installed
command: which yay
register: yay_installed
changed_when: false
failed_when: false
- name: Install yay (AUR helper)
when: yay_installed.rc != 0
become: no
block:
- name: Clone yay repository
git:
repo: https://aur.archlinux.org/yay.git
dest: "{{ user_home }}/yay"
- name: Build and install yay
command: makepkg -si --noconfirm
args:
chdir: "{{ user_home }}/yay"
- name: Clean up yay build directory
file:
path: "{{ user_home }}/yay"
state: absent
# Install terminal emulator - Alacritty
- name: Install Alacritty terminal
pacman:
name:
- alacritty
state: present
# Configure Alacritty
- name: Create Alacritty config directory
become: no
file:
path: "{{ user_home }}/.config/alacritty"
state: directory
mode: '0755'
- name: Install Nerd Font for Alacritty
become: no
command: yay -S --noconfirm ttf-firacode-nerd
register: font_result
changed_when: font_result.rc == 0
failed_when: font_result.rc != 0 and 'error' in font_result.stderr
- name: Configure Alacritty
become: no
copy:
dest: "{{ user_home }}/.config/alacritty/alacritty.yml"
content: |
# Performance
env:
TERM: xterm-256color
# Appearance
window:
padding:
x: 10
y: 10
dynamic_padding: true
decorations: full
opacity: 0.95 # Slight transparency
# Font configuration
font:
normal:
family: FiraCode Nerd Font
style: Regular
bold:
style: Bold
italic:
style: Italic
size: 12.0
offset:
x: 0
y: 0
glyph_offset:
x: 0
y: 0
use_thin_strokes: true
# Colors (Dracula theme)
colors:
primary:
background: '#282a36'
foreground: '#f8f8f2'
cursor:
text: '#44475a'
cursor: '#f8f8f2'
selection: https://github.com/mylinuxforwork/hyprland-starter
text: '#f8f8f2'
background: '#44475a'
# Shell integration
shell:
program: /bin/zsh
# Keybindings for productivity
key_bindings:
- { key: V, mods: Control|Shift, action: Paste }
- { key: C, mods: Control|Shift, action: Copy }
- { key: N, mods: Control|Shift, action: SpawnNewInstance }
- { key: Key0, mods: Control, action: ResetFontSize }
- { key: Plus, mods: Control, action: IncreaseFontSize }
- { key: Minus, mods: Control, action: DecreaseFontSize }
mode: '0644'
# Install VS Code
- name: Install VS Code
pacman:
name:
- code
state: present
# Install VS Code extensions
- name: Install VS Code extensions
become: no
command: code --install-extension {{ item }}
loop:
- redhat.ansible
- ms-azuretools.vscode-docker
- ms-kubernetes-tools.vscode-kubernetes-tools
- hashicorp.terraform
register: vscode_ext_result
changed_when: "'already installed' not in vscode_ext_result.stdout"
# Install PyCharm Professional
- name: Install PyCharm Professional
become: no
command: yay -S --noconfirm pycharm-professional
register: pycharm_result
changed_when: pycharm_result.rc == 0
failed_when: pycharm_result.rc != 0 and 'error' in pycharm_result.stderr
# Install UV package manager
- name: Install UV package manager
become: no
command: yay -S --noconfirm uv
register: uv_result
changed_when: uv_result.rc == 0
failed_when: uv_result.rc != 0 and 'error' in uv_result.stderr
# Configure UV
- name: Create UV config directory
become: no
file:
path: "{{ user_home }}/.config/uv"
state: directory
mode: '0755'
- name: Create UV config file
become: no
copy:
dest: "{{ user_home }}/.config/uv/uv.toml"
content: |
default-python = "python3"
mode: '0644'
# Install Gitea for local Git server
# - name: Install Gitea
# pacman:
# name:
# - gitea
# state: present
# - name: Create Gitea config directory
# file:
# path: /etc/gitea
# state: directory
# mode: '0755'
# - name: Configure Gitea
# copy:
# remote_src: yes
# src: /etc/gitea/app.example.ini
# dest: /etc/gitea/app.ini
# force: no
# - name: Update Gitea configuration
# lineinfile:
# path: /etc/gitea/app.ini
# regexp: '^HTTP_PORT'
# line: 'HTTP_PORT = {{ git_server_port }}'
# - name: Enable and start Gitea service
# systemd:
# name: gitea
# enabled: yes
# state: started
# Install Docker
- name: Install Docker
pacman:
name:
- docker
state: present
- name: Enable and start Docker service
systemd:
name: docker
enabled: yes
state: started
- name: Add user to docker group
user:
name: "{{ username }}"
groups: docker
append: yes
# Install additional data analysis tools
- name: Install R (optional)
pacman:
name:
- r
state: present
- name: Install RStudio (optional)
become: no
command: yay -S --noconfirm rstudio-desktop-bin
register: rstudio_result
changed_when: rstudio_result.rc == 0
failed_when: rstudio_result.rc != 0 and 'error' in rstudio_result.stderr
# Install database tools
- name: Install database tools
pacman:
name:
- postgresql
- mariadb
- mongodb
state: present
- name: Install powerlevel10k theme
become: no
git:
repo: https://github.com/mylinuxforwork/hyprland-starter
dest: "{{ user_home }}/hyprland-started"
depth: 1
register: hyprland-starter_installed
# Install Zsh and Oh My Zsh
- name: Install Zsh
pacman:
name:
- zsh
state: present
# Install Fish shell
- name: Install Fish shell
pacman:
name:
- fish
state: present
# Install powerlevel10k
- name: Install powerlevel10k theme
become: no
git:
repo: https://github.com/romkatv/powerlevel10k.git
dest: "{{ user_home }}/.oh-my-zsh/custom/themes/powerlevel10k"
depth: 1
register: p10k_installed
- name: Check if Oh My Zsh is installed
become: no
stat:
path: "{{ user_home }}/.oh-my-zsh"
register: oh_my_zsh_installed
- name: Install Oh My Zsh
become: no
when: not oh_my_zsh_installed.stat.exists
shell: curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh | sh
args:
creates: "{{ user_home }}/.oh-my-zsh"
- name: Configure powerlevel10k theme in zshrc
become: no
lineinfile:
path: "{{ user_home }}/.zshrc"
regexp: '^ZSH_THEME='
line: 'ZSH_THEME="powerlevel10k/powerlevel10k"'
# Install tiling window manager if enabled
- name: Install tiling window manager
when: install_tiling_wm
pacman:
name:
- "{{ tiling_wm }}"
- rofi # Application launcher
- dunst # Notifications
- picom # Compositor
- feh # Wallpaper manager
- sxhkd # Hotkey daemon
- lxappearance
- i3status
- i3clock
- dmenu
- i3status
- i3lock
- dmenu
- i3-gaps
state: present
# Install common development tools
- name: Install productivity tools
pacman:
name:
- flameshot # Screenshot tool
- meld # Diff tool
- zeal # Offline documentation
- tmux # Terminal multiplexer
- btop # System monitoring
- ranger # File manager
- timeshift # System backups
- syncthing # File synchronization
- keepassxc # Password manager
state: present
# Install common fonts
- name: Install additional fonts
pacman:
name:
- ttf-dejavu
- ttf-liberation
- noto-fonts
- noto-fonts-emoji
state: present
# Add GPU support for ML/LLM (NVIDIA)
- name: Check for NVIDIA GPU
shell: lspci | grep -i nvidia
register: has_nvidia
changed_when: false
failed_when: false
- name: Install NVIDIA CUDA support
when: has_nvidia.rc == 0
pacman:
name:
- cuda
- cudnn
state: present
# Create projects directory structure
- name: Create project directories
become: no
file:
path: "{{ user_home }}/projects/{{ item }}"
state: directory
mode: '0755'
loop:
- llm-dev
- app-dev
- data-analysis
# Set Alacritty as default terminal (if installed)
- name: Set Alacritty as default terminal
become: no
command: xdg-mime default alacritty.desktop x-scheme-handler/terminal
changed_when: false
failed_when: false
# Notify user about completion
- name: Display completion message
debug:
msg: |
Development environment setup complete!
Access your local Git server at: http://localhost:{{ git_server_port }}
Remember to log out and back in for the docker group changes to take effect.
Python environments were not created as requested - use the following commands to set them up:
cd ~/projects/llm-dev
uv venv
source .venv/bin/activate
uv pip install torch transformers datasets huggingface_hub
Shells setup:
- ZSH with Powerlevel10k theme is installed
- Fish shell is also available, switch to it by typing 'fish'
Terminal:
- Alacritty has been configured as your terminal emulator
{% if install_tiling_wm %}
Window Manager:
- {{ tiling_wm }} has been installed as your tiling window manager
{% endif %}

View File

@ -0,0 +1,51 @@
---
# playbook.yml - Ansible playbook for Arch Linux development environment setup
- name: Arch Linux Development Environment Setup
hosts: localhost
gather_facts: true
connection: local
become: true
vars:
USE_STARSHIP: true
USE_P10K: false
USE_ALACRITTY: false
INSTALL_CUSTOM_APPS: false
INSTALL_CLAUDE_CODE: true # Install Claude Code CLI
username: "{{ lookup('env', 'USER') }}"
user_home: "/home/{{ username }}"
git_server_port: 3000
install_tiling_wm: true # Set to false if you don't want a tiling WM
tiling_wm: "i3-gaps" # Options: i3-gaps, sway, awesome, qtile, bspwm
home: "{{ user_home }}"
user: "{{ username }}"
# DISPLAY: "{{ ansible_env.DISPLAY | default('') }}"
# XDG_CONFIG_HOME: "{{ ansible_env.XDG_CONFIG_HOME | default(user_home + '/.config') }}"
# XDG_DATA_HOME: "{{ ansible_env.XDG_DATA_HOME | default(user_home + '/.local/share') }}"
# PATH: "{{ ansible_env.PATH }}"
roles:
- role: custom
tags:
- custom
- base_setup
- role: manage_zsh
tags:
- manage_zsh
- base_setup
- role: starship
when: USE_STARSHIP
tags:
- starship
- base_setup
- role: geerlingguy.docker
become: true
tags:
- docker
- base_setup
- role: claude_code
when: INSTALL_CLAUDE_CODE
tags:
- claude_code
- dev_tools
- base_setup

View File

@ -0,0 +1,11 @@
[project]
name = "arch-custom"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
"ansible>=11.6.0",
"ansible-lint>=25.4.0",
"yamllint>=1.37.1",
]

View File

@ -0,0 +1,5 @@
---
# ansible-galaxy install -r requirements.yml
roles:
- name: geerlingguy.docker
version: 7.3.0

View File

@ -0,0 +1,90 @@
---
- name: Claude_code | Install Node.js and npm
community.general.pacman:
name:
- nodejs
- npm
state: present
- name: Claude_code | Check if Claude Code is already installed
ansible.builtin.command: npm list -g @anthropic-ai/claude-code
register: claude_installed
changed_when: false
failed_when: false
become: true
become_user: "{{ ansible_user_id }}"
- name: Claude_code | Install Claude Code globally
ansible.builtin.command: npm install -g @anthropic-ai/claude-code
become: true
become_user: "{{ ansible_user_id }}"
when: claude_installed.rc != 0
register: claude_install_result
changed_when: claude_install_result.rc == 0
- name: Claude_code | Update Claude Code if already installed
ansible.builtin.command: npm update -g @anthropic-ai/claude-code
become: true
become_user: "{{ ansible_user_id }}"
when: claude_installed.rc == 0
register: claude_update_result
changed_when: "'up to date' not in claude_update_result.stdout"
- name: Claude_code | Get npm global bin path
ansible.builtin.command: npm config get prefix
register: npm_prefix
changed_when: false
become: true
become_user: "{{ ansible_user_id }}"
- name: Claude_code | Set npm bin path fact
ansible.builtin.set_fact:
npm_bin_path: "{{ npm_prefix.stdout }}/bin"
- name: Claude_code | Add npm global bin to PATH in .zshrc
ansible.builtin.lineinfile:
path: "{{ user_home }}/.zshrc"
line: 'export PATH="{{ npm_bin_path }}:$PATH"'
regexp: '^export PATH=.*npm.*bin'
state: present
create: false
become: true
become_user: "{{ ansible_user_id }}"
# when:
# - ansible_env.SHELL is defined
# - ansible_env.SHELL | regex_search('zsh')
# - name: Claude_code | Add npm global bin to PATH in .bashrc
# ansible.builtin.lineinfile:
# path: "{{ user_home }}/.bashrc"
# line: 'export PATH="{{ npm_bin_path }}:$PATH"'
# regexp: '^export PATH=.*npm.*bin'
# state: present
# create: false
# become: true
# become_user: "{{ ansible_user_id }}"
# when:
# - ansible_env.SHELL is defined
# - ansible_env.SHELL | regex_search('bash')
- name: Claude_code | Verify installation
ansible.builtin.command: "{{ npm_bin_path }}/claude --version"
register: claude_version
changed_when: false
become: true
become_user: "{{ ansible_user_id }}"
- name: Claude_code | Display installation info
ansible.builtin.debug:
msg:
- "✓ Claude Code installed successfully!"
- "Version: {{ claude_version.stdout }}"
- "Location: {{ npm_bin_path }}/claude"
- ""
- "Next steps:"
- "1. Restart your terminal or run: source ~/.zshrc"
- "2. Run 'claude' to start using Claude Code"
- "3. Set ANTHROPIC_API_KEY environment variable if not already set:"
- " export ANTHROPIC_API_KEY='your-api-key-here'"
- ""
- "For more info: https://docs.claude.com/claude-code"

View File

@ -0,0 +1,55 @@
# Performance
env:
TERM: xterm-256color
# Appearance
window:
padding:
x: 10
y: 10
dynamic_padding: true
decorations: full
opacity: 0.95 # Slight transparency
# Font configuration
font:
normal:
family: FiraCode Nerd Font
style: Regular
bold:
style: Bold
italic:
style: Italic
size: 12.0
offset:
x: 0
y: 0
glyph_offset:
x: 0
y: 0
use_thin_strokes: true
# Colors (Dracula theme)
colors:
primary:
background: '#282a36'
foreground: '#f8f8f2'
cursor:
text: '#44475a'
cursor: '#f8f8f2'
selection:
text: '#f8f8f2'
background: '#44475a'
# Shell integration
shell:
program: /bin/zsh
# Keybindings for productivity
key_bindings:
- { key: V, mods: Control|Shift, action: Paste }
- { key: C, mods: Control|Shift, action: Copy }
- { key: N, mods: Control|Shift, action: SpawnNewInstance }
- { key: Key0, mods: Control, action: ResetFontSize }
- { key: Plus, mods: Control, action: IncreaseFontSize }
- { key: Minus, mods: Control, action: DecreaseFontSize }

View File

@ -0,0 +1,18 @@
# Syntax highlighting (many languages supported)
include /usr/share/nano/*.nanorc
# Custom colors
set titlecolor brightwhite,blue
set statuscolor brightwhite,green
set errorcolor brightwhite,red
set selectedcolor brightwhite,magenta
set numbercolor cyan
set keycolor cyan
set functioncolor green
# Quality of life
set linenumbers
set mouse
set smooth
set tabsize 4
set tabstospaces

View File

@ -0,0 +1,63 @@
set -sa terminal-overrides ",xterm*:Tc"
set -g default-shell /usr/bin/zsh
set -g mouse on
set -g base-index 1
setw -g pane-base-index 1
set -g renumber-windows on
set -sg escape-time 0
set -g history-limit 50000
unbind C-b
set -g prefix C-Space
bind C-Space send-prefix
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
unbind '"'
unbind %
bind r source-file ~/.config/tmux/tmux.conf \; display "Config reloaded!"
bind -r h select-pane -L
bind -r j select-pane -D
bind -r k select-pane -U
bind -r l select-pane -R
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
setw -g mode-keys vi
bind -T copy-mode-vi v send -X begin-selection
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "xclip -in -selection clipboard"
set -g status-position top
set -g status-justify left
set -g status-style 'bg=#1e1e2e fg=#cdd6f4'
set -g status-left '#[fg=#89b4fa,bg=#313244,bold] #S '
set -g status-right '#[fg=#f9e2af,bg=#313244] #(cd #{pane_current_path}; git rev-parse --abbrev-ref HEAD 2>/dev/null) #[fg=#a6e3a1,bg=#313244] #H #[fg=#f5c2e7,bg=#313244] #{b:pane_current_path} '
set -g status-right-length 100
set -g status-left-length 20
setw -g window-status-current-style 'fg=#1e1e2e bg=#89b4fa bold'
setw -g window-status-current-format ' #I#[fg=#1e1e2e]:#[fg=#1e1e2e]#W#[fg=#f9e2af]#F '
setw -g window-status-style 'fg=#cdd6f4 bg=#313244'
setw -g window-status-format ' #I#[fg=#cdd6f4]:#[fg=#cdd6f4]#W#[fg=#6c7086]#F '
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible'
set -g @plugin 'tmux-plugins/tmux-yank'
set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-continuum'
set -g @resurrect-strategy-nvim 'session'
set -g @continuum-restore 'on'
run '~/.config/tmux/plugins/tpm/tpm'

View File

@ -0,0 +1,38 @@
---
- name: Install PyCharm Professional
become: false
community.general.pacman:
name: pycharm-professional
state: present
executable: yay
extra_args: "--builddir /tmp/yay"
- name: Install R (optional)
community.general.pacman:
name:
- r
state: present
- name: Install RStudio (optional)
become: false
community.general.pacman:
name: rstudio-desktop-bin
state: present
executable: yay
extra_args: "--builddir /tmp/yay"
- name: Install database tools
community.general.pacman:
name:
- postgresql
- mariadb
state: present
# Uncomment to install mongodb from AUR
# - name: Install mongodb
# community.general.pacman:
# name: mongodb
# state: present
# executable: yay
# extra_args: "--builddir /tmp/yay"
# become: false

View File

@ -0,0 +1,199 @@
- name: Debug user variables
ansible.builtin.debug:
msg:
- "ansible_user_id: {{ ansible_user_id | default('NOT SET') }}"
- "ansible_env.USER: {{ ansible_env.USER | default('NOT SET') }}"
- "Current user from whoami: {{ ansible_facts['user_id'] | default('NOT SET') }}"
- " username {{ username }}"
- " userhome {{ user_home }}"
- name: Update system packages
community.general.pacman:
update_cache: true
upgrade: true
- name: Install development essentials
community.general.pacman:
name:
- fish
- base-devel
- git
- curl
- wget
- openssh
- python
- python-pip
- hyprland
- tmux
state: present
- name: Add nano settings
become: true
become_user: "{{ ansible_user_id }}"
ansible.builtin.copy:
content: nanorc
path: "{{ user_home }}/.nanorc"
state: directory
mode: '0644'
- name: Check if yay is installed
ansible.builtin.command: which yay
register: yay_installed
changed_when: false
failed_when: false
- name: Install yay (AUR helper)
when: yay_installed.rc != 0
become: false
block:
- name: Clone yay repository
ansible.builtin.git:
repo: https://aur.archlinux.org/yay.git
dest: "{{ user_home }}/yay"
clone: true
update: false
- name: Build and install yay
ansible.builtin.shell: |
cd "{{ user_home }}/yay" && makepkg -si --noconfirm
args:
chdir: "{{ user_home }}/yay"
register: yay_build_result
changed_when: yay_build_result.rc == 0
failed_when: yay_build_result.rc != 0
- name: Clean up yay build directory
ansible.builtin.file:
path: "{{ user_home }}/yay"
state: absent
- name: Install UV package manager
become: true
become_user: "{{ ansible_user_id }}"
ansible.builtin.command: yay -S --noconfirm uv
register: uv_result
changed_when: uv_result.rc == 0
failed_when: uv_result.rc != 0 and 'error' in uv_result.stderr
- name: Create UV config directory
become: true
become_user: "{{ ansible_user_id }}"
ansible.builtin.file:
path: "{{ user_home }}/.config/uv"
state: directory
mode: '0755'
- name: Check if hyprland starter is already cloned
become: true
become_user: "{{ ansible_user_id }}"
ansible.builtin.stat:
path: "{{ user_home }}/hyprland-started"
register: hyprland_starter_dir
- name: Install hyprland starter
become: true
become_user: "{{ ansible_user_id }}"
ansible.builtin.git:
repo: https://github.com/mylinuxforwork/hyprland-starter
dest: "{{ user_home }}/hyprland-started"
depth: 1
when: not hyprland_starter_dir.stat.exists
- name: Install tiling window manager
when: install_tiling_wm
community.general.pacman:
name:
# - "{{ tiling_wm }}"
- rofi
- dunst
- picom
- feh
- sxhkd
- lxappearance
- i3status
- dmenu
- i3lock
state: present
- name: Install productivity tools
community.general.pacman:
name:
- flameshot
- meld
- zeal
- tmux
- btop
- ranger
- timeshift
- syncthing
- keepassxc
state: present
- name: Install additional fonts
community.general.pacman:
name:
- ttf-dejavu
- ttf-liberation
- noto-fonts
- noto-fonts-emoji
state: present
- name: Check for NVIDIA GPU
ansible.builtin.shell: lspci | grep -i nvidia
register: has_nvidia
changed_when: false
failed_when: false
- name: Install NVIDIA CUDA support
when: has_nvidia.rc == 0
community.general.pacman:
name:
- cuda
- cudnn
state: present
# - name: Create project directories
# ansible.builtin.file:
# path: "{{ user_home }}/Projects/{{ item }}"
# state: directory
# mode: '0755'
# loop:
# - llm-dev
# - app-dev
# - data-analysis
# become: false
- name: Include custom apps tasks
ansible.builtin.include_tasks:
file: capps.yml
when: INSTALL_CUSTOM_APPS
- name: Include terms tasks
ansible.builtin.include_tasks:
file: terminals.yml
- name: Display completion message
ansible.builtin.debug:
msg: |
Development environment setup complete!
Access your local Git server at: http://localhost:{{ git_server_port }}
Remember to log out and back in for the docker group changes to take effect.
Python environments were not created as requested - use the following commands to set them up:
cd ~/projects/llm-dev
uv venv
source .venv/bin/activate
uv pip install torch transformers datasets huggingface_hub
Shells setup:
- ZSH with Powerlevel10k theme is installed
- Fish shell is also available, switch to it by typing 'fish'
Terminal:
- Alacritty has been configured as your terminal emulator
{% if install_tiling_wm %}
Window Manager:
- {{ tiling_wm }} has been installed as your tiling window manager
{% endif %}

View File

@ -0,0 +1,83 @@
- name: Install Alacritty terminal
community.general.pacman:
name:
- alacritty
state: present
- name: Create Alacritty config directory
become: true
become_user: "{{ ansible_user_id }}"
ansible.builtin.file:
path: "{{ user_home }}/.config/alacritty"
state: directory
mode: '0755'
- name: Install Nerd Font for Alacritty
become: true
become_user: "{{ ansible_user_id }}"
ansible.builtin.command: yay -S --noconfirm ttf-firacode-nerd
register: font_result
changed_when: font_result.rc == 0
failed_when: font_result.rc != 0 and 'error' in font_result.stderr
- name: Configure Alacritty
become: true
become_user: "{{ ansible_user_id }}"
ansible.builtin.copy:
content: alacritty.yml
dest: "{{ user_home }}/.config/alacritty/alacritty.yml"
mode: '0644'
- name: Set Alacritty as default terminal
become: true
become_user: "{{ ansible_user_id }}"
ansible.builtin.command: xdg-mime default alacritty.desktop x-scheme-handler/terminal
changed_when: false
failed_when: false
when: USE_ALACRITTY
- name: Install TMUX terminal
community.general.pacman:
name:
- tmux
state: present
- name: Create TMUX config directory
become: true
become_user: "{{ ansible_user_id }}"
ansible.builtin.file:
path: "{{ user_home }}/.config/tmux"
state: directory
mode: '0755'
- name: Configure TMUX
become: true
become_user: "{{ ansible_user_id }}"
ansible.builtin.copy:
content: tmux.conf
dest: "{{ user_home }}/.config/tmux/tmux.conf"
mode: '0644'
- name: Create tmux plugins directory
ansible.builtin.file:
path: "{{ user_home }}/.config/tmux/plugins"
state: directory
mode: '0755'
- name: Clone TPM (Tmux Plugin Manager)
ansible.builtin.git:
repo: https://github.com/tmux-plugins/tpm
dest: "{{ user_home }}/.config/tmux/plugins/tpm"
version: master
update: true
- name: Display next steps
ansible.builtin.debug:
msg:
- "✓ Tmux installed successfully"
- "✓ TPM installed to {{ user_home }}/.config/tmux/plugins/tpm"
- "✓ Config copied to {{ user_home }}/.config/tmux/tmux.conf"
- ""
- "Next steps:"
- "1. Start tmux: tmux"
- "2. Install plugins: Press Ctrl+Space + I (capital I)"
- "3. Or run: {{ user_home }}/.config/tmux/plugins/tpm/bin/install_plugins"

View File

@ -0,0 +1,4 @@
skip_list:
- 'yaml'
- 'risky-shell-pipe'
- 'role-name'

View File

@ -0,0 +1,4 @@
# These are supported funding model platforms
---
github: geerlingguy
patreon: geerlingguy

View File

@ -0,0 +1,71 @@
---
name: CI
'on':
pull_request:
push:
branches:
- master
schedule:
- cron: "0 7 * * 0"
defaults:
run:
working-directory: 'geerlingguy.docker'
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- name: Check out the codebase.
uses: actions/checkout@v4
with:
path: 'geerlingguy.docker'
- name: Set up Python 3.
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install test dependencies.
run: pip3 install yamllint
- name: Lint code.
run: |
yamllint .
molecule:
name: Molecule
runs-on: ubuntu-latest
strategy:
matrix:
distro:
- rockylinux9
- ubuntu2404
- ubuntu2204
- debian12
- debian11
- fedora40
- opensuseleap15
steps:
- name: Check out the codebase.
uses: actions/checkout@v4
with:
path: 'geerlingguy.docker'
- name: Set up Python 3.
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install test dependencies.
run: pip3 install ansible molecule molecule-plugins[docker] docker
- name: Run Molecule tests.
run: molecule test
env:
PY_COLORS: '1'
ANSIBLE_FORCE_COLOR: '1'
MOLECULE_DISTRO: ${{ matrix.distro }}

View File

@ -0,0 +1,40 @@
---
# This workflow requires a GALAXY_API_KEY secret present in the GitHub
# repository or organization.
#
# See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy
# See: https://github.com/ansible/galaxy/issues/46
name: Release
'on':
push:
tags:
- '*'
defaults:
run:
working-directory: 'geerlingguy.docker'
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Check out the codebase.
uses: actions/checkout@v4
with:
path: 'geerlingguy.docker'
- name: Set up Python 3.
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install Ansible.
run: pip3 install ansible-core
- name: Trigger a new import on Galaxy.
run: >-
ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }}
$(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2)

View File

@ -0,0 +1,34 @@
---
name: Close inactive issues
'on':
schedule:
- cron: "55 6 * * 1" # semi-random time
jobs:
close-issues:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v8
with:
days-before-stale: 120
days-before-close: 60
exempt-issue-labels: bug,pinned,security,planned
exempt-pr-labels: bug,pinned,security,planned
stale-issue-label: "stale"
stale-pr-label: "stale"
stale-issue-message: |
This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution!
Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale.
close-issue-message: |
This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details.
stale-pr-message: |
This pr has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution!
Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale.
close-pr-message: |
This pr has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details.
repo-token: ${{ secrets.GITHUB_TOKEN }}

View File

@ -0,0 +1,5 @@
*.retry
*/__pycache__
*.pyc
.cache

View File

@ -0,0 +1,10 @@
---
extends: default
rules:
line-length:
max: 200
level: warning
ignore: |
.github/workflows/stale.yml

View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2017 Jeff Geerling
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,173 @@
# Ansible Role: Docker
[![CI](https://github.com/geerlingguy/ansible-role-docker/actions/workflows/ci.yml/badge.svg)](https://github.com/geerlingguy/ansible-role-docker/actions/workflows/ci.yml)
An Ansible Role that installs [Docker](https://www.docker.com) on Linux.
## Requirements
None.
## Role Variables
Available variables are listed below, along with default values (see `defaults/main.yml`):
```yaml
# Edition can be one of: 'ce' (Community Edition) or 'ee' (Enterprise Edition).
docker_edition: 'ce'
docker_packages:
- "docker-{{ docker_edition }}"
- "docker-{{ docker_edition }}-cli"
- "docker-{{ docker_edition }}-rootless-extras"
docker_packages_state: present
```
The `docker_edition` should be either `ce` (Community Edition) or `ee` (Enterprise Edition).
You can also specify a specific version of Docker to install using the distribution-specific format:
Red Hat/CentOS: `docker-{{ docker_edition }}-<VERSION>` (Note: you have to add this to all packages);
Debian/Ubuntu: `docker-{{ docker_edition }}=<VERSION>` (Note: you have to add this to all packages).
You can control whether the package is installed, uninstalled, or at the latest version by setting `docker_packages_state` to `present`, `absent`, or `latest`, respectively. Note that the Docker daemon will be automatically restarted if the Docker package is updated. This is a side effect of flushing all handlers (running any of the handlers that have been notified by this and any other role up to this point in the play).
```yaml
docker_obsolete_packages:
- docker
- docker.io
- docker-engine
- docker-doc
- docker-compose
- docker-compose-v2
- podman-docker
- containerd
- runc
```
`docker_obsolete_packages` for different os-family:
- [`RedHat.yaml`](./vars/RedHat.yml)
- [`Debian.yaml`](./vars/Debian.yml)
- [`Suse.yaml`](./vars/Suse.yml)
A list of packages to be uninstalled prior to running this role. See [Docker's installation instructions](https://docs.docker.com/engine/install/debian/#uninstall-old-versions) for an up-to-date list of old packages that should be removed.
```yaml
docker_service_manage: true
docker_service_state: started
docker_service_enabled: true
docker_service_start_command: ""
docker_restart_handler_state: restarted
```
Variables to control the state of the `docker` service, and whether it should start on boot. If you're installing Docker inside a Docker container without systemd or sysvinit, you should set `docker_service_manage` to `false`.
```yaml
docker_install_compose_plugin: true
docker_compose_package: docker-compose-plugin
docker_compose_package_state: present
```
Docker Compose Plugin installation options. These differ from the below in that docker-compose is installed as a docker plugin (and used with `docker compose`) instead of a standalone binary.
```yaml
docker_install_compose: false
docker_compose_version: "v2.32.1"
docker_compose_arch: "{{ ansible_facts.architecture }}"
docker_compose_url: "https://github.com/docker/compose/releases/download/{{ docker_compose_version }}/docker-compose-linux-{{ docker_compose_arch }}"
docker_compose_path: /usr/local/bin/docker-compose
```
Docker Compose installation options.
```yaml
docker_add_repo: true
```
Controls whether this role will add the official Docker repository. Set to `false` if you want to use the default docker packages for your system or manage the package repository on your own.
```yaml
docker_repo_url: https://download.docker.com/linux
```
The main Docker repo URL, common between Debian and RHEL systems.
```yaml
docker_apt_release_channel: stable
docker_apt_gpg_key: "{{ docker_repo_url }}/{{ ansible_facts.distribution | lower }}/gpg"
docker_apt_filename: "docker"
```
(Used only for Debian/Ubuntu.) You can switch the channel to `nightly` if you want to use the Nightly release.
You can change `docker_apt_gpg_key` to a different url if you are behind a firewall or provide a trustworthy mirror.
`docker_apt_filename` controls the name of the source list file created in `sources.list.d`. If you are upgrading from an older (<7.0.0) version of this role, you should change this to the name of the existing file (e.g. `download_docker_com_linux_debian` on Debian) to avoid conflicting lists.
```yaml
docker_yum_repo_url: "{{ docker_repo_url }}/{{ 'fedora' if ansible_facts.distribution == 'Fedora' else 'rhel' if ansible_facts.distribution == 'RedHat' else 'centos' }}/docker-{{ docker_edition }}.repo"
docker_yum_repo_enable_nightly: '0'
docker_yum_repo_enable_test: '0'
docker_yum_gpg_key: "{{ docker_repo_url }}/{{ 'fedora' if ansible_facts.distribution == 'Fedora' else 'rhel' if ansible_facts.distribution == 'RedHat' else 'centos' }}/gpg"
```
(Used only for RedHat/CentOS.) You can enable the Nightly or Test repo by setting the respective vars to `1`.
You can change `docker_yum_gpg_key` to a different url if you are behind a firewall or provide a trustworthy mirror.
Usually in combination with changing `docker_yum_repository` as well.
```yaml
docker_users:
- user1
- user2
```
A list of system users to be added to the `docker` group (so they can use Docker on the server).
```yaml
docker_daemon_options:
storage-driver: "overlay2"
log-opts:
max-size: "100m"
```
Custom `dockerd` options can be configured through this dictionary representing the json file `/etc/docker/daemon.json`.
## Use with Ansible (and `docker` Python library)
Many users of this role wish to also use Ansible to then _build_ Docker images and manage Docker containers on the server where Docker is installed. In this case, you can easily add in the `docker` Python library using the `geerlingguy.pip` role:
```yaml
- hosts: all
vars:
pip_install_packages:
- name: docker
roles:
- geerlingguy.pip
- geerlingguy.docker
```
## Dependencies
None.
## Example Playbook
```yaml
- hosts: all
roles:
- geerlingguy.docker
```
## License
MIT / BSD
## Sponsors
* [We Manage](https://we-manage.de): Helping start-ups and grown-ups scaling their infrastructure in a sustainable way.
The above sponsor(s) are supporting Jeff Geerling on [GitHub Sponsors](https://github.com/sponsors/geerlingguy). You can sponsor Jeff's work too, to help him continue improving these Ansible open source projects!
## Author Information
This role was created in 2017 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/).

View File

@ -0,0 +1,65 @@
---
# Edition can be one of: 'ce' (Community Edition) or 'ee' (Enterprise Edition).
docker_edition: 'ce'
docker_packages:
- "docker-{{ docker_edition }}"
- "docker-{{ docker_edition }}-cli"
- "docker-{{ docker_edition }}-rootless-extras"
- "containerd.io"
- docker-buildx-plugin
docker_packages_state: present
docker_obsolete_packages:
- docker
- docker.io
- docker-engine
- docker-doc
- docker-compose
- docker-compose-v2
- podman-docker
- containerd
- runc
# Service options.
docker_service_manage: true
docker_service_state: started
docker_service_enabled: true
docker_service_start_command: ""
docker_restart_handler_state: restarted
# Docker Compose Plugin options.
docker_install_compose_plugin: true
docker_compose_package: docker-compose-plugin
docker_compose_package_state: present
# Docker Compose options.
docker_install_compose: false
docker_compose_version: "v2.32.1"
docker_compose_arch: "{{ ansible_facts.architecture }}"
docker_compose_url: "https://github.com/docker/compose/releases/download/{{ docker_compose_version }}/docker-compose-linux-{{ docker_compose_arch }}"
docker_compose_path: /usr/local/bin/docker-compose
# Enable repo setup
docker_add_repo: true
# Docker repo URL.
docker_repo_url: https://download.docker.com/linux
# Used only for Debian/Ubuntu/Pop!_OS/Linux Mint. Switch 'stable' to 'nightly' if needed.
docker_apt_release_channel: stable
# docker_apt_ansible_distribution is a workaround for Ubuntu variants which can't be identified as such by Ansible,
# and is only necessary until Docker officially supports them.
docker_apt_ansible_distribution: "{{ 'ubuntu' if ansible_facts.distribution in ['Pop!_OS', 'Linux Mint'] else ansible_facts.distribution }}"
docker_apt_gpg_key: "{{ docker_repo_url }}/{{ docker_apt_ansible_distribution | lower }}/gpg"
docker_apt_filename: "docker"
# Used only for RedHat/CentOS/Fedora.
docker_yum_repo_url: "{{ docker_repo_url }}/{{ 'fedora' if ansible_facts.distribution == 'Fedora' else 'rhel' if ansible_facts.distribution == 'RedHat' else 'centos' }}/docker-{{ docker_edition }}.repo"
docker_yum_repo_enable_nightly: '0'
docker_yum_repo_enable_test: '0'
docker_yum_gpg_key: "{{ docker_repo_url }}/{{ 'fedora' if ansible_facts.distribution == 'Fedora' else 'rhel' if ansible_facts.distribution == 'RedHat' else 'centos' }}/gpg"
# A list of users who will be added to the docker group.
docker_users: []
# Docker daemon options as a dict
docker_daemon_options: {}

View File

@ -0,0 +1,11 @@
---
- name: restart docker
ansible.builtin.service:
name: docker
state: "{{ docker_restart_handler_state }}"
ignore_errors: "{{ ansible_check_mode }}"
when: docker_service_manage | bool
- name: apt update
ansible.builtin.apt:
update_cache: true

View File

@ -0,0 +1,2 @@
install_date: 'Sun 16 Nov 2025 01:12:02 AM '
version: 7.8.0

View File

@ -0,0 +1,46 @@
---
dependencies: []
galaxy_info:
role_name: docker
author: geerlingguy
description: Docker for Linux.
company: "Midwestern Mac, LLC"
license: "license (BSD, MIT)"
min_ansible_version: 2.15.1
platforms:
- name: Fedora
versions:
- all
- name: Debian
versions:
- buster
- bullseye
- bookworm
- trixie
- name: Ubuntu
versions:
- bionic
- focal
- jammy
- noble
- name: Alpine
version:
- all
- name: ArchLinux
versions:
- all
- name: SLES
versions:
- all
- name: openSUSE
versions:
- all
galaxy_tags:
- web
- system
- containers
- docker
- orchestration
- compose
- server

View File

@ -0,0 +1,24 @@
---
- name: Converge
hosts: all
# become: true
pre_tasks:
- name: Update apt cache.
apt: update_cache=yes cache_valid_time=600
when: ansible_facts.os_family == 'Debian'
- name: Wait for systemd to complete initialization. # noqa 303
command: systemctl is-system-running
register: systemctl_status
until: >
'running' in systemctl_status.stdout or
'degraded' in systemctl_status.stdout
retries: 30
delay: 5
when: ansible_facts.service_mgr == 'systemd'
changed_when: false
failed_when: systemctl_status.rc > 1
roles:
- role: geerlingguy.docker

View File

@ -0,0 +1,21 @@
---
role_name_check: 1
dependency:
name: galaxy
options:
ignore-errors: true
driver:
name: docker
platforms:
- name: instance
image: "geerlingguy/docker-${MOLECULE_DISTRO:-rockylinux9}-ansible:latest"
command: ${MOLECULE_DOCKER_COMMAND:-""}
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
cgroupns_mode: host
privileged: true
pre_build_image: true
provisioner:
name: ansible
playbooks:
converge: ${MOLECULE_PLAYBOOK:-converge.yml}

View File

@ -0,0 +1,51 @@
---
- name: Verify Docker Role
hosts: all
tasks:
- name: Verify Docker binary is available
command: docker version
register: docker_version_result
changed_when: false
failed_when: docker_version_result.rc != 0
- name: Show Docker version details
debug:
msg: >
Docker Version Output:
{{ docker_version_result.stdout_lines | join('\n') }}
- name: Verify Docker service is running
command: systemctl is-active docker
register: docker_service_status
when: ansible_facts.service_mgr == 'systemd'
changed_when: false
failed_when: docker_service_status.stdout.strip() != "active"
- name: Display Docker service status
debug:
msg: "Docker service is {{ docker_service_status.stdout.strip() }}"
when: ansible_facts.service_mgr == 'systemd'
- name: Pull the 'hello-world' image
command: docker pull hello-world
register: docker_pull_result
changed_when: true
failed_when: docker_pull_result.rc != 0
- name: Show result of pulling the 'hello-world' image
debug:
msg: >
Pulling 'hello-world' completed with output:
{{ docker_pull_result.stdout_lines | join('\n') }}
- name: Run a test container (hello-world)
command: docker run --rm hello-world
register: docker_run_result
changed_when: true
failed_when: docker_run_result.rc != 0
- name: Display test container output
debug:
msg: >
Running 'hello-world' container completed with output:
{{ docker_run_result.stdout_lines | join('\n') }}

View File

@ -0,0 +1,31 @@
---
- name: Check current docker-compose version.
command: "{{ docker_compose_path }} --version"
register: docker_compose_vsn
check_mode: false
changed_when: false
failed_when: false
- set_fact:
docker_compose_current_version: "{{ docker_compose_vsn.stdout | regex_search('(\\d+(\\.\\d+)+)') }}"
when: >
docker_compose_vsn.stdout is defined
and (docker_compose_vsn.stdout | length > 0)
- name: Delete existing docker-compose version if it's different.
file:
path: "{{ docker_compose_path }}"
state: absent
when: >
docker_compose_current_version is defined
and (docker_compose_version | regex_replace('v', '')) not in docker_compose_current_version
- name: Install Docker Compose (if configured).
get_url:
url: "{{ docker_compose_url }}"
dest: "{{ docker_compose_path }}"
mode: 0755
when: >
(docker_compose_current_version is not defined)
or (docker_compose_current_version | length == 0)
or (docker_compose_current_version is version((docker_compose_version | regex_replace('v', '')), '<'))

View File

@ -0,0 +1,10 @@
---
- name: Ensure docker users are added to the docker group.
user:
name: "{{ item }}"
groups: docker
append: true
with_items: "{{ docker_users }}"
- name: Reset ssh connection to apply user changes.
meta: reset_connection

View File

@ -0,0 +1,122 @@
---
- name: Load OS-specific vars.
include_vars: "{{ lookup('first_found', params) }}"
vars:
params:
files:
- '{{ansible_facts.distribution}}.yml'
- '{{ansible_facts.os_family}}.yml'
- main.yml
paths:
- 'vars'
- include_tasks: setup-RedHat.yml
when: ansible_facts.os_family == 'RedHat'
- include_tasks: setup-Suse.yml
when: ansible_facts.os_family == 'Suse'
- include_tasks: setup-Debian.yml
when: ansible_facts.os_family == 'Debian'
- name: Install Docker packages.
package:
name: "{{ docker_packages }}"
state: "{{ docker_packages_state }}"
notify: restart docker
ignore_errors: "{{ ansible_check_mode }}"
when: "ansible_version.full is version_compare('2.12', '<') or ansible_facts.os_family not in ['RedHat', 'Debian']"
- name: Install Docker packages (with downgrade option).
package:
name: "{{ docker_packages }}"
state: "{{ docker_packages_state }}"
allow_downgrade: true
notify: restart docker
ignore_errors: "{{ ansible_check_mode }}"
when: "ansible_version.full is version_compare('2.12', '>=') and ansible_facts.os_family in ['RedHat', 'Debian']"
- name: Install docker-compose plugin.
package:
name: "{{ docker_compose_package }}"
state: "{{ docker_compose_package_state }}"
notify: restart docker
ignore_errors: "{{ ansible_check_mode }}"
when: "docker_install_compose_plugin | bool == true and (ansible_version.full is version_compare('2.12', '<') or ansible_facts.os_family not in ['RedHat', 'Debian', 'Suse'])"
- name: Install docker-compose-plugin (with downgrade option).
package:
name: "{{ docker_compose_package }}"
state: "{{ docker_compose_package_state }}"
allow_downgrade: true
notify: restart docker
ignore_errors: "{{ ansible_check_mode }}"
when: "docker_install_compose_plugin | bool == true and ansible_version.full is version_compare('2.12', '>=') and ansible_facts.os_family in ['RedHat', 'Debian']"
- name: Ensure /etc/docker/ directory exists.
file:
path: /etc/docker
state: directory
mode: 0755
when: docker_daemon_options.keys() | length > 0
- name: Configure Docker daemon options.
copy:
content: "{{ docker_daemon_options | to_nice_json }}"
dest: /etc/docker/daemon.json
mode: 0644
when: docker_daemon_options.keys() | length > 0
notify: restart docker
- name: Replace Docker service ExecStart command if configured.
when: docker_service_start_command != ""
notify: restart docker
block:
- name: Get Docker service status
ansible.builtin.systemd_service:
name: docker
register: docker_service_status
- name: Patch docker.service
ansible.builtin.replace:
path: "{{ docker_service_status.status['FragmentPath'] }}"
regexp: "^ExecStart=.*$"
replace: "ExecStart={{ docker_service_start_command }}"
register: docker_service_patch
- name: Reload systemd services
service:
daemon_reload: true
when: docker_service_patch is changed
- name: Ensure Docker is started and enabled at boot.
service:
name: docker
state: "{{ docker_service_state }}"
enabled: "{{ docker_service_enabled }}"
ignore_errors: "{{ ansible_check_mode }}"
when: docker_service_manage | bool
- name: Ensure handlers are notified now to avoid firewall conflicts.
meta: flush_handlers
- include_tasks: docker-compose.yml
when: docker_install_compose | bool
- name: Get docker group info using getent.
getent:
database: group
key: docker
split: ':'
when: docker_users | length > 0
- name: Check if there are any users to add to the docker group.
set_fact:
at_least_one_user_to_modify: true
when:
- docker_users | length > 0
- item not in ansible_facts.getent_group["docker"][2]
with_items: "{{ docker_users }}"
- include_tasks: docker-users.yml
when: at_least_one_user_to_modify is defined

View File

@ -0,0 +1,42 @@
---
- name: Ensure apt key is not present in trusted.gpg.d
ansible.builtin.file:
path: /etc/apt/trusted.gpg.d/docker.asc
state: absent
- name: Ensure old apt source list is not present in /etc/apt/sources.list.d
ansible.builtin.file:
path: "/etc/apt/sources.list.d/download_docker_com_linux_{{ docker_apt_ansible_distribution | lower }}.list"
state: absent
# See https://docs.docker.com/engine/install/debian/#uninstall-old-versions
- name: Ensure old versions of Docker are not installed.
ansible.builtin.package:
name: "{{ docker_obsolete_packages }}"
state: absent
- name: Ensure legacy repo file is not present.
ansible.builtin.file:
path: "/etc/apt/sources.list.d/docker.list"
state: absent
- name: Ensure dependencies are installed.
ansible.builtin.apt:
name:
- ca-certificates
- python3-debian
state: present
- name: Add or remove Docker repository.
ansible.builtin.deb822_repository:
name: "{{ docker_apt_filename }}"
types: deb
uris: "{{ docker_repo_url }}/{{ docker_apt_ansible_distribution | lower }}"
suites: "{{ ansible_facts.distribution_release }}"
components: "{{ docker_apt_release_channel }}"
signed_by: "{{ docker_apt_gpg_key }}"
state: "{{ 'present' if docker_add_repo | bool else 'absent' }}"
notify: apt update
- name: Ensure handlers are notified immediately to update the apt cache.
ansible.builtin.meta: flush_handlers

View File

@ -0,0 +1,58 @@
---
- name: Ensure old versions of Docker are not installed.
package:
name: "{{ docker_obsolete_packages }}"
state: absent
- name: Add Docker GPG key.
rpm_key:
key: "{{ docker_yum_gpg_key }}"
state: present
when: docker_add_repo | bool
- name: Add Docker repository.
get_url:
url: "{{ docker_yum_repo_url }}"
dest: '/etc/yum.repos.d/docker-{{ docker_edition }}.repo'
owner: root
group: root
mode: 0644
when: docker_add_repo | bool
- name: Configure Docker Nightly repo.
ini_file:
dest: '/etc/yum.repos.d/docker-{{ docker_edition }}.repo'
section: 'docker-{{ docker_edition }}-nightly'
option: enabled
value: '{{ docker_yum_repo_enable_nightly }}'
mode: 0644
no_extra_spaces: true
when: docker_add_repo | bool
- name: Configure Docker Test repo.
ini_file:
dest: '/etc/yum.repos.d/docker-{{ docker_edition }}.repo'
section: 'docker-{{ docker_edition }}-test'
option: enabled
value: '{{ docker_yum_repo_enable_test }}'
mode: 0644
no_extra_spaces: true
when: docker_add_repo | bool
- name: Configure containerd on RHEL 8.
block:
- name: Ensure runc is not installed.
package:
name: runc
state: absent
- name: Ensure container-selinux is installed.
package:
name: container-selinux
state: present
- name: Ensure containerd.io is installed.
package:
name: containerd.io
state: present
when: ansible_facts.distribution_major_version | int == 8

View File

@ -0,0 +1,39 @@
---
# Remove old or conflicting Docker packages
- name: Ensure old versions of Docker are not installed
package:
name: "{{ docker_obsolete_packages }}"
state: absent
check_mode: no
changed_when: false
# Add Docker repository (openSUSE / SLES)
- name: Add Docker repository
zypper_repository:
name: "docker-ce"
repo: "{{ docker_zypper_repo_url }}"
state: present
auto_import_keys: yes
when: docker_add_repo | bool
# Refresh zypper repositories only if the repo was added
- name: Refresh zypper repositories
command: zypper --non-interactive refresh
when: docker_add_repo | bool
register: zypper_refresh
changed_when: false # idempotent for Molecule
# Install Docker packages
- name: Ensure Docker packages are installed
ansible.legacy.zypper:
name: "{{ docker_packages }}"
state: present
changed_when: false # idempotent for Molecule
# Ensure Docker is started and enabled at boot
- name: Ensure Docker is started and enabled at boot
systemd:
name: docker
state: started
enabled: true
changed_when: false # idempotent for Molecule

View File

@ -0,0 +1,3 @@
---
docker_packages: "docker"
docker_compose_package: docker-cli-compose

View File

@ -0,0 +1,3 @@
---
docker_packages: "docker"
docker_compose_package: docker-compose

View File

@ -0,0 +1,14 @@
---
# Used only for Debian/Ubuntu (Debian OS-Family)
# https://docs.docker.com/engine/install/debian/#uninstall-old-versions
docker_obsolete_packages:
- docker
- docker.io
- docker-engine
- docker-doc
- docker-compose
- docker-compose-v2
- podman-docker
- containerd
- runc

View File

@ -0,0 +1,14 @@
---
# Used only for Fedora/Rocky (RedHat OS-Family)
# https://docs.docker.com/engine/install/fedora/#uninstall-old-versions
# https://docs.docker.com/engine/install/centos/#uninstall-old-versions
docker_obsolete_packages:
- docker
- docker-client
- docker-client-latest
- docker-common
- docker-latest
- docker-latest-logrotate
- docker-logrotate
- docker-engine

View File

@ -0,0 +1,41 @@
---
# Used only for openSUSE / SLES (SUSE OS-Family)
# https://en.opensuse.org/Docker
# https://docs.docker.com/engine/install/binaries/
# Packages to remove if present (old or conflicting Docker packages)
docker_obsolete_packages:
- docker-engine
- docker.io
- docker-ce
- docker-ce-cli
- docker-buildx-plugin
- docker-ce-rootless-extras
- containerd.io
- runc
# Packages to install on openSUSE / SLES
# Use 'runc' from repo, not 'docker-runc' (avoids conflicts on Leap 15.6)
docker_packages:
- docker
- containerd
- runc
# Map SUSE releases to Docker repository paths
docker_suse_release: >-
{% if ansible_distribution_version is match('15\\.6') %}
openSUSE_Leap_15.6
{% elif ansible_distribution_version is match('15\\.5') %}
openSUSE_Leap_15.5
{% elif ansible_distribution_version is match('15\\.4') %}
openSUSE_Leap_15.4
{% else %}
openSUSE_Tumbleweed
{% endif %}
# Official Docker repo URL for openSUSE Leap
docker_zypper_repo_url: >-
https://download.opensuse.org/repositories/Virtualization:/containers/{{ docker_suse_release | trim }}/
# Control whether to add the Docker repository
docker_add_repo: true

View File

@ -0,0 +1,2 @@
---
# Empty file

View File

@ -0,0 +1,2 @@
---
manage_zsh_user: "{{ user }}"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,125 @@
# Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc.
# Initialization code that may require console input (password prompts, [y/n]
# confirmations, etc.) must go above this block; everything else may go below.
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi
# If you come from bash you might have to change your $PATH.
# export PATH=$HOME/bin:$HOME/.local/bin:/usr/local/bin:$PATH
# Path to your Oh My Zsh installation.
export ZSH="$HOME/.oh-my-zsh"
# Set name of the theme to load --- if set to "random", it will
# load a random theme each time Oh My Zsh is loaded, in which case,
# to know which specific one was loaded, run: echo $RANDOM_THEME
# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes
ZSH_THEME="powerlevel10k/powerlevel10k"
# Set list of themes to pick from when loading at random
# Setting this variable when ZSH_THEME=random will cause zsh to load
# a theme from this variable instead of looking in $ZSH/themes/
# If set to an empty array, this variable will have no effect.
# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" )
# Uncomment the following line to use case-sensitive completion.
# CASE_SENSITIVE="true"
# Uncomment the following line to use hyphen-insensitive completion.
# Case-sensitive completion must be off. _ and - will be interchangeable.
# HYPHEN_INSENSITIVE="true"
# Uncomment one of the following lines to change the auto-update behavior
# zstyle ':omz:update' mode disabled # disable automatic updates
# zstyle ':omz:update' mode auto # update automatically without asking
# zstyle ':omz:update' mode reminder # just remind me to update when it's time
# Uncomment the following line to change how often to auto-update (in days).
# zstyle ':omz:update' frequency 13
# Uncomment the following line if pasting URLs and other text is messed up.
# DISABLE_MAGIC_FUNCTIONS="true"
# Uncomment the following line to disable colors in ls.
# DISABLE_LS_COLORS="true"
# Uncomment the following line to disable auto-setting terminal title.
# DISABLE_AUTO_TITLE="true"
# Uncomment the following line to enable command auto-correction.
# ENABLE_CORRECTION="true"
# Uncomment the following line to display red dots whilst waiting for completion.
# You can also set it to another string to have that shown instead of the default red dots.
# e.g. COMPLETION_WAITING_DOTS="%F{yellow}waiting...%f"
# Caution: this setting can cause issues with multiline prompts in zsh < 5.7.1 (see #5765)
# COMPLETION_WAITING_DOTS="true"
# Uncomment the following line if you want to disable marking untracked files
# under VCS as dirty. This makes repository status check for large repositories
# much, much faster.
# DISABLE_UNTRACKED_FILES_DIRTY="true"
# Uncomment the following line if you want to change the command execution time
# stamp shown in the history command output.
# You can set one of the optional three formats:
# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"
# or set a custom format using the strftime function format specifications,
# see 'man strftime' for details.
# HIST_STAMPS="mm/dd/yyyy"
# Would you like to use another custom folder than $ZSH/custom?
# ZSH_CUSTOM=/path/to/new-custom-folder
# Which plugins would you like to load?
# Standard plugins can be found in $ZSH/plugins/
# Custom plugins may be added to $ZSH_CUSTOM/plugins/
# Example format: plugins=(rails git textmate ruby lighthouse)
# Add wisely, as too many plugins slow down shell startup.
plugins=(git
zsh-autosuggestions)
source $ZSH/oh-my-zsh.sh
# User configuration
# export MANPATH="/usr/local/man:$MANPATH"
# You may need to manually set your language environment
# export LANG=en_US.UTF-8
# Preferred editor for local and remote sessions
# if [[ -n $SSH_CONNECTION ]]; then
# export EDITOR='vim'
# else
# export EDITOR='nvim'
# fi
# Compilation flags
# export ARCHFLAGS="-arch $(uname -m)"
# Set personal aliases, overriding those provided by Oh My Zsh libs,
# plugins, and themes. Aliases can be placed here, though Oh My Zsh
# users are encouraged to define aliases within a top-level file in
# the $ZSH_CUSTOM folder, with .zsh extension. Examples:
# - $ZSH_CUSTOM/aliases.zsh
# - $ZSH_CUSTOM/macos.zsh
# For a full list of active aliases, run `alias`.
#
# Example aliases
# alias zshconfig="mate ~/.zshrc"
# alias ohmyzsh="mate ~/.oh-my-zsh"
# BEGIN ANSIBLE MANAGED BLOCK - Fastfetch aliases
# Aliases for fastfetch
alias fetch='fastfetch'
alias neofetch='fastfetch'
# END ANSIBLE MANAGED BLOCK - Fastfetch aliases
# BEGIN ANSIBLE MANAGED BLOCK - Fastfetch
# Run fastfetch
source ~/.fastfetch.sh
# END ANSIBLE MANAGED BLOCK - Fastfetch
# To customize prompt, run `p10k configure` or edit ~/.p10k.zsh.
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh

View File

@ -0,0 +1,51 @@
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": {
"type": "auto",
"color": {
"1": "magenta",
"2": "blue"
}
},
"display": {
"separator": " ➜ ",
"color": {
"separator": "green",
"keys": "blue",
"title": "magenta"
}
},
"modules": [
{
"type": "title",
"color": {
"user": "magenta",
"at": "white",
"host": "blue"
}
},
"separator",
"os",
"host",
"kernel",
"uptime",
"packages",
"shell",
"terminal",
"de",
"wm",
"theme",
"icons",
"font",
"cursor",
"cpu",
"gpu",
"memory",
"disk",
"localip",
"battery",
"locale",
"break",
"colors"
]
}

View File

@ -0,0 +1,5 @@
---
- name: Manage_zsh | Restart SSH
ansible.builtin.service:
name: ssh
state: restarted

View File

@ -0,0 +1,99 @@
- name: Manage_zsh | Install required packages
community.general.pacman:
name:
- git
- zsh
- powerline
- fastfetch
- zsh-autosuggestions
- zsh-syntax-highlighting
- zsh-completions
# - zsh-transient-prompt
- fzf
state: present
- name: Clone zsh-transient-prompt
ansible.builtin.git:
repo: https://github.com/olets/zsh-transient-prompt.git
dest: "{{ ansible_env.HOME }}/.zsh/zsh-transient-prompt"
version: main
depth: 1
- name: Manage_zsh | Set ZSH as default shell
ansible.builtin.user:
name: "{{ user }}"
shell: /bin/zsh
# - name: Manage_zsh | Setup ZSH
# block:
# - name: Manage_zsh | Copy zsh setting file
# ansible.builtin.copy:
# src: .zshrc
# dest: "/home/{{ user }}/.zshrc"
# mode: '0644'
- name: Manage_zsh | Configure fastfetch motd
block:
- name: Manage_zsh | Become user for fastfetch script
become: true
become_user: "{{ user }}"
block:
- name: Manage_zsh | Create fastfetch script
ansible.builtin.copy:
dest: "/home/{{ user }}/.fastfetch.sh"
mode: '0755'
content: |
#!/bin/bash
if [[ $- == *i* && $TERM_PROGRAM != "vscode" && -z "$FASTFETCH_DISPLAYED" ]]; then
fastfetch
export FASTFETCH_DISPLAYED=1
fi
- name: Copy fastfetch configuration
ansible.builtin.copy:
src: config.jsonc
dest: "{{ ansible_env.HOME }}/.config/fastfetch/config.jsonc"
mode: '0644'
- name: Manage_zsh | Source fastfetch script in .zshrc
ansible.builtin.blockinfile:
path: "/home/{{ user }}/.zshrc"
marker: "# {mark} ANSIBLE MANAGED BLOCK - Fastfetch"
block: |
# Run fastfetch
source ~/.fastfetch.sh
insertafter: "# {mark} ANSIBLE MANAGED BLOCK - Powerlevel10k instant prompt"
- name: Manage_zsh | Source fastfetch script in .zprofile
ansible.builtin.lineinfile:
path: "/home/{{ user }}/.zprofile"
line: 'source ~/.fastfetch.sh'
create: true
mode: '0664'
- name: Manage_zsh | Disable default MOTD
ansible.builtin.file:
path: /etc/motd
state: absent
- name: Manage_zsh | Disable login information in /etc/issue
ansible.builtin.copy:
content: ""
dest: /etc/issue
force: true
mode: '0644'
- name: Manage_zsh | Disable login information in /etc/issue.net
ansible.builtin.copy:
content: ""
dest: /etc/issue.net
force: true
mode: '0644'
- name: Include plugins tasks
ansible.builtin.include_tasks:
file: zsh-plugin.yml
- name: Include p10k tasks
ansible.builtin.include_tasks:
file: zsh-p10k.yml
when: USE_P10K

View File

@ -0,0 +1,76 @@
---
- name: Manage_zsh | Download Oh My ZSH installer
ansible.builtin.get_url:
url: https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh
dest: /tmp/install-ohmyzsh.sh
mode: "0755"
failed_when: false
- name: Manage_zsh | Check if Oh My ZSH is installed
ansible.builtin.stat:
path: /home/{{ user }}/.oh-my-zsh
register: zsh_ohmyzsh_installed
- name: Manage_zsh | Become user for ZSH config
become: true
become_user: "{{ user }}"
block:
- name: Manage_zsh | Run Oh My ZSH installer
ansible.builtin.command:
cmd: /tmp/install-ohmyzsh.sh --unattended
creates: /home/{{ user }}/.oh-my-zsh
- name: Manage_zsh | Install Oh My ZSH plugins
ansible.builtin.git:
repo: "{{ manage_zsh_item.repo }}"
dest: "/home/{{ user }}/.oh-my-zsh/custom/plugins/{{ manage_zsh_item.name }}"
version: master
force: true
loop:
- { name: zsh-autosuggestions, repo: https://github.com/zsh-users/zsh-autosuggestions }
- { name: zsh-syntax-highlighting, repo: https://github.com/zsh-users/zsh-syntax-highlighting }
- { name: fzf-tab, repo: https://github.com/Aloxaf/fzf-tab }
- { name: zsh-completions, repo: https://github.com/zsh-users/zsh-completions }
loop_control:
loop_var: manage_zsh_item
- name: Manage_zsh | Install and configure Powerlevel10k
block:
- name: Manage_zsh | Clone Powerlevel10k
ansible.builtin.git:
repo: https://github.com/romkatv/powerlevel10k
dest: /home/{{ user }}/.oh-my-zsh/custom/themes/powerlevel10k
version: master
force: true
- name: Manage_zsh | Set Powerlevel10k as the default theme
ansible.builtin.lineinfile:
path: /home/{{ user }}/.zshrc
regexp: ^ZSH_THEME=".*"
line: ZSH_THEME="powerlevel10k/powerlevel10k"
state: present
- name: Manage_zsh | Add Powerlevel10k instant prompt to .zshrc
ansible.builtin.blockinfile:
path: /home/{{ user }}/.zshrc
insertbefore: BOF
block: |
# Enable Powerlevel10k instant promptt
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi
- name: Manage_zsh | Copy p10file to home directory
ansible.builtin.copy:
src: ./files/.p10k.zsh
dest: "/home/{{ user }}/.p10k.zsh"
mode: '0644'
- name: Install zsh-theme-powerlevel10k
become: false
community.general.pacman:
name: zsh-theme-powerlevel10k
state: present
executable: yay
extra_args: "--builddir /tmp"
- name: Install zsh-theme-powerlevel10k from AUR
ansible.builtin.command: yay -S --noconfirm --builddir /tmp zsh-theme-powerlevel10k
become: false

View File

@ -0,0 +1,34 @@
---
- name: Create zsh plugin directory
ansible.builtin.file:
path: "{{ user_home }}/.zsh"
state: directory
mode: '0755'
- name: Clone zsh-autosuggestions
ansible.builtin.git:
repo: https://github.com/zsh-users/zsh-autosuggestions.git
dest: "{{ user_home }}/.zsh/zsh-autosuggestions"
version: master
depth: 1
- name: Clone zsh-syntax-highlighting
ansible.builtin.git:
repo: https://github.com/zsh-users/zsh-syntax-highlighting.git
dest: "{{ user_home }}/.zsh/zsh-syntax-highlighting"
version: master
depth: 1
- name: Clone zsh-completions
ansible.builtin.git:
repo: https://github.com/zsh-users/zsh-completions.git
dest: "{{ user_home }}/.zsh/zsh-completions"
version: master
depth: 1
- name: Clone zsh-transient-prompt
ansible.builtin.git:
repo: https://github.com/olets/zsh-transient-prompt.git
dest: "{{ user_home }}/.zsh/zsh-transient-prompt"
version: main
depth: 1

View File

@ -0,0 +1 @@
---

View File

@ -0,0 +1,188 @@
# ~/.config/starship.toml
# --- 1. THE ASSEMBLY LINE ---
format = """
[](white)[ ](bg:#9A348E)\
$os\
[](fg:#9A348E bg:#0087FF)\
$directory\
[](fg:#0087FF bg:#00D700)\
$git_branch\
$git_commit\
$git_state\
$git_status\
[](fg:#00D700)\
$fill\
[](fg:#86BBD8)\
$python\
$nodejs\
$rust\
$golang\
$java\
$scala\
[](fg:#06969A bg:#86BBD8)\
$docker_context\
[](fg:#33658A bg:#06969A)\
$time\
[ ](bg:#33658A)\
$status\
$line_break\
$character\
"""
# --- 2. PART DEFINITIONS ---
[fill]
symbol = " "
# OS Module (Purple Block)
[os]
disabled = false
style = "fg:#ffffff bg:#9A348E"
format = '[$symbol]($style)'
[os.symbols]
Windows = " "
Macos = " "
Linux = " "
Arch = " "
Ubuntu = " "
Fedora = " "
Debian = " "
Mint = " "
# UPDATED: Correct Manjaro logo
Manjaro = " "
# Directory Module (Blue Block)
[directory]
style = "fg:#ffffff bg:#0087FF"
format = '[ $path ]($style)'
truncation_length = 3
truncation_symbol = "…/"
# Git Branch Module (Green Block)
[git_branch]
symbol = " "
style = "fg:#000000 bg:#00D700"
format = '[ $symbol$branch(:$remote_branch) ]($style)'
truncation_length = 20
truncation_symbol = "…"
# Git Status Module (detailed status)
[git_status]
style = "fg:#000000 bg:#00D700"
format = '[$all_status$ahead_behind ]($style)'
conflicted = "⚔️ "
ahead = "⇡${count} "
behind = "⇣${count} "
diverged = "⇕⇡${ahead_count}⇣${behind_count} "
untracked = "?${count} "
stashed = "📦${count} "
modified = "!${count} "
staged = "+${count} "
renamed = "»${count} "
deleted = "✘${count} "
# Git Commit (shows current commit)
[git_commit]
style = "fg:#000000 bg:#00D700"
format = '[ #$hash$tag ]($style)'
commit_hash_length = 7
only_detached = true
# Git State (rebase, merge, etc)
[git_state]
style = "fg:#ffffff bg:#FF0000"
format = '[\($state( $progress_current/$progress_total)\)]($style)'
rebase = "REBASING"
merge = "MERGING"
revert = "REVERTING"
cherry_pick = "CHERRY-PICKING"
bisect = "BISECTING"
am = "AM"
am_or_rebase = "AM/REBASE"
[python]
# UPDATED: Switched from emoji to Nerd Font
symbol = " "
style = "fg:#000000 bg:#86BBD8"
format = '[ $symbol($virtualenv )($version) ](fg:#000000 bg:#86BBD8)'
[golang]
symbol = " "
style = "fg:#000000 bg:#86BBD8"
format = '[ $symbol($version) ](fg:#000000 bg:#86BBD8)'
[gradle]
style = "bg:#86BBD8"
format = '[ $symbol ($version) ]($style)'
[haskell]
symbol = " "
style = "bg:#86BBD8"
format = '[ $symbol ($version) ]($style)'
[java]
symbol = " "
style = "fg:#000000 bg:#86BBD8"
format = '[ $symbol($version) ](fg:#000000 bg:#86BBD8)'
[julia]
symbol = " "
style = "bg:#86BBD8"
format = '[ $symbol ($version) ]($style)'
[nodejs]
symbol = " "
style = "fg:#000000 bg:#86BBD8"
format = '[ $symbol($version) ](fg:#000000 bg:#86BBD8)'
[nim]
symbol = "󰆥 "
style = "bg:#86BBD8"
format = '[ $symbol ($version) ]($style)'
[rust]
symbol = " "
style = "fg:#000000 bg:#86BBD8"
format = '[ $symbol($version) ](fg:#000000 bg:#86BBD8)'
[scala]
symbol = " "
style = "fg:#000000 bg:#86BBD8"
format = '[ $symbol($version) ](fg:#000000 bg:#86BBD8)'
[docker_context]
# UPDATED: Added standard Docker icon
symbol = " "
style = "fg:#ffffff bg:#06969A"
#format = 'via [🐋 $context](blue bold)'
format = '[ $symbol$context ](fg:#ffffff bg:#06969A)'
#format = "via [⬢ $context](bold blue) "
#detect_files = ["Dockerfile", "docker-compose.yml", ".dockerenv"]
#disabled = false
#[docker_context]
#format = 'via [🐋 $context](blue bold)'
[time]
disabled = false
time_format = "%R"
style = "fg:#FFFFFF bg:#33658A"
format = '[ $time  ]($style)'
[status]
disabled = false
style = "(fg:#ffffff bg:#FF0000)"
format = '[](fg:#FF0000 bg:#33658A)[ ✘ $status ](fg:#ffffff bg:#FF0000)'
# The Prompt Arrow
[character]
success_symbol = '[╰─](white) '
error_symbol = '[╰─](white) '
#[status]
#disabled = false
#style = "(fg:#ffffff bg:#FF0000)"
#format = '[](fg:#FF0000 bg:#33658A)[ ✘ $status ]($style)'

View File

@ -0,0 +1,111 @@
HISTFILE=~/.histfile
HISTSIZE=10000
SAVEHIST=10000
setopt appendhistory sharehistory incappendhistory histignorealldups autocd extendedglob nomatch notify
bindkey -e
export COLORTERM=truecolor
fastfetch
# History search with up/down arrows (like Fish!)
autoload -Uz up-line-or-beginning-search down-line-or-beginning-search
zle -N up-line-or-beginning-search
zle -N down-line-or-beginning-search
bindkey "^[[A" up-line-or-beginning-search
bindkey "^[[B" down-line-or-beginning-search
zstyle :compinstall filename '/home/travis/.zshrc'
autoload -Uz compinit
compinit
# Completion styling
zstyle ':completion:*' menu select
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' # Case insensitive
zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}" # Color files like ls
zstyle ':completion:*:descriptions' format '%F{blue}-- %d --%f'
zstyle ':completion:*:warnings' format '%F{red}-- no matches found --%f'
zstyle ':completion:*:messages' format '%F{magenta}-- %d --%f'
zstyle ':completion:*:corrections' format '%F{yellow}-- %d (errors: %e) --%f'
zstyle ':completion:*' group-name '' # Group results by category
PROMPT_THEME="${PROMPT_THEME:-starship}"
if [[ "$PROMPT_THEME" == "p10k" ]]; then
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi
# Use powerline
USE_POWERLINE="true"
# Has weird character width
# Example:
#  is not a diamond
HAS_WIDECHARS="false"
# Source manjaro-zsh-configuration
if [[ -e /usr/share/zsh/manjaro-zsh-config ]]; then
source /usr/share/zsh/manjaro-zsh-config
fi
# Use manjaro zsh prompt
if [[ -e /usr/share/zsh/manjaro-zsh-prompt ]]; then
source /usr/share/zsh/manjaro-zsh-prompt
fi
source ~/.p10k.zsh
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
else
TRANSIENT_PROMPT_TRANSIENT_PROMPT='%F{blue}λ:%f '
TRANSIENT_PROMPT_TRANSIENT_RPROMPT=''
eval "$(starship init zsh)"
SPACESHIP_EXEC_TIME_ELAPSED=.01
source ~/.zsh/zsh-transient-prompt/transient-prompt.zsh-theme
fi
# Other init
eval "$(zoxide init zsh)"
source ~/.zsh/zsh-transient-prompt/transient-prompt.zsh-theme
source ~/.zsh/zsh-autosuggestions/zsh-autosuggestions.zsh
source ~/.zsh/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
fpath=(~/.zsh/zsh-completions/src $fpath)
source /usr/share/fzf/key-bindings.zsh
source /usr/share/fzf/completion.zsh
if [ -f ~/.zsh_aliases ]; then
source ~/.zsh_aliases
fi
# Quick alias management
addalias() {
echo "alias $1='$2'" >> ~/.zsh_aliases
source ~/.zsh_aliases
echo "✅ Added: $1"
}
listalias() {
cat ~/.zsh_aliases
}
alias xc='xclip -selection clipboard'
alias ls='eza --icons'
alias ll='eza -lah --icons'
alias cat='bat'
alias cd='z'
alias dps='docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"'
alias dlog='docker logs -f'
alias dcup='docker compose up -d'
alias dcdown='docker compose down'
alias ap='ansible-playbook'
alias av='ansible-vault'
alias pysync='uv sync'
alias pyrun='uv run'
alias pyshell='uv run ipython'
# Aliases for fastfetch
alias fetch='fastfetch'
alias neofetch='fastfetch'

View File

@ -0,0 +1,29 @@
---
- name: Install zsh and dependencies
ansible.builtin.package:
name:
- zsh
- starship
- zoxide
- fzf
- eza
- bat
- ttf-jetbrains-mono-nerd
state: present
become: true
- name: Copy .zshrc configuration
ansible.builtin.copy:
src: zshrc
dest: "{{ ansible_env.HOME }}/.zshrc"
mode: '0644'
become: true
become_user: "{{ user }}"
- name: Copy starship configuration
ansible.builtin.copy:
src: starship.toml
dest: "{{ user_home }}/.config/starship.toml"
mode: '0644'
become: true
become_user: "{{ user }}"

View File

@ -0,0 +1,464 @@
version = 1
revision = 2
requires-python = ">=3.13"
[[package]]
name = "ansible"
version = "11.6.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "ansible-core" },
]
sdist = { url = "https://files.pythonhosted.org/packages/a6/6f/b491cd89e0393810b67598098ccb6a204d6a9202c9733a541568f69f6dea/ansible-11.6.0.tar.gz", hash = "sha256:934a948caa3ec1a3eb277e7ab1638b808b074a6e0c46045794cde7b637e275d8", size = 44015165, upload-time = "2025-05-20T20:28:24.184Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ef/92/8aebdbdd4574d337e47ebb7171fdc83095b82c255f8362f96681b113b79d/ansible-11.6.0-py3-none-any.whl", hash = "sha256:5b9c19d6a1080011c14c821bc7e6f8fd5b2a392219cbf2ced9be05e6d447d8cd", size = 55488595, upload-time = "2025-05-20T20:28:17.672Z" },
]
[[package]]
name = "ansible-compat"
version = "25.5.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "ansible-core" },
{ name = "jsonschema" },
{ name = "packaging" },
{ name = "pyyaml" },
{ name = "subprocess-tee" },
]
sdist = { url = "https://files.pythonhosted.org/packages/30/66/5ab513ccbc8a5820056ee06eab293591a3ed0908eff47e7d3447a4280e20/ansible_compat-25.5.0.tar.gz", hash = "sha256:0b71052313596e128d2bf60166a1d2ac41c6d140a0ca97d56b878e3c23bfce42", size = 88398, upload-time = "2025-05-13T07:34:29.62Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/db/4c/8fd9e702bef678cede0e34c5c7a8be2ff205dfb37c605bf8b7ea9840a6a1/ansible_compat-25.5.0-py3-none-any.whl", hash = "sha256:284c6f175e7301d7474b65629c5b10a41016569ce03f50bb7478d6fa9001a2b8", size = 25861, upload-time = "2025-05-13T07:34:27.823Z" },
]
[[package]]
name = "ansible-core"
version = "2.18.6"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cryptography" },
{ name = "jinja2" },
{ name = "packaging" },
{ name = "pyyaml" },
{ name = "resolvelib" },
]
sdist = { url = "https://files.pythonhosted.org/packages/4c/1e/c5d52171ae2b86689e3ef9e4f578c605a7f53a862d1e9fe8c254deb75fe1/ansible_core-2.18.6.tar.gz", hash = "sha256:25bb20ce1516a1b7307831b263cef684043b3720711466bd9d4164e5fd576557", size = 3088072, upload-time = "2025-05-19T16:59:59.234Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/48/b7/2ca5a126486a5323dde87cc43b207e926f3f3bce0b5758395308de3f146d/ansible_core-2.18.6-py3-none-any.whl", hash = "sha256:12a34749a7b20f0f1536bd3e3b2e137341867e4642e351273e96647161f595c0", size = 2208798, upload-time = "2025-05-19T16:59:57.372Z" },
]
[[package]]
name = "ansible-lint"
version = "25.4.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "ansible-compat" },
{ name = "ansible-core" },
{ name = "black" },
{ name = "filelock" },
{ name = "importlib-metadata" },
{ name = "jsonschema" },
{ name = "packaging" },
{ name = "pathspec" },
{ name = "pyyaml" },
{ name = "referencing" },
{ name = "ruamel-yaml" },
{ name = "subprocess-tee" },
{ name = "wcmatch" },
{ name = "yamllint" },
]
sdist = { url = "https://files.pythonhosted.org/packages/24/50/3d0bb7e77aed2a66fce4b87aec249adb11070ef2025db1215b1c0fb14b51/ansible_lint-25.4.0.tar.gz", hash = "sha256:f2f2b31ad199925b2343f660552fb9468970f16c2c5d57da9feae70ec4eeca7d", size = 556175, upload-time = "2025-04-28T12:10:55.556Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ae/13/099bccd0e9c8db63c6abaee114c25fa371a7632c3fccf404d81b12928607/ansible_lint-25.4.0-py3-none-any.whl", hash = "sha256:16644f11dbfc4b52a12a16e2069eab83d089f154c55dd837484e92de7f031244", size = 314548, upload-time = "2025-04-28T12:10:53.369Z" },
]
[[package]]
name = "arch-custom"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
{ name = "ansible" },
{ name = "ansible-lint" },
{ name = "yamllint" },
]
[package.metadata]
requires-dist = [
{ name = "ansible", specifier = ">=11.6.0" },
{ name = "ansible-lint", specifier = ">=25.4.0" },
{ name = "yamllint", specifier = ">=1.37.1" },
]
[[package]]
name = "attrs"
version = "25.3.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032, upload-time = "2025-03-13T11:10:22.779Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload-time = "2025-03-13T11:10:21.14Z" },
]
[[package]]
name = "black"
version = "25.1.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "click" },
{ name = "mypy-extensions" },
{ name = "packaging" },
{ name = "pathspec" },
{ name = "platformdirs" },
]
sdist = { url = "https://files.pythonhosted.org/packages/94/49/26a7b0f3f35da4b5a65f081943b7bcd22d7002f5f0fb8098ec1ff21cb6ef/black-25.1.0.tar.gz", hash = "sha256:33496d5cd1222ad73391352b4ae8da15253c5de89b93a80b3e2c8d9a19ec2666", size = 649449, upload-time = "2025-01-29T04:15:40.373Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/98/87/0edf98916640efa5d0696e1abb0a8357b52e69e82322628f25bf14d263d1/black-25.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f0b18a02996a836cc9c9c78e5babec10930862827b1b724ddfe98ccf2f2fe4f", size = 1650673, upload-time = "2025-01-29T05:37:20.574Z" },
{ url = "https://files.pythonhosted.org/packages/52/e5/f7bf17207cf87fa6e9b676576749c6b6ed0d70f179a3d812c997870291c3/black-25.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:afebb7098bfbc70037a053b91ae8437c3857482d3a690fefc03e9ff7aa9a5fd3", size = 1453190, upload-time = "2025-01-29T05:37:22.106Z" },
{ url = "https://files.pythonhosted.org/packages/e3/ee/adda3d46d4a9120772fae6de454c8495603c37c4c3b9c60f25b1ab6401fe/black-25.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:030b9759066a4ee5e5aca28c3c77f9c64789cdd4de8ac1df642c40b708be6171", size = 1782926, upload-time = "2025-01-29T04:18:58.564Z" },
{ url = "https://files.pythonhosted.org/packages/cc/64/94eb5f45dcb997d2082f097a3944cfc7fe87e071907f677e80788a2d7b7a/black-25.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:a22f402b410566e2d1c950708c77ebf5ebd5d0d88a6a2e87c86d9fb48afa0d18", size = 1442613, upload-time = "2025-01-29T04:19:27.63Z" },
{ url = "https://files.pythonhosted.org/packages/09/71/54e999902aed72baf26bca0d50781b01838251a462612966e9fc4891eadd/black-25.1.0-py3-none-any.whl", hash = "sha256:95e8176dae143ba9097f351d174fdaf0ccd29efb414b362ae3fd72bf0f710717", size = 207646, upload-time = "2025-01-29T04:15:38.082Z" },
]
[[package]]
name = "bracex"
version = "2.5.post1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d6/6c/57418c4404cd22fe6275b8301ca2b46a8cdaa8157938017a9ae0b3edf363/bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6", size = 26641, upload-time = "2024-09-28T21:41:22.017Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/4b/02/8db98cdc1a58e0abd6716d5e63244658e6e63513c65f469f34b6f1053fd0/bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6", size = 11558, upload-time = "2024-09-28T21:41:21.016Z" },
]
[[package]]
name = "cffi"
version = "1.17.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pycparser" },
]
sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621, upload-time = "2024-09-04T20:45:21.852Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989, upload-time = "2024-09-04T20:44:28.956Z" },
{ url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802, upload-time = "2024-09-04T20:44:30.289Z" },
{ url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792, upload-time = "2024-09-04T20:44:32.01Z" },
{ url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893, upload-time = "2024-09-04T20:44:33.606Z" },
{ url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810, upload-time = "2024-09-04T20:44:35.191Z" },
{ url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200, upload-time = "2024-09-04T20:44:36.743Z" },
{ url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447, upload-time = "2024-09-04T20:44:38.492Z" },
{ url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358, upload-time = "2024-09-04T20:44:40.046Z" },
{ url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469, upload-time = "2024-09-04T20:44:41.616Z" },
{ url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475, upload-time = "2024-09-04T20:44:43.733Z" },
{ url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009, upload-time = "2024-09-04T20:44:45.309Z" },
]
[[package]]
name = "click"
version = "8.2.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "colorama", marker = "sys_platform == 'win32'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202", size = 286342, upload-time = "2025-05-20T23:19:49.832Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b", size = 102215, upload-time = "2025-05-20T23:19:47.796Z" },
]
[[package]]
name = "colorama"
version = "0.4.6"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
]
[[package]]
name = "cryptography"
version = "45.0.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/f6/47/92a8914716f2405f33f1814b97353e3cfa223cd94a77104075d42de3099e/cryptography-45.0.2.tar.gz", hash = "sha256:d784d57b958ffd07e9e226d17272f9af0c41572557604ca7554214def32c26bf", size = 743865, upload-time = "2025-05-18T02:46:34.986Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/3d/2f/46b9e715157643ad16f039ec3c3c47d174da6f825bf5034b1c5f692ab9e2/cryptography-45.0.2-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:61a8b1bbddd9332917485b2453d1de49f142e6334ce1d97b7916d5a85d179c84", size = 7043448, upload-time = "2025-05-18T02:45:12.495Z" },
{ url = "https://files.pythonhosted.org/packages/90/52/49e6c86278e1b5ec226e96b62322538ccc466306517bf9aad8854116a088/cryptography-45.0.2-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cc31c66411e14dd70e2f384a9204a859dc25b05e1f303df0f5326691061b839", size = 4201098, upload-time = "2025-05-18T02:45:15.178Z" },
{ url = "https://files.pythonhosted.org/packages/7b/3a/201272539ac5b66b4cb1af89021e423fc0bfacb73498950280c51695fb78/cryptography-45.0.2-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:463096533acd5097f8751115bc600b0b64620c4aafcac10c6d0041e6e68f88fe", size = 4429839, upload-time = "2025-05-18T02:45:17.614Z" },
{ url = "https://files.pythonhosted.org/packages/99/89/fa1a84832b8f8f3917875cb15324bba98def5a70175a889df7d21a45dc75/cryptography-45.0.2-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:cdafb86eb673c3211accffbffdb3cdffa3aaafacd14819e0898d23696d18e4d3", size = 4205154, upload-time = "2025-05-18T02:45:19.874Z" },
{ url = "https://files.pythonhosted.org/packages/1c/c5/5225d5230d538ab461725711cf5220560a813d1eb68bafcfb00131b8f631/cryptography-45.0.2-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:05c2385b1f5c89a17df19900cfb1345115a77168f5ed44bdf6fd3de1ce5cc65b", size = 3897145, upload-time = "2025-05-18T02:45:22.209Z" },
{ url = "https://files.pythonhosted.org/packages/fe/24/f19aae32526cc55ae17d473bc4588b1234af2979483d99cbfc57e55ffea6/cryptography-45.0.2-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:e9e4bdcd70216b08801e267c0b563316b787f957a46e215249921f99288456f9", size = 4462192, upload-time = "2025-05-18T02:45:24.773Z" },
{ url = "https://files.pythonhosted.org/packages/19/18/4a69ac95b0b3f03355970baa6c3f9502bbfc54e7df81fdb179654a00f48e/cryptography-45.0.2-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b2de529027579e43b6dc1f805f467b102fb7d13c1e54c334f1403ee2b37d0059", size = 4208093, upload-time = "2025-05-18T02:45:27.028Z" },
{ url = "https://files.pythonhosted.org/packages/7c/54/2dea55ccc9558b8fa14f67156250b6ee231e31765601524e4757d0b5db6b/cryptography-45.0.2-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:10d68763892a7b19c22508ab57799c4423c7c8cd61d7eee4c5a6a55a46511949", size = 4461819, upload-time = "2025-05-18T02:45:29.39Z" },
{ url = "https://files.pythonhosted.org/packages/37/f1/1b220fcd5ef4b1f0ff3e59e733b61597505e47f945606cc877adab2c1a17/cryptography-45.0.2-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d2a90ce2f0f5b695e4785ac07c19a58244092f3c85d57db6d8eb1a2b26d2aad6", size = 4329202, upload-time = "2025-05-18T02:45:31.925Z" },
{ url = "https://files.pythonhosted.org/packages/6d/e0/51d1dc4f96f819a56db70f0b4039b4185055bbb8616135884c3c3acc4c6d/cryptography-45.0.2-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:59c0c8f043dd376bbd9d4f636223836aed50431af4c5a467ed9bf61520294627", size = 4570412, upload-time = "2025-05-18T02:45:34.348Z" },
{ url = "https://files.pythonhosted.org/packages/dc/44/88efb40a3600d15277a77cdc69eeeab45a98532078d2a36cffd9325d3b3f/cryptography-45.0.2-cp311-abi3-win32.whl", hash = "sha256:80303ee6a02ef38c4253160446cbeb5c400c07e01d4ddbd4ff722a89b736d95a", size = 2933584, upload-time = "2025-05-18T02:45:36.198Z" },
{ url = "https://files.pythonhosted.org/packages/d9/a1/bc9f82ba08760442cc8346d1b4e7b769b86d197193c45b42b3595d231e84/cryptography-45.0.2-cp311-abi3-win_amd64.whl", hash = "sha256:7429936146063bd1b2cfc54f0e04016b90ee9b1c908a7bed0800049cbace70eb", size = 3408537, upload-time = "2025-05-18T02:45:38.184Z" },
{ url = "https://files.pythonhosted.org/packages/59/bc/1b6acb1dca366f9c0b3880888ecd7fcfb68023930d57df854847c6da1d10/cryptography-45.0.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:e86c8d54cd19a13e9081898b3c24351683fd39d726ecf8e774aaa9d8d96f5f3a", size = 7025581, upload-time = "2025-05-18T02:45:40.632Z" },
{ url = "https://files.pythonhosted.org/packages/31/a3/a3e4a298d3db4a04085728f5ae6c8cda157e49c5bb784886d463b9fbff70/cryptography-45.0.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e328357b6bbf79928363dbf13f4635b7aac0306afb7e5ad24d21d0c5761c3253", size = 4189148, upload-time = "2025-05-18T02:45:42.538Z" },
{ url = "https://files.pythonhosted.org/packages/53/90/100dfadd4663b389cb56972541ec1103490a19ebad0132af284114ba0868/cryptography-45.0.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49af56491473231159c98c2c26f1a8f3799a60e5cf0e872d00745b858ddac9d2", size = 4424113, upload-time = "2025-05-18T02:45:44.316Z" },
{ url = "https://files.pythonhosted.org/packages/0d/40/e2b9177dbed6f3fcbbf1942e1acea2fd15b17007204b79d675540dd053af/cryptography-45.0.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f169469d04a23282de9d0be349499cb6683b6ff1b68901210faacac9b0c24b7d", size = 4189696, upload-time = "2025-05-18T02:45:46.622Z" },
{ url = "https://files.pythonhosted.org/packages/70/ae/ec29c79f481e1767c2ff916424ba36f3cf7774de93bbd60428a3c52d1357/cryptography-45.0.2-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9cfd1399064b13043082c660ddd97a0358e41c8b0dc7b77c1243e013d305c344", size = 3881498, upload-time = "2025-05-18T02:45:48.884Z" },
{ url = "https://files.pythonhosted.org/packages/5f/4a/72937090e5637a232b2f73801c9361cd08404a2d4e620ca4ec58c7ea4b70/cryptography-45.0.2-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:18f8084b7ca3ce1b8d38bdfe33c48116edf9a08b4d056ef4a96dceaa36d8d965", size = 4451678, upload-time = "2025-05-18T02:45:50.706Z" },
{ url = "https://files.pythonhosted.org/packages/d3/fa/1377fced81fd67a4a27514248261bb0d45c3c1e02169411fe231583088c8/cryptography-45.0.2-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:2cb03a944a1a412724d15a7c051d50e63a868031f26b6a312f2016965b661942", size = 4192296, upload-time = "2025-05-18T02:45:52.422Z" },
{ url = "https://files.pythonhosted.org/packages/d1/cf/b6fe837c83a08b9df81e63299d75fc5b3c6d82cf24b3e1e0e331050e9e5c/cryptography-45.0.2-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:a9727a21957d3327cf6b7eb5ffc9e4b663909a25fea158e3fcbc49d4cdd7881b", size = 4451749, upload-time = "2025-05-18T02:45:55.025Z" },
{ url = "https://files.pythonhosted.org/packages/af/d8/5a655675cc635c7190bfc8cffb84bcdc44fc62ce945ad1d844adaa884252/cryptography-45.0.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ddb8d01aa900b741d6b7cc585a97aff787175f160ab975e21f880e89d810781a", size = 4317601, upload-time = "2025-05-18T02:45:56.911Z" },
{ url = "https://files.pythonhosted.org/packages/b9/d4/75d2375a20d80aa262a8adee77bf56950e9292929e394b9fae2481803f11/cryptography-45.0.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:c0c000c1a09f069632d8a9eb3b610ac029fcc682f1d69b758e625d6ee713f4ed", size = 4560535, upload-time = "2025-05-18T02:45:59.33Z" },
{ url = "https://files.pythonhosted.org/packages/aa/18/c3a94474987ebcfb88692036b2ec44880d243fefa73794bdcbf748679a6e/cryptography-45.0.2-cp37-abi3-win32.whl", hash = "sha256:08281de408e7eb71ba3cd5098709a356bfdf65eebd7ee7633c3610f0aa80d79b", size = 2922045, upload-time = "2025-05-18T02:46:01.012Z" },
{ url = "https://files.pythonhosted.org/packages/63/63/fb28b30c144182fd44ce93d13ab859791adbf923e43bdfb610024bfecda1/cryptography-45.0.2-cp37-abi3-win_amd64.whl", hash = "sha256:48caa55c528617fa6db1a9c3bf2e37ccb31b73e098ac2b71408d1f2db551dde4", size = 3393321, upload-time = "2025-05-18T02:46:03.441Z" },
]
[[package]]
name = "filelock"
version = "3.18.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/0a/10/c23352565a6544bdc5353e0b15fc1c563352101f30e24bf500207a54df9a/filelock-3.18.0.tar.gz", hash = "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2", size = 18075, upload-time = "2025-03-14T07:11:40.47Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/4d/36/2a115987e2d8c300a974597416d9de88f2444426de9571f4b59b2cca3acc/filelock-3.18.0-py3-none-any.whl", hash = "sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de", size = 16215, upload-time = "2025-03-14T07:11:39.145Z" },
]
[[package]]
name = "importlib-metadata"
version = "8.7.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "zipp" },
]
sdist = { url = "https://files.pythonhosted.org/packages/76/66/650a33bd90f786193e4de4b3ad86ea60b53c89b669a5c7be931fac31cdb0/importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000", size = 56641, upload-time = "2025-04-27T15:29:01.736Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/20/b0/36bd937216ec521246249be3bf9855081de4c5e06a0c9b4219dbeda50373/importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd", size = 27656, upload-time = "2025-04-27T15:29:00.214Z" },
]
[[package]]
name = "jinja2"
version = "3.1.6"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "markupsafe" },
]
sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" },
]
[[package]]
name = "jsonschema"
version = "4.23.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "attrs" },
{ name = "jsonschema-specifications" },
{ name = "referencing" },
{ name = "rpds-py" },
]
sdist = { url = "https://files.pythonhosted.org/packages/38/2e/03362ee4034a4c917f697890ccd4aec0800ccf9ded7f511971c75451deec/jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4", size = 325778, upload-time = "2024-07-08T18:40:05.546Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/69/4a/4f9dbeb84e8850557c02365a0eee0649abe5eb1d84af92a25731c6c0f922/jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566", size = 88462, upload-time = "2024-07-08T18:40:00.165Z" },
]
[[package]]
name = "jsonschema-specifications"
version = "2025.4.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "referencing" },
]
sdist = { url = "https://files.pythonhosted.org/packages/bf/ce/46fbd9c8119cfc3581ee5643ea49464d168028cfb5caff5fc0596d0cf914/jsonschema_specifications-2025.4.1.tar.gz", hash = "sha256:630159c9f4dbea161a6a2205c3011cc4f18ff381b189fff48bb39b9bf26ae608", size = 15513, upload-time = "2025-04-23T12:34:07.418Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/01/0e/b27cdbaccf30b890c40ed1da9fd4a3593a5cf94dae54fb34f8a4b74fcd3f/jsonschema_specifications-2025.4.1-py3-none-any.whl", hash = "sha256:4653bffbd6584f7de83a67e0d620ef16900b390ddc7939d56684d6c81e33f1af", size = 18437, upload-time = "2025-04-23T12:34:05.422Z" },
]
[[package]]
name = "markupsafe"
version = "3.0.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload-time = "2024-10-18T15:21:54.129Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274, upload-time = "2024-10-18T15:21:24.577Z" },
{ url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352, upload-time = "2024-10-18T15:21:25.382Z" },
{ url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122, upload-time = "2024-10-18T15:21:26.199Z" },
{ url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085, upload-time = "2024-10-18T15:21:27.029Z" },
{ url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978, upload-time = "2024-10-18T15:21:27.846Z" },
{ url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208, upload-time = "2024-10-18T15:21:28.744Z" },
{ url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357, upload-time = "2024-10-18T15:21:29.545Z" },
{ url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344, upload-time = "2024-10-18T15:21:30.366Z" },
{ url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101, upload-time = "2024-10-18T15:21:31.207Z" },
{ url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603, upload-time = "2024-10-18T15:21:32.032Z" },
{ url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510, upload-time = "2024-10-18T15:21:33.625Z" },
{ url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486, upload-time = "2024-10-18T15:21:34.611Z" },
{ url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480, upload-time = "2024-10-18T15:21:35.398Z" },
{ url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914, upload-time = "2024-10-18T15:21:36.231Z" },
{ url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796, upload-time = "2024-10-18T15:21:37.073Z" },
{ url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473, upload-time = "2024-10-18T15:21:37.932Z" },
{ url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114, upload-time = "2024-10-18T15:21:39.799Z" },
{ url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098, upload-time = "2024-10-18T15:21:40.813Z" },
{ url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208, upload-time = "2024-10-18T15:21:41.814Z" },
{ url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739, upload-time = "2024-10-18T15:21:42.784Z" },
]
[[package]]
name = "mypy-extensions"
version = "1.1.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" },
]
[[package]]
name = "packaging"
version = "25.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" },
]
[[package]]
name = "pathspec"
version = "0.12.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" },
]
[[package]]
name = "platformdirs"
version = "4.3.8"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/fe/8b/3c73abc9c759ecd3f1f7ceff6685840859e8070c4d947c93fae71f6a0bf2/platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc", size = 21362, upload-time = "2025-05-07T22:47:42.121Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4", size = 18567, upload-time = "2025-05-07T22:47:40.376Z" },
]
[[package]]
name = "pycparser"
version = "2.22"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736, upload-time = "2024-03-30T13:22:22.564Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552, upload-time = "2024-03-30T13:22:20.476Z" },
]
[[package]]
name = "pyyaml"
version = "6.0.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" },
{ url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" },
{ url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" },
{ url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" },
{ url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" },
{ url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" },
{ url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" },
{ url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" },
{ url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" },
]
[[package]]
name = "referencing"
version = "0.36.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "attrs" },
{ name = "rpds-py" },
]
sdist = { url = "https://files.pythonhosted.org/packages/2f/db/98b5c277be99dd18bfd91dd04e1b759cad18d1a338188c936e92f921c7e2/referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", size = 74744, upload-time = "2025-01-25T08:48:16.138Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c1/b1/3baf80dc6d2b7bc27a95a67752d0208e410351e3feb4eb78de5f77454d8d/referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0", size = 26775, upload-time = "2025-01-25T08:48:14.241Z" },
]
[[package]]
name = "resolvelib"
version = "1.0.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/ce/10/f699366ce577423cbc3df3280063099054c23df70856465080798c6ebad6/resolvelib-1.0.1.tar.gz", hash = "sha256:04ce76cbd63fded2078ce224785da6ecd42b9564b1390793f64ddecbe997b309", size = 21065, upload-time = "2023-03-09T05:10:38.292Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/d2/fc/e9ccf0521607bcd244aa0b3fbd574f71b65e9ce6a112c83af988bbbe2e23/resolvelib-1.0.1-py2.py3-none-any.whl", hash = "sha256:d2da45d1a8dfee81bdd591647783e340ef3bcb104b54c383f70d422ef5cc7dbf", size = 17194, upload-time = "2023-03-09T05:10:36.214Z" },
]
[[package]]
name = "rpds-py"
version = "0.25.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/8c/a6/60184b7fc00dd3ca80ac635dd5b8577d444c57e8e8742cecabfacb829921/rpds_py-0.25.1.tar.gz", hash = "sha256:8960b6dac09b62dac26e75d7e2c4a22efb835d827a7278c34f72b2b84fa160e3", size = 27304, upload-time = "2025-05-21T12:46:12.502Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/2b/da/323848a2b62abe6a0fec16ebe199dc6889c5d0a332458da8985b2980dffe/rpds_py-0.25.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:659d87430a8c8c704d52d094f5ba6fa72ef13b4d385b7e542a08fc240cb4a559", size = 364498, upload-time = "2025-05-21T12:43:54.841Z" },
{ url = "https://files.pythonhosted.org/packages/1f/b4/4d3820f731c80fd0cd823b3e95b9963fec681ae45ba35b5281a42382c67d/rpds_py-0.25.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:68f6f060f0bbdfb0245267da014d3a6da9be127fe3e8cc4a68c6f833f8a23bb1", size = 350083, upload-time = "2025-05-21T12:43:56.428Z" },
{ url = "https://files.pythonhosted.org/packages/d5/b1/3a8ee1c9d480e8493619a437dec685d005f706b69253286f50f498cbdbcf/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:083a9513a33e0b92cf6e7a6366036c6bb43ea595332c1ab5c8ae329e4bcc0a9c", size = 389023, upload-time = "2025-05-21T12:43:57.995Z" },
{ url = "https://files.pythonhosted.org/packages/3b/31/17293edcfc934dc62c3bf74a0cb449ecd549531f956b72287203e6880b87/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:816568614ecb22b18a010c7a12559c19f6fe993526af88e95a76d5a60b8b75fb", size = 403283, upload-time = "2025-05-21T12:43:59.546Z" },
{ url = "https://files.pythonhosted.org/packages/d1/ca/e0f0bc1a75a8925024f343258c8ecbd8828f8997ea2ac71e02f67b6f5299/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c6564c0947a7f52e4792983f8e6cf9bac140438ebf81f527a21d944f2fd0a40", size = 524634, upload-time = "2025-05-21T12:44:01.087Z" },
{ url = "https://files.pythonhosted.org/packages/3e/03/5d0be919037178fff33a6672ffc0afa04ea1cfcb61afd4119d1b5280ff0f/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c4a128527fe415d73cf1f70a9a688d06130d5810be69f3b553bf7b45e8acf79", size = 416233, upload-time = "2025-05-21T12:44:02.604Z" },
{ url = "https://files.pythonhosted.org/packages/05/7c/8abb70f9017a231c6c961a8941403ed6557664c0913e1bf413cbdc039e75/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a49e1d7a4978ed554f095430b89ecc23f42014a50ac385eb0c4d163ce213c325", size = 390375, upload-time = "2025-05-21T12:44:04.162Z" },
{ url = "https://files.pythonhosted.org/packages/7a/ac/a87f339f0e066b9535074a9f403b9313fd3892d4a164d5d5f5875ac9f29f/rpds_py-0.25.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d74ec9bc0e2feb81d3f16946b005748119c0f52a153f6db6a29e8cd68636f295", size = 424537, upload-time = "2025-05-21T12:44:06.175Z" },
{ url = "https://files.pythonhosted.org/packages/1f/8f/8d5c1567eaf8c8afe98a838dd24de5013ce6e8f53a01bd47fe8bb06b5533/rpds_py-0.25.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3af5b4cc10fa41e5bc64e5c198a1b2d2864337f8fcbb9a67e747e34002ce812b", size = 566425, upload-time = "2025-05-21T12:44:08.242Z" },
{ url = "https://files.pythonhosted.org/packages/95/33/03016a6be5663b389c8ab0bbbcca68d9e96af14faeff0a04affcb587e776/rpds_py-0.25.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:79dc317a5f1c51fd9c6a0c4f48209c6b8526d0524a6904fc1076476e79b00f98", size = 595197, upload-time = "2025-05-21T12:44:10.449Z" },
{ url = "https://files.pythonhosted.org/packages/33/8d/da9f4d3e208c82fda311bff0cf0a19579afceb77cf456e46c559a1c075ba/rpds_py-0.25.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1521031351865e0181bc585147624d66b3b00a84109b57fcb7a779c3ec3772cd", size = 561244, upload-time = "2025-05-21T12:44:12.387Z" },
{ url = "https://files.pythonhosted.org/packages/e2/b3/39d5dcf7c5f742ecd6dbc88f6f84ae54184b92f5f387a4053be2107b17f1/rpds_py-0.25.1-cp313-cp313-win32.whl", hash = "sha256:5d473be2b13600b93a5675d78f59e63b51b1ba2d0476893415dfbb5477e65b31", size = 222254, upload-time = "2025-05-21T12:44:14.261Z" },
{ url = "https://files.pythonhosted.org/packages/5f/19/2d6772c8eeb8302c5f834e6d0dfd83935a884e7c5ce16340c7eaf89ce925/rpds_py-0.25.1-cp313-cp313-win_amd64.whl", hash = "sha256:a7b74e92a3b212390bdce1d93da9f6488c3878c1d434c5e751cbc202c5e09500", size = 234741, upload-time = "2025-05-21T12:44:16.236Z" },
{ url = "https://files.pythonhosted.org/packages/5b/5a/145ada26cfaf86018d0eb304fe55eafdd4f0b6b84530246bb4a7c4fb5c4b/rpds_py-0.25.1-cp313-cp313-win_arm64.whl", hash = "sha256:dd326a81afe332ede08eb39ab75b301d5676802cdffd3a8f287a5f0b694dc3f5", size = 224830, upload-time = "2025-05-21T12:44:17.749Z" },
{ url = "https://files.pythonhosted.org/packages/4b/ca/d435844829c384fd2c22754ff65889c5c556a675d2ed9eb0e148435c6690/rpds_py-0.25.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:a58d1ed49a94d4183483a3ce0af22f20318d4a1434acee255d683ad90bf78129", size = 359668, upload-time = "2025-05-21T12:44:19.322Z" },
{ url = "https://files.pythonhosted.org/packages/1f/01/b056f21db3a09f89410d493d2f6614d87bb162499f98b649d1dbd2a81988/rpds_py-0.25.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f251bf23deb8332823aef1da169d5d89fa84c89f67bdfb566c49dea1fccfd50d", size = 345649, upload-time = "2025-05-21T12:44:20.962Z" },
{ url = "https://files.pythonhosted.org/packages/e0/0f/e0d00dc991e3d40e03ca36383b44995126c36b3eafa0ccbbd19664709c88/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dbd586bfa270c1103ece2109314dd423df1fa3d9719928b5d09e4840cec0d72", size = 384776, upload-time = "2025-05-21T12:44:22.516Z" },
{ url = "https://files.pythonhosted.org/packages/9f/a2/59374837f105f2ca79bde3c3cd1065b2f8c01678900924949f6392eab66d/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6d273f136e912aa101a9274c3145dcbddbe4bac560e77e6d5b3c9f6e0ed06d34", size = 395131, upload-time = "2025-05-21T12:44:24.147Z" },
{ url = "https://files.pythonhosted.org/packages/9c/dc/48e8d84887627a0fe0bac53f0b4631e90976fd5d35fff8be66b8e4f3916b/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:666fa7b1bd0a3810a7f18f6d3a25ccd8866291fbbc3c9b912b917a6715874bb9", size = 520942, upload-time = "2025-05-21T12:44:25.915Z" },
{ url = "https://files.pythonhosted.org/packages/7c/f5/ee056966aeae401913d37befeeab57a4a43a4f00099e0a20297f17b8f00c/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:921954d7fbf3fccc7de8f717799304b14b6d9a45bbeec5a8d7408ccbf531faf5", size = 411330, upload-time = "2025-05-21T12:44:27.638Z" },
{ url = "https://files.pythonhosted.org/packages/ab/74/b2cffb46a097cefe5d17f94ede7a174184b9d158a0aeb195f39f2c0361e8/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3d86373ff19ca0441ebeb696ef64cb58b8b5cbacffcda5a0ec2f3911732a194", size = 387339, upload-time = "2025-05-21T12:44:29.292Z" },
{ url = "https://files.pythonhosted.org/packages/7f/9a/0ff0b375dcb5161c2b7054e7d0b7575f1680127505945f5cabaac890bc07/rpds_py-0.25.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c8980cde3bb8575e7c956a530f2c217c1d6aac453474bf3ea0f9c89868b531b6", size = 418077, upload-time = "2025-05-21T12:44:30.877Z" },
{ url = "https://files.pythonhosted.org/packages/0d/a1/fda629bf20d6b698ae84c7c840cfb0e9e4200f664fc96e1f456f00e4ad6e/rpds_py-0.25.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8eb8c84ecea987a2523e057c0d950bcb3f789696c0499290b8d7b3107a719d78", size = 562441, upload-time = "2025-05-21T12:44:32.541Z" },
{ url = "https://files.pythonhosted.org/packages/20/15/ce4b5257f654132f326f4acd87268e1006cc071e2c59794c5bdf4bebbb51/rpds_py-0.25.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:e43a005671a9ed5a650f3bc39e4dbccd6d4326b24fb5ea8be5f3a43a6f576c72", size = 590750, upload-time = "2025-05-21T12:44:34.557Z" },
{ url = "https://files.pythonhosted.org/packages/fb/ab/e04bf58a8d375aeedb5268edcc835c6a660ebf79d4384d8e0889439448b0/rpds_py-0.25.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:58f77c60956501a4a627749a6dcb78dac522f249dd96b5c9f1c6af29bfacfb66", size = 558891, upload-time = "2025-05-21T12:44:37.358Z" },
{ url = "https://files.pythonhosted.org/packages/90/82/cb8c6028a6ef6cd2b7991e2e4ced01c854b6236ecf51e81b64b569c43d73/rpds_py-0.25.1-cp313-cp313t-win32.whl", hash = "sha256:2cb9e5b5e26fc02c8a4345048cd9998c2aca7c2712bd1b36da0c72ee969a3523", size = 218718, upload-time = "2025-05-21T12:44:38.969Z" },
{ url = "https://files.pythonhosted.org/packages/b6/97/5a4b59697111c89477d20ba8a44df9ca16b41e737fa569d5ae8bff99e650/rpds_py-0.25.1-cp313-cp313t-win_amd64.whl", hash = "sha256:401ca1c4a20cc0510d3435d89c069fe0a9ae2ee6495135ac46bdd49ec0495763", size = 232218, upload-time = "2025-05-21T12:44:40.512Z" },
]
[[package]]
name = "ruamel-yaml"
version = "0.18.10"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/ea/46/f44d8be06b85bc7c4d8c95d658be2b68f27711f279bf9dd0612a5e4794f5/ruamel.yaml-0.18.10.tar.gz", hash = "sha256:20c86ab29ac2153f80a428e1254a8adf686d3383df04490514ca3b79a362db58", size = 143447, upload-time = "2025-01-06T14:08:51.334Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c2/36/dfc1ebc0081e6d39924a2cc53654497f967a084a436bb64402dfce4254d9/ruamel.yaml-0.18.10-py3-none-any.whl", hash = "sha256:30f22513ab2301b3d2b577adc121c6471f28734d3d9728581245f1e76468b4f1", size = 117729, upload-time = "2025-01-06T14:08:47.471Z" },
]
[[package]]
name = "subprocess-tee"
version = "0.4.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d7/22/991efbf35bc811dfe7edcd749253f0931d2d4838cf55176132633e1c82a7/subprocess_tee-0.4.2.tar.gz", hash = "sha256:91b2b4da3aae9a7088d84acaf2ea0abee3f4fd9c0d2eae69a9b9122a71476590", size = 14951, upload-time = "2024-06-17T19:51:51.249Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/4d/ab/e3a3be062cd544b2803760ff707dee38f0b1cb5685b2446de0ec19be28d9/subprocess_tee-0.4.2-py3-none-any.whl", hash = "sha256:21942e976715af4a19a526918adb03a8a27a8edab959f2d075b777e3d78f532d", size = 5249, upload-time = "2024-06-17T19:51:15.949Z" },
]
[[package]]
name = "wcmatch"
version = "10.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "bracex" },
]
sdist = { url = "https://files.pythonhosted.org/packages/41/ab/b3a52228538ccb983653c446c1656eddf1d5303b9cb8b9aef6a91299f862/wcmatch-10.0.tar.gz", hash = "sha256:e72f0de09bba6a04e0de70937b0cf06e55f36f37b3deb422dfaf854b867b840a", size = 115578, upload-time = "2024-09-26T18:39:52.505Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ab/df/4ee467ab39cc1de4b852c212c1ed3becfec2e486a51ac1ce0091f85f38d7/wcmatch-10.0-py3-none-any.whl", hash = "sha256:0dd927072d03c0a6527a20d2e6ad5ba8d0380e60870c383bc533b71744df7b7a", size = 39347, upload-time = "2024-09-26T18:39:51.002Z" },
]
[[package]]
name = "yamllint"
version = "1.37.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pathspec" },
{ name = "pyyaml" },
]
sdist = { url = "https://files.pythonhosted.org/packages/46/f2/cd8b7584a48ee83f0bc94f8a32fea38734cefcdc6f7324c4d3bfc699457b/yamllint-1.37.1.tar.gz", hash = "sha256:81f7c0c5559becc8049470d86046b36e96113637bcbe4753ecef06977c00245d", size = 141613, upload-time = "2025-05-04T08:25:54.355Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/dd/b9/be7a4cfdf47e03785f657f94daea8123e838d817be76c684298305bd789f/yamllint-1.37.1-py3-none-any.whl", hash = "sha256:364f0d79e81409f591e323725e6a9f4504c8699ddf2d7263d8d2b539cd66a583", size = 68813, upload-time = "2025-05-04T08:25:52.552Z" },
]
[[package]]
name = "zipp"
version = "3.21.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/3f/50/bad581df71744867e9468ebd0bcd6505de3b275e06f202c2cb016e3ff56f/zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4", size = 24545, upload-time = "2024-11-10T15:05:20.202Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b7/1a/7e4798e9339adc931158c9d69ecc34f5e6791489d469f5e50ec15e35f458/zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931", size = 9630, upload-time = "2024-11-10T15:05:19.275Z" },
]

@ -1 +0,0 @@
Subproject commit 81afa59a5ac7aea580db01186dc8f3de9cf997d6

View File

View File

@ -0,0 +1,3 @@
{
"ansible.python.interpreterPath": "/bin/python"
}

View File

@ -0,0 +1,35 @@
# Laptop Ansible Setup Playbook
# Tasks
Install packages for
- Pycharm
- curl
- wget
- git
- vim
- htop
- unzip
- gimp
- pcsc-tools
- pcsc-perl
- ccid
- glib-perl
- opensc
- pcsclite
- gparted
- nodejs
- snap
- npm
- libpamac-flatpal-plugin
- traceroute
- sublime-text
- vlc
- timeshift
- firefox
Setup trucktrav user as paswordless sudo
Change SSH port

View File

@ -0,0 +1,9 @@
[defaults]
inventory = inventories/inventory.yml
interpreter_python = auto
stdout_callout = yaml
collections_path = .dependencies
roles_path = .dependencies:roles
[diff]
always = true

View File

@ -0,0 +1,54 @@
---
- name: Configure Ubuntu for user trucktrav
hosts: all
become: yes
tasks:
- name: Ensure the system is updated
apt:
update_cache: yes
upgrade: dist
- name: Apt | Install defaults
ansible.builtin.apt:
update_cache: false
name: "{{ default_apps + (extra_apps | default([])) }}"
state: present
register: apt_defaults
retries: 3
until: apt_defaults is success
- name: Create the user trucktrav
user:
name: trucktrav
shell: /bin/bash
create_home: yes
groups: sudo
append: yes
- name: Set authorized key for trucktrav
authorized_key:
user: trucktrav
state: present
key: "{{ lookup('file', 'files/trucktrav.pub') }}"
- name: Ensure sudoers file allows passwordless sudo for trucktrav
lineinfile:
path: /etc/sudoers
line: "trucktrav ALL=(ALL) NOPASSWD: ALL"
validate: "visudo -cf %s"
- name: Ensure SSH service is enabled and running
service:
name: ssh
state: started
enabled: yes
# todo
# snap install --classic code
#dnf config-manager --enable ansible-automation-platform-2.4-for-rhel-8-x86_64-rpms
#dnf install ansible-core ansible-navigator ansible-lint ansible-builder
#python3 -m pip install ansible-lint --break-system-packages

View File

View File

@ -0,0 +1,6 @@
---
roles:
collections:

View File

@ -0,0 +1,34 @@
#vars file
default_aps:
- Pycharm
- curl
- wget
- git
- vim
- htop
- unzip
- gimp
- pcsc-tools
- pcsc-perl
- ccid
- glib-perl
- opensc
- pcsclite
- gparted
- nodejs
- snap
- npm
- libpamac-flatpal-plugin
- traceroute
- sublime-text
- vlc
- timeshift
- firefox
- ansible
- ansible-lint
- python-ansible
- python-pipx
- uv
- python-ansible-compat
- dnf