Traincoding: dynamic content for tftp
When installing many machines via PXEboot kickstart/d-i installs, it is often useful to generate pxelinux.cfg files on demand with contents grabbed from a database. When I worked at the university of amsterdam, I had to set up a cluster where easy reinstalls were a requirement. Basically it meant reboot — reinstall, unless told otherwise. How to tell otherwise? pxelinux.cfg/mac-address-file. At that setup, these files were generated by a php script that lived behind a certain url that was called at the end of a d-i run. Removing the file means that the machine will be reinstalled at the next reboot.
In my current job we also want easy installs, and due to scale the php script approach will not do. The files need to be generated beforehand or on the fly, using information from a database. In my search for a solution to this problem, I decided to see how easy it would be to make atftpd call an external command to generate content. As it turns out: very easy! atftpd already has the option to use regular expressions to do filename mangling. At the same points in the code where this does its job, one can easliy do what I wanted. It is implemented in this patch.
The patch is against the debian package, here is how to apply it (jaunty version of atftpd):
$ apt-get source atftpd $ wget -q -O- http://www.kaarsemaker.net/static/downloads/code/atftp.patch | patch -p0 $ cd atftp-0.7.dfsg $ autoreconf # Needed because configure.ac is modified $ dpkg-buildpackage -rfakeroot
If you do not use the debian package, make sure to autoreconf and to pass –enable-generated-content to ./configure.
The generated content feature can be used as follows:
- Add the “–content-generator /path/to/executable” argument to the atftpd commandline (eg. in xinetd.conf or /etc/default/atftpd, depending on your setup).
- Whenever a requested file cannot be found, atftpd will open a temporary file with tmpfile(3) and will execute your application, with its filenumber and the requested name as arguments (example: /usr/local/bin/tftp-generator 6 /var/lib/tftpboot/some_file)
- Your application is now responsible for writing the content that atftpd should send to the given fd (6 in the example). If the content needs to be stored, your application also must do so itself.
- If your application exists with a non-zero exitstatus or writes zero bytes, atftpd will treat that as “file not found”. If data is written and your application exits with code 0, the written data is sent to the client.
An example application can be found in the README.GENERATED file.
Uhmm did you send the patch upstream? No matter what you did, you should always say that Ubuntu has forwarded the patch upstream.
“Mark”, please realize that wordpress checks IP addresses and that the real Mark Shuttleworth is not in Australia right now (and also does not want Ubuntu members to spread lies, but that’s pretty much a given).
Overall, a very good idea Dennis. I was scratching my head at that problem recently, and I had not come to a satisfying conclusion. Generating the pxelinux.cfg file on the fly is something I had not considered … Will need to think abot it further.
Let me know if this patch works for you or needs changing. I’m pondering a few changes:
- Always use fd 4 and close other fd’s before exec()
- Passing the filename as –file filename and forcing applications to accept other parameters, ignoring unknowns. This allows one to change the ‘api’ more easily.
Updated patch has been uploaded.
A colleague gave a presentation on the system that this is part of at the Open Source Datacenter Conference, http://blog.koehntopp.de/index.php?url=archives/2440-Kickstart-Puppet.html