Technical Musings: January 2013

Wednesday, January 30, 2013

'yum update' that excludes Puppet managed files

I have many machines that I manage with Puppet. If you have more than one machine, you need to use a tool like it. It does a great job of managing the configuration of packages that we use directly or are direct dependencies. But we do not put every package that is installed on a box in Puppet; I don't think anyone does this. On our boxes we have around 500 packages installed. I imagine some environment would have the time to review each rpm to ensure it was compatible, and then change it's version in Puppet, ensuring that no dependencies for that package have changed. A much more realistic approach is to just update a test machine to the latest, and then test out your application, only reviewing the changes for the packages that are direct dependencies. Even better would be to have yum update all packages except the packages you have specified in Puppet. You want all the basic upgrades, like a kernel update, without changing that version of ruby you have been using.

How to do this?

First, run puppet a puppet no operation test, to update the local catalog:

/usr/bin/puppet agent --onetime --ignorecache --server ${puppet_master} \
 --no-daemonize --verbose --detailed-exitcodes \
 --logdest /var/log/puppet/puppet.log --noop --test

Then build up a list of packages that are controlled by Puppet, and exclude them from a 'yum update' command:

packages=$(grep "reference:\ \"Package" /var/lib/puppet/client_yaml/catalog/*.yaml \
| awk -F"[" '{print $2}' \
| awk -F"]" '{print $1}')

exclude=$(for package in ${packages};do echo -n " -x ${package}";done); 

yum update ${exclude}

You could use a similar approach with other package managers like apt.

Found the data when I checked out puppet-ls

Friday, January 25, 2013

OSX SSH Terminal Console Coloring, Redux

I've come up with a much better, simpler recipe to color my OSX Terminal session depending on the host I'm ssh-ing into. First, take a function with some cool BASH-only splitting and arrays and add that I found a way to address the current session in Applescript. Then add a one line way to enable bash ssh auto-complete when using the function. Ensure you pass all args to SSH so you can tunnel, etc. Finish with another line to switch the colors back to some default when you disconnect. Add this to your .profile, and voila!

This function assumes a certain host naming scheme, and that you have a Terminal profile for each environment.  I just copied 'Basic', and changed the background colors.  If you can't parse your server names, you need a better naming scheme ;)

ash() {
    IFS=" "
    set -- $ARGS 
    ARGSARRAY=( $@ )
    set -- ${HOST}
    MYARRAY=( $@ )
    if [ "${ENVNAME}" = "pro" ]; then
        if [ "${serverType}" = "p19" ]; then
            PROFILE="Basic Green"
            PROFILE="Basic Black"
    elif [ "${ENVNAME}" = "qa" ]; then
       PROFILE="Basic Grey"
    elif [ "${ENVNAME}" = "stage" ]; then
        PROFILE="Man Page"
    elif [ "${ENVNAME}" = "shadow" ]; then
        PROFILE="Basic Blue"
    echo "tell app \"Terminal\" to set current settings of first window to settings set \"${PROFILE}\"" | osascript
    ssh "${ARGS}" 

    echo "tell app \"Terminal\" to set current settings of first window to settings set \"Basic\"" | osascript 
complete -o default -o nospace -F _ssh ash
$ ash
will ssh to and set the background to black, and when I logout, the background will be set to white.


One limitation currently, is that the hostname must be the first argument.

Another slight disadvantage is that you have to type something other than 'ssh'.  You could rename the ssh binary to something else, and then name the function 'ssh'.   Don't just name the function 'ssh' w/out renaming the binary (try it and find out why!)

Ideas taken from everywhere, including: