diff --git a/README.md b/README.md
index 493ef26..62bb178 100644
--- a/README.md
+++ b/README.md
@@ -1,39 +1,66 @@
-A new beginning for what used to be my
-[conf_dir](https://github.com/kejadlen/conf_dir) project, since `dotfiles`
-appears to be the conventional name of these types of repos nowadays.
+# Dotfiles
-This uses [Ansible](https://github.com/ansible/ansible) to provision new
-machines.
+This repo contains both my dotfiles as well as [Ansible][ansible] playbooks to
+provision new machines.
+
+**Use at your own risk.** Untested except on my own El Capitan installs.
+
+[ansible]: https://github.com/ansible/ansible
+
+# Playbooks
+
+- `bootstrap.yml`: SSH and Homebrew setup
+- `main.yml`: Pretty much everything else
+- `imac.yml`: For quieting down the broken HDD fan on my iMac
+- `macbook_pro.yml`: Remap Caps Lock to Control on the laptop
# Usage
-There are two ways to go about using this - either locally or remotely. The main
-difference is that OS X application settings are only copied over when running
-this on a remote machine.
+First, some steps need to be performed on the remote machine that I couldn't
+figure out how to automate:
-Either way, we start with installing Xcode:
+- Enable Remote Login in System Preferences -> Sharing.
+- Install the command line developer tools: `xcode-select --install`. (It looks
+like the Homebrew installer [_should_][xcode-select-cli] be able to handle
+this, but I haven't been able to get it to work headless.)
+- Install Xcode: `open 'https://itunes.apple.com/us/app/xcode/id497799835?mt=12'`
+- Accept the Xcode license: `sudo xcodebuild -license`
+- Accept the sudo disclaimer: `sudo -v`
-``` shell
-xcode-select --install
-open 'https://itunes.apple.com/us/app/xcode/id497799835?mt=12'
-sudo xcodebuild -license
+[xcode-select-cli]: https://github.com/Homebrew/install/blob/master/install#L207-L216
+
+On the control machine:
+
+```
+brew install ansible
+git clone --recursive git@github.com:kejadlen/dotfiles
+cd dotfiles/ansible
+
+echo HOST > hosts.private
+
+ansible-playbook bootstrap.yml --ask-pass --ask-become-pass
+ansible-playbook main.yml --ask-become-pass
```
-**After running Ansible**, there are some optional tasks for full desktop setup:
+A couple items that I haven't gotten around to automating yet that need to be
+manually run post-provisioning:
``` shell
-# Remove the bootstrap directory for the canonical one in Dropbox
-rm -rf ~/.dotfiles
-ln -s ~/Dropbox/dotfiles ~/.dotfiles
-
# Apply personal Terminal settings
open ~/.dotfiles/Alpha.terminal
+# Symlink ~/.dotfiles to Dropbox
+rm -rf ~/.dotfiles
+ln -s ~/Dropbox/dotfiles ~/.dotfiles
+
# Add private SSH keys
ruby ~/.dotfiles/scripts/setup_ssh_keys.rb
```
-## Local
+## Provisioning Locally
+
+You can also use this to provision a machine by itself, although this won't
+be able to copy over OS X application settings, for obvious reasons.
``` shell
# Install Homebrew
@@ -46,31 +73,14 @@ brew install ansible
git clone --recursive https://github.com/kejadlen/dotfiles.git ~/.dotfiles
# Run Ansible
-cd ~/.dotfiles/ansible && ansible-playbook main.yml --ask-sudo-pass
-rm -f ~/*.retry
-```
-
-## Remote
-
-On the remote machine, SSH access must first be enabled (under System
-Preferences -> Sharing) and the Xcode Command Line Tools need to be installed
-(`xcode-select --install`).
-
-``` shell
-cd ~/.dotfiles/ansible && ansible-playbook main.yml --ask-pass --ask-sudo-pass
-```
-
-# Misc
-
-To update submodules:
-
-``` shell
-git submodule foreach git pull
+cd ~/.dotfiles/ansible
+echo localhost > hosts.private
+ansible-playbook main.yml --ask-pass --ask-become-pass
```
# Development
-Ansible tags are indispensible when tweaking the config.
+Ansible tags are indispensible when tweaking the config:
```
- command: echo debug
@@ -78,14 +88,7 @@ Ansible tags are indispensible when tweaking the config.
```
``` shell
-ansible-playbook main.yml --ask-sudo-pass --tags debug
-```
-
-# Vagrant
-
-``` shell
-vagrant up
-ansible vagrant -m ping
+ansible-playbook main.yml --ask-become-pass --tags=debug
```
# TODO
diff --git a/ansible/.gitignore b/ansible/.gitignore
deleted file mode 100644
index 8000dd9..0000000
--- a/ansible/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-.vagrant
diff --git a/ansible/Vagrantfile b/ansible/Vagrantfile
deleted file mode 100644
index 7e8de7d..0000000
--- a/ansible/Vagrantfile
+++ /dev/null
@@ -1,122 +0,0 @@
-# -*- mode: ruby -*-
-# vi: set ft=ruby :
-
-# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
-VAGRANTFILE_API_VERSION = "2"
-
-Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
- # All Vagrant configuration is done here. The most common configuration
- # options are documented and commented below. For a complete reference,
- # please see the online documentation at vagrantup.com.
-
- # Every Vagrant virtual environment requires a box to build off of.
- config.vm.box = "ubuntu/trusty64"
-
- # Disable automatic box update checking. If you disable this, then
- # boxes will only be checked for updates when the user runs
- # `vagrant box outdated`. This is not recommended.
- # config.vm.box_check_update = false
-
- # Create a forwarded port mapping which allows access to a specific port
- # within the machine from a port on the host machine. In the example below,
- # accessing "localhost:8080" will access port 80 on the guest machine.
- # config.vm.network "forwarded_port", guest: 80, host: 8080
-
- # Create a private network, which allows host-only access to the machine
- # using a specific IP.
- # config.vm.network "private_network", ip: "192.168.33.10"
-
- # Create a public network, which generally matched to bridged network.
- # Bridged networks make the machine appear as another physical device on
- # your network.
- # config.vm.network "public_network"
-
- # If true, then any SSH connections made will enable agent forwarding.
- # Default value: false
- # config.ssh.forward_agent = true
-
- # Share an additional folder to the guest VM. The first argument is
- # the path on the host to the actual folder. The second argument is
- # the path on the guest to mount the folder. And the optional third
- # argument is a set of non-required options.
- # config.vm.synced_folder "../data", "/vagrant_data"
-
- # Provider-specific configuration so you can fine-tune various
- # backing providers for Vagrant. These expose provider-specific options.
- # Example for VirtualBox:
- #
- # config.vm.provider "virtualbox" do |vb|
- # # Don't boot with headless mode
- # vb.gui = true
- #
- # # Use VBoxManage to customize the VM. For example to change memory:
- # vb.customize ["modifyvm", :id, "--memory", "1024"]
- # end
- #
- # View the documentation for the provider you're using for more
- # information on available options.
-
- # Enable provisioning with CFEngine. CFEngine Community packages are
- # automatically installed. For example, configure the host as a
- # policy server and optionally a policy file to run:
- #
- # config.vm.provision "cfengine" do |cf|
- # cf.am_policy_hub = true
- # # cf.run_file = "motd.cf"
- # end
- #
- # You can also configure and bootstrap a client to an existing
- # policy server:
- #
- # config.vm.provision "cfengine" do |cf|
- # cf.policy_server_address = "10.0.2.15"
- # end
-
- # Enable provisioning with Puppet stand alone. Puppet manifests
- # are contained in a directory path relative to this Vagrantfile.
- # You will need to create the manifests directory and a manifest in
- # the file default.pp in the manifests_path directory.
- #
- # config.vm.provision "puppet" do |puppet|
- # puppet.manifests_path = "manifests"
- # puppet.manifest_file = "default.pp"
- # end
-
- # Enable provisioning with chef solo, specifying a cookbooks path, roles
- # path, and data_bags path (all relative to this Vagrantfile), and adding
- # some recipes and/or roles.
- #
- # config.vm.provision "chef_solo" do |chef|
- # chef.cookbooks_path = "../my-recipes/cookbooks"
- # chef.roles_path = "../my-recipes/roles"
- # chef.data_bags_path = "../my-recipes/data_bags"
- # chef.add_recipe "mysql"
- # chef.add_role "web"
- #
- # # You may also specify custom JSON attributes:
- # chef.json = { mysql_password: "foo" }
- # end
-
- # Enable provisioning with chef server, specifying the chef server URL,
- # and the path to the validation key (relative to this Vagrantfile).
- #
- # The Opscode Platform uses HTTPS. Substitute your organization for
- # ORGNAME in the URL and validation key.
- #
- # If you have your own Chef Server, use the appropriate URL, which may be
- # HTTP instead of HTTPS depending on your configuration. Also change the
- # validation key to validation.pem.
- #
- # config.vm.provision "chef_client" do |chef|
- # chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME"
- # chef.validation_key_path = "ORGNAME-validator.pem"
- # end
- #
- # If you're using the Opscode platform, your validator client is
- # ORGNAME-validator, replacing ORGNAME with your organization name.
- #
- # If you have your own Chef Server, the default validation client name is
- # chef-validator, unless you changed the configuration.
- #
- # chef.validation_client_name = "ORGNAME-validator"
-end
diff --git a/ansible/ansible.cfg b/ansible/ansible.cfg
index 8d7ca41..808be45 100644
--- a/ansible/ansible.cfg
+++ b/ansible/ansible.cfg
@@ -1,5 +1,4 @@
[defaults]
-hostfile = hosts.private
-retry_files_enabled = False
-retry_files_save_path = /dev/null
-# ask_sudo_pass = True
+hostfile = hosts.private
+retry_files_enabled = False
+pipelining = True
diff --git a/ansible/bootstrap.yml b/ansible/bootstrap.yml
new file mode 100644
index 0000000..3062b4d
--- /dev/null
+++ b/ansible/bootstrap.yml
@@ -0,0 +1,25 @@
+- hosts: all
+ tasks:
+ - name: Clone dotfiles repo into ~/.dotfiles
+ git:
+ repo: https://github.com/kejadlen/dotfiles.git
+ recursive: yes
+ dest: ~/.dotfiles
+ accept_hostkey: yes
+ version: ansible-2 # TODO Don't check this in
+
+ - name: create ~/.ssh
+ file: dest=~/.ssh state=directory
+
+ - name: symlink ~/.ssh/authorized_keys so future plays don't need a password
+ file: src=~/.dotfiles/.ssh/authorized_keys dest=~/.ssh/authorized_keys state=link
+
+ # This is necessary since we want to enable sudo when running the Homebrew
+ # install script but don't want to run it as root. Yeah, I know.
+ - name: authenticate sudo
+ ping:
+ become: yes
+
+ - name: install Homebrew
+ shell: /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" < /dev/null
+ when: ansible_distribution == "MacOSX"
diff --git a/ansible/dotfiles.yml b/ansible/dotfiles.yml
deleted file mode 100644
index 15f1aa0..0000000
--- a/ansible/dotfiles.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-- hosts: all
- roles:
- - dotfiles
diff --git a/ansible/ec2.yml b/ansible/ec2.yml
deleted file mode 100644
index 19834a1..0000000
--- a/ansible/ec2.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-- hosts: ec2
- vars:
- user: ubuntu
- group: ubuntu
- tasks:
- - apt: update_cache=yes
- sudo: true
- - apt: name={{ item }} state=present
- sudo: true
- with_items:
- - nginx
- - git
-
- - file: path=/etc/nginx/sites-enabled/default state=absent
- sudo: true
- notify: reload nginx
-
- - include: tiddlywiki/tasks.yml
-
- handlers:
- - name: reload nginx
- service: name=nginx state=reloaded
diff --git a/ansible/hosts b/ansible/hosts
deleted file mode 100644
index 98668f3..0000000
--- a/ansible/hosts
+++ /dev/null
@@ -1,7 +0,0 @@
-[local]
-localhost ansible_connection=local
-
-[remote]
-
-[test]
-# vagrant ansible_ssh_host=127.0.0.1 ansible_ssh_port=2222 ansible_ssh_user=vagrant ansible_ssh_private_key_file=/Users/alpha/.vagrant.d/insecure_private_key
diff --git a/ansible/imac.yml b/ansible/imac.yml
new file mode 100644
index 0000000..0e3f4fc
--- /dev/null
+++ b/ansible/imac.yml
@@ -0,0 +1,8 @@
+- hosts: all
+ tasks:
+ - name: install sleepwatcher
+ homebrew_cask: name=sleepwatcher state=installed
+ - name: install smcfancontrol
+ homebrew_cask: name=smcfancontrol state=installed
+ - name: link ~/.wakeup
+ file: src=~/.dotfiles/scripts/kill_imac_hdd_fan.rb dest=~/.wakeup state=link
diff --git a/ansible/intro_example.yml b/ansible/intro_example.yml
new file mode 100644
index 0000000..87fbddf
--- /dev/null
+++ b/ansible/intro_example.yml
@@ -0,0 +1,28 @@
+---
+# this is an annotated example of some features available in playbooks
+# it shows how to make sure packages are updated, how to make sure
+# services are running, and how to template files. It also demos
+# change handlers that can restart things (or trigger other actions)
+# when resources change. For more advanced examples, see example2.yml
+
+# on all hosts, run as the user root...
+
+- name: example play
+ hosts: all
+
+# could have also have done:
+# remote_user: mdehaan
+# sudo: yes
+
+ # make these variables available inside of templates
+ # for when we use the 'template' action/module later on...
+
+ vars:
+ http_port: 80
+ max_clients: 200
+
+ # define the tasks that are part of this play...
+
+ tasks:
+ - name: ping
+ ping:
diff --git a/ansible/laptop.yml b/ansible/laptop.yml
deleted file mode 100644
index 111eefa..0000000
--- a/ansible/laptop.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-- hosts: local
- tasks:
- - file: path={{ ansible_env.HOME }}/Applications state=directory
-
- - homebrew_tap: name=caskroom/cask state=present
- - homebrew: name=brew-cask state=present
-
- - name: get id for built-in keyboard
- shell: ioreg -n IOHIDKeyboard -r | grep -e VendorID\" -e ProductID | ruby -e 'print ARGF.read.scan(/\d+/).join(?-)'
- register: keyboard_id
- - name: s/caps lock/ctrl/
- command: defaults -currentHost write -g com.apple.keyboard.modifiermapping.{{ keyboard_id.stdout }}-0 -array-add 'HIDKeyboardModifierMappingDst2HIDKeyboardModifierMappingSrc0'
diff --git a/ansible/macbook_pro.yml b/ansible/macbook_pro.yml
new file mode 100644
index 0000000..fb94a96
--- /dev/null
+++ b/ansible/macbook_pro.yml
@@ -0,0 +1,8 @@
+- hosts: all
+ tasks:
+ - name: register keyboard_id
+ shell: ioreg -n IOHIDKeyboard -r | grep -e VendorID\" -e ProductID | ruby -e 'print ARGF.read.scan(/\d+/).join(?-)'
+ register: keyboard_id
+
+ - name: s/caps lock/ctrl/
+ command: defaults -currentHost write -g com.apple.keyboard.modifiermapping.{{ keyboard_id.stdout }}-0 -array-add 'HIDKeyboardModifierMappingDst2HIDKeyboardModifierMappingSrc0'
diff --git a/ansible/main.yml b/ansible/main.yml
index 461d376..ad64983 100644
--- a/ansible/main.yml
+++ b/ansible/main.yml
@@ -1,5 +1,28 @@
+---
+- hosts: all
+ tasks:
+ - group_by: key=os_{{ ansible_distribution }}
+
+- hosts: all
+ pre_tasks:
+ - name: update dotfiles repo
+ git:
+ repo: https://github.com/kejadlen/dotfiles.git
+ dest: ~/.dotfiles
+ version: ansible-2 # TODO Don't check this in
+ - name: Update Homebrew
+ homebrew: update_homebrew=yes
+
+- hosts: os_MacOSX
+ roles:
+ - role: homebrew
+ when: ansible_distribution == "MacOSX"
+ - role: osx
+ when: ansible_distribution == "MacOSX"
+
- hosts: all
roles:
- - bootstrap
- - { role: osx, when: ansible_distribution == "MacOSX" }
- dotfiles
+ - ruby
+ - powerline
+ - zsh
diff --git a/ansible/nested_playbooks.yml b/ansible/nested_playbooks.yml
new file mode 100644
index 0000000..dd863a7
--- /dev/null
+++ b/ansible/nested_playbooks.yml
@@ -0,0 +1,25 @@
+---
+# it is possible to have top level playbook files import other playbook
+# files. For example, a playbook called could include three
+# different playbooks, such as webservers, workers, dbservers, etc.
+#
+# Running the site playbook would run all playbooks, while individual
+# playbooks could still be run directly. This is somewhat like
+# the tag feature and can be used in conjunction for very fine grained
+# control over what you want to target when running ansible.
+
+- name: this is a play at the top level of a file
+ hosts: all
+ tasks:
+ - name: say hi
+ tags: foo
+ shell: echo "hi..."
+
+# and this is how we include another playbook, be careful and
+# don't recurse infinitely or anything. Note you can't use
+# any variables in the include path here.
+
+- include: intro_example.yml
+
+# and if we wanted, we can continue with more includes here,
+# or more plays inline in this file
diff --git a/ansible/playbooks/dnsmasq.yml b/ansible/playbooks/dnsmasq.yml
deleted file mode 100644
index 06b76fc..0000000
--- a/ansible/playbooks/dnsmasq.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-# TODO
-# - Only run on OS X?
-# - Better reloading of dnsmasq after re-configuring
-- hosts: all
- tasks:
- - homebrew: name=dnsmasq state=present
- - file: src=~/.dotfiles/dnsmasq/dnsmasq.conf dest=/usr/local/etc/dnsmasq.conf state=link
- - shell: cp -fv /usr/local/opt/dnsmasq/*.plist /Library/LaunchDaemons
- become: yes
- - file: path=/Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist owner=root
- become: yes
- - file: path=/usr/local/etc/dnsmasq.d state=directory
- - get_url:
- url: http://pgl.yoyo.org/adservers/serverlist.php?hostformat=dnsmasq&showintro=0&startdate%5Bday%5D=&startdate%5Bmonth%5D=&startdate%5Byear%5D=&mimetype=plaintext
- dest: /usr/local/etc/dnsmasq.d/adblock.conf
- - command: launchctl load /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
- become: yes
- - command: launchctl stop /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
- become: yes
- ignore_errors: True
- - command: launchctl start /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
- become: yes
- ignore_errors: True
diff --git a/ansible/resolver.yml b/ansible/resolver.yml
deleted file mode 100644
index 0c8a973..0000000
--- a/ansible/resolver.yml
+++ /dev/null
@@ -1,32 +0,0 @@
----
-- hosts: all
- vars:
- dnsmasq_conf: "{{ ansible_env.HOME }}/Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist"
- tasks:
- - include: tasks/update_dotfiles.yml
- - name: Install Dnsmasq
- homebrew: name=dnsmasq state=present
- - name: Stow dnsmasq.conf
- command: chdir={{ ansible_env.HOME }}/.dotfiles stow --target=/usr/local/etc --stow dnsmasq
- - name: Make local LaunchDaemons directory
- file: path={{ ansible_env.HOME }}/Library/LaunchDaemons state=directory
- - name: Delete old launchd config
- sudo: True
- file: path={{ dnsmasq_conf }} state=absent
- # Copy the config instead of linking since it needs to be owned by root.
- - name: Copy launchd config
- sudo: True
- command: cp /usr/local/opt/dnsmasq/homebrew.mxcl.dnsmasq.plist {{ dnsmasq_conf }}
- - name: Fix launchd config permissions
- sudo: True
- file: path={{ ansible_env.HOME }}/Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist owner=root
- - name: Load Dnsmasq
- sudo: True
- command: launchctl load {{ dnsmasq_conf }}
- - name: Create /etc/resolver
- sudo: True
- file: path=/etc/resolver state=directory
- # Link instead of stow since there's a stow bug with relative paths.
- - name: Symlink /etc/resolver/dev
- sudo: True
- file: src={{ ansible_env.HOME }}/.dotfiles/resolver/dev dest=/etc/resolver/dev state=link
diff --git a/ansible/roles/bootstrap/tasks/main.yml b/ansible/roles/bootstrap/tasks/main.yml
deleted file mode 100644
index fc1ac43..0000000
--- a/ansible/roles/bootstrap/tasks/main.yml
+++ /dev/null
@@ -1,10 +0,0 @@
----
-- git:
- repo: https://github.com/kejadlen/dotfiles.git
- recursive: yes
- dest: ~/.dotfiles
- force: no
- ignore_errors: True
-- name: no-op so that sudo works in Homebrew later
- ping:
- sudo: True
diff --git a/ansible/roles/dotfiles/tasks/dotfiles.yml b/ansible/roles/dotfiles/tasks/dotfiles.yml
deleted file mode 100644
index ecce06b..0000000
--- a/ansible/roles/dotfiles/tasks/dotfiles.yml
+++ /dev/null
@@ -1,16 +0,0 @@
----
-- file: path={{ item }} state=directory # TODO Do this automatically
- with_items:
- - ~/.bundle
- - ~/.ssh
- - ~/.vim_tmp
-- file: src=~/.dotfiles/{{ item.key }} dest={{ item.value }} state=link
- with_dict: dotfiles
-- file:
- src: ~/Dropbox/dotfiles/{{ item.key }}
- dest: "{{ item.value }}"
- state: link
- force: yes # Since these won't exist until later.
- with_dict: private
-- file: src={{ item }} dest=~/.ssh/{{ item | basename }} state=link
- with_fileglob: ~/.dotfiles/.ssh/*
diff --git a/ansible/roles/dotfiles/tasks/main.yml b/ansible/roles/dotfiles/tasks/main.yml
index 0b05666..17727d0 100644
--- a/ansible/roles/dotfiles/tasks/main.yml
+++ b/ansible/roles/dotfiles/tasks/main.yml
@@ -1,6 +1,23 @@
----
-- include: dotfiles.yml
- tags: dotfiles
-- include: powerline.yml
- tags: powerline
-- include: zsh.yml
+- name: create config directories
+ file: path={{ item }} state=directory
+ with_items: "{{ conf_dirs }}"
+
+- name: symlink configs
+ file: src=~/.dotfiles/{{ item.key }} dest={{ item.value }} state=link
+ with_dict: "{{ conf_symlinks }}"
+
+- name: force-symlink private configs
+ file:
+ src: ~/Dropbox/dotfiles/{{ item.key }}
+ dest: "{{ item.value }}"
+ state: link
+ force: yes # Since these won't exist until later.
+ with_dict: "{{ private_symlinks }}"
+
+- name: symlink SSH configs
+ file: src={{ item }} dest=~/.ssh/{{ item | basename }} state=link
+ with_fileglob: ~/.dotfiles/.ssh/*
+
+- name: symlink ~/.tmux.conf.local
+ file: src=~/.dotfiles/osx/.tmux.conf.local dest=~/.tmux.conf.local state=link
+ when: ansible_distribution == "MacOSX"
diff --git a/ansible/roles/dotfiles/tasks/powerline.yml b/ansible/roles/dotfiles/tasks/powerline.yml
deleted file mode 100644
index 26c4fbe..0000000
--- a/ansible/roles/dotfiles/tasks/powerline.yml
+++ /dev/null
@@ -1,18 +0,0 @@
----
-- homebrew: name=python state=present
- when: ansible_distribution == "MacOSX"
-- apt: name={{ item }} state=present
- sudo: True
- with_items:
- - python
- - python-pip
- when: ansible_os_family == "Debian"
-- command: >
- /usr/local/bin/pip
- install
- --user
- --editable={{ ansible_env.HOME }}/.dotfiles/src/powerline
-- file: src={{ item }} dest=/usr/local/bin/{{ item | basename }} state=link
- with_fileglob: ~/.dotfiles/src/powerline/scripts/*
-- file: path=~/.config state=directory
-- file: src=~/.dotfiles/powerline dest=~/.config/powerline state=link
diff --git a/ansible/roles/dotfiles/tasks/zsh.yml b/ansible/roles/dotfiles/tasks/zsh.yml
deleted file mode 100644
index 1124d56..0000000
--- a/ansible/roles/dotfiles/tasks/zsh.yml
+++ /dev/null
@@ -1,21 +0,0 @@
----
-- homebrew: name=zsh state=present
- when: ansible_distribution == "MacOSX"
-- apt: name=zsh state=present
- sudo: True
- when: ansible_os_family == "Debian"
-- file:
- src: "{{ ansible_env.HOME }}/.dotfiles/src/prezto"
- dest: "{{ ansible_env.HOME}}/.zprezto"
- state: link
-- file:
- src: "{{ ansible_env.HOME }}/.zprezto/runcoms/{{ item }}"
- dest: "{{ ansible_env.HOME}}/.{{ item }}"
- state: link
- with_lines: ls ~/.zprezto/runcoms | grep -v README.md
-- lineinfile: dest=/etc/shells line=/usr/local/bin/zsh state=present
- sudo: True
- when: ansible_distribution == "MacOSX"
-- command: chsh -s /usr/local/bin/zsh {{ ansible_env.USER }}
- sudo: True
- when: ansible_distribution == "MacOSX"
diff --git a/ansible/roles/homebrew/tasks/main.yml b/ansible/roles/homebrew/tasks/main.yml
new file mode 100644
index 0000000..2235286
--- /dev/null
+++ b/ansible/roles/homebrew/tasks/main.yml
@@ -0,0 +1,31 @@
+- name: install Formulae
+ homebrew:
+ name: "{{ item.name }}"
+ install_options: "{{ item.install_options | default(omit) }}"
+ state: present
+ with_items: "{{ formulae }}"
+
+- name: link Homebrew apps
+ command: /usr/local/bin/brew linkapps
+
+- name: create ~/Applications
+ file: path={{ ansible_env.HOME }}/Applications state=directory
+
+# This is necessary since we want to enable sudo when setting up Homebrew-Cask.
+- name: authenticate sudo
+ ping:
+ become: yes
+
+- name: setup Homebrew-Cask
+ command: /usr/local/bin/brew cask
+
+- name: install casks
+ homebrew_cask: name={{ item }} state=installed
+ with_items: "{{ casks }}"
+
+- name: tap caskroom/fonts
+ homebrew_tap: tap=caskroom/fonts state=present
+
+- name: install fonts
+ homebrew_cask: name=font-{{ item }} state=installed
+ with_items: "{{ fonts }}"
diff --git a/ansible/roles/homebrew/vars/main.yml b/ansible/roles/homebrew/vars/main.yml
new file mode 100644
index 0000000..75b1754
--- /dev/null
+++ b/ansible/roles/homebrew/vars/main.yml
@@ -0,0 +1,50 @@
+formulae:
+ - name: ctags
+ - name: direnv
+ - name: fasd
+ - name: git
+ - name: macvim
+ install_options: with-override-system-vim
+ - name: reattach-to-user-namespace
+ - name: terminal-notifier
+ - name: the_silver_searcher
+ - name: tmux
+ - name: tree
+ - name: youtube-dl
+ - name: zsh
+
+casks:
+ - 1password
+ - acorn
+ - adium
+ - alfred
+ # - anybar
+ - arq
+ - bartender
+ - bittorrent-sync
+ - black-ink
+ - disk-inventory-x
+ - dropbox
+ - fantastical
+ - firefox
+ - flux
+ - google-chrome
+ - little-snitch
+ # - moom
+ - night-owl
+ - omnifocus
+ - openscad
+ - plug
+ - qlmarkdown
+ - qlstephen
+ - quicklook-csv
+ - quicklook-json
+ - slack
+ - steam
+ # - things
+ - transmission
+ - vlc
+
+fonts:
+ - hack
+ - sauce-code-powerline
diff --git a/ansible/roles/osx/handlers/main.yml b/ansible/roles/osx/handlers/main.yml
index eb641b8..7803a25 100644
--- a/ansible/roles/osx/handlers/main.yml
+++ b/ansible/roles/osx/handlers/main.yml
@@ -1,4 +1,4 @@
-- name: restart osx system services
+- name: restart OS X system services
command: killall {{ item }}
with_items:
- Finder
diff --git a/ansible/library/osx_defaults.py b/ansible/roles/osx/library/osx_defaults.py
similarity index 95%
rename from ansible/library/osx_defaults.py
rename to ansible/roles/osx/library/osx_defaults.py
index 0dd7ca8..9ff179c 100644
--- a/ansible/library/osx_defaults.py
+++ b/ansible/roles/osx/library/osx_defaults.py
@@ -19,14 +19,14 @@
DOCUMENTATION = '''
---
module: osx_defaults
-author: Franck Nijhof
+author: Franck Nijhof (@frenck)
short_description: osx_defaults allows users to read, write, and delete Mac OS X user defaults from Ansible
description:
- osx_defaults allows users to read, write, and delete Mac OS X user defaults from Ansible scripts.
Mac OS X applications and other programs use the defaults system to record user preferences and other
information that must be maintained when the applications aren't running (such as default font for new
documents, or the position of an Info panel).
-version_added: 1.8
+version_added: "2.0"
options:
domain:
description:
@@ -47,7 +47,7 @@ options:
description:
- Add new elements to the array for a key which has an array as its value.
required: false
- default: string
+ default: false
choices: [ "true", "false" ]
value:
description:
@@ -124,9 +124,11 @@ class OSXDefaults(object):
if type == "string":
return str(value)
elif type in ["bool", "boolean"]:
- if value.lower() in [True, 1, "true", "1", "yes"]:
+ if isinstance(value, basestring):
+ value = value.lower()
+ if value in [True, 1, "true", "1", "yes"]:
return True
- elif value.lower() in [False, 0, "false", "0", "no"]:
+ elif value in [False, 0, "false", "0", "no"]:
return False
raise OSXDefaultsException("Invalid boolean value: {0}".format(repr(value)))
elif type == "date":
@@ -209,13 +211,16 @@ class OSXDefaults(object):
# We need to convert some values so the defaults commandline understands it
if type(self.value) is bool:
- value = "TRUE" if self.value else "FALSE"
+ if self.value:
+ value = "TRUE"
+ else:
+ value = "FALSE"
elif type(self.value) is int or type(self.value) is float:
value = str(self.value)
elif self.array_add and self.current_value is not None:
value = list(set(self.value) - set(self.current_value))
- elif isinstance(self.value, datetime):
- value = self.value.strftime('%Y-%m-%d %H:%M:%S')
+ # elif isinstance(self.value, datetime):
+ # value = self.value.strftime('%Y-%m-%d %H:%M:%S')
else:
value = self.value
@@ -306,7 +311,7 @@ def main():
array_add=dict(
default=False,
required=False,
- choices=BOOLEANS,
+ type='bool',
),
value=dict(
default=None,
@@ -340,7 +345,7 @@ def main():
array_add=array_add, value=value, state=state, path=path)
changed = defaults.run()
module.exit_json(changed=changed)
- except OSXDefaultsException as e:
+ except OSXDefaultsException, e:
module.fail_json(msg=e.message)
# /main ------------------------------------------------------------------- }}}
diff --git a/ansible/roles/osx/tasks/bootstrap.yml b/ansible/roles/osx/tasks/bootstrap.yml
deleted file mode 100644
index fdab52f..0000000
--- a/ansible/roles/osx/tasks/bootstrap.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-- name: ensure that Xcode is installed
- command: command -v xcodebuild
-
-- name: install homebrew
- shell: ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
- args:
- creates: /usr/local/bin/brew
diff --git a/ansible/roles/osx/tasks/casks.yml b/ansible/roles/osx/tasks/casks.yml
deleted file mode 100644
index 423c7f7..0000000
--- a/ansible/roles/osx/tasks/casks.yml
+++ /dev/null
@@ -1,18 +0,0 @@
----
-- include_vars: casks.yml
-
-- file: path={{ ansible_env.HOME }}/Applications state=directory
-
-# - homebrew: name=caskroom/cask/brew-cask state=upgraded
-- homebrew_tap: name=caskroom/cask state=present
-- homebrew: name=brew-cask state=present
-
-- homebrew_cask: name={{ item }} state=installed
- with_items: casks
-
-- synchronize:
- src: "{{ item }}"
- dest: "{{ item | regex_replace(' ', '\ ') }}"
- rsync_opts: --ignore-existing
- with_items: prefs
- tags: prefs
diff --git a/ansible/roles/osx/tasks/defaults.yml b/ansible/roles/osx/tasks/defaults.yml
deleted file mode 100644
index 7fb21ed..0000000
--- a/ansible/roles/osx/tasks/defaults.yml
+++ /dev/null
@@ -1,10 +0,0 @@
----
-- include_vars: defaults.yml
-
-- osx_defaults:
- domain: "{{ item.domain | default(omit) }}"
- key: "{{ item.key }}"
- type: "{{ item.type }}"
- value: "{{ item.value }}"
- with_items: osx_defaults
- notify: restart osx system services
diff --git a/ansible/roles/osx/tasks/dock.yml b/ansible/roles/osx/tasks/dock.yml
index 72f27b3..83a8638 100644
--- a/ansible/roles/osx/tasks/dock.yml
+++ b/ansible/roles/osx/tasks/dock.yml
@@ -1,12 +1,20 @@
----
-- homebrew: name=dockutil state=present
+- name: install dockutil
+ homebrew: name=dockutil state=present
+
- command: /usr/local/bin/dockutil --list
register: dockutil_result
-- command: /usr/local/bin/dockutil --remove all
+- name: remove all Dock icons
+ command: /usr/local/bin/dockutil --remove all
when: not (dockutil_result.stdout_lines | length == 1 and dockutil_result.stdout | search("^Downloads"))
-- command: /usr/local/bin/dockutil --add ~/Downloads
+- name: add ~/Downloads to the Dock
+ command: /usr/local/bin/dockutil --add ~/Downloads
--view list
--display stack
--sort datemodified
when: not (dockutil_result.stdout_lines | length == 1 and dockutil_result.stdout | search("^Downloads"))
-- homebrew: name=dockutil state=absent
+
+- name: remove Dockutil
+ homebrew: name=dockutil state=absent
+
+- name: restart Dock
+ command: killall Dock
diff --git a/ansible/roles/osx/tasks/fonts.yml b/ansible/roles/osx/tasks/fonts.yml
deleted file mode 100644
index ed3bc52..0000000
--- a/ansible/roles/osx/tasks/fonts.yml
+++ /dev/null
@@ -1,7 +0,0 @@
----
-- include_vars: fonts.yml
-
-- homebrew_tap: tap=caskroom/fonts state=present
-
-- homebrew_cask: name={{ item }} state=installed
- with_items: fonts
diff --git a/ansible/roles/osx/tasks/formulae.yml b/ansible/roles/osx/tasks/formulae.yml
deleted file mode 100644
index 397dbf1..0000000
--- a/ansible/roles/osx/tasks/formulae.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-- include_vars: formulae.yml
-- homebrew:
- name: "{{ item.name }}"
- install_options: "{{ item.install_options | default(omit) }}"
- state: present
- with_items: formulae
-- command: /usr/local/bin/brew linkapps
diff --git a/ansible/roles/osx/tasks/main.yml b/ansible/roles/osx/tasks/main.yml
index b6cb9a1..d79449a 100644
--- a/ansible/roles/osx/tasks/main.yml
+++ b/ansible/roles/osx/tasks/main.yml
@@ -1,20 +1,28 @@
----
-- include: bootstrap.yml
-- include: formulae.yml
+- name: copy application preferences
+ synchronize:
+ src: "{{ item }}"
+ dest: "{{ item | regex_replace(' ', '\ ') }}"
+ rsync_opts: --ignore-existing
+ with_items: "{{ app_prefs }}"
+
- include: dock.yml
- tags: dock
-- include: casks.yml
- tags: casks
-- include: fonts.yml
-- include: defaults.yml
- tags: defaults
+
+- name: set OS X defaults
+ osx_defaults:
+ domain: "{{ item.domain | default(omit) }}"
+ key: "{{ item.key }}"
+ type: "{{ item.type }}"
+ value: "{{ item.value }}"
+ with_items: "{{ osx_defaults }}"
+ notify: restart OS X system services
- file: path=~/Library/KeyBindings state=directory
-- file:
+- name: Symlink Emacs-style keybindings for OS X
+ file:
src: ~/.dotfiles/osx/DefaultKeyBinding.dict
dest: ~/Library/KeyBindings/DefaultKeyBinding.dict
state: link
-- file: src=~/.dotfiles/osx/Colors dest=~/Library/Colors state=link
-# TODO This should probably be moved to the dotfiles role.
-- file: src=~/.dotfiles/osx/.tmux.conf.local dest=~/.tmux.conf.local state=link
+- name: symlink OS X colors palettes
+ file: src={{ item }} dest=~/Library/Colors/{{ item | basename }} state=link
+ with_fileglob: ~/.dotfiles/osx/Colors/*
diff --git a/ansible/roles/osx/vars/casks.yml b/ansible/roles/osx/vars/casks.yml
deleted file mode 100644
index 411ff96..0000000
--- a/ansible/roles/osx/vars/casks.yml
+++ /dev/null
@@ -1,33 +0,0 @@
----
-casks:
- - 1password
- - adium
- - alfred
- - anybar
- - bartender
- - bittorrent-sync
- - black-ink
- - dropbox
- # - fantastical
- - firefox
- - flux
- - google-chrome
- - mailbox
- - moom
- - plug
- - qlmarkdown
- - qlstephen
- - quicklook-csv
- - quicklook-json
- - steam
- - terminal-notifier
- - things
- - transmission
- - vlc
- - yorufukurou
-prefs:
- - ~/Library/Application Support/Adium 2.0/
- - ~/Library/Preferences/com.adiumX.adiumX.plist
- - ~/Library/Preferences/com.adiumX.adiumX.plist
- - ~/Library/Preferences/com.culturedcode.things.plist
- - ~/Library/Preferences/com.YoruFukurouProject.YoruFukurou.plist
diff --git a/ansible/roles/osx/vars/fonts.yml b/ansible/roles/osx/vars/fonts.yml
deleted file mode 100644
index 54e23d7..0000000
--- a/ansible/roles/osx/vars/fonts.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-fonts:
- - font-sauce-code-powerline
- - font-hack
diff --git a/ansible/roles/osx/vars/formulae.yml b/ansible/roles/osx/vars/formulae.yml
deleted file mode 100644
index 1b49fa1..0000000
--- a/ansible/roles/osx/vars/formulae.yml
+++ /dev/null
@@ -1,16 +0,0 @@
----
-formulae:
- - name: chruby
- - name: ctags
- - name: direnv
- - name: fasd
- - name: git
- - name: macvim
- install_options: override-system-vim
- - name: ruby-install
- - name: reattach-to-user-namespace
- - name: the_silver_searcher
- - name: tmux
- - name: tree
- - name: youtube-dl
- - name: zsh
diff --git a/ansible/roles/osx/vars/defaults.yml b/ansible/roles/osx/vars/main.yml
similarity index 88%
rename from ansible/roles/osx/vars/defaults.yml
rename to ansible/roles/osx/vars/main.yml
index 21145e1..340fac2 100644
--- a/ansible/roles/osx/vars/defaults.yml
+++ b/ansible/roles/osx/vars/main.yml
@@ -1,4 +1,3 @@
----
osx_defaults:
# This is named `osx_defaults` since there's an Ansible conflict when this key
# is named just `defaults`.
@@ -101,12 +100,12 @@ osx_defaults:
value: true
- domain: com.apple.driver.AppleBluetoothMultitouch.trackpad
key: DragLock
- type: int
- value: 1
+ type: bool
+ value: true
- domain: com.apple.driver.AppleBluetoothMultitouch.trackpad
key: Dragging
- type: int
- value: 1
+ type: bool
+ value: true
# Finder defaults
- # don't ask when changing file extension
@@ -150,3 +149,12 @@ osx_defaults:
key: AppleEnableSwipeNavigateWithScrolls
type: bool
value: false
+
+app_prefs:
+ - ~/Library/Application Support/Adium 2.0/
+ - ~/Library/Preferences/com.adiumX.adiumX.plist
+ - ~/Library/Preferences/com.culturedcode.things.plist
+ - ~/Library/Preferences/com.YoruFukurouProject.YoruFukurou.plist
+ - ~/Library/Preferences/com.surteesstudios.Bartender.plist
+ - ~/Library/Preferences/com.flexibits.fantastical.plist
+ - ~/Library/Preferences/org.herf.Flux.plist
diff --git a/ansible/roles/powerline/tasks/main.yml b/ansible/roles/powerline/tasks/main.yml
new file mode 100644
index 0000000..de6351b
--- /dev/null
+++ b/ansible/roles/powerline/tasks/main.yml
@@ -0,0 +1,13 @@
+- name: install Python
+ homebrew: name=python state=present
+
+- name: install Powerline
+ command: >
+ /usr/local/bin/pip
+ install
+ --user
+ --editable={{ ansible_env.HOME }}/.dotfiles/src/powerline
+
+- name: symlink Powerline configs
+ file: src={{ item }} dest=/usr/local/bin/{{ item | basename }} state=link
+ with_fileglob: ~/.dotfiles/src/powerline/scripts/*
diff --git a/ansible/roles/ruby/tasks/main.yml b/ansible/roles/ruby/tasks/main.yml
new file mode 100644
index 0000000..b3bfc58
--- /dev/null
+++ b/ansible/roles/ruby/tasks/main.yml
@@ -0,0 +1,8 @@
+- name: install chruby
+ homebrew: name={{ item }} state=present
+ with_items:
+ - chruby
+ - ruby-install
+
+- name: install Ruby
+ command: /usr/local/bin/ruby-install ruby
diff --git a/ansible/roles/zsh/tasks/main.yml b/ansible/roles/zsh/tasks/main.yml
new file mode 100644
index 0000000..b2cf096
--- /dev/null
+++ b/ansible/roles/zsh/tasks/main.yml
@@ -0,0 +1,27 @@
+- name: install ZSH
+ homebrew: name=zsh state=present
+
+- name: symlink ~/.zprezto
+ file:
+ src: "{{ ansible_env.HOME }}/.dotfiles/src/prezto"
+ dest: "{{ ansible_env.HOME}}/.zprezto"
+ state: link
+
+- name: get Prezto runcoms from dotfiles
+ shell: ls ~/.zprezto/runcoms | grep -v README.md
+ register: prezto_runcoms
+
+- name: symlink Prezto runcoms
+ file:
+ src: "{{ ansible_env.HOME }}/.zprezto/runcoms/{{ item }}"
+ dest: "{{ ansible_env.HOME}}/.{{ item }}"
+ state: link
+ with_items: "{{ prezto_runcoms.stdout_lines }}"
+
+- name: add /usr/local/bin/zsh to /etc/shells
+ lineinfile: dest=/etc/shells line=/usr/local/bin/zsh state=present
+ become: yes
+
+- name: set the default user shell to zsh
+ user: name={{ ansible_env.USER }} shell=/usr/local/bin/zsh
+ become: yes
diff --git a/ansible/sudo.yml b/ansible/sudo.yml
deleted file mode 100644
index 28177bb..0000000
--- a/ansible/sudo.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-- hosts: prgmr
- tasks:
- - name: setup sudo
- apt: pkg=sudo state=latest
- - name: add users to sudo group
- user: name={{ item }} append=yes groups=sudo state=present
- with_items:
- - alpha
- - name: copy sudoers file
- command: cp -f /etc/sudoers /tmp/sudoers
- - name: backup sudoers file
- command: cp -f /tmp/sudoers /tmp/sudoers.bak
- - name: don't require a password for sudo group in /tmp/sudoers
- lineinfile: "dest=/tmp/sudoers state=present regexp='^%sudo' line='%sudo ALL=(ALL:ALL) NOPASSWD: ALL'"
- - name: check /tmp/sudoers and update /etc/sudoers
- shell: visudo -qcf /tmp/sudoers && cp -f /tmp/sudoers /etc/sudoers
diff --git a/ansible/tiddlywiki/nginx.conf b/ansible/tiddlywiki/nginx.conf
deleted file mode 100644
index 9d5270b..0000000
--- a/ansible/tiddlywiki/nginx.conf
+++ /dev/null
@@ -1,8 +0,0 @@
-server {
- listen 80;
-
- location / {
- proxy_pass http://localhost:8080;
- proxy_set_header X-Forwarded-Host $host;
- }
-}
diff --git a/ansible/tiddlywiki/tasks.yml b/ansible/tiddlywiki/tasks.yml
deleted file mode 100644
index 3dbae40..0000000
--- a/ansible/tiddlywiki/tasks.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-- include_vars: tiddlywiki/vars.yml.private
-
-- apt: name={{ item }} state=present
- sudo: true
- with_items:
- - nodejs
- - nodejs-legacy
- - npm
-
-# Use TiddlyWiki from source until this fix is released:
-# https://github.com/Jermolene/TiddlyWiki5/issues/1474
-#
-# - npm: name=tiddlywiki global=yes state=present
-# sudo: true
-#
-- git: repo=https://github.com/Jermolene/TiddlyWiki5.git dest=~/TiddlyWiki5
- notify: restart tiddlywiki
-- command: npm link chdir=~{{ user }}/TiddlyWiki5
- sudo: true
-
-- command: tiddlywiki ~/tiddlywiki --init server
- args:
- creates: ~/tiddlywiki
-- copy: src=tiddlywiki/nginx.conf dest=/etc/nginx/conf.d/tiddlywiki.conf
- sudo: true
- notify: reload nginx
-- template: src=tiddlywiki/upstart.conf.j2 dest=/etc/init/tiddlywiki.conf
- sudo: true
-
-- name: restart tiddlywiki
- service: name=tiddlywiki state=restarted
- sudo: true
diff --git a/ansible/tiddlywiki/upstart.conf.j2 b/ansible/tiddlywiki/upstart.conf.j2
deleted file mode 100644
index 71bd6ff..0000000
--- a/ansible/tiddlywiki/upstart.conf.j2
+++ /dev/null
@@ -1,12 +0,0 @@
-description "TiddlyWiki"
-author "Alpha Chen"
-
-start on started network-services
-stop on stopping network-services
-
-setuid {{ user }}
-setgid {{ group }}
-
-console log
-
-exec tiddlywiki /home/{{ user }}/tiddlywiki --server 8080 $:/core/save/all text/plain text/html alpha "{{ password }}"
diff --git a/ansible/roles/dotfiles/vars/main.yml b/ansible/vars/dotfiles.yml
similarity index 80%
rename from ansible/roles/dotfiles/vars/main.yml
rename to ansible/vars/dotfiles.yml
index 6a777a2..7240f29 100644
--- a/ansible/roles/dotfiles/vars/main.yml
+++ b/ansible/vars/dotfiles.yml
@@ -1,16 +1,21 @@
-dotfiles:
+conf_dirs:
+ - ~/.bundle
+ - ~/.ssh
+ - ~/.vim_tmp
+
+conf_symlinks:
gitignore: ~/.gitignore
.bundle/config: ~/.bundle/config
+ .config: ~/.config
.gemrc: ~/.gemrc
.git_templates: ~/.git_templates
.gitconfig: ~/.gitconfig
.hammerspoon: ~/.hammerspoon
- # .pentadactyl: ~/.pentadactyl
.pentadactylrc: ~/.pentadactylrc
.pryrc: ~/.pryrc
.tmux.conf: ~/.tmux.conf
.vim: ~/.vim
.vimrc: ~/.vimrc
-private:
- .config: ~/.config
+
+private_symlinks:
.gitconfig.private: ~/.gitconfig.private