New Blog

I’m no longer posting to this blog.

All new updates will go to my page.

Using Puppet + Augeas to turn off usb ports

no usb

Augeas and Puppet can team up to modify the modprobe config files

My blog posts always seem to start with a question asked on stackexchange or This is no exception.

Danilo asked if puppet was able to block access to usb ports on linux machines. I decided to flex the Augeas muscle.


tl;dr Here is a working solution

class blockusb {

   augeas {'block usb-storage':
    context   =>"/files/etc/modprobe.d/blacklist.conf/",
    changes =>["set blacklist[last()+1] usb-storage",],
    onlyif =>"match blacklist[.='usb-storage'] size == 0 ",
include blockusb


The match functionality in augeas is very non intuitive. Instinct would suggest that the following solution should work:

onlyif =>"match blacklist not_include 'usb-storage' ",

However as pointed out by Dominic in the user list, match returns a list of paths, not the values of those paths.  While you *can* see the values of the path when using augtool from the command line, those values are not included in Augeas’s API call.

 augtool> match /files/etc/modprobe.d/blacklist.conf/blacklist
/files/etc/modprobe.d/blacklist.conf/blacklist[1] = evbug
/files/etc/modprobe.d/blacklist.conf/blacklist[2] = usbmouse
/files/etc/modprobe.d/blacklist.conf/blacklist[3] = usbkbd
/files/etc/modprobe.d/blacklist.conf/blacklist[16] = amd76x_edac
/files/etc/modprobe.d/blacklist.conf/blacklist[17] = usb-storage


By requesting the actual usb-storage value in the tree and then checking it’s length we are able to return a boolean. The result is that puppet will only modify the blacklist.conf file once.


Share single .bashrc across multiple linux machines

Often I manage many servers and find myself wishing I had the same shortcuts available on my workstation, also present on the server.

Normally I’d use puppet to manage the .bashrc or .bash_profile, but my workstations don’t have a puppet master. To work around this, I store my .bash_profile on github, and have a script to update it automatically.

Here is the script to update my bash_profile

       curl -L > ~/.bash_profile

The actual bash profile is located here

    alias ls='ls -G'
    alias sl='ls -G'
    alias up='cd ..'
    alias redo='sudo \!-1'
    alias sdou='sudo'
    alias suod='sudo'
    alias sodu='sudo'
    alias tailf='tail -f'
    # Open sublime text editor with command subl
    if [ ! -f /usr/local/bin/subl ]; then /bin/ln -s /Applications/Sublime\ /usr/local/bin/subl; fi;

Now on every machine I manage, I run the following command just once

    curl -L | bash -x

After that, I can just execute the bashupdate alias to pull down the latest version.

    spuder@Spuders-MacBook-Pro:~$ bashupdate

Open a new terminal, or source your ~/.bash_profile and you will instantly have the new changes. Pretty slick right?

Recovering from lost git commit messages

I posted a question and answer to stack overflow that explains how to undo the dangerous -c flag in git.

If ever you accidentially overwrite a commit message using git commit –amend, you can easily undo it by search the .git/logs directory. There will still be a hash that points to the previous object which will contain the original message. 



git pre-receive hooks.

In my attempts to block users from committing code as root users which I mentioned in my previous blog post; I’ve identified an unusual behavior in git.


Git pre-receive hooks do not have any parameters passed in, but rather query stdin for parameters.

To demonstrate, create the following file on your git server


set -x

echo "$# parameters have been passed in"


Then try and push code


spencer@workstation:/tmp/hooktest3$ git push
Counting objects: 11, done.

Delta compression using up to 4 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (9/9), 731 bytes | 0 bytes/s, done

remote: + echo '0 parameters have been passed in'

The correct way to evaluate the incoming commit is with


while read oldsha newsha refname; do
    case $oldsha,$newsha in
    *,$NULL_SHA1) # it's a delete
        echo "delete request received";;
    $NULL_SHA1,*) # it's a create
       echo creating $newsha";;
    *,*) # it's an update
        echo "updating with $newsha";;

So why is this important?
This is the only way to parse an incoming git commit. You can then evaluate the commit to see who the author is, what type of commit ect..

Thanks go to torek for pointing this out on my stack overflow question here:

Changing the author on git commits

Some of the users at my company have been accidentally creating and pushing git commits as the root user.


While trying to setup a script to block these commits, I found an interesting quirk of git.

Many guides online suggest amending the git author like so:

git commit --amend --author

This unfortunately only changes the author, and not the committer. To prove this I created the following test.

Set the user name and email

git config "bad user" --replace-all
git config ""

Now make a commit and check the  output of git log.

git log
commit bf4343f6a41978ef5c1236c558aeab9415d17601
Author: bad user <>

Change the author

git commit --amend --author "good guy <>"

Check the full output of the last commit. You will notice that while the author is correct, the committer is incorrect.

git log --format=full
commit 52ee52afde053b5c2102760011359dd4ad7fea47
Author: good guy <>
Commit: bad user <>


The correct way to change the author *and* the committer is with the following command:

git config "good guy" --replace-all
git config ""

git commit --amend --reset-author

Now everything works properly

commit 52ee52afde053b5c2102760011359dd4ad7fea47
Author: good guy <>
Commit: good guy <>


Navigate linux ‘info’ command

The command ‘info’ can provide additional information that isn’t present in the man pages. Unfortunately it isn’t easy to navigate.

A trick is learned is to add the following to your ~/.bashrc file

function infos () {
info --vi-keys --subnodes -o - "$@" | less;

Now you can call infos (with an s), to be able to navigate the info page.


$ infos ls

Thanks to Evan Teitelman for pointing this out on unix.stackexchange


Get every new post delivered to your Inbox.