<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>version2beta archive</title><link href="http://www.version2beta.com/archive/atom.xml" rel="self"/><link href="http://www.version2beta.com"/><updated>2012-05-20T04:06:41Z</updated><id>http://www.version2beta.com</id><entry><title>Ramada Plaza Milwaukee kicks my 70 year old mother out at midnight</title><author><name>Rob Martin</name></author><link href="http://www.version2beta.com/archive/2012/ramada-plaza-milwaukee-kicks-out-my-70-year-old-mother-at-midnight.html"/><updated>2012-05-20T02:21:00Z</updated><published>2012-05-20T02:21:00Z</published><id>http://www.version2beta.com/archive/2012/ramada-plaza-milwaukee-kicks-out-my-70-year-old-mother-at-midnight.html</id><content type="html">
       
&lt;!-- Hyde::Excerpt::Begin --&gt;

&lt;p&gt;&lt;em&gt;Dear Ramada&amp;nbsp;Worldwide,&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Your Wisconsin Ramada Plaza Hotel on 13th at College Ave in Milwaukee just kicked my 70 year old mother out of her hotel room at midnight, because I complained about&amp;nbsp;accessibility.&lt;/em&gt;&lt;/p&gt;
&lt;!-- Hyde::Excerpt::End --&gt;

&lt;p&gt;I know that sounds absurd. It is absurd, and it actually gets worse. You see, what I actually complained about was that the hotel told my sisters to cart my mother to their room on a luggage rack. You know, the rack the bellboy&amp;nbsp;pushes.&lt;/p&gt;
&lt;p&gt;Mom has had bypass surgeries, back surgeries, neck surgeries, heart surgeries, you name it. Last month they did an operation on her carotid artery. A month before they replaced her pacemaker. She also has primary progressive &lt;span class=&quot;caps&quot;&gt;MS&lt;/span&gt;. Mom is a modern medical miracle. One would think that when you arrive with a 70 year old woman and ask for a wheel chair, you might recognize the kind of situation that requires a level head for both customer service and legal compliance. You might not want to tell the guests to load mom up on a luggage cart and skate her up to her&amp;nbsp;room.&lt;/p&gt;
&lt;p&gt;Upstairs, and all the way to the other end of the building. To a room where, when one sits on the foot of the bed, the head of the bed rises 12 inches. (Try to picture my mother sitting on the edge of the bed putting on her shoes, with the other end of the bed floating away. It&amp;#8217;s okay if you need to&amp;nbsp;laugh.)&lt;/p&gt;
&lt;p&gt;My younger sister didn&amp;#8217;t just tell me about it, she called up Ramada and complained. Nothing&amp;nbsp;happened.&lt;/p&gt;
&lt;p&gt;Trying to do something about this worried my older sister - with good reason, as it turned out. After all, look what happened when I did try to do something about it. They got kicked right out on their asses at midnight.&amp;nbsp;Duh!&lt;/p&gt;
&lt;p&gt;My mother didn&amp;#8217;t want to be a bother. To be honest, I think she feels bad she can no longer walk from the lobby to room&amp;nbsp;256.&lt;/p&gt;
&lt;p&gt;On the other hand, I was willing to be a bother. Here&amp;#8217;s what I&amp;nbsp;did:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I tweeted about it.&lt;sup id=&quot;fnref:t1&quot;&gt;&lt;a href=&quot;#fn:t1&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; &lt;sup id=&quot;fnref:t2&quot;&gt;&lt;a href=&quot;#fn:t2&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; &lt;sup id=&quot;fnref:t3&quot;&gt;&lt;a href=&quot;#fn:t3&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; &lt;sup id=&quot;fnref:t4&quot;&gt;&lt;a href=&quot;#fn:t4&quot; rel=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; &lt;sup id=&quot;fnref:t5&quot;&gt;&lt;a href=&quot;#fn:t5&quot; rel=&quot;footnote&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; Really, this is some absurd stuff. Push the old lady up on a luggage rack? It&amp;#8217;s almost funny, you know? I mean, if she&amp;#8217;s not your&amp;nbsp;mom.&lt;/li&gt;
&lt;li&gt;I called Ramada Worldwide customer service and told them about it. They told me to call the hotel. I said I would, but I still wanted to talk to a manager. Turns out, Ramada Worldwide customer service is one of those departments that is set up to prevent the customer from getting service. I had to tell the woman to (a) get a manager, or (b) take my information so that a manager could get back to me, or (c) hang up on me. She chose option (b) and promised a manager would return my call by Thursday, five days&amp;nbsp;hence.&lt;/li&gt;
&lt;li&gt;I called the Ramada Plaza Milwaukee, where they were staying. Scratch that. I tried to call the hotel, but &lt;span class=&quot;caps&quot;&gt;THEIR&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;NUMBER&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;WAS&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;DISCONNECTED&lt;/span&gt;. Yes, the 800-303-8002 number on every page of their website&lt;sup id=&quot;fnref:ramadaplaza&quot;&gt;&lt;a href=&quot;#fn:ramadaplaza&quot; rel=&quot;footnote&quot;&gt;6&lt;/a&gt;&lt;/sup&gt; was disconnected.&amp;nbsp;Wtf?&lt;/li&gt;
&lt;li&gt;I drove down to the hotel and I talked to a manager, Jennifer, who was actually very sweet and helpful. She was aghast about the luggage rack. Jennifer&amp;#8217;s indignation made me feel good. She also found an accessible room on the first floor. She gave me keys so I could move my mom and my sisters (who were visiting with my son at his hippotherapy) to the new room. As it happens, she couldn&amp;#8217;t find one of the aforementioned luggage racks so I had to make five trips. But she did take some notes on my concerns (like the see-sawing bed and the out-of-service phone number) to leave for the&amp;nbsp;owner.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The owner didn&amp;#8217;t call me. When my sisters returned at midnight, their room key didn&amp;#8217;t work. When they checked in at the counter, my sisters were informed that they were no longer guests and would be escorted out, with their&amp;nbsp;things.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s the really fun part - mom wasn&amp;#8217;t even there because she was at the hospital for a heart attack! My sisters were returning to the hotel room after we got mom admitted to St Luke&amp;#8217;s Hospital. I&amp;#8217;m sitting in mom&amp;#8217;s hospital room where it&amp;#8217;s still not clear if she had a heart attack or if it&amp;#8217;s just a stage one blockage, and my sisters - after one hell of an evening - are getting kicked out of their&amp;nbsp;hotel.&lt;/p&gt;
&lt;p&gt;The reason they were given is that &lt;strong&gt;I was&amp;nbsp;combative.&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;Some people might think I was being reasonable to ask that they help find a more appropriate room. But some people might call it reasonable that the hotel didn&amp;#8217;t have any wheelchairs and didn&amp;#8217;t offer help beyond a luggage rack for her transport. My mother could have chosen to travel with her electric scooter, except that she wouldn&amp;#8217;t have been able to fly here from Maine. Or maybe my sister should have reserved a handicapped room - I don&amp;#8217;t actually know whether she reserved a handicap room, or if she even knew they exist. If she didn&amp;#8217;t &lt;strong&gt;reserve&lt;/strong&gt; an accessible room, why should that be the hotel&amp;#8217;s&amp;nbsp;problem?&lt;/p&gt;
&lt;p&gt;(Except for the &lt;span class=&quot;caps&quot;&gt;ADA&lt;/span&gt;. And Wisconsin law. I don&amp;#8217;t know if the city has any laws on the&amp;nbsp;subject.)&lt;/p&gt;
&lt;p&gt;Just to be clear: I was not there when my sisters wheeled our mother up to the room on a luggage rack, but all three of them told me it happened, that it was what the hotel told them to do and they had no other way to get mom to the room. I did sit on the seesawing bed. I did talk to Ramada Worldwide customer service. And I did talk to Jennifer at the hotel, who is the person who answered my questions when I asked for a&amp;nbsp;manager.&lt;/p&gt;
&lt;p&gt;My conclusion can only be that my elderly mother and two sisters were kicked out of the Ramada Plaza Milwaukee because I complained about accessibility. To be fair, what I call complaint they call combat. And I did tweet about them five times. So maybe I deserved to feel like a total shit when my sister called me crying at half past midnight to tell me they kicked them out of their room because I was&amp;nbsp;combative.&lt;/p&gt;
&lt;p&gt;I fear many people don&amp;#8217;t actually understand what accessibility is, and why it&amp;#8217;s important. Some of them work in (or even own) businesses that deal with accessibility challenges on this scale every day, and often they are handled poorly. I encourage you to share this story for the value of a bad example, and reinforce why accessibility is&amp;nbsp;important.&lt;/p&gt;

   </content></entry><entry><title>A Response to Tom Henrich&#39;s Document The Why</title><author><name>Rob Martin</name></author><link href="http://www.version2beta.com/archive/2012/document-the-why-not-just-the-how.html"/><updated>2012-03-26T10:15:00Z</updated><published>2012-03-26T10:15:00Z</published><id>http://www.version2beta.com/archive/2012/document-the-why-not-just-the-how.html</id><content type="html">
       
&lt;!-- Hyde::Excerpt::Begin --&gt;

&lt;p&gt;On his blog, Tom Henrich&lt;sup id=&quot;fnref:th&quot;&gt;&lt;a href=&quot;#fn:th&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; calls for better developer documentation&lt;sup id=&quot;fnref:why&quot;&gt;&lt;a href=&quot;#fn:why&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; on &lt;em&gt;why&lt;/em&gt; a design decision was made, rather than just &lt;em&gt;what&lt;/em&gt; decision was made. In this post I share my&amp;nbsp;example.&lt;/p&gt;
&lt;!-- Hyde::Excerpt::End --&gt;

&lt;p&gt;From the source code for a Box.net&lt;sup id=&quot;fnref:box.net&quot;&gt;&lt;a href=&quot;#fn:box.net&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; uploader snippet I wrote in &lt;span class=&quot;caps&quot;&gt;MODX&lt;/span&gt;:&lt;sup id=&quot;fnref:modx&quot;&gt;&lt;a href=&quot;#fn:modx&quot; rel=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/*
 * @name      Down and Dirty Box.net Uploader
 * @author    Rob Martin &amp;lt;rob@qmuxs.com&amp;gt;
 * @copyright (c) 2011 Quintessential Mischief LLC
 * @link      http://www.qmuxs.com
 * @license   GPLv3
 * @version   0.1.0
 * 
 * The need for a down &lt;span class=&quot;amp&quot;&gt;&amp;amp;&lt;/span&gt; dirty uploader came about after reviewing the 
 * box.net &lt;span class=&quot;caps&quot;&gt;PHP&lt;/span&gt; library code at https://github.com/boxplatform/box-php.
 * It&#39;s just not very good, and some of it is totally borked. It&#39;s not
 * even a surprise - I found comments on blog posts dated from February
 * 2008 complaining about a bug (can you call a whole missing function
 * - promised in the docs - a bug?) that has not changed in over three
 * years.
 *
 * I was about to start over. :-( But I did get in touch with Sean ****
 * at Box.net who threw some salt on the open wounds. He let me know
 * that the new &lt;span class=&quot;caps&quot;&gt;PHP&lt;/span&gt; library is **just days from release**. 
 *
 * And no, he couldn&#39;t get it for me. So sorry.
 *
 * The Python code isn&#39;t much better, though I haven&#39;t read through it
 * as much. However, documentation such as:
 *
 * &amp;gt; &quot;&quot;&quot;Exception class for errors received from Facebook.&quot;&quot;&quot;
 * 
 * makes me think it might not be. Facebook has nothing to do with this
 * code.
 *
 * **&lt;span class=&quot;caps&quot;&gt;NOTE&lt;/span&gt;**: Just so you know, this code doesn&#39;t do any of the
 * authentication work. You&#39;ve gotta do that manually. You need an &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; key,
 * an auth_token, and a folder &lt;span class=&quot;caps&quot;&gt;ID&lt;/span&gt; for where you want the files to land.
 *
 * Here&#39;s how:
 *
 * 1. Get a ticket. It&#39;ll come back as &amp;lt;ticket&amp;gt;...&amp;lt;/ticket&amp;gt;.
 * https://www.box.net/api/1.0/rest?action=get_ticket&amp;amp;api_key={YOUR_API_KEY}
 *
 * 2. Using the ticket, log in.
 * https://www.box.net/api/1.0/auth/{YOUR_TICKET}
 *
 * 3. Request the auth_token. It&#39;ll come back as &amp;lt;auth_token&amp;gt;...&amp;lt;/auth_token&amp;gt;.
 * https://www.box.net/api/1.0/rest?action=get_auth_token&amp;amp;api_key={YOUR_API_KEY}&amp;amp;ticket={YOUR_TICKET}
 *
 * 4. Get the &lt;span class=&quot;caps&quot;&gt;ID&lt;/span&gt; of the folder you want. It&#39;ll look like &amp;lt;folder id=&quot;xxx&quot; name=&quot;this-one&quot;.../&amp;gt;
 * https://www.box.net/api/1.0/rest?action=get_account_tree&amp;amp;api_key={YOUR_API_KEY}&amp;amp;auth_token={YOUR_AUTH_TOKEN}&amp;amp;folder_id=0&amp;amp;params[]=nozip
 * 
 * So that&#39;s the story. Here&#39;s the code:
 */
&lt;/code&gt;&lt;/pre&gt;

   </content></entry><entry><title>MODX can beat up your content management system</title><author><name>Rob Martin</name></author><link href="http://www.version2beta.com/archive/2011/modx-can-beat-up-your-content-management-system.html"/><updated>2011-12-13T10:48:00Z</updated><published>2011-12-13T10:48:00Z</published><id>http://www.version2beta.com/archive/2011/modx-can-beat-up-your-content-management-system.html</id><content type="html">
       
&lt;!-- Hyde::Excerpt::Begin --&gt;

&lt;p&gt;Tonight&amp;#8217;s Milwaukee Web Design Meetup featured a &lt;span class=&quot;caps&quot;&gt;CMS&lt;/span&gt; MegaPanel - eight pros in eight content management systems, head to head on development, features, ecosystems, costs. I represented for&amp;nbsp;&lt;span class=&quot;caps&quot;&gt;MODX&lt;/span&gt;.&lt;/p&gt;
&lt;!-- Hyde::Excerpt::End --&gt;

&lt;p&gt;Here is my Prezi&lt;sup id=&quot;fnref:prezi&quot;&gt;&lt;a href=&quot;#fn:prezi&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; on &lt;span class=&quot;caps&quot;&gt;MODX&lt;/span&gt;:&lt;sup id=&quot;fnref:modx&quot;&gt;&lt;a href=&quot;#fn:modx&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;prezi-player&quot;&gt;
    &lt;style type=&quot;text/css&quot; media=&quot;screen&quot;&gt;
        .prezi-player { width: 640px; } .prezi-player-links { text-align: center; }
    &lt;/style&gt;
    &lt;object id=&quot;prezi_xemmat6oavos&quot; name=&quot;prezi_xemmat6oavos&quot; classid=&quot;clsid:D27CDB6E-AE6D-11cf-96B8-444553540000&quot; width=&quot;640&quot; height=&quot;440&quot;&gt;
        &lt;param name=&quot;movie&quot; value=&quot;http://prezi.com/bin/preziloader.swf&quot;/&gt;
        &lt;param name=&quot;allowfullscreen&quot; value=&quot;true&quot;/&gt;
        &lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot;/&gt;
        &lt;param name=&quot;bgcolor&quot; value=&quot;#ffffff&quot;/&gt;
        &lt;param name=&quot;flashvars&quot; value=&quot;prezi_id=xemmat6oavos&amp;amp;lock_to_path=0&amp;amp;color=ffffff&amp;amp;autoplay=no&amp;amp;autohide_ctrls=0&quot;/&gt;
        &lt;embed id=&quot;preziEmbed_xemmat6oavos&quot; name=&quot;preziEmbed_xemmat6oavos&quot; src=&quot;http://prezi.com/bin/preziloader.swf&quot; type=&quot;application/x-shockwave-flash&quot; allowfullscreen=&quot;true&quot; allowscriptaccess=&quot;always&quot; width=&quot;640&quot; height=&quot;440&quot; bgcolor=&quot;#ffffff&quot; flashvars=&quot;prezi_id=xemmat6oavos&amp;amp;lock_to_path=0&amp;amp;color=ffffff&amp;amp;autoplay=no&amp;amp;autohide_ctrls=0&quot;&gt;&lt;/embed&gt;
        &lt;p&gt;Sorry, Flash is required here. I don&amp;#8217;t like it either, and I know I really need to learn a different presentation&amp;nbsp;system.&lt;/p&gt;
    &lt;/object&gt;
    &lt;div class=&quot;prezi-player-links&quot;&gt;
        &lt;p&gt;&lt;a title=&quot;MODX can beat up your Content Management System.&quot; href=&quot;http://prezi.com/xemmat6oavos/modx-can-beat-up-your-content-management-system/&quot;&gt;&lt;span class=&quot;caps&quot;&gt;MODX&lt;/span&gt; can beat up your Content Management System.&lt;/a&gt; on &lt;a href=&quot;http://prezi.com&quot;&gt;Prezi&lt;/a&gt;&lt;/p&gt;
    &lt;/div&gt;
&lt;/div&gt;


   </content></entry><entry><title>A quick note on MongoDB replica sets</title><author><name>Rob Martin</name></author><link href="http://www.version2beta.com/archive/2011/mongod-replica-set-slave.html"/><updated>2011-11-29T11:49:00Z</updated><published>2011-11-29T11:49:00Z</published><id>http://www.version2beta.com/archive/2011/mongod-replica-set-slave.html</id><content type="html">
       
&lt;!-- Hyde::Excerpt::Begin --&gt;

&lt;p&gt;MongoDB is replying to a replica-set add command with &amp;#8220;Need most members up to reconfigure, not ok&amp;#8221;. The problem is with my&amp;nbsp;configuration.&lt;/p&gt;
&lt;!-- Hyde::Excerpt::End --&gt;

&lt;p&gt;Here&amp;#8217;s the&amp;nbsp;error:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PRIMARY&amp;gt; rs.add(&quot;nosql1-private:27017&quot;)
{
    &quot;assertion&quot; : &quot;need most members up to reconfigure, not ok : nosql1-private:27017&quot;,
    &quot;assertionCode&quot; : 13144,
    &quot;errmsg&quot; : &quot;db assertion failure&quot;,
    &quot;ok&quot; : 0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The problem is in my configuration on the slave Mongod. Note that I&amp;#8217;m using a configuration file, rather than command line options, which is how the tutorials are written. This fits in with my init file, which I can share if anyone wants an Ubuntu init for MongoDB&amp;nbsp;2.0.2.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fork = true
bind_ip = nosql1-private
port = 27017 # default port
logpath = /var/log/mongodb/mongod.log
logappend = true
cpu = true # log CPU activity periodically
journal = true
auth = true
replSet = gedc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I disabled journal (shouldn&amp;#8217;t be needed on a slave, right?) and auth, which seems to actually be the problem. After, the rs.add() works&amp;nbsp;fine.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PRIMARY&amp;gt; rs.add(&quot;nosql1-private:27017&quot;)
{ &quot;ok&quot; : 1 }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I&amp;#8217;m not sure I don&amp;#8217;t have to go back and get auth reenabled, though, because now my status says that the second server is &amp;#8220;still initializing&amp;#8221; and &amp;#8220;(not reachable/healthy)&amp;#8221;. But when I try to add authentication credentials, I get this&amp;nbsp;error:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;uncaught exception: error { &quot;$err&quot; : &quot;not master and slaveok=false&quot;, &quot;code&quot; : 13435 }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, I did discover what I really needed was a keyFile directive&lt;sup id=&quot;fnref:key&quot;&gt;&lt;a href=&quot;#fn:key&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; in my mongod.conf. The file itself contains a base64 text key the servers will use for&amp;nbsp;communicating.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...
keyFile = /etc/mongodb/key.txt
...
&lt;/code&gt;&lt;/pre&gt;

   </content></entry><entry><title>My 18-monitor setup</title><author><name>Rob Martin</name></author><link href="http://www.version2beta.com/archive/2011/my-eighteen-monitor-setup.html"/><updated>2011-11-29T09:04:00Z</updated><published>2011-11-29T09:04:00Z</published><id>http://www.version2beta.com/archive/2011/my-eighteen-monitor-setup.html</id><content type="html">
       
&lt;!-- Hyde::Excerpt::Begin --&gt;

&lt;p&gt;Sitting right now at my desk at Top Floor Technologies, I&amp;#8217;ve got 18 monitors available to me as I work. Excessive? Nah. 18 is almost&amp;nbsp;enough.&lt;/p&gt;
&lt;!-- Hyde::Excerpt::End --&gt;

&lt;p&gt;I&amp;#8217;ve had a variety of computer configurations. Hell, I have a variety of configurations right now, ranging from a decent setup in my home office that&amp;#8217;s stuck in the middle of an &lt;span class=&quot;caps&quot;&gt;OS&lt;/span&gt; update I started last month and haven&amp;#8217;t gotten back to, to a setup at my &lt;span class=&quot;caps&quot;&gt;QM&lt;/span&gt;&lt;sup id=&quot;fnref:qm&quot;&gt;&lt;a href=&quot;#fn:qm&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; with a 32&amp;#8221; &lt;span class=&quot;caps&quot;&gt;LCD&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;TV&lt;/span&gt; as the main monitor (with a 23&amp;#8221; on the side), to my Version2beta&lt;sup id=&quot;fnref:version2beta&quot;&gt;&lt;a href=&quot;#fn:version2beta&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; laptop and 19&amp;#8221; Dell monitor that I take with me when working onsite with&amp;nbsp;customers.&lt;/p&gt;
&lt;p&gt;In the past, I&amp;#8217;ve done 3-monitor configurations. Once even a 4-monitor setup. They&amp;#8217;ve been good, sometimes even&amp;nbsp;fun.&lt;/p&gt;
&lt;p&gt;Now though, at Top Floor,&lt;sup id=&quot;fnref:tft&quot;&gt;&lt;a href=&quot;#fn:tft&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; I count 18 monitors on my&amp;nbsp;setup.&lt;/p&gt;
&lt;p&gt;As you might guess, these aren&amp;#8217;t all full, separate physical monitors. My desk is not so big, nor my chair so rolly. In fact, no one computer (there are three) has more than one physical monitor installed. But I have lots of virtual workspaces, and my fingers are very&amp;nbsp;rolly.&lt;/p&gt;
&lt;p&gt;My setup. Count along with&amp;nbsp;me.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Main: Intel Core i7 @ 3.4GHz with 12 &lt;span class=&quot;caps&quot;&gt;GB&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;RAM&lt;/span&gt;. 27&amp;#8221; &lt;span class=&quot;caps&quot;&gt;LED&lt;/span&gt; monitor. 8 virtual monitors configured in pairs.&lt;ul&gt;
&lt;li&gt;General web on Chrome (1) and general consoles (2). Stuff like filling out my time card, logging into Rackspace,&amp;nbsp;etc.&lt;/li&gt;
&lt;li&gt;Email (3) and Google Talk&amp;nbsp;(4).&lt;/li&gt;
&lt;li&gt;Project web on Chromium (5) and project consoles (6). Whatever development project I&amp;#8217;m working&amp;nbsp;one.&lt;/li&gt;
&lt;li&gt;Interuptions, web (7) and consoles (8). The stuff that gets done inbetween the stuff I&amp;#8217;m supposed to be working&amp;nbsp;on.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Laptop: Intel i5 @ 2.4GHz with 6 &lt;span class=&quot;caps&quot;&gt;GB&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;RAM&lt;/span&gt;. 17&amp;#8221; widescreen display. 8 more virtual monitors configured in pairs.&lt;ul&gt;
&lt;li&gt;General (personal) web (9). My webmail clients, twitter, etc. Also, general consoles&amp;nbsp;(10). &lt;/li&gt;
&lt;li&gt;Google talk (11) and network tests (12). Yes, it&amp;#8217;s the same Google Talk account. Sometimes I don&amp;#8217;t want to switch away on my main&amp;nbsp;monitor.&lt;/li&gt;
&lt;li&gt;Version2beta project work browsers (13) and consoles&amp;nbsp;(14).&lt;/li&gt;
&lt;li&gt;Overflow (15) and (16). Okay, I have more monitors than I need on my laptop. Usually&amp;nbsp;need.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;iPad: first generation. It has a processor and some memory, but I don&amp;#8217;t recall how much.&lt;ul&gt;
&lt;li&gt;Just one display (17). It often has my Twitter client on it, but sometimes I&amp;#8217;ll throw email on screen, especially if I need to look at one of my more obscure personal&amp;nbsp;accounts.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Dell 19&amp;#8221; widescreen (18). Currently sitting on the floor next to my desk, unused. I need to buy an &lt;span class=&quot;caps&quot;&gt;HDMI&lt;/span&gt; cable for my main system so I can run this one off the secondary&amp;nbsp;output.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I configure &lt;span class=&quot;caps&quot;&gt;CCSM&lt;/span&gt; (Compiz Configuration Settings Manager) to use Ctl-Alt-Arrows to move me from virtual monitor to virtual monitor, alt-tab (and alt-shift-tab) to get me between applications on my current workspace, and alt-super-tab (and alt-super-shift-tab) to switch me between all applications on all virtual monitors. It&amp;#8217;s almost as fast as moving my eyes from one screen to the&amp;nbsp;next.&lt;/p&gt;

   </content></entry><entry><title>Drupal, on GlusterFS, on Rackspace Cloud</title><author><name>Rob Martin</name></author><link href="http://www.version2beta.com/archive/2011/drupal-on-glusterfs-on-rackspace-cloud.html"/><updated>2011-11-28T16:12:00Z</updated><published>2011-11-28T16:12:00Z</published><id>http://www.version2beta.com/archive/2011/drupal-on-glusterfs-on-rackspace-cloud.html</id><content type="html">
       
&lt;!-- Hyde::Excerpt::Begin --&gt;

&lt;p&gt;I ran Drupal on GlusterFS for a few days. I didn&amp;#8217;t like it. Here&amp;#8217;s&amp;nbsp;why.&lt;/p&gt;
&lt;!-- Hyde::Excerpt::End --&gt;

&lt;p&gt;I&amp;#8217;m building an eight-node server cluster on Rackspace Cloud for a Drupal site. Clearly, I want it to go&amp;nbsp;fast.&lt;/p&gt;
&lt;p&gt;It is a busy site, peaking at 20,000 unique visitors a day, maybe 100,000 pageviews. But the real fun part is that it has 1.6 million&amp;nbsp;users.&lt;/p&gt;
&lt;p&gt;Putting it on Drupal is a decision that predates me (and I withhold judgement - I don&amp;#8217;t have nearly enough Drupal experience yet), but the rest of the structure has been up to me. I have specific goals, like 1.5 second response times even for users who are logged&amp;nbsp;in. &lt;/p&gt;
&lt;p&gt;My architecture goes like&amp;nbsp;this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Two load balancers, running nginx. Nginx is also serving all static content and boost cache from Drupal. Upstream servers are selected by&amp;nbsp;ip_hash.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Two application servers upstream of nginx run lighttpd and fastcgi. Hello,&amp;nbsp;Drupal. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A dual-master pair of MySQL servers back up the application servers. I wanted to run PostgreSQL, and I was really happy when I remembered that Drupal works with PostgreSQL. But Drupal only works with Postgres for some values of the word &amp;#8220;works&amp;#8221;. Modules may or may not support it. &lt;span class=&quot;caps&quot;&gt;CCK&lt;/span&gt; has some issues&amp;nbsp;too. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Two MongoDB servers hold up the rear and contain user-specific information for all 1.6 million users. A custom Python program manages authentication and data&amp;nbsp;interface.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Originally, I intended to use &lt;span class=&quot;caps&quot;&gt;DR&lt;/span&gt;:&lt;span class=&quot;caps&quot;&gt;BD&lt;/span&gt;&lt;sup id=&quot;fnref:drbd&quot;&gt;&lt;a href=&quot;#fn:drbd&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; much like I do with my high-availability Linode virtual private servers.&lt;sup id=&quot;fnref:linode-ha&quot;&gt;&lt;a href=&quot;#fn:linode-ha&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; It turns out that you can do that on Rackspace a couple different ways, neither of which are recommended. The first requires you to make a loopback device, since it&amp;#8217;s really difficult to get more than one block-level device on a Rackspace cloud server. The second requires you to get more than one block-level device on a Rackspace cloud server, which is not (as you might guess) only really difficult to accomplish, but it can also break things like backups and&amp;nbsp;snapshots.&lt;/p&gt;
&lt;p&gt;So bzzzzt to &lt;span class=&quot;caps&quot;&gt;DR&lt;/span&gt;:&lt;span class=&quot;caps&quot;&gt;BD&lt;/span&gt;, this&amp;nbsp;time.&lt;/p&gt;
&lt;p&gt;Next, I tried GlusterFS.&lt;sup id=&quot;fnref:gluster&quot;&gt;&lt;a href=&quot;#fn:gluster&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; The docs sucked&lt;sup id=&quot;fnref:docs&quot;&gt;&lt;a href=&quot;#fn:docs&quot; rel=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;. At least I think they would have sucked if I&amp;#8217;d read them, nearly all of them, because that&amp;#8217;s how far you have to get into them before you can see what really needs to be done. In part, this highlights the absence of a useful quickstart guide. But there&amp;#8217;s this sad thing, too. Once you manage to infer the organization of the configuration, it&amp;#8217;s really rather elegant. You could think of it as a string of Unix pipes, each volume handing off to the next, but I picture it like a stack of matryoshka dolls. This volume (the littlest doll) provides a &lt;span class=&quot;caps&quot;&gt;POSIX&lt;/span&gt; device. This volume (the next littlest doll) provides locks. The next volume (we&amp;#8217;re getting bigger now) provides multiple I/O threads. And so&amp;nbsp;on.&lt;/p&gt;
&lt;p&gt;When all the dolls were stacked, I had a working GlusterFS filesystem across four&amp;nbsp;servers.&lt;/p&gt;
&lt;p&gt;Since I&amp;#8217;m not the only person on this project (which is a good thing, or else we&amp;#8217;d really be in trouble) we also had a development server at WebEnabled.&lt;sup id=&quot;fnref:we&quot;&gt;&lt;a href=&quot;#fn:we&quot; rel=&quot;footnote&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; I compared the Drupal devel module timing between the two systems and realized that I had a serious problem. What WebEnabled was doing in 1,200ms, my setup was taking&amp;nbsp;4,200ms.&lt;/p&gt;
&lt;p&gt;Ultimately I tracked this down to GlusterFS. It appears (and I haven&amp;#8217;t really tested this) that Drupal is I/O intensive enough that the delays of GlusterFS made a noticeable (and unacceptable)&amp;nbsp;difference.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s the timing for one page (logged into Drupal, so boost isn&amp;#8217;t helping) with&amp;nbsp;GlusterFS:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Executed 229 queries in 294.47 milliseconds. Page execution time was 3820.92 ms.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here&amp;#8217;s the same page without&amp;nbsp;GlusterFS:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Executed 229 queries in 325.98 milliseconds. Page execution time was 839.68 ms.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now I&amp;#8217;m not here saying you can&amp;#8217;t run Drupal on GlusterFS. I&amp;#8217;m not even saying I had it configured right. (Remember, I didn&amp;#8217;t read the docs - at least not all of them.) But I&amp;#8217;m reasonably confident I had it configured and optimized well, and I got considerably better results when not using GlusterFS. In my case, I got acceptable results only without&amp;nbsp;GlusterFS.&lt;/p&gt;
&lt;p&gt;I still need to synchronize filesystems, so I tried another new-to-me program, lsyncd.&lt;sup id=&quot;fnref:lsyncd&quot;&gt;&lt;a href=&quot;#fn:lsyncd&quot; rel=&quot;footnote&quot;&gt;6&lt;/a&gt;&lt;/sup&gt; I like it, and it works well for this application, where the file system is not changing all that often. Perhaps I&amp;#8217;ll write something up on lsyncd another&amp;nbsp;day.&lt;/p&gt;

   </content></entry><entry><title>Elavon Phishing Scam</title><author><name>Rob Martin</name></author><link href="http://www.version2beta.com/archive/2011/elavon-phishing-scam.html"/><updated>2011-11-28T11:20:00Z</updated><published>2011-11-28T11:20:00Z</published><id>http://www.version2beta.com/archive/2011/elavon-phishing-scam.html</id><content type="html">
       
&lt;!-- Hyde::Excerpt::Begin --&gt;

&lt;p&gt;A customer received 40,000 mailer-daemon messages yesterday. I bet that was&amp;nbsp;fun.&lt;/p&gt;
&lt;!-- Hyde::Excerpt::End --&gt;

&lt;p&gt;I&amp;#8217;ve seen only four or five of the emails, but it was enough to demonstrate that someone had credentials to use the &lt;span class=&quot;caps&quot;&gt;SMTP&lt;/span&gt; server to send phishing messages pretending to be from Elavon Merchant&amp;nbsp;Services.&lt;/p&gt;
&lt;p&gt;The text of the message goes something like&amp;nbsp;this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;- Elavon Virtual Merchant Account Alert -

Your RETAIL account has expired. If you intend to use our services in the future you have to update your online info now.

- Download the attached login page in this email to continue. -

*** Please note : Only Retail accounts are locked. (Example : Market Segment : Retail )

Thank you - Elavon Merchant Services Team.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The attached &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; file looks like a login form for Elavon, but sends the data to a Japanese website http://depot-abc.com, deep linked into a Wordpress installation, probably&amp;nbsp;hacked. &lt;/p&gt;
&lt;p&gt;While it looked like the client&amp;#8217;s computer might have been compromised, it turned out the messages were being sent from colocated or shared servers, at least the few I tracked down. Most of the messages I looked at were sent from The Planet in Texas, which I believe is still the world&amp;#8217;s largest privately held hosting facility (hosting services, not like Facebook or Google which undoubtedly have bigger facilities.) Some of the other messages came from a machine hosted at Netelligent.ca, providing hosting services in and around Montreal. In this case, the machine seems to be in Laval,&amp;nbsp;&lt;span class=&quot;caps&quot;&gt;QC&lt;/span&gt;.&lt;/p&gt;

   </content></entry><entry><title>Tryton as an e-commerce back-end - Web Framework</title><author><name>Rob Martin</name></author><link href="http://www.version2beta.com/archive/2011/evaluating-tryton-as-an-ecommerce-backend_web-framework.html"/><updated>2011-11-19T16:44:00Z</updated><published>2011-11-19T16:44:00Z</published><id>http://www.version2beta.com/archive/2011/evaluating-tryton-as-an-ecommerce-backend_web-framework.html</id><content type="html">
       
&lt;!-- Hyde::Excerpt::Begin --&gt;

&lt;p&gt;This is part three in a series exploring how Tryton might fare as the heavy-lifting portion of an e-commerce package. This third part explores what it means to do&amp;nbsp;e-commerce.&lt;/p&gt;
&lt;!-- Hyde::Excerpt::End --&gt;

&lt;p&gt;The whole&amp;nbsp;series:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://version2beta.com/archive/2011/evaluating-tryton-as-an-ecommerce-backend_about-tryton.html&quot; title=&quot;Evaluation Tryton as an e-commerce back-end: Stalking the Tryton community&quot;&gt;Part 1: About&amp;nbsp;Tryton&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://version2beta.com/archive/2011/evaluating-tryton-as-an-ecommerce-backend_stalking-the-tryton-community.html&quot; title=&quot;Evaluation Tryton as an e-commerce back-end: Stalking the Tryton community&quot;&gt;Part 2: Stalking the Tryton&amp;nbsp;community&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Part 3: The crux of the&amp;nbsp;matter&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;First a&amp;nbsp;review&lt;/h2&gt;
&lt;p&gt;If you read my last two posts on this topic, you&amp;#8217;ll recall I&amp;#8217;m in the process of discovering the whys and hows of using Tryton as the back end of an e-commerce&amp;nbsp;system.&lt;/p&gt;
&lt;p&gt;To review, Tryton&lt;sup id=&quot;fnref:tryton&quot;&gt;&lt;a href=&quot;#fn:tryton&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; is an open source &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt;&lt;sup id=&quot;fnref:erp&quot;&gt;&lt;a href=&quot;#fn:erp&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; platform licensed under the &lt;span class=&quot;caps&quot;&gt;GNU&lt;/span&gt; General Public License,&lt;sup id=&quot;fnref:gpl&quot;&gt;&lt;a href=&quot;#fn:gpl&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; written in Python&lt;sup id=&quot;fnref:python&quot;&gt;&lt;a href=&quot;#fn:python&quot; rel=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; and working with a PostgreSQL&lt;sup id=&quot;fnref:postgres&quot;&gt;&lt;a href=&quot;#fn:postgres&quot; rel=&quot;footnote&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; database server. Phew. In short, it&amp;#8217;s a cool way to set up One Software To Rule Them All.&lt;sup id=&quot;fnref:lotr&quot;&gt;&lt;a href=&quot;#fn:lotr&quot; rel=&quot;footnote&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;In this post we get into the meat and potatoes: what is e-commerce&amp;nbsp;anyway?&lt;/p&gt;
&lt;h2&gt;What&amp;#8217;s e-commerce&amp;nbsp;anyway?&lt;/h2&gt;
&lt;p&gt;There are many ways to define e-commerce. Perhaps most comprehensive would be a list of features that are implemented in a given e-commerce system. I considered creating such a list for this blog post. Ultimately, I decided to keep it simple, because the most simple view also exposes the biggest holes in almost all e-commerce&amp;nbsp;systems.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s the simple definition: &lt;strong&gt;e-commerce is the implementation of a business&amp;#8217; customer interface on the internet.&lt;/strong&gt; If it involves a customer, a company, and a computer, it&amp;#8217;s probably&amp;nbsp;e-commerce.&lt;/p&gt;
&lt;p&gt;Obviously this covers all the typical interactions: Buying a shirt, choosing an &lt;span class=&quot;caps&quot;&gt;XL&lt;/span&gt; size. Reviewing my order before I check out. Paying for my order, getting my order confirmation. Getting a note when my shirt ships. Returning it when I discover the hole in the underarm.  As you can see, this is all part of a&amp;nbsp;process.&lt;/p&gt;
&lt;p&gt;A lot of this typical process is well defined by best practices, and implemented in (almost) every sort of e-commerce platform. So why do we need to consider&amp;nbsp;Tryton?&lt;/p&gt;
&lt;p&gt;The problem is that my process, or your process, might actually be different. In fact, I can say my process is definitely different - I&amp;#8217;m not selling shirts, or widgets, or anything concrete. I sell services as diverse as disinfecting a compromised web server to building an e-commerce web site. Many of my sales are projects, made up of milestones and tasks and billing stages. Sure, when I order a shirt online I might wish to see when it&amp;#8217;s going to ship, but when my customer orders a web site, she might wish to see where we&amp;#8217;re at in the process of producing&amp;nbsp;it. &lt;/p&gt;
&lt;p&gt;My work is not unique in its e-commerce needs. Heck, my field isn&amp;#8217;t even unique. Just about everyone who sells anything other than widgets online needs something that&amp;#8217;s either custom, or developed special for their vertical market. Lawyers, doctors, veternarians, carpet cleaners, housekeepers, daycare providers, doggie daycare providers, landscapers, painters, roofers, artists, appliance repair persons, gutter cleaners, chimney sweeps, &lt;span class=&quot;caps&quot;&gt;HVAC&lt;/span&gt; cleaners, pest control applicators, plumbers, electricians, home theater installers, home automation designers, car mechanics, small engine mechanics, massage therapists, optomotrists, window cleaners, holiday window painters, office plant carepeople, office fish carepeople, snow removers, community theater, professional theater, cinema, parking space rental, storage space rental, apartment rental, house rental, hoteliers and moteliers, concierge and personal assistants - the list goes&amp;nbsp;on.&lt;/p&gt;
&lt;p&gt;Why can&amp;#8217;t I pay my rent online? Schedule my car service? Schedule a gutter cleaning, a chimney cleaning, and a tooth cleaning - all for the same day? After all, I can practically watch Domino&amp;#8217;s make my pizza with their new&amp;nbsp;system.&lt;/p&gt;
&lt;h2&gt;E-commerce is the &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt;&amp;nbsp;interface&lt;/h2&gt;
&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; is a system that manages documents as they progress through a pre-defined process. The documents very often represent something else &amp;mdash; a purchase order represents some product that needs to be received and paid for, a sales order represents a set of products that need to be shipped and paid for, a work order represents some raw product that will be transformed into something new. We call the process they go through&amp;nbsp;&amp;#8220;workflow&amp;#8221;. &lt;/p&gt;
&lt;p&gt;The more accurately we model the real world with our &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; analogs, the more accurate the information we retrieve from the &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; will be. If we count incoming deliveries before marking an order received, we&amp;#8217;ll probably have better inventory numbers and fewer overcharges from vendors. If we eschew back door sales, chances are good our sales figures will be closer to reality and more profitable&amp;nbsp;too.&lt;/p&gt;
&lt;p&gt;Normally speaking, our customer doesn&amp;#8217;t have much more access to our &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; system than glancing at my screen as I fill out their order. That is, until we connect a website to it, and then much of the interaction they have is - or should be, as I propose - interfaced to the&amp;nbsp;&lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s start at the beginning with a brand new customer, and fictitious business called Hearty Dog Treats that sells natural treats for dogs. Jane Doe goes shoppping for some new treats for her Newfoundland (his name is Jayne, but he&amp;#8217;s named for Jayne Cobb from Firefly and Serenity, not because it sounds just like Jane&amp;#8217;s name) and she finds Hearty Dog Treats through a series of fortuitous events. Here is her process, and how it could and should represent an interface tightly integrated with&amp;nbsp;&lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Jane visits the home page of the website to see who the company is. A sidebar advertisement is promoting 12&amp;#8221; bully sticks.&lt;sup id=&quot;fnref:bully&quot;&gt;&lt;a href=&quot;#fn:bully&quot; rel=&quot;footnote&quot;&gt;7&lt;/a&gt;&lt;/sup&gt; This advertisement might be promoted based on an overstock, or special pricing received, or other condition modeled within the&amp;nbsp;&lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;Jane clicks through to the product page for bully sticks. She reads the ingredients (wow - she didn&amp;#8217;t realize what they were actually made of!) She looks at the price and stock status. The three primary pieces of information Jane pursued all come from the &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; system. A food&amp;#8217;s ingredient list really must be kept up to date and managed in a system that allows for appropriate controls and distribution. Something like an &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; system would work. The stock status is certainly derived from the &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt;&amp;#8217;s inventory of bully sticks. And Jane&amp;#8217;s price comes from the default web pricelist. Too bad she&amp;#8217;s not a repeat customer or a dealer - she could create an account on the website, and get access to better pricing. &lt;em&gt;Her&lt;/em&gt;&amp;nbsp;pricing.&lt;/li&gt;
&lt;li&gt;Jane is actually looking for duck hearts. She returns to the &amp;#8220;Treats&amp;#8221; section of the catalog. The catalog as a whole, and the navigation for it, may very well come directly from the &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; system. Indeed, if Hearty Dog Treats maintains multiple sales channels (say, online sales, a print catalog, and flyers to hand out at dog shows) they might wish to maintain the official copy for marketing materials in the &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; system as well, associated directly with the product or product line. Besides, the high school kids with the after school jobs running a point of sale terminal at Hearty Dog Treats&amp;#8217; retail location doesn&amp;#8217;t know much about the product, so putting good product information into the &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; system will help them make the sale&amp;nbsp;too.&lt;/li&gt;
&lt;li&gt;Jane clicks through to Freeze Dried Duck Hearts. (These are real, by the way.&lt;sup id=&quot;fnref:fddh&quot;&gt;&lt;a href=&quot;#fn:fddh&quot; rel=&quot;footnote&quot;&gt;8&lt;/a&gt;&lt;/sup&gt; I often claim that either of my Basset hounds would balance a piano on their nose for a freeze-dried duck heart.) See step 2&amp;nbsp;above.&lt;/li&gt;
&lt;li&gt;Jane decides to buy. She fills out her order and submits it. She&amp;#8217;s just created a new document in the &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; system and started the process of filling an&amp;nbsp;order.&lt;/li&gt;
&lt;li&gt;Jane gets a confirmation email from the &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; system. She clicks the link and sees that her order has been picked from inventory and moved to shipping. She thinks to herself how cool it is to be able to see the progress of her&amp;nbsp;order.&lt;/li&gt;
&lt;li&gt;When Jane&amp;#8217;s order is ready to ship, the &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; system captures her credit card funds. Sure, it used to be that e-commerce systems grabbed the money when the order came in, regardless of whether it could ever be filled, but today&amp;#8217;s system knows it&amp;#8217;s better all around to charge for what you&amp;#8217;re shipping, not what you hope to ship as soon as&amp;nbsp;possible.&lt;/li&gt;
&lt;li&gt;Jane receives an email that her order has shipped, containing a tracking number so that she can check the progress of her delivery. She does. The truck is out for&amp;nbsp;delivery.&lt;/li&gt;
&lt;li&gt;The day after delivery, she gets an email from Hearty Dog Treats&lt;sup id=&quot;fnref:hearty&quot;&gt;&lt;a href=&quot;#fn:hearty&quot; rel=&quot;footnote&quot;&gt;9&lt;/a&gt;&lt;/sup&gt; saying she should have received her order, and asking if everything okay with it. It also suggests she might want to subscribe to their email newsletter, or follow them on Twitter, or fan them on Facebook. In fact, maybe Jane would like to click the link below and share Hearty Dog Treats with her friends on Twitter and&amp;nbsp;Facebook.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Every step of Jane&amp;#8217;s order interfaced with the &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; system. Many, many websites work this way, but far from all of them. Most tier 3 and 4 businesses aren&amp;#8217;t running &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; at all. They&amp;#8217;re getting by on Quickbooks, Peachtree, or sometimes even the shoebox accounting method. Many e-commerce systems don&amp;#8217;t connect to any &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; system, or even to Quickbooks. Since that is the case, some companies actually use their e-commerce &lt;em&gt;as an &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; package&lt;/em&gt; even though the design is weak at&amp;nbsp;best.&lt;/p&gt;
&lt;p&gt;That brings us to the next point: &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; is the company&amp;#8217;s interface to the e-commerce&amp;nbsp;system.&lt;/p&gt;
&lt;h2&gt;&lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; is the e-commerce&amp;nbsp;interface&lt;/h2&gt;
&lt;p&gt;It stands to reason that, if &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; is the flip side of the e-commerce coin, the e-commerce is the flip side of the &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; coin too, right? (If not, that would make a cool magic&amp;nbsp;trick&amp;#8230;)&lt;/p&gt;
&lt;p&gt;For each step Jane when through, there were one or more steps that Hearty Dog Treats went through as well. They need to order the product and have some in stock. They need to process her order and issue a pull slip or pick ticket or delivery order or whatever Hearty Dog Treats is using to represent a stock move from inventory to shipping to the customer. They need to order more stock, if their inventory has fallen below the trigger point. They need to reconcile her payment on the back account. All of these tasks are triggered by, and performed in their &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt;&amp;nbsp;system.&lt;/p&gt;
&lt;p&gt;In fact, the reason Hearty Dog Treats has &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; is so that these processes can be automated as much as possible. Hearty Dog Treats wants things to run smoothly and profitably, even when the boss is&amp;nbsp;away.&lt;/p&gt;
&lt;h2&gt;Wow, so Tryton can do all&amp;nbsp;this?&lt;/h2&gt;
&lt;p&gt;Nope.&lt;/p&gt;
&lt;p&gt;Tryton can&amp;#8217;t do it. OpenERP can&amp;#8217;t do it. Magento can&amp;#8217;t do it. Quickbooks, Peachtree, Sage &amp;mdash; I don&amp;#8217;t really think any &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; or accounting system, open or closed source, &lt;em&gt;designed for small business,&lt;/em&gt; can do what I&amp;#8217;m describing. (If you think I&amp;#8217;m wrong about this, comment or tweet at me right away. I don&amp;#8217;t want to redesign the wheel. I do want a system that does all of this, scales down to a mom-and-pop shop and up to tens of thousands of products and&amp;nbsp;customers.)&lt;/p&gt;
&lt;p&gt;I can&amp;#8217;t let that sit. I feel like those statements need to be expanded upon. I hear someone saying, &amp;#8220;There&amp;#8217;s someone wrong on the Internet! He uses the handle&amp;nbsp;Version2beta!&amp;#8221;&lt;/p&gt;
&lt;p&gt;First, Tryton can do it, because Tryton is a framework for developing business applications. Given a framework and a developer, much can be done. It&amp;#8217;s my opinion after months of planning this project that Tryton can do it well. Nonetheless, Tryton cannot do it&amp;nbsp;yet.&lt;/p&gt;
&lt;p&gt;According to OpenERP &lt;span class=&quot;caps&quot;&gt;SA&lt;/span&gt;, OpenERP will integrate with a number of popular open source e-commerce platforms, including OSCommerce, Magento, and Joomla.&lt;sup id=&quot;fnref:oerp1&quot;&gt;&lt;a href=&quot;#fn:oerp1&quot; rel=&quot;footnote&quot;&gt;10&lt;/a&gt;&lt;/sup&gt; And they do - I know some of the people who have worked on the Magento Connector.&lt;sup id=&quot;fnref:oerp2&quot;&gt;&lt;a href=&quot;#fn:oerp2&quot; rel=&quot;footnote&quot;&gt;11&lt;/a&gt;&lt;/sup&gt; In the very next paragraph of the same page, OpenERP says that &amp;#8220;to benefit from all the power of OpenERP &amp;#8230; you can also use our own eCommerce system that automatically plugs in an existing website. Add a few lines of &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; in your website and OpenERP converts it to a full featured eCommerce platform.&amp;#8221;&lt;sup id=&quot;fnref:oerp3&quot;&gt;&lt;a href=&quot;#fn:oerp3&quot; rel=&quot;footnote&quot;&gt;12&lt;/a&gt;&lt;/sup&gt; The rest of the page lists cool things you can do, a broken image link, and some comments from visitors asking how. If you dig deeper into their site, you can find the e-commerce module, version 5.0.1.0 (which often indicates it is a module for OpenERP version 5, even though it&amp;#8217;s listed under OpenERP version 6). This module is not an official module, not quality certified, and reimplements Partner, Address, Payment, Shop, Category, Sale Order, and Order Line &amp;mdash; all standard OpenERP objects &amp;mdash; in order to achieve e-commerce. And so I hold that OpenERP cannot do&amp;nbsp;this.&lt;/p&gt;
&lt;p&gt;Magento can&amp;#8217;t do this.&lt;sup id=&quot;fnref:magento&quot;&gt;&lt;a href=&quot;#fn:magento&quot; rel=&quot;footnote&quot;&gt;13&lt;/a&gt;&lt;/sup&gt; Now that they&amp;#8217;ve been bought by eBay, Magento is doing a lot of cool things, and it would not surprise me if they moved in this direction down the road. (I&amp;#8217;m certain many companies will.) They&amp;#8217;re even providing a &lt;span class=&quot;caps&quot;&gt;US&lt;/span&gt;$1 million stimulus to encourage small business e-commerce.&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;Quickbooks might be able to do it, if you go for the Enterprise version and add on third party software. It&amp;#8217;s my impression (earned in part by having used Quickbooks) that it&amp;#8217;s a great accounting package for small businesses, but the software&amp;#8217;s enterprise features are flawed with usability issues. Then there&amp;#8217;s the third party problem for the e-commerce software - how integrated is it with Quickbooks? Both Quickbooks and the e-commerce package are proprietary; how well are they kept in sync? Is the quality of the code there? I&amp;#8217;m not trying to engage in &lt;span class=&quot;caps&quot;&gt;FUD&lt;/span&gt;&lt;sup id=&quot;fnref:fud&quot;&gt;&lt;a href=&quot;#fn:fud&quot; rel=&quot;footnote&quot;&gt;15&lt;/a&gt;&lt;/sup&gt; &amp;mdash; I&amp;#8217;d be thrilled to hear about a solid Quickbooks e-commerce solution that goes beyond widgets. Let me know and I will list it right&amp;nbsp;here.&lt;/p&gt;
&lt;p&gt;Peachtree can&amp;#8217;t do it &amp;mdash; or if it can, we&amp;#8217;re looking at the same situation as Quickbooks at best. But Peachtree&amp;#8217;s parent company, Sage, can do it. Once again, though, you need to use their proprietary module (eBusiness Web Services) combined with a third party e-commerce application.&lt;sup id=&quot;fnref:sage&quot;&gt;&lt;a href=&quot;#fn:sage&quot; rel=&quot;footnote&quot;&gt;16&lt;/a&gt;&lt;/sup&gt; Besides, Sage is pretty pricey for a small business. We had a customer gut OpenERP (and us, along with it) and put in Sage. Rumor has it the licenses alone were more than &lt;span class=&quot;caps&quot;&gt;US&lt;/span&gt;$80,000, plus integration, plus e-commerce software and&amp;nbsp;hosting.&lt;/p&gt;
&lt;p&gt;Netsuite can probably do it. With Netsuite Ecommerce, a lot of set-up, and &lt;span class=&quot;caps&quot;&gt;US&lt;/span&gt;$1,200 a month, a mom-and-pop shop can sell widgets online and get the benefit of Netsuite&amp;#8217;s accounting, finance, and supply chain management. At that price, it is probably affordable for a business doing a million a year in sales. (Mom and pop are good at this widget&amp;nbsp;business.)&lt;/p&gt;
&lt;p&gt;You know who can do it, with open source software even? Apache OFBiz.&lt;sup id=&quot;fnref:ofbiz&quot;&gt;&lt;a href=&quot;#fn:ofbiz&quot; rel=&quot;footnote&quot;&gt;17&lt;/a&gt;&lt;/sup&gt; Honestly I know very little about OFBiz (which stands for &amp;#8220;Open For Business&amp;#8221;), but it clearly does a lot, and if you&amp;#8217;re looking for a community open source &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; project that does web e-commerce right now, this might be your choice. If you use it, let me know what you&amp;nbsp;think?&lt;/p&gt;
&lt;h2&gt;What does Tryton&amp;nbsp;need?&lt;/h2&gt;
&lt;p&gt;I think Tryton needs a web&amp;nbsp;framework.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m somewhat at odds with Cédric Krier&lt;sup id=&quot;fnref:cedrick&quot;&gt;&lt;a href=&quot;#fn:cedrick&quot; rel=&quot;footnote&quot;&gt;19&lt;/a&gt;&lt;/sup&gt; on this, I know. We&amp;#8217;ve chatted on &lt;span class=&quot;caps&quot;&gt;IRC&lt;/span&gt;, and he assures me that Tryton doesn&amp;#8217;t need a full framework; &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt;&lt;sup id=&quot;fnref:jsonrpc&quot;&gt;&lt;a href=&quot;#fn:jsonrpc&quot; rel=&quot;footnote&quot;&gt;18&lt;/a&gt;&lt;/sup&gt; is enough. And he&amp;#8217;s right - &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt; is enough. Tryton itself is a framework, and with an easily implemented interface like &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt;, one can do all I describe above. But unless there&amp;#8217;s something on the other end of the &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt;, it&amp;#8217;s useless to my customers, and in turn useless to my customers&amp;#8217;&amp;nbsp;customers. &lt;/p&gt;
&lt;p&gt;Cédric&amp;#8217;s &amp;#8220;something on the other end of the &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt;&amp;#8221; approach puts Tryton as a rather smart back end to a web application (any application, really - I can totally see using it behind an Android or iPhone app), without building an actual framework into Tryton. But I&amp;#8217;m not sure that a real web framework built into Tryton wouldn&amp;#8217;t be very, very useful. I have ideas on how to do this, involving some of my favorite tech tools - MongoDB&lt;sup id=&quot;fnref:mongo&quot;&gt;&lt;a href=&quot;#fn:mongo&quot; rel=&quot;footnote&quot;&gt;20&lt;/a&gt;&lt;/sup&gt;, Jinja2&lt;sup id=&quot;fnref:jinja2&quot;&gt;&lt;a href=&quot;#fn:jinja2&quot; rel=&quot;footnote&quot;&gt;21&lt;/a&gt;&lt;/sup&gt; or Restructured Text&lt;sup id=&quot;fnref:rst&quot;&gt;&lt;a href=&quot;#fn:rst&quot; rel=&quot;footnote&quot;&gt;22&lt;/a&gt;&lt;/sup&gt;, maybe a little Flask&lt;sup id=&quot;fnref:flask&quot;&gt;&lt;a href=&quot;#fn:flask&quot; rel=&quot;footnote&quot;&gt;24&lt;/a&gt;&lt;/sup&gt; action. Some Redis&lt;sup id=&quot;fnref:redis&quot;&gt;&lt;a href=&quot;#fn:redis&quot; rel=&quot;footnote&quot;&gt;25&lt;/a&gt;&lt;/sup&gt; and Celery&lt;sup id=&quot;fnref:celery&quot;&gt;&lt;a href=&quot;#fn:celery&quot; rel=&quot;footnote&quot;&gt;26&lt;/a&gt;&lt;/sup&gt; to make sure we never ask Tryton to try too&amp;nbsp;hard.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m certain this can be done. I&amp;#8217;m pretty sure I can do it. I strongly suspect it&amp;#8217;s already been done by at least one company, for private&amp;nbsp;use.&lt;/p&gt;
&lt;h2&gt;A Tryton web&amp;nbsp;framework&lt;/h2&gt;
&lt;p&gt;When I first started this blog post almost two months ago, my work life was considerably different than it is right now. At that time, I thought I may be days from starting the web framework project for at least one, and maybe two different&amp;nbsp;customers. &lt;/p&gt;
&lt;p&gt;Hell, when I first started this series of blog posts on Tryton as an e-commerce back-end, I thought I&amp;#8217;d have a Tryton-based e-commerce platform done by now. Funny, that. But then life knocked on my door - kicked it in, more like. Among other things, I worked with one of the best Tryton programmers in the world for nearly 40 hours straight, and at the end of it, I had lost my biggest customer. (Correlation, not causation - he didn&amp;#8217;t steal my customer or anything like&amp;nbsp;that.)&lt;/p&gt;
&lt;p&gt;I still have prospects for using Tryton as an e-commerce back end. If any of them come through I may continue the series. Until then I hope it&amp;#8217;s been a useful&amp;nbsp;discussion.&lt;/p&gt;
&lt;h3&gt;What else is&amp;nbsp;there?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://version2beta.com/archive/2011/evaluating-tryton-as-an-ecommerce-backend_about-tryton.html&quot; title=&quot;Evaluation Tryton as an e-commerce back-end: Stalking the Tryton community&quot;&gt;Part 1: About Tryton&lt;/a&gt;. An overview of Tryton – architecture,
    business model, features,&amp;nbsp;license.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://version2beta.com/archive/2011/evaluating-tryton-as-an-ecommerce-backend_stalking-the-tryton-community.html&quot; title=&quot;Evaluation Tryton as an e-commerce back-end: Stalking the Tryton community&quot;&gt;Part 2: Stalking the Tryton community&lt;/a&gt;. There are some
    impressive people working on this project. I’m pleased to get to
    know&amp;nbsp;them.&lt;/li&gt;
&lt;li&gt;Part 3: The crux of the matter. What
    does a Tryton-backed e-commerce system need to&amp;nbsp;do?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;If I’ve inspired a response from you (probably the type of response that deserves an apology), mention &lt;a href=&quot;http://twitter.com/version2beta&quot; title=&quot;Me, twitterfied&quot;&gt;@version2beta&lt;/a&gt; on &lt;a href=&quot;http://twitter.com/&quot; title=&quot;All of twitter, including me.&quot;&gt;Twitter&lt;/a&gt; and I’ll see it there. Or, if you can’t comment in less than 126 characters (my handle takes 14 characters with a space), blog about it and tweet&amp;nbsp;that.&lt;/em&gt;&lt;/p&gt;

   </content></entry><entry><title>DjangoCon, part four</title><author><name>Rob Martin</name></author><link href="http://www.version2beta.com/archive/2011/djangocon-part-four.html"/><updated>2011-09-11T16:55:00Z</updated><published>2011-09-11T16:55:00Z</published><id>http://www.version2beta.com/archive/2011/djangocon-part-four.html</id><content type="html">
       
&lt;!-- Hyde::Excerpt::Begin --&gt;

&lt;p&gt;Here&amp;#8217;s the recap of day three, the last day of the talks. Apparently I took good notes on day three, since this is by far the longest post, and the one it took me longest to produce. It was, indubitably, an excellent&amp;nbsp;day.&lt;/p&gt;
&lt;!-- Hyde::Excerpt::End --&gt;

&lt;h2&gt;DjangoCon&amp;nbsp;agenda&lt;/h2&gt;
&lt;h3&gt;Keynote: Glyph Lefkowitz on Why does Django hate&amp;nbsp;Python&lt;/h3&gt;
&lt;p&gt;In 2008 Cal Henderson gave a DjangoCon speech entitled &amp;#8220;Why I Hate Django&amp;#8221;. Apparently it provided an opportunity for Django core developers to demonstrate gracefulness and generosity. The speech has also created a legacy. 2011&amp;#8217;s Why I Hate Django keynote was given by Glyph Lefkowitz, founder of the Twisted framework project. Glyph&amp;#8217;s particular flavor was not why he hates Django (indeed, he&amp;#8217;d only tried to install it once before writing the speech) but why Django hates Python. His premise is that, if Django didn&amp;#8217;t hate Python, we might start using more Python (and fewer tools that are not based on Python.) &amp;#8220;It is not enough that your system be well designed. It needs to be consistently designed as&amp;nbsp;well.&amp;#8221;&lt;/p&gt;
&lt;p&gt;In order to assist Djangonauts and developers in moving toward a more Pythonic environment, Glyph recommended a number of projects we might wish to consider. It may be more accurate to say that Glyph challenged the Django community to use more Python, including these projects. (I&amp;#8217;m breaking my style guideline on footnotes over in-line links for this list, since it&amp;#8217;s basically a list of&amp;nbsp;links.)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fabric: &lt;a href=&quot;http://www.fabfile.org&quot; title=&quot;Fabric&quot;&gt;Fabric&lt;/a&gt; is a library and framework for performing systems administration tasks, both locally and over a network using &lt;span class=&quot;caps&quot;&gt;SSH&lt;/span&gt;. I&amp;#8217;d heard of Fabric prior to DjangoCon, but not used it. Using Fabric will be one of the key benefits I got from this year&amp;#8217;s&amp;nbsp;conference.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;WSGI&lt;/span&gt; and Web servers&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;FAPWS&lt;/span&gt;: &lt;span class=&quot;caps&quot;&gt;FAPWS&lt;/span&gt; stands for &lt;a href=&quot;http://www.fapws.org/&quot; title=&quot;FAPWS Fast Asynchronous Python Web Server&quot;&gt;Fast Asynchronous Python Web Server&lt;/a&gt;. It&amp;#8217;s &lt;span class=&quot;caps&quot;&gt;WSGI&lt;/span&gt;-compliant with two primary goals: keep it small, and keep it&amp;nbsp;asynchronous.&lt;/li&gt;
&lt;li&gt;Spawning: &lt;a href=&quot;http://pypi.python.org/pypi/Spawning/0.7&quot; title=&quot;PyPi page on spawning&quot;&gt;Spawning&lt;/a&gt; is a multi-process, multi-threaded, non-blocking &lt;span class=&quot;caps&quot;&gt;WSGI&lt;/span&gt; compliant web server. Eric Florenzano wrote about &lt;a href=&quot;http://www.eflorenzano.com/blog/post/spawning-django/&quot; title=&quot;Using Spawning and Django together from Eric Florenzano&#39;s blog&quot;&gt;using Spawning and Django together&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Tornado: &lt;a href=&quot;http://www.tornadoweb.org/&quot; title=&quot;Scalable, non-blocking web server written in Python&quot;&gt;Tornado&lt;/a&gt; is the open-source version of a Web server written to run &lt;a href=&quot;http://friendfeed.com/&quot; title=&quot;FriendFeed&#39;s web site&quot;&gt;FriendFeed&lt;/a&gt;. It is non-blocking, relatively fast, and includes some of the tools they use at&amp;nbsp;FriendFeed.&lt;/li&gt;
&lt;li&gt;Gunicorn: &lt;a href=&quot;http://gunicorn.org/&quot; title=&quot;Prefork worker model web server&quot;&gt;Gunicorn&lt;/a&gt; is a Python fork of the &lt;a href=&quot;http://unicorn.bogomips.org/&quot; title=&quot;Ruby Unicorn project&quot;&gt;Ruby Unicorn project&lt;/a&gt;, a prefork worker model &lt;span class=&quot;caps&quot;&gt;WSGI&lt;/span&gt; web&amp;nbsp;server.&lt;/li&gt;
&lt;li&gt;Cogen: &lt;a href=&quot;http://code.google.com/p/cogen/&quot; title=&quot;Python-based WSGI web server&quot;&gt;Cogen&lt;/a&gt; is a library for network programming using coroutines via enhanced generators. I don&amp;#8217;t understand it either, but it provides a &lt;span class=&quot;caps&quot;&gt;WSGI&lt;/span&gt; server and is&amp;nbsp;asynchronous.&lt;/li&gt;
&lt;li&gt;Twisted Web: &lt;a href=&quot;http://twistedmatrix.com/trac/wiki/TwistedWeb&quot; title=&quot;Web component of the Twisted Matrix event-driven network engine&quot;&gt;Twisted Web&lt;/a&gt; is the &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; portion of Twisted, an event-driven networking engine.&lt;sup id=&quot;fnref:twisted&quot;&gt;&lt;a href=&quot;#fn:twisted&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; It may be important to note that this is the project that Glyph&amp;nbsp;heads.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Lamson Project: &lt;a href=&quot;http://lamsonproject.org/&quot; title=&quot;Python SMTP server&quot;&gt;Lamson&lt;/a&gt; is a Python-based &lt;span class=&quot;caps&quot;&gt;MTA&lt;/span&gt;, &lt;span class=&quot;caps&quot;&gt;SMTP&lt;/span&gt; server and library. While that probably says enough, I want to add it can use anything Python can use for storing it&amp;#8217;s data, which of course includes the Django &lt;span class=&quot;caps&quot;&gt;ORM&lt;/span&gt; as well as CouchDB, MongoDB, and many other options. I&amp;#8217;m pretty excited about&amp;nbsp;Lamson.&lt;/li&gt;
&lt;li&gt;PyDNS: &lt;a href=&quot;http://pydns.sourceforge.net/&quot; title=&quot;Python DNS library&quot;&gt;PyDNS&lt;/a&gt; is a Python library for performing &lt;span class=&quot;caps&quot;&gt;DNS&lt;/span&gt;&amp;nbsp;lookups.&lt;/li&gt;
&lt;li&gt;PyCron: Glyph, maybe you were just stretching at this point, looking for more applications? I found two pycrons. Neither are in PyPi. One doesn&amp;#8217;t seem to include source. &lt;a href=&quot;http://pycron.sourceforge.net/&quot; title=&quot;Python cron engine&quot;&gt;Here is the&amp;nbsp;other.&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Python Sched library: &lt;a href=&quot;http://docs.python.org/library/sched.html&quot; title=&quot;Python event scheduler library&quot;&gt;sched&lt;/a&gt; is the Python event scheduler&amp;nbsp;library.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Glyph had much more to say in his keynote, much of it about the overall monolithic structure of Django. Really, I think it boils down to &amp;#8220;Django is not particularly Pythonic.&amp;#8221; But that&amp;#8217;s beyond my pay grade right now &amp;mdash; I am improving my Django skills so that might work with more customers. I am not asking to join the core development team in planning Django 2.0.&lt;sup id=&quot;fnref:django2.0&quot;&gt;&lt;a href=&quot;#fn:django2.0&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h3&gt;Advanced django&amp;nbsp;forms&lt;/h3&gt;
&lt;p&gt;Danny Greenfeld and Miguel Araujo proposed and then demonstrated a more thoughtful application of The Zen of Python&lt;sup id=&quot;fnref:zen&quot;&gt;&lt;a href=&quot;#fn:zen&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; and Spartan Programming&lt;sup id=&quot;fnref:spartan&quot;&gt;&lt;a href=&quot;#fn:spartan&quot; rel=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; to Django forms. Some key points for&amp;nbsp;me:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Limit vertical&amp;nbsp;complexity&lt;/li&gt;
&lt;li&gt;Limit&amp;nbsp;conditionals&lt;/li&gt;
&lt;li&gt;Flat is better than&amp;nbsp;nested&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A few more notes I took for making Django forms easier for me in the&amp;nbsp;future:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;See &lt;a href=&quot;http://jacobian.org/writing/dynamic-form-generation/&quot; title=&quot;Jacob Kaplan-Moss provides a description of how Django might handle dynamic forms&quot;&gt;Jacob Kaplan-Moss&amp;#8217; post on Dynamic Form&amp;nbsp;Generation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Check out &lt;a href=&quot;http://readthedocs.org/docs/django-uni-form/en/latest/&quot; title=&quot;django-uni-form at Read the Docs&quot;&gt;django-uni-forms&lt;/a&gt;, especially since it is Section 508&amp;nbsp;compliant&lt;/li&gt;
&lt;li&gt;Also look at &lt;a href=&quot;http://django-floppyforms.readthedocs.org/en/latest/&quot; title=&quot;dango-floppyforms at Read the Docs&quot;&gt;django-floppyforms&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;http://www.slideshare.net/pydanny/advanced-django-forms-usage&quot;&gt;Danny Greenfeld and Miguel Araujo&amp;#8217;s&amp;nbsp;slides&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Teaching Django to&amp;nbsp;comrades&lt;/h3&gt;
&lt;p&gt;Issac Kelly gave some excellent starting advice, which is good since I&amp;#8217;m still starting in many&amp;nbsp;ways.&lt;/p&gt;
&lt;p&gt;Some key&amp;nbsp;troublespots:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The&amp;nbsp;&lt;span class=&quot;caps&quot;&gt;ORM&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Reverse&amp;nbsp;relations&lt;/li&gt;
&lt;li&gt;Migrations&lt;/li&gt;
&lt;li&gt;Forms, forms,&amp;nbsp;forms&lt;/li&gt;
&lt;li&gt;Signals&lt;/li&gt;
&lt;li&gt;URLs&lt;/li&gt;
&lt;li&gt;Deployment&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of course, it might have been easier to list the areas that are not key&amp;nbsp;troublespots&amp;#8230;&lt;/p&gt;
&lt;p&gt;I particularly liked Issac&amp;#8217;s&amp;nbsp;Axioms:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;There is a method for that. Corollary: If you&amp;#8217;re new and it&amp;#8217;s hard, you&amp;#8217;re probably doing it&amp;nbsp;wrong.&lt;/li&gt;
&lt;li&gt;There is a Django way of doing this. Corollary: Don&amp;#8217;t fight the system until you are assured of&amp;nbsp;victory.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Deployment, daemons, and&amp;nbsp;datacenters&lt;/h3&gt;
&lt;p&gt;I wasn&amp;#8217;t sure if I&amp;#8217;d need to read five years of Andrew Godwin&amp;#8217;s blog in order to describe him well enough. He is young and brilliant, in a polite, relatively unassuming way. I like Andrew; he impresses me. And his presentation was good too &amp;mdash; solid mechanics and good advice, some of which I&amp;nbsp;recorded:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ep.io&amp;#8217;s standard stack is nginx (for static files and gzipping), gunicorn, postgres 9, redis, and&amp;nbsp;virtualenv&lt;/li&gt;
&lt;li&gt;For higher loads, Andrew says:&lt;ul&gt;
&lt;li&gt;Use Varnish or other upstream&amp;nbsp;caching&lt;/li&gt;
&lt;li&gt;Use HAProxy or nginx for load&amp;nbsp;balancing&lt;/li&gt;
&lt;li&gt;Give PostgreSQL more&amp;nbsp;resources&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Keep staging identical to&amp;nbsp;production&lt;/li&gt;
&lt;li&gt;Redis is easy to setup and&amp;nbsp;use&lt;/li&gt;
&lt;li&gt;Ship long-running tasks off. Use Celery or a worker&amp;nbsp;solution.&lt;/li&gt;
&lt;li&gt;Don&amp;#8217;t use SQLite in&amp;nbsp;production&lt;/li&gt;
&lt;li&gt;Use&amp;nbsp;transactions&lt;/li&gt;
&lt;li&gt;Plan so you can always add another&amp;nbsp;machine.&lt;/li&gt;
&lt;li&gt;Keep things loosely coupled - simple components loosely connected are easy to&amp;nbsp;troubleshoot&lt;/li&gt;
&lt;li&gt;Anything you&amp;#8217;ve done at least three times should be&amp;nbsp;automated&lt;/li&gt;
&lt;li&gt;ZeroMQ is really, really nice to&amp;nbsp;have.&lt;/li&gt;
&lt;li&gt;MongoDB and Redis will both lose data when they are running low on disk&amp;nbsp;space.&lt;/li&gt;
&lt;li&gt;Regarding backups and redundancy&lt;ul&gt;
&lt;li&gt;A Postgres slave is not a&amp;nbsp;backup&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;RAID&lt;/span&gt; is not a&amp;nbsp;backup&lt;/li&gt;
&lt;li&gt;Backup in multiple forms at diverse&amp;nbsp;locations&lt;/li&gt;
&lt;li&gt;Make sure you can restore from backup on a somewhat regular&amp;nbsp;basis&lt;/li&gt;
&lt;li&gt;Always make the backup machine pull the backups, not production&amp;nbsp;push&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I didn&amp;#8217;t know about that last one. In fact, for much of my backup process that wouldn&amp;#8217;t work - Amazon S3, for example, cannot pull files. But I&amp;#8217;m curious about&amp;nbsp;this.&lt;/p&gt;
&lt;p&gt;I don&amp;#8217;t know that Andrew exactly promoted this, but I put in my notes to make backups progressive. I&amp;#8217;ve thought of this before, too. Perhaps ep.io is doing it. Here is a progressive schedule of backups to&amp;nbsp;keep:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First of&amp;nbsp;year&lt;/li&gt;
&lt;li&gt;First of&amp;nbsp;month&lt;/li&gt;
&lt;li&gt;First of&amp;nbsp;week&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Content ain&amp;#8217;t a thing: web&amp;nbsp;scraping&lt;/h3&gt;
&lt;p&gt;I missed the first half of this session, and decided not to take notes on the second half. While much of what the presenter offered was technically interesting, I found myself increasingly bothered by the blasé disregard for intellectual property rights on the web. It&amp;#8217;s not that the speaker did not give some homage to the concept, just that a cultivated ability to split hairs was obviously a part of her professional&amp;nbsp;upbringing.&lt;/p&gt;
&lt;p&gt;So no further notes on the&amp;nbsp;topic.&lt;/p&gt;
&lt;h3&gt;Cache rules everything around&amp;nbsp;me&lt;/h3&gt;
&lt;p&gt;Especially on Thursday, the last day of talks, there were quite a few tag-team presentations. Some of them were so highly tuned, they finished each other&amp;#8217;s sentences. Each one I saw was&amp;nbsp;impressive.&lt;/p&gt;
&lt;p&gt;Jacob Burch and Noah Silas presented on caching. Jacob works with Frank Wiles and now Jacob Kaplan-Moss at Revolution Systems. I don&amp;#8217;t actually know where Noah is from, but he certainly knew his stuff&amp;nbsp;too.&lt;/p&gt;
&lt;p&gt;First, I liked the&amp;nbsp;warnings.&lt;/p&gt;
&lt;p&gt;Don&amp;#8217;t&amp;nbsp;cache: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Caching adds complexity. Don&amp;#8217;t do&amp;nbsp;it.&lt;/li&gt;
&lt;li&gt;Caching adds additional points of failure. Don&amp;#8217;t do&amp;nbsp;it.&lt;/li&gt;
&lt;li&gt;Modern databases are &amp;#8220;stupidly optimized&amp;#8221; (by which they seem to mean fast). Maybe you don&amp;#8217;t even need to cache. Don&amp;#8217;t do&amp;nbsp;it.&lt;/li&gt;
&lt;li&gt;As the quote goes, there are only two hard things in computer science. Naming things and cache invalidation. Don&amp;#8217;t do&amp;nbsp;it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you do&amp;nbsp;cache:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Your application should never ever rely on&amp;nbsp;caching.&lt;/li&gt;
&lt;li&gt;The Super Awesome Fun Time Rule for Minimizing Sadness: You should have one canonical data source, and it is not your&amp;nbsp;cache.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;From here, they went into a number of caching patterns. I&amp;#8217;m not going to translate all my notes here. I took too many for just part of one blog post. Suffice with just a&amp;nbsp;few.&lt;/p&gt;
&lt;p&gt;The &amp;#8220;New Hotness&amp;#8221;&amp;nbsp;model:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cache indefinitely - for as long as the back-end will&amp;nbsp;allow.&lt;/li&gt;
&lt;li&gt;Invalidate explicitly - replace, don&amp;#8217;t&amp;nbsp;delete&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;dquo&quot;&gt;&amp;#8220;&lt;/span&gt;Publish&amp;nbsp;Cache&amp;#8221;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Put entire responses into&amp;nbsp;cache&lt;/li&gt;
&lt;li&gt;Implementation in Django is easy - just drop in&amp;nbsp;middleware&lt;/li&gt;
&lt;li&gt;Cache invalidation is probably easy too, when the blog post, article, etc. is&amp;nbsp;updated&lt;/li&gt;
&lt;li&gt;Might be difficult with dynamic page&amp;nbsp;elements&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Django.core.cache is simple to setup and supports multiple caching backends. Don&amp;#8217;t use these&amp;nbsp;backends:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;db.DatabaseCache&lt;/li&gt;
&lt;li&gt;filebased.FileBasedCache&lt;/li&gt;
&lt;li&gt;locmem.LocMemCache&lt;/li&gt;
&lt;li&gt;dummy.DummyCache&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are&amp;nbsp;okay:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;memcached.MemcachedCache&lt;/li&gt;
&lt;li&gt;memcached.PyLibMCCache&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And these are good for the Publish Cache&amp;nbsp;pattern:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;django.views.decorators.cache.cache_page&lt;/li&gt;
&lt;li&gt;django.middleware.cache.UpdateCacheMiddleware&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Third party enhancements for&amp;nbsp;Django:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;django-newcache&lt;/li&gt;
&lt;li&gt;johnny-cache&lt;/li&gt;
&lt;li&gt;django-cache-machine&lt;/li&gt;
&lt;li&gt;django-autocache&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And finally, they recommend that it might be good to create a &amp;#8220;Does Not Exist&amp;#8221; cache entry, something like &lt;code&gt;!!!DNE!!!&lt;/code&gt;. This can come in handy if you ever get slammed for something that, no matter how many times the back-end is asked for it, you cannot create it. Putting &lt;code&gt;!!!DNE!!!&lt;/code&gt; in cache can prevent the extra load of discovering over and over that it does not&amp;nbsp;exist.&lt;/p&gt;

   </content></entry><entry><title>DjangoCon, part three</title><author><name>Rob Martin</name></author><link href="http://www.version2beta.com/archive/2011/djangocon-part-three.html"/><updated>2011-09-08T07:45:00Z</updated><published>2011-09-08T07:45:00Z</published><id>http://www.version2beta.com/archive/2011/djangocon-part-three.html</id><content type="html">
       
&lt;!-- Hyde::Excerpt::Begin --&gt;

&lt;p&gt;Day two is done, and I&amp;#8217;m trying to do better at this. I definitely have better notes than yesterday. I have slightly fewer of them too, since the South session was absolutely worthless to me, and I blew off Tilting at Windmills to go up to the room with a stomach ache and a customer who needed&amp;nbsp;help.&lt;/p&gt;
&lt;!-- Hyde::Excerpt::End --&gt;

&lt;h2&gt;DjangoCon&amp;nbsp;agenda&lt;/h2&gt;
&lt;p&gt;Here&amp;#8217;s the recap of day&amp;nbsp;two:&lt;/p&gt;
&lt;h3&gt;Lightning&amp;nbsp;talks&lt;/h3&gt;
&lt;p&gt;By the schedule, there were 90 minutes of lightning talks happening in the morning. I guess when 9:&lt;span class=&quot;caps&quot;&gt;00AM&lt;/span&gt; rolled around, there were only three submitted so they postponed the start time. This gave me enough impetus to put together my own, on using Prezi for presentations. Here it is. (This is my first time embedding media in this blog. It may look crappy until I spend more time formatting. If so, please excuse the visual disruption; I will try to make it better&amp;nbsp;soon.)&lt;/p&gt;
&lt;div class=&quot;prezi-player&quot;&gt;&lt;style type=&quot;text/css&quot; media=&quot;screen&quot;&gt;.prezi-player { width: 550px; } .prezi-player-links { text-align: center; }&lt;/style&gt;&lt;object id=&quot;prezi_ntrlqxhxpzbv&quot; name=&quot;prezi_ntrlqxhxpzbv&quot; classid=&quot;clsid:D27CDB6E-AE6D-11cf-96B8-444553540000&quot; width=&quot;550&quot; height=&quot;400&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://prezi.com/bin/preziloader.swf&quot;/&gt;&lt;param name=&quot;allowfullscreen&quot; value=&quot;true&quot;/&gt;&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot;/&gt;&lt;param name=&quot;bgcolor&quot; value=&quot;#ffffff&quot;/&gt;&lt;param name=&quot;flashvars&quot; value=&quot;prezi_id=ntrlqxhxpzbv&amp;amp;lock_to_path=1&amp;amp;color=ffffff&amp;amp;autoplay=no&amp;amp;autohide_ctrls=0&quot;/&gt;&lt;embed id=&quot;preziEmbed_ntrlqxhxpzbv&quot; name=&quot;preziEmbed_ntrlqxhxpzbv&quot; src=&quot;http://prezi.com/bin/preziloader.swf&quot; type=&quot;application/x-shockwave-flash&quot; allowfullscreen=&quot;true&quot; allowscriptaccess=&quot;always&quot; width=&quot;550&quot; height=&quot;400&quot; bgcolor=&quot;#ffffff&quot; flashvars=&quot;prezi_id=ntrlqxhxpzbv&amp;amp;lock_to_path=1&amp;amp;color=ffffff&amp;amp;autoplay=no&amp;amp;autohide_ctrls=0&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class=&quot;prezi-player-links&quot;&gt;&lt;p&gt;&lt;a title=&quot; No description &quot; href=&quot;http://prezi.com/ntrlqxhxpzbv/a-prezi-on-prezi-for-djangocon/&quot;&gt;A Prezi on Prezi for DjangoCon&lt;/a&gt; on &lt;a href=&quot;http://prezi.com&quot;&gt;Prezi&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3&gt;Keynote: Brad&amp;nbsp;Fitzpatrick&lt;/h3&gt;
&lt;p&gt;Laid-back, easy-going guy who receives a lot of emails. Of course, he&amp;#8217;s written some pretty important open source software, like memcached&lt;sup id=&quot;fnref:memcached&quot;&gt;&lt;a href=&quot;#fn:memcached&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;, and an Android app that runs on a server in his garage scanning for his phone&amp;#8217;s &lt;span class=&quot;caps&quot;&gt;SSID&lt;/span&gt; so that when he rides up on his motorcycle it can open the garage door automatically&lt;sup id=&quot;fnref:garage&quot;&gt;&lt;a href=&quot;#fn:garage&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;. &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://bradfitz.com/talks/2011-09-Djangocon/&quot;&gt;Brad Fitzpatrick&amp;#8217;s&amp;nbsp;slides&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Restful &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;&amp;#8217;s, promises and&amp;nbsp;lies&lt;/h3&gt;
&lt;p&gt;Tareque Hossain gave an excellent, easy-to-follow introductory presentation on Django &lt;span class=&quot;caps&quot;&gt;REST&lt;/span&gt; APIs, with illustrations from &lt;span class=&quot;caps&quot;&gt;PBS&lt;/span&gt; children&amp;#8217;s shows. Really - his opening slide had Elmo on it, which was only the start of visuals borrowed from his employer. His technical examples also came from &lt;span class=&quot;caps&quot;&gt;PBS&lt;/span&gt;, of&amp;nbsp;course. &lt;/p&gt;
&lt;p&gt;One cool takeaway: &lt;span class=&quot;caps&quot;&gt;JSONP&lt;/span&gt;&lt;sup id=&quot;fnref:jsonp&quot;&gt;&lt;a href=&quot;#fn:jsonp&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; for sharing APIs across multiple&amp;nbsp;domains.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.slideshare.net/tarequeh/restful-apis-promises-lies&quot;&gt;Tareque Hossain&amp;#8217;s&amp;nbsp;slides&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;A Little South&amp;nbsp;Sanity&lt;/h3&gt;
&lt;p&gt;I really tried to get something out of this session. I can totally see how useful South could be, despite my initial misimpression that it was useful only in the largest, most drawn out installations. Unfortunately, Brian Luft did much of the presentation live at the terminal and it wasn&amp;#8217;t working, so I have no clue which parts were South and which parts were Brian&amp;#8217;s attempts to get it working. It was like I was the customer showing up for training, looking over the lead developer&amp;#8217;s shoulder. Which is something I&amp;#8217;m sure I&amp;#8217;ve done with customers before. Many&amp;nbsp;times.&lt;/p&gt;
&lt;h3&gt;Building APIs with&amp;nbsp;TastyPie&lt;/h3&gt;
&lt;p&gt;Isaac Kelly did in fact convince me I could build an &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; with TastyPie. Someday I&amp;#8217;ll have to prove that,&amp;nbsp;right?&lt;/p&gt;
&lt;p&gt;I hadn&amp;#8217;t known about json.tool for pretty printing &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt; from the command line, but that looks useful&amp;nbsp;too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ echo &#39;{&quot;json&quot;:&quot;obj&quot;}&#39; | python -mjson.tool
{
    &quot;json&quot;: &quot;obj&quot;
{
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Stop Tilting at Windmills: Spotting&amp;nbsp;Bottlenecks&lt;/h3&gt;
&lt;p&gt;By the end of the &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt; session I was already fielding voicemail, email, and text messages from a customer back home. One of us had managed to break his brand new Box.net uploader library.&lt;sup id=&quot;fnref:multiup&quot;&gt;&lt;a href=&quot;#fn:multiup&quot; rel=&quot;footnote&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; I spent the Stop Tilting at Windmills session tilting at&amp;nbsp;windmills.&lt;/p&gt;
&lt;h3&gt;Safely Deploying on the Cutting&amp;nbsp;Edge&lt;/h3&gt;
&lt;p&gt;This session was very cool. Best parts&amp;nbsp;included:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;a good branching model for git&lt;sup id=&quot;fnref:branch&quot;&gt;&lt;a href=&quot;#fn:branch&quot; rel=&quot;footnote&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;a vocabulary of deployment verbs implemented in scripts (pull, build, tag, sync, install, rollback, start, stop, restart,&amp;nbsp;reload)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;a reminder that the startup processes (init.d, upstart, etc) are just processes written by other developers, and sometimes it makes sense to roll your&amp;nbsp;own&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The session next door, &amp;#8220;Best Practices for Front-End Django Developers&amp;#8221;, was clearly very popular as well. Roughly half the conference attendees were in the same session I was. Next door, it sounded like they had about one-and-a-half times as many people&amp;nbsp;clapping.&lt;/p&gt;
&lt;h3&gt;Benevolent Designer For Life&amp;#8217;s Keynote - Designers Make It Go to&amp;nbsp;Eleven&lt;/h3&gt;
&lt;p&gt;Idan is cool, an excellent choice. I&amp;#8217;m guessing that, just as design implements the physical interface between human and machine - where the skin meets metal - Idan may do the same for the Django&amp;nbsp;community.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.scribd.com/doc/64286481/Designers-Make-it-Go-to-Eleven&quot;&gt;Idan Gazit&amp;#8217;s&amp;nbsp;slides&lt;/a&gt;&lt;/p&gt;

   </content></entry><entry><title>DjangoCon, part two</title><author><name>Rob Martin</name></author><link href="http://www.version2beta.com/archive/2011/djangocon-part-two.html"/><updated>2011-09-07T12:04:00Z</updated><published>2011-09-07T12:04:00Z</published><id>http://www.version2beta.com/archive/2011/djangocon-part-two.html</id><content type="html">
       
&lt;!-- Hyde::Excerpt::Begin --&gt;

&lt;p&gt;Oh my, I&amp;#8217;m not good at this. There are people around live-blogging (and live-noting) the conference, and I&amp;#8217;m scraping the sleepiness off my face enough to see the screen, only to realize I don&amp;#8217;t actually remember yesterday very well. I may be exagerating a little, but I did not take adequate notes (sorry, PyDanny - I heard you on this, really I&amp;nbsp;did.)&lt;/p&gt;
&lt;!-- Hyde::Excerpt::End --&gt;

&lt;h2&gt;DjangoCon&amp;nbsp;agenda&lt;/h2&gt;
&lt;p&gt;Here&amp;#8217;s the recap of my first&amp;nbsp;day:&lt;/p&gt;
&lt;h3&gt;David Eaves&amp;#8217; keynote on the science of&amp;nbsp;community&lt;/h3&gt;
&lt;p&gt;David Eaves is awesome.&lt;sup id=&quot;fnref:eaves&quot;&gt;&lt;a href=&quot;#fn:eaves&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; He doesn&amp;#8217;t know much about the Django community, but he clearly knows about communities, including open source communities. Mostly he talked about two topics: using metrics to track and plan within a community, and using negotiation theory to include more people more effectively. Here was an important, but only peripheral, take-away: the involvement of women in an open source project is a key indicator of the health of the&amp;nbsp;project.&lt;/p&gt;
&lt;h3&gt;From designer to Django&amp;#8217;er in six&amp;nbsp;weeks&lt;/h3&gt;
&lt;p&gt;I understand that Alex was ill in the morning, so his slot went to Adam Nelson for &amp;#8216;Testing with Lettuce and Splinter&amp;#8217;. I arrived about four minutes in, and left about eight minutes in. I&amp;#8217;m sure it was a valuable talk. I&amp;#8217;ve even heard that from someone who stayed. I missed the discussion on &lt;span class=&quot;caps&quot;&gt;BDD&lt;/span&gt; (behavior driven development), and given that my testing experience is in many ways nascent, I decided that learning alternatives was further out than I was ready&amp;nbsp;for.&lt;/p&gt;
&lt;p&gt;What I did instead was listen to Tracy Osborn&amp;#8217;s&lt;sup id=&quot;fnref:limedaring&quot;&gt;&lt;a href=&quot;#fn:limedaring&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; fascinating &amp;#8216;From Designer to Django&amp;#8217;er in Six Weeks: A Story from Solo Founder&amp;#8217;.&lt;sup id=&quot;fnref:solo&quot;&gt;&lt;a href=&quot;#fn:solo&quot; rel=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; Anecdotes of learning not just Django, but of becoming an entrepreneur with Django.&lt;sup id=&quot;fnref:invite&quot;&gt;&lt;a href=&quot;#fn:invite&quot; rel=&quot;footnote&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Alex did present in the afternoon, opposite Frank Wiles&amp;#8217; PostgreSQL Performance talk, so I did not see him then&amp;nbsp;either.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.slideshare.net/limedaring/from-designer-to-djangoer-in-six-weeks-a-story-from-solo-founder&quot;&gt;Tracy Osborn&amp;#8217;s&amp;nbsp;slides&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Confessions of Joe&amp;nbsp;Developer&lt;/h3&gt;
&lt;p&gt;Danny claims to be lazy and stupid, which is not only a solid rhetorical tool but also a good starting point for learning complex systems. I half expected to hear a reference to Larry Walls&amp;#8217; three virtues of a good programmer.&lt;sup id=&quot;fnref:virtues&quot;&gt;&lt;a href=&quot;#fn:virtues&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; (In fact, it would have fit right in, except for the language&amp;nbsp;mismatch.) &lt;/p&gt;
&lt;p&gt;A good portion of his presentation described various methods for saving time, not relying on memorization, and the merits of doing things &amp;#8220;the dumb way&amp;#8221;. His example contrasts urllib2 with the requests library&lt;sup id=&quot;fnref:requests&quot;&gt;&lt;a href=&quot;#fn:requests&quot; rel=&quot;footnote&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Also terrifically important, Danny talked about diversity at the conference - PyLadies,&lt;sup id=&quot;fnref:pyladies&quot;&gt;&lt;a href=&quot;#fn:pyladies&quot; rel=&quot;footnote&quot;&gt;7&lt;/a&gt;&lt;/sup&gt; women in tech, our wives and daughters, the role of men in creating open and diverse environments. I like the thought, and believe Danny&amp;#8217;s sincere desire to make it all better. At the same time, as men we risk being the patron by being involved at all. There&amp;#8217;s much more to be said here, but I&amp;#8217;m reluctant to say it for fear my position stands counter to the enlightened attitudes around DjangoCon. It does not. I salute the efforts to include women, to build an inclusive environment and to identify narratives and behaviors that interfere. I think I&amp;#8217;ll stick with helping my daughter with her &lt;span class=&quot;caps&quot;&gt;AP&lt;/span&gt; Physics, &lt;span class=&quot;caps&quot;&gt;AP&lt;/span&gt; Calculus, and &lt;span class=&quot;caps&quot;&gt;AP&lt;/span&gt; Statistics homework. If she even needs&amp;nbsp;help.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.slideshare.net/pydanny/confessions-of-a-joe-developer&quot;&gt;Danny Greenfeld&amp;#8217;s Joe Developer&amp;nbsp;slides&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;The story and tech of Read the&amp;nbsp;Docs&lt;/h3&gt;
&lt;p&gt;I like devops.&lt;sup id=&quot;fnref:devops&quot;&gt;&lt;a href=&quot;#fn:devops&quot; rel=&quot;footnote&quot;&gt;8&lt;/a&gt;&lt;/sup&gt; I&amp;#8217;m fascinated by it. Eric Holscher&amp;#8217;s discussion on Read the Doc kept my attention as much as anything for how they solved the devops questions - clearly, that is the essence of Eric&amp;#8217;s work,&amp;nbsp;right?&lt;/p&gt;
&lt;h3&gt;Testing - The developer strikes&amp;nbsp;back&lt;/h3&gt;
&lt;p&gt;This was the densest presentation I&amp;#8217;ve seen at Djangon yet. Sandy&lt;sup id=&quot;fnref:sandy&quot;&gt;&lt;a href=&quot;#fn:sandy&quot; rel=&quot;footnote&quot;&gt;9&lt;/a&gt;&lt;/sup&gt; laid it down at 10 &lt;span class=&quot;caps&quot;&gt;MBPS&lt;/span&gt;, I swear. I knew little about &amp;#8220;real&amp;#8221; testing practices before I went in, and now I have enough familiarity with the universe of options, I&amp;#8217;m highly likely to recognize them when I finally sit down and learn them&amp;nbsp;right.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.google.com/present/view?id=0AVthC0Z3iw8DZGRrdnFzeGdfN2c5bWJ6d2Y1&quot;&gt;Sandy Strong&amp;#8217;s&amp;nbsp;slides&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Secrets of PostgreSQL&amp;nbsp;performance&lt;/h3&gt;
&lt;p&gt;I&amp;#8217;ve known of Frank Wiles and Revolution Systems&lt;sup id=&quot;fnref:revsys&quot;&gt;&lt;a href=&quot;#fn:revsys&quot; rel=&quot;footnote&quot;&gt;10&lt;/a&gt;&lt;/sup&gt; for about as long as I&amp;#8217;ve used PostgreSQL, so much of what he offered wasn&amp;#8217;t brand new to me. But some of it was new - tablespaces, for&amp;nbsp;instance.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://media.revsys.com/talks/djangocon/2011/secrets-of-postgresql-performance.pdf&quot;&gt;Frank Wiles&amp;#8217;&amp;nbsp;slides&lt;/a&gt;&lt;/p&gt;

   </content></entry><entry><title>DjangoCon, part one</title><author><name>Rob Martin</name></author><link href="http://www.version2beta.com/archive/2011/djangocon-part-one.html"/><updated>2011-09-04T12:33:00Z</updated><published>2011-09-04T12:33:00Z</published><id>http://www.version2beta.com/archive/2011/djangocon-part-one.html</id><content type="html">
       
&lt;!-- Hyde::Excerpt::Begin --&gt;

&lt;p&gt;It&amp;#8217;s two days before DjangoCon, I&amp;#8217;m on a plane to Portland, and I&amp;#8217;ve mostly been spending my time reading the Django Book. That has me thinking about what I expect from the&amp;nbsp;conference.&lt;/p&gt;
&lt;!-- Hyde::Excerpt::End --&gt;

&lt;h2&gt;DjangoCon&amp;nbsp;agenda&lt;/h2&gt;
&lt;p&gt;You&amp;#8217;ll be able to recognize me at DjangoCon.&lt;sup id=&quot;fnref:djangocon&quot;&gt;&lt;a href=&quot;#fn:djangocon&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; I have all of the sessions printed and three-hole punched inside a 1.5&amp;#8221; binder, with my schedule inserted in the front cover. My schedule looks reasonably good - I have a session I want to see during every session, and in two or three slots, I have both sessions selected. I&amp;#8217;m hoping my wife will be willing to attend the my&amp;nbsp;counter-sessions.&lt;/p&gt;
&lt;h2&gt;Tuesday&lt;/h2&gt;
&lt;h3&gt;Alex Gaynor, Summer in the&amp;nbsp;wild&lt;/h3&gt;
&lt;p&gt;Optimization is good and I always want to feel reasonably confident I can make things faster, so I look forward to this discussion of PyPy. But I&amp;#8217;m also curious to hear about Alex&amp;#8217;s position at Quora, a company  I expect to fail, which probably indicates it will be wildly&amp;nbsp;successful.&lt;/p&gt;
&lt;h3&gt;Confessions of Joe&amp;nbsp;Developer&lt;/h3&gt;
&lt;p&gt;Joe&amp;#8217;s real name is @PyDanny,&lt;sup id=&quot;fnref:pydanny&quot;&gt;&lt;a href=&quot;#fn:pydanny&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; which is why I plan to attend this session. Danny promises the benefit of his experience. I&amp;#8217;ll buy&amp;nbsp;that.&lt;/p&gt;
&lt;h3&gt;The story and tech of Read the&amp;nbsp;Docs&lt;/h3&gt;
&lt;p&gt;When I first visited readthedocs.org,&lt;sup id=&quot;fnref:readthedocs&quot;&gt;&lt;a href=&quot;#fn:readthedocs&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; I wondered how they got anyone to put in the effort to maintain their centralized database of software manuals. I learned enough more to make the important connections between Sphinx, GitHub, and Django to make the automation connection. Now I&amp;#8217;m fascinated with how Read The Docs came about and how it works. This session is one of my highest&amp;nbsp;priorities.&lt;/p&gt;
&lt;h3&gt;Testing - The developer strikes&amp;nbsp;back&lt;/h3&gt;
&lt;p&gt;I don&amp;#8217;t know who Sandy is, but I hope she or he is going to help me greatly improve my understanding and use of unit tests. I&amp;#8217;ve been coding a long time, like over thirty years now, but generally by myself. Shortcuts have happened, but I know I do not want to develop code without tests any&amp;nbsp;more.&lt;/p&gt;
&lt;h3&gt;Secrets of PostgreSQL&amp;nbsp;performance&lt;/h3&gt;
&lt;p&gt;I have over the years had a few opportunities to optimize databases, most recently PostgreSQL. I&amp;#8217;ve used three different resources for that task, and they all came from Frank Wiles.&lt;sup id=&quot;fnref:revsys&quot;&gt;&lt;a href=&quot;#fn:revsys&quot; rel=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; Hell yeah I&amp;#8217;m going to hear him&amp;nbsp;talk.&lt;/p&gt;
&lt;h2&gt;Wednesday&lt;/h2&gt;
&lt;h3&gt;RESTful APIs - promises and&amp;nbsp;lies&lt;/h3&gt;
&lt;p&gt;You may have heard the term &amp;#8220;mobile first&amp;#8221;. I&amp;#8217;m beginning to wonder if we shouldn&amp;#8217;t be looking at the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; goals of a website first. I&amp;#8217;m serious. Even the semantic web has goals related to sites as applications - what&amp;#8217;s my address, hours of operation, etc. What web site has no opportunity to&amp;nbsp;share?&lt;/p&gt;
&lt;h3&gt;Real-world Django deployment using&amp;nbsp;Chef&lt;/h3&gt;
&lt;p&gt;Scale is one big reason I am learning Django and attending DjangoCon at all. Besides, it sounds like Glyph is going to complain about Chef in his keynote address &amp;#8220;Why does Django hate Python?&amp;#8221; Might be good to have more context with Chef, as Glyph specifically mentions&amp;nbsp;it.&lt;/p&gt;
&lt;h3&gt;Building APIs in Django with&amp;nbsp;Tastypie&lt;/h3&gt;
&lt;p&gt;See above on APIs. Now add in Tastypie, which does sounds&amp;nbsp;interesting.&lt;/p&gt;
&lt;h3&gt;Making the Django &lt;span class=&quot;caps&quot;&gt;ORM&lt;/span&gt;&amp;nbsp;multilingual&lt;/h3&gt;
&lt;p&gt;I&amp;#8217;ve only had the opportunity to work on a couple of multilingual websites so far, but I expect that frequency to shift. I don&amp;#8217;t have a clue yet how Django does i18n, translation, or localization. I&amp;#8217;m worried it doesn&amp;#8217;t do it well, based on the description of this&amp;nbsp;session.&lt;/p&gt;
&lt;h3&gt;Stop tilting at windmills - Spotting&amp;nbsp;bottlenecks&lt;/h3&gt;
&lt;p&gt;This session promises the kind of good advice you only get from someone &lt;em&gt;experienced&lt;/em&gt;. But just as important to me, it appears that the best Django debugging tools will be demonstrated and potentially&amp;nbsp;discussed.&lt;/p&gt;
&lt;h3&gt;Safely deploying on the cutting&amp;nbsp;edge&lt;/h3&gt;
&lt;p&gt;Urban Airship&amp;#8217;s Eric Holscher&lt;sup id=&quot;fnref:urbanairship&quot;&gt;&lt;a href=&quot;#fn:urbanairship&quot; rel=&quot;footnote&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;  talking about Fabric, Gunicorn, Virtualenv, Rsync, Supervisord, and Python in fully isolated server environments? Oh yeah. Yes yes yes. This session is like sysadmin porn.&lt;sup id=&quot;fnref:nomore&quot;&gt;&lt;a href=&quot;#fn:nomore&quot; rel=&quot;footnote&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2&gt;Thursday&lt;/h2&gt;
&lt;h3&gt;Advanced Django Form&amp;nbsp;usage&lt;/h3&gt;
&lt;p&gt;@PyDanny&amp;#8217;s back again, talking about forms. We have a customer who does a lot with forms, and I&amp;#8217;ve already redesigned everything for them once, more than a year ago, to drastically improve the usability of their forms. That was the front side - how good can it get on the back&amp;nbsp;side?&lt;/p&gt;
&lt;h3&gt;Pinax after three years: lessons learnt and the way&amp;nbsp;forward&lt;/h3&gt;
&lt;p&gt;I want a content management system that my customers will rave about. I have no idea what that is with Django, if there even is someone complete and open source. Learning more about Pinax seems like a good direction to go,&amp;nbsp;though.&lt;/p&gt;
&lt;h3&gt;Advanced security&amp;nbsp;topics&lt;/h3&gt;
&lt;p&gt;&lt;span class=&quot;quo&quot;&gt;&amp;#8216;&lt;/span&gt;nuf&amp;nbsp;said.&lt;/p&gt;
&lt;h3&gt;Write the friendly&amp;nbsp;manual&lt;/h3&gt;
&lt;p&gt;There is some really good stuff going on in the Python world with documentation. Sure, I&amp;#8217;ve read most of the Django book, but have you looked at Flask&amp;#8217;s documentation? Geez, who has time to not only code a cool platform like Flask, but also put out documentation of that quality? There has to be some secrets. I plan to uncover&amp;nbsp;them.&lt;/p&gt;
&lt;h3&gt;Content ain&amp;#8217;t a thing: Web scraping with our favorite Python&amp;nbsp;libraries&lt;/h3&gt;
&lt;p&gt;I&amp;#8217;m bracketing my DjangoCon experience, right? Share (APIs with Tastypie, etc.) and share (Web scraping)&amp;nbsp;alike!&lt;/p&gt;
&lt;h3&gt;Cache rules everything around&amp;nbsp;me&lt;/h3&gt;
&lt;p&gt;I&amp;#8217;m back to scale, and systems administration, with this last formal&amp;nbsp;session.&lt;/p&gt;
&lt;h2&gt;Find&amp;nbsp;me?&lt;/h2&gt;
&lt;p&gt;So these are my picks for DjangoCon - find me at any of these sessions, strike up a conversation, and maybe even talk about sprints. I&amp;#8217;m the guy with the long beard, big laugh, and contemplative look, trying to figure out how to put this new knowledge to use&amp;nbsp;professionally.&lt;/p&gt;

   </content></entry><entry><title>jQuery.multiup plugin for multiple files</title><author><name>Rob Martin</name></author><link href="http://www.version2beta.com/archive/2011/jquery-multiup-plugin.html"/><updated>2011-08-30T20:21:00Z</updated><published>2011-08-30T20:21:00Z</published><id>http://www.version2beta.com/archive/2011/jquery-multiup-plugin.html</id><content type="html">
       
&lt;!-- Hyde::Excerpt::Begin --&gt;

&lt;p&gt;I&amp;#8217;m a progressive. By this I mean I like things to get progressively more complicated. Don&amp;#8217;t you? Of course, I don&amp;#8217;t mean that things should be more complicated than they are &amp;mdash; in fact, I think they should be &lt;em&gt;at most&lt;/em&gt; only as complicated as they are. But they don&amp;#8217;t have to start off that complicated; they can get complicated &lt;em&gt;progressively&lt;/em&gt;.&lt;/p&gt;
&lt;!-- Hyde::Excerpt::End --&gt;

&lt;p&gt;One example is file uploads. Sure, some of the time we only need to upload one file, and the way that &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; inputs (type=file) work is okay. But often, we need to upload more than 1 file. Maybe 10 of them. Maybe N of&amp;nbsp;them.&lt;/p&gt;
&lt;p&gt;So a progressive solution is to show one file uploader, but give the visitor the option to get another file. And another one. Right up until they&amp;#8217;ve selected as many as you&amp;#8217;re willing to allow them to upload, or as many as they&amp;nbsp;have.&lt;/p&gt;
&lt;p&gt;I did a review on this, and found some options. Malsup&lt;sup id=&quot;fnref:malsup&quot;&gt;&lt;a href=&quot;#fn:malsup&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; has a nice option for Ajaxifying forms, even does an Ajaxian-type thing for file uploads, but it doesn&amp;#8217;t let you build a package of files to upload. I found some nice stuff from the Stickman&lt;sup id=&quot;fnref:stickman&quot;&gt;&lt;a href=&quot;#fn:stickman&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;, but only in a MooTools dialect. Long story short, I wrote a&amp;nbsp;plugin.&lt;/p&gt;
&lt;p&gt;I guess that&amp;#8217;s significant. It is my first jQuery plugin. Feedback welcome,&amp;nbsp;please.&lt;/p&gt;
&lt;p&gt;Here is an example of the &lt;a href=&quot;/media/examples/jquery-multiup-plugin/&quot; title=&quot;Try the multiup plugin here.&quot;&gt;jQuery.multiup plugin in action&lt;/a&gt;. &lt;a href=&quot;https://github.com/Version2beta/multiup&quot; title=&quot;jQuery.multiup source code at GitHub.&quot;&gt;Source code hosted at GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Keep the progressive idea in mind. I hope to write something about progressive authentication systems eventually&amp;nbsp;too.&lt;/p&gt;

   </content></entry><entry><title>blog reset</title><author><name>Rob Martin</name></author><link href="http://www.version2beta.com/archive/2011/blog-reset.html"/><updated>2011-08-25T08:27:00Z</updated><published>2011-08-25T08:27:00Z</published><id>http://www.version2beta.com/archive/2011/blog-reset.html</id><content type="html">
       
&lt;!-- Hyde::Excerpt::Begin --&gt;

&lt;p&gt;My blog had been hosted on a legacy shared server account that I don&amp;#8217;t manage, running Wordpress. I was frankly embarrased to tweet links to it - often it wouldn&amp;#8217;t come up at all. Now that&amp;#8217;s all changed. Now my blog is on Django. (But only&amp;nbsp;kinda.)&lt;/p&gt;
&lt;!-- Hyde::Excerpt::End --&gt;

&lt;p&gt;A month ago I heard from a potential customer in Chicago who needs to move a site from Wordpress to Django.&lt;sup id=&quot;fnref:django&quot;&gt;&lt;a href=&quot;#fn:django&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; They&amp;#8217;d heard about me in particular from a colleague, and wanted to know if I could&amp;nbsp;help.&lt;/p&gt;
&lt;p&gt;Of course I could! I&amp;#8217;ve been learning Django for months. I even have the Django book.&lt;sup id=&quot;fnref:djangobook&quot;&gt;&lt;a href=&quot;#fn:djangobook&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; I&amp;#8217;ve even &lt;em&gt;read&lt;/em&gt; the Django book. Parts of it, anyway. And I do have tickets for DjangoCon&lt;sup id=&quot;fnref:djangocon&quot;&gt;&lt;a href=&quot;#fn:djangocon&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; in Portland next&amp;nbsp;month.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m afraid the colleague might have oversold me. It wasn&amp;#8217;t complete radio silence when I said I didn&amp;#8217;t have any production Django sites she could look at, but it was&amp;nbsp;close.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;dquo&quot;&gt;&amp;#8220;&lt;/span&gt;But I was thinking of moving my blog onto Django. I could probably have that done over the weekend.&amp;#8221; I could hear her slight sigh of&amp;nbsp;relief.&lt;/p&gt;
&lt;p&gt;I didn&amp;#8217;t move my blog onto Django that weekend. What I did with my weekend was build out two sets of high-availability server pairs and write up a how-to on the same.&lt;sup id=&quot;fnref:ha-pairs&quot;&gt;&lt;a href=&quot;#fn:ha-pairs&quot; rel=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; Then, at 5:30pm on the night before my 6:15am train to Chicago to meet with this customer, I sat down to figure out how I could get my blog onto Django,&amp;nbsp;quickly.&lt;/p&gt;
&lt;p&gt;I was already somewhat familiar with Hyde&lt;sup id=&quot;fnref:hyde&quot;&gt;&lt;a href=&quot;#fn:hyde&quot; rel=&quot;footnote&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;. It&amp;#8217;s a static site generator written in Python, inspired by a remarkably similar Jekyll&lt;sup id=&quot;fnref:jekyll&quot;&gt;&lt;a href=&quot;#fn:jekyll&quot; rel=&quot;footnote&quot;&gt;6&lt;/a&gt;&lt;/sup&gt; written in Ruby. Conveniently, Hyde is also based on Django, using both the settings.py file and Django templates, so I&amp;#8217;d be able to use some of what I already knew to show off what I might be able to do for a customer using Django. Because that&amp;#8217;s what every customer needs, right? A small, unobtrusive, under-designed blog-like website that uses Django&amp;nbsp;templates?&lt;/p&gt;
&lt;p&gt;My whole blog did not get moved that evening, but I did post the high-availability write-up in a blog section of a website I called &amp;#8220;proof of concept&amp;#8221;. That was convenient, since the new site is hosted on one of the server pairs I&amp;#8217;d just built, and the write-up was a key take-away for my presentation at Web414&lt;sup id=&quot;fnref:web414&quot;&gt;&lt;a href=&quot;#fn:web414&quot; rel=&quot;footnote&quot;&gt;7&lt;/a&gt;&lt;/sup&gt; the next night on cloud&amp;nbsp;hosting.&lt;/p&gt;
&lt;p&gt;A couple of weeks passed before I got back to the project, but I did finally move my blog. I also improved the design some, though of course it&amp;#8217;s still small, unobtrusive, under-designed, and blog-like. I did away with almost all of my inline links in blog posts, opting for footnotes instead. Not only does this make the reading easier (and less spammy-looking), it gives me more room to be snarky&lt;sup id=&quot;fnref:snarky&quot;&gt;&lt;a href=&quot;#fn:snarky&quot; rel=&quot;footnote&quot;&gt;8&lt;/a&gt;&lt;/sup&gt; out-of-band. (There are many fine examples of footnoting bloggers, but as usual Barbara&lt;sup id=&quot;fnref:barbara&quot;&gt;&lt;a href=&quot;#fn:barbara&quot; rel=&quot;footnote&quot;&gt;9&lt;/a&gt;&lt;/sup&gt; has the most influence on me.) I&amp;#8217;d also been wanting to use Disqus for comments, and figured it&amp;#8217;d be best to do that while I only have 8 comments to figure out what to do with. (Note: if you are one of the people who&amp;#8217;d commented on my old blog, please accept my apology as I decide how, when, and if to move&amp;nbsp;them.)&lt;/p&gt;
&lt;p&gt;I haven&amp;#8217;t heard back from the Chicago customer yet, which is probably okay because they wanted freelance, and I would want to run it through &lt;span class=&quot;caps&quot;&gt;QMUXS&lt;/span&gt;.&lt;sup id=&quot;fnref:qmuxs&quot;&gt;&lt;a href=&quot;#fn:qmuxs&quot; rel=&quot;footnote&quot;&gt;10&lt;/a&gt;&lt;/sup&gt; But in spite of the dubious benefit of the sales call, I worked through the new high-availability challenges, built up the new servers, got to work with Django more, and built a new fast fast fast website for&amp;nbsp;version2beta. &lt;/p&gt;
&lt;p&gt;I hope you enjoy&amp;nbsp;it.&lt;/p&gt;

   </content></entry><entry><title>High Availability Linode Pairs</title><author><name>Rob Martin</name></author><link href="http://www.version2beta.com/archive/2011/high-availability-linode-pairs.html"/><updated>2011-08-08T20:08:08Z</updated><published>2011-08-08T20:08:08Z</published><id>http://www.version2beta.com/archive/2011/high-availability-linode-pairs.html</id><content type="html">
       
&lt;!-- Hyde::Excerpt::Begin --&gt;

&lt;p&gt;Something like a recipe for creating database and application servers that failover on each other. This recipe is for Lighttpd and MySQL, but it can be extended easily for other applications. Later, I&amp;#8217;ll do one for Tryton and PostgreSQL. I use Ubuntu 11.04 64-bit on two Linode virtual private&amp;nbsp;servers.&lt;/p&gt;
&lt;!-- Hyde::Excerpt::End --&gt;

&lt;h2&gt;Initial configuration, from within the Linode&lt;sup id=&quot;fnref:linode&quot;&gt;&lt;a href=&quot;#fn:linode&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; dashboard&lt;/h2&gt;
&lt;p&gt;Repeat the following procedure for each member of the&amp;nbsp;pair:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Go to the Remote Access tab on the Linode&amp;nbsp;dashboard. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Note the public &lt;span class=&quot;caps&quot;&gt;IP&lt;/span&gt;. We&amp;#8217;ll need that&amp;nbsp;later.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add a private &lt;span class=&quot;caps&quot;&gt;IP&lt;/span&gt;, and note it. We&amp;#8217;ll need that later,&amp;nbsp;too.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If by any chance you have an IPv6 private address, note that. We&amp;#8217;ll use it all. If you don&amp;#8217;t have one, click on &amp;#8220;Enable IPv6&amp;#8221; and get one. We really are going to use&amp;nbsp;it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Set a Lish password. I use &lt;span class=&quot;caps&quot;&gt;APG&lt;/span&gt;&lt;sup id=&quot;fnref:APG&quot;&gt;&lt;a href=&quot;#fn:APG&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; to generate new passwords, e.g. &lt;code&gt;apg -n 100&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add an &lt;span class=&quot;caps&quot;&gt;SSH&lt;/span&gt; public key to the Keys box. This is in addition to the Lish password.  Or instead of it, if you&amp;nbsp;prefer.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;This is also good time to write to Linode support. You&amp;#8217;ll need to order an additional public &lt;span class=&quot;caps&quot;&gt;IP&lt;/span&gt; address, and by default you are unable to purchase an additional &lt;span class=&quot;caps&quot;&gt;IP&lt;/span&gt; address until you&amp;#8217;ve requested and justified it specifically with support. You&amp;#8217;ll also need another &lt;em&gt;private&lt;/em&gt; &lt;span class=&quot;caps&quot;&gt;IP&lt;/span&gt; address, which doesn&amp;#8217;t cost anything but it takes a support person to do it - there&amp;#8217;s no way to automatically add more than one private &lt;span class=&quot;caps&quot;&gt;IP&lt;/span&gt; address. These addresses will float between the pairs, so it doesn&amp;#8217;t matter which of the pair get these additional addresses. Make note of these floating&amp;nbsp;addresses.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Go to the Settings tab in the Linode&amp;nbsp;dashboard.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Give the Linode a good&amp;nbsp;name. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Name a display group for your pair. Generally we use &amp;#8220;location pair&amp;#8221;, e.g. &amp;#8220;newark pair&amp;#8221;, &amp;#8220;dallas pair&amp;#8221;,&amp;nbsp;etc.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Change the email alert&amp;nbsp;thresholds&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;CPU&lt;/span&gt; Usage: 50% (Default 80% over two hours is too&amp;nbsp;high)&lt;/p&gt;
&lt;p&gt;Disk I/O Rate: 2000 I/O Ops/sec (Default 1000 ops over two hours is too&amp;nbsp;low)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Go to the Dashboard tab in the Linode dashboard, and click on &amp;#8220;Create a new Disk&amp;nbsp;Image&amp;#8221;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Create a disk image called &amp;#8220;var-www&amp;#8221;, type &amp;#8220;unformatted / raw&amp;#8221;, with a size that&amp;#8217;s half your available space (just as a rule of&amp;nbsp;thumb).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create another disk image called &amp;#8220;var-mysql&amp;#8221;, also type &amp;#8220;unformatted / raw&amp;#8221;, with a size that&amp;#8217;s half your &lt;em&gt;remaining&lt;/em&gt; available space (again, a rule of&amp;nbsp;thumb).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Also on the Linode dashboard tab, choose to deploy a Linux&amp;nbsp;distribution.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;I like the latest Ubuntu&lt;sup id=&quot;fnref:ubuntu&quot;&gt;&lt;a href=&quot;#fn:ubuntu&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;. Right now, that&amp;#8217;s 11.04&amp;nbsp;64bit.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Set the swap partition size next. Max it out, which on Linode seems to be 1 x&amp;nbsp;&lt;span class=&quot;caps&quot;&gt;RAM&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use everything that&amp;#8217;s left for the deployment disk&amp;nbsp;size.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Set a good root&amp;nbsp;password.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Press the Deploy button. That takes you back to the&amp;nbsp;dashboard.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The configuration profile name is too pedestrian. &amp;#8220;My Ubuntu blah blah blah&amp;#8221;. I already knew it was mine, after all I made it, didn&amp;#8217;t I? Click the &amp;#8220;Edit&amp;#8221; link to the right of the&amp;nbsp;profile.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Change the label to something with some teeth. Something like &amp;#8220;Ubuntu 11.04-64bit high availability&amp;nbsp;pair&amp;#8221;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Assign block devices for our &lt;span class=&quot;caps&quot;&gt;DR&lt;/span&gt;:&lt;span class=&quot;caps&quot;&gt;BD&lt;/span&gt; drives. Put var-mysql on /dev/xvdc, and var-www on /dev/xvdd. Save the changes, and you&amp;#8217;ll be taken back to the&amp;nbsp;dashboard.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Each server needs to be able to assume the &lt;span class=&quot;caps&quot;&gt;IP&lt;/span&gt; address from the other. From the &amp;#8220;Remote Access&amp;#8221; tab for each server, select all of the addresses, both the public and private, for &lt;span class=&quot;caps&quot;&gt;IP&lt;/span&gt;&amp;nbsp;Failover.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Boot the system and log in, either through &lt;span class=&quot;caps&quot;&gt;SSH&lt;/span&gt; using the root password you just assigned, or through&amp;nbsp;Lish.&lt;/p&gt;
&lt;p&gt;This is a good time to repeat the previous six steps on the other member of the pair. Once that is done, continue to the final step in the Linode&amp;nbsp;dashboard.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Some notes before we get into&amp;nbsp;it&lt;/h2&gt;
&lt;p&gt;We have a number of implementation specific details, stuff that changes for each cluster. I&amp;#8217;d like to refer to things in here in a way that is internally consistent, yet easy to use. So here is an index of variable&amp;nbsp;data:&lt;/p&gt;
&lt;p&gt;Server names: &lt;code&gt;alice&lt;/code&gt; and &lt;code&gt;gertrude&lt;/code&gt;. If you&amp;#8217;re running &lt;code&gt;vi&lt;/code&gt; or &lt;code&gt;vim&lt;/code&gt; against this document, and wanted to name your systems Fred and Wilma, you should be able to run &lt;code&gt;:%s/alice/fred/g&lt;/code&gt; followed by &lt;code&gt;:%s/gertrude/wilma/g&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;IP&lt;/span&gt;&amp;nbsp;addresses:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Public &lt;span class=&quot;caps&quot;&gt;IP&lt;/span&gt; on alice: &lt;code&gt;pub.a.a.a&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Private &lt;span class=&quot;caps&quot;&gt;IP&lt;/span&gt; on alice: &lt;code&gt;priv.a.a.a&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;IPv6 on alice: &lt;code&gt;ipv6:pub:a&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Public &lt;span class=&quot;caps&quot;&gt;IP&lt;/span&gt; on gertrude: &lt;code&gt;pub.g.g.g&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Private &lt;span class=&quot;caps&quot;&gt;IP&lt;/span&gt; on gertrude: &lt;code&gt;priv.g.g.g&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;IPv6 on gertrude: &lt;code&gt;ipv6:pub:g&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Floating public &lt;span class=&quot;caps&quot;&gt;IP&lt;/span&gt;: &lt;code&gt;pub.f.f.f&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Floating private &lt;span class=&quot;caps&quot;&gt;IP&lt;/span&gt;: &lt;code&gt;priv.f.f.f&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Initial configuration, operating&amp;nbsp;system&lt;/h2&gt;
&lt;p&gt;Again, repeat the following steps for each member of the&amp;nbsp;pair:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Name the&amp;nbsp;server.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;echo &#39;alice&#39; &amp;gt; /etc/hostname&lt;/code&gt;&lt;sup id=&quot;fnref:toklas&quot;&gt;&lt;a href=&quot;#fn:toklas&quot; rel=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Fix (as in &amp;#8220;make permanent&amp;#8221;) the networking in &lt;code&gt;/etc/network/interfaces&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#vi /etc/network/interfaces

    # The loopback interface
    auto lo
    iface lo inet loopback

    # Configuration for eth0 and aliases

    # This line ensures that the interface will be brought up during boot.
    auto eth0 eth0:0

    # eth0 - This is the main IP address that will be used for most outbound connections.
    # The address, netmask and gateway are all necessary.
    iface eth0 inet static
     address pub.a.a.a
     netmask 255.255.255.0
     gateway gate.a.a.a

    # eth0:0
    # This is a private IP
    iface eth0:0 inet static
     address priv.a.a.a
     netmask 255.255.128.0

    # eth0 ipv6
    iface eth0 inet6 static
     address ipv6:pub:a
     netmask 64
     gateway fe80::1
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Deal with some networking stuff that makes our life&amp;nbsp;easier.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#vi /etc/hosts

    127.0.0.1       localhost.localdomain       localhost
    pub.a.a.a       alice.version2beta.com      # FQDN is public
    priv.a.a.a  alice               # short name is private
    pub.g.g.g   gertrude.version2beta.com   # FQDN is public
    priv.g.g.g  gertrude            # short name is private
    pub.f.f.f   ag.version2beta.com     # public floating IP
    priv.f.f.f  ag              # private floating IP

    #IPv6 addresses
    ipv6:a      ip6-alice
    ipv6:g      ip6-gertrude

    # The following lines are desirable for IPv6 capable hosts
    ::1     ip6-localhost ip6-loopback
    fe00::0 ip6-localnet
    ff00::0 ip6-mcastprefix
    ff02::1 ip6-allnodes
    ff02::2 ip6-allrouters
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;SSH&lt;/span&gt;&amp;nbsp;Keys&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# ssh-keygen -t rsa
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Copy &lt;code&gt;/etc/.ssh/id_rsa.pub&lt;/code&gt; into the other server&amp;#8217;s &lt;code&gt;/etc/.ssh/authorized_keys&lt;/code&gt;, which you&amp;#8217;ll need to create. While you&amp;#8217;re at it, put your key in there&amp;nbsp;too.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Restart networking. (If there&amp;#8217;s a mistake in the previous step, we&amp;#8217;ll catch it either here or in the next few&amp;nbsp;steps.)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /etc/init.d/networking restart
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Bring the package database, and installed packages, up to&amp;nbsp;date.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# apt-get update &amp;amp;&amp;amp; apt-get upgrade
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Install and configure&amp;nbsp;&lt;span class=&quot;caps&quot;&gt;DR&lt;/span&gt;:&lt;span class=&quot;caps&quot;&gt;BD&lt;/span&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install the&amp;nbsp;tools&lt;/p&gt;
&lt;p&gt;First,&amp;nbsp;try:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# apt-get install drbd8-utils
# drbdadm -V
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At the top of the options, it will give the version of the &lt;span class=&quot;caps&quot;&gt;DRBD&lt;/span&gt; module and userland version. If these match, you&amp;#8217;re golden. If they don&amp;#8217;t (as is the case currently for me), you need to build userland tools from&amp;nbsp;source.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# drbdadm -V

DRBD module version: 8.3.10
   userland version: 8.3.9
you should upgrade your drbd tools!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Building drbd8-utils from&amp;nbsp;source:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# apt-get remove drbd8-utils
# apt-get install psmisc build-essential flex git xsltproc
# wget http://oss.linbit.com/drbd/8.3/drbd-8.3.10.tar.gz
# tar xvzf drbd-8.3.10.tar.gz
# cd drbd-8.3.10
# ./configure
# make
# make install
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All good? Try the drbdadm -V&amp;nbsp;again:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# drbdadm -V

...
Version: 8.3.10 (api:88)
GIT-hash: 5c0b0469666682443d4785d90a2c603378f9017b build by root@alice, 2011-08-06 22:35:11
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Configure &lt;span class=&quot;caps&quot;&gt;DR&lt;/span&gt;:&lt;span class=&quot;caps&quot;&gt;BD&lt;/span&gt; global settings in &lt;code&gt;/usr/local/etc/drbd.d/global_common.conf&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# vi /usr/local/etc/drbd.d/global_common.conf

    global {
        usage-count yes;
        # minor-count dialog-refresh disable-ip-verification
    }

    common {
        protocol C;

        handlers {
            pri-on-incon-degr &quot;/usr/lib/drbd/notify-pri-on-incon-degr.sh; /usr/lib/drbd/notify-emergency-reboot.sh; echo b &amp;gt; /proc/sysrq-trigger ; reboot -f&quot;;
            pri-lost-after-sb &quot;/usr/lib/drbd/notify-pri-lost-after-sb.sh; /usr/lib/drbd/notify-emergency-reboot.sh; echo b &amp;gt; /proc/sysrq-trigger ; reboot -f&quot;;
            local-io-error &quot;/usr/lib/drbd/notify-io-error.sh; /usr/lib/drbd/notify-emergency-shutdown.sh; echo o &amp;gt; /proc/sysrq-trigger ; halt -f&quot;;
            # fence-peer &quot;/usr/lib/drbd/crm-fence-peer.sh&quot;;
            split-brain &quot;/usr/lib/drbd/notify-split-brain.sh root&quot;;
            # out-of-sync &quot;/usr/lib/drbd/notify-out-of-sync.sh root&quot;;
            # before-resync-target &quot;/usr/lib/drbd/snapshot-resync-target-lvm.sh -p 15 -- -c 16k&quot;;
            # after-resync-target /usr/lib/drbd/unsnapshot-resync-target-lvm.sh;
        }

        startup {
            # wfc-timeout degr-wfc-timeout outdated-wfc-timeout wait-after-sb
            wfc-timeout 15;
            degr-wfc-timeout 60;
        }

        disk {
            # on-io-error fencing use-bmbv no-disk-barrier no-disk-flushes
            # no-disk-drain no-md-flushes max-bio-bvecs
        }

        net {
            # sndbuf-size rcvbuf-size timeout connect-int ping-int ping-timeout max-buffers
            # max-epoch-size ko-count allow-two-primaries cram-hmac-alg shared-secret
            # after-sb-0pri after-sb-1pri after-sb-2pri data-integrity-alg no-tcp-cork
            cram-hmac-alg sha1;
        }

        syncer {
            # rate after al-extents use-rle cpu-mask verify-alg csums-alg
            rate 4M;
        }
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Configure &lt;span class=&quot;caps&quot;&gt;DR&lt;/span&gt;:&lt;span class=&quot;caps&quot;&gt;BD&lt;/span&gt; resource settings for mysql in &lt;code&gt;/usr/local/etc/drbd.d/mysql.res&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# vi /usr/local/etc/drbd.d/mysql.res

    resource mysql {
        net {
            shared-secret &quot;DONTTELL!&quot;;
        }
        on alice {
            device /dev/drbd0;
            disk /dev/xvdc;
            address ipv6 [ipv6:a]:7801;
            meta-disk internal;
        }
        on gertrude {
            device /dev/drbd0;
            disk /dev/xvdc;
            address ipv6 [ipv6:g]:7801;
            meta-disk internal;
        }
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And create resource settings for www in &lt;code&gt;/usr/local/etc/drbd.d/www.res&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# vi /usr/local/etc/drbd.d/www.res

    resource www {
        net {
            shared-secret &quot;DON&#39;T TELL!&quot;;
        }
        on alice {
            device /dev/drbd1;
            disk /dev/xvdd;
            address ipv6 [ipv6:a]:7802;
            meta-disk internal;
        }
        on gertrude {
            device /dev/drbd1;
            disk /dev/xvdd;
            address ipv6 [ipv6:g]:7802;
            meta-disk internal;
        }
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On this setup, drbd expects configuration files to be in /usr/local/etc/, and won&amp;#8217;t recognize them in /etc/. So we&amp;#8217;ve put all our new stuff in the right place. Now get rid of the old. &lt;span class=&quot;caps&quot;&gt;BUT&lt;/span&gt;, the cluster resource manager &lt;span class=&quot;caps&quot;&gt;IS&lt;/span&gt; going to want them in /etc/, so we&amp;#8217;ll create symbolic&amp;nbsp;links.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# rm -rd /etc/drbd.*
# ln -s /usr/local/etc/drbd.conf /etc/drbd.conf
# ln -s /usr/local/etc/drbd.d /etc/drbd.d
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Start up&amp;nbsp;&lt;span class=&quot;caps&quot;&gt;DR&lt;/span&gt;:&lt;span class=&quot;caps&quot;&gt;BD&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Create metadata for the devices (only need to do this on one&amp;nbsp;host):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# drbdadm create-md mysql
# drbdadm create-md www
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Modify the init script for drbd to accomodate a problem where IPv6 might not be ready when drbd&amp;nbsp;starts:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# vi /etc/init.d/drbd # Add a sleep to the top of the script

    ### END INIT INFO
    sleep 5
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On each server, at roughly the same time, start&amp;nbsp;drbd:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /etc/init.d/drbd start
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On the server that will be primarily a database&amp;nbsp;server:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# drbdadm -- --overwrite-data-of-peer primary mysql
# drbdadm disconnect mysql
# drbdadm connect mysql
# drbdadm disconnect www
# drbdadm connect www
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On the server that will be primarily a web application&amp;nbsp;server:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# drbdadm -- --overwrite-data-of-peer primary www
# drbdadm disconnect www
# drbdadm connect www
# drbdadm disconnect mysql
# drbdadm connect mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On either or both servers, check to make sure the primaries are primary, the secondaries are secondary, and the sync is&amp;nbsp;syncing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# cat /proc/drbd

version: 8.3.10 (api:88/proto:86-96)
built-in
 0: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r-----
    ns:3116484 nr:0 dw:0 dr:3593516 al:0 bm:219 lo:0 pe:2 ua:1 ap:0 ep:1 wo:f oos:1649980
    [============&amp;gt;.......] sync&#39;ed: 65.5% (1608/4652)Mfinish: 0:05:08 speed: 5,328 (5,056) K/sec
 1: cs:SyncTarget ro:Secondary/Primary ds:Inconsistent/UpToDate C r-----
    ns:0 nr:2976256 dw:2976256 dr:0 al:0 bm:181 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:7509148
    [====&amp;gt;...............] sync&#39;ed: 28.4% (7332/10236)Mfinish: 0:24:20 speed: 5,136 (5,060) want: 4,096 K/sec
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Format the &lt;span class=&quot;caps&quot;&gt;DR&lt;/span&gt;:&lt;span class=&quot;caps&quot;&gt;BD&lt;/span&gt; devices, each on the server that is primary for that device. On the database&amp;nbsp;server:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# apt-get install jfsutils
# mkfs.jfs /dev/drbd0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And on the web application&amp;nbsp;server:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# apt-get install jfsutils
# mkfs.ext4 /dev/drbd1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On both servers, create the mount&amp;nbsp;points:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# mkdir /var/www
# mkdir /var/mysql

# vi /etc/fstab // Add two lines

    /dev/drbd/by-res/www    /var/www        ext4    noauto,noatime
    /dev/drbd/by-res/mysql  /var/mysql      jfs     noauto
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mount the drives, each on it&amp;#8217;s primary&amp;nbsp;server:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# mount /dev/drbd/by-res/mysql /var/mysql/
# mount /dev/drbd/by-res/www /var/www
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And there you have it - &lt;span class=&quot;caps&quot;&gt;RAID&lt;/span&gt; 1 drives over a network. Failover comes later, after we install and configure the server&amp;nbsp;software.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Services: MySQL and Lighttpd, plus a few other little things I like to&amp;nbsp;have&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install stuff. Not too much stuff. Just the right&amp;nbsp;stuff.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# apt-get install bc whois apg s3cmd lsof traceroute exim4 mailutils mutt \
    aspell-doc wamerican spellutils ispell mysql-server mysql-client lighttpd \
    lighttpd-doc lighttpd-mod-magnet lua5.1 php5-cli php5-cgi php5 php5-mcrypt \
    php5-mhash php5-gd php5-mysql php5-imagick php5-curl php5-memcache php5-ps \
    php5-pspell php5-tidy php5-xmlrpc php5-xsl libgd-tools libmagickcore3-extra \
    libmcrypt-dev mcrypt rrdtool

# dpkg-reconfigure exim4-config
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Configure&amp;nbsp;MySQL. &lt;/p&gt;
&lt;p&gt;Edit &lt;code&gt;/etc/mysql/my.cnf&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# vi /etc/mysql/my.cnf

    [client]
    port            = 3306
    socket          = /var/run/mysqld/mysqld.sock

    [mysqld_safe]
    socket          = /var/run/mysqld/mysqld.sock
    nice            = 0

    [mysqld]
    user            = mysql
    socket          = /var/run/mysqld/mysqld.sock
    port            = 3306
    basedir         = /usr
    datadir         = /var/mysql
    tmpdir          = /tmp
    skip-external-locking
    bind-address            = priv.f.f.f
    key_buffer              = 16M
    max_allowed_packet      = 16M
    thread_stack            = 192K
    thread_cache_size       = 8
    myisam-recover         = BACKUP
    #max_connections        = 100
    #table_cache            = 64
    #thread_concurrency     = 10
    query_cache_limit       = 1M
    query_cache_size        = 16M
    #general_log_file        = /var/log/mysql/mysql.log
    #general_log             = 1
    log_error                = /var/log/mysql/error.log
    #server-id              = 1
    #log_bin                        = /var/log/mysql/mysql-bin.log
    expire_logs_days        = 10
    max_binlog_size         = 100M
    #binlog_do_db           = include_database_name
    #binlog_ignore_db       = include_database_name
    # ssl-ca=/etc/mysql/cacert.pem
    # ssl-cert=/etc/mysql/server-cert.pem
    # ssl-key=/etc/mysql/server-key.pem

    [mysqldump]
    quick
    quote-names
    max_allowed_packet      = 16M

    [mysql]
    #no-auto-rehash # faster start of mysql but no tab completition

    [isamchk]
    key_buffer              = 16M

    !includedir /etc/mysql/conf.d/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We changed the default directory for MySQL, so we need to move it&amp;#8217;s files into the correct&amp;nbsp;directory.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# stop mysql
# chown mysql:mysql /var/mysql
# cp -Rp /var/lib/mysql/* /var/mysql/
# ifconfig eth0:1 priv.f.f.f netmask 255.255.128.0
# start mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sync these settings with the other server (both need the same configuration so that either can run the service off the same&amp;nbsp;data).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# scp -r /etc/mysql root@gertrude:/etc/
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Configure Lighttpd. (Substitute other instructions for nginx, apache,&amp;nbsp;etc.)&lt;/p&gt;
&lt;p&gt;Edit &lt;code&gt;/etc/lighttpd/lighttpd.conf&lt;/code&gt; on the web application&amp;nbsp;server:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# vi /etc/lighttpd/lighttpd.conf

    server.modules = (
        &quot;mod_access&quot;,
        &quot;mod_alias&quot;,
        &quot;mod_compress&quot;,
        &quot;mod_redirect&quot;,
            &quot;mod_rewrite&quot;,
    )

    server.document-root        = &quot;/var/www&quot;
    server.upload-dirs          = ( &quot;/var/www/cache/uploads&quot; )
    server.errorlog             = &quot;/var/www/logs/error.log&quot;
    server.pid-file             = &quot;/var/run/lighttpd.pid&quot;
    server.username             = &quot;www-data&quot;
    server.groupname            = &quot;www-data&quot;

    index-file.names            = ( &quot;index.php&quot;, &quot;index.html&quot;)

    url.access-deny             = ( &quot;~&quot;, &quot;.inc&quot; )

    static-file.exclude-extensions = ( &quot;.php&quot;, &quot;.pl&quot;, &quot;.fcgi&quot; )

    ## Use ipv6 if available
    include_shell &quot;/usr/share/lighttpd/use-ipv6.pl&quot;

    dir-listing.encoding        = &quot;utf-8&quot;
    server.dir-listing          = &quot;enable&quot;

    compress.cache-dir          = &quot;/var/www/cache/compress/&quot;
    compress.filetype           = ( &quot;application/x-javascript&quot;, &quot;text/css&quot;, &quot;text/html&quot;, &quot;text/plain&quot; )

    include_shell &quot;/usr/share/lighttpd/create-mime.assign.pl&quot;
    include_shell &quot;/usr/share/lighttpd/include-conf-enabled.pl&quot;

    magnet.attract-physical-path-to = ( &quot;/etc/lighttpd/modx.lua&quot; )
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Enable some more&amp;nbsp;modules:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# lighttpd-enable-mod fastcgi
# lighttpd-enable-mod simple-vhost
# lighttpd-enable-mod accesslog
# lighttpd-enable-mod magnet
# lighttpd-enable-mod status
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Edit more config&amp;nbsp;files:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# vi /etc/lighttpd/conf-enabled/10-accesslog.conf

    server.modules += ( &quot;mod_accesslog&quot; )
    accesslog.filename = &quot;/var/www/logs/access.log&quot;

# vi /etc/lighttpd/conf-enabled/10-simple-vhost.conf

    server.modules += ( &quot;mod_simple_vhost&quot; )
    simple-vhost.server-root         = &quot;/var/www/servers/&quot;
    simple-vhost.document-root       = &quot;htdocs&quot;
    simple-vhost.default-host        = &quot;{hostname}&quot;

# vi /etc/lighttpd/conf-enabled/10-fastcgi.conf

    server.modules += ( &quot;mod_fastcgi&quot; )
    fastcgi.server    = ( &quot;.php&quot; =&amp;gt;
            ((
                    &quot;bin-path&quot; =&amp;gt; &quot;/usr/bin/php-cgi&quot;,
                    &quot;socket&quot; =&amp;gt; &quot;/tmp/php.socket&quot;,
                    &quot;max-procs&quot; =&amp;gt; 2,
                    &quot;idle-timeout&quot; =&amp;gt; 20,
                    &quot;bin-environment&quot; =&amp;gt; (
                            &quot;PHP_FCGI_CHILDREN&quot; =&amp;gt; &quot;4&quot;,
                            &quot;PHP_FCGI_MAX_REQUESTS&quot; =&amp;gt; &quot;10000&quot;
                    ),
                    &quot;bin-copy-environment&quot; =&amp;gt; (
                            &quot;PATH&quot;, &quot;SHELL&quot;, &quot;USER&quot;
                    ),
                    &quot;broken-scriptfilename&quot; =&amp;gt; &quot;enable&quot;
            ))
    )

# vi /etc/lighttpd/modx.lua

    attr = lighty.stat(lighty.env[&quot;physical.doc-root&quot;] .. &quot;manager/includes/config.inc.php&quot;) -- Appears to be a ModX site
    if (attr) then
      attr = lighty.stat(lighty.env[&quot;physical.path&quot;])
      if (not attr) then -- Requested resource doesn&#39;t exist in the file system
        path = &quot;/index.php&quot;
        uri = lighty.env[&quot;request.uri&quot;]
        uri2 = string.gsub(lighty.env[&quot;request.uri&quot;], &quot;\?&quot;, &quot;\&amp;amp;&quot;)
        -- print(&quot;Original request.uri: &quot; .. uri .. &quot; Replaced with: &quot; .. uri2)
        lighty.env[&quot;uri.query&quot;] = &quot;q=&quot; .. string.gsub(uri, &quot;\?&quot;, &quot;\&amp;amp;&quot;)
        lighty.env[&quot;uri.path&quot;] = path
        lighty.env[&quot;request.uri&quot;] = path .. &quot;?&quot; .. lighty.env[&quot;uri.query&quot;]
        -- print(&quot;New request.uri: &quot; .. lighty.env[&quot;request.uri&quot;])
        lighty.env[&quot;physical.rel-path&quot;] = path
        lighty.env[&quot;physical.path&quot;] = lighty.env[&quot;physical.doc-root&quot;] .. string.sub(lighty.env[&quot;physical.rel-path&quot;], 2)
        -- print(&quot;New physical.path: &quot; .. lighty.env[&quot;physical.path&quot;])
      end
    end

# vi /etc/lighttpd/wp-rewrite.conf

    # Use when a site has a blog
    # Example:
    # $HTTP[&quot;host&quot;] =~ &quot;www\.example\.com&quot; {
    #   var.wpdir = &quot;/blog/&quot;
    #   include &quot;wp-rewrite.conf&quot;
    # }

    url.rewrite-once = (
      &quot;^&quot; + wpdir + &quot;(wp-.+).*/?&quot; =&amp;gt; &quot;$0&quot;,
      &quot;^&quot; + wpdir + &quot;(sitemap.xml)&quot; =&amp;gt; &quot;$0&quot;,
      &quot;^&quot; + wpdir + &quot;(xmlrpc.php)&quot; =&amp;gt; &quot;$0&quot;,
      &quot;^&quot; + wpdir + &quot;keyword/([A-Za-z_0-9-])/?$&quot; =&amp;gt; wpdir + &quot;index.php?keyword=$1&quot;,
      &quot;^&quot; + wpdir + &quot;(.+)/?$&quot; =&amp;gt; wpdir + &quot;index.php/$1&quot;
    )
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Edit &lt;code&gt;/etc/php5/cgi/php.ini&lt;/code&gt; so that these lines are&amp;nbsp;correct:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;display_errors = stderr
error_log = /var/www/logs/php_errors.log
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create some directories we just specified, but don&amp;#8217;t yet&amp;nbsp;have:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# mkdir /var/www/run /var/www/cache /var/www/cache/compress /var/www/cache/uploads /var/www/logs /var/www/servers /var/www/servers/{hostname} /var/www/servers/{hostname}/htdocs
# chown -R www-data:www-data /var/www/run /var/www/cache /var/www/logs/ /var/www/servers
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Restart the local server and sync these settings with the other server (both need the same configuration so that either can run the service off the same&amp;nbsp;data).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /etc/init.d/lighttpd restart
# scp -r /etc/php5 /etc/lighttpd root@alice:/etc/
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Test that either server can run either&amp;nbsp;service.&lt;/p&gt;
&lt;p&gt;On the database&amp;nbsp;server:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# stop mysql
# ifconfig eth0:1 down
# umount /var/mysql/
# drbdadm secondary mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On the web application&amp;nbsp;server:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# drbdadm primary mysql
# mount /dev/drbd0 /var/mysql/
# ifconfig eth0:1 priv.f.f.f netmask 255.255.128.0
# start mysql
# mysql -p
# stop mysql
# ifconfig eth0:1 down
# umount /var/mysql/
# drbdadm secondary mysql
# /etc/init.d/lighttpd stop
# umount /var/www
# drbdadm secondary www
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On the database&amp;nbsp;server:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# drbdadm primary mysql
# drbdadm primary www
# mount /dev/drbd0 /var/mysql/
# mount /dev/drbd1 /var/www/
# /etc/init.d/lighttpd start
# ps ax | grep light
# /etc/init.d/lighttpd stop
# umount /var/www
# drbdadm secondary www
# ifconfig eth0:1 priv.f.f.f 255.255.128.0
# start mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On the web application&amp;nbsp;server:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# drbdadm primary www
# mount /dev/drbd1 /var/www
# /etc/init.d/lighttpd start
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Configure a failover&amp;nbsp;cluster&lt;/h2&gt;
&lt;p&gt;Just a note here before we start. I would have liked to run corosync&lt;sup id=&quot;fnref:corosync&quot;&gt;&lt;a href=&quot;#fn:corosync&quot; rel=&quot;footnote&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; rather than heartbeat&lt;sup id=&quot;fnref:heartbeat&quot;&gt;&lt;a href=&quot;#fn:heartbeat&quot; rel=&quot;footnote&quot;&gt;6&lt;/a&gt;&lt;/sup&gt; based solely on my understanding of pacemaker&lt;sup id=&quot;fnref:pacemaker&quot;&gt;&lt;a href=&quot;#fn:pacemaker&quot; rel=&quot;footnote&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;, how and why it split from heartbeat. However, corosync seems to mostly require multicast networking to work&lt;sup id=&quot;fnref:mcast&quot;&gt;&lt;a href=&quot;#fn:mcast&quot; rel=&quot;footnote&quot;&gt;8&lt;/a&gt;&lt;/sup&gt; and after some struggles, I&amp;#8217;ve learned that Linode doesn&amp;#8217;t support&amp;nbsp;multicast.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Set up heartbeat and&amp;nbsp;pacemaker&lt;/p&gt;
&lt;p&gt;Install and configure software on both&amp;nbsp;servers&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# apt-get install heartbeat pacemaker
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Edit &lt;code&gt;/usr/lib/ocf/resource.d/heartbeat/Filesystem&lt;/code&gt; to comment out this whole block. This will fix a problem with the script&amp;#8217;s handling of jfs filesystems. Besides, they say right in the code, &amp;#8220;Why should a filesystem resource agent magically load a kernel module?&amp;#8221; I agree. Lemme handle that part and just mount the drive&amp;nbsp;please.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# vi /usr/lib/ocf/resource.d/heartbeat/Filesystem

    #       if [ &quot;X${HOSTOS}&quot; != &quot;XOpenBSD&quot; ];then
    #               # Insert SCSI module
    #               # TODO: This probably should go away. Why should the filesystem
    #               # RA magically load a kernel module?
    #               $MODPROBE scsi_hostadapter &amp;gt;/dev/null 
    #
    #               if [ -z &quot;$FSTYPE&quot; -o &quot;$FSTYPE&quot; = none ]; then
    #                       : No FSTYPE specified, rely on the system has the right file-system support already 
    #               else
    #                       # Insert Filesystem module
    #                       $MODPROBE $FSTYPE &amp;gt;/dev/null 
    #                       grep -e &quot;$FSTYPE&quot;&#39;$&#39; /proc/filesystems &amp;gt;/dev/null
    #                       if [ $? -ne 0 ] ; then
    #                               ocf_log err &quot;Couldn&#39;t find filesystem $FSTYPE in /proc/filesystems&quot;
    #                               return $OCF_ERR_INSTALLED
    #                       fi
    #               fi
    #       fi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Configuration&amp;nbsp;files:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# vi /etc/ha.d/authkeys

    auth 1
    1 sha1 Don&#39;tTell

# chmod 600 /etc/heartbeat/authkeys

# vi /etc/ha.d/ha.cf

    autojoin none
    logfacility daemon
    keepalive 2
    deadtime 15
    warntime 5
    initdead 120
    udpport 694
    ucast eth0 priv.a.a.a
    ucast eth0 priv.g.g.g
    node alice
    node gertrude
    auto_failback on
    use_logd yes
    crm respawn
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Propogate the configuration and restart each&amp;nbsp;server&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# scp -r /etc/ha.d/* root@gertrude:/etc/ha.d/

# /etc/init.d/heartbeat restart
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Disable automatic start of Lighttpd (using &lt;span class=&quot;caps&quot;&gt;LSB&lt;/span&gt;) and MySQL (using&amp;nbsp;Upstart)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# update-rc.d lighttpd disable
# vi /etc/init/mysql.conf

    # Comment out the startup
    #start on (net-device-up
    #          and local-filesystems
    #         and runlevel [2345])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Configure the&amp;nbsp;resources&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# vi /usr/lib/ocf/resource.d/linbit/drbd

    OCF_RESKEY_drbdconf_default=&quot;/usr/local/etc/drbd.conf&quot;

# crm configure

    primitive db_alert ocf:heartbeat:MailTo \
        params email=&quot;root&quot; subject=&quot;(db)&quot;
    primitive db_drbd ocf:linbit:drbd \
        params drbd_resource=&quot;mysql&quot; \
        op start interval=&quot;0&quot; timeout=&quot;240&quot; \
        op stop interval=&quot;0&quot; timeout=&quot;100&quot;
    primitive db_fs ocf:heartbeat:Filesystem \
        params device=&quot;/dev/drbd0&quot; directory=&quot;/var/mysql&quot; fstype=&quot;jfs&quot; \
        op start interval=&quot;0&quot; timeout=&quot;60&quot; \
        op stop interval=&quot;0&quot; timeout=&quot;120&quot;
    primitive db_ip ocf:heartbeat:IPaddr \
        params ip=&quot;priv.f.f.f&quot; cidr_netmask=&quot;24&quot;
    primitive db_mysql lsb:mysql \
        op monitor interval=&quot;0&quot; enabled=&quot;false&quot;

    primitive www_alert ocf:heartbeat:MailTo \
        params email=&quot;root&quot; subject=&quot;(www)&quot;
    primitive www_drbd ocf:linbit:drbd \
        params drbd_resource=&quot;www&quot; \
        op start interval=&quot;0&quot; timeout=&quot;240&quot; \
        op stop interval=&quot;0&quot; timeout=&quot;100&quot;
    primitive www_fs ocf:heartbeat:Filesystem \
        params device=&quot;/dev/drbd1&quot; directory=&quot;/var/www&quot; fstype=&quot;ext4&quot; \
        op start interval=&quot;0&quot; timeout=&quot;60&quot; \
        op stop interval=&quot;0&quot; timeout=&quot;120&quot;
    primitive www_ip ocf:heartbeat:IPaddr \
        params ip=&quot;pub.f.f.f&quot; cidr_netmask=&quot;24&quot;
    primitive www_lighty lsb:lighttpd \
        op monitor interval=&quot;0&quot; enabled=&quot;false&quot;

    group db db_ip db_fs db_mysql db_alert \
        meta target-role=&quot;Started&quot;

    group www www_fs www_ip www_lighty www_alert \
        meta target-role=&quot;Started&quot;

    ms ms_db_drbd db_drbd \
        meta master-max=&quot;1&quot; master-node-max=&quot;1&quot; clone-max=&quot;2&quot; clone-node-max=&quot;1&quot; notify=&quot;true&quot;

    ms ms_www_drbd www_drbd \
        meta master-max=&quot;1&quot; master-node-max=&quot;1&quot; clone-max=&quot;2&quot; clone-node-max=&quot;1&quot; notify=&quot;true&quot;

    location db_gertrude db 10: gertrude
    location db_alice db 100: alice
    location www_gertrude www 100: gertrude
    location www_alice www 10: alice

    colocation db_on_drbd inf: db ms_db_drbd:Master
    colocation www_on_drbd inf: www ms_www_drbd:Master

    order db_after_drbd inf: ms_db_drbd:promote db:start
    order www_after_drbd inf: ms_www_drbd:promote www:start

    property cluster-infrastructure=&quot;Heartbeat&quot; \
        stonith-enabled=&quot;false&quot; \
        no-quorum-policy=&quot;ignore&quot; \
        default-resource-stickiness=&quot;5&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;

   </content></entry><entry><title>A new OpenERP product and license</title><author><name>Rob Martin</name></author><link href="http://www.version2beta.com/archive/2011/a-new-openerp-product-and-license.html"/><updated>2011-06-27T20:03:00Z</updated><published>2011-06-27T20:03:00Z</published><id>http://www.version2beta.com/archive/2011/a-new-openerp-product-and-license.html</id><content type="html">
       
&lt;!-- Hyde::Excerpt::Begin --&gt;

&lt;p&gt;Last Friday (June 24, 2011) under an unassuming headline &amp;#8216;Improved OpenERP Website&amp;#8217;,&lt;sup id=&quot;fnref:headline&quot;&gt;&lt;a href=&quot;#fn:headline&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; OpenERP announced the new Enterprise edition of the OpenERP software. The response among community members was swift. Two topics attracted most of the conversation: the new OpenERP &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt; + Private Use license&lt;sup id=&quot;fnref:private-use&quot;&gt;&lt;a href=&quot;#fn:private-use&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; available only to Enterprise edition customers, and apparent policy changes regarding security&amp;nbsp;alerts.&lt;/p&gt;
&lt;!-- Hyde::Excerpt::End --&gt;

&lt;h2&gt;The OpenERP &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt; + Private Use&amp;nbsp;license&lt;/h2&gt;
&lt;p&gt;Essentially, OpenERP &lt;span class=&quot;caps&quot;&gt;SA&lt;/span&gt; has introduced a dual licensing model for
the OpenERP&amp;nbsp;program.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Download the community version and the code is strictly
    licensed under the &lt;span class=&quot;caps&quot;&gt;GNU&lt;/span&gt; Affero Public License&lt;sup id=&quot;fnref:affero&quot;&gt;&lt;a href=&quot;#fn:affero&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;, which is much
    like the &lt;span class=&quot;caps&quot;&gt;GNU&lt;/span&gt; General Public License&lt;sup id=&quot;fnref:gpl&quot;&gt;&lt;a href=&quot;#fn:gpl&quot; rel=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; except that it closes what
    is sometimes called the “Application Service Provider&amp;nbsp;Loophole”.&lt;/li&gt;
&lt;li&gt;Subscribers of the OpenERP Enterprise Edition receive much the
    same code as the community users, but they are conveyed the right
    to create “private modules”. These modules are meant for companies
    that need to include confidential data and/or business practices in
    their customizations to the program. This second, private license
    grants such users an exception to the &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt; so that they are not
    required to distribute that sensitive code to users of the system,
    but only under very limited&amp;nbsp;circumstances.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I have no doubt this additional license addresses a need or meets a
demand among some users of OpenERP. Certainly I can see how it
might desirable, or even necessary in some applications.
Nonetheless, members of the OpenERP community raised serious
concerns about this&amp;nbsp;announcement.&lt;/p&gt;
&lt;h3&gt;The right to&amp;nbsp;license&lt;/h3&gt;
&lt;p&gt;OpenERP &lt;span class=&quot;caps&quot;&gt;SA&lt;/span&gt; owns the rights to a significant portion of the source
code for the OpenERP system. However, portions of the core code for
OpenERP, and the vast majority of the 1,200 modules for OpenERP,
were written by developers who have not handed their rights over to
OpenERP &lt;span class=&quot;caps&quot;&gt;SA&lt;/span&gt;. As such, these developers have the right to release
their code as they choose. In fact, they have exercised that right
in releasing their code under the &lt;span class=&quot;caps&quot;&gt;GNU&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt; license, which is why
their modules can be distributed along with the rest of the OpenERP&amp;nbsp;system.&lt;/p&gt;
&lt;p&gt;For clarity I should note that
&lt;strong&gt;all OpenERP modules must be licensed under the &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt;&lt;/strong&gt;, as they
are derivative works of OpenERP, which is released under the &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt;
license. (There is an exception for &lt;span class=&quot;caps&quot;&gt;GPL&lt;/span&gt; licensed code; more below.)
This isn’t to say that anyone anywhere should have access to the
source code for any custom OpenERP module ever written, but because
OpenERP itself is released
&lt;strong&gt;under the &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt;, the users of any given OpenERP system have the right to the source code for the entire system including the custom modules&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;It is unclear at this point exactly what code OpenERP &lt;span class=&quot;caps&quot;&gt;SA&lt;/span&gt; will be
offering under this new dual license. It could be as described
above – only including core code and modules to which OpenERP owns
all the rights. It’s my opinion (and I am not a lawyer) that they
could license a system comprised only of OpenERP &lt;span class=&quot;caps&quot;&gt;SA&lt;/span&gt; code under any
license they wish. But some community members fear it will include
work they created, relicensed without their&amp;nbsp;permission.&lt;/p&gt;
&lt;p&gt;One basis for this concern is that OpenERP &lt;span class=&quot;caps&quot;&gt;SA&lt;/span&gt; code, without modules
and base code contributed by community developers, may be
insufficient for building an effective &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; system. If this is the
case, every Enterprise edition installation will include community&amp;nbsp;code.&lt;/p&gt;
&lt;p&gt;Another basis for this concern might be drawn from the new dual
license itself. In reviewing the text of their OpenERP &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt; +
Private Use license, some of the terms seem to include code created
by the&amp;nbsp;community.&lt;/p&gt;
&lt;p&gt;Under section 0, &lt;em&gt;Additional Definitions&lt;/em&gt;, the license defines
Program to include all components without limitation (emphasis is&amp;nbsp;mine):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In the context of this License, the Program refers to OpenERP
&lt;strong&gt;&lt;em&gt;including all its components: client programs, server system, modules, etc.&lt;/em&gt;&lt;/strong&gt;
“OpenERP modules” are extensions to the Program that can be
activated&amp;nbsp;separately.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Under section 1, &lt;em&gt;Exceptions to section 13 of the &lt;span class=&quot;caps&quot;&gt;GNU&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt;&lt;/em&gt;,
describing the conditions required for the exception, the license
implies that OpenERP &lt;span class=&quot;caps&quot;&gt;SA&lt;/span&gt; is the original licensor of the program
defined to include all components in section 0 (again, emphasis is&amp;nbsp;mine):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;a. You have received written permission to do so
 &lt;strong&gt;&lt;em&gt;from the original licensor of the Program, OpenERP&amp;nbsp;&lt;span class=&quot;caps&quot;&gt;S.A.&lt;/span&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;b. You do not convey the covered&amp;nbsp;work.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One could read this as OpenERP &lt;span class=&quot;caps&quot;&gt;SA&lt;/span&gt; claiming licensing rights to code
written by the community, and several developers in the community
interpreted the announcement in exactly this&amp;nbsp;way.&lt;/p&gt;
&lt;h3&gt;Compatible&amp;nbsp;licenses&lt;/h3&gt;
&lt;p&gt;Under the terms of the dual license, nearly all of the code
distributed to an Enterprise edition subscriber is licensed &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt;.
The subscriber then has the option of creating a derived work (in
the form of a module that extends the functionality of the system)
that is not open source. Under the &lt;span class=&quot;caps&quot;&gt;GPL&lt;/span&gt; this is clearly allowed. The
Free Software Foundation has made this clear in the
Frequently Asked Questions about the &lt;span class=&quot;caps&quot;&gt;GNU&lt;/span&gt; Licenses:&lt;sup id=&quot;fnref:gpl-faq&quot;&gt;&lt;a href=&quot;#fn:gpl-faq&quot; rel=&quot;footnote&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; ”The &lt;span class=&quot;caps&quot;&gt;GPL&lt;/span&gt;
does not require you to release your modified version, or any part
of it. You are free to make modifications and use them privately,
without ever releasing them.” In fact, OpenERP’s language even
parallels that of the Free Software Foundation in terming the
license “&lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt; + Private&amp;nbsp;Use”.&lt;/p&gt;
&lt;p&gt;If OpenERP were released under the &lt;span class=&quot;caps&quot;&gt;GPL&lt;/span&gt; (as it used to be), private
use of modified source code could cover Application Service
Providers offering the program as a service over a network, and
then the provider would not be required to offer their customers
the source code for the program. OpenERP base code and all modules,
however, are released under the Affero &lt;span class=&quot;caps&quot;&gt;GPL&lt;/span&gt; license that plugs the
Application Service Provider loophole. Users of the system, even
those accessing it as an online service, must be prominently
offered the opportunity to download all corresponding source&amp;nbsp;code.&lt;/p&gt;
&lt;p&gt;I mentioned briefly above that there is the option to combine
another (possibly non-derivative) work licensed under the &lt;span class=&quot;caps&quot;&gt;GPL&lt;/span&gt; with
OpenERP licensed under the &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt;. The terms of the &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt; suggest the
&lt;span class=&quot;caps&quot;&gt;GPL&lt;/span&gt; portion of the combined work would be covered under the &lt;span class=&quot;caps&quot;&gt;GPL&lt;/span&gt;
license. However, Section 13 of the &lt;span class=&quot;caps&quot;&gt;GPL&lt;/span&gt; clearly states that “the
special requirements of the &lt;span class=&quot;caps&quot;&gt;GNU&lt;/span&gt; Affero General Public License,
section 13, concerning interaction through a network will apply to
the combination as such.” So even combined with the explicitly
compatible &lt;span class=&quot;caps&quot;&gt;GPL&lt;/span&gt; license, the more restrictive (from the publishers
perspective) requirement to prominently offer source code applies,
even to the &lt;span class=&quot;caps&quot;&gt;GPL&lt;/span&gt;&amp;nbsp;code.&lt;/p&gt;
&lt;h3&gt;Why it&amp;nbsp;matters&lt;/h3&gt;
&lt;p&gt;In many cases, an OpenERP installation with base and
community-developed modules will be sufficient all by itself. No
additional modules are needed, let alone custom modules containing
hard-coded sensitive business intelligence. In cases where custom
modules are required, much or all of the sensitive business
intelligence can or should be integrated as data, not program code.
(Pricelists, for instance, are data and under normal circumstances
would never need to be distributed with the source code for a
program.) In the rare circumstances where business methods are
implemented by a module, the source code must be available to the
company that performed (or hired) the modifications, and their&amp;nbsp;users.&lt;/p&gt;
&lt;p&gt;Those final three words, “and their users”, contain the key to
understanding the change. The &lt;span class=&quot;caps&quot;&gt;GPL&lt;/span&gt; was created in large part to
protect users by ensuring they have access to the source code of
the programs on which they depend, and some companies would not
wish employees and other system users to have access to the source&amp;nbsp;code.&lt;/p&gt;
&lt;p&gt;The &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt; extends that protection to include another class of users,
those that access the system across a network. In this case, that
will include users who subscribe to OpenERP under a
Software as a Service (SaaS)&lt;sup id=&quot;fnref:saas&quot;&gt;&lt;a href=&quot;#fn:saas&quot; rel=&quot;footnote&quot;&gt;6&lt;/a&gt;&lt;/sup&gt; model. Under the &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt;, no company
(including OpenERP &lt;span class=&quot;caps&quot;&gt;SA&lt;/span&gt;) could offer OpenERP as a hosted service
without offering links to download their service’s source code,
including custom modules. Under the dual license, only the code
which is distributed (sold or given away to other companies) must
include the option to download&amp;nbsp;source.&lt;/p&gt;
&lt;p&gt;SaaS is a powerful and lucrative force in the market. OpenERP &lt;span class=&quot;caps&quot;&gt;SA&lt;/span&gt;
itself is promoting their
online service at 39€ per month per user&lt;sup id=&quot;fnref:openerp-saas&quot;&gt;&lt;a href=&quot;#fn:openerp-saas&quot; rel=&quot;footnote&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;. In the &lt;span class=&quot;caps&quot;&gt;US&lt;/span&gt;, a company
of merely twenty employees would be paying $11,760.00 a year for
the service. Under the &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt;, OpenERP &lt;span class=&quot;caps&quot;&gt;SA&lt;/span&gt; is required to allow me
(assuming I am an online user) to download the source code,
including the source code for any modules they’ve written
exclusively for their online service, which I may then use to
create a competing service. Under the dual license, for some amount
of money starting at 1,950€ per year, I can create a custom module
for SaaS and not offer the source code to my users. Or, if I’m
OpenERP, perhaps I can just do it for&amp;nbsp;free.&lt;/p&gt;
&lt;h3&gt;Community&amp;nbsp;Relations&lt;/h3&gt;
&lt;p&gt;In the two years I’ve been working with OpenERP, I’ve watched
OpenERP &lt;span class=&quot;caps&quot;&gt;SA&lt;/span&gt; sink in the estimation of many community members and
developers. The release of the Enterprise edition with a dual
license may have created a new&amp;nbsp;low.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://twitter.com/#!/fpopenerp/status/73712952632545280&quot; title=&quot;Click the image to view Fabien Pinckaers&#39; tweet at Twitter.com&quot; target=&quot;_blank&quot;&gt;
  &lt;img src=&quot;/media/2011/openerp-no-dual-license-tweet-may-26-2011.png&quot; alt=&quot;Fabien&#39;s No Dual License tweet&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;(&lt;strong&gt;Update 23 August 2011:&lt;/strong&gt; This tweet has been removed from Fabien Pinckaer&amp;#8217;s Twitter account, so if you click on the image, you&amp;#8217;ll see a Twitter 404&amp;nbsp;page.)&lt;/p&gt;
&lt;p&gt;I first heard of the dual license possibility from the transcript
of a Certified Training Partner (&lt;span class=&quot;caps&quot;&gt;CTP&lt;/span&gt;) meeting held on &lt;span class=&quot;caps&quot;&gt;IRC&lt;/span&gt; in May.
(I am not a &lt;span class=&quot;caps&quot;&gt;CTP&lt;/span&gt;, but a link to the transcript was provided by an
attendee.) Some partners in the meeting expressed considerable
opposition to the idea at that time, and Fabien Pinckaers made what
many would consider an unequivocable statement on May 26th that
there would be no dual-license. Nonetheless, the June 24
announcement indicates Enterprise subscribers will have access to
the new dual&amp;nbsp;license.&lt;/p&gt;
&lt;p&gt;It could be argued that Fabien’s tweet has not been&amp;nbsp;violated:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The new license is a modified &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt;, granting additional
    permissions in limited&amp;nbsp;circumstances.&lt;/li&gt;
&lt;li&gt;Only undistributed custom modules qualify for the private use
    license. For the rest of the software, the license is modified from
    &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt; only enough to allow for those private modules to be installed
    with the&amp;nbsp;system.&lt;/li&gt;
&lt;li&gt;Fabien didn’t &lt;em&gt;actually&lt;/em&gt; say they wouldn’t dual license, only
    that they didn’t have to. (Okay, this one feels like a&amp;nbsp;stretch.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I haven’t heard these arguments presented by anyone in the
community, but my impression is they are not reassuring. My own
employer tweeted last&amp;nbsp;Friday:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://twitter.com/#!/lageekitude/status/84306783111352320&quot; title=&quot;Click the image to view @LaGeekitude&#39;s tweet at Twitter.com&quot; target=&quot;_blank&quot;&gt;
  &lt;img src=&quot;/media/2011/openerp-tryton-house-tweet-jun-242.png&quot; alt=&quot;Ditching OpenERP for Tryton?&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Security&amp;nbsp;Alerts&lt;/h2&gt;
&lt;p&gt;On the OpenERP ‘Buy’ page&lt;sup id=&quot;fnref:catalog&quot;&gt;&lt;a href=&quot;#fn:catalog&quot; rel=&quot;footnote&quot;&gt;8&lt;/a&gt;&lt;/sup&gt; showing the options for purchase and
download, the presence of ‘Security Alerts’ under OpenERP
Enterprise, and only under Enterprise, attracted&amp;nbsp;conversation.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://twitter.com/#!/sharoonthomas/status/84269468506800128&quot; title=&quot;A Twitter comment by @SharoonThomas&quot;&gt;@SharoonThomas&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Acc to &lt;a href=&quot;http://twitter.com/OpenERP&quot;&gt;@openerp&lt;/a&gt; community users will not get security alerts.
Not needed since community has always found security holes, not
openerp&amp;nbsp;&lt;span class=&quot;caps&quot;&gt;SA&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;http://twitter.com/#!/sharoonthomas/status/84269785071882240&quot; title=&quot;A follow-up comment by @sharoonthomas&quot;&gt;@SharoonThomas&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;http://twitter.com/OpenERP&quot;&gt;@openerp&lt;/a&gt; how dare u talk about security alerts when u dont know
why software needs encrypted passwords &lt;span class=&quot;amp&quot;&gt;&amp;amp;&lt;/span&gt; not plain text??
&lt;a href=&quot;http://j.mp/lffPGi&quot;&gt;http://j.mp/lffPGi&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;http://twitter.com/#!/lageekitude/status/84279132279672832&quot; title=&quot;A Twitter comment by @lageekitude&quot;&gt;@LaGeekitude&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Security alerts should be public announcements. All users deserve
notice. &lt;a href=&quot;http://twitter.com/OpenERP&quot;&gt;@OpenERP&lt;/a&gt; &lt;a href=&quot;http://twitter.com/fpopenerp&quot;&gt;@fpopenerp&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Upon closer review, it’s apparent that OpenERP only promises that
Enterprise customers will receive notices in advance of a public
disclosure. This is detailed on the multiple product pages
describing OpenERP Enterprise, such as
the page describing the 70 to 150 user license&lt;sup id=&quot;fnref:150users&quot;&gt;&lt;a href=&quot;#fn:150users&quot; rel=&quot;footnote&quot;&gt;9&lt;/a&gt;&lt;/sup&gt; (emphasis is&amp;nbsp;mine):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If we detect a security issue on OpenERP
&lt;strong&gt;&lt;em&gt;we develop the patch and warn our customers three weeks before a public announcement&lt;/em&gt;&lt;/strong&gt;.
We also provide you with the explanation on how to migrate or apply
the security patch. After three weeks, we do a public communication
about the security hole for the rest of the community. We strongly
advice you to apply the patch to your server within these three
weeks to avoid any security&amp;nbsp;trouble.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Under the OpenERP Publisher’s Warranty, the promise regarding
security alerts was even less favorable to community users (again,
emphasis is&amp;nbsp;mine):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As OpenERP manages critical data for your company, it is important
to be very proactive in case of a vulne­rability issue detection in
the OpenERP software. Once a security bug is detected by OpenERP sa
or by the community,
&lt;strong&gt;&lt;em&gt;we provide you with a patch to fix the issue one month before the public announce of the security fix&lt;/em&gt;&lt;/strong&gt;.
This allows you to update your installation before the public
announce and release of the&amp;nbsp;patch.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Since the new Enterprise offerings replace the OpenERP Publisher’s
Warranty, it seems likely that the Enterprise policy on security
alerts will become the current practice. In effect, this is an
improvement over the previous&amp;nbsp;practice.&lt;/p&gt;
&lt;h2&gt;OpenERP &lt;span class=&quot;caps&quot;&gt;SA&lt;/span&gt; and the commercial open source business&amp;nbsp;model&lt;/h2&gt;
&lt;p&gt;I can certainly relate to the community of developers who are
concerned and frustrated by OpenERP &lt;span class=&quot;caps&quot;&gt;SA&lt;/span&gt;’s announcement. Some of the
developers have devoted literally months of their time to make
OpenERP a better product, and have reason to feel used, even
abused, by liberties that may be (or have been) taken with their
hard work. Because of this, I’ve tried to discuss the situation
objectively, and I hope I’ve demonstrated that the situation is not
quite as bad as it seemed at first. There are unanswered questions,
and I trust OpenERP &lt;span class=&quot;caps&quot;&gt;SA&lt;/span&gt; will answer those through further
communication and their future&amp;nbsp;actions.&lt;/p&gt;
&lt;p&gt;It is important to consider that OpenERP &lt;span class=&quot;caps&quot;&gt;SA&lt;/span&gt; is working to cement
their commercial open source business model. We know what to
expect: a difficult transition, especially for early adopters and
contributors as more of the product is brought under the company’s
control. They are master editor of the software, selling services
to end users as well as companies offering services related to
their software. With persistence and planning, OpenERP &lt;span class=&quot;caps&quot;&gt;SA&lt;/span&gt; and many
of their partners will enjoy a profitable&amp;nbsp;future.&lt;/p&gt;
&lt;p&gt;One freedom often ascribed to the &lt;span class=&quot;caps&quot;&gt;GPL&lt;/span&gt; is the freedom to not use the
software. Don’t like the fact you have to release your source code?
Don’t use it. Don’t like the direction the project is going? Fork&amp;nbsp;it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Please don’t hesitate to do your own investigation about the new OpenERP products and licenses.&lt;/strong&gt;
Visit their website&lt;sup id=&quot;fnref:openerp&quot;&gt;&lt;a href=&quot;#fn:openerp&quot; rel=&quot;footnote&quot;&gt;10&lt;/a&gt;&lt;/sup&gt;, especially their &lt;span class=&quot;caps&quot;&gt;FAQ&lt;/span&gt; on the changes&lt;sup id=&quot;fnref:openerp-faq&quot;&gt;&lt;a href=&quot;#fn:openerp-faq&quot; rel=&quot;footnote&quot;&gt;11&lt;/a&gt;&lt;/sup&gt;
and community section&lt;sup id=&quot;fnref:community&quot;&gt;&lt;a href=&quot;#fn:community&quot; rel=&quot;footnote&quot;&gt;12&lt;/a&gt;&lt;/sup&gt; for information on all of their
communication&amp;nbsp;channels.&lt;/p&gt;
&lt;h3&gt;In related&amp;nbsp;news…&lt;/h3&gt;
&lt;p&gt;Nicolas Évrard of &lt;span class=&quot;caps&quot;&gt;B2CK&lt;/span&gt;&lt;sup id=&quot;fnref:b2ck&quot;&gt;&lt;a href=&quot;#fn:b2ck&quot; rel=&quot;footnote&quot;&gt;13&lt;/a&gt;&lt;/sup&gt; posted to the Tryton mailing list&lt;sup id=&quot;fnref:groups-general&quot;&gt;&lt;a href=&quot;#fn:groups-general&quot; rel=&quot;footnote&quot;&gt;14&lt;/a&gt;&lt;/sup&gt;
last Saturday a
call for comments on the creation of the Tryton Software Foundation&lt;sup id=&quot;fnref:foundation&quot;&gt;&lt;a href=&quot;#fn:foundation&quot; rel=&quot;footnote&quot;&gt;15&lt;/a&gt;&lt;/sup&gt;.
&lt;span class=&quot;caps&quot;&gt;B2CK&lt;/span&gt; proposes this foundation as a consensus-based community formed
to promote and protect the freedom of Tryton. As Tryton and OpenERP
share a common lineage (both can be traced back to TinyERP, each
with improvements in different areas), OpenERP users and
contributors frustrated by OpenERP’s business model may find a more
favorable environment among Tryton’s community open source&amp;nbsp;model.&lt;/p&gt;
&lt;p&gt;I have been writing a series of articles on Tryton on this blog; consult
them or visit Tryton’s website&lt;sup id=&quot;fnref:tryton.org&quot;&gt;&lt;a href=&quot;#fn:tryton.org&quot; rel=&quot;footnote&quot;&gt;16&lt;/a&gt;&lt;/sup&gt; for more&amp;nbsp;information.&lt;/p&gt;
&lt;h3&gt;&lt;em&gt;Updated 28 June&amp;nbsp;2011&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;There has been remarkable conversation on Twitter regarding this
post, and I’m grateful for all the feedback. I’d especially like to
thank Olivier Dony (&lt;a href=&quot;http://twitter.com/#!/odony&quot; title=&quot;Olivier Dony on Twitter&quot;&gt;@odony&lt;/a&gt; on Twitter), Community Manager at
OpenERP &lt;span class=&quot;caps&quot;&gt;SA&lt;/span&gt;, for his clarifications on some of the points I’ve&amp;nbsp;raised.&lt;/p&gt;
&lt;p&gt;The biggest comes from this tweet, which &lt;a href=&quot;http://twitter.com/#!/rvalyi&quot; title=&quot;Raphaël Valyi on Twitter&quot;&gt;@ravlyi&lt;/a&gt; described as
“the missing OpenERP re-licensing&amp;nbsp;&lt;span class=&quot;caps&quot;&gt;FAQ&lt;/span&gt;”:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://twitter.com/#!/odony/status/85706734865367040&quot; title=&quot;Click the image to view Olivier Dony&#39;s tweet at Twitter.com&quot; target=&quot;_blank&quot;&gt;
  &lt;img src=&quot;/media/2011/openerp-relicensing-faq-tweet-from-odony.png&quot; alt=&quot;Olivier Dony&#39;s Not Compatible tweet&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This certainly seems to make clear that no Enterprise edition
customer using private modules may install any &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt;-only modules.
It doesn’t answer concerns about what happens if an Enterprise
edition subscriber installs a community module, or about community
contributions to OpenERP core code, such as the netsvc.py&lt;sup id=&quot;fnref:netsvc&quot;&gt;&lt;a href=&quot;#fn:netsvc&quot; rel=&quot;footnote&quot;&gt;17&lt;/a&gt;&lt;/sup&gt; file
&lt;a href=&quot;http://twitter.com/#!/cedrickrier&quot; title=&quot;Cédric Krier on Twitter&quot;&gt;@cedrickrier&lt;/a&gt; tweeted from OpenERP-server trunk, as excerpted&amp;nbsp;here:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;…  
5 \# OpenERP, Open Source Management Solution  
6 \# Copyright (C) 2004-2009 Tiny SPRL (). All Rights Reserved  
7 \# The refactoring about the OpenSSL support come from Tryton  
8 \# Copyright (C) 2007-2009 Cédric Krier.  
9 \# Copyright (C) 2007-2009 Bertrand Chenal.  
10 \# Copyright (C) 2008 B2CK SPRL.  
…
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also, one aspect I did not address in the original post was
OpenERP’s original transition from &lt;span class=&quot;caps&quot;&gt;GPL&lt;/span&gt; to &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt;.
Fabien Pinckaers discussed it on his Blogspot blog&lt;sup id=&quot;fnref:fpblog&quot;&gt;&lt;a href=&quot;#fn:fpblog&quot; rel=&quot;footnote&quot;&gt;20&lt;/a&gt;&lt;/sup&gt; and
reviewing this clears any question about his thoughts at that time
on SaaS and&amp;nbsp;OpenERP:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Our goal is to better promote and maintain the free and open
source nature of OpenERP. We think this licence will better protect
the community to ‘evil’ SaaS offers that do not want to release
their source code to the&amp;nbsp;community.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It’s my opinion (and again, I am not a lawyer) that the new
&lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt;+Private enables the ‘evil SaaS offers’ Fabien warns about, so
long as the SaaS provider is either a paying OpenERP Enterprise
subscriber, or OpenERP &lt;span class=&quot;caps&quot;&gt;SA&lt;/span&gt; themselves.
&lt;strong&gt;I am in no way saying it is OpenERP &lt;span class=&quot;caps&quot;&gt;SA&lt;/span&gt;’s intention to support a secondary SaaS market based on private modules, or to create private modules for their own SaaS product.&lt;/strong&gt;
I merely point at the license and say I think it could be done
under these&amp;nbsp;terms.&lt;/p&gt;
&lt;h3&gt;&lt;em&gt;Updated 23 August&amp;nbsp;2011&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;I was doing maintenance on this post (moving it to the version2beta.com domain with the rest of my blog) and came across some discrepencies between linked documents when I wrote the post, and how those documents appear today. For example, the netsvc.py&lt;sup id=&quot;fnref:netsvc&quot;&gt;&lt;a href=&quot;#fn:netsvc&quot; rel=&quot;footnote&quot;&gt;17&lt;/a&gt;&lt;/sup&gt; discussion above: Cédric Krier&amp;#8217;s copyright no longer appears in the header in the trunk source code. I researched the revision and found this:&lt;sup id=&quot;fnref:revision&quot;&gt;&lt;a href=&quot;#fn:revision&quot; rel=&quot;footnote&quot;&gt;18&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Committer: Olivier Dony
Date: 2011-06-29 09:51:38
Revision ID: odo@openerp.com-20110629095138-hmo91mvk1m8u4643
[FIX] netsvc: corrected copyright header

Corrected license to AGPLv3, and removed obsolete copyright lines
as confirmed by Cedric Krier by email on 2011-06-29.
These copyright lines referred to a refactoring copied from Tryton
in revision rev 1439 - stephane@tinyerp.com-20081218235433-cnsc5a4iyfzqvbdx
All this code has disappeared since then, specifically after
a major rewrite by xrg, merged at revision 1900 
(mga@tinyerp.com-20091126113653-0ym60nvtjinvp82h).
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This was reassuring, that the copyright notice was in error. I believe it is better that my research into the issue exposed an oversight rather than a disagreement over who owns the code. According to Oliver Dony&amp;#8217;s forum post two weeks later, all such issues are resolved:&lt;sup id=&quot;fnref:forum&quot;&gt;&lt;a href=&quot;#fn:forum&quot; rel=&quot;footnote&quot;&gt;19&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;p&gt;OpenERP &lt;span class=&quot;caps&quot;&gt;SA&lt;/span&gt; does own the copyright to the server, clients, and all modules whose author is OpenERP/Tiny. And we are exclusively offering the &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt;+PrivateUse option for those pieces of code, and nothing else. If someone believes they own copyright on a contribution within that specific set of source code lines, and are against the &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt;+PrivateUse license, they can contact us, and we&amp;#8217;ll find a solution. We&amp;#8217;ve only seen one such claim so far (from C.Krier), and it was about code that was long gone from our source, so there was no problem. So if you are such a person, please contact&amp;nbsp;us.&lt;/p&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Again, this claim is reassuring. However, I understand these are not the only items in question or the only copyright that has been contested. Here are three more sections of code with conflicted&amp;nbsp;copyright.&lt;/p&gt;
&lt;p&gt;In the OpenERP client, widget/view/list.py:&lt;sup id=&quot;fnref:view-list&quot;&gt;&lt;a href=&quot;#fn:view-list&quot; rel=&quot;footnote&quot;&gt;21&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;…
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2010 Tiny SPRL (&amp;lt;http://tiny.be&amp;gt;). All Rights Reserved
6 #    Copyright (c) 2008-2009 B2CK, Bertrand Chenal, Cedric Krier (D&amp;amp;D in lists)
…
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the OpenERP base_vat module:&lt;sup id=&quot;fnref:base-vat&quot;&gt;&lt;a href=&quot;#fn:base-vat&quot; rel=&quot;footnote&quot;&gt;22&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;…
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2010 Tiny SPRL (&amp;lt;http://tiny.be&amp;gt;). All Rights Reserved
6 #    Copyright (C) 2008-2009 B2CK, Cedric Krier, Bertrand Chenal (the methods &quot;check_vat_[a-z]{2}&quot;
…
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And in the webdav module:&lt;sup id=&quot;fnref:webdav&quot;&gt;&lt;a href=&quot;#fn:webdav&quot; rel=&quot;footnote&quot;&gt;23&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;…
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2010 Tiny SPRL (&amp;lt;http://tiny.be&amp;gt;).
6 #    Copyright (c) 1999 Christian Scholz (ruebe@aachen.heimat.de)
…
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Without a complete audit of the source code, all such copyright discrepencies may not be recognized, and it would seem to me that such an audit should occur before the product is&amp;nbsp;relicensed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;One last note:&lt;/strong&gt; Several people have raised the question whether modules in OpenERP (or, in two cases, themes in Wordpress - a similar but not identical question) are in fact derivative works that must be licensed &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt;. This is a big question, of course, and deserves more than merely a mention in an addendum to a months-old blog post. Here I&amp;#8217;d like to point out that I make the statement in my original post that modules must be licensed &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt;, and that this statement is debatable. I hope to question that statement in a future blog&amp;nbsp;post.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;If I’ve inspired a response from you (probably the type of response that deserves an apology), mention &lt;a href=&quot;http://twitter.com/version2beta&quot; title=&quot;Me, twitterfied&quot;&gt;@version2beta&lt;/a&gt; on &lt;a href=&quot;http://twitter.com/&quot; title=&quot;All of twitter, including me.&quot;&gt;Twitter&lt;/a&gt; and I’ll see it there. Or, if you can’t comment in less than 126 characters (my handle takes 14 characters with a space), blog about it and tweet&amp;nbsp;that.&lt;/em&gt;&lt;/p&gt;

   </content></entry><entry><title>Tryton as an e-commerce back-end - Stalking the Tryton community</title><author><name>Rob Martin</name></author><link href="http://www.version2beta.com/archive/2011/evaluating-tryton-as-an-ecommerce-backend_stalking-the-tryton-community.html"/><updated>2011-06-17T12:58:00Z</updated><published>2011-06-17T12:58:00Z</published><id>http://www.version2beta.com/archive/2011/evaluating-tryton-as-an-ecommerce-backend_stalking-the-tryton-community.html</id><content type="html">
       
&lt;!-- Hyde::Excerpt::Begin --&gt;

&lt;p&gt;This is part two in a series exploring how Tryton might fair as the heavy-lifting portion of an e-commerce package. This part discusses some of my experiences with members of the Tryton&amp;nbsp;community.&lt;/p&gt;
&lt;!-- Hyde::Excerpt::End --&gt;

&lt;p&gt;The whole series, at least as&amp;nbsp;planned:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://version2beta.com/archive/2011/evaluating-tryton-as-an-ecommerce-backend_about-tryton.html&quot; title=&quot;Tryton as an e-commerce back-end: About Tryton&quot;&gt;Part 1: About&amp;nbsp;Tryton&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Part 2: Stalking the Tryton&amp;nbsp;community&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://version2beta.com/archive/2011/evaluating-tryton-as-an-ecommerce-backend_web-framework.html&quot; title=&quot;Tryton as an e-commerce back-end: Tryton needs a web framework.&quot;&gt;Part 3: The crux of the&amp;nbsp;matter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;The Tryton&amp;nbsp;community&lt;/h2&gt;
&lt;p&gt;My first experience with Tryton was two years ago, when we were
evaluating open source &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; packages for a business systems
integration project. I came, I saw, and I moved on to OpenERP,
which offered more features and centralized commercial support. Now
that we have considerably more experience with OpenERP, I’ve come
back for a closer look at&amp;nbsp;Tryton.&lt;/p&gt;
&lt;p&gt;I started with the community, and I suspect that is a very valid
approach. I’m looking for a long term relationship. I wanted to
meet the family. So naturally I hid behind some bushes and watched
them for a month or so. Some of the things I&amp;nbsp;noticed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;They don’t bicker very much. Like, hardly at all. Most of the
    communication I’ve seen is in non-native English, and they speak
    carefully so as not to be&amp;nbsp;misunderstood.&lt;/li&gt;
&lt;li&gt;Mostly they are proactive, identifying potential problems and
    solutions before people become invested in various&amp;nbsp;outcomes.&lt;/li&gt;
&lt;li&gt;They air their laundry (bugs, issues, etc) as well as most open
    source projects. It seems they don’t have as much laundry to air,&amp;nbsp;though.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Tryton family has some key members. I’ve identified some of
them from looking at the services page on the website&lt;sup id=&quot;fnref:services&quot;&gt;&lt;a href=&quot;#fn:services&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;, some
from the Google groups for Tryton&lt;sup id=&quot;fnref:groups-general&quot;&gt;&lt;a href=&quot;#fn:groups-general&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; and Tryton-dev&lt;sup id=&quot;fnref:groups-dev&quot;&gt;&lt;a href=&quot;#fn:groups-dev&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;, and some
on &lt;span class=&quot;caps&quot;&gt;IRC&lt;/span&gt;&lt;sup id=&quot;fnref:irc&quot;&gt;&lt;a href=&quot;#fn:irc&quot; rel=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;. Many of these people I also recognized from the OpenERP
community, as there’s considerable overlap. I’m reluctant to point
names and name fingers (with a nod to Jack Sparrow&lt;sup id=&quot;fnref:captainjack&quot;&gt;&lt;a href=&quot;#fn:captainjack&quot; rel=&quot;footnote&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;) as I’m far
too likely to miss someone’s most excellent contribution, and that
would be an unfortunate oversight.  &lt;strong&gt;Kudos and gratitude to everyone who has worked on Tryton.&lt;/strong&gt; Despite my reluctance, I still want to point out a few&amp;nbsp;people.&lt;/p&gt;
&lt;p&gt;There is no doubt a reason why the Tryton.org website&lt;sup id=&quot;fnref:tryton.org&quot;&gt;&lt;a href=&quot;#fn:tryton.org&quot; rel=&quot;footnote&quot;&gt;6&lt;/a&gt;&lt;/sup&gt; looks so
much like &lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;B2CK&lt;/span&gt; Software Development’s website&lt;sup id=&quot;fnref:b2ck&quot;&gt;&lt;a href=&quot;#fn:b2ck&quot; rel=&quot;footnote&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/strong&gt;. I’ve read
hundreds of emails on the mailing lists from Cédric Krier, Nicolas
Évrard, and others in this company. Clearly these are key people in
Tryton development and I cannot say enough nice things. Cédric is a
programming god: targeted, responsive, attentive, and sharp. I
greatly enjoyed the night Udo Spallek recommended two accessibility
improvements to the Tryton &lt;span class=&quot;caps&quot;&gt;GUI&lt;/span&gt; and Cédric replied 52 minutes later
with the one word&amp;nbsp;“Done”.&lt;/p&gt;
&lt;p&gt;I already had a healthy respect (perhaps even a geek-crush) on
&lt;strong&gt;Sharoon Thomas&lt;/strong&gt;&lt;sup id=&quot;fnref:sharoon&quot;&gt;&lt;a href=&quot;#fn:sharoon&quot; rel=&quot;footnote&quot;&gt;8&lt;/a&gt;&lt;/sup&gt;, &lt;span class=&quot;caps&quot;&gt;CEO&lt;/span&gt; of &lt;strong&gt;Openlabs in the &lt;span class=&quot;caps&quot;&gt;UK&lt;/span&gt; and India&lt;/strong&gt;&lt;sup id=&quot;fnref:openlabs&quot;&gt;&lt;a href=&quot;#fn:openlabs&quot; rel=&quot;footnote&quot;&gt;9&lt;/a&gt;&lt;/sup&gt;.
Sharoon and Openlabs have written about
using Tryton as a Python module in Django&lt;sup id=&quot;fnref:django-module&quot;&gt;&lt;a href=&quot;#fn:django-module&quot; rel=&quot;footnote&quot;&gt;10&lt;/a&gt;&lt;/sup&gt;,
integrated &lt;span class=&quot;caps&quot;&gt;UPS&lt;/span&gt; international shipping with OpenERP&lt;sup id=&quot;fnref:ups-module&quot;&gt;&lt;a href=&quot;#fn:ups-module&quot; rel=&quot;footnote&quot;&gt;11&lt;/a&gt;&lt;/sup&gt;, and built
Callisto e-commerce for OpenERP&lt;sup id=&quot;fnref:callisto&quot;&gt;&lt;a href=&quot;#fn:callisto&quot; rel=&quot;footnote&quot;&gt;12&lt;/a&gt;&lt;/sup&gt; as well as
Nereid for Tryton&lt;sup id=&quot;fnref:nereid&quot;&gt;&lt;a href=&quot;#fn:nereid&quot; rel=&quot;footnote&quot;&gt;13&lt;/a&gt;&lt;/sup&gt;. Sharoon has clearly already considered the
question of Tryton and e-commerce, as indicated in
his email list discussion on building a Magento Connector for Tryton&lt;sup id=&quot;fnref:connector&quot;&gt;&lt;a href=&quot;#fn:connector&quot; rel=&quot;footnote&quot;&gt;14&lt;/a&gt;&lt;/sup&gt;. (My favorite part: “An integration with
Magento does not add &amp;#8216;The best e-commerce possibility for Tryton&amp;#8217;
but does make &amp;#8216;A great &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; backend for&amp;nbsp;Magento&amp;#8217;.&amp;#8221;)&lt;/p&gt;
&lt;p&gt;Again I want to add, there are others. I can just barely read
French, German, and Spanish, and do not know the developers who
spend most of their time in these channels. Even among the
participants in the English language forums, I’m not representing
everyone here, but I do wish to include them in my&amp;nbsp;appreciation.&lt;/p&gt;
&lt;h3&gt;What else is&amp;nbsp;there?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://version2beta.com/archive/2011/evaluating-tryton-as-an-ecommerce-backend_about-tryton.html&quot; title=&quot;Tryton as an e-commerce back-end: About Tryton&quot;&gt;Part 1: About Tryton&lt;/a&gt;. An overview of Tryton – architecture,
    business model, features,&amp;nbsp;license.&lt;/li&gt;
&lt;li&gt;Part 2: Stalking the Tryton community. There are some
    impressive people working on this project. I’m pleased to get to
    know&amp;nbsp;them.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://version2beta.com/archive/2011/evaluating-tryton-as-an-ecommerce-backend_web-framework.html&quot; title=&quot;Tryton as an e-commerce back-end: Tryton needs a web framework.&quot;&gt;Part 3: The crux of the matter&lt;/a&gt;. Tryton needs a web framework so we don&amp;#8217;t have to do things&amp;nbsp;twice.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;If I’ve inspired a response from you (probably the type of response that deserves an apology), mention &lt;a href=&quot;http://twitter.com/version2beta&quot; title=&quot;Me, twitterfied&quot;&gt;@version2beta&lt;/a&gt; on &lt;a href=&quot;http://twitter.com/&quot; title=&quot;All of twitter, including me.&quot;&gt;Twitter&lt;/a&gt; and I’ll see it there. Or, if you can’t comment in less than 126 characters (my handle takes 14 characters with a space), blog about it and tweet&amp;nbsp;that.&lt;/em&gt;&lt;/p&gt;

   </content></entry><entry><title>Freaky shadow</title><author><name>Rob Martin</name></author><link href="http://www.version2beta.com/archive/2011/freaky-shadow.html"/><updated>2011-06-09T13:21:00Z</updated><published>2011-06-09T13:21:00Z</published><id>http://www.version2beta.com/archive/2011/freaky-shadow.html</id><content type="html">
       
&lt;!-- Hyde::Excerpt::Begin --&gt;

&lt;p&gt;The webserver logs showed I was being followed on my path through a website by a computer at an &lt;span class=&quot;caps&quot;&gt;IP&lt;/span&gt; address in Texas. It trailed two seconds behind me, on every&amp;nbsp;page.&lt;/p&gt;
&lt;!-- Hyde::Excerpt::End --&gt;

&lt;p&gt;It was a dark and stormy day, and a strange thing happened while I
was debugging some &lt;span class=&quot;caps&quot;&gt;PHP&lt;/span&gt;&amp;nbsp;code.&lt;/p&gt;
&lt;p&gt;I was using [error_log][] to pass some variables and values to the
standard Apache log, and tailing it to make sure &lt;span class=&quot;caps&quot;&gt;PHP&lt;/span&gt; was seeing
what I wanted it to see. That was when I saw something I didn’t
expect to&amp;nbsp;see.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Thu Jun 09 13:37:54 2011] [error] [client 24.xxx.xx.xxx] Carrier: ...
[Thu Jun 09 13:37:54 2011] [error] [client 24.xxx.xx.xxx] Returning ...
[Thu Jun 09 13:37:56 2011] [error] [client 75.xxx.xx.xxx] Carrier: ...
[Thu Jun 09 13:37:56 2011] [error] [client 75.xxx.xx.xxx] Returning ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each time I hit the page, my code logged the access. Then, a second
or two later, another entry &lt;em&gt;from a different &lt;span class=&quot;caps&quot;&gt;IP&lt;/span&gt; address&lt;/em&gt; was also&amp;nbsp;logged.&lt;/p&gt;
&lt;p&gt;Everything I did was being shadowed by a server in&amp;nbsp;Texas.&lt;/p&gt;
&lt;p&gt;It took a few minutes of research to discover that the &lt;span class=&quot;caps&quot;&gt;IP&lt;/span&gt; address
belongs to one of &lt;a href=&quot;http://www.clicktale.com/&quot; title=&quot;Clicktale does experience analytics&quot;&gt;ClickTale’s servers&lt;/a&gt;, and that the page I was
modifying runs their analytic code. Freakiness&amp;nbsp;abated.&lt;/p&gt;

   </content></entry><entry><title>Tryton as an e-commerce back-end - About Tryton</title><author><name>Rob Martin</name></author><link href="http://www.version2beta.com/archive/2011/evaluating-tryton-as-an-ecommerce-backend_about-tryton.html"/><updated>2011-06-05T15:24:00Z</updated><published>2011-06-05T15:24:00Z</published><id>http://www.version2beta.com/archive/2011/evaluating-tryton-as-an-ecommerce-backend_about-tryton.html</id><content type="html">
       
&lt;!-- Hyde::Excerpt::Begin --&gt;

&lt;p&gt;This is part one in a series exploring how Tryton might fair as the heavy-lifting portion of an e-commerce package. This first part describes Tryton - architecture, features, community,&amp;nbsp;license.&lt;/p&gt;
&lt;!-- Hyde::Excerpt::End --&gt;

&lt;p&gt;Upcoming parts (as planned,&amp;nbsp;anyway):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Part 1: About&amp;nbsp;Tryton&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.version2beta.com/blog/2011/evaluation-tryton-as-an-ecommerce-back-end-stalking-the-tryton-community/&quot; title=&quot;Evaluation Tryton as an e-commerce back-end: Stalking the Tryton community&quot;&gt;Part 2: Stalking the Tryton&amp;nbsp;community&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://version2beta.com/archive/2011/evaluating-tryton-as-an-ecommerce-backend_web-framework.html&quot; title=&quot;Tryton as an e-commerce back-end: Tryton needs a web framework.&quot;&gt;Part 3: The crux of the&amp;nbsp;matter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;About&amp;nbsp;Tryton&lt;/h2&gt;
&lt;p&gt;I want to call Tryton&lt;sup id=&quot;fnref:tryton&quot;&gt;&lt;a href=&quot;#fn:tryton&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; an open source &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt;&lt;sup id=&quot;fnref:erp&quot;&gt;&lt;a href=&quot;#fn:erp&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; system, and it is,
but I like their description of the project better: A
three-tier&lt;sup id=&quot;fnref:3tier&quot;&gt;&lt;a href=&quot;#fn:3tier&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; high-level general purpose application platform
released under the &lt;span class=&quot;caps&quot;&gt;GPL&lt;/span&gt;-3&lt;sup id=&quot;fnref:gpl&quot;&gt;&lt;a href=&quot;#fn:gpl&quot; rel=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; license, written in Python&lt;sup id=&quot;fnref:python&quot;&gt;&lt;a href=&quot;#fn:python&quot; rel=&quot;footnote&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;, using
PostgreSQL&lt;sup id=&quot;fnref:postgres&quot;&gt;&lt;a href=&quot;#fn:postgres&quot; rel=&quot;footnote&quot;&gt;6&lt;/a&gt;&lt;/sup&gt; as its database&amp;nbsp;engine.&lt;/p&gt;
&lt;p&gt;That’s a lot of descriptors, but basically what it says to me is
that it’s a platform for building stuff, made from tech I like, and
licensed under the GPLv3. And when you look at the base modules
that come with Tryton, you can see it has an emphasis on &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt;:
accounting, invoicing, sales management, purchasing management,
inventory&amp;nbsp;management.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;[Note to past self: In the future, you&amp;#8217;re going to get excited about this stuff. No, not anxious. I said&amp;nbsp;excited.]&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;[Note from past selves: Did you forget your first professional programming project - 1985 - was calculating economic order quantities? And your first industrial automation job - 1991 - counted feet of magnetic wire coming off 50 machines for integration with their business systems? Loser. We&amp;#8217;re ready. You&amp;#8217;re the anxious&amp;nbsp;one.]&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Architecture&lt;/h3&gt;
&lt;p&gt;So Tryton is made up of three main components &lt;em&gt;(tiers)&lt;/em&gt;: A client,
a database, and some code stuck in the middle to make things go&amp;nbsp;smoothly.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;On the client side, we have a Python &lt;span class=&quot;caps&quot;&gt;GTK&lt;/span&gt;+ program that runs on
    a bunch of desktop operating systems (unfortunately not yet
    including mobile.) But there’s lots of ways to look at what the
    client application is. In some ways, my e-commerce websites will be
    the client,&amp;nbsp;too.&lt;/li&gt;
&lt;li&gt;Opposite the client, we have PostgreSQL, a badass database
    powerhouse. ‘Nuff&amp;nbsp;said.&lt;/li&gt;
&lt;li&gt;In the middle comes a bunch of Python programming that does all
    sorts of cool stuff. From my perspective, it manages a bunch of
    objects (as in Object Oriented Programming&lt;sup id=&quot;fnref:oop&quot;&gt;&lt;a href=&quot;#fn:oop&quot; rel=&quot;footnote&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;) like ‘Orders’ and
    ‘Persons’, and keeps most of them tucked safely away in the
    database for future reference. This is where the magic happens.
    It’s also where the growth happens, because Tryton is modular,
    which means you can create new objects, introduce Tryton to them,
    and wham-bam you get new features. For example, instead of blogging
    about Tryton right now I’m supposed to be building two new modules
    for Tryton’s cousin, OpenERP&lt;sup id=&quot;fnref:openerp&quot;&gt;&lt;a href=&quot;#fn:openerp&quot; rel=&quot;footnote&quot;&gt;8&lt;/a&gt;&lt;/sup&gt;, adding increased functionality
    for interfacing with &lt;span class=&quot;caps&quot;&gt;UPS&lt;/span&gt;&lt;sup id=&quot;fnref:ups&quot;&gt;&lt;a href=&quot;#fn:ups&quot; rel=&quot;footnote&quot;&gt;9&lt;/a&gt;&lt;/sup&gt; for shipping and CyberSource&lt;sup id=&quot;fnref:cybersource&quot;&gt;&lt;a href=&quot;#fn:cybersource&quot; rel=&quot;footnote&quot;&gt;10&lt;/a&gt;&lt;/sup&gt; for&amp;nbsp;payments.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That middle layer between the client and the database is also the
reason Tryton isn’t just an &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; system, because really, you can use
it to manage any data-intensive application. There’s nothing about
Tryton that intrinsically says “You must have an Certified Public
Accountant involved in this project” – Tryton’s design lets it
manage schools and hospitals and music festivals and motorcycles
and people and emails and whatnots just as easily procurement
orders or P&amp;amp;L&amp;nbsp;statements.&lt;/p&gt;
&lt;p&gt;While the middle tier provides the magic, there’s an important
consideration in the client, too.
&lt;strong&gt;The client doesn’t have to be human&lt;/strong&gt;. If I had my druthers, I’d
no longer develop any web applications that don’t provide an
&lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;, or Application Programming Interface&lt;sup id=&quot;fnref:api&quot;&gt;&lt;a href=&quot;#fn:api&quot; rel=&quot;footnote&quot;&gt;11&lt;/a&gt;&lt;/sup&gt;. Tryton’s server,
known as trytond or “the Tryton daemon”, connects to the regular
old client using a protocol known as &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt;-&lt;span class=&quot;caps&quot;&gt;RPC&lt;/span&gt;&lt;sup id=&quot;fnref:xmlrpc&quot;&gt;&lt;a href=&quot;#fn:xmlrpc&quot; rel=&quot;footnote&quot;&gt;12&lt;/a&gt;&lt;/sup&gt;, or “eXtensible
Markup Language – Remote Procedure Call”. trytond uses &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt;-&lt;span class=&quot;caps&quot;&gt;RPC&lt;/span&gt; to
tell the client what to show, and the client responds in &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt;-&lt;span class=&quot;caps&quot;&gt;RPC&lt;/span&gt; to
tell the server what to do. Well, that means that any program that
knows the secret handshake and how to speak &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt;-&lt;span class=&quot;caps&quot;&gt;RPC&lt;/span&gt; can be a Tryton
client. (For accuracy’s sake, I’d like to point out that Trytond is
like, trilingual. It’s fluent in &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt;-&lt;span class=&quot;caps&quot;&gt;RPC&lt;/span&gt;&lt;sup id=&quot;fnref:xmlrpcspec&quot;&gt;&lt;a href=&quot;#fn:xmlrpcspec&quot; rel=&quot;footnote&quot;&gt;13&lt;/a&gt;&lt;/sup&gt;, &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt;-&lt;span class=&quot;caps&quot;&gt;RPC&lt;/span&gt;&lt;sup id=&quot;fnref:jsonrpc&quot;&gt;&lt;a href=&quot;#fn:jsonrpc&quot; rel=&quot;footnote&quot;&gt;14&lt;/a&gt;&lt;/sup&gt;, and
Net-&lt;span class=&quot;caps&quot;&gt;RPC&lt;/span&gt;&lt;sup id=&quot;fnref:netrpc&quot;&gt;&lt;a href=&quot;#fn:netrpc&quot; rel=&quot;footnote&quot;&gt;15&lt;/a&gt;&lt;/sup&gt;. It’s also gets by with WebDAV&lt;sup id=&quot;fnref:webdav&quot;&gt;&lt;a href=&quot;#fn:webdav&quot; rel=&quot;footnote&quot;&gt;16&lt;/a&gt;&lt;/sup&gt;, psycopg&lt;sup id=&quot;fnref:psycopg&quot;&gt;&lt;a href=&quot;#fn:psycopg&quot; rel=&quot;footnote&quot;&gt;17&lt;/a&gt;&lt;/sup&gt;, and
even some OpenOffice&lt;sup id=&quot;fnref:openoffice&quot;&gt;&lt;a href=&quot;#fn:openoffice&quot; rel=&quot;footnote&quot;&gt;18&lt;/a&gt;&lt;/sup&gt; – you know, enough to ask where the
bathroom is, how to hail a cab, what’s safe to order at a
restaurant.) The upshot of this, of course, is that I can create an
e-commerce site running on &lt;span class=&quot;caps&quot;&gt;MODX&lt;/span&gt;&lt;sup id=&quot;fnref:modx&quot;&gt;&lt;a href=&quot;#fn:modx&quot; rel=&quot;footnote&quot;&gt;19&lt;/a&gt;&lt;/sup&gt; Revolution&lt;sup id=&quot;fnref:revolution&quot;&gt;&lt;a href=&quot;#fn:revolution&quot; rel=&quot;footnote&quot;&gt;20&lt;/a&gt;&lt;/sup&gt; or Django&lt;sup id=&quot;fnref:django&quot;&gt;&lt;a href=&quot;#fn:django&quot; rel=&quot;footnote&quot;&gt;21&lt;/a&gt;&lt;/sup&gt;
that interfaces completely with Tryton because
&lt;strong&gt;my website is the client&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;Features&lt;/h3&gt;
&lt;p&gt;I feel like I should mention something about what Tryton actually
does, which is an interesting concept. I almost think of it like I
would a programming language – not what it does, but what you can
do with it. Given enough&amp;nbsp;time.&lt;/p&gt;
&lt;p&gt;Despite my inclination to see multiple uses for it, Tryton focuses
on business systems. Install the standard modules and it will
handle the business of a catalog retailer, for&amp;nbsp;example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Manage contacts: customers, vendors, companies, employees,
    addresses,&amp;nbsp;etc.&lt;/li&gt;
&lt;li&gt;Workflow&amp;nbsp;management&lt;/li&gt;
&lt;li&gt;Issue RFQs (requests for quotation) and purchase orders to
    suppliers, keep track of current and historical costs associated
    with&amp;nbsp;products&lt;/li&gt;
&lt;li&gt;Receive stock, track inventory by location, move stock around
    and out the door, get the value of inventory by location, set&amp;nbsp;orderpoints&lt;/li&gt;
&lt;li&gt;Process invoices for accounts payable, reconcile the invoices
    against received product, make&amp;nbsp;payments&lt;/li&gt;
&lt;li&gt;Track leads, schedule meetings and&amp;nbsp;events&lt;/li&gt;
&lt;li&gt;Create customer quotations, accept purchase orders, schedule&amp;nbsp;delivery&lt;/li&gt;
&lt;li&gt;Issue invoices, accept payments, reconcile&amp;nbsp;accounts&lt;/li&gt;
&lt;li&gt;Manage projects, including billing for time on&amp;nbsp;projects&lt;/li&gt;
&lt;li&gt;Review finances, generate reports, close out financial&amp;nbsp;periods&lt;/li&gt;
&lt;li&gt;Track specialized business&amp;nbsp;intelligence&lt;/li&gt;
&lt;li&gt;Generate standard and customized&amp;nbsp;reports&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are certainly some things that Tryton doesn’t do, that a
typical &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; system might (or should, or maybe I wish it would)&amp;nbsp;do:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Manage production (work orders, repair orders, schedule
    resources,&amp;nbsp;etc.)&lt;/li&gt;
&lt;li&gt;Comprehensive &lt;span class=&quot;caps&quot;&gt;CRM&lt;/span&gt; (track emails, phone calls, social media;
    manage issues or complaints; delegate accounts and tasks,&amp;nbsp;etc.)&lt;/li&gt;
&lt;li&gt;Better localization support for the United&amp;nbsp;States&lt;/li&gt;
&lt;li&gt;Support mobile&amp;nbsp;clients&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That’s not to say Tryton can’t do these things. It can – some
assembly required, please allow six to eight months for&amp;nbsp;delivery.&lt;/p&gt;
&lt;p&gt;Looking at my target application, however – performing as the
backend for a large-scale e-commerce system – Tryton has much of
what I&amp;nbsp;need:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Account&amp;nbsp;management&lt;/li&gt;
&lt;li&gt;Catalog&amp;nbsp;management&lt;/li&gt;
&lt;li&gt;Stock management and product&amp;nbsp;availability&lt;/li&gt;
&lt;li&gt;Multiple pricelists and multi-tiered&amp;nbsp;pricelists&lt;/li&gt;
&lt;li&gt;Sales quotations (often called “shopping carts” and “wish&amp;nbsp;lists”)&lt;/li&gt;
&lt;li&gt;Sales orders (“Complete your&amp;nbsp;order”)&lt;/li&gt;
&lt;li&gt;Order&amp;nbsp;management&lt;/li&gt;
&lt;li&gt;Customer&amp;nbsp;support&lt;/li&gt;
&lt;li&gt;Process integration (“track your&amp;nbsp;order”)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Alas, there are a few things I’d want to add to that&amp;nbsp;list:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Online payment support through Authorize.net, PayPal, Google
    Checkout,&amp;nbsp;etc.&lt;/li&gt;
&lt;li&gt;Shipping integration with &lt;span class=&quot;caps&quot;&gt;UPS&lt;/span&gt;, &lt;span class=&quot;caps&quot;&gt;USPS&lt;/span&gt;, and&amp;nbsp;FedEx&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;WYSIWYG&lt;/span&gt; editing of product&amp;nbsp;data&lt;/li&gt;
&lt;li&gt;A decent point of sale terminal interface for e-commerce stores
    with a brick-and-mortar&amp;nbsp;presence&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;While I might not expect it to be part of Tryton, there’s always
the rest of the e-commerce site too – content management, templates,
dynamic content outside of the store, etc. I think it could be
interesting to see a merger between these elements, but I am not
convinced it’s a good marriage. Should an &lt;span class=&quot;caps&quot;&gt;ERP&lt;/span&gt; system provide
internet and intranet, online document management, institutional
knowledge management? Sounds like a question for another blog post.
Meanwhile there’s MODx and&amp;nbsp;Django.&lt;/p&gt;
&lt;h3&gt;Community&lt;/h3&gt;
&lt;p&gt;I’ll discuss community more in the next post, but Tryton seems to
be developed under what’s called a Community Open Source model. If
you ask me, that’s the old school way of doing it. You know, the
right way, before the new fangled methods came along and perverted
the process. (I’m not opinionated or&amp;nbsp;anything.)&lt;/p&gt;
&lt;p&gt;Tryton is developed by a federation of companies and individual
developers. There seem to be at least five main companies involved,
all of which also provide commercial services for the system as
well. Of course, there is a strong argument that these companies
are most expert in the software. This expertise translates into
demand, and&amp;nbsp;revenue.&lt;/p&gt;
&lt;p&gt;In contrast, some open source projects (examples include
OpenERP&lt;sup id=&quot;fnref:openerp2&quot;&gt;&lt;a href=&quot;#fn:openerp2&quot; rel=&quot;footnote&quot;&gt;22&lt;/a&gt;&lt;/sup&gt; and Magento&lt;sup id=&quot;fnref:magento&quot;&gt;&lt;a href=&quot;#fn:magento&quot; rel=&quot;footnote&quot;&gt;23&lt;/a&gt;&lt;/sup&gt;) follow what’s called a Commercial
Open Source model. In this model, one company typically calls the
shots (or “edits”) the software. They often do most of the
development, especially early on, but they also draw upon work done
by users and developers of the system. If the editor likes your
code, they pull it into the main branch. If they like your idea but
not your code, they might implement your idea themselves. If they
don’t want either your idea or your code, it sits out there for
others to find and use. Often, the commercial open source model
matures into a dual-release model, where the package is released in
a community (open source) version, and an enterprise (proprietary)&amp;nbsp;version.&lt;/p&gt;
&lt;h3&gt;License&lt;/h3&gt;
&lt;p&gt;I’ve developed in OpenERP and already had that uncomfortable
discussion with the client where you teach them how to read a
specification, especially the section defining how the code is
licensed. OpenERP is, curiously, licensed under the
&lt;span class=&quot;caps&quot;&gt;GNU&lt;/span&gt; Affero General Public License version 3.0&lt;sup id=&quot;fnref:agpl&quot;&gt;&lt;a href=&quot;#fn:agpl&quot; rel=&quot;footnote&quot;&gt;24&lt;/a&gt;&lt;/sup&gt;. It’s just like
the (in)famous &lt;span class=&quot;caps&quot;&gt;GNU&lt;/span&gt; General Public License version 3.0&lt;sup id=&quot;fnref:gpl2&quot;&gt;&lt;a href=&quot;#fn:gpl2&quot; rel=&quot;footnote&quot;&gt;25&lt;/a&gt;&lt;/sup&gt;, except
it adds a bit of text closing what’s called the “Application
Service Provider Loophole”. That is, the user of a system licensed
under the &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt; has a right to the source code for the system, even
if they’re accessing the system over a network. Even if it’s been
customized. Even if it’s got trade secrets in it. In practice (and
I Am Not A Lawyer) this seems to mean that the people using the
OpenERP client to connect to an OpenERP server over a network
should be able to retrieve the source code for custom modules.
Generally speaking, this would be the customer who paid a developer
to create the modules, and of course they should get the code.
Likewise, the person who owns a website that connects to an OpenERP
server should be able to get any custom OpenERP module code that
supports the website connecting to it. Phew. But I don’t think it
goes farther than that – I don’t believe this means that the
website needs to be licensed &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt;, or that visitors to the website
should be able to download code for the website, or any custom
OpenERP&amp;nbsp;modules.&lt;/p&gt;
&lt;p&gt;Tryton, on the other hand, is licensed under the regular old
&lt;span class=&quot;caps&quot;&gt;GNU&lt;/span&gt; General Public License version 3.0, complete with &lt;span class=&quot;caps&quot;&gt;ASP&lt;/span&gt;
loophole. That tells me that the source code for any customization
made to the Tryton code (a custom module, for instance) used by a
client over a network does not need that custom code offered to the
client. I don’t have a problem playing nicely with others. I like
to share. I appreciate those subtle shades of difference between
the &lt;span class=&quot;caps&quot;&gt;AGPL&lt;/span&gt; and &lt;span class=&quot;caps&quot;&gt;GPL&lt;/span&gt;. But when it comes to splitting the hairs of
freedom, it seems that distributing custom code to lowly users
causes palpitations among some clients, typically those with legal&amp;nbsp;departments.&lt;/p&gt;
&lt;h3&gt;What else is&amp;nbsp;there?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Part 1: About Tryton. An overview of Tryton – architecture,
    business model, features,&amp;nbsp;license.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.version2beta.com/blog/2011/evaluation-tryton-as-an-ecommerce-back-end-stalking-the-tryton-community/&quot; title=&quot;Evaluation Tryton as an e-commerce back-end: Stalking the Tryton community&quot;&gt;Part 2: Stalking the Tryton community&lt;/a&gt;. There are some
    impressive people working on this project. I’m pleased to get to
    know&amp;nbsp;them.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://version2beta.com/archive/2011/evaluating-tryton-as-an-ecommerce-backend_web-framework.html&quot; title=&quot;Tryton as an e-commerce back-end: Tryton needs a web framework.&quot;&gt;Part 3: The crux of the matter&lt;/a&gt;. Tryton needs a web framework so we don&amp;#8217;t have to do things&amp;nbsp;twice.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;If I’ve inspired a response from you (probably the type of response that deserves an apology), mention &lt;a href=&quot;http://twitter.com/version2beta&quot; title=&quot;Me, twitterfied&quot;&gt;@version2beta&lt;/a&gt; on &lt;a href=&quot;http://twitter.com/&quot; title=&quot;All of twitter, including me.&quot;&gt;Twitter&lt;/a&gt; and I’ll see it there. Or, if you can’t comment in less than 126 characters (my handle takes 14 characters with a space), blog about it and tweet&amp;nbsp;that.&lt;/em&gt;&lt;/p&gt;

   </content></entry><entry><title>Instantiate Blog</title><author><name>Rob Martin</name></author><link href="http://www.version2beta.com/archive/2011/instantiate-blog.html"/><updated>2011-05-09T20:15:00Z</updated><published>2011-05-09T20:15:00Z</published><id>http://www.version2beta.com/archive/2011/instantiate-blog.html</id><content type="html">
       
&lt;!-- Hyde::Excerpt::Begin --&gt;

&lt;p&gt;The story of how and why I ended up blogging.&amp;nbsp;Again.&lt;/p&gt;
&lt;!-- Hyde::Excerpt::End --&gt;

&lt;h2&gt;Stranger in a strange&amp;nbsp;land.&lt;/h2&gt;
&lt;p&gt;This is somewhere around blogging attempt number 12 for me. I feel like
the cheerleader on Heroes&lt;sup id=&quot;fnref:claire&quot;&gt;&lt;a href=&quot;#fn:claire&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; announcing yet another failed try at
offing myself. And here I go&amp;nbsp;again.&lt;/p&gt;
&lt;p&gt;Actually, I haven’t done horribly. Some of my blogs had a few readers. 2
or 3 a month even. Some high&amp;nbsp;points:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;grokd.org – an automated blog pulling news clips on autism. Hundreds
    of readers a month, probably because I didn’t write hardly any of
    the posts. I shut it down when the b2/cafelog&lt;sup id=&quot;fnref:b2&quot;&gt;&lt;a href=&quot;#fn:b2&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; developers
    announced they were shifting focus to some new project they called&amp;nbsp;“WordPress”.&lt;/li&gt;
&lt;li&gt;closew.org – discussion of community and cooperative living, back
    when I still thought consensus was the greatest political tool since
    pork on sliced bread. Now I favor benevolent dictators&lt;sup id=&quot;fnref:bdfl&quot;&gt;&lt;a href=&quot;#fn:bdfl&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; (so long
    as he is me) and anarchy&lt;sup id=&quot;fnref:anarchy&quot;&gt;&lt;a href=&quot;#fn:anarchy&quot; rel=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;, especially anarcho-primitivism&lt;sup id=&quot;fnref:anarchoprimitivism&quot;&gt;&lt;a href=&quot;#fn:anarchoprimitivism&quot; rel=&quot;footnote&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;.&lt;/li&gt;
&lt;li&gt;woundedpig.com – an attempt to satirize scary conservatives. Took me
    forever to write each post. Turns out I’m not Jon&amp;nbsp;Stewart.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Look. And&amp;nbsp;feel.&lt;/h2&gt;
&lt;p&gt;What can I add beyond what I’ve said &lt;a href=&quot;http://version2beta.com/about/about.html&quot; title=&quot;about version2beta&#39;s blog&quot;&gt;on the about page&lt;/a&gt;? As of this
writing, the blog has an extremely basic theme. One could call it naked,
except that would suggest you could see what lies underneath. Let’s say
it’s unadorned. I’m using the Roots theme&lt;sup id=&quot;fnref:roots&quot;&gt;&lt;a href=&quot;#fn:roots&quot; rel=&quot;footnote&quot;&gt;6&lt;/a&gt;&lt;/sup&gt; for these&amp;nbsp;features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;HTML5&lt;/span&gt; Boilerplate (&lt;a href=&quot;http://html5boilerplate.com/&quot;&gt;http://html5boilerplate.com/&lt;/a&gt;) makes
    rock-solid &lt;span class=&quot;caps&quot;&gt;HTML5&lt;/span&gt;&amp;nbsp;sites&lt;/li&gt;
&lt;li&gt;960.gs (&lt;a href=&quot;http://960.gs/&quot;&gt;http://960.gs/&lt;/a&gt;) makes 960px grid-based design&amp;nbsp;easy&lt;/li&gt;
&lt;li&gt;Cleaner URLs with a custom&amp;nbsp;.htaccess&lt;/li&gt;
&lt;li&gt;jQuery &lt;a href=&quot;http://jquery.malsup.com/cycle/&quot; title=&quot;Malsup&#39;s jQuery Cycle. Vrooom.&quot;&gt;Cycle&lt;/a&gt; and &lt;a href=&quot;http://fancybox.net/&quot; title=&quot;Fancybox makes content pop.&quot;&gt;FancyBox&lt;/a&gt; – my two favorite jQuery&amp;nbsp;plugins&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of course, Roots is just a starter theme. Ideally the developer will
still style it, you know, choose those cleaner and more trustworthy
fonts, maybe add a logo, etc.? Take a look at this page. If you’re
seeing what I’m seeing (quite possibly not, since I’m at a different
point in the space-time continuum than you are), then the developer
(a/k/a me, version2beta, rob) has not gotten around to&amp;nbsp;it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Updated 8/22/11:&lt;/strong&gt; I&amp;#8217;ve moved the blog onto my version2beta.com domain and now I&amp;#8217;m using Hyde&lt;sup id=&quot;fnref:hyde&quot;&gt;&lt;a href=&quot;#fn:hyde&quot; rel=&quot;footnote&quot;&gt;7&lt;/a&gt;&lt;/sup&gt; to generate the site, so I&amp;#8217;m not actually using Wordpress, Roots theme, or Apache, or even HTML5Boilerplate. Or FancyBox, jQuery Cycle, or jQuery &lt;em&gt;anything&lt;/em&gt;. It&amp;#8217;s all rustic. I&amp;#8217;ve gone native. (But I&amp;#8217;ll probably get around to making it look more designed&amp;nbsp;eventually.)&lt;/p&gt;
&lt;h2&gt;Poke&amp;nbsp;me.&lt;/h2&gt;
&lt;p&gt;Look around at what I’ve written. Or maybe what I’m going to write, since so far all I’ve written is this and the about page. Or maybe, what I think I’m going to write. I’ll probably leave comments on, but really, don’t bother. If I’ve inspired a response from you (probably the type of response that deserves an apology), mention &lt;a href=&quot;http://twitter.com/version2beta&quot; title=&quot;Me, twitterfied&quot;&gt;@version2beta&lt;/a&gt; on Twitter and I’ll see it there. Or, if you can’t comment in less than 126 characters (my handle takes 14 characters with a space), blog about it and tweet that. I have my doubts about blogging (especially me blogging), but one thing it seems good for is inter-blogal&amp;nbsp;discussions.&lt;/p&gt;

   </content></entry></feed>