Skip to content

benfiola/dotfiles

Repository files navigation

dotfiles

This is my personal dotfiles project and supports macOS, Ubuntu, Archlinux operating systems on arm64 and amd64 architectures (to varying degrees).

Requirements

  • ansible
  • git

If running on MacOS, additionally:

  • 'Full-disk access' Terminal permissions

Basic usage

Running the following command will fully personalize your local machine.

# clone dotfiles repo to target location
git clone [email protected]:benfiola/dotfiles.git ~/.dotfiles
cd ~/.dotfiles

# install ansible galaxy dependencies
ansible-galaxy install -r requirements.yaml

# symlink collection into ansible galaxy install location
mkdir -p ~/.ansible/collections/ansible_collections/benfiola
ln -s "$(pwd)" ~/.ansible/collections/ansible_collections/benfiola/dotfiles

# run collection
LOCAL=1 ansible-playbook benfiola.dotfiles.main

Ansible?

Generally, dotfiles projects provide a mix of static configuration and bootstrapping scripts to provision a local computing environment. However, the effort to provide bootstrapping scripts that comprehensively provision an arbirary machine (architecture, os, package manager) eventually becomes significant - ansible is more capable of accomplishing this goal.

Expected outcome and conventions

When this ansible playbook is run, the following outcomes are expected:

  • Files at $HOME/.profile.d are sourced when terminal sessions are created
  • Helper shell scripts are implemented as functions/aliases provided via sourced files in $HOME/.profile.d
  • Helper scripts that exist beyond the terminal session are installed to /usr/local/bin
  • File-based configuration is symlinked/hardlinked from the project's clone path to their expected location (such that local configuration change leaves the cloned repo in a dirty state)
  • Script-based configuration is applied on every playbook execution (e.g., gsettings settings)
  • All necessary, supported applications are installed
  • OS, desktop environments, and applications are all configured and themed appropriately

Inventory

Inventory is defined from the environment via the benfiola.dotfiles.environmnent inventory plugin.

Envioronment Variable Description
LOCAL When set to a truthy value, playbook will be applied to the local machine. One of LOCAL or REMOTE_IP must be provided.
REMOTE_IP When set to a truthy value, playbook will be applied to the provided IP address. One of LOCAL or REMOTE_IP must be provided.

Playbook

The benfiola.dotfiles.main playbook lists all available roles in vague dependency order to ensure that downstream roles are fulfilled by upstream roles

Tags ultimately filter down the roles that are executed.

Roles

Roles are intended to be analogous to software libraries and often represent the installation and configuration of core functionality. Ideally, any role should be able to be isolated and deployed to ansible-galaxy without any modification. All roles can be found here.

As an example of a role's functionality, the zsh role will:

  • Install zsh
  • Set zsh as the shell for the current user
  • Install a zshrc file.

The decision to create a role (versus adding to an existing role's task list) is arbitrary - but is generally a decision made on a mix of complexity (e.g., wine has a lot of explicit package dependencies) or replaceability (e.g., konsole could get swapped out for another terminal emulator).

Dependencies on other roles are manually enforced at the playbook level - care should be taken to ensure that facts used by the role are fulfilled by an upstream role.

Tags

Tags are utilized to apply various levels of personalization to the target machine.

Tags need to be composed - personalizing a machine with a graphical environment requires minimal,graphical tags.

Tag Name Description
minimal installs programs and configuration required for command line interactivity
graphical installs programs and configuration required for graphical interactivity
optional installs programs and configuration unrelated to development

By default, all tags (minimal,graphical,optional) are applied.

Additionally, each role is tagged with its name - allowing you to target specific roles by name.

Task lists

Role task lists are structured to:

  • Have a common set of tags applied to all tasks within the role
  • Inform the end-user when a task might be incompletely implemented
  • Guarding all subsequent tasks against fall-through when incompletely implemented

As a result, role task lists often look like the following:

---
# apply common tags
- tags: [<tag>, <role_name>]
  block:
    # this block only gets executed in the fall-through case
    - when: not (darwin or (linux and amd64))
      block:
        - name: unimplemented
          empty: {}
    
    # guards for one os
    - when: darwin
      block:
        - debug:
            msg: darwin
    
    # guard for an os + architecture combination
    - when: linux and amd64
      block:
        - debug:
            msg: linux + amd64 task

    # guard common tasks
    - when: darwin or (linux and amd64)
      block:
        - debug:
            msg: common task
...

Custom modules

Generally, tasks that require a bit of processing or state aren't a great fit for ansible task lists. To avoid needlessly complex common tasks within ansible, some functionality is instead implemented as custom ansible modules.

Task Description
benfiola.dotfiles.asdf_plugin Helps manage (un)installation of asdf plugins
benfiola.dotfiles.empty No-op task - used primarily to identify 'unimplemented' paths within role implementations
benfiola.dotfiles.temp_file Creates a temp file on the target machine
benfiola.dotfiles.temp_file_cleanup Cleans up created temp files on the target machine - must be manually run before the end of the playbook run

Notes

  • This is the rough sequence of steps I go through to install arch linux from scratch. You'll need to substitute details where necessary (i.e., device paths).

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages