It is no secret that
I use GNU Emacs
as my default text editor. It is perhaps less evident but no less
relevant that I use Emacs 24. I really like the built-in color theme
support and the package management system for getting the various
modes I like to use.
Recently, I revamped my
Emacs configuration. This
post isn’t about that topic. Instead, this post is about how I made
sure that all the systems I want to use Emacs on have the latest
version available.
Unfortunately, Emacs 24 is still unreleased, so it is not available as
the default package on the distributions I use for my personal systems
(Ubuntu/Debian flavors). I wrote a recipe to install Emacs
from source. This is easy enough to do, but since I already automate
everything on my home network with Chef, it was a natural fit for a
new recipe. I simply added this to my local emacs cookbook, in
recipes/source24.rb.
Then I updated my base role to replace recipe[emacs] with
recipe[emacs::source24] and ran Chef. It took about 25 minutes to do
the build, but now I have the same version of Emacs everywhere, and
there was much rejoicing.
And yes, you’re absolutely right, I could just build a package and
install that. However, I don’t want to set up and maintain a package
management repository for my small network, as
easy as that may be.
My OS X systems are a special case because I’m using Homebrew, but the
homebrew cookbook does not [yet?] support
install-time options, and I didn’t spend the time adding support for
building the OS X Emacs w/ cocoa support from git. When I tackle that,
I’ll make another post, so stay tuned!
Mac OS X Lion introduced a new nifty feature called AirDrop. This
allows users on a local network to drag and drop files to each other
with Finder.
While it seems that this would be useful, there are security
implications. After looking through
Google Search Results
on the topic, I found some un-helpful information in a random forum
post (unsurprising). A little more
review of the search results
resulted in finding the actual defaults(1) command to do so:
If you change a class name in your library, do a major version
change! You don’t know who is using your library, even the
undocumented parts.
Background
Recently, we had a post on the
Chef mailing list that using bluepill for
the Chef Server daemon process(es) was broken. Upon further
investigation of the output from
Chef debug output, it appeared to
be an issue with
Bluepill itself, but
after looking into that ticket, the daemons gem had made a change.
Out of curiosity, I was compelled to find out what the source of the
change in the daemons gem was. This lead to a yak shave, as first, I
had to look up the daemons gem on
RubyGems.org to try and find the source. The author of the gem still
uses RubyForge rather than GitHub. That’s fine, but it means I have to
do some link-spelunking to find where the source code lives.
Now I take a look at the change log:
Release 1.1.8: February 7, 2012
rename to daemonization.rb to daemonize.rb (and Daemonization to Daemonize) to ensure compatibility.
Release 1.1.7: February 6, 2012
start_proc: Write out the PID file in the newly created proc to avoid race conditions.
daemonize.rb: remove to simplify licensing (replaced by daemonization.rb).
Release 1.1.6: January 18, 2012
Add the :app_name option for the "call" daemonization mode.
Release 1.1.5: December 19, 2011
Catch the case where the pidfile is empty but not deleted and restart
the app (thanks to Rich Healey)
I then went to the ticket tracker to find out what the source of the
changes might be. Fortunately, there was an open issue that I could
reference.
My question (which I posted to the ticket) is why wouldn’t renaming a
class cause the author to do a new major version? This way other Gems
that rely on this as a dependency could use the paranoia operator,
~> so the broken class name wouldn’t break usage elsewhere.
I’m glad that the daemons gem author did the right thing and yanked
the broken version. Open source worked well here. The process of
finding this was a bit slower than it should have been, and I think
that the bluepill maintainers moved too quickly to “resolve” the
issue, rather than post their concern about the class naming. Kudos to
thuehlinger for fixing his gem, though.
I primarily use this to manage the VMware Fusion virtual machines I
use for testing Opscode’s Chef Cookbooks.
This post is rather light on specific details about things that are
either “common” knowledge or documented elsewhere. Particularly, I
won’t tell you how to set up the virtual machines, other than a few
notes that I think make it easier to manage virtual machines in this
way. In other words, you’re smart and can figure them out.
Install and Configure
The first step to use the fission RubyGem is to install it. If you
don’t like RubyGems, then create a package or grab the source from the
GitHub link, above.
gem install fission
Test that it is detecting your VMware Fusion VMs:
fission status
Fission has a configuration file, ~/.fissionrc, which is yaml
format. If the status command fails, you may need to configure fission
to find the vmrun command. Here’s the example from my system:
If you’re reading this, I presume you know how to install an OS in a
VMware virtual machine. I do a number of tasks during the installation
to make it easy and consistent to work with all my test VMs.
Use bridged networking with DHCP
This usually results in the least amount of hassle for connecting to
the VM without any tunneling or port forwarding tomfoolery.
Give it a simple VM name with alphanumeric characters only.
Use the same hostname during installation as the VM name
In the examples below, I use my “guineapig” system. I also have other
systems like “ubuntu1110”, “freebsd82” and “centos6”. This is the name
you’ll use to refer to the VM with fission, so it should be short,
easy to type and clearly identifiable.
Set the root password, even if the OS doesn’t use the root account
Make sure SSH as root is enabled
Some Linux distributions such as Ubuntu do not enable the root login.
This is for testing, so I really don’t care, and I can always write a
Chef recipe to lock things down (as I would in production) if
required.
I also set a simple password that I can use with -P to knife
bootstrap without the shell doing anything with special characters.
Use NTP
Install the NTP package for your operating system. The workflow here
(and the whole point really) is to make heavy use of VMware Fusion
snapshots and rollback, so it is important that the system time is
correct. I customized the bootstrap templates I use to add ntpdate.
Using Fission
And now the moment you’ve been waiting for. First, see the fission
README for full detail on the commands available. I’m going to focus
here on how I use it.
After the install and post install tasks are done, I create a
new snapshot for the VM.
% fission status
guineapig [running]
% fission snapshot create guineapig base
The name is “base” because thats a good name for a baseline. It can be
useful to create specifically named snapshots for particular purposes.
I use Opscode Hosted Chef as my server and I already have my local
workstation set up with the validation key, a Chef repository and have
uploaded the cookbook(s) I use for testing. I’ll use “knife
bootstrap” to kick off a run on my VM:
% knife bootstrap 10.1.1.129 -x root -Pvanilla -r 'recipe[apache2]'
...
INFO: service[apache2] restarted
INFO: Chef Run complete in 44.324473 seconds
Sweet, it worked. However, if the Chef run fails, I can log in as
root, fix the bug and rerun, or whatever else may need to be done.
Then once I’m ready to reset the VM, fission comes back to play.
% fission snapshot revert guineapig base
Reverting to snapshot 'base'
Reverted to snapshot 'base'
Note that fission will poweroff the VM when reverting the snapshot.
Turn it on again with the start command.
% fission status
guineapig [not running]
% fission start guineapig
Starting 'guineapig'
VM 'guineapig' started
% fission status
guineapig [running]
And after logging in, we can see that apache2 is not installed as it
should not be after the snapshot is restored.
% ssh root@guineapig
root@guineapig's password:
root@guineapig:~# dpkg -l apache2
No packages found matching apache2.
The VM is now ready to do my bidding once again.
Cleanup
Note that reverting the snapshot doesn’t delete the Chef node or
client objects. Since fission is a Ruby library, a simple knife plugin
can wrap up all the fission revert, restart and Chef cleanup, though.
I called mine nukular.
% knife nukular guineapig base guineapig.int.example.com
And here’s the plugin I’m using:
12345678910111213141516171819202122
require'chef/knife'moduleKnifePluginsclassNukular<Chef::Knifedepsdorequire'fission'require'chef/node'require'chef/api_client'endbanner"knife nukular VM SNAPSHOT [NODE]"defrunvm,snapshot=@name_argsnode=@name_args[2].nil??vm:@name_args[2]Fission::Command::SnapshotRevert.new(args=[vm,snapshot]).executeFission::Command::Start.new(args=[vm]).executeChef::Node.load(node).destroyChef::ApiClient.load(node).destroyendendend
The command-line usage takes 2 or 3 arguments. The first two must be
the VM name and the snapshot name, e.g. guineapig and base. If the
node name is different than the VM name, then specify it.
% knife nukular guineapig base guineapig.int.example.com
Note that the plugin has zero error handling or any other sensible
things. You may want to modify it before you use it. Or not, these are
just test systems after all.
Full example
Minus the output from the commands, here is the full output of testing
the Opscode apache2 cookbook on my guinea pig. Assume that all the
required things from my Chef Repository have been uploaded to the Chef
Server and the knife configuration is correct. Also, the chef-full
bootstrap template specified here is a customized version of the
template in the
Chef source master branch template
that has ntpdate -u pool.ntp.org in it.
Earlier this month, I completed a
switch to DNSimple for my
domain’s DNS provider. I am still happy with the switch, and finally,
just now, got around to writing a recipe to have my systems
automatically register themselves in DNS.
In the post, I described automatically adding the DNS entries with the
dnsimple cookbook.
I did this as a proof of concept, but I didn’t add it to all my nodes,
instead using my existing data bag-driven solution.
That said, this post serves as a brief document on how you can mimic
this behavior with your own environment.
Encrypted Data Bag
I put my DNSimple credentials in an
encrypted data bag.
Since I have to decrypt and read the entire thing anyway, I also store
the relevant data there. I keep my encrypted data bags in a bag called
secrets. The structure looks like this:
1234567
{"id":"dnsimple","api_token":"DNSimple API Token Here","domain":"your-domain.example.com","username":"DNSimple username","password":"DNSimple password"}
Replace the values with your values. Encrypting the data is optional,
but requires that you create a secret key or key file. Read my
previous post on the topic
for more information.
The first command just uploads the data bag item, the second encrypts
it. Note that I manage my workstation with Chef, so I will use the
same secret file as the Chef default. The secret file needs to be
copied to each system that will need it.
As
mentioned in the previous blog post,
the encrypted_data_bag_item method is in a library. Either add that
library to your cookbook, or use the class directly.
If you’re not using an encrypted data bag, then the item can be
accessed with the normal method:
1
dnsimple=data_bag_item("bagname","dnsimple")
The real work happens in the dnsimple_record LWRP, which will add an
“A” record for the system running the recipe. Note that the actual
entry is going to use the int subdomain, and it will use the domain
stored in the data bag item. It also will use the default IP address
of the node, which means the IP for the interface with the default
route.
A new “which tool is best” battle is raging in the internets amongst
developers and system administrators. The contestants are screen
and tmux, and the
jury is still out.
This is very much an argument over what color to paint the bikeshed,
but with the latest version of
iTerm2, I think tmux is even more
compelling. Personally, I chose tmux awhile ago.
At my day job, I worked with a customer that
uses tmux for remote pairing between developers. At the time, tmux had
better customizability, and better split-pane support (screen didn’t
yet have vertical split). I stuck with tmux ever since, and was very
pleased when an iTerm2 update announced integration with tmux.
iTerm2
For those who aren’t aware, iTerm2 is an alternate terminal program
for Mac OS X. It is actually an updated codebase from the original,
iTerm, which is effectively
unmaintained. iTerm2 offers
a lot of excellent features like split panes, Growl support, and
many more.
One of the excellent new features is integration with tmux.
iTerm2’s tmux integration
If you already have iTerm2 installed, you may have seen the update
check prompt you to update. You also need to install a special version
of tmux that has the integration patched. The iTerm2 author is working
with the tmux author to get this into the latest tmux codebase, so
hopefully the custom compiled version won’t be necessary soon.
Using the new feature is relatively straightforward. Start up iTerm2
like normal. Then run tmux -C to open a new iTerm2 window that works
like tmux.
Use the tmux menu in iTerm2 to open new windows in tmux. Note that there
are keyboard shortcuts for each of these, and they are not the same as
the tmux window commands.
You can also attach to a tmux session running in iTerm2. In the
screenshot, this is running on the same system, for example purposes.
However, since OS X has SSH, this can be useful if you want to SSH to
another system in the local network and connect to the running
session. For example, the system shown below is my wife’s iMac over
screensharing, but I wouldn’t need to use screenshare (or participate
in its lag) to connect to this anymore. The same holds true for
connecting to my work laptop if necessary.
In this final example screenshot, you can see that I have multiple
panes split in one iTerm2 tab. These correspond to the split windows
in the attached tmux in the other window. Also, the two tabs in the
iTerm2 window are separate tmux windows (0:zsh and 1:zsh).
And now, I can SSH to that system and attach to the tmux session
started by iTerm2.
Automating Installation with Chef
Installing OS X apps is quite easy, but I automate them
with Chef
anyway. While it is a simple “install update and restart”, with a
couple commands to install the update, I do have three systems I want
this on. I updated my
iterm2 cookbook to
support installing the tmux integration for iTerm2. This is disabled
by default, so it needs to be enabled via a node attribute. For
example, I have this in my workstation role applied to my OS X
workstations.
12345678
name"workstation"description"Mac OS X workstations"run_list("recipe[tmux]")default_attributes("iterm2"=>{"tmux_enabled"=>true})
Check out the iterm2 cookbook’s README for more information.
A few weeks ago, I listened to the
Changelog Podcast
episode featuring Chris Forsythe, lead of the Growl project. I
actually don’tWdidn’t use Growl for a long time, because I really
disliked notifications of any kind, as they are distracting. However,
I do appreciate the project, and supporting them by purchasing Growl
on the App Store seemed totally reasonable.
Of course, buying the app means it was installed on the spot. I always
resisted it in the past because it was bundled with so many apps, but
I don’t want unsolicited software to show up on my computer. Now, it
seemed a bit more natural, and I made a few configuration tweaks (I
should put those into Chef…). I’m actually happy to use it now,
especially since it has a nice network accessible API.
Growlnotify
Shortly after I started using Growl on my work system, I looked into
ways I could get notifications fired off from the command-line after
long running processes finished. In particular, I wanted to get a
notification that knife ec2 server create was done. I found the
growlnotify program, which is available via
homebrew. This is quite a nifty
tool, and I set it to use immediately, doing things like this:
I could kick off the server creation, switch focus to another
workspace, and then know via growl if the instance was created.
Chef Handler
As many know, I
manage my workstations with Chef.
Chef has a pretty cool
exception and report handler API
that has a lot of flexibility. I thought it would be fun to throw
together a simple report handler that would send a growl notification
after a Chef run. In this case, it will report the elapsed time of the
run if it was successful, or report an exception if it failed.
Using the handler is pretty straightforward. Install the
chef-handler-growl Gem, then configure chef-client (or solo).
Reminder: this blog reflects my opinions and thoughts, and not
those of my employer, Chef Software, Inc.
Like any good sysadmin, I have my own domain for email and other
purposes. I actually have had a couple, but this post is about my
current one. I originally set it up through Google Apps a couple years
ago, including registering the new domain with Google Apps’ default
registrar, GoDaddy. For the most part, it was pretty simple and
painless to set up, including private registration via Domains by
Proxy. Yay!
However, as I automated more components of my home network with Chef,
I found the lack of API driven DNS rather frustrating. At last count,
I had 15 distinct networked devices, counting all the computers,
consoles, mobile devices, etc. This does not count the virtual
machines that I manage as a part of my daily job in doing Chef
cookbook development and testing, which should all have their own DNS
entries, since I’ll access them over the network, and remembering IPs
is ridiculous.
Internal DNS Server
I use DJB’s tinydns as my DNS server,
and it is automated with the
Opscode Chef Cookbook.
The first incarnation of this setup was a single monolithic template
file containing all the entries in my local network zone, delivered by
the djbdns::tinydns-internal recipe, like so:
This was great, and simple to manage for this single purpose setup. At
some point, I wrote cookbooks for
unbound and
powerdns, as I was
evaluating whether one or the other might be easier to modularize. In
the process, I created a data bag of all my DNS entries that I could
step through in templates, so I could use the same data without caring
which software was going to consume it. In the end, I extended the
djbdns cookbook with a lightweight resource and provider, and added
usage to the djbdns::tinydns-internal recipe like this:
123456789101112131415161718192021
dns=data_bag_item("djbdns",node[:djbdns][:domain].gsub(/\./,"_"))#file"#{node[:djbdns][:tinydns_internal_dir]}/root/data"doaction:createend#%w{ ns host alias }.eachdo|type|dns[type].eachdo|record|record.eachdo|fqdn,ip|#djbdns_rr"#{fqdn}.#{dns['domain']}"docwd"#{node[:djbdns][:tinydns_internal_dir]}/root"ipiptypetypeaction:addnotifies:run,"execute[build-tinydns-internal-data]"end#endendend
I am pretty pleased with this approach in that this data can be used
no matter what DNS resolver software I choose. While this is great for
the more static part of my network, as I mentioned I do have some
dynamic usage where I create new virtual machines, and I really want
them to register themselves in DNS automatically.
Enter DNSimple
A few months ago I decided to switch over to DNSimple. The service was
compelling over the alternatives for a few reasons:
Low cost ($3/mo) for my size of account.
Very simple interface
API for managing records (!)
Reputation for great service
Darrin Eden
wrote a cookbook
for automatically creating records through the API, too, so half my
work for automating with Chef was already done!
However, for various reasons I procrastinated the switchover. After
all, my existing solution worked ok for my purposes. Then after seeing
GoDaddy show up on the SOPA supporters list, and being one a
contributing author to the legislation(*), I decided that was the last
straw and I busted a move to finish the
switch.
Honestly, from the DNSimple side, it couldn’t have been a better
experience. They have one-click services for managing DNS records for
a variety of common services – including Google Apps! It took some
time and hassle to move my domain out of GoDaddy, since their
interface is rather clunky, and I had to unprotect things through
Domains by Proxy to make the move, but after a couple hours everything
was fine. DNSimple has some
tips for migrating,
no matter who your current registrar is.
Now for the truly fun part!
Automated DNS with Chef
Using the dnsimple cookbook is very straightforward. You create an “A”
record like this:
Yes, that is a private network IP, and yes it is going to be
registered in public DNS. It really doesn’t matter that much in my
(and others’)
opinion. Especially given that zomg, I just created a DNS entry with
Chef!
By default, the cookbook does assume, and use, node attributes for
storing the username and password. This can be set by a role, but it
means that all nodes will have the data. For my use, I decided to put
these values in a data bag, and because they are sensitive, I used an
encrypted data bag.
I also wanted to reuse the data bag from my earlier DNS example, so I
wrote a recipe like this:
12345678910111213141516171819202122
dnsimple=encrypted_data_bag_item("secrets","dnsimple")dns=data_bag_item("dns","int_example_com")#%w{ host alias }.eachdo|type|dns[type].eachdo|record|record_type=type=~/^host$/?"A":"CNAME"record.eachdo|hostname,ip|#dnsimple_record"#{hostname}.#{dns['domain']}"donamehostnamecontentiptyperecord_typeaction:createusernamednsimple['username']passworddnsimple['password']domaindnsimple['domain']end#endend#end
I put that recipe in my “dnsserver” role, ran Chef, and boom, all my
DNS entries are updated on systems I don’t have to manage, and all
around the world.
% host cask.int.example.com 8.8.8.8
Using domain server:
Name: 8.8.8.8
Address: 8.8.8.8#53
Aliases:
cask.int.example.com has address 10.10.20.20
What a wonderful redundant distributed key value store :–).
Note that the encrypted_data_bag_item method used in the recipe is in a cookbook
library. I wrote about that in an
earlier blog post.
It is pretty simple:
12345678910111213141516
classChefclassRecipe#defencrypted_data_bag_item(bag,item,secret_file=Chef::EncryptedDataBagItem::DEFAULT_SECRET_FILE)DataBag.validate_name!(bag.to_s)DataBagItem.validate_id!(item)secret=EncryptedDataBagItem.load_secret(secret_file)EncryptedDataBagItem.load(bag,item,secret)rescueExceptionLog.error("Failed to load data bag item: #{bag.inspect}#{item.inspect}")raiseend#endend
Drawbacks
While conveniently reusing the data I already had for my DNS entries,
the dnsimple_record provider does take about a second on my internet
connection for each entry to check if it’s there. This makes the DNS
server’s Chef client run take over a minute, where it used to be less
than 12 seconds. Many of the entries that are in the DNS data bag are
on systems that can add their own records, and will soon once I
refactor things a bit.
Other Uses
A number of the entries in the DNS data bag are CNAMEs for services
that run on my home LAN server. I have internal services like
Netatalk/Time Machine, Samba, or Munin. I also have external services
like OpenVPN, SSH and Teamspeak. I’ll add DNSimple records for each of
these so the recipes can automatically register new DNS entries,
eliminating a step in bringing up a new service.
Open Source is Awesome
Chef is open source, of course, as is the
dnsimple cookbook
that I’m using. While working with the cookbook as describe above over
the last couple days, I made some improvements and I sent a
pull request,
which has been merged and released. Thanks Darrin!
If you use Chef and are looking for an API driven way to manage DNS
entries for your systems, I strongly recommend DNSimple as a provider,
and the dnsimple cookbook to tie it all together.
(*) This isn’t a political-blog-soap-box, but this
really was the final motivator.
I was playing around with Ubuntu 11.10 the other day, to explore some of the
changes that have happened to Ruby lately, and thought I’d share my findings.
First off, there are still Ruby 1.8(.7p352) packages. This is the
default you get with the ruby package. However, the ruby1.9.1 has
Ruby 1.9.2p290 as the default version. This isn’t the absolute latest
released (officially, 1.9.3 is the latest stable release), but it’s a
widespread release that a lot of people are using in production.
The main package for getting the Ruby executables is ruby1.9.1. It
is now a “full” installation and includes:
/usr/bin/gem1.9.1
/usr/bin/rdoc1.9.1
/usr/bin/rake1.9.1
/usr/bin/erb1.9.1
/usr/bin/ri1.9.1
/usr/bin/ruby1.9.1
/usr/bin/irb1.9.1
/usr/bin/testrb1.9.1
Previous versions had these as separate packages, and you had to
remember to install everything to have a full Ruby installation
available.
In the package name and the above binaries, 1.9.1 indicates the Ruby
library compatibility, 1.9.2 is compatible with 1.9.1.
The Debian alternatives system is used to set the default ruby, gem
and irb binaries in the $PATH as links to the 1.9.1 versions, e.g.:
The -E is significant so the variable is available via
sudo. Without this variable set, this command will warn noisily
that you should know what you’re doing, and what this is up
to. Personally, I’m fine with RubyGems 1.3.7, as that is the version
that the Chef gem_package provider uses for the API. With the
default RubyGems, you also get binaries in /usr/local/bin, rather than
the awkward /var/lib/ruby location in earlier versions.
That said, let’s put this to use so we can have Chef running under the
Ruby 1.9.2 available via APT.
123456789101112131415161718192021222324252627
% sudo apt-get install ruby1.9.1 ruby1.9.1-dev build-essential
Reading package lists... Done
Building dependency tree
Reading state information... Done
build-essential is already the newest version.
Suggested packages:
ruby1.9.1-examples ri1.9.1 graphviz
The following NEW packages will be installed:
libruby1.9.1 ruby1.9.1 ruby1.9.1-dev
0 upgraded, 3 newly installed, 0 to remove and 1 not upgraded.
Need to get 0 B/5,027 kB of archives.
After this operation, 19.5 MB of additional disk space will be used.
Selecting previously deselected package libruby1.9.1.
(Reading database ... 141637 files and directories currently installed.)Unpacking libruby1.9.1 (from .../libruby1.9.1_1.9.2.290-2_amd64.deb) ...
Selecting previously deselected package ruby1.9.1.
Unpacking ruby1.9.1 (from .../ruby1.9.1_1.9.2.290-2_amd64.deb) ...
Selecting previously deselected package ruby1.9.1-dev.
Unpacking ruby1.9.1-dev (from .../ruby1.9.1-dev_1.9.2.290-2_amd64.deb) ...
Processing triggers for man-db ...
Setting up libruby1.9.1 (1.9.2.290-2) ...
Setting up ruby1.9.1 (1.9.2.290-2) ...
update-alternatives: using /usr/bin/gem1.9.1 to provide /usr/bin/gem (gem) in auto mode.
update-alternatives: using /usr/bin/ruby1.9.1 to provide /usr/bin/ruby (ruby) in auto mode.
Setting up ruby1.9.1-dev (1.9.2.290-2) ...
Processing triggers for libc-bin ...
ldconfig deferred processing now taking place
One of Chef’s dependency gems is json, which has native C
extensions, so the development headers for Ruby, and build tools are
required (though already installed on my system).
% sudo gem install chef
Building native extensions. This could take a while...
[Version 0.7.8]test suite cleanup (eliminated some race conditions related to queue.message_count)Building native extensions. This could take a while...
Successfully installed mixlib-config-1.1.2
Successfully installed mixlib-cli-1.2.2
Successfully installed mixlib-log-1.3.0
Successfully installed mixlib-authentication-1.1.4
Successfully installed yajl-ruby-1.1.0
Successfully installed systemu-2.2.0
Successfully installed ohai-0.6.10
Successfully installed mime-types-1.17.2
Successfully installed rest-client-1.6.7
Successfully installed bunny-0.7.8
Successfully installed json-1.5.2
Successfully installed polyglot-0.3.3
Successfully installed treetop-1.4.10
Successfully installed net-ssh-2.1.4
Successfully installed net-ssh-gateway-1.1.0
Successfully installed net-ssh-multi-1.1
Successfully installed erubis-2.7.0
Successfully installed moneta-0.6.0
Successfully installed highline-1.6.8
Successfully installed uuidtools-2.1.2
Successfully installed chef-0.10.4
21 gems installed
And running Chef just works:
1234
% sudo chef-client
[Thu, 24 Nov 2011 14:02:38 -0700] INFO: *** Chef 0.10.4 ***
...
[Thu, 24 Nov 2011 14:02:50 -0700] INFO: Chef Run complete in 9.862972181 seconds
The results of the node object on the Chef Server:
1234567891011121314151617
% knife node show virt1test -a languages.ruby
languages.ruby:
bin_dir: /usr/bin
gem_bin: /usr/bin/gem1.9.1
gems_dir: /var/lib/gems/1.9.1
host: x86_64-pc-linux-gnu
host_cpu: x86_64
host_os: linux-gnu
host_vendor: pc
platform: x86_64-linux
release_date: 2011-07-09
ruby_bin: /usr/bin/ruby1.9.1
target: x86_64-pc-linux-gnu
target_cpu: x86_64
target_os: linux
target_vendor: pc
version: 1.9.2
Overall, I’m happy with the changes that the Debian Ruby Packaging
Team has made, and I’m glad to see these come to Ubuntu in
11.10+. It’s not the absolute latest version available, but this is
good forward progress for binary Linux distributions. I also like that
the alternatives system is used, so users could choose to install and
use other Ruby interpreters. Hopefully these changes quell some of the
arguments about Debian and Ubuntu and their handling of Ruby.
Over the past 20 years, I always had a Windows (or DOS!) PC as the
main system I use at home. The primary purpose was for gaming,
although building my own systems is also a hobby. In 2007, I wanted to
build a new system to use as a home theater PC. Originally, I built it
with Windows Vista – Windows Media Center was Vista’s killer app! I
painstakingly installed software, tweaked system settings and tuned
the registry. Then Windows 7 came along with further
improvements. After almost 20 years of reinstalling from scratch for
new versions of Windows, I treated this upgrade as no
different.
Unfortunately, I didn’t capture all the system tweaks and settings. I
didn’t get all the software reinstalled. I did what I remembered, and
W7 did have some improvements that made extra software and tweaks
unnecessary. The thing I was lacking in the rebuild, and up until
recently, was configuration management for Windows.
Enter Chef
Recently, my employer Opscode
announced broader Windows support
for Chef. The awesome Chef community, and our development team have
added some key features to Chef in the form of core libraries and
cookbooks. While I did get Chef running on my HTPC a few months ago, I
had only used it to test out the
powershell cookbook,
and also wrote a
silverlight cookbook
as a proof of concept. In the mean time, the
windows cookbook
cookbook received some serious leveling up thanks to
Seth Chisamore.
Windows Cookbook
The Windows cookbook has a number of excellent “primitives” in the
form of libraries and resources. You can read all about that on
The Chef Wiki. For
now, I’ll talk about how I captured some of the configuration so I
don’t have to remember next time (Windows 8, coming soon…). Of
interest here are the windows_registry and windows_auto_run resources.
My HTPC’s cookbooks
I wrote two cookbooks this weekend. First, is a general “Windows Media
Center” cookbook called, aptly, “wmc”. This will capture the
specific registry and other configuration related to Windows Media
Center itself. The idea with this one is it manages only Windows Media
Center. It’s not ready for release, but I’ll post some snippets
of code here as I go.
The second cookbook I created is specifically for the Home Theater PC
itself, named htpc. This is going to contain all my preferences and
biases of how I want my HTPC to look like in order to provide
entertainment in my house.
Windows Media Center (wmc)
First and foremost, I want to make sure that Windows Media Center is
running at boot time, and the windows_auto_run resource fits the
bill. This resource modifies the registry to update the key
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run, using the
windows_registry resource. It does operate at the machine level,
not just the current user, but I only have one user on my HTPC, so
it’s okay. Here’s the resource:
12345
windows_auto_run"Windows Media Center"doprogram"RunDLL32.exe C:/Windows/ehome/ehuihlp.exe,BootMediaCenter"not_if{Registry.value_exists?(AUTO_RUN_KEY,'Windows Media Center')}action:createend
Next, I want to tweak a few other registry settings. Some of these I
discovered through an
MSDN blog post,
others are from setting up WMC itself and observing the “HKCU”
registry. Not the most sophisticated way, but I don’t see a great
“diff” tool for the registry. Because the name of the HKCU and HKLM keys for WMC are
long, I set them to a couple local variables, via cookbooks/attributes/default.rb.
I also optimize the display for LCD/Plasma (I have a RP DLP, but I
digress).
123
windows_registryhkcudovalues'TVSkin'=>0end
For now, that’s all the wmc cookbook has going for it. I do have
plans to enable additional features of WMC, install useful plugins,
and improve playback quality and performance. Mainly, I need to find
my old notes :–).
Home Theater PC (htpc)
The htpc cookbook will contain additional tweaks and settings for
how I want my HTPC configured. I don’t know if I’ll release it
publicly, as it is pretty specific to me, but it might be useful as
examples for others, so stay tuned to my
GitHub account for updates.
First up are some local performance tweaks. These are done to
Explorer(.exe), and I don’t remember the source.
Second, since this system is where all my music files live, I have
iTunes installed for
Home Sharing. It doesn’t do much
good if iTunes isn’t running, however, so I use windows_auto_run to
start it up.
It’s pretty simple so far, but I have some plans in store for my HTPC cookbook.
HTPC Cookbook Plans
I do plan to add some new features to the htpc cookbook. First, I
want to make sure all the software I need is installed. While the
system mainly sits in WMC (with iTunes in the background), I do have
some additional software and utilities that I like to have for
managing my media library.
iTunes – I already have the software installed, but it would be nice
to not have to do that during system setup (Windows 8, I say…).
Google Chrome – there’s no abc.com, nbc.com, etc plugins for WMC
(yet?), so I need a browser to go to the respective web sites to
catch up on older episodes.
CDBurnerXP – decent CD/DVD burning software, rarely used but useful
for backups.
Logitech Harmony Remote Software – I have a
Harmony 700 universal remote
(and it’s awesome!). This one might be tricky, but really I just
want to make sure the software is installed. Configuration profiles
are stored in an online support account with Logitech as far as I’m
aware.
Netflix plugin for WMC – This will probably go into the wmc
cookbook, though.
Additional performance tweaks – There are a whole slew of tweaks
that I know I made, I just don’t remember them all. These will be
added with windows_registry resources.
Windows Features – With the windows_feature resource, Chef can
manage core features included in Windows installations.
Logging, monitoring – What kind of system administrator would I be
if I didn’t also monitor my system for performance? :–)
Some of the things I want to manage on my HTPC are covered by other
cookbooks I have, or exist on the
Chef Community Site.
Steam – This system is still capable of running some games, like
StarCraft II, TeamFortress 2 and Left 4 Dead (1 & 2). I have a Steam
cookbook that works on OS X, it just isn’t released (yet).
Teamspeak 3 – I already have a
teamspeak3 cookbook,
I’ll just need to add installation of the client for Windows there.
A text editor – Since I have games, and
games have configuration files, it makes sense to … wait, I should
put those in Chef too! Or at least, in a Version Control System and
check out the repository…