WordPress mu non-wildcard vhosts

December 4th, 2009

*** UPDATE ***
This hack is probably unnessesary, I found that wp-mu has a sites framework that is not exposed, there is a plugin that’s trying to accoplish the same thing I am. Just google ‘wordpress mu sites’
*******

I need to have multiple wordpress instances installed, but I want them each to have their own vhost, I also want an easy way to maintain them (upgrades and such). I thought wordpress mu could do this… but out of the box it only supports wildecards on a single domain. (blog1.example.com and blog2.example.com and blog3.example.com) Turns out you can change 2 lines (3 if you want to clean up a view cosmetically) and you seemingly can use wordpress-mu to host multiple domains. www.blog1.com and www.blog2.com and www.blog3.com

I’ve not deployed this yet… so use at your own risk. I’ll post again later with results after I’ve migrated a couple sites to it.

The problem: wp-mu assumes in vhost mode that all your blogs are of convention {something_here}.example.com. It does this by concatenating the domain you configure at install time onto the name of any new wordpress site you setup.

The solution: tell it not to append your installed time configured domain when you setup a new site. No special magic seems to happen with a new wordpress site’s configured domain after install time.

To show how this works this we’ll setup an example.com instance of wordpress mu and replace the wildcard magic so that not-example.com is hosted by the same code base.
1. download and and install wp-mu just as they tell you to, use example.com (set a hosts record to point example.com to your localhost) You’ll now have a fresh new wp-mu blog at example.com.
2. patch the files to remove the wildcard vhost magic
a. This change will remove the hardcoded base domain and will assume the domain name you’re accessing wordpress with is the current domain. Without amking this dynamic the authentication would fail on some or all of the configured sites.

wp-config.php
@@ -38,7 +38,7 @@
-define(‘DOMAIN_CURRENT_SITE’, ‘example.com’);
+define(‘DOMAIN_CURRENT_SITE’, getenv(‘HTTP_HOST’));

b. This is the concatenation magic that we want to prevent from happening. It undoes the “force append install-time configured domain” or in our example case, don’t force .example.com on the back of my new blog.

wp-admin/wpmu-edit.php
@@ -147,7 +147,7 @@
if( constant(‘VHOST’) == ‘yes’ ) {
-                       $newdomain = $domain.”.”.$current_site->domain;
+                       $newdomain = $domain;

c. This last one is optional. It’s just removes the domain name below the test box on the form for a new blog. This is a pure cosmetic change.

wp-admin/wpmu-blogs.php
@@ -582,7 +582,7 @@
<?php if ( constant( “VHOST” ) == ‘yes’ ) { ?>
-                                                       <input name=”blog[domain]” type=”text” title=”<?php _e(‘Domain’) ?>”/>.<?php echo $current_site->domain;?>
+                                                       <input name=”blog[domain]” type=”text” title=”<?php _e(‘Domain’) ?>”/>

3. Add a new wp site at not-example.com (add the hosts record that points to localhost again to test)
4. use the dashboard -> tools -> export to get an xml dump of a single instance blog that you can import into a wp-mu managed blog.

Like I said I’ve not actually deployed this yet, but authentication in and out of the two domains dashboard and frontend seem happy. I’ll be sure to update this post with any other issues I come across. let me know if you try it and if it works!


Expanding a xen disk image’s space

August 12th, 2009

I documented this a while back and never posted it. Had to use it again today so I figured it would be fun to post it.

Compiled these steps using these urls:

http://www.mail-archive.com/centos@centos.org/msg08928.html

http://www.howtoforge.com/linux_resizing_ext3_partitions_p2

1. use dd to create a 1 GB file

[root@virtserver os]# cd /var/lib/xen/images/os
[root@virtserver os]# dd if=/dev/zero of=Tempfile bs=1024 count=1000000

3.  backup your disk image

[root@virtserver os]# cp somehost.example.com-disk0 somehost.example.com-disk0.bkup

4.  append the tmp file to virtual image file

cat Tempfile >> somehost.example.com-disk0

5. attach to the disk image

[root@virtserver os]# modprobe xenblk
[root@virtserver os]# pwd
/var/lib/xen/images/os
[root@virtserver os]# xm block-attach 0 ‘file:/var/lib/xen/images/os/somehost.example.com-disk0′ xvda w

if you try and mount a file that doesn’t exist you’ll get output like this:

Error: Device 51712 (vbd) could not be connected.
File /var/lib/xen/images/os/notreal.example.com-disk0 is read-only, and so I will not
mount it read-write in a guest domain.
Usage: xm block-attach <Domain> <BackDev> <FrontDev> <Mode>

Create a new virtual block device.

if you copy and paste you may have to fix your single quotes. when I copy and pasted this I got a weird ascii error.

6. fsck

[root@virtserver os]# e2fsck -f /dev/xvda1
e2fsck 1.39 (29-May-2006)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/boot: 42/524288 files (2.4% non-contiguous), 28805/524112 blocks

[root@virtserver os]# e2fsck -f /dev/xvda2
e2fsck 1.39 (29-May-2006)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/: 43523/2097152 files (0.9% non-contiguous), 487769/2096482 blocks

7. Strip out the ext3 fournal

[root@virtserver os]# tune2fs -O^has_journal /dev/xvda1
tune2fs 1.39 (29-May-2006)

[root@virtserver os]# tune2fs -O^has_journal /dev/xvda2
tune2fs 1.39 (29-May-2006)

8. delete and re-add the last partition on the disk using the new end cylinder

[root@virtserveros]# fdisk /dev/xvda

The number of cylinders for this disk is set to 1156.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)

Command (m for help): p

Disk /dev/xvda: 9514 MB, 9514450944 bytes
255 heads, 63 sectors/track, 1156 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Device Boot      Start         End      Blocks   Id  System
/dev/xvda1   *           1         261     2096451   83  Linux
/dev/xvda2             262         783     4192965   83  Linux

Command (m for help): d
Partition number (1-4): 2

Command (m for help): p

Disk /dev/xvda: 9514 MB, 9514450944 bytes
255 heads, 63 sectors/track, 1156 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Device Boot      Start         End      Blocks   Id  System
/dev/xvda1   *           1         261     2096451   83  Linux

Command (m for help): n
Command action
e   extended
p   primary partition (1-4)
p
Partition number (1-4): 2
First cylinder (262-1156, default 262):
Using default value 262
Last cylinder or +size or +sizeM or +sizeK (262-1156, default 1156):
Using default value 1156

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

8. fsck and recreate the ext3 journals

[root@virtserver os]# e2fsck /dev/xvda2
e2fsck 1.39 (29-May-2006)
/: clean, 62190/1048576 files, 860683/1048241 blocks

[root@virtserver os]# tune2fs -j /dev/xvda2
tune2fs 1.39 (29-May-2006)
Creating journal inode: done
This filesystem will be automatically checked every -1 mounts or
0 days, whichever comes first.  Use tune2fs -c or -i to override.

[root@virtserver os]# tune2fs -j /dev/xvda1
tune2fs 1.39 (29-May-2006)
Creating journal inode: done
This filesystem will be automatically checked every -1 mounts or
0 days, whichever comes first.  Use tune2fs -c or -i to override.

9. Resize the filesystem

[root@virtserver os]# resize2fs -f /dev/xvda2
resize2fs 1.39 (29-May-2006)
Resizing the filesystem on /dev/xvda2 to 1797271 (4k) blocks.
The filesystem on /dev/xvda2 is now 1797271 blocks long.

10. detach the disk image and get on with your day with more space

[root@virtserver os]# xm block-detach 0 xvda


Google found JADDOG

August 7th, 2009

I was working on something for work that involved python and kerberos again. Very generic search looking for the docs I used last time I was implementing similar functionality. Something seemed familiar about the last result on the second page:

JaddogGoogle

I don’t feel so much like and island in nowhere land any more.


Experimenting with Railo

August 6th, 2009

Coldfusion was the first programming language that actually did something with. I haven’t been writing it too much latley (yay django) but I still have code written in coldfusion that is faithfully running. I love open source and saw a while back that railo was going open source and being shipped with jboss. Went to the Railo site recently and found that Railo 3.1 had in fact been released so I thought I’d give it a spin. Rail 3.1 is downloadable with a copy of resin. I’d not ever heard of resin, seems like a lighter-weight java app server kind like jboss. Hope that’s not too far off base from what it really is. So here’s my experience getting Railo 3.1 to run on CentOS 5.3.

When you first download you need to compile… Found a post that said to download the railo-resin-no-jre and get sun’s jre, of course after I tried it with the jre and couldn’t get mod_coucho to compile. So in the root of what I unpacked (this assumes that you’ve installed things to build with):

$ ./configure –with-java-home=/usr/java/jre1.6.0_15

Got a warning on java JNI not existing. Couldn’t figure it out quicly but I think this is just performance related. Skipping it for now as I don’t need the performance yet. After configuring I ran make and make install. Going to use apache, the main compile didn’t seem to compile the apache module so did that. (this is the piece that failed when I tried to use the included jre) Also copied it to apache’s modules dir.

$ cd modules/c/src/apache2/
$ make all
$ cp .libs/mod_caucho.so /etc/httpd/modules

Now configure apache to use railo. I use virtual hosts heavily so went ahead a configured a couple to test with.

/etc/httpd/conf.d/railo.conf

LoadModule caucho_module modules/mod_caucho.so
DirectoryIndex index.cfm index.php index.htm index.html index.html.var
ResinConfigServer localhost 6800
<VirtualHost *>
ServerName site1.local
</VirtualHost>
<VirtualHost *>
ServerName site2.local
</VirtualHost>
<Location /caucho-status>
SetHandler caucho-status
</Location>

The resin config file had defaults that would use virtual hosting if you just create the proper directory structure. This is done in the root of what was unpacked.

$ mkdir -p hosts/site1.local/webapps/ROOT
$ mkdir -p hosts/site2.local/webapps/ROOT

I also stuck an index.cfm file in each root directory for testing… just a cfoutput with #now()# in it and a site identifier. The hosts/${domainname}/webapps/ROOT structure I think is the standard directory resin expects to do the virtual hosting. Finally start resin.

$ bin/httpd.sh start

I’ve used all the defaults here. There’s some docs on the virtual hosting stuff here. My next step is to integrate it with my existing server setup to see if I can customize this to the point I’d consider replacing AdobeCF with RailoCF. I’ve already tested a simple app written in CF7 on it. No problems.


python + kerberos + apache GSSAPI Example

July 6th, 2009

I’m writing a kerberos enabled tool at work. The primary interface is the web ui which we will forward our kerberos tickets to apache and use gssapi to authenticate. The secondary interface is a cli that we use to push data into the server. In interest of kinit letting us login though the web ui or the cli without having to type our password again I wanted the cli to also be able to pass the nessesary headers to apache for a password-less authentication. I’m not the most experienced programmer at kerb implementations so I figured I’d just figure it out and learn how to do it. I found there was a distinct lack of tutorials on how to implement a kerberos client. So here’s my experience.

Pre-established kerberos infrastructure would include you being able to kinit and have firefox login to a kerberos enabled website using your ticket. If you have a valid service principal and you have a valid ticket make sure that firefox knows the domain is trusted. Visit about:config and set network.negotiate-auth.trusted-uris to the trusted domain you’re logging into. Don’t use a widecard. So use example.com, not *.example.com. For example sake I’ll use HTTP/myhost.example.com and myuser@EXAMPLE.COM as my principals.

From here I would recommend using python-kerberos. I was browsing the code of another kerberos enabled cli app today. It implemented krbV and I think the server side also did. I also think this was a custom implementation that did not match gssapi’s implementation. From here the code is quite simple using python-kerberos, here’s a quick little example using httplib.

import kerberos
import httplib

# setup kerb
_ignore, ctx = authGSSClientInit(‘HTTP@myhost.example.com’, gssflags=GSS_C_DELEG_FLAG|GSS_C_MUTUAL_FLAG|GSS_C_SEQUENCE_FLAG)
_ignore = authGSSClientStep(ctx, ”)
tgt = authGSSClientResponse(ctx)

# setup http connection
servername, port = (‘myhost.exmple.com’, 443)
h = httplib.HTTPSConnection(servername, port)
h.connect()

# Setup Headers
http_conn.putrequest(“GET”, “/XMLRPC/”)
if tgt:
h.putheader(‘Authorization’, ‘Negotiate %s’ % tgt)
h.endheaders()

# Make http call
resp = http_conn.getresponse()
if resp.status != 200:
print “Error: %s” % str(resp.status)
return None

#Check for kerb header
krb_reply = resp.getheader(‘WWW-Authenticate’)
if not krb_reply:
print “Server did not send kerberos reply”
return None

# print html contents
print resp.read()

There’s all kinds of validation and such missing here. This just worked so I figured I post it for reference. The _ignore variables get populated with a 1 or a 0. You can read more about those in the python-kerberos docs. There is another example in the python-kerberos package that is more in depth on using these properly and validating other things. I think my biggest problem ended up being the choice of syntax and flags to pass to authGSSClientInit. My next issue is that I’d like to pump this through xmlrpclib instead of httplib. Though, I think that there are some better examples out there on how to add the header to xmlrpclib. Hope this simple snip helps someone with getting a proof of concept runnning.


PyCon ’09

March 26th, 2009

It’s been over a month since I last posted. Lots has happened. Sickness, work, new baby on the way, training for the triathlon and God has been faithful through it all.

This week I’m in Chicago at PyCon ’09. I’ve been enjoying the conference and have a few new concepts to apply to my python programming.

I’m on the train to meet my family for dinner. Mmm Thai. Just wanted to through down a couple lines. I have been wanting to write a couple posts on things I’ve been learning. I finished Basic Christianity and have cross referenced Worship Matters with Authentic Christianity. I also started Why Small Groups by CJ Mahaney. It’s a book I’m reading with a Leadership Development group at church. All have a post associated with them.

I’m thankful for the desire the Lord has given me to read in the past few months and I pray the more consistent consumption of reading material continues.


Git :: fixing the commit date

February 20th, 2009

Earlier this year my laptop battery died. I had to remove it from my laptop to get my laptop to even boot. Through quite a fiasco I hope the battery is on the way and I’ll have it soon. I’ve been without for over a month now. In the mean time my system clock needs updating every time I boot. I guess the laptop needs the battery to keep the system time accurate when the machine is not running. For a while my machine would boot with the date as Feb 06 2009 10pm. Today it seems that my clock boots to Feb 17 2009 10pm. When I forget to run ntpdate to update my system clock all my git commit timestamps are wrong.

Today is the second time I’ve have to fix my dates so I’m blogging this fix so it’s easier to find when/if I ever need it again:

git filter-branch --env-filter \
    'if [ $GIT_COMMIT = 119f9ecf58069b265ab22f1f97d2b648faf932e0 ]
     then
         export GIT_AUTHOR_DATE="Fri Jan 2 21:38:53 2009 -0800"
         export GIT_COMMITTER_DATE="Sat May 19 01:01:01 2007 -0700"
     fi'

http://stackoverflow.com/questions/454734/how-can-one-change-the-timestamp-of-an-old-commit-in-git

I just thrown the above command into a little bash script and called it fix. If you run this more than once you’ll get an error:

$ ./fix
Namespace refs/original/ not empty

To fix the broken “fix” script just rm -rf the directory it’s refering to:

$ rm -rf .git/refs/original/*
$ ./fix
Rewrite 6b37ac946f9b2af3a0e66657038a1c4cafaeab89 (63/63)
Ref ‘refs/heads/master’ was rewritten

As I’m writing this I’m told my manager has tried to ping me in irc to tell me my new battery is in. I didn’t get the message because my client has disconnected for some reason. Now I will have a new battery, hopefully no system time problem and a new irc problem. Such is life.


The death of Christ

February 14th, 2009

I just finished chapter 7 in John Stott’s Basic Christianity. I can’t do a better job of depicting the meaning of Christ’s death on the cross than he’s done. This quote is from pages 117-118.

… “For our sake he made him to be sin who knew no sin, so that in him we might become the righteousness of God.” Jesus Christ had no sins of his own; he was made sin with our sins, on the cross.

As we look at the cross, we can begin to understand the terrible implications of these words. At twelve noon “there was darkness over the whole land” which continued for three hours until Jesus died. With the darkness came silence, for no eye should see, and no lips could tell, the agony of soul which the spotless Lamb of God now endured. The accumulated sins of all human history were laid upon him. Voluntarily he bore the in his own body. He made them his own. He shouldered full responsibility for them.

And then in desolate spiritual abandonment that cry was wrung from his lips, “My God, my God, why hast thou forsaken me?” It was a quotation from the first verse of Psalm 22. No doubt he had been meditating during his agony on its description of the sufferings and glory of the Christ. But why did he quote that verse? Why not one of the triumphant verses at the end? Why not, “You who fear the Lord, praise Him!” or “Dominion belongs to the Lord”? Are we to believe that it was a cry of human weakness and despair, or that the Son of God was imagining things?

No. These words must be taken at their face value. He quoted this verse of Scripture, as he quoted all others, because he believed he himself was fulfilling it. He was bearing our sins. And God who is “of purer eyes than to behold evil” and cannot “look on wrong” turned away his face. Our sins came between the Father and the Son. The Lord Jesus Christ who was eternally with the Father, who enjoyed unbroken communion with him throughout his life on earth, was thus momentarily abandoned. Our sins sent Christ to hell. He tasted the torment of a soul estranged from God. Bearing our sins, he died our death. He endured instead of us the penalty of separation from God which our sins deserved.

Then at once, emerging from that outer darkness, he cried in triumph, “It is finished,” and finally, “Father, into thy hands I commit my spirit.” And so he died. The work he had come to do was completed. The salvation he had come to win was accomplished. The sins of the world were borne. Reconciliation to God was available to all who would trust this Savior for themselves, and receive him as their own. Immediately, as if to demonstrate this truth publicly, the unseen hand of God tore down the curtain of the temple and hurled it aside. It was needed no longer. The way into God’s holy presence was no longer barred. Christ had “opened the gate of heaven to all believers.” And thirty-six hours later he was raised from death, to prove that he had not died in vain.


Gran Torino

February 7th, 2009

Tonight a couple of buddies of mine and I saw the new Clint Eastwood movie. Not at all what I expected. The movie had a religious flavor to the underlying story. While there was absolutely no accurate depiction of salvation, there was a strangely touching sacrificial message delivered. Stop reading here if you don’t want the end of the movie ruined. The movie ends with Eastwood’s character, Walt, being shot an excessive amount of times by a gang. This brutal murder is witnessed by many people and has the gang arrested to be locked up for a long time. One of the gang members cousins lived next door to Walt and through out the movie is befriended by Walt, not really intentionally.

I don’t think that the movie was trying to depict the sacrificial death that Christ dies for the sake of believers. Though, the movie does a  fairly good job of it. Christ died for sinners, of whom he owed nothing to. He died that they would be freed from the wrath they deserved for their sins. Walt dies for his next door neighbours, of whom he owed nothing to. He dies that they would be freed from the pain and suffering the gang was inflicting on the family. A fairly important difference is that this family did not necessarily deserve to be mistreated by the gang. Sinners deserve eternal  death.

I’ll admit the parallel isn’t perfect. Though, it was and unexpected ending to an unexpected story. An ending that reminded me of and unexpected sacrifice that Christ made. A sacrifice that those who  believe and follow will live eternally with Christ.


Victory and Defeat

February 3rd, 2009

Tonight, in a marriage class my wife and I are taking, one of the pastors of our church said a quote worthy line:

In the Christian life we experience moments of victory and seasons of defeat.

- Daniel Baker

I feel I’m in one of those moments of victory, as I’m about to complete reading a book in its entirety. The first in quite some time. I’ve picked up, read a couple chapters and put down a number of books over the past season of defeat. I pray this moment of victory would turn into a life long passion. I’ve always struggled to desire to read, anything. What better reason to put that weakness to rest than seeking to be more like Christ.