Friday, August 14, 2009
DNSMASQ and multiple DHCP networks with DHCP relay
I switched from MaraDNS to DNSMasq. DNSmasq is an excellent tool for small networks. Small networks are defined as something less than 1000 hosts. This is most networks! I love DNSMasq's simplicity. I also like how it bundles DHCP, DNS recursive server, DNS caching. The DHCP is surprisingly simple to use and configure and incredibly feature-full. For example, the DHCP server handles PXE clients requests for the next server. It also handles requests that are relayed, so you can provide multiple subnets DHCP service and do it based on the tag provided by the relayer. I also like how you can reuse the local (to the DNSmasq) machine's /etc/hosts and /etc/resolv.conf to gather static entries and upstream recursive DNS caches. It seems simple to just reuse these files for the server and clients. You are essentially exporting the server's /etc/hosts and /etc/resolv.conf to your clients.
Friday, May 29, 2009
Tail recursion in Python
Problem: When marshalling an object to be able to transmit to or from an XMLRPC server and the xmlrpc lib is insufficient to the task because the objects within the main object do not implement a marshal method.
Admittedly the datetime, mxDateTime and None objects should just know what to do if asked by the xmlrpclib to marshal themselves, but in this case, I want to do this myself.
Answer: Here is a tail recursive way to perform this task. This should not use any stack space, but I cannot confirm this since I am not sure what is going on in the interpreter.
Admittedly the datetime, mxDateTime and None objects should just know what to do if asked by the xmlrpclib to marshal themselves, but in this case, I want to do this myself.
Answer: Here is a tail recursive way to perform this task. This should not use any stack space, but I cannot confirm this since I am not sure what is going on in the interpreter.
def __convertNonMarshalables(self, obj):
if type(obj) == type({}):
for key, value in obj.items():
if value is None:
obj[key] = ""
elif type(value) is type(mx.DateTime.now()) or type(value) is type(datetime.datetime.now()):
obj[key] = value.strftime('%Y-%m-%d')
elif type(value) == type([]) or type(value) == type({}):
value = self.__convertNonMarshalables(value)
elif type(obj) == type([]):
for value in obj:
if value is None:
value = ""
elif type(value) is type(mx.DateTime.now()) or type(value) is type(datetime.datetime.now()):
value = value.strftime('%Y-%m-%d')
elif type(value) == type([]) or type(value) == type({}):
value = self.__convertNonMarshalables(value)
else:
if obj is None:
obj = ""
return obj
Tuesday, May 26, 2009
Leopard killed TextMate, sort of
Just updated Leopard and now having "#!/bin/sh" in the "command(s)" section of the bundle editor for any bundle yields "bad interpreter: no such file or directory" if I remove the directive, it works fine, but now on the shell bundle, the run command script is a ruby script and TextMate will not take #!/usr/bin/env ruby, yields bad interpreter again, but I really need to tell TextMate this is a ruby script. So I ran the script with ruby -e'do something'. That is weak sauce but it works. I also noticed circular dependencies in the bundles. You need ruby to run a python script in the python bundle; you need bash to run a ruby script, you need ruby to run a shell script.
I am not sure why this is because the text in command(s) should be treated as a shell script. Anyway, if anyone else has this problem, then removing the shell directive line should help.
I am not sure why this is because the text in command(s) should be treated as a shell script. Anyway, if anyone else has this problem, then removing the shell directive line should help.
Tuesday, March 10, 2009
Saturday, March 7, 2009
Auto adding DHCP host names to DNS (MaraDNS)
Ever wonder why a host that you offer a DHCP lease to just does not automagicly appear in your non recursive DNS server's zone file. Well, it should! Using this "glue" code, it will be a snap to update your zone files whenever a new host joins the network. In this example, I am using MaraDNS and dhcpd.
Overall concept:
dhcpd --> lease file --> cron script --> ruby script --> DNS zone file
Cron entry (/etc/cron.d/update_dns):
*/5 * * * * root sh /usr/local/bin/parse_leases_add_to_dns.sh
parse_leases_add_to_dns.sh:
add_hosts.rb:
So why are you using a ruby script, can't you just do it all with bash/awk?
Sure, but the ruby script is more fun to write and maintain; if you feel the need to use bash, then this is possible too.
Overall concept:
dhcpd --> lease file --> cron script --> ruby script --> DNS zone file
Cron entry (/etc/cron.d/update_dns):
*/5 * * * * root sh /usr/local/bin/parse_leases_add_to_dns.sh
parse_leases_add_to_dns.sh:
#!/bin/bash
#check modification time
if [ ! -f /tmp/leases_mod_time ]; then
touch /tmp/leases_mod_time
fi
#see if the last check time is less than mod time
if [ /tmp/leases_mod_time -ot /var/lib/dhcp/dhcpd.leases ]; then
/usr/local/bin/ruby add_hosts.rb
touch /tmp/leases_mod_time
fi
#check modification time
if [ ! -f /tmp/leases_mod_time ]; then
touch /tmp/leases_mod_time
fi
#see if the last check time is less than mod time
if [ /tmp/leases_mod_time -ot /var/lib/dhcp/dhcpd.leases ]; then
/usr/local/bin/ruby add_hosts.rb
touch /tmp/leases_mod_time
fi
add_hosts.rb:
leases = open('/var/lib/dhcp/dhcpd.leases')
dns = open('/etc/maradns/kleetus.1337.foo', 'w')
leases_string = leases.read
lease = ""
client_hostname = ""
leases_string.each do |line|
next if line[0..0]=="#"
unless (line =~ /lease/).nil?
lease = line.split[1].gsub("\"","").gsub(";","")
end
unless (line =~ /client-hostname/).nil?
client_hostname = line.split[1].gsub("\"","").gsub(";","")
end
if client_hostname!="" and lease!=""
w_string = "#{client_hostname}.% #{lease}"
dns.write("#{w_string}\n")
lease = ""
client_hostname = ""
end
end
statics = ["myth-test.% 10.20.10.120", "*.% 10.20.10.100"]
statics.each do |line|
dns.write("#{line}\n")
end
dns.close
load=`/etc/init.d/maradns force-reload`
dns = open('/etc/maradns/kleetus.1337.foo', 'w')
leases_string = leases.read
lease = ""
client_hostname = ""
leases_string.each do |line|
next if line[0..0]=="#"
unless (line =~ /lease/).nil?
lease = line.split[1].gsub("\"","").gsub(";","")
end
unless (line =~ /client-hostname/).nil?
client_hostname = line.split[1].gsub("\"","").gsub(";","")
end
if client_hostname!="" and lease!=""
w_string = "#{client_hostname}.% #{lease}"
dns.write("#{w_string}\n")
lease = ""
client_hostname = ""
end
end
statics = ["myth-test.% 10.20.10.120", "*.% 10.20.10.100"]
statics.each do |line|
dns.write("#{line}\n")
end
dns.close
load=`/etc/init.d/maradns force-reload`
So why are you using a ruby script, can't you just do it all with bash/awk?
Sure, but the ruby script is more fun to write and maintain; if you feel the need to use bash, then this is possible too.
Monday, February 23, 2009
Adam Carolla
If you have never heard of this man, you are for a treat, my friend! Adam is the Quintessential everyman's man. He can be heard here
Here are the reasons why I love Adam Carolla:
1. He connects with his listeners on a personal level because he doesn't act like some stuck up rich person. He recognizes that most of his listeners are just like he is. He worked construction and cleaned carpet. Now he has means, so it is nice that he can create a portal into the world of Hollywood, but he always remains genuine. He is sincerely connected to "the rest of us".
2. He is honest. This really should be number 1 on my list. You cannot connect with people if you are phony. People can see through this in a second and radio people are fooling themselves if they think that they put on a persona and retain an audience. Ace Man (Carolla) just puts himself out there, take it or leave it. He has flaws and those flaws can be endearing since we all have them too.
3. He is observant. This is more than schtick, Adam brings out the truly absurd in our culture. He comes off more genuine that the Seinfeld ("Who are these people") bits. He gets into more counter-culture routines that are really funny. He has one bit where is mimes a strip club MC. Callers will ask him to do an impromptu routine centered around them. Great bit.
4. Connections. Adam is plugged into Hollywood and its weirdness. He will call out weird shit too. Life is all about relationships. Adam's personality is likeable and most pop culture stars like Adam, so he can leverage this.
5. Adam is old school So. California. He was born in North Hollywood and lived amoung the regional culture. I find people who talk about subculture amoung the most interesting. I live in Atlanta, so this is far removed from this, but I love to hear about how "the Valley" is like or dislike my area.
Here are the reasons why I love Adam Carolla:
1. He connects with his listeners on a personal level because he doesn't act like some stuck up rich person. He recognizes that most of his listeners are just like he is. He worked construction and cleaned carpet. Now he has means, so it is nice that he can create a portal into the world of Hollywood, but he always remains genuine. He is sincerely connected to "the rest of us".
2. He is honest. This really should be number 1 on my list. You cannot connect with people if you are phony. People can see through this in a second and radio people are fooling themselves if they think that they put on a persona and retain an audience. Ace Man (Carolla) just puts himself out there, take it or leave it. He has flaws and those flaws can be endearing since we all have them too.
3. He is observant. This is more than schtick, Adam brings out the truly absurd in our culture. He comes off more genuine that the Seinfeld ("Who are these people") bits. He gets into more counter-culture routines that are really funny. He has one bit where is mimes a strip club MC. Callers will ask him to do an impromptu routine centered around them. Great bit.
4. Connections. Adam is plugged into Hollywood and its weirdness. He will call out weird shit too. Life is all about relationships. Adam's personality is likeable and most pop culture stars like Adam, so he can leverage this.
5. Adam is old school So. California. He was born in North Hollywood and lived amoung the regional culture. I find people who talk about subculture amoung the most interesting. I live in Atlanta, so this is far removed from this, but I love to hear about how "the Valley" is like or dislike my area.
Subscribe to:
Posts (Atom)

I got this figured out, so I thought I would share this with anyone transcoding mpeg2ts (over the air high definition) to something that the iphone 3G can play from a streaming server such as apache. Here is my ffmpeg line:
The key here is to ensure the playback is at no more than 30 frames a second, or your iphone will play like 1 second and then stop...like it can't buffer the stream. Of course, when you do this, you will lose audio/video sync since you just yanked some frames out out the stream, so you need to use -async 3 to fix this; 3 works for me, but you may want to experiment. Also, I am using a recent SVN trunk compilation of ffmpeg with libfaac and xvid enabled in the compilation. This made a huge difference in whether ffmpeg could work with me on this TS file.
Now the bash like variables are exactly that, bash variable interpolations. Rate is the sample frequency of the audio...something like 44100 or 48000, abirate is the audio bit rate...something like 128k, the vbirate is not crucial, the video bit rate, something like 480K or 378K. The vbirate will really make the resulting file smallish. The original was prolly 2 or 3 times that. The dimensions usually work out to be 320x240, but I have also used 432x240 with success for 1.78 ratios.