The Shoes of the Fisherman's Wife Are Some Jive-Ass Slippers

tpot (at) frungy . org

rss

2008
Months
AugSep
Oct Nov Dec

Fri, 02 May 2008

Building RPMs in SCons

Here's a recipe I've developed for building a RPM in SCons with out too much mucking around. My big issue with RPM is the whole /usr/src/redhat thing which is silly from a permissions point of view, and also prevent multiple users on the same machine from building at the same time.

import string, os

# Sources for RPM

arch = 'i386'

sources = [
    'foo.spec',
    'foo-upstream.tar.gz',
    'bippity.patch',
    'flippity.patch',
]

# Create RPM build environment

env = Environment()

env.Append(
    ENV = {'HOME': os.environ['HOME']},
    TARFLAGS = '-z')

# Build tar file of sources

tarfile = env.Tar(
    'foo.tar.gz',
    sources)

# Build RPM from tarfile with included spec

rpm_defines = {
    '_topdir': Dir('#build').abspath,
}

rpm = env.Command(
    'rpm_dummy',
    tarfile,
    'rpmbuild %s -tb %s' % (
        string.join(['--define "%s %s" ' % (i[0], i[1])
                     for i in rpm_defines.items()], ' '),
        tarfile[0]))

# Take care of creating and removing various temporary directories
# required by RPM.

env.AddPreAction(rpm, Delete('#build'))

env.AddPreAction(rpm, [Mkdir('#build/SPECS'),
                       Mkdir('#build/BUILD'),
                       Mkdir('#build/RPMS/%s' % arch)])

env.AddPostAction(rpm, [Delete('#build/BUILD'),
                        Delete('#build/SPECS')])

# Clean up after ourselves

env.Clean(rpm, ['#build/BUILD', '#build/SRPMS', '#build/RPMS'])

I like the use of pre and post actions here to create the directory structure expected by RPM and the cleanup of it afterwards. Running scons -c will delete all the generated RPM files as well as the tar file of sources.

Oh yeah, installing and using ccache is absolutely essential for debugging RPM files.

posted at: 12:58 | path: /software/scons | permanent link to this entry

Sun, 06 Jan 2008

Getting Started with smbpython

After many false starts, Samba is starting to acquire some client-side scripting support. The language being used is Python, although Swig is being used to generate bindings. At a later stage perhaps other scripting languages might be supported.

At the moment the Python bindings are in their infancy, but it's still possible to do some useful things. To start hacking on the Samba Python bindings check out a copy of the source from Subversion and build as per usual:

$ svn co svn://svn.samba.org/samba/branches/SAMBA_4_0
[...stuff...]
$ cd SAMBA_4_0/source
$ ./autogen.sh && ./configure.developer && make
[...more stuff...]
Now these commands will build a complete Samba environment including the Python bindings. For the moment we will be working directly out of the build directory and not bother installing libraries, executables, etc. The only tweak we need to do is to set LD_LIBRARY_PATH to point at the shared libraries we have just built and then run a Python executable with all the Samba goodies compiled in:
$ export LD_LIBRARY_PATH=`pwd`/bin/shared
$ bin/smbpython
Python 2.5.1 (r251:54863, Oct  5 2007, 13:38:40) 
[GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 
What can we do from here? I'm hoping to write some more entries about some of the existing Python bindings, starting with tdb and ldb.

Thanks to Jelmer Vernooij for taking my bits and pieces of decrepit Swig bindings and turning it into something useful.

posted at: 21:30 | path: /software/samba | permanent link to this entry

Tue, 08 May 2007

SCons Builder for Ragel

Here's a SCons builder for the Ragel State Machine Compiler, based on the one for SWIG included in the SCons distribution.

#            tastes like -*- python -*-

"""Tool-specific initialisation for ragel."""

import SCons.Util
import SCons.Tool
import SCons.Action

def generate(env):

    c_file, cxx_file = SCons.Tool.createCFileBuilders(env)
    c_file.suffix['.rl'] = '.c'

    c_file.add_action('.rl', SCons.Action.Action('$RAGELCOM', '$RAGELCOMSTR'))

    env['RAGEL'] = 'ragel'
    env['RAGELFLAGS'] = SCons.Util.CLVar('')

    env['RLCODEGEN'] = 'rlcodegen'
    env['RLCODEGENFLAGS'] = SCons.Util.CLVar('')

    env['RAGELCOM'] = \
        '$RAGEL $RAGELFLAGS $SOURCE | $RLCODEGEN $RLCODEGENFLAGS -o $TARGET'

def exists(env):
    return env.Detect(['ragel', 'rlcodegen'])

posted at: 22:59 | path: /software/scons | permanent link to this entry

Wed, 02 May 2007

How to patch and rebuild a RPM package

Here's a nice tutorial on how to make a patch to a program distributed as a SRPM file. I would also recommend installing ccache and maybe distcc as finding and fixing bugs in a RPM build usually involves compiling the same source files over and over again.

posted at: 13:51 | path: /software | permanent link to this entry

Fri, 05 Jan 2007

Another Stevey Blog Rant About Emacs

Here. It's quite long and complicated. I wish I had time to write that much stuff about Emacs. Anyway, some choice quotes about whether you should learn Emacs Lisp:

"First, recognize that Emacs Lisp isn't going anywhere. Emacs is not going to magically become programmable in Python or Ruby or JavaScript or Perl overnight ... [Emacs Lisp] will never be obsolete knowledge. You might as well start learning it now, and reap the benefits now."

On Lisp syntax:

"If you do it enough, eventually you'll enjoy programming in Emacs-Lisp, no matter how much you hate it initially ... you'll initially dislike Emacs-Lisp's syntax; it's virtually guaranteed. Fortunately, it doesn't really have much in the way of syntax; almost everything follows the exact same s-expression form. So you should get past the syntax pretty quickly, and in a few weeks you'll start liking it just fine.
Kind of reminds me of people who dislike using tabs as syntax when writing Python code for the first time. I'm poking around with Ruby at the moment and having to put end everywhere is actually pretty annoying.

I've done some bits and pieces of Emacs Lisp programming over the years and it is quite seductive, for lack of a better word. I think that's the nature of functional programming though once you really get in to it.

posted at: 12:06 | path: /software/emacs | permanent link to this entry

Tue, 02 Jan 2007

Everything You Ever Wanted To Know About Autotools

And then some. Here is a funky autotools tutorial that clocks in at 557 pages.

posted at: 15:07 | path: /software | permanent link to this entry

Wed, 25 Oct 2006

Tridge on NULL pointer checks

From the samba-technical mailing list:

From:		tridge@samba.org
To:		samba-technical@samba.org
Subject:	Re: Coverity errors in libndr/
Date:		Wed, 25 Oct 2006 12:35:56 +1000

Luke,

 > Or put some assertion checks in?

time for my bi-yearly rant about assertions on NULL dereference :)

Unix and unix-like systems provide a highly efficient, zero code
assertion system. It interfaces to debuggers, it correctly propogates
to parent processes and it is even implemented in hardware on nearly
every system in existance. 

It's called the segmentation fault. It's wonderful. Use it :-)

Cheers, Tridge
posted at: 16:01 | path: /software | permanent link to this entry

Mon, 16 Oct 2006

bfr - nonblocking 8-bit-clean pipe buffer

I recently discovered the bfr program while searching for a way to watch a large video file stored on a web server connected by a slow pipe. The premise is that your link is slower than the rate at which the video codec consumes data so say hello to Mr Progress Bar every ten seconds or so. Most video players can buffer up a small amount of data and some even allow you to change the size of the buffer but sometimes this just doesn't work well.

Here's my command line:

$ wget -q -O http://some.domain/bigassfile.ogg | \
  bfr -pk -b 100m | \
  xine stdin://
The command line above starts a wget of a big-ass file, then uses bfr to start accumulating up to 100M of data and displays a progress bar in KB on stderr. The xine video player is used to display the output appearing on standard input.

The exact moment when streaming starts is 10% of the buffer size though the options to change this don't seem to work as advertised in the manual page. The progress bar is very nice though as it displays a graphical display of the size of the buffer, as well as the rate data is entering and leaving. If the buffer empties completely, you can hit pause in xine and go get a cup of coffee while the buffer refills.

posted at: 14:33 | path: /software | permanent link to this entry

Tue, 26 Sep 2006

agulbra-switch-cpp-h

I was thinking the other day that my life would be so much better if I could be editing a C++ file in Emacs and by simply hitting a key, the header for that file would be loaded. Hitting the key again would swap back from the header to the implementation. Before breaking out the Emacs Lisp manual I did a quick search and it turns out that those crazy kids at KDE have such a function in their kde-devel-emacs.el file.

Copy this bit of elisp somewhere and bind it to a key:

; From kde-devel-emacs.el, by by David Faure <faure@kde.org>

(defun agulbra-switch-cpp-h ()
  "Switch to the corresponding .cpp, .C, .cc or .h file."
  (interactive)
  (let ((n (buffer-file-name))
        (c nil))
    (cond ((and (string-match "\\.h$" n)
                (progn
                  (setq c (replace-match ".cpp" t t n))
                  (file-readable-p c)))
           (find-file c))
          ((and (string-match "\\.h$" n)
                (progn
                  (setq c (replace-match ".cc" t t n))
                  (file-readable-p c)))
           (find-file c))
          ((and (string-match "\\.h$" n)
                (progn
                  (setq c (replace-match ".C" t t n))
                  (file-readable-p c)))
           (find-file c))
          ((string-match "\\.h$" n)
           (find-file (replace-match ".cpp" t t n)))
          ((string-match "\\.h$" n)
           (find-file (replace-match ".cpp" t t n)))
          ;((string-match "_[a-z]+[0-9]*.cpp$" n)
          ; (find-file (replace-match ".h" t t n)))
          ((string-match "\\.cpp$" n)
           (find-file (replace-match ".h" t t n)))
          ((string-match "\\.cc$" n)
           (find-file (replace-match ".h" t t n)))
          ((string-match "\\.c$" n)
           (find-file (replace-match ".h" t t n)))
          (t
           (error "%s is neither .h, .cc, .C or .cpp" n)))))

posted at: 17:35 | path: /software/emacs | permanent link to this entry

Wed, 17 May 2006

On Dodgy Log Messages

logcheck is cool. A stray SMART error message in /var/log/messages suggested that a disk in the RAID array on samba.org was going to fail. Turns out that the RAID controller was not fully supported under Linux when the machine was installed, so RAID status info was not being logged and one of the disks had completely failed a number of months ago. Thanks to efforts by tridge we had a new disk up and running within a short period of time.

This has spurred me to continue tweaking my logcheck filters in case something like this happens again. It's very easy to visually filter (i.e completely ignore) a large number of messages and miss out on the important stuff so I've been researching each unfiltered message that appears and either doing something about it, or creating filter so I don't see it in the future.

According to this mailing list posting, the log message:

May 17 00:46:12 dp spamd[656]: prefork: select returned error on server filehandle:  

is perfectly normal and occurs every time a spamd child processes 200 messages. Unfortunately this message implies something has gone wrong when really everything is OK. Why does it appear in the log file then? Grr.

posted at: 12:23 | path: /software | permanent link to this entry