Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Dotfiles and dev tools provisioned by Ansible (palcu.blogspot.com)
19 points by palcu on June 22, 2014 | hide | past | favorite | 21 comments


Several months ago, I became pretty interested in the idea of a unified computer setup. Between my home computers and work computers, it began weighing on me mentally to have to switch contexts all the time. I'd forget which machine had `wget`, which `fish` functions were installed on which host, etc. The most tedious thing was the process of setting up a new computer: painstakingly finding each and every little configuration I had on my other machines, and copying them over. I'd spend half a day just setting up a new machine. I wanted something better.

I first tried Ira's [mackup](https://github.com/lra/mackup), which syncs files to Dropbox. Its catch-all approach scared me, though, as it backs up `fish` history by default. I decided to move to something different.

I ended up basing my dotfiles setup on the GNU [stow](https://www.gnu.org/software/stow/) utility. Here's how it works:

- In `~`, I have a git-managed directory `dotfiles`

- For every new app I use, I make a new directory in `dotfiles`. For example, `vim`, `fish`, etc.

- I run `stow` on all these directories, and it symlinks everything into place

I ended up rolling my own update script, but it's pretty trivial. I also made heavy use of Homebrew brewfiles, which can be used to define what commands you would like to run through Homebrew. I also use [Homebrew Cask](http://caskroom.io/) to install apps.

In the end, I now have the exact same configuration on all my machines. For work, I have a separate branch, which has other fish functions / utilities. I recently got a new computer, and I ran the `update.sh` script while I went to lunch. When I came back, my machine was ready to go.

Take a look at my setup [here](https://github.com/peterhajas/dotfiles).


I think it would be better to use the "--no-folding" argument to stow in your update.sh script, otherwise stow will do something which I find undesired:

- let's say you have a file ~/dotfiles/vim-powerlinefonts/.config/fontconfig/conf.d/10-powerlinefonts.conf and you don't have the ~/.config/fontconfig directory

- when you do "stow vim-powerlinefonts" in the dotfiles directory it will create ~/.config/fontconfig as a symlink to your ~/dotfiles/vim-powerlinefonts/.config/fontconfig directory so now you can't add other fontconfig files in ~/.config/fontconfig/conf.d

- if instead you do "stow --no-folding vim-powerlinefonts" in the dotfiles directory it will create ~/.config/fontconfig/conf.d/ and there it will symlink 10-powerlinefonts.conf to ~/dotfiles/vim-powerlinefonts/.config/fontconfig/conf.d/10-powerlinefonts.conf, which is usually what you want.


I generally prefer xstow[1] to GNU Stow (if for no other reason than that it doesn't require perl) -- and I couldn't find a reference to --no-folding -- however, at least xstow appear to do the right thing:

    stow $ find ..
    ..
    ../stow
    ../stow/a
    ../stow/a/c
    ../stow/a/c/a
    ../stow/a/c/b
    ../stow/b
    ../stow/b/c
    ../stow/b/c/c
    ../stow/b/c/c/a

    $ xstow b
    $ ls -l ..
    total 4
    lrwxrwxrwx 1 e12e e12e    8 Jun 22 16:47 c -> stow/b/c
    drwxr-xr-x 4 e12e e12e 4096 Jun 22 16:44 stow
   
    #drumrolll...
    $ xstow a
    $ ls -l ..
    total 8
    drwxr-xr-x 2 e12e e12e 4096 Jun 22 16:48 c
    drwxr-xr-x 4 e12e e12e 4096 Jun 22 16:44 stow
    e12e@stripe:~/tmp/stowtest/stow $ ls -l ../c
    total 0
    lrwxrwxrwx 1 e12e e12e 13 Jun 22 16:48 a -> ../stow/a/c/a
    lrwxrwxrwx 1 e12e e12e 13 Jun 22 16:48 b -> ../stow/a/c/b
    lrwxrwxrwx 1 e12e e12e 13 Jun 22 16:48 c -> ../stow/b/c/c
    
So as long as the symlink is managed by (xstow) -- subdirs will be created as needed. If your point was more about mixing (x)stow'ed and non-stowed files in directories, then you would still want to make sure (x)stow makes the directories, and only symlinks files.

I'm not sure if there's an (easy) way to make xstow do that.

[1] http://xstow.sourceforge.net/


Yes, I was thinking specifically about mixing stowed and non-stowed files in directories, that's why I chose the fontconfig example: it's likely that I will want to add files there that I don't want to stow/sync to other machines. I also find it cleaner using --no-folding and easier to reason about. I remember feeling surprised and not understanding what stow did the first time I used it without --no-folding. Some people might actually prefer the folding behavior, I just wanted to highlight that the default behavior might not be what one would expect.


Why ansible? I'm storing my dotfiles in a private git repo and sync across multiple laptops. Works fine so far.

Put the dotfiles and directories into git. Symlink from ~/.vim to ~/dotfiles/.vim and be done with it. (~/dotfiles would contain the git checkout of course).


I was also using a simple bootstrap script and I too felt I was "killing mosquitos with a bazooka" using Ansible.

But I wanted to symlink my Sublime settings. That meant tinkering with shell code and separating the files in different dirs. Then I wanted to preinstall my Brew apps, but only for Mac.

So these tasks pilled up in shell scripts and became ugly. So Ansible, with it's easy YAML configs, is the perfect tool for a dev like me that wants to setup machines and maintain the configurations synced.


You should take a look at GNU stow. I also felt the same frustration as my bootstrap script got ugly and uglier. And then I shifted to stow. And now its just a single line:

    stow * --target ~
With respect to ansible, I've been thinking of managing my laptop using just ansible to install new packages, and update configuration (apache, sshd and so on). Kinda like chef-solo, but using ansible. Has anyone done anything like that?


Thanks for the tip about Stow, never knew about it and I will research it.

Ansible can be used for your local machine without any central server by default. I use this[0] playbook to update my packages daily on my DigitalOcean machines.

[0]: https://github.com/palcu/dotfiles/blob/master/playbooks/task...


I think that's the better way to to it (at least compared to ansible/chef/puppet/etc). I additionally use GNU Stow for doing the symlinking.


Sounds interesting. Could you explain a bit more how this works, briefly? I find the GNU stow page not really good to understand and lack some example of how it would be used...


Sure, I use a pretty simple setup:

I have a ~/dotfiles directory in which I have one directory for each program/entity I want to manage using stow. Let's say I want to manage my GNOME keyrings and my settings for the program EasyStroke. My ~/dotfiles directory would look like this:

  ~/dotfiles
  ├── easystroke
  │   └── .easystroke
  │       ├── actions-0.5.6
  │       └── preferences-0.5.5
  └── keyrings
      └── .local
          └── share
              └── keyrings
                  ├── login.keyring
                  └── user.keystore
Then, in ~/dotfiles I can do "stow easystroke" and it will create ~/.easystroke and there it will symlink "actions-0.5.6" to ~/dotfiles/easystroke/.easystroke/ actions-0.5.6 and "preferences-0.5.5" to ~/dotfiles/easystroke/.easystroke/preferences-0.5.5


What's the advantage over doing (assuming GNU cp):

  cp -sr ~/dotfiles/easystroke/.easystroke ~/


Stow can handle multiple directories in one go. For my powerline config:

    vim-powerlinefonts
    ├── .config
    │   └── fontconfig
    │       └── conf.d
    │           └── 10-powerline-symbols.conf
    └── .local
        └── share
            └── fonts
                └── PowerlineSymbols.otf
I just do "stow vim-powerlinefonts" and it creates the directories and symlinks as needed.

For your cp example I would have to do "cp -sr ..." twice and also think about missing directories in the tree, and possibly create them.


Question on stow that you might have knowledge on.

Could I say have stow manage separate or conflicting files?

An example is in order, say for work I have a .gitconfig that has a separate email address etc... and for home I have basically the same but not quite. Would there be any easy-ish way to say something akin to: ok this is the base of things, these are the generalized components that override?

I have a jacky way of doing this now but any way to eliminate the nonsense would be helpful. xstow looks interesting however.


Stow can do that if you only need files to be replaced, not sections of files. Let's say you want to manage the file ~/test/.gitconfig, you can create this structure:

  $ cd ~/gittest
  $ tree -a
  ~/gittest/
  ├── gitconfig-home
  │   └── test
  │       └── .gitconfig
  └── gitconfig-work
      └── test
          └── .gitconfig
  $ cat ~/gittest/gitconfig-home/test/.gitconfig
  git config 1
  $ cat ~/gittest/gitconfig-work/test/.gitconfig
  git config 2
  $ stow --no-folding --override='.+/.gitconfig' gitconfig-home
  $ cat ~/test/.gitconfig 
  git config 1
  $ stow --no-folding --override='.+/.gitconfig' gitconfig-work
  $ cat ~/test/.gitconfig 
  git config 2
If you need to manage sections of files, take a look at dotdee[0] or update-dotdee[1]

[0] - https://launchpad.net/dotdee [1] - https://pypi.python.org/pypi/update-dotdee


That helps thanks. So note for now I just copy/update my entire gitconfig and replace the one off changes every so often.

Its not ideal but each difference is really an entire file. I worded my question poorly in that regard but i'll have a look at dotdee.

I'm somewhat tempted to just use m4 for generating the dot files for things that may change and doing a conf.d type setup that just lets me copy a fragment file into place then instantiate the file.


I recently shifted to stow as well. You can see my configuration on github[0].

[0]: http://github.com/captn3m0/dotfiles


That has to be the worst webdesign I have seen this week. Not only does it require JS to show anything but a blank page but it displays an "inner-window" window. Dear web gods, why?

http://i.imgur.com/qBHLCac.png


FWIW, Google Cache can serve you HTML for these Dynamic Views blogs; just prefix the URL with https://webcache.googleusercontent.com/search?q=cache:

e.g. https://webcache.googleusercontent.com/search?q=cache:http:/...

Incidentally, it's the only place you can get HTML for these blogs, and I suspect that Blogspot has special-cased Googlebot to give it HTML instead a pile of JavaScript.

For convenience, I have this bookmarklet bound to my 'c' keyword in Firefox:

  javascript:(function(){window.open('https://webcache.googleusercontent.com/search?q=cache:'+(''+window.location));})();


Thanks for the tip. I'm using NoScript/HTTPSwitchboard and have long been frustrated by javascript being required to show even simple posts on blogspot.


I still use Blogspot because moving my posts to another platform would mean too much time lost. I prefer to invest this time in hacking and writing articles. But yes, the desktop experience is a little awful. However, it's the only theme that works flawless on tablets and mobile devices.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: