<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:wfw="http://wellformedweb.org/CommentAPI/"
     >
  <channel>
    <title>Let’s Discuss the Matter Further</title>
    <link>http://rhodesmill.org/brandon</link>
    <description>Your Blog's short description</description>
    <pubDate>Thu, 19 Jan 2012 00:48:19 GMT</pubDate>
    <generator>Blogofile</generator>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Mounting Windows shares in Linux userspace</title>
      <link>http://rhodesmill.org/brandon/2010/mounting-windows-shares-in-linux-userspace/</link>
      <pubDate>Wed, 09 Jun 2010 17:33:30 EDT</pubDate>
      <category><![CDATA[emacs]]></category>
      <category><![CDATA[computing]]></category>
      <guid>http://rhodesmill.org/brandon/?p=341</guid>
      <description>Mounting Windows shares in Linux userspace</description>
      <content:encoded><![CDATA[
<p>
  A current project has forced me into the clunky world of Windows,
  to verify that a Python program compiles and runs there
  just like it runs under Linux.
  Instead of trying to port my entire development environment to Windows —
  which includes two decades of customizations
  and a small empire of tools like
  <a href="http://www.gnu.org/software/emacs/"
     >Emacs</a>,
  <a href="http://pypi.python.org/pypi/pyflakes"
     >pyflakes</a>, and
  <a href="http://rope.sourceforge.net/"
     >Rope</a> —
  I want to simply mount my Windows home directory under Linux
  so that I can run my normal editor and version control tools
  in a more familiar environment.
</p>
<p>
  I have worked out an elegant solution
  by combining <i>two</i> of the powerful user-space filesystems
  available through the <a href="http://fuse.sourceforge.net/">FUSE</a>
  mechanism in the Linux kernel.
  Let me take you through the story of how I put them together!
</p>
<!--more-->
<p>
  Mounting and unmounting a "cifs" mount point —
  the most basic and low-level way of mounting a Windows share
  under the Linux filesystem —
  unfortunately requires root privileges under Ubuntu,
  even if one is careful to specify the "user" option
  in <tt>/etc/fstab</tt> when creating the share.
  The only way, therefore, for all users
  to be given CIFS mounting superpowers
  is through a manual intervention like:
</p>

<div class="pygments_murphy syntax_highlight"><pre><span class="c"># Even with the &quot;user&quot; option in fstab, user</span><br/><span class="c"># mounting of CIFS shares under Ubuntu require:</span><br/><br/>chmod u+s /sbin/mount.cifs<br/>chmod u+s /sbin/umount.cifs<br/></pre></div>


<p>
  But I want a safe solution,
  that requires neither root permissions
  nor any editing of the master <tt>fstab</tt>
  each time the details about a particular Windows share change.
  Plus, the error messages from the system mounting logic
  are a bit cryptic for my taste!
  Can you guess the meaning of the following error message,
  which was deposited unceremoniously into my <tt>syslog</tt> file?
</p>
<pre>
CIFS VFS: cifs_mount failed w/return code = -22
</pre>
<p>
  It means that I forgot to install
  the <tt>smbfs</tt> Ubuntu package before attempting the mount.
  I should have guessed.
</p>
<p>
  So I turned my attention to userspace filesystems,
  those wonderful inventions that let normal users
  create and delete mount points under their home directories.
  Linux keeps the scheme secure
  by imposing a few reasonable restrictions
  on the owners and modes of the files inside the filesystem,
  so that users cannot elevate their privileges
  through indiscretions like SUID binaries.
  For years, as an example,
  I have been using the userspace <tt>sshfs</tt>
  to make remote source trees visible to my editor here on my laptop,
  and now I just needed to do the same magic for a Windows filesystem.
</p>
<p>
  My first Google searches on the subject
  lead me to old pages mentioning something called <tt>fusesmb</tt>,
  which, it turns out, is still available as an Ubuntu package.
  But after several frustrating attempts
  resulted only in empty mount points,
  I did further some investigation and discovered
  that a new project named <tt>smbnetfs</tt>
  is now carrying the torch
  and maintaining compatibility with the most recent kernel versions.
  It also is available as an Ubuntu package,
  so I installed it and was immediately up and running!
</p>

<div class="pygments_murphy syntax_highlight"><pre><span class="nv">$ </span>mkdir ~/win<br/><span class="nv">$ </span>smbnetfs ~/win<br/><span class="nv">$ </span>ls ~/win<br/>ALAN/   KB/    TOSH/<br/>IRMA/   SAM/   W2K/<br/>KAREN/  TEST/<br/></pre></div>


<p>
  As you can see, this filesystem is far more dynamic
  than a single-share CIFS mount point:
  it makes your entire Network Neighborhood visible,
  and lets you browse both workgroups and individual machines
  by simply visiting the directories beneath it!
</p>
<p>
  The virtual Windows machine that contains my development environment
  is not actually visible to the master browser
  that generated the listing shown above,
  but that is okay: we can list any machine's shares,
  whether it appears in the directory listing or not,
  by simply naming it and seeing what happens:
</p>

<div class="pygments_murphy syntax_highlight"><pre><span class="nv">$ </span>ls ~/win/BRANDON-PC<br/>Brandon/  Python26/  project/<br/></pre></div>


<p>
  There!
  We can see both of the shares that my virtual machine makes available,
  and can start editing files with equal ease:
</p>

<div class="pygments_murphy syntax_highlight"><pre><span class="nv">$ </span><span class="nb">cd</span> ~/win/BRANDON-PC/project/src<br/><span class="nv">$ </span>svn st<br/>?       trace.out<br/>M       setup.py<br/><span class="nv">$ </span>svn up<br/>At revision 3677.<br/><span class="nv">$ </span>emacs setup.py<br/></pre></div>


<p>
  After a minute of work in my new playground, however,
  I was stymied when Emacs suddenly ground to a halt —
  then, after a minute, continued running again.
  By judiciously running <tt>strace</tt> against the editor
  during these morbid pauses,
  I discovered the problem.
  The Emacs version control logic
  often climbs up the directory tree from the current file,
  looking for version control directories
  that might provide context to the current buffer.
  This usually happens so fast that, actually,
  I had never known that Emacs was performing this check —
  after all, how much time can it take
  to quickly verify whether a containing directory contains
  an <tt>.svn</tt>, <tt>.git</tt>, or <tt>{arch}/=tagging-method</tt> file?
</p>
<p>
  Well, it turns out that it can take quite some time,
  when one of the containing directories
  is a virtual filesystem that scans the network for Windows machines
  each time an unknown filename is accessed!
  Take a look at how long two sample file accesses take
  when invoked from the command line:
</p>

<div class="pygments_murphy syntax_highlight"><pre><span class="c"># Looking for a machine named &quot;.git&quot;: 20 seconds!</span><br/><br/><span class="nv">$ </span><span class="nb">time </span>ls win/.git<br/>ls: cannot open directory ...: Input/output error<br/>... 20.701 total<br/><br/><span class="c"># Looking for a share named &quot;.git&quot;: &gt;1 second</span><br/><br/><span class="nv">$ </span><span class="nb">time </span>ls win/BRANDON-PC/.git<br/>ls: cannot open directory ...: No such file or directory<br/>... 1.227 total<br/></pre></div>


<p>
  I probably wasted a half hour
  playing with the Emacs setting <tt>vc-ignore-dir-regexp</tt>
  in a vain attempt to explain to my editor
  that the <tt>~/win</tt> directory was not an appropriate place
  to search for version control files
  but, despite my considerable talent with Emacs regular expressions,
  I could never get the setting to have any effect.
  And, anyway, I soon noticed that other Emacs mechanisms
  were also filesystem recursive —
  such as the search for <tt>.dir-locals.el</tt> files
  that is now a feature of Emacs 23 —
  and I determined that trying to subvert them all
  would be a long and losing battle.
</p>
<p>
  I toyed with the idea of tackling the problem from the other end,
  because <tt>smbnetfs</tt> supports a “workaround depth” setting
  in its configuration file
  by which you can protect its top few directory levels
  from user agents that check for special file names.
  Unfortunately, though, this list of files is hard-coded in the binary,
  and includes only one of the many version control directories
  for which Emacs searches
  (because it is only trying to protect Konqueror and Gnome Terminal
  from hanging, and they search for only three particular files).
</p>
<p>
  Having failed to solve the problem from either direction,
  I saw clearly that the only way out
  was to hide the <tt>~/win</tt> directory from Emacs altogether.
  My first experiment, which failed, was to create a symlink
  and then ask Emacs to edit files under the link instead:
</p>

<div class="pygments_murphy syntax_highlight"><pre><span class="c"># Does not actually fix the problem</span><br/><br/><span class="nv">$ </span>ln -s win/BRANDON-PC/project/src ~/winsrc<br/><span class="nv">$ </span><span class="nb">cd</span> ~/winsrc<br/><span class="nv">$ </span>emacs setup.py<br/></pre></div>


<p>
  Unfortunately,
  Emacs is not so easily fooled.
  To help programmers avoid all of the problems
  that arise when you try to edit the same file
  under several different pathnames,
  Emacs always resolves any symlinks in a file's path
  during the process of opening it —
  so that I found myself, in Emacs, editing the <tt>setup.py</tt> file
  deep inside of the <tt>~/win</tt> directory anyway.
  So I removed the symlink and took a different approach.
</p>
<p>
  The user filesystem toolbox has a feature
  that addresses exactly this case —
  where you need a given directory
  to appear somewhere else on your filesystem.
  This kind of mount is called a <i>bind</i>
  because it simply creates another name for an already-mounted file,
  rather than connecting to a new share or block device.
  And it is supported by a FUSE-powered <tt>bindfs</tt> command
  which, as usual, has already been packaged by the Ubuntu folks!
  Here is what it looks like in action:
</p>

<div class="pygments_murphy syntax_highlight"><pre><span class="nv">$ </span>mkdir ~/winsrc<br/><span class="nv">$ </span>bindfs ~/win/BRANDON-PC/project/src ~/winsrc<br/><span class="nv">$ </span><span class="nb">cd</span> ~/winsrc<br/><span class="nv">$ </span>svn up<br/>At revision 3677.<br/><span class="nv">$ </span>emacs setup.py<br/></pre></div>


<p>
  Success!
  Emacs now behaves normally,
  my editing operations finish quickly,
  and the editor's version control features
  can be invoked and run without hanging.
  All thanks to a simple user-mode command
  that lets me mount a directory from inside of another mount
  and thereby draw my tools' attention away
  from the powerful but expensive virtual directory
  that dynamically searches the network for Windows computers and shares.
</p>
<p>
  In case I have managed to obscure the actual solution
  by describing all of my wrong turns,
  here is the entire procedure for mounting my development directory
  on a newly installed Ubuntu system:
</p>

<div class="pygments_murphy syntax_highlight"><pre><span class="c"># The whole shebang</span><br/><br/><span class="nv">$ </span>sudo aptitude install smbnetfs bindfs<br/><span class="nv">$ </span>mkdir -p ~/win ~/winsrc<br/><span class="nv">$ </span>smbnetfs ~/win<br/><span class="nv">$ </span>bindfs ~/win/BRANDON-PC/project/src ~/winsrc<br/><span class="nv">$ </span><span class="nb">cd</span> ~/winsrc<br/></pre></div>


]]></content:encoded>
    </item>
    <item>
      <title>Opening tabs remotely in Google Chrome</title>
      <link>http://rhodesmill.org/brandon/2010/remote-tabs-google-chrome/</link>
      <pubDate>Wed, 24 Feb 2010 23:07:06 EST</pubDate>
      <category><![CDATA[python]]></category>
      <category><![CDATA[emacs]]></category>
      <category><![CDATA[computing]]></category>
      <guid>http://rhodesmill.org/brandon/?p=291</guid>
      <description>Opening tabs remotely in Google Chrome</description>
      <content:encoded><![CDATA[
<p>
Now that I use
<a href="http://www.google.com/chrome">Google Chrome</a>
almost exclusively,
I miss the fact
that a running <a href="http://www.firefox.com">Firefox</a> instance
could be controlled from the command line so that Emacs could call for a new tab
when I clicked on a URL.
It would run a command something like this:
</p>
<pre>
firefox -remote 'openURL(http://example.com/, new-tab)'
</pre>
<p>
But after a few months of manually cutting and pasting URLs into Chrome —
which wasn't actually <i>that</i> bad,
since the address bar in Chrome is such a convenient and large target —
I decided that I needed a real solution.
After not finding anything like a <tt>-remote</tt> option,
I discovered that Chrome can at least be run
with a debugging port open:
</p>
<pre>
google-chrome --remote-shell-port=9222
</pre>
<p>
The protocol that Chrome speaks is primitive enough
that it was quick work to implement a small client in Python.
Rather than merely cutting and pasting its code here on my blog,
or even be satisfied with
<a href="http://bitbucket.org/brandon/chrome_remote_shell/"
   >making it available on bitbucket</a>,
I decided to place the code inside of a new Python package
and make it generally available on PyPI as <a href="http://pypi.python.org/pypi/chrome_remote_shell/"
   >chrome_remote_shell</a>.
</p>
<p>
Thanks to this simple package,
a four-line program (not counting the shebang and comment)
is now all that I need to ask Google Chrome to open a new tab:
</p>

<div class="pygments_murphy syntax_highlight"><pre><span class="c">#!/usr/bin/env python</span><br/><span class="c"># Name this file &quot;google-chrome-open-url&quot;</span><br/><span class="kn">import</span> <span class="nn">sys</span><br/><span class="kn">import</span> <span class="nn">chrome_remote_shell</span><br/><span class="n">shell</span> <span class="o">=</span> <span class="n">chrome_remote_shell</span><span class="o">.</span><span class="n">open</span><span class="p">()</span><br/><span class="n">shell</span><span class="o">.</span><span class="n">open_url</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span><br/></pre></div>


<p>
To teach Emacs to start using Google Chrome when I clicked on a link,
I only needed to supply it with two new settings:
</p>

<div class="pygments_murphy syntax_highlight"><pre><span class="p">(</span><span class="nf">setq</span> <span class="nv">browse-url-browser-function</span><br/>      <span class="ss">&#39;browse-url-generic</span><span class="p">)</span><br/><span class="p">(</span><span class="nf">setq</span> <span class="nv">browse-url-generic-program</span><br/>      <span class="s">&quot;google-chrome-open-url&quot;</span><span class="p">)</span>  <br/></pre></div>


<p>
And now everything works.
I hope that these notes prove useful to someone else.
Enjoy!
</p>
]]></content:encoded>
    </item>
    <item>
      <title>Installing Python packages for Emacs with virtualenv</title>
      <link>http://rhodesmill.org/brandon/2009/emacs-python-virtualenv/</link>
      <pubDate>Wed, 25 Feb 2009 18:25:15 EST</pubDate>
      <category><![CDATA[python]]></category>
      <category><![CDATA[emacs]]></category>
      <category><![CDATA[computing]]></category>
      <guid>http://rhodesmill.org/brandon/?p=30</guid>
      <description>Installing Python packages for Emacs with virtualenv</description>
      <content:encoded><![CDATA[
The only rough edge I have found amidst the otherwise exceptional advice on Ryan McGuire's <a href="http://www.enigmacurry.com/">Enigma Curry blog</a> is that Ryan recommends installing Python packages with:
<pre>
$ sudo easy_install <i>package_url</i>
</pre>
This means that his Emacs configuration — which, very generously, <a href="http://www.enigmacurry.com/2009/01/19/my-emacs-config-on-github/">he has started maintaining as a project on github</a> so that other people can use it themselves, or branch their own versions — requires root access merely to install.

Like Ryan, I also keep my Emacs configuration under version control, so that improvements I check in from one account are easy to check out into all of my other accounts. Although my setup is probably too simple to be interesting as a public project, there is one aspect of it that I should share: unlike Ryan, I use the advanced technology of a <a href="http://pypi.python.org/pypi/virtualenv"><tt>virtualenv</tt></a> to hold the Python packages that Emacs needs. The virtual environment lives under my own account, and is easy to create, access, and rebuild, even in the absence of root privileges on a particular machine. Even better, packages that I install or upgrade inside of the virtual environment cannot interfere with Python programs running elsewhere on the system.

<!--more-->

A “virtual environment” is a little self-contained Python install, whose essential files are copied from your main system Python; no additional compilation is necessary! A virtual environment can be created under any directory on your system.

For example, on a Unix system, the default Python probably lives under the <tt>/usr</tt> directory, and looks like this:
<pre>
/usr/bin/easy_install             # to add new packages
/usr/bin/python                   # the main executable
/usr/lib/python2.5/               # normal packages
/usr/lib/python2.5/site-packages/ # 3rd party packages
</pre>
To create a virtual environment where my Emacs-related packages can live in peace by themselves, I simply instruct <tt>virtualenv</tt> to reproduce a directory structure like the one outlined above, but in a more convenient location — in this case, hidden beneath my <tt>~/.emacs</tt> directory:
<pre>
$ virtualenv ~/.emacs/usr
</pre>
This means that I now have a little Python directory hierarchy of my own, but writable with my normal user file permissions, and easy to remove and re-create:
<pre>
/home/bcr/.emacs/usr/bin/easy_install
/home/bcr/.emacs/usr/bin/python
/home/bcr/.emacs/usr/lib/python2.5/
/home/bcr/.emacs/usr/lib/python2.5/site-packages/
</pre>
Whenever you run the <tt>easy_install</tt> and <tt>python</tt> commands that <tt>virtualenv</tt> has created under this new directory, they will install packages to, and load packages from, the <tt>site-packages</tt> directory sitting right there in the virtual environment with them.

But how, you ask, does the <tt>virtualenv</tt> command itself get installed? Doesn't <i>that</i>, at least, require root access to <tt>easy_install</tt>? Not at all! The command is entirely self-contained; just grab the <tt>virtualenv.py</tt> file from inside of the <tt>virutalenv</tt> tar archive on <a href="http://pypi.python.org/pypi/virtualenv">its page at the Python Package Index</a>. I always simply include a copy of <tt>virtualenv</tt> in the files that I push to a new home directory whenever I get a new account somewhere.

Here is the real-life <tt>build.sh</tt> shell script (yes, I am old-fashioned) that I keep in version control along with the <tt>.tar.gz</tt> archives of the Python packages that I want Emacs to use:

<div class="pygments_murphy syntax_highlight"><pre><span class="c"># Brandon&#39;s ~/.emacs.d/src/build.sh</span><br/><span class="c"># Change to the directory containing this script.</span><br/><br/><span class="nb">cd</span> <span class="k">$(</span>dirname <span class="s2">&quot;$0&quot;</span><span class="k">)</span><br/><br/><span class="c"># Clean up directories left over from previous run.</span><br/><br/><span class="nv">DIRS</span><span class="o">=(</span>Pymacs-0.23 rope-0.9.2 ropemacs-0.6 pyflakes-0.3.0<span class="o">)</span><br/>rm -rf ../usr <span class="k">${</span><span class="nv">DIRS</span><span class="p">[@]</span><span class="k">}</span><br/><br/><span class="c"># Create the virtualenv.</span><br/><br/>python2.5 virtualenv.py ../usr<br/><span class="nb">source</span> ../usr/bin/activate<br/><br/><span class="c"># Unpack the four Python packages that Emacs needs.</span><br/><br/>tar xvfz Pymacs.tar.gz<br/>tar xvfz rope-0.9.2.tar.gz<br/>tar xvfz ropemacs-0.6.tar.gz<br/>tar xvfz pyflakes-0.3.0.tar.gz<br/><br/><span class="c"># Install them in &quot;~/.emacs/usr&quot; (the &quot;python2.5&quot; that</span><br/><span class="c"># gets called here is the one in the virtualenv, thanks</span><br/><span class="c"># to my having sourced its &quot;activate&quot; script up above).</span><br/><br/><span class="k">for </span>D in <span class="k">${</span><span class="nv">DIRS</span><span class="p">[@]</span><span class="k">}</span><br/><span class="k">do </span><span class="nb">cd</span> <span class="nv">$D</span>; python2.5 setup.py install; <span class="nb">cd</span> ..; <span class="k">done</span><br/><br/><span class="c"># Make fresh pymacs.el symlink from ~/.emacs</span><br/><br/>rm -f ../pymacs.el<br/>ln -s src/Pymacs-0.23/pymacs.el ../pymacs.el<br/></pre></div>


Without having to assume an elevated privilege even once, this script removes any old <tt>virtualenv</tt> sitting in the way, builds a new one, and installs the four Python packages into it. As a final step, it creates an easy-to-find symlink to the <tt>pymacs.el</tt> so that my main Emacs file does not have to remember the name of its source directory, which changes with each new version.

My <tt>~/.emacs.d/init.el</tt> file simply has to point Emacs at the Python executable inside the virtual environment, and everything works:

<div class="pygments_murphy syntax_highlight"><pre><span class="c1">;; From Brandon&#39;s ~/.emacs.d/init.el</span><br/><span class="p">(</span><span class="nf">add-to-list</span> <span class="ss">&#39;load-path</span> <span class="s">&quot;~/.emacs.d&quot;</span><span class="p">)</span><br/><span class="p">(</span><span class="nf">setenv</span> <span class="s">&quot;PYMACS_PYTHON&quot;</span> <span class="s">&quot;~/.emacs.d/usr/bin/python2.5&quot;</span><span class="p">)</span><br/></pre></div>


Actually, <a href="/brandon/static/2009/init.sample.el">the real file is a bit more complicated</a> because several LISP commands are required to set up each feature, but you get the idea: by always running commands from the <tt>bin</tt> directory of the virtual environment, Emacs can have access to any number of Python packages without my having to touch the system Python install at all!

With this one improvement, I have a portable Emacs configuration that can quickly be installed on new machines — which makes it easy whenever Ryan discovers new improvements for my favorite editor! While his original “<a href="http://www.enigmacurry.com/2008/05/09/emacs-as-a-powerful-python-ide/">Emacs as a powerful Python IDE</a>” post was what got me started turning Emacs into a modern IDE, <a href="http://www.enigmacurry.com/category/emacs/">Ryan continues to find new gems</a> from among the many Emacs packages and features floating around on the Internet. I'll be watching!
]]></content:encoded>
    </item>
  </channel>
</rss>

