Monday, December 01, 2008
Auto mounting an sshfs volume at login on OS X Leopard 10.5.5 using MacFuse
If you maintain a remote machine, it can be really useful to mount that machine's filesystem locally to move files around. MacFuse and sshfs make this really easy, although getting it set up and mounted automatically at login can be a bit tricky.
Basically, this file sets SSH_AUTH_SOCK to the most recent socket in your tmp directory. In most cases, this should be the proper one. It's unlikely to fail, and there's no security issue if it does.
If you see no error messages, see if the volume was mounted properly:
If your remote files show up, then great! You're done!
If not, use "launchctl unload ~/Library/LaunchAgents/BACKWARDS_HOST_DNS.PATH.sshfs" to unload the file before making edits to it, then use "ps auxwww | grep sshfs" and "kill" to find and kill any sshfs processes before trying again.
Hope this helps.
References
First, make sure you can ssh to your remote machine without entering a password. Do the setup in http://ormset.no/wordpress/2007/10/28/leopard-finally-supporting-ssh-agent-at-login/ and verify that it works:
ssh USER@HOSTNAME:
If it logged you in without prompting for a password or passkey, you're ready to proceed.
Next, install sshfs and MacFuse as per http://emmby.blogspot.com/2008/12/installing-sshfs-19-with-macfuse-17-on.html
Figure out where you want to mount your remote volume. I wouldn't recommend using /Volumes since it appears that OS X automatically deletes directories in there when you unmount things. So instead I used /mnt/HOSTNAME
mkdir -p /mnt/HOSTNAME
(Obviously, you'll replace HOSTNAME with whatever your remote server's name is)
Then make sure you can mount your remote site as a volume without specifying a password using sshfs:
sshfs USER@HOSTNAME:PATH /mnt/HOSTNAME -oreconnect,allow_other,volname=VOLUME_NAME
Set VOLUME_NAME to whatever you want your volume to be named in the Finder. I used HOSTNAME. PATH is optional, set it to whichever directory you want to mount on the remote host. If it's not set, it'll use your home directory.
If you get no error messages and when you do an "ls /mnt/HOSTNAME" the remote files show up, then you're ready to proceed to the next step.
Unmount the volume you just mounted:
umount /mnt/HOSTNAME
Now comes the tricky party. You'll need to create a LaunchAgent item to mount your volume at login. This in itself is pretty easy. However, if your system is anything like mine, this item won't have its SSH_AUTH_SOCK set properly so it won't be able to login to the remote host without using a password. You'll have to manually set the SSH_AUTH_SOCK yourself.
First, create a wrapper around sshfs that will set the SSH_AUTH_SOCK for you. Put this in a file wherever you want, I suggest /opt/local/bin/sshfs-authsock
#!/bin/bash
export SSH_AUTH_SOCK=$( ls -t /tmp/launch-*/Listeners | head -1)
/opt/local/bin/sshfs $*
Now you can finally create the launchd plist file. Put this in ~/Library/LaunchAgents/BACKWARDS_HOST_DNS.PATH.sshfs.plist
(if your host's path is, say, foo.niskala.org and your PATH was /tmp, then your resulting filename would be org.niskala.foo.tmp.sshfs.plist. This is just a convention, feel free to name the file whatever you want really, but it does need to end in .plist)
(if your host's path is, say, foo.niskala.org and your PATH was /tmp, then your resulting filename would be org.niskala.foo.tmp.sshfs.plist. This is just a convention, feel free to name the file whatever you want really, but it does need to end in .plist)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>BACKWARDS_HOST_DNS.PATH.sshfs</string>
<key>ProgramArguments</key>
<array>
<string>/opt/local/bin/sshfs-authsock</string>
<string>USER@HOSTNAME:</string>
<string>/mnt/HOSTNAME</string>
<string>-oreconnect,allow_other,volname=VOLUME_NAME</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
Now load the plist file and run it to see if it works.
launchctl load ~/Library/LaunchAgents/BACKWARDS_HOST_DNS.PATH.sshfs
launchctl start BACKWARDS_HOST_DNS.PATH.sshfs
If you see no error messages, see if the volume was mounted properly:
ls /mnt/HOSTNAME
If your remote files show up, then great! You're done!
If not, use "launchctl unload ~/Library/LaunchAgents/BACKWARDS_HOST_DNS.PATH.sshfs" to unload the file before making edits to it, then use "ps auxwww | grep sshfs" and "kill" to find and kill any sshfs processes before trying again.
Hope this helps.
References
Installing sshfs 1.9 with MacFuse 1.7 on OS X Leopard 10.5.5
Just a quick post today about getting sshfs up and running with MacFuse on Leopard 10.5.5.
The easiest way I found was to use MacPorts, supplemented by the Google MacFuse package. In other words, install them both.
First install sshfs (assuming you have MacPorts):
sudo port install sshfs
This will automatically install the MacFuse dependency. However, for whatever reason this version of MacFuse does not work out of the box when you try to run sshfs. To make it work properly, download the MacFuse installer from http://code.google.com/p/macfuse/ and install it over the MacFuse you just installed. No, really. It all installs to the same place so you won't end up with two copies.
You may need to reboot, but once you do you'll be able to run sshfs as per http://code.google.com/p/macfuse/wiki/MACFUSE_FS_SSHFS
References
Thursday, July 17, 2008
Tropologs and Rotasmagrams
Some friends and I were discussing words today that look the same when rotated 180 degrees, which we've dubbed Rotasmagrams (or Tropologs, depending on whichever tickles your fancy more).
We successfully came up with "pod" and "suns". And then we wrote a script to generate the rest:
Reading in /usr/share/dict/words
Generating stems
Computing valid tropologs
unsun
un
suns
sooloos
pod
nu
dop
dollop
SIS
OHO
NOON
NON
MOW
IHI
I
Note that there is some controversy over the use of the lowercase letter 'l', which will tend to droop a bit when rotated. Also, it's clear that /usr/share/dict/words has some pretty unwordy words in it ("sooloos?").
#!/usr/bin/env python
DICT_FILE='/usr/share/dict/words'
TROPOLOGS = { 'b':'q', 'd':'p', 'n':'u', 'q':'b', 'p':'d', 'u':'n', 'o':'o', 's':'s', 'z':'z', 'l':'l',
'H':'H', 'I':'I', 'N':'N', 'O':'O', 'S':'S', 'X':'X', 'Z':'Z', 'M':'W' }
def potential_words(word):
words = [];
for i in TROPOLOGS.keys():
new_word = i + word + TROPOLOGS[i]
if new_word.lower() in VALID_STEMS:
words += [ new_word ] + potential_words(new_word)
return words
def mysort(l):
l.sort() # I hate that python's builtin sort doesn't return the list
l.reverse()
return l
print "Reading in " + DICT_FILE # dict file is mysteriously missing 'suns'
VALID_WORDS = [ word.lower() for word in open(DICT_FILE).read().splitlines() ] + ['suns']
print "Generating stems"
VALID_STEMS = {}
for word in VALID_WORDS:
for i in range(0, len(word)+1):
for j in range(i+1, len(word)+1):
VALID_STEMS[word[i:j]] = True
print "Computing valid tropologs"
potentials = ['I']
for word in [''] + [ x for x in TROPOLOGS.keys() if x==TROPOLOGS[x] ]:
potentials += potential_words(word)
# Strip out duplicates with different capitalization
tmp={}
for word in mysort([ word for word in potentials if word.lower() in VALID_WORDS and ( word == word.lower() or word == word.upper() ) ]):
if not word.lower() in tmp.keys(): print word
tmp[word.lower()] = word
Friday, June 06, 2008
Configuring Postfix to relay email through your Gmail account on OS X Leopard
Configure Postfix to launch at startup on OS X Leopard describes how to launch postfix at startup. But many ISPs block the SMTP port 25 for at least some hosts in an effort to prevent spam from originating from their network. This may prevent your postfix server from successfully delivering mail to some or all email addresses.
Since the file and its hash will have your password, make sure they're readable only by the root user:
Next, you will need to grab the Thawte Premium root certificates from https://www.verisign.com/support/roots.html. Don't let your browser unzip these when you download them, you'll unzip them in the next step.
If you have a Google Mail account, you can easily configure postfix to relay your email through Gmail. Many thanks to Installation Experiences (see the References below) who provided all the instructions how to do this.
First, "sudo vi /etc/postfix/relay_password" and insert the following content:
smtp.googlemail.com youremail@gmail.com:yourpassword
smtp.gmail.com youremail@googlehosteddomain.com:yourpassword
Now use postmap to hash the file:
sudo postmap /etc/postfix/relay_password
sudo chmod 600 /etc/postfix/relay_password
sudo chmod 600 /etc/postfix/relay_password.db
sudo mkdir /etc/postfix/certs
cd /etc/postfix/certs
sudo unzip -j roots.zip
sudo openssl x509 -inform der -in ThawtePremiumServerCA.cer -out
ThawtePremiumServerCA.pem
sudo c_rehash /etc/postfix/certs
Now configure postfix by adding the following to the bottom of /etc/postfix/main.cf:
relayhost = smtp.googlemail.com:587
# auth
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/relay_password
smtp_sasl_security_options = noanonymous
# tls
smtp_tls_security_level = may
smtp_tls_CApath = /etc/postfix/certs
smtp_tls_session_cache_database = btree:/etc/postfix/smtp_scache
smtp_tls_session_cache_timeout = 3600s
smtp_tls_loglevel = 1
tls_random_source = dev:/dev/urandom
That should be it, just run a quick test by sending mail to yourself using "/usr/bin/mail ". You can watch the maillog from Console.app (in Applications/Utilities)
References
- http://www.installationexperiences.com/?p=87 has great instructions on how to do this, although there were a few bugs in the original post which haven't been corrected as of this writing.
Configure Postfix to launch at startup on OS X Leopard
Mac OS X Leopard comes with the Postfix SMTP server built-in. You can easily turn it on or off using "sudo postfix start" or "sudo postfix stop".
After you do, verify that it's running by doing a "telnet localhost 25" and checking that you get a response from Postfix. I verified these instructions on OS X 10.5.3, but it should be the same for all Leopard variants.
If you'd like the postfix server to always run at startup, simply do the following:
sudo launchctl load -w /System/Library/LaunchDaemons/org.postfix.master.plist
After you do, verify that it's running by doing a "telnet localhost 25" and checking that you get a response from Postfix. I verified these instructions on OS X 10.5.3, but it should be the same for all Leopard variants.
References
- "man launchctl" from the terminal
- http://diymacserver.com/installing-the-mailserver/the-basic-mailserver-on-leopard/starting-your-basic-mailserver-on-leopard/
Tuesday, May 13, 2008
Installing Python PIL on Mac OS X 10.5.2 Leopard
For some reason, the easy_install of python's PIL 1.1.6 imaging library didn't work for me or my coworkers when using Django.
After much trial-and-error using the various builds out there, the solution I found that works best for me was to use the one that comes with MacPorts.
After installing MacPorts, do the following:
Once the installation is complete, you'll need to supplement your PYTHONPATH with the location of the python libraries that macport uses. In your /etc/profile or ~/.profile, add the following line:
That should be it! Works like a charm for me. Note that these instructions are for python 2.5. If you want python 2.4, you can probably install the py-pil package instead (although I haven't tried this myself)
Resources
After much trial-and-error using the various builds out there, the solution I found that works best for me was to use the one that comes with MacPorts.
After installing MacPorts, do the following:
sudo /opt/local/bin/port install py25-pil
Once the installation is complete, you'll need to supplement your PYTHONPATH with the location of the python libraries that macport uses. In your /etc/profile or ~/.profile, add the following line:
export PYTHONPATH=/opt/local/lib/python2.5/site-packages
That should be it! Works like a charm for me. Note that these instructions are for python 2.5. If you want python 2.4, you can probably install the py-pil package instead (although I haven't tried this myself)
Resources
- http://www.martin-geber.com/weblog/2007/08/22/problems-installing-easy_install-pil/: Installation succeeded, but for some reason Django still couldn't find the PIL library.
- http://effbot.org/zone/pil-index.htm: In addition to installing the PIL dmg, you also have to install their python2.5 dmg, which I wasn't keen to do.
- http://paul.annesley.cc/articles/2007/11/19/django-and-python-imaging-library-pil-on-leopard: If you like building from source, this solution may work for you. I prefer using packages since it makes deinstallation easier.
- http://py25-pil.darwinports.com/
- http://py-pil.darwinports.com/
Wednesday, May 07, 2008
Using Cruise Control with Django
I wanted to set up a Continuous Integration server for our project, and after doing a quick tour of the available options I settled on Cruise Control as one of the better options, even though it doesn't have any python-specific features.
We use mercurial as our source control system, so this example uses mercurial, but resources abound for configuring cruise-control with CVS and SVN if you're using one of those SCCS systems.
- Download and install Cruise Control as per http://cruisecontrol.sourceforge.net/gettingstartedsourcedist.html. I used the binary distribution, the latest being 2.7.2 as of this writing.
- Creating and populate a work directory as per the Running the Build Loop instructions. They make the sensible recommendation to keep your working directory separate from your Cruise Control installation directory. Mine is called "work":
mkdir -p work/checkout work/logs work/artifacts
- Check out your project under work/checkout.
- DO NOT bother creating a delegating build script as per the Running the Build Loop instructions. This is only used if you're using Ant to control your build.
- In your work directory, create config.xml, replacing MY_PROJECT_1 with your django root directory. The following configuration will run "python manage.py test" whenever there are new changes to pull from your mercurial repository.
<cruisecontrol>
<project name="MY_PROJECT_1" buildafterfailed="true">
<listeners>
<currentbuildstatuslistener file="logs/MY_PROJECT_1/status.txt">
</currentbuildstatuslistener>
</listeners>
<!-- Bootstrappers are run every time the build runs, *before* the modification checks -->
<bootstrappers>
<mercurialbootstrapper localworkingcopy="checkout/MY_PROJECT_1">
</mercurialbootstrapper>
</bootstrappers>
<!-- Defines where cruise looks for changes, to decide whether to run the build -->
<modificationset quietperiod="10">
<mercurial localworkingcopy="checkout/MY_PROJECT_1">
</mercurial>
</modificationset>
<!-- Configures the actual build loop, how often and which build file/target -->
<schedule interval="60">
<exec workingdir="checkout/MY_PROJECT_1" command="python" args="manage.py test">
</exec>
</schedule>
<!-- directory to write build logs to -->
<log logdir="logs/MY_PROJECT_1">
<!-- Publishers are run *after* a build completes -->
<publishers>
</publishers>
</log>
</project>
</cruisecontrol> - If you're using mercurial, mercurialbootstrapper won't allow you to specify a username or password for hg pull, so edit the .hg/hgrc in your checked out directory to add authentication to your url. Note that this means your password is stored in plain text on your local machine and will be exposed when doing pulls across the network.
[paths]
default = https://username:password@host/path - Optionally copy dashboard-config.xml from the Cruise Control install directory into your work directory. This'll allow you to view the dashboard at http://yourhost:yourport/dashboard. It's pretty nice, I recommend it.
- Start up your server FROM YOUR WORK DIRECTORY.
cd work
<cruise-control-install-dir>/cruisecontrol.sh
If everything went according to plan, you should now be able to view your builds at http://localhost:8080/dashboard.
Currently, Cruise Control doesn't seem to recognize the django test output format, so it won't show individual testcases. However, if your tests pass the build will succeed, and if your test fail the build will fail.
Resources
Wednesday, April 23, 2008
X11 and Spaces on Mac OS X 10.5.2 Leopard
If you're having difficulties running X11 applications with Spaces.app, you may want to try upgrading to the latest X11.app offered by the XQuartz community. In particular, I was having a problem where my Wing IDE (an X11 app) would "steal" the focus and jump to the X11 space at random moments while I was working in other applications. No more!
Apple basically ships XQuartz's X11 as their own official X11.app, and the one included in 10.5.2 is "somewhere between the 2.1.1 and 2.1.2", whereas the XQuartz version is now up to 2.2.0.1 as of this writing.
Note that, as per the installation instructions, you may need to logout after upgrading.
Apple basically ships XQuartz's X11 as their own official X11.app, and the one included in 10.5.2 is "somewhere between the 2.1.1 and 2.1.2", whereas the XQuartz version is now up to 2.2.0.1 as of this writing.
Note that, as per the installation instructions, you may need to logout after upgrading.
Tuesday, April 22, 2008
How to set up multiple mysql instances on Mac OS X 10.5 Leopard
Turns out that it's fairly simple, really. The basic idea is that you edit your /etc/my.cnf to switch to using the MySQL Instance Manager and then to set up a second instance using a different socket, port, and data directory.
The following steps assume that you've got a standard MySQL 5.1.x for Mac OS X installation. In other words, you probably installed the mysql-*.pkg and the MySQLStartupItem.pkg from the dmg available on the MySQL website.
If everything went according to plan, you should now have two mysql instances that are each accessible on their own socket or port.
Here's my complete my.cnf file for my two instances:
References
1. http://dev.mysql.com/doc/refman/5.0/en/instance-manager-startup-process.html
The following steps assume that you've got a standard MySQL 5.1.x for Mac OS X installation. In other words, you probably installed the mysql-*.pkg and the MySQLStartupItem.pkg from the dmg available on the MySQL website.
- Verify everything is working in your existing instance, however you want to do it. For me, I do a quick check by doing:
echo "show databases" | mysql -u root -p
- Stop your mysql server (sudo /Library/StartupItems/MySQLCOM/MySQLCOM stop) then, switch to using MySQL's instance manager by adding the following two lines to the top of your /etc/my.cnf:
[mysql.server]
use-manager - Start your mysql server (... MySQLCOM start), then verify everything is working and that you can still connect to your databases.
- Stop the server again, then add a second instance to my.cnf, being sure to set socket, port, and datadir. You can pick whatever you want, as long as it's not the values used by your other instance (which default to 3306, /tmp/mysql.sock, and /usr/local/mysql/data, respectively):
[mysqld2]
socket=/tmp/mysql.sock2
port=3307
datadir=/usr/local/mysql/data2 - Set up the second data directory. If you already have one then you can skip this step. Otherwise, make sure you specify the same user that owns your /usr/local/mysql/data dir when creating your second data directory ( _mysql in my case, and probably in yours)
cd /usr/local/mysql
sudo scripts/mysql_install_db --user=_mysql --datadir=/usr/local/mysql/data2 - Start it up (... MySQLCOM start) and test it out!
echo "show databases" | mysql -u root -p
echo "show databases" | mysql --sock=/tmp/mysql.sock2
If everything went according to plan, you should now have two mysql instances that are each accessible on their own socket or port.
Here's my complete my.cnf file for my two instances:
[mysql.server]
use-manager
[mysqld]
[mysqld2]
socket=/tmp/mysql.sock2
port=3307
datadir=/usr/local/mysql/data2
References
1. http://dev.mysql.com/doc/refman/5.0/en/instance-manager-startup-process.html
Wednesday, December 27, 2006
Mac - Sprint RAZR with iSync and DUN
The Sprint RAZR v3m is a great phone, but it's not officially supported by Apple's bluetooth software yet. This means that it won't work with iSync (to sync contacts, calendar entries, etc), nor will it work for Dial-up Networking (DUN) with Sprint.
After much failed experimentation I was able to get my RAZR to work with both iSync and DUN. Note that to use DUN you must pay Sprint the appropriate monthly fee. DUN won't work if you don't have this feature enabled for your Sprint account, but you can still use iSync regardless.
Before you begin
Add the following block of XML to the file after the first <dict> tag (on line 5 in my file, your mileage may vary)
<!-- from http://emmby.blogspot.com/ -->
<key>com.motorola.razorV3m</key>
<dict>
<key>Identification</key>
<dict>
<key>com.apple.gmi+gmm</key>
<array>
<string>Motorola CE, Copyright 2000+Motorola V3m-Sprint Phone</string>
</array>
</dict>
<key>InheritsFrom</key>
<array>
<string>com.motorola.usb-bt.0x22B8/0x4902</string>
</array>
<key>Services</key>
<array>
<dict>
<key>ServiceName</key>
<string>com.apple.model</string>
<key>ServiceProperties</key>
<dict>
<key>ModelIcon</key>
<string>MOTV3-black.tiff</string>
<key>ModelName</key>
<string>NC-V3m</string>
</dict>
</dict>
<dict>
<key>ServiceName</key>
<string>com.apple.synchro</string>
<key>ServiceProperties</key>
<dict>
<key>OnlySupportASCIIChar</key>
<true/>
<key>deleteContactBeforeModifying</key>
<true/>
<key>stringEncoding</key>
<string>UCS2</string>
</dict>
</dict>
</array>
</dict>
<key>com.motorola.usb-bt.0x22B8/0x2A64</key>
<dict>
<key>Identification</key>
<dict>
<key>com.apple.usb.vendorid-modelid</key>
<string>0x22B8/0x2A64</string>
</dict>
<key>InheritsFrom</key>
<array>
<string>family.com.motorola.p2k.usb-bt</string>
</array>
<key>Services</key>
<array/>
</dict>
At this point I highly recommend rebooting your computer.
After the restart you should be able to pair your RAZR to your Mac and both iSync and DUN should show up in the list of available services. Pairing your bluetooth phone to your Mac is outside of the scope of this doc, but check Google or the references below for instructions.
Many thanks to vibesaw at whopack for finding the correct entry to use.
References
After much failed experimentation I was able to get my RAZR to work with both iSync and DUN. Note that to use DUN you must pay Sprint the appropriate monthly fee. DUN won't work if you don't have this feature enabled for your Sprint account, but you can still use iSync regardless.
Before you begin
- Update to the latest version of iSync. As of this writing it's version iSync 2.3 500.8.
- Update your RAZR's firmware. Go to Settings -> Phone Info -> Update Phone SW. As of this writing the latest is 24.2_00.37.00R
Add the following block of XML to the file after the first <dict> tag (on line 5 in my file, your mileage may vary)
<!-- from http://emmby.blogspot.com/ -->
<key>com.motorola.razorV3m</key>
<dict>
<key>Identification</key>
<dict>
<key>com.apple.gmi+gmm</key>
<array>
<string>Motorola CE, Copyright 2000+Motorola V3m-Sprint Phone</string>
</array>
</dict>
<key>InheritsFrom</key>
<array>
<string>com.motorola.usb-bt.0x22B8/0x4902</string>
</array>
<key>Services</key>
<array>
<dict>
<key>ServiceName</key>
<string>com.apple.model</string>
<key>ServiceProperties</key>
<dict>
<key>ModelIcon</key>
<string>MOTV3-black.tiff</string>
<key>ModelName</key>
<string>NC-V3m</string>
</dict>
</dict>
<dict>
<key>ServiceName</key>
<string>com.apple.synchro</string>
<key>ServiceProperties</key>
<dict>
<key>OnlySupportASCIIChar</key>
<true/>
<key>deleteContactBeforeModifying</key>
<true/>
<key>stringEncoding</key>
<string>UCS2</string>
</dict>
</dict>
</array>
</dict>
<key>com.motorola.usb-bt.0x22B8/0x2A64</key>
<dict>
<key>Identification</key>
<dict>
<key>com.apple.usb.vendorid-modelid</key>
<string>0x22B8/0x2A64</string>
</dict>
<key>InheritsFrom</key>
<array>
<string>family.com.motorola.p2k.usb-bt</string>
</array>
<key>Services</key>
<array/>
</dict>
At this point I highly recommend rebooting your computer.
After the restart you should be able to pair your RAZR to your Mac and both iSync and DUN should show up in the list of available services. Pairing your bluetooth phone to your Mac is outside of the scope of this doc, but check Google or the references below for instructions.
Many thanks to vibesaw at whopack for finding the correct entry to use.
References