Cron != Shell

I’m as guilty as anyone of treating cron as if it’s “just a shell”, and it finally bit me today. I had a quick-n-dirty Postgres backup command that worked wonderfully from the command line:

/usr/local/postgres/bin/pg_dumpall -U pgadmin | gzip -9 > \
/usr/local/db/backups/pgsql/pgdump.`/bin/date +"%Y%m%d-%H%M%S"`.gz

But when I put this into my crontab, I started getting error messages about an EOF being reached before finding a closing ‘`’.

The answer is not to get rid of backticks and call an external script. The answer is to simply escape the percent signs! From `man 5 crontab`:

Percent-signs (%) in the command, unless escaped with backslash (\), will be changed into newline characters, and all data after the first % will be sent to the command as standard input.

Technorati Tags: , , , , , ,

Social Bookmarks:

Why Does SourceForge Hate Its Users?

SourceForge has been a lumbering, slow, clumsy, ugly site for a long time. So-called “improvements” over the past couple of *years* have done as much to hurt performance of the site as it has to make it prettier and (debatably) easy to navigate. In reality, it seems that most of the changes made to SourceForge over the years were done to maximize advertising space without regard for the end user experience.

I received further proof today that SourceForge hates its end users when I went to check up on the latest development efforts on the Moodle forums and found a link to this Moodle bug tracker entry. That’s right folks, the first contact sent from SourceForge to the user (in this case, the leader of a project that serves hundreds of thousands of people) came *AFTER* access to the project was unceremoniously revoked.

Moodle is now revisiting plans like setting up CVS mirrors and the like, which will probably be better in the long run anyway, but it just sucks that SourceForge wakes up one day and shuts your service down with little information and zero warning instead of contacting users ahead of time with trending statistics and saying something like “once you reach point x, we may need to start throttling or disabling your service”.

Technorati Tags: , , , , , ,

Social Bookmarks:

*STILL* No Multiple Inheritance in PHP!

This is maddening. There have been requests for multiple inheritance in PHP since I started using it in mid 1999. Of course, in mid-1999, I didn’t really care. There wasn’t much written in PHP that was any good, so I was writing little scripts of glue code to tie pieces of HTML together and the like. I wasn’t working on anything big. Now, like 8 years later, I *am* working on a big project, and I *need* multiple inheritance, and it’s *still* not there!

Here’s my dilemma: I wrote an extension for Moodle 1.5.x. Not that it’s really important, but I implemented a new assignment type geared toward Computer Science departments. The current release of Moodle is 1.8. In looking at a new built-in assignment type in 1.8, I’m noticing that it does roughly 85% of what I need it to do. Further, in looking at the code, it appears that the remaining 15% wouldn’t be difficult to implement.

“I’ll just make my assignment type inherit from this new built-in one, write a couple of new methods (the code for which can be ripped almost verbatim from my old 1.5.x code), and I’ll be on my way!”

Wrong. The shiny new built-in assignment type extends the base assignment class, and that’s the whole inheritance story in PHP. Even though 90% of what I need is in that new built-in class, I can’t base my class on it, because *it* already inherits from another class.

Now, I make no claims of *being* a computer scientist, so my question is simply this:

“Am I missing something here, or does it seem moronic to keep debating the usefulness of this particular feature instead of just implementing it?”

For the record, I don’t mean for this to be a rhetorical question. If you have an answer or comment (besides “it’s open source, just implement it yourself”), I’d love to hear it.

Technorati Tags: , , , , , , , ,

Social Bookmarks:

Quick CVS Cheat Sheet

Actually, I’d love to say that I’ve moved completely to using git instead of CVS, but the truth of the matter is that, for a recent project where I’m just trying to consolidate a whole bunch of admin scripts, organize them under one (managed) roof, and (most importantly) get a bunch of admins on board using it, CVS is really probably the way to go. Besides, there’s no branching and merging going on, all of the development is internal, and for simple stuff like this, CVS is really just fine.

The one thing I used to hate about CVS is that it seemed like every time I switched gears from doing some project not involving it to one that used it heavily, I would have to read the whole manual all over again. One thing that helps me remember things is writing about them, so here’s a cheat sheet full of things that I do either regularly, or occasionally enough to be annoying ;-)

For the duration of this post, we’ll work with a project called ‘foobrew’, which lives on a remote CVS server. This isn’t meant to be a total n00b intro to CVS, so I’ll assume you know the basics like how to set your CVS_RSH environment variable, for example.

Checking out a repository, or part of one

If you just want to check out the entire project from a remote CVS server, you’d simply run this command:

cvs -d :ext:username@cvs.yourdomain.com:/cvs foobrew

This will download every single file in the source tree into a directory under the one you ran this command from called ‘foobrew’. One of the projects I’ve imported into CVS has various modules that are worked on by different people. If someone only wants to write code for one module, they can easily check out only one module from the repository. For example, to get the ‘malt’ module from the ‘foobrew’ repository, you could run this command:

cvs -d :ext:username@cvs.yourdomain.com:/cvs malt

Of course, maybe the module hasn’t yet been defined, but you know that there’s a directory called ‘malt’ in your repository, and that’s what you’re interested in. Well, in that case, you just alter the above command a bit:

cvs -d :ext:username@cvs.yourdomain.com:/cvs foobrew/malt

Both of those commands result in a directory being created locally called ‘malt’.

Adding to a repository with ‘cvs add’… or not

You don’t *have* to use ‘cvs add’ to add stuff to a repository, but sometimes it’s the easiest way to do what you need. If you have already checked out the project, and you want to add a file to the project, it’s not enough to just copy the file into the right directory. You have to tell the CVS server that you want the file to be managed using CVS, using ‘cvs add’, and then you have to actually check the file in using ‘cvs commit’. So, once you’ve copied the file into place, you would do this:

cvs add README.txt

Followed by

cvs commit README.txt

If the file you want to add is a binary file, only the syntax of the ‘cvs add’ command changes:

cvs add -kb somefile.bin

Using ‘-kb’ tells the CVS server to treat this a bit differently by *not* putting identification strings in the file that could render the binary file un-runnable the next time you check it out of the repository.

The above assume that you’ve checked out the repository, which you might not want to do. For example, if you have a directory full of code you’d like to add to an existing repository, you can add it without first doing a checkout like this:

cvs -d :ext:username@cvs.yourdomain.com:/cvs import foobrew/mycode bkj start

This will create the ‘mycode’ directory under our top-level project directory on the remote server. The ‘bkj’ and ‘start’ arguments are a vendor tag and release tag, respectively, and are required whether you make use of them or not. The use of these tags is out of the scope of this document, but I’ll write about it in another one later :-) In general, if you need to use these tags, start looking at using git ;-P

Another option that might be easy enough is to just check out the top level directory of the project, and then use ‘cvs add’ to add your files. If you only want to check out the top level directory of the project, run this command:

cvs -d :ext:username@cvs.yourdomain.com:/cvs checkout -l foobrew

The ‘modules’ file

If you want to find out what modules are available, or you want to create a module, you can check out the ‘CVSROOT/modules’ file from any CVS repository, and then inspect it or edit it. Since you’d presumably inspect it before editing it, I’ll show here how to create a simple module:

  • cvs checkout CVSROOT/modules
  • cd CVSROOT
  • open the ‘modules’ file, and add a line like this to define a module called ‘hops’
    • hops foobrew/hops
  • save the file, and run cvs commit modules to commit the change.
  • cd ..
  • run cvs release -d CVSROOT to release the CVSROOT directory and remove it from your working copy (since it isn’t of general use on a day-to-day basis).

Overriding Credentials

One nice thing about CVS is that you can enforce accountability with it. You can give everyone an account on the CVS server and see who made what changes when. On one project, the code needs to be checked out to a directory where only root has write access. So create a read-only user on the server for that user so they can check out the code. But then what happens if I discover a problem in the working copy of the code? Well, generally you’d just make the edit in place and run ‘cvs commit’, but that’s not going to work in this case because by default, CVS uses the credentials that were used to check out the code, which was done in this case by a read-only user. In this case, I need to provide my *own* credentials on the command line to override the ones that were stored locally during the checkout. This is done just like any other command that requires credentials. I just put this note here to remind myself that this is possible:

cvs -d :ext:username@cvs.yourdomain.com:/cvs commit

Technorati Tags: , , , , , , , , , , , ,

Social Bookmarks:

I’m Now A FiOS Customer

Some people will be shocked to hear that I’m now a FiOS customer, especially if they’ve read a previous post I made over a year ago now about how FiOS looked like the biggest scam ever. Well, I’m not sure I changed my mind per se, but a number of realizations have been made over the past months that made me reconsider.

But… But why?!

First, you have to know that before this, I got cable TV and internet service from Comcast. I can’t stand Comcast. Their customer service is terrible, their pricing is outrageous, the reliability of the service is so-so at best, and the quality of the signal is spotty. To top this off, their on-screen guide recently underwent a change which resulted in about 2/3 of the space being devoted to ads of one form or another.

Second, you also need to know that I’m too far from a CO to get DSL. I can get what’s called IDSL, which is really just ISDN. A *full* three times faster than dialup, at about $100/month!

Third, you also need to know my stance on VoIP: It’s not soup yet. Not from a technology standpoint – but from a political one. Until the issues about which packets can be passed over whose lines and all this, the telcos have zero incentive to treat VoIP traffic with any respect, since it competes with their own phone business. In fact, they have every incentive to impose restrictions and limits on that traffic. The result, for now, is shoddy, unreliable service that’s no better than your cell phone, in which case… just use your cell phone.

With all that in mind, I had to reconsider whether or not I cared about them taking my copper. Turns out I didn’t care. However, I also learned that I could’ve kept my copper in a number of ways. One was to tell them that my alarm system was not compatible and required copper (some do). Another way is to assess the attitude of the worker on site doing the installation. I’m pretty sure I could’ve told the guy to leave my copper alone and he would’ve been more than happy to leave it there. It saves him the work of removing it, and it was raining out during the installation.

Also note that they didn’t take my coax that was placed there by Comcast. So if I decide that Verizon really sucks as much as I think they do deep down inside, I can always move back to Comcast, which is my only other real choice anyway since I can’t get DSL.

Nuts & Bolts

The battery backup unit, as it turns out, emits a signal when the battery needs replacing. Verizon replaces it once every 5 years, and if it needs to be replaced sooner, then allegedly I can get a new battery at Radio Shack. So I’m told. I haven’t looked, but I’ve heard this from more than one source now, and it’s rare that sales, customer service, and the guys in the field are on the same page about anything, so I tend to think it’s at least based on reality. If someone can confirm with a part number or a link or something, that’d be even better!

My house is completely 100% wireless, and Verizon provides a modem/ap in one box. Mine is an ActionTec, which I’m told is new (at least to this guy it was new). The old ones, I believe, were Motorolas (the TV box is still Motorola). I was a little worried that this was going to be a total black box, but it’s not – you can have your way with it. It’s your default gateway, and it gives you an IP on a /24 network, usually 192.168.1.0/24 (I’ve never heard of anyone getting a different network by default), so just go to 192.168.1.1 and log in with username ‘admin’ and password ‘password’ or ‘password1′. How’s that for security?

If that’s not open enough for you, also note that the wireless access point broadcasts its SSID, uses a 40-bit WEP key, and has a firewall built in that is set (or, was set in my case) to “Minimum Security” which sets the default policy for both inbound and outbound traffic to “accept”. Ugh.

The good news is that the administrative interface on this thing is *really* nice, and has just about every feature you could want. I haven’t even been through every screen yet, but setting up MAC filtering, turning off SSID broadcasts, changing the firewall settings, and changing the admin login information took no time at all.

The TV box is the thing I’ll interact with less than anything else. It appears to have a zillion channels, some I’ve never even heard of, and the first two things I’ve noticed are 1) the channel changes and guide are much faster than comcast 2) the channels are grouped in ways that are unintuitive to old Comcasters like me. I’ll get used to it.

So that’s it for now. I’ll report back on the ActionTec, because that looks like it could be fun to mess with. Stay tuned.

Technorati Tags: , , , , , , ,

Social Bookmarks: