tag:blogger.com,1999:blog-4054222445576331092024-03-06T02:54:17.715+01:00Kai's Development BlogKaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.comBlogger54125tag:blogger.com,1999:blog-405422244557633109.post-16584410892008761582013-07-05T10:40:00.000+02:002013-07-05T10:40:58.365+02:00Running a Stage Prop Using a BeagleBone Black<p>As long term readers of this blog might remember, I am involved with the theatre and <a href="http://kblin.blogspot.de/2011/06/geeky-stage-props-made-easy.html">have built electronics-driven stage props before</a>. However, the last time I used an Arduino to drive an H-bridge IC for a stepper motor, so pretty much low level electrical engineering, with a bit of Arduino coding.</p>
<p>This semester however, I'm involved in a play with the <a href="http://www.provisional-players.de/">Provisional Players</a>, a student theatre group at the University of Tübingen. The play is <b>Around the World in 80 Days</b>, our own adaption of the novel by Jules Verne. And as the protagonists are traveling around the world, their progress is tracked by moving dots on a world map. The map is fairly large, about 2 meters wide, and we're using about 150 LEDs to mark the red dots. Naturally, driving 150 LEDs directly from a single microcontroller would require 150 outputs, so that was out of the question. Phileas Fogg and Passepartout only travel into one direction, though, so pretty soon we had the idea to use shift registers to turn on LEDs instead. To control the shift registers, we wanted a straightforward interface, because we'll only have one technician handle lights, sound and the world map during the show, and we wanted to make her life as easy as possible. The prototype set-up that I just got to work (with a couple of days to spare, go me!) looks like this: <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiT9RaQTqwOSYQrLCmgeVhZWS84aR13nWSJRtfuwLQT2Kbq27HcJ0d4afPr6Q-Gy0nekU0v-quDav5xyNPza6F9siFHcYI48l_uUP6Ql70eiaZMukZhJoLBtc7U92UcM8aQil47WZzzBX1M/s1600/IMG_20130704_012223.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiT9RaQTqwOSYQrLCmgeVhZWS84aR13nWSJRtfuwLQT2Kbq27HcJ0d4afPr6Q-Gy0nekU0v-quDav5xyNPza6F9siFHcYI48l_uUP6Ql70eiaZMukZhJoLBtc7U92UcM8aQil47WZzzBX1M/s320/IMG_20130704_012223.jpg" /></a></div>
</p>
<p>In the beginning of the project, it wasn't very clear how we would drive the LEDs, so having 60 GPIO pins available sounded like a smart idea. I decided to use a BeagleBone Black (BBB) that I had lying around after almost demoing it at the SambaXP conference in May. As I didn't build the circuits around the shift register, I won't dwell on that topic. What I want to talk about a bit more is the software side of things. The task of the system is to run LEDs that illustrate the protagonists' travels around the world.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://upload.wikimedia.org/wikipedia/commons/c/c4/Around_the_World_in_Eighty_Days_map.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="182" src="http://upload.wikimedia.org/wikipedia/commons/c/c4/Around_the_World_in_Eighty_Days_map.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Fogg's trip around the world, courtesy to Wikipedia.</td></tr>
</tbody></table></p>
<p>The play has many, many scenes, and unfortunately the map is unlikely to be visible from the tech booth driving it. So the interface not only needed to allow turning on the appropriate LEDs but also provide visual feedback to the technician driving it. Also, experience with the software running our stage lights has told us that the "go back one light change" feature is used more than we'd like to admit, so a "back" button for the map would be great as well. As there's a network connection for the BBB, I decided to go for a web interface. The BBB already comes with some demo web pages, some of which also demo a JavaScript library called <a href="http://beagleboard.org/support/bonescript/">bonescript</a>. That was what I wanted to use as well.</p>
<p>However, on closer inspection it turned out that bonescript was originally designed as a node.js module, and running it from the browser sometimes just didn't work right, and getting it integrated into a website that looked the way I wanted wasn't trivial either. A look at the bonescript page showed that the main use case seemed to be running from the cloud9 web-based IDE that is also shipped on the BBB image. For me, that turned out to be even less useful. Half of the time, my program refused to start up at all, and if it did, most of the time it'd refuse to terminate, forcing me to ssh into the BBB and killing the stray node.js job from the command line. Clearly, that wasn't a viable solution for our show.</p>
<p>But of course, bonescript being a nodejs module meant that I could simply write a node.js webapp that would then call the appropriate bonescript functions to trigger the hardware actions needed. And that's just what I did. The <a href="https://github.com/kblin/around-the-world">code is available on GitHub</a> if you want to have a look, but basically it works like this:<br />
A node.js application is providing an http server with a bunch of endpoints to trigger advancing the LEDs, and figuring out what travel destinations are available. The http server also serves out the UI files.<br />
There's a separate module that keeps the list of destinations along with the pin that needs to be signaled to advance the shift register, and how many signals need to be sent per destination.<br />
I also have a <code>fakebonescript</code> library that instead of talking to real hardware just prints to stdout so I could develop on my laptop instead of having to have the BBB available all the time.<br />
On the user interface side of things, I use <a href="http://knockoutjs.com/">KnockoutJS</a> to keep track of the world map state and handle user interface updates. KnockoutJS also comes with a simple templating system that allows me to build the UI for the travel destinations dynamically. For layouting, I use <a href="http://twitter.github.io/bootstrap/">Twitter's Bootstrap</a> framework. This allows me to build a simple UI with all the required "travel", "back" and "clear" buttons in less than 100 lines of custom HTML and JavaScript code.</p>
<p>For a total of slightly under 350 lines of code I had to write myself, I've got a BeagleBone Black running ~150 LEDs that light up to show the route Phileas Fogg and his servant Passepartout travel around the world, and the total hardware cost of the setup is less than 100 EUR if I also count the BBB that will be reusable for other projects. I'm still amazed myself how nice and easy it is to do really cool electronic projects these days.</p>Kaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com2tag:blogger.com,1999:blog-405422244557633109.post-20269175802193035312013-03-21T08:34:00.000+01:002013-03-21T08:34:02.115+01:00Model vs. Reality<p>My twitter feed currently is ablaze with discussions about sexism in <a href="http://ivory.idyll.org/blog/pycon-2013-and-codes-of-conduct.html">tech</a> and <a href="http://www.guardian.co.uk/science/us-news-blog/2013/mar/20/i-love-science-woman-facbook">science</a>. As a member of the social group that goes through life with difficulty set to "easy", of course none of this has happened to me. I don't know what it feels like to go to a conference where people constantly comment on my looks or gender instead of my work. As I lack the experience, and I also lack solid data, I don't want to write about that in this post.</p>
<p>However, as a computational biologist, I do have some experience with model vs. reality clashes, and I believe that might be the reason why people on the internet are surprised about the existence of female scientists or engineers. People also tend to get upset when they realize their mental model doesn't match reality, which might explain some of the emotional upset males show in the discussions I mentioned in the first paragraph.</p>
<p>Now, instead of taking the easy way out and blaming this on <a href="http://ars.userfriendly.org/cartoons/?id=19991114">internet stupidity</a>, I want to put another theory out there. <b>People often don't get statistics.</b>
In my day-to-day work, I frequently run into publications where there is at best a <a href="http://www.plosone.org/article/info%3Adoi%2F10.1371%2Fjournal.pone.0013060">loose correlation between the data and the model supposed to explain said data</a>. And I believe that's what is happening here as well.</p>
<p>So by the time-proven method of pulling data out of my hat, I propose that when you graph the "ability to do science" against the sex chromosome layout of individuals, you'll get something similar to this: <br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1IRkILkKNgGXNgzlUAQ9gZt4r4u-upNbtwQgjd9cMHjz3RXTDDfKhnKzvaIBKPG9je3s6qmURXkQNKhFacMB2g5G9bgGnXAorKuB47_oFvlSqcGcxFR56ZYhq8ThGA9G7t5qklZwsLsD0/s1600/gender_science_data.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1IRkILkKNgGXNgzlUAQ9gZt4r4u-upNbtwQgjd9cMHjz3RXTDDfKhnKzvaIBKPG9je3s6qmURXkQNKhFacMB2g5G9bgGnXAorKuB47_oFvlSqcGcxFR56ZYhq8ThGA9G7t5qklZwsLsD0/s320/gender_science_data.png" /></a><br>
So far, so good. The problem is that despite "ability to do science" not clustering for any sane definition of a cluster, the mental model of many people seems to look like this:<br>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqo89jIvg55YUt4Bxe16fIYitgT350-XMJOiMj6ETWk-VsfZj1-ApVNXRaP49RQFRjNf2ChTNZYsvztyjNnQHjCSv8cyBOMS9F8zSavrHKsgFF9sKAIF8E9TR_FCGcigyWUezBTY_m-pUk/s1600/gender_science_model.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqo89jIvg55YUt4Bxe16fIYitgT350-XMJOiMj6ETWk-VsfZj1-ApVNXRaP49RQFRjNf2ChTNZYsvztyjNnQHjCSv8cyBOMS9F8zSavrHKsgFF9sKAIF8E9TR_FCGcigyWUezBTY_m-pUk/s320/gender_science_model.png" /></a></p>
<p>If you have settled for a given model, there is quite some inertia to stay with your chosen model, even if the data doesn't back it up. If reality dares to come up with conflicting data, blame reality! The ripples of a lot of mental models running into reality hard are currently washing over my twitter feed. The inertia of sticking with your model makes it hard to realize it, but in the end <b>when reality and your model disagree, it is easier to change your model</b>. In my example graph, a lot of lines I could put in there would likely have a similar quadratic error. To me, this is a warning sign that my model probably is bad. In the example, the conclusion should be that not only "women are bad at science, men are great" (the red line) is wrong, but also every other attempt at constructing a linear correlation between the parameters. "Ability to do science" and "sex chromosome layout" are orthogonal characteristics*. Also, why is there an arrow on the x axis, when we're looking at discrete parameters?</p>
<p><small>* According to my hat, of course.</small></p>Kaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com0tag:blogger.com,1999:blog-405422244557633109.post-63500303644101561742012-05-14T18:07:00.002+02:002012-05-14T18:07:41.366+02:00Playing with POSIX pipes in Python<p>Recently I was faced with an external program that I wanted to call from my script that only writes its output to a file, not to stdout. Faced with having to call this program a lot of times in parallel, I decided to fake up its output files via POSIX FIFO pipes.<br>
Unfortunately the python API around FIFOs is pretty close to the POSIX API, so it feels a bit un-pythonish. The following post illustrates my approach to getting around this limitation.
</p>
<p>
<a name="workload"><h1>Workload</h1></a>
In order to simulate my workload, I came up with the following simple script called <code>pipetest.py</code> that takes an output file name and then writes some text into that file.
<pre class="prettyprint">#!/usr/bin/env python
import sys
def main():
pipename = sys.argv[1]
with open(pipename, 'w') as p:
p.write("Ceci n'est pas une pipe!\n")
if __name__ == "__main__":
main()
</pre>
</p>
<a name="the_code"><h1>The Code</h1></a>
<p>
In my test, this "file" will be a FIFO created by my wrapper code. The implementation of the wrapper code is as follows, I will go over the code in detail further down this post:
<pre class="prettyprint">
#!/usr/bin/env python
import tempfile
import os
from os import path
import shutil
import subprocess
class TemporaryPipe(object):
def __init__(self, pipename="pipe"):
self.pipename = pipename
self.tempdir = None
def __enter__(self):
self.tempdir = tempfile.mkdtemp()
pipe_path = path.join(self.tempdir, self.pipename)
os.mkfifo(pipe_path)
return pipe_path
def __exit__(self, type, value, traceback):
if self.tempdir is not None:
shutil.rmtree(self.tempdir)
def call_helper():
with TemporaryPipe() as p:
script = "./pipetest.py"
subprocess.Popen(script + " " + p, shell=True)
with open(p, 'r') as r:
text = r.read()
return text.strip()
def main():
call_helper()
if __name__ == "__main__":
main()
</pre>
</p>
<a name="code_in_detail"><h1>Code in Detail</h1></a>
<p>
So let's look at the code in more detail. The code I'm using relies on a bunch of libs from the python standard library, and is working with Python 2.6 and up.<br>
<ul>
<li><code>tempfile</code> is used to get a temporary directory for me to create the FIFO in.</li>
<li><code>os</code> has the <code>os.mkfifo()</code> call.</li>
<li><code>os.path</code> handles the path crunching required.</li>
<li><code>shutil</code> is used to remove the temporary directory after use.</li>
<li><code>subprocess</code> is used to run the workload script.</li>
</ul>
</p>
<a name="class_temporary_pipe"><h2>TemporaryPipe class</h2></a>
<p>
Next comes the nifty part, a <a href="http://docs.python.org/reference/datamodel.html#context-managers">context manager object</a> handling the creation and removal of the temporary FIFO pipe. Let's look at the class in detail.
<pre class="prettyprint">class TemporaryPipe(object):
def __init__(self, pipename="pipe"):
self.pipename = pipename
self.tempdir = None
</pre>
The class definition and the constructor don't really hide anything interesting, though it's worth noting that <code>self.tempdir</code> is set to <code>None</code>. That will make the clean-up easier further down.
</p>
<a name="class_temporary_pipe__enter"><h2>__enter__</h2></a>
<p>
<pre class="prettyprint"> def __enter__(self):
self.tempdir = tempfile.mkdtemp()
pipe_path = path.join(self.tempdir, self.pipename)
os.mkfifo(pipe_path)
return pipe_path
</pre>
The <code>__enter__(self)</code> function is the set-up code for the context manager. Here, a temporary directory is created. Afterwards, <code>os.mkfifo()</code> creates the FIFO. Finally, the pipe's path is returned.
</p>
<a name="class_temporary_pipe__exit"><h2>__exit__</h2></a>
<p>
<pre class="prettyprint"> def __exit__(self, type, value, traceback):
if self.tempdir is not None:
shutil.rmtree(self.tempdir)
</pre>
The <code>__exit__(self, type, value, traceback)</code> function is always called when the context manager's block is exited. Thus, it's the ideal place to run the clean-up, in our case removing the temporary directory and the pipe contained within it.
<code>shutil.rmtree()</code> takes care of this just fine. If <code>mkdtemp()</code> failed, we don't have to bother, of course. Our clean-up doesn't require any extra knowledge of the things we're cleaning up, so we're free to ignore all those parameters.
</p>
<a name="call_helper"><h2>The call_helper Function</h2></a>
<p>
<pre class="prettyprint">def call_helper():
with TemporaryPipe() as p:
script = "./pipetest.py"
subprocess.Popen(script + " " + p, shell=True)
with open(p, 'r') as r:
text = r.read()
return text.strip()
</pre>
Because <code>TemporaryPipe</code> is a context manager, it's useable from a <code>with</code> statement. This means that in the block inside the <code class="prettyprint">with TemporaryPipe() as p</code> block, there is a temporary directory containing a FIFO pipe. Because <a href="#class_temporary_pipe__enter"><code>__enter__()</code></a> returns the pipe's path, that will be assigned to <code>p</code> within the block.<br>
<code>subprocess.Popen()</code> is now used to run the <a href="#workload">workload script</a>, going via a shell to evaluate the hashtag. This probably isn't the smartest idea performance-wise, but this is proof-of-concept code after all.<br>
After the workload script was run, another <code>with</code> statement opens a new block using the pipe's path, opening the FIFO for reading. The text is read out and the newline stripped. Now, the <code class="prettyprint">return</code> statement returns the read text, and also causes the pipe's context manager to call the <a href="#class_temporary_pipe__exit"><code>__exit__()</code></a> function to clean up.
</p>
<a name="conclusions"><h1>Conclusions</h1></a>
<p>
I'm pretty content with the way the <a href="#call_helper"><code>call_helper()</code></a> function reads. The complexity of setting up and then cleaning up the FIFO is hidden away in the <code>TemporaryPipe</code> class. I spent a bit of time coming up with this, so I thought I'd share this solution with other people. Now I just need to add this to my utility library and write tests for it.
</p>Kaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com0tag:blogger.com,1999:blog-405422244557633109.post-81018171452630604042012-03-31T02:04:00.001+02:002012-03-31T02:04:21.739+02:00Samba4 DNS sprint, day 5 summary<p>Another long and only partially successful day is behind me, and my allocated time for this sprint is over.
I said "partially successful", because I did not manage to get GSS-TSIG working. This is mostly due to the fact that
I don't understand how to hook it up to GENSEC/gss on the Samba side. The API is a bit confusing to the uninitiated.
What I did get done was to get to a point where incoming TKEY messages are parsed and checked, and pretty much handled correctly.
We currently bail out of there with a BADKEY error, pretending the client's key didn't work. If someone with a reasonable grasp of
GENSEC would explain what I need to do there to get the GSSAPI blob from the client authenticated, I would expect GSS-TSIG is very,
very close.</p>
<p>Because it's the end of the week let me take a look at the high and low points of this sprint over the week:
<ul>
<li>High point: On Tuesday morning, I finally got forwarding sorted out. Ever since Tuesday, all DNS requests on my dev machine were handled by my local samba server.</li>
<li>Low point: I wasted most of Tuesday trying to debug my HMAC-MD5 signing code. Debugging crypto is hard, because the only debug tool available is "stare at the code and think very hard". This might be the weapon of choice of the kernel community, but certainly not my preferred way of doing things.</li>
<li>High point: On Wednesday morning, I managed to fix signing of TSIG requests.</li>
<li>Low point: This got me work on TSIG some more instead of moving on to GSS-TSIG, and ultimately failed because signing of TSIG replies doesn't work correctly yet, another day wasted.</li>
<li>Low point: After reading up on TKEY and GSS-TSIG, I realized that I didn't really understand what I had to do in Samba to get this sorted out. This ended up being a major stumbling block, in fact I'm still stuck there.</li>
<li>High point: During my tries to find a useful test for TKEY, I set up a Win7 client for my domain, and after a tiny fix to get PTR records handled in the update code, that machine would correctly register forward and reverse zones (without crypto, but also without complaining), and was perfectly happy using samba's DNS service for it's needs.</li>
</ul>
</p>
<p>So to sum up, forwarding turned out to be a neater feature than I initially expected it to be, and allows me to run samba as my main name server for the local network. On the negative side, all that fancy crypto stuff isn't working yet. I do feel that none of these is really far off anymore. Maybe another pair or two of eyes would help there. I've updated the <a href="https://wiki.samba.org/index.php/DNS#Internal_DNS">Samba Wiki DNS</a> page to reflect the current status.</p>Kaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com0tag:blogger.com,1999:blog-405422244557633109.post-83497066294910573272012-03-30T01:28:00.000+02:002012-03-30T01:28:09.754+02:00Samba DNS sprint, day 4 summary.<p>I'm still a but stuck with TKEY/TSIG, unfortunately. While looking at the GSS-TSIG implementation we have in libaddns, I realized that I could simplify my time handling. That ended up fixing my TSIG issues from yesterday. That is, I can now correctly generate the client/request side of a HMAC-MD5 TSIG. The server side still seems broken, at least I can't get dig to accept my reply signature, and if I query bind the server reply differs from what I would calculate fore it. Oh well.</p>
<p>I've looked at plain TKEY, but for now it doesn't really seem worth the effort. So I've decided to work on GSS-TSIG directly instead. I don't really know how to deal with the Gensec side of this, though, so it's a bit hard to keep the momentum going for this. I'm beginning to fear that I won't get this implemented this week. Not because any part of it was particularly hard, but because there's tons of little things that all take a couple of minutes. And of course sitting in front of the computer alone lone ranger style isn't the most fun way to develop software.</p>
<p>For tomorrow, I hope to get a bit more done than today. I'll be working on a little gss-tsig test utility based on libaddns that I can use to test my server implementation. That should at least allow me to figure out what's going on at specific steps. I still might need some help on the Gensec side.</p>Kaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com0tag:blogger.com,1999:blog-405422244557633109.post-66512398981803443882012-03-29T08:04:00.000+02:002012-03-29T08:04:53.153+02:00Samba DNS sprint, day 3 summary<p>Some progress on the TSIG front, but I'm stuck with the exact signing method for a packet.
For some reason dig and I disagree on what the HMAC-MD5 of a specific query should be. <a href="http://www.ietf.org/rfc/rfc2845.txt">The RFC</a> is a bit vague, and the BIND code of that area seems to be in assembler. (Ok, it's C, but their coding conventions differ so much from ours that I probably have to spend a week getting my brain to adjust to that)</p>
<p>So I'm not continuing on hmac-md5 support, but will instead look at GSS-TSIG directly today. That's the must-have feature, and the whole week would be wasted if I didn't get <i>that</i> in.</p>
<p>TL;DR: HMAC-MD5-TSIG stupid, working on GSS-TSIG now.</p>Kaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com0tag:blogger.com,1999:blog-405422244557633109.post-59037513097857510042012-03-27T23:08:00.001+02:002012-03-27T23:08:27.441+02:00Samba4 DNS sprint, day 2 summary<p>I actually spent my time working out some smaller kinks in the DNS server that I ran into while using it as the only DNS server on my development machine. I also started with restructuring my dns processing code a bit so I can handle TSIGs in a sensible way. I've got dig set up to send TSIGs with an all-0 hmac key, so for tomorrow I should be ready to go.</p>
<p>Oh, and I pushed my dns forwarder work to master, and it passed autobuild. Life is good.</p>Kaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com0tag:blogger.com,1999:blog-405422244557633109.post-87144554723917757932012-03-27T09:12:00.000+02:002012-03-27T09:12:18.388+02:00Samba4 DNS sprint, day 2<p>Ok, so I cheated a bit and kept poking at the DNS forwarder code a bit more yesterday after posting my summary. I didn't quite get anywhere final before I went to bed, but this morning, while waiting for my coffee to run through the machine, I got this thing set up. I now can forward requests the internal server doesn't feel responsible for to another DNS server and get the reply back to the client. :) It's not quite production-ready code, but it sure works good enough to switch my DNS settings on my development machine to use Samba DNS.</p>
<p>That makes today TSIG-day. Time to re-read RFC2845 and see if I can get this implemented in my test client.</p>Kaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com0tag:blogger.com,1999:blog-405422244557633109.post-17051356827932790562012-03-26T22:10:00.001+02:002012-03-26T22:10:52.492+02:00Samba4 DNS sprint, day 1 summary<p>Ok, of course this didn't go as planned. It took longer than expected to figure out how to best test my DNS library, which by itself seems to work ok but also only is a thin wrapper around tdgram, so it doesn't do anything fancy yet.</p>
<p>I played with getting some code into the server, but I think I'm not quite doing the right thing there yet. I've set myself a deadline until tomorrow 11:00, if I haven't got it by then, I'm back to TSIG et al.</p>
<p>All in all, I notice that with all the python programming I've been doing recently, my C-fu has rusted a bit. I hope today will prove to be the WD-40 I needed to get going again. :)</p>
<p>Oh well, enough for today, more Samba DNS work will come tomorrow.</p>Kaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com0tag:blogger.com,1999:blog-405422244557633109.post-42402897989085874412012-03-26T11:56:00.001+02:002012-03-26T11:56:05.027+02:00Samba4 DNS sprint, day 1Samba has it's own small DNS server built in, but it's still lacking a couple of very nice-to-have features. This week, I'll be trying to get as many of those in as possible.
There's two big parts here. One is getting forwarder support, so we can query other name servers on behalf of our clients. The other big item is getting signed updates to work so windows clients can sign their dynamic update requests.
My battle plan for this week is:
<ul>
<li>Have a quick stab at a really simple forwarder library, but fall back to running dnsmasq with forwarding set up if I don't get anywhere until early afternoon today</li>
<li>Implement shared secret TSIG updates, to get the TSIG logic sorted out</li>
<li>Implement TKEY exchanges as specified in RFC2930, to set up the TKEY handling infrastructure</li>
<li>Make GSS-TSIG work as a possible signing method, so Windows is happy finally</li>
<li>More work on the forwarder library if needed/I have the time</li>
</ul>
Let's see how far I'll get, I'll post another update with what I accomplished today in the evening.Kaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com1tag:blogger.com,1999:blog-405422244557633109.post-81544239518346614242012-03-16T06:44:00.000+01:002012-03-16T06:44:45.583+01:00Running Samba's autobuild.py<a href="http://samba.org/">Samba</a> has a lot of tests, and we like to run them often. In order to easily do that, we've got a script that checks out a bunch of repositories and runs all tests in them, in parallel and independent of each other. It's living in the source tree at <code>scripts/autobuild.py</code>. Here's my notes for running <code>autobuild.py</code> on a local machine.
First, set up an in-memory file system. <code>autobuild.py</code> and the tests run by it touch a lot of files, and not running these tests on a spinning disk will speed things up a lot.
<pre class="prettyprint">
# create the memdisk location
mkdir /memdisk
# default size is half your ram, use -o size=SIZE
# to change that if needed
mount -t tmpfs tmpfs /memdisk
# now create an image file, samba's tests don't like plain tmpfs
# Needs to be bigger than 3 gig
dd if=/dev/zero of=/memdisk/build.img bs=1MiB count=4000
losetup /dev/loop0 /memdisk/build.img
# format as ext2, no need to do journalling
# it's gone when the machine fails anyway
mkfs.ext2 /dev/loop0
# mount
mkdir /memdisk/kai
mount /dev/loop0 /memdisk/kai
chown -R kai:kai /memdisk/kai
</pre>
And now, I can just run <code>./script/autobuild.py</code> and get a coffee while all the tests are run.Kaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com0tag:blogger.com,1999:blog-405422244557633109.post-66721388449549272962011-12-08T09:55:00.001+01:002011-12-08T09:56:21.239+01:00Python Regexes: Named Groups. Cool BananasI'm currently writing a Python parser for GenBank files. I know BioPython has one, and it doesn't even suck, but BioPython requires a bunch of C extensions, so I can't go and just ship it with my Python application.
So I'm creating a BioPython-compatible API for the classes that I need for antiSMASH, without the dependency tail BioPython forces on me.
Having contributed to BioPerl before, I do like to use regular expressions for token-based parsers, especially as I'm not too fond of lexers in Python.
Now, a GenBank header is a peculiar thing that stems from the punch card ages, with a fixed-width format. Unfortunately, at some point that format changed, and things moved around. And there's a ton of programs out there that produce GenBank files that are slightly off. So parsing the header using a token-based approach seems like a good thing.
Now, let's look at the first line. That has a bunch of interesting information.
<pre class="prettyprint">LOCUS SCU49845 5028 bp DNA PLN 21-JUN-1999</pre>
The 'LOCUS' tag explains what this line is about, then there's the accession number for the sequence, the length of the sequence, the type of the molecule, some classification where the sequence comes from, and the date the sequence last saw a major update.
The regex to parse this is pretty straightforward (yeah, right):
<pre class="prettyprint">LOCUS\s+([\w.]+)\s+(\d+)\sbp\s(ss-|ds-|ms-|\s{3,3})(\S{2,4})\s+(linear\s\s|circular|\s{7,7})\s+(\w{3,3})\s+(\d\d-\w{3,3}-\d{4,4})</pre>
Incidently, this is a great example for why people dislike regular expressions.
Now, in both Perl and Python, there's a way to define verbose regular expressions, so you can restate the regular expression as:
<pre class="prettyprint">LOCUS\s+ # Header line starts with LOCUS tag followed by multiple spaces
( # accession number regex:
[\w.]+ # any alphanumeric character or '.'
)
\s+ # skip over whitespace
( # sequence length
\d+ # digits only
)\sbp\s # skip ' bp ' string
( # single, double or mixed stranded or nothing
ss-|ds-|ms-|\s\s\s # can be all spaces
)
( # Molecule type DNA, RNA, rRNA, mRNA, uRNA
\S+
)
\s+
( # linear, circular or seven spaces
linear|circular|\s{7,7}
)\s+
( # division code, three characters
\w{3,3}
)
\s+
( # date, in dd-MMM-yyyy
\d\d-\w{3,3}-\d{4,4}
)</pre>
This is already pretty decent, but Python can do one better. With the current version of the regex, I need to remember that the molecule type is the 4th group, so match.group(3) will be what I'm looking for. Python decided to extend the Perl extension syntax a bit more, to add named groups. With <code>?P<name></code> you can name groups. and then call match.group('name') to access them later. So the final version of the parser regex turns into
<pre class="prettyprint">LOCUS\s+ # Header line starts with LOCUS tag followed by multiple spaces
(?P<accession> # accession number regex:
[\w.]+ # any alphanumeric character or '.'
)
\s+ # skip over whitespace
(?P<length> # sequence length
\d+ # digits only
)\sbp\s # skip ' bp ' string
(?P<stranded> # single, double or mixed stranded or nothing
ss-|ds-|ms-|\s\s\s # can be all spaces
)
(?P<molecule> # Molecule type DNA, RNA, rRNA, mRNA, uRNA
\S+
)
\s+
(?P<formation> # linear, circular or seven spaces
linear|circular|\s{7,7}
)\s+
(?P<division> # division code, three characters
\w{3,3}
)
\s+
(?P<date> # date, in dd-MMM-yyyy
\d\d-\w{3,3}-\d{4,4}
)</pre> and you can use speaking names to access the group's contents later. Great to make the code more readable. Combined with a bunch of tests, that should stay maintainable.Kaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com0tag:blogger.com,1999:blog-405422244557633109.post-10601899291215337622011-08-12T09:16:00.002+02:002011-08-12T17:08:06.669+02:00From the frontline, day 5<div>Another day, another piece of testing mayhem. I've completed the 0.1 version of my <a href="http://pypi.python.org/pypi/Flask-Downloader/0.1">Flask-Downloader</a> helper class. With this, I could complete my web app. Now, the downloader itself has a bunch of tests to make sure it's working as expected, but I was also going to test the corresponding code paths in the web app's tests.<br />
The user can provide the input either by uploading a file or by giving an accession number. Testing for the file uploads was easy, as the Flask test client accepts file-like objects as data input for POST requests. So testing the app will do the right thing is as easy as:
<pre class="prettyprint">def test_upload(self):
file_handle = open(tmp_filename)
data = dict(file=file_handle)
rv = self.client.post('/upload', data=data)
assert "upload succeeded" in rv.data
</pre>
Assuming your upload function listens on '/upload' and returns a page that contains "upload ducceeded", of course.</div>
<div>Testing file downloads is a bit more elaborated, because I don't actually want my downloader to connect to the internet during a test run. Minimock to the rescue! I can fake the download helper and create the same kind of output to fool the application code.
<pre class="prettyprint">from minimock import Mock
from werkzeug import FileStore
def test_download(self):
data = dict(id="FAKE")
# now create the fake downloader
tmp_file = open(tmp_file_path)
dl.download = Mock('dl.download')
dl.download.mock_returns = FileStore(stream=tmp_file)
rv = self.client.post('/download', data=data)
assert "download succeeded" in rv.data
</pre>
With similar assumptions as in the example before, and also the idea that you have a pre-existing file in tmp_file_path. A StringIO file-like object should do the trick as well.</div>
<div>With all the tests in place and a test coverage of 100%, I declare this campaign a success. I still need to deploy the new web app on my test server instead of the old one, but I'm going to do that next week. I will also continue my war on legacy code, now tackling the pieces that do the actual work. No war is over as quick as you'd initially hope after all. Also, I'm pretty sure the 100% code coverage don't mean there's not plenty of places for bugs to hide in, just that at least all of the code is looked at by the interpreter once. Still, it's a good conclusion to a busy week. Testing rocks.</div>Kaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com2tag:blogger.com,1999:blog-405422244557633109.post-47599255339211152482011-08-11T13:24:00.006+02:002011-08-11T23:58:03.254+02:00From the frontline, day 4<div>Today, I decided to go for the downloader component that can download files on the behalf of the users. While looking at how to test this, I actually noticed that the mm_unit functionality has been merged into the minimock package. Sweet.<br />
I wanted to keep this modular, a downloader sounds like a tool I could use in a couple of projects. So I created a Flask extension. There's a nice wizard script that automates the creation of the boilerplate files. Using the wizard, I created <a href="https://github.com/kblin/flask-downloader">Flask-Downloader</a>. It's pretty straightforward to use. There's a <code class="prettyprint lang-python">download(url)</code> function that will return a <code class="prettyprint lang-python">werkzeug.FileStorage</code> instance, just like the flask upload hander. I'll also add a <code class="prettyprint lang-python">save(url)</code> function that'll save the url's contents to a file without returning a file-like object.</div>
<div>Not too much to write about, spent a lot of time researching stuff today. Hope to get done with my changes tomorrow. Let's see how that'll work out</div>Kaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com0tag:blogger.com,1999:blog-405422244557633109.post-12985676228147172402011-08-10T09:21:00.004+02:002011-08-10T18:18:17.963+02:00From the frontline, day 3<div>Today, I decided to go and restructure my webapp into a package as recommended by the <a href="http://flask.pocoo.org/docs/patterns/packages/">Flask "Larger Applications" pattern</a>. Thanks to my existing test suite, the move was quick and pain-free. I had to fix imports in one of the tests, but apart from that, the only thing I had to do was splitting up the webapp.py file correctly into webapp/__init__.py, webapp/views.py and webapp/models.py.</div>
<div>I then started playing with implementing the actual functionality for uploading files and creating database entries for the jobs submitted. Took a while to get this right, never done database stuff with Flask before. But again, pretty easy to set up tests for all this. Also, I discovered <a href="http://packages.python.org/Flask-Testing/">Flask-Testing</a>, making flask unit testing even more comfy. Just had to fix up the <a href="http://twill.idyll.org/">Twill</a> module Flask-Testing comes with to not use the md5 and sha modules, triggering deprecation warnings. Will continue to write the last tests for the job submission form tomorrow, and then see how to deal with making the web app download data from elsewhere for the user.</div>Kaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com0tag:blogger.com,1999:blog-405422244557633109.post-90638813120913069452011-08-09T09:41:00.006+02:002011-08-10T09:20:43.744+02:00From the frontline, day 2<div>Looks like my system strikes back. A fitting thing to happen for an episode 2, I guess. Turns out that <code>nosetests</code> and <code>virtualenv</code> need some extra care and feeding when kept together. Installing another copy of nosetests into my virtualenv fixed the test failures I was seeing. Thanks to the folks on #python and #pocoo for pointing me the right way.</div>
<div>Of course this broke the code coverage. Nothing a <code>pip install --upgrade coverage</code> wouldn't fix, though. As an added bonus, the coverage html output now looks much nicer. I guess it was redesigned between whatever my system got and the version pip grabbed.</div>
<div>Of course, after spending quite some time writing tests for my email sending module, the #pocoo folks point me at the already existing <a href="http://packages.python.org/flask-mail">Flask-Mail</a> extension, that integrates into the Flask test harness (as in, if you're testing, it won't send email) already. Oh well. Switched, ditched quite some code and corresponding tests. Even less stuff I have to maintain myself.</div>
<div>Unfortunately, Flask-Mail doesn't seem to like it when you switch on <code class="prettyprint">app.config['TESTING'] = True</code> after initialization. Fortunately, you can still fiddle with the value used so it doesn't try sending emails, like so:
<pre class="prettyprint">def setUp(self):
webapp.app.config['TESTING'] = True
webapp.mail.suppress = True
</pre>
The key here is the <code class="prettyprint">mail.suppress = True</code> setting.
Once that's done, all the testing options work as expected. You can even have a look at the msg objects that would have been sent using the following snippet:
<pre class="prettyprint">def test_sent_mail(self):
"""Test if emails were generated and sent correctly"""
with webapp.mail.record_messages() as outbox:
rv = self.app.post('/send-email',
data=dict(message="hello world"))
assert len(outbox) == 1
msg = outbox[0]
assert "hello world" in msg.body
</pre>
I like it, this really gets all the stuff I do under test in a very straightforward manner.
</div>
Kaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com0tag:blogger.com,1999:blog-405422244557633109.post-41150874771140836582011-08-08T11:17:00.004+02:002011-08-08T18:39:36.249+02:00From the frontline, day 1<div>I've decided to start the campaign by ditching the existing PHP web app. I lost all confidence in it last Friday, when I found that it only worked by accident, due to a well-placed typo.<br />
As I'm rewriting the web app anyway, I thought I could also ditch PHP altogether. Not that it's necessarily a bad language for web apps, but the rest of the code is perl or python, so getting rid of php means one less language to get confused by.</div>
<div>Because this is the <a href="http://kblin.blogspot.com/2011/08/war-on-legacy-code.html">War on Legacy Code</a>, I'm not going to write untested code in this campaign. So first I need to brush up my python unit testing skills. I do have parts of a python version of the web app already (untested, that won't work later), but it's missing a user feedback form.<br />
I don't want to send an email for every run of the test suite, so I need to mock up smtplib.SMTP. After some web research, I'll be using Ian Bicking's <a href="http://blog.ianbicking.org/minimock.html">minimock</a> to provide my mock objects. As I don't just run doctests (even though they're pretty cool), I decided to also throw in <a href="http://blog.webmynd.com/2009/02/18/mocking-objects-in-python-unit-tests/">MiniMockUnit</a>, which makes minimock print the output to a StringIO buffer instead of stdout. That way, you can easily put it in a normal unit test.
</div>
<div>I usually run my tests using nosetests. Turns out, nosetests allows me to run both vanilla unit tests and doctests, and it also has a code coverage plugin. Thus,
<pre>nosetests -v --with-doctest --with-coverage --cover-html --cover-package="testmodule"</pre> will get the module "testmodule" tested using available unit tests, doctests and the test coverage will be reported in html in the cover/ directory. The <code>--cover-package</code> part seems to be needed to stop the coverage code from trying (and failing) to create coverage information files in the standard lib paths.</div>
<div>To sum up, I didn't actually see much battle.. er.. code today but my arsenal is filled with testing tools, and I'm well prepared to jump into the fray tomorrow. Also, thanks to some help from the folks on #gsoc IRC on freenode, I now have decent syntax highlighting and formatting on my blog, so I might be able to post code samples for real now. Life is good so far.</div>Kaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com0tag:blogger.com,1999:blog-405422244557633109.post-45537831166644348672011-08-08T08:04:00.005+02:002011-08-08T18:15:18.581+02:00War on Legacy CodeFollowing the hallowed US American tradition of declaring war on whatever things you don't like, I've decided to declare war on legacy code this week.
<br />
By legacy code, I mostly mean untested code, following the definition of Michael Feathers' book <span style="font-style:italic;">Working with Legacy Code</span>. That's a great read, by the way. If you're working with old code, you should go read it. I found that I've been doing most of the things mentioned already, but it's nice to see a systematic write-up about it.
<br />
My chosen battlefield in this war is the code at my day job, mostly because it's in a much worse shape than the code I deal with in the various Open Source projects I'm involved in. Seeing how my day job code is a Frankenstein's monster of Perl, PHP and Python parts, some of the work will be to get some of the tests done twice. In particular, I really want to get rid of the PHP parts.
<br />
I won't delve into the particulars of the code too much, it's published under the GPLv3 if anyone is interested. I will however try to post some daily news from the front lines, with things that I have thought about during that particular day of the battle.Kaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com0tag:blogger.com,1999:blog-405422244557633109.post-7310895941903854692011-06-19T22:29:00.004+02:002011-06-21T22:16:54.531+02:00Geeky stage props made easy<div>
Currently I'm involved in building the stage and props for an amateur theater, the <a href="http://www.brechtbautheater.de/">Brechtbau Theater</a> at my university. We're currently preparing for an Agatha Cristie play, "And then there were none". As a great opportunity, we are able to perform this piece in the city's professional theater, the <a href="http://www.landestheater-tuebingen.de/events/view/id/46131/date/1311026400">Landestheater Tübingen (LTT)</a>.</div>
<div>
Needless to say, we're really excited about this. Of course having to build a stage for a 300 seat theater is a bit different to building a stage for the 80 seat theater we've got at university. Also, we only have about four hours to set up the stage, and after the last night, we have to clear out immediately. While the way to build a modular stage design probably is worth a blog post on it's own, I want to talk about the electronics behind stage a bit today.</div>
<div>
Without wanting to spoil some of the surprises we have in store for our audience, we're working on a stage design with lots of big cogwheels and other moving parts. We will power some of these with the cheapest and most readily available power source we have available: actors. But some of the stage has parts that are just out of reach, or need to be positioned more precisely. For this, I'm currently planning to use a combination of stepper motors and hobby servos, run by an Arduino Uno.</div>
<div>
I'm still heavy in the prototyping stage, but I just wanted to share my discovery on how easy it is to do stuff like this with the Arduino. My current test setup looks a bit like <br /><a href="http://goo.gl/photos/f7cgza0vTJ" imageanchor="1" style="clear:right;margin-bottom:1em;margin-left:1em"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNSaeF1BxTDYeubRJxfsL7CZb4rsKkMTyBzq_h08Xr8dPTQAW6xHHZnitPD6GOpS_nnVeWMT9CJYKK0Osfe-q95Kh8Xax3QOQM-tfHN6vYr3afcaogEXVjGmKX-ijuM4frIYuRq9B3NTpr/s512/setup.jpg"></a>
<br/>
Using an L293D (left) and an L293NE (right) IC, I'm running two Trinamic bipolar steppers, and I'm also controlling four servo motors. For making all of these move forwards and backwards, I had to write about 50 lines of code, including whitespace and some comments. Arguably, moving a couple of motors forward and backward in a loop isn't that intersting, but the amout of work the Arduino default libraries already take care of is just great.
</div>
<div>Next, I'll have to figure out how to build a lamellar transport belt and move it with one of the steppers, while converting the circular movement of the other stepper to a linear movement. Never played with elaborate hardware stuff before, this is fun.</div>Kaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com0tag:blogger.com,1999:blog-405422244557633109.post-20471997221491510352011-02-17T16:24:00.004+01:002011-02-17T16:38:24.399+01:00Packaging python modules, the really easy wayI just had to package up a python package to make installation of a software we use at work easier. The systems we run here are Suse- and Ubuntu-based, so I got to package RPMs and debs.
I did package the odd perl package and some bioinformatics tool before, but I haven't looked at it for a while, so I was pretty rusty. I use the <a href="http://build.opensuse.org/">OpenSuse Build Service</a> to build RPMs, and the nice folks in FreeNode's #opensuse-buildservice pointed me a <a href="http://saschpe.wordpress.com/2010/12/12/braindead-python-packaging/">py2pack</a>, a truly amazing piece of software that creates a .spec file for you from package information in pypi.
Now, I had to package pysvn, which happens to not link to the downloadable file from pypi. As it turns out, this just stopped me from using py2pack for downloading the file, <code>py2pack generate</code> works fine. Filling in the missing License and Description information was easy, and my package was building on OBS in under five minutes.
For Ubuntu, <a href="https://wiki.ubuntu.com/PackagingGuide/Python">Python packaging guide</a> was a bit less comfortable, but a short while afterwards my Ubuntu package was built on <a href="https://launchpad.net/">Launchpad</a> as well.
Life is good. At least so far, now I get to make all of that work for system #3 in the department. This happens to be an OS sold by a company from the northern west coast of the USA, and it doesn't have an execute bit and can't deal with hashbang lines. Oh well, two out of three isn't too bad.Kaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com0tag:blogger.com,1999:blog-405422244557633109.post-37834708078216436722011-01-21T10:14:00.015+01:002011-08-08T23:45:24.280+02:00Defensive programming to the rescueI've just fixed a bug in a web app that I'm working on with a couple of colleagues, a bug that is a great example of a hard to find, easy to fix bug that could have been avoided by some defensive programming.
I thought I'd share this titbit to illustrate why defensive programming is a good idea.<div>The application we're working on consists of three parts:</div><div><ul><li>a web front-end that accepts jobs (php based)</li><li>a database keeping the job queue (SQL)</li><li>the back-end that runs the jobs (python)</li></ul>The job is actually an external script, which is important for this bug as well.</div><div>
</div><div>On the web front-end, the user gets to choose a couple of options for the job using check-boxes.</div><div>The bug we were seeing was that if the user just clicked one checkbox (and that wasn't the "all" checkbox), the external script would die with an "invalid options" error.</div><div>
</div><div>The options are passed into the SQL database as a comma-separated string, and our first suspicion was that for single options, there was a trailing comma left. A quick look at the database dump showed that this was not the case.</div><div>
</div><div>The next idea was that the back-end was not constructing the command line for the external script correctly. The code looked sane, but just to be sure I decided to do some printf debugging. In the printout of the command line, I finally found the bug. It was in the web front-end after all. Let's look at the code (changed a bit for brevity).</div>
<div><pre class="prettyprint">// 1 is "all"
if($_POST["1"] == "on" ){
$options = "1";
} else {
for ($i = 2; $i <= 10; $i++) {
if($_POST["$i"] == "on") {
$options .= " " . $i . ",";
}
}
$suffix = strripos($options, ",");
$options = substr($options, 0, $suffix);
}
</pre></div>
<div>Can you spot the problem? <pre>$options .= " " . $i . ",";</pre> is the culprit. It adds a leading white-space to the $options string. Looking at the database dump, that's easy to miss.</div><div>
</div><div>Now, why is this a problem? Let's look at the back-end code (changed for clarity again):</div>
<div><pre class="prettyprint">
job = get_next_job_from_work_queue()
args = ['./do_stuff.py', job.filename]
args += ['--options', job.options != None and \
jobs.options or '1']
subprocess.call(args)
</pre>
</div><div>The back-end uses an array for it's command line arguments to avoid having to call out to a shell first. This has the side effect that all the arguments are passed to the called script verbatim. Thus, a leading space character is kept and passed to the called application. This is <b>defensive programming fail #1</b>.</div><div>
</div><div>Still, this doesn't explain why the white-space is a problem. For that, we need to look at do_stuff.py (Changed for clarity again).</div>
<div><code><pre class="prettyprint">value = options[options.index(i) + 1]
if i == "--options":
if "," not in value and value not in ["1","2","3","4","5",\
"6","7","8","9","10"]:
invalidoptions(i)
</pre></code>
</div><div>
</div><div>Assuming we clicked on the #7 check-box in the front-end, " 7" is passed to do_stuff.py. " 7" is not in <code>["1","2","3","4","5","6","7","8","9","10"]</code>, so we fail. <b>Defensive programming fail #2</b> is in the <code>value = options[options.index(i) + 1]</code> line. Adding a strip() here would have avoided the bug. This was not found in manual testing, as the shell takes care of stripping the white-space characters for us. Still, a bit of defensive programming would have helped to avoid the issue.</div><div>
</div><div>If I ever teach a programming course, one of the assignments will be finding and fixing a bug like this.</div>
<span style="font-weight:bold;">Update:</span> 2011-08-08 Pretty-print code.Kaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com0tag:blogger.com,1999:blog-405422244557633109.post-52412851123611571592011-01-17T07:36:00.004+01:002011-01-17T07:47:33.505+01:00My Samba status 11/1Hi folks,
you will have noticed that I failed to post any of my "On the way to Samba4" reports in December last year. That was because I failed to do any Samba work in December, spending all of my time on work-related things. A few co-workers and me had to rush to get a <a href="http://antismash.secondarymetabolites.org/">web server</a> up and running that allows biologists to figure out what secondary metabolites like antibiotics might be produced by their bacterium/fungus. After pulling a 90-hour-week to get finished between Christmas and New Year's Eve, I had to take some time off <span style="font-style:italic;">not</span> staring at a computer screen. Batteries recharged now, I'm ready to get into action.
Over the weekend, I've been getting the skeleton for some DNS torture tests set up, I'm hoping to flesh this out a bit more during the week.
Cheers,
KaiKaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com0tag:blogger.com,1999:blog-405422244557633109.post-23221389716509320752010-12-01T23:58:00.001+01:002010-12-01T23:59:27.239+01:00On the way to Samba 4, week 47Not much to show for this week. I spent the week at a conference, and while I learned many interesting things, I didn't have time to get Samba-related work done. Let's try again for week 48.Kaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com0tag:blogger.com,1999:blog-405422244557633109.post-86656319170279107012010-11-24T23:05:00.003+01:002010-11-24T23:11:16.241+01:00On the way to Samba 4, week 46Really not much time to work on Samba this week. So I didn't get around to really debug the failing echo test for quite a while. Then tridge pointed out that I was trying to use a connected UDP socket as if it was not connected, and things started to work like a charm.
It doesn't look like I'll have much more time during week 47. Hopefully I will get around to clean up the patches and push my example anyway.Kaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com0tag:blogger.com,1999:blog-405422244557633109.post-22043945031370446012010-11-17T23:25:00.003+01:002010-11-17T23:59:32.839+01:00On the way to Samba 4, week 45A bit late, as usual, but I finally have something productive again. I've got a Samba4 UDP echo server and async client library (including torture test suite), and they're almost working. :)
I'm saying almost because I can only get it to work manually right now, not from "make test". I'm sure it's some small thing I'm missing, I'm expecting this to be fixed soon.
The code also still lacks some explanatory comments, but should be ready for the mainline for the week 46 report.
The client library and torture test also runs against netcat, so two "implementations" of echo servers are supported for sure. ;)Kaihttp://www.blogger.com/profile/13606545162348261048noreply@blogger.com0