• So what exactly are you looking forward to in Leopard?

    So there's this big Leopard thing that's the talk of Mac town (well, that and Safari) with all the new features being revealed (officially, at least, to the general public) at WWDC 2007.

    Screenshot of Apple Leopard homepage


    Some of the features are pretty cool, most of them are mundane. For me, I am really looking forward to:

    • the new Finder - Finder sucks so bad as a file system interface. I use Path Finder, which incidentally had an upgrade recently to 4.7. The new Finder looks pretty (Cover Flow for files, sexy!) but what I'm really hoping for is a Finder with which you can actually be productive.
    • Ruby and Rails baked right into Mac OS X - while installing Rails and upgrading Ruby is a breeze on Mac OS X as it is right now, having these installed by default is pretty sweet. Even Capistrano will be included. Now, how one upgrades Ruby is another thing though...
    • Time Machine - Even though I already own a licensed copy of SuperDuper!, I'm still eager to use Time Machine. I mean, who isn't hooked on the time travel metaphor yet? It's like System Restore done right (with the advantage of hindsight, of course).

    What are you looking forward in Leopard?

  • That "Safari" thing...

    So what exactly is new in Safari 3 (other than the big OMGWTFBBQ over Safari for Windows)? TUAW has the best writeup (with screenshots of course) of the new features in Safari 3 I've seen so far. Check it out if you're lazy to try it out - I did install the beta and took it for a test drive, but was never much of a Safari user to recognize what exactly did change in Safari 3 beta, so this helped. I must say the new Find interface is really slick and the draggable tabs has been a long time coming (one of my biggest annoyances with Safari and Camino).

  • Nginx, PHP and a PHP FastCGI daemon init script

    One of the things us ex-Apache httpd or ex-Lighttpd users have to get used to when installing nginx is how there isn't built-in FastCGI support for process spawning. While these means nginx is more lightweight and faster, it does mean that you have to manage your FastCGI processes yourself.

    Having just upgraded to Ubuntu Feisty Fawn, I set to installing nginx and tried to get WordPress (which needs PHP, of course) running on it. Thanks to the new nginx package in the Feisty universe repository, getting nginx up and PHP (CGI version) and running is really straightforward. There're lots of tutorials to help you out as well.

    So that's that. The part that bugged me though, was how the tutorials always provided a script to start your PHP FastCGI processes, but never provided a way to ensure your FastCGI processes started up on a reboot (i.e. an init script). Once again, Google doesn't disappoint, turning up this php-cgi init script. Tweak the init script a little, put it in /etc/init.d/php-fastcgi, sudo chmod +x /etc/init.d/php-fastcgi, run sudo update-rc.d php-fastcgi defaults and place the configuration for the script in /etc/default/php-fastcgi, and you're done. You now have a PHP FastCGI init script that spawns and kills your PHP FastCGI processes.

    Note: Lighttpd does come with a spawn-fcgi binary that does the same, but I'm having trouble finding a suitable init script for spawn-fcgi (only the Gentoo emerge seems to have the init script). Still, this script works and I didn't really want to install lightty on my starving VPS.

    The init script: /etc/init.d/php-fastcgi

    #! /bin/sh
    ### BEGIN INIT INFO
    # Provides:          php-fastcgi
    # Required-Start:    $all
    # Required-Stop:     $all
    # Default-Start:     2 3 4 5
    # Default-Stop:      0 1 6
    # Short-Description: Start and stop php-cgi in external FASTCGI mode
    # Description:       Start and stop php-cgi in external FASTCGI mode
    ### END INIT INFO
    
    # Author: Kurt Zankl <[EMAIL PROTECTED]>
    
    # Do NOT "set -e"
    
    PATH=/sbin:/usr/sbin:/bin:/usr/bin
    DESC="php-cgi in external FASTCGI mode"
    NAME=php-fastcgi
    DAEMON=/usr/bin/php-cgi
    PIDFILE=/var/run/$NAME.pid
    SCRIPTNAME=/etc/init.d/$NAME
    PHP_CONFIG_FILE=/etc/php5/cgi/php.ini
    
    # Exit if the package is not installed
    [ -x "$DAEMON" ] || exit 0
    
    # Read configuration variable file if it is present
    [ -r /etc/default/$NAME ] && . /etc/default/$NAME
    
    # Load the VERBOSE setting and other rcS variables
    . /lib/init/vars.sh
    
    # Define LSB log_* functions.
    # Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
    . /lib/lsb/init-functions
    
    # If the daemon is not enabled, give the user a warning and then exit,
    # unless we are stopping the daemon
    if [ "$START" != "yes" -a "$1" != "stop" ]; then
            log_warning_msg "To enable $NAME, edit /etc/default/$NAME and set START=yes"
            exit 0
    fi
    
    # Process configuration
    export PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS
    DAEMON_ARGS="-q -b $FCGI_HOST:$FCGI_PORT -c $PHP_CONFIG_FILE"
    
    
    do_start()
    {
            # Return
            #   0 if daemon has been started
            #   1 if daemon was already running
            #   2 if daemon could not be started
            start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
                    || return 1
            start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON \
                    --background --make-pidfile --chuid $EXEC_AS_USER --startas $DAEMON -- \
                    $DAEMON_ARGS \
                    || return 2
    }
    
    do_stop()
    {
            # Return
            #   0 if daemon has been stopped
            #   1 if daemon was already stopped
            #   2 if daemon could not be stopped
            #   other if a failure occurred
            start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE > /dev/null # --name $DAEMON
            RETVAL="$?"
            [ "$RETVAL" = 2 ] && return 2
            # Wait for children to finish too if this is a daemon that forks
            # and if the daemon is only ever run from this initscript.
            # If the above conditions are not satisfied then add some other code
            # that waits for the process to drop all resources that could be
            # needed by services started subsequently.  A last resort is to
            # sleep for some time.
            start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
            [ "$?" = 2 ] && return 2
            # Many daemons don't delete their pidfiles when they exit.
            rm -f $PIDFILE
            return "$RETVAL"
    }
    case "$1" in
      start)
            [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
            do_start
            case "$?" in
                    0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                    2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
            esac
            ;;
      stop)
            [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
            do_stop
            case "$?" in
                    0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                    2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
            esac
            ;;
      restart|force-reload)
            log_daemon_msg "Restarting $DESC" "$NAME"
            do_stop
            case "$?" in
              0|1)
                    do_start
                    case "$?" in
                            0) log_end_msg 0 ;;
                            1) log_end_msg 1 ;; # Old process is still running
                            *) log_end_msg 1 ;; # Failed to start
                    esac
                    ;;
              *)
                    # Failed to stop
                    log_end_msg 1
                    ;;
            esac
            ;;
      *)
            echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
            exit 3
            ;;
    esac

    Config file for init script (the init script looks for this): /etc/default/php-fastcgi

    START=yes
    
    # Which user runs PHP? (default: www-data)
    
    EXEC_AS_USER=www-data
    
    # Host and TCP port for FASTCGI-Listener (default: localhost:9000)
    
    FCGI_HOST=localhost
    FCGI_PORT=9000
    
    # Environment variables, which are processed by PHP
    
    PHP_FCGI_CHILDREN=4
    PHP_FCGI_MAX_REQUESTS=1000

    nginx config file: /etc/nginx/nginx.conf

    location ~ \.php$ {
      fastcgi_pass   127.0.0.1:9000;
      fastcgi_index  index.php;
      fastcgi_param  SCRIPT_FILENAME  /var/www/chuyeow.wtf$fastcgi_script_name;
      include        /etc/nginx/fastcgi.conf;
    }

    My fastcgi.conf file (I'm not sure I need everything here...)

    fastcgi_param  QUERY_STRING       $query_string;
    fastcgi_param  REQUEST_METHOD     $request_method;
    fastcgi_param  CONTENT_TYPE       $content_type;
    fastcgi_param  CONTENT_LENGTH     $content_length;
    
    fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
    fastcgi_param  REQUEST_URI        $request_uri;
    fastcgi_param  DOCUMENT_URI       $document_uri;
    fastcgi_param  DOCUMENT_ROOT      $document_root;
    fastcgi_param  SERVER_PROTOCOL    $server_protocol;
    
    fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
    fastcgi_param  SERVER_SOFTWARE    nginx;
    
    fastcgi_param  REMOTE_ADDR        $remote_addr;
    fastcgi_param  REMOTE_PORT        $remote_port;
    fastcgi_param  SERVER_ADDR        $server_addr;
    fastcgi_param  SERVER_PORT        $server_port;
    fastcgi_param  SERVER_NAME        $server_name;
    
    # PHP only, required if PHP was built with --enable-force-cgi-redirect
    fastcgi_param  REDIRECT_STATUS    200;
  • Toilets and Linux evangelism

    Pardon the self-promoting cross-linking: Toilets and Linux evangelism (or what we use to build Bezurk) is an entry I just posted on the brand new Bezurk Blog about how the toilet is a good place to spread the word.

    If you've found other neat ways to use the free Ubuntu stickers (or even the Apple stickers that comes with iPods), do post it!

  • ImageMagick port "broken" temporarily

    Just in case anyone runs into this problem (which, I might add, would probably go away when either the portfile is updated or the source mirror fixes the problem) while installing ImageMagick via MacPorts...

    While trying to install Rmagick on my spanking, new, glossy, kakkoii MacBook, MacPorts reported a checksum error with the ImageMagick source tarball:

    Target com.apple.checksum returned: Unable to verify file checksums

    At first, I thought it was an outdated portfile but even after a sudo port selfupdate and sudo port -d sync, the checksum error was still occurring (checksum of the file: 4bcb4264c2170fe562b10a732f43e7af, expected checksum in the portfile: 9469ce1b1b645f8c728158cc434b0ff8).

    Turns out, the first listed master site (where MacPorts gets its source files from), http://imagemagick.linux-mirror.org/download/ is hosting a source tarball with a bad checksum. Digging around the man page for port a bit, and switching the order of the master source sites solved it, so it was just a case of a bad file on one of the mirror sites.

    sudo port edit imagemagick to edit the portfile and change the source mirror to a legit one. You should see something like this:

    master_sites \
      http://imagemagick.linux-mirror.org/download/ \
      http://ftp.surfnet.nl/pub/ImageMagick/ \
      sourceforge:imagemagick \
      ftp://ftp.imagemagick.net/pub/${name}/ \
      ftp://ftp.fifi.org/pub/ImageMagick/ \
      ftp://ftp.nluug.nl/pub/${name}/

    Just move an alternative master_site to the top of the list (I used the SourceForge one). There probably is a way to specify the master_site on the command line with port install but I've had just about enough of reading man pages and the now nearly unfindable MacPorts documentation (whatever happened to the old Darwin Ports site that had great documentation?)

    Anyway, I've written to the webmaster of the mirror site linux-mirror.org, so this would probably be fixed for all two of you who are gonna be installing ImageMagick via MacPorts within these few days or so. Still, it was a good exercise in debugging bad port installations.

subscribe via RSS