I spent most of the day debugging ganglia when the problem wasn’t even ganglia, but I’m mentioning ganglia, and gmond, here so that
if someone else searches google for the same problems that I was having using the same words, they’ll be able to find the appropriate solution.
tl;dr: If you can’t get your gmetric in xen using multicast to cluster across a linux bridged interface, disable multicast snooping in dom0.
I’ve played with puppet in the past, but I never actually deployed anything significant with it.
I have built manifests for work, to help deploy packages, and I’ve been tinkering with one
that does some fancy stuff to install elasticsearch.
This weekend I actually spent the time to get a puppet master set up on ArchLinux, and it went relatively smoothly.
I had to apply two patches, however, and one I got to write myself..
I’ve got an old box under my desk that can run xen, but doesn’t have the virtualization extensions.
This makes it somewhat difficult to do things like install certain linux distributions
coughcentoscough that don’t provide a simple
network installation mechanism, or their net install stuff requires being fully virtualized.
I found instructions on building your own chroot within a centos box to run chrooted services, which isn’t what
I wanted, but I can extrapolate from a chroot into a xen vm. Just need to make a simple grub menu.lst and make
sure that it has a real init system to actually boot from.
Following those instructions, I was able to construct a chroot on my fedora desktop. Unfortunately, after
chrooting into the box itself, I wasn’t actually able to yum install anything, since the database formats were
from the yum on my fedora 17 desktop, which is significantly newer than old CentOS 6.
Solution was to simply build a chroot within the chroot. Creating database files that are the appropriate format
for centos 6. Then I pulled that chroot out and did away with the intermediary chroot. A bit of yum groupinstall Base and I had a working system that I could boot in a paravirtualized way. Fantastic.
After the completion of the course, I started working on learning Play, just to start a new project. Unfortunately,
Play comes with it’s own, and yet exactly the same, version of the IDEA generation plugin. It is in the same
namespace, and so collides with the existing one. The only solution is to disable the globally configured SBT one
for the duration of working with Play.
It’s not a very good solution, but it does get it working again.
It’s about a quarter to three in the afternoon on a Thursday and the twitter goes off! An open source project that I haven’t worked on in a while is having some trouble with UTF-8.
I was stuck on some code that was proving to be kind of boring, so I decided to give it a whirl to try and shake my brain up a bit.
My initial solution was way off base.
This solution didn’t deal with filenames, it dealt with data in the file. Cucumber-JVM is already setting UTF-8 in all places like it’s supposed to. That wasn’t the solution, it wasn’t even close. The adrenaline fires up as I realize this is going to be a challenge. All thoughts of doing work previously are gone, now this challenge is all that matters. I try my search again, looking to see what else I could find about UTF-8 and filenames.
I love my DasKeyboard, but it doesn’t have any media keys. That makes it somewhat tricky to do things
like controlling Clementine
and Pithos, my two favorite ways of listening to music.
Originally, I’d gone down the path of simulating multimedia keys. That was the most frustrating 30ish minutes of my day. Do not want.
And so, the solution was to write a script to send messages over dbus to the system if it’s running, so I can
pause my music with a keyboard command.
Here’s my ruby script that uses the native Ruby DBUS interface
(yeah, I know it’s got an “invalid” self-signed ssl certificate, annoying, but cheaper than
paying for one :) ) to send the commands. It should be resonably easy to now extend to other media apps
if I desire to. No big deal. Even if they’re command line apps, I’ve got one centralized, simple script
that can talk to anything I want it to. It’s supposed to be magicked away by media keys and stuff within your
window manager, but it’s made more difficult if your keyboard doesn’t have media keys. No longer will I be
discriminated against! I will rise up with my awesome DasKeyboard and type to victory! Er, well, listen to music.
#!/usr/bin/env ruby## ARGV.first should be play, stop, next, prevrequire'dbus'command=ARGV.firstexit1unless%w{PlayPause Next Previous Stop}.include?command#play with dbus stuffbus=DBus::SessionBus.instancebeginclementine=bus.service("org.mpris.clementine").object('/org/mpris/MediaPlayer2')clementine.introspectclementine.default_iface='org.mpris.MediaPlayer2.Player'#clementine.PlayPause#clementine.Next#clementine.Previous#clementine.Stopclementine.send(command.to_sym)rescueDBus::Error=>e# don't really care, means it's probably not thereendbeginpithos=bus.service("net.kevinmehall.Pithos").object('/net/kevinmehall/Pithos')pithos.introspectpithos.default_iface='net.kevinmehall.Pithos'ifcommand=="Next"pithos.send(:SkipSong)elsifcommand=="PlayPause"pithos.send(:PlayPause)endrescueDBus::Error=>e# don't really care againend
There’s one more bit necessary, you’d have to hook it up to some kind of keymapper. I used xbindkeys, so it’s not
particularly bound to any particular window manager, even though I use KDE4.
UPDATE: I’m a moron. Latest RVM (1.14.5) handles all this for you. I’ll leave the post
here since it’s already on the internet, and if anyone wants to see how to do things anyway, heh.
Unfortunately, the default RHEL system ruby is 1.8.7, which is quite old. This also means
that I will have to develop against 1.8.7, and so it needs to be installed on my local development
box. I use RVM, and so it makes sense to have RVM install 1.8.7 for me.
Unfortunately, the first thing it does is explode horribly :(
AUGH, Explodie!
1234567891011121314151617
gcc -I/opt/local/include -I. -I/opt/local/include -I../.. -I../../. -I../.././ext/dl -DHAVE_DLFCN_H -DHAVE_DLOPEN -DHAVE_DLCLOSE -DHAVE_DLSYM -DHAVE_DLERROR -I. -fPIC -g -O2 -fno-defer-pop -fno-omit-frame-pointer -c ptr.c
gcc -I/opt/local/include -I. -I/opt/local/include -I../.. -I../../. -I../.././ext/dl -DHAVE_DLFCN_H -DHAVE_DLOPEN -DHAVE_DLCLOSE -DHAVE_DLSYM -DHAVE_DLERROR -I. -fPIC -g -O2 -fno-defer-pop -fno-omit-frame-pointer -c handle.c
Generating callback.func
Generating cbtable.func
gcc -I/opt/local/include -I. -I/opt/local/include -I../.. -I../../. -I../.././ext/dl -DHAVE_DLFCN_H -DHAVE_DLOPEN -DHAVE_DLCLOSE -DHAVE_DLSYM -DHAVE_DLERROR -I. -fPIC -g -O2 -fno-defer-pop -fno-omit-frame-pointer -c dl.c
In file included from dl.c:104:0:
callback.func:1:1: warning: data definition has no type or storage class [enabled by default]
callback.func:1:7: error: expected identifier or ‘(’ before ‘long’
In file included from dl.c:104:0:
callback.func:78:33: error: expected ‘)’ before ‘(’ token
callback.func:79:3: warning: data definition has no type or storage class [enabled by default]
callback.func:79:24: error: ‘proc’ undeclared here (not in a function)
callback.func:79:39: error: ‘argc’ undeclared here (not in a function)
callback.func:79:45: error: ‘argv’ undeclared here (not in a function)
callback.func:82:1: error: expected identifier or ‘(’ before ‘}’ token
dl.c:106:1: error: expected ‘;’, ‘,’ or ‘)’ before ‘static’
make[1]: *** [dl.o] Error 1
Adding nginx to logwatch was more complicated than I’d imagined. I found a couple entries on the internets
about how to do it, but I wasn’t really impressed with any of them.
And so, my list of steps to accomplish this follows. Enjoy!
Blocks are fantastic. Being able to store code in the current context and execute it elsewhere is wonderful.
On a project I’m working on, we’ve got a bunch of ruby test code executed using Cucumber, and right now I’m working on integration
with third party systems. This results in a large number of polling loops.
I start to notice a pattern appearing. They almost all follow the same syntax, keep track of time and timeout after a certain amount of time
has passed. The only differences are:
* Amount of time to wait
* The criteria for success
* The code to execute to get that criteria (maybe a rest call, maybe selenium UI tests)
That seems like it’d be a lot to try to narrow down. In Java I can’t even imagine how I’d go about doing it. In groovy it could be done with closures,
but it wouldn’t be as clean as I’d like it to be. In Ruby, however, it comes out beautifully:
I can pass in all three items and handle all the time logic trivially. Makes the end user’s code much cleaner:
123456
x=0do_timeout(10,lambda{x<3})doputs"omg, I'm doing something and it results in x being #{x}"x=x+0.25sleep1end
This will hit the timeout and raise a nice Timedout exception for me. Making my tests fail as they should.
If one changes the increment to 0.5 it’ll pass and everything comes out perfectly fine and moves on just fine.
This is basically an enhanced while loop. I can easily encapsulate the logic as well as the block of execution. It’s almost
like I added a new keyword to the language.
Ruby is fantastic. So is functional programming :)
Rewriting your history is generally anti social. Any downstream clones of your repository will no longer
be valid. Their history and your history will have diverged. That’s not impossible to recover from, but
it is best if you can get everyone to push everything they’d want to push, and then clobber your history.
People will just clone the repo again and have the new history and everything will be peachy.