<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-9144864480315874152</id><updated>2012-02-16T02:42:48.090-05:00</updated><category term='linux'/><category term='gpg'/><category term='postgres'/><category term='cli'/><category term='s3'/><category term='security'/><category term='air gap'/><category term='apt'/><category term='privacy'/><category term='bash'/><category term='django'/><category term='mvc'/><category term='encryption'/><category term='server administration'/><category term='git'/><category term='python'/><category term='backblaze'/><category term='utf8'/><category term='reference'/><category term='book review'/><category term='samba'/><category term='VirtualLab'/><category term='project management'/><category term='ubuntu'/><category term='model'/><category term='architecture'/><category term='database'/><title type='text'>frontier technologist</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://frontiertechnologist.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://frontiertechnologist.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Stephan Stachurski</name><uri>http://www.blogger.com/profile/18429374901205223065</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>21</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-9144864480315874152.post-7260540771791007411</id><published>2011-05-31T13:56:00.001-04:00</published><updated>2011-05-31T13:56:20.206-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='utf8'/><category scheme='http://www.blogger.com/atom/ns#' term='samba'/><title type='text'>Mount Samba With UTF8</title><content type='html'>Hey dumbass-&lt;br /&gt;&lt;br /&gt;You will reference this link again, I promise.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ubuntuforums.org/showthread.php?t=288534"&gt;http://ubuntuforums.org/showthread.php?t=288534&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Signed,&lt;br /&gt;Dumbass.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9144864480315874152-7260540771791007411?l=frontiertechnologist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frontiertechnologist.blogspot.com/feeds/7260540771791007411/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://frontiertechnologist.blogspot.com/2011/05/mount-samba-with-utf8.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/7260540771791007411'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/7260540771791007411'/><link rel='alternate' type='text/html' href='http://frontiertechnologist.blogspot.com/2011/05/mount-samba-with-utf8.html' title='Mount Samba With UTF8'/><author><name>Stephan Stachurski</name><uri>http://www.blogger.com/profile/18429374901205223065</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9144864480315874152.post-3086284877558268360</id><published>2011-05-31T13:20:00.000-04:00</published><updated>2011-05-31T13:20:31.855-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='django'/><category scheme='http://www.blogger.com/atom/ns#' term='postgres'/><title type='text'>Django "duplicate key value violates unique constraint"</title><content type='html'>The few times that I have seen this error in my own code, finding the source and squashing any related bugs was pretty easy. For the first time today, I saw it appear when I was using the provided admin interface to add a user to my project where I was using django.contrib.auth. It caused me to panic a little.&lt;br /&gt;&lt;br /&gt;With a little bit of google searching, I found &lt;a href="http://groups.google.com/group/django-users/browse_thread/thread/8400f45dfa45dd46/5b3f76b0d89369c0?show_docid=5b3f76b0d89369c0"&gt;this post&lt;/a&gt; on the django google group that helped me fix my problem clearly and quickly.&lt;br /&gt;&lt;br /&gt;I am using a postgres back end, and it seems like the counter for the serial field was reset. By looking at the table and finding which value should come next, I was able to set this counter to the proper value, and so far everything is working great.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9144864480315874152-3086284877558268360?l=frontiertechnologist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frontiertechnologist.blogspot.com/feeds/3086284877558268360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://frontiertechnologist.blogspot.com/2011/05/django-duplicate-key-value-violates.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/3086284877558268360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/3086284877558268360'/><link rel='alternate' type='text/html' href='http://frontiertechnologist.blogspot.com/2011/05/django-duplicate-key-value-violates.html' title='Django &quot;duplicate key value violates unique constraint&quot;'/><author><name>Stephan Stachurski</name><uri>http://www.blogger.com/profile/18429374901205223065</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9144864480315874152.post-5993688939878319553</id><published>2011-05-30T21:57:00.001-04:00</published><updated>2011-05-30T21:57:56.343-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VirtualLab'/><title type='text'>VirtualLab</title><content type='html'>I'm going to begin documenting a project with the tentative title of VirtualLab.&lt;br /&gt;&lt;br /&gt;VirtualLab will attempt to be a complete test-bench of environment of heterogeneous clients and servers interacting.&lt;br /&gt;&lt;br /&gt;In addition to being a tool with a real-world use, the VirtualLab project is also meant to provide an educational tool. The VirtualLab project aims to teach the ability to bootstrap itself.&lt;br /&gt;&lt;br /&gt;I'm trying to carve out the first piece of this project now, is to start by selecting and implementing the bare metal foundation. A virtualization stack needs to be selected from free and license-compatible options. The initial list is KVM, Xen, VMWare and Oracle.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9144864480315874152-5993688939878319553?l=frontiertechnologist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frontiertechnologist.blogspot.com/feeds/5993688939878319553/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://frontiertechnologist.blogspot.com/2011/05/virtual-lab.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/5993688939878319553'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/5993688939878319553'/><link rel='alternate' type='text/html' href='http://frontiertechnologist.blogspot.com/2011/05/virtual-lab.html' title='VirtualLab'/><author><name>Stephan Stachurski</name><uri>http://www.blogger.com/profile/18429374901205223065</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9144864480315874152.post-1753230685263889903</id><published>2011-05-25T07:34:00.000-04:00</published><updated>2011-05-25T07:34:44.659-04:00</updated><title type='text'>Crossbeam</title><content type='html'>Trying to find a name for the project, and this is the first dart I'm throwing at it. Crossbeam for Coarse Search for Barcodes (CSB). It's the best thing that&lt;br /&gt;grep -i '^c.*s.*b' /usr/share/dict/words&lt;br /&gt;turned up. It's kind of evocative of physical laser barcode scanners so it could work.&lt;br /&gt;&lt;br /&gt;Anyway, the first part will be the module that actually interacts with output. I need to write a layer where I convert PDF output into images that can be processed, and that part will be taken care of by a system call to the ImageMagick program &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;convert&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9144864480315874152-1753230685263889903?l=frontiertechnologist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frontiertechnologist.blogspot.com/feeds/1753230685263889903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://frontiertechnologist.blogspot.com/2011/05/crossbeam.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/1753230685263889903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/1753230685263889903'/><link rel='alternate' type='text/html' href='http://frontiertechnologist.blogspot.com/2011/05/crossbeam.html' title='Crossbeam'/><author><name>Stephan Stachurski</name><uri>http://www.blogger.com/profile/18429374901205223065</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9144864480315874152.post-6090548472938151503</id><published>2011-05-25T00:33:00.001-04:00</published><updated>2011-05-25T00:40:08.533-04:00</updated><title type='text'>Coarse Search For Barcodes In A Large Images</title><content type='html'>There are a few decent python modules that are capable of reading barcodes in images. They work reliably if the barcode is large enough in the image. They do not provide any kind of ability for searching a large image for a small barcode (that I know of). I require a module that guesses coordinates until barcode(s) are extracted from an image.&lt;br /&gt;&lt;br /&gt;The first part of this project is some scaffolding. The project should have an interface between a search algorithm and a scaffold that tries search results and parses the results of trying those search results. The project is then divided into two parts, on either side of that interface. This interface is meant to allow creating pluggable components by completely decoupling the barcode scanning&amp;nbsp;package&amp;nbsp;from the search algorithm.&lt;br /&gt;&lt;br /&gt;The motivation to solve this problem comes from extending a document management system. The source images are going to be classes of forms that have barcodes always in the same spot. I see the project as having a significant potential to be useful to lots of people...if done well. I think the most important part is sticking to this interface.&lt;br /&gt;&lt;br /&gt;Since the first use of this project will be to scan a certain well-defined form, it will start with a search module that is specifically designed to extract a barcode from that form. It's important to decouple any implementation details of this "dumb" search module from the as-yet undefined abstract search API.&lt;br /&gt;&lt;br /&gt;This module will be hard-coded to find one particular barcode most likely on the first guess of a box coordinate. Stated like this, the first definition of the project's API comes into light. We are given a BCS (box coordinate slice) to try, and parse the results. The parser will black box the actual module that performs the barcode analysis. I think a certain constraint needs to be introduced...that a BCS is meant only to contain a single barcode. The user should be easily able to define a regular expression that checks the validity of the barcode. This would be for a convenience layer, that could potentially be an API to a set of document classes. A document class would define a list of barcodes and&amp;nbsp;corresponding&amp;nbsp;optimized search functions. This could be the beginning of a third component of the system, or that be more integrated with the document management system than the actual barcode scanning system.&lt;br /&gt;&lt;br /&gt;The creation of the hard-coded search for a particular form is important. Firstly, our goal should be to get something functional as soon as possible. In order to iterate towards this goal as soon as possible, a requirement will be the ability to benchmark the search on a reasonable test data set from the beginning.&lt;br /&gt;&lt;br /&gt;The process of creating a hard-coded search module will start with a guess for the BCS that works on the test data set. The document has a pretty gigantic barcode on it, for now, with a goal in mind to shrink it. A BCS of the quadrant of the document that contains the barcode will be the first guess, and I'm not going to change that guess until the project can successfully analyze the effectiveness of that guess, and adheres to the design laid out in this first document.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9144864480315874152-6090548472938151503?l=frontiertechnologist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frontiertechnologist.blogspot.com/feeds/6090548472938151503/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://frontiertechnologist.blogspot.com/2011/05/coarse-search-for-barcodes-in-large.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/6090548472938151503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/6090548472938151503'/><link rel='alternate' type='text/html' href='http://frontiertechnologist.blogspot.com/2011/05/coarse-search-for-barcodes-in-large.html' title='Coarse Search For Barcodes In A Large Images'/><author><name>Stephan Stachurski</name><uri>http://www.blogger.com/profile/18429374901205223065</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9144864480315874152.post-8233482231447950139</id><published>2010-09-10T01:20:00.003-04:00</published><updated>2010-09-10T01:26:34.150-04:00</updated><title type='text'>Video talk: Real Software Engineering</title><content type='html'>&lt;a href="http://confreaks.net/videos/282-lsrc2010-real-software-engineering"&gt;Real Software Engineering - Glenn Vanderburg&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This talk was given at a Ruby conference, but it really has nothing to do with Ruby or Rails at all.&lt;br /&gt;&lt;br /&gt;The intro, and partially, the thesis, of the talk is that software engineering has been misunderstood. In particular, he says that theories taught at universities are completely misguided and result in projects that are over budget, behind schedule, or in some cases even complete failures. I studied a little bit of software engineering in university and I was never taught any of the points that he criticizes. The ideas that he says should replace the bad ideas have been outlined in books such as &lt;i&gt;&lt;a href="http://en.wikipedia.org/wiki/The_Mythical_Man-Month"&gt;The Mythical Man Month&lt;/a&gt;&lt;/i&gt;&amp;nbsp;(1975) and &lt;i&gt;&lt;a href="http://en.wikipedia.org/wiki/Code_Complete"&gt;Code Complete&lt;/a&gt;&lt;/i&gt;&amp;nbsp;(1993). If you grok those books and beyond, then this video might be boring to you; however, he concisely explains a few important points that form the core of software engineering.&lt;br /&gt;&lt;br /&gt;You can skip the first 15 minutes if you're short on time, but it's at least engaging.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Initially, one of the principals of software engineering was that the cost of changing the project increased near the tail end of a project. This data had a hidden bias, because all of the projects measured followed the flawed&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Waterfall_model"&gt;waterfall model&lt;/a&gt;. Really, the data being measured was more&amp;nbsp;semantically&amp;nbsp;described as the "cost of finding and fixing errors as a function of the distance in time from when the error was actually made (i.e. long feedback loops." The insight to be gained from the data, from this perspective, is that errors need to be rapidly discovered. By interlacing testing into the entire development process, the cost is reduced.&lt;/li&gt;&lt;li&gt;He describes a spectrum of&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Process_model"&gt;process models&lt;/a&gt;&amp;nbsp;&lt;i&gt;defined process model&lt;/i&gt;&amp;nbsp;(requires that every piece of work be completely understood; a defined process has the same results every time) at one end and the&amp;nbsp;&lt;i&gt;empirical process model&lt;/i&gt;&amp;nbsp;(provides and exercises control through frequent inspection and adaption for processes that are imperfectly defined and generate unpredictable and unrepeatable outputs) at the other. In particular, there's a bit of history where software engineers borrowed the defined process model from chemical engineering, when chemical engineers all knew that no real process is ever completely understood.&lt;/li&gt;&lt;li&gt;Mr. Vanderburg made a very good point using the Boeing 777 as an example.&amp;nbsp;As a test of the wing design, the engineers devised a test where the wings would be subjected to 150% of the maximum force they were ever expected to encounter in use.&amp;nbsp;&lt;a href="http://www.blogger.com/post-edit.g?blogID=9144864480315874152&amp;amp;postID=8233482231447950139"&gt;Video of the test&lt;/a&gt;&amp;nbsp;is pretty cool.&amp;nbsp;The point is that engineer is more concerned with practice than theory. Mathematics was originally applied to engineering as a cost saving method. Real-world tests are in many ways more valid than mathematical model validation. A quote I liked: "Ask your friendly neighborhood aerospace engineer how much math he would do if building a model of his design and testing it were effectively instantaneous and free...the answer would probably be 'A lot less than I do now.'" [I paraphrase for clarity a bit at the end.]&lt;/li&gt;&lt;li&gt;He follows up with a treatment of the Structural Engineer's Association definition of their craft: it is the science and art of designing and making, with economy and elegance...structures so that they ca safely resist the forces to which they may be subjected."&lt;/li&gt;&lt;li&gt;Mr Vanderburg proposes an&amp;nbsp;adaptation&amp;nbsp;of this definition for software. The juxtaposed ideals of science and art, designing and making, with economy and elegance are preserved, regarding "systems so that they can readily adapt to the situations to which they may be subjected."&lt;/li&gt;&lt;li&gt;From Royce's paper that introduced the waterfall process, Mr. Vanderburg lifts an excellent quote: "The testing phase...is the first event for which timing, storage, input/output, transfer, etc. are&amp;nbsp;&lt;i&gt;experienced&amp;nbsp;&lt;/i&gt;as distinguished from&amp;nbsp;&lt;i&gt;analyzed&lt;/i&gt;. These phenomena are not precisely analyzable. Yet, if these phenomena fail to satisfy the various external contraints, then invariably a major redesign is required..."&lt;/li&gt;&lt;li&gt;On the analogy between software development and engineering: In structural engineering, engineers produce a design which they provide laborers to implement a physical structure. Applied to software engineering, we have so far been unable to come up with a way to describe a design in such a way that is comprehensible, sufficient, and precise enough for programmers to use without redesigning a lot of it, which they're not trained to do because they're not engineers (in a strict interpretation of the preceding process model. Let the software developers be the engineers and designers; customers don't care about source code.&amp;nbsp;&lt;i&gt;Source code is the design&lt;/i&gt;.&amp;nbsp;&lt;/li&gt;&lt;li&gt;He concludes with a link to a paper on&amp;nbsp;&lt;i&gt;&lt;a href="http://en.wikipedia.org/wiki/Agile_software_development"&gt;Agile&lt;/a&gt;&lt;/i&gt;&amp;nbsp;methodology, with a simplified diagram of the process. He describes it as "as far on the empirical process design as you can get, but it's no less disciplined, no less rational for being empirical rather than defined."&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;a href="http://vanderburg.org/Writing/xpannealed.pdf"&gt;A Simple Model of Agile Software Processes - Glenn Vanderburg&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_EoKCjnnaxHQ/TIm-rcarO1I/AAAAAAAADKY/Ij5CGtXyadk/s1600/extremeprogramming.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_EoKCjnnaxHQ/TIm-rcarO1I/AAAAAAAADKY/Ij5CGtXyadk/s320/extremeprogramming.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;All in all, it was a very nice presentation, and definitely worth 50 minutes of your time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9144864480315874152-8233482231447950139?l=frontiertechnologist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frontiertechnologist.blogspot.com/feeds/8233482231447950139/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://frontiertechnologist.blogspot.com/2010/09/video-talk-real-software-engineering.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/8233482231447950139'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/8233482231447950139'/><link rel='alternate' type='text/html' href='http://frontiertechnologist.blogspot.com/2010/09/video-talk-real-software-engineering.html' title='Video talk: Real Software Engineering'/><author><name>Stephan Stachurski</name><uri>http://www.blogger.com/profile/18429374901205223065</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_EoKCjnnaxHQ/TIm-rcarO1I/AAAAAAAADKY/Ij5CGtXyadk/s72-c/extremeprogramming.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9144864480315874152.post-9218546938441539198</id><published>2010-08-29T00:22:00.002-04:00</published><updated>2010-08-29T00:48:46.947-04:00</updated><title type='text'>Iterating over many-to-many</title><content type='html'>I have a django data model that, amongst other things, defines a many-to-many relationship with itself. This post is about solving the problem of iterating the objects related to a particular object in the model.&lt;br /&gt;&lt;br /&gt;A self-referential many-to-many relationship is pretty peculiar and deserves some coverage by itself. In order to better grasp what it means, let's examine a concrete example. Consider a social networking site, like Facebook. The relationship between users and their friends is a self-referential, many-to-many relationship. The objects of this relationship are users, and users' friends, the connections between users, represent the relationships that we are interested in.&lt;br /&gt;&lt;br /&gt;The connections between users are also significant in their own right. In addition to representing a connection between two users, the relation is also able to keep track of when friends met, how they met, etc.&lt;br /&gt;&lt;br /&gt;In the facebook example, the relationship is bi-directional. Facebook friends are always on each others' friends list. This isn't always true. The twitter model, for example, allows one user to follow another without a reverse relationship.&lt;br /&gt;&lt;br /&gt;In my case, my self-referential many-to-many relationship has some special properties:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Relationships are not bi-directional&lt;/li&gt;&lt;li&gt;Objects can have no relation to other objects&lt;/li&gt;&lt;li&gt;The relationships have weight&lt;/li&gt;&lt;li&gt;If an object has relationships to one or more other objects, the weights of all those relationships sum to 100%, or 1.&lt;/li&gt;&lt;li&gt;An object could theoretically be a child of itself, directly or indirectly. This would lead to a sort of infinite loop as the relationships are traversed. The sum of all the related objects might be able to be calculated to a specific value of infinite sums are used; however, we are not going to allow an object to be a child of itself.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;When iterating over the relationships of a specific object, none of the properties we have listed preclude the possibility that we could visit the same object more than once. One optimization we can apply is to keep track of which objects have been visited so they only have to be traversed once.&lt;br /&gt;&lt;br /&gt;I think it can be represented by a weighted, directed tree. The last point in the above bulleted list technically means that the graph contains no cycles. A cycle is basically a loop in the graph, that would occur if an object was allowed to point to itself (directly or indirectly). A graph with no cycles is a special graph that is better known as a tree.&lt;br /&gt;&lt;br /&gt;A python instance method is suited to solving this problem, but it's not thread-safe. It is going to rely on a class variable to keep track of previously-visited objects. It could be made to be thread-safe by using objects instantiated from a local copy of the class itself, but as far as I know this possible to explicitly code into the class method; I have to admit that my knowledge of python is limited.&lt;br /&gt;&lt;br /&gt;A starter instance method should be used that initializes a hash that keeps track of objects that have already been visited. Then, it calls another recursive instance method that does most of the work. This method visits each related object. First it checks that an object has not already been visited. If it has not, it checks to see if the object has relationships to any other objects. If not, it does some calculations based on the path taken to that object. If it has other relationships, then it does some work to help keep track of the path taken and calls itself on all of the children objects.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9144864480315874152-9218546938441539198?l=frontiertechnologist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frontiertechnologist.blogspot.com/feeds/9218546938441539198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://frontiertechnologist.blogspot.com/2010/08/iterating-over-many-to-many.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/9218546938441539198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/9218546938441539198'/><link rel='alternate' type='text/html' href='http://frontiertechnologist.blogspot.com/2010/08/iterating-over-many-to-many.html' title='Iterating over many-to-many'/><author><name>Stephan Stachurski</name><uri>http://www.blogger.com/profile/18429374901205223065</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9144864480315874152.post-4595120013752939941</id><published>2010-08-27T17:18:00.000-04:00</published><updated>2010-08-27T17:18:06.060-04:00</updated><title type='text'>Collaborative network shares without compromising security</title><content type='html'>I'm in the process of working out a few kinks of setting up Ubuntu services for a small business network. We have successfully used a web server running mediawiki, and some basic NFS services so far. A special type of network share that I need provided by my file server is one in which users are free to read and write each others' files. I'm not sure if NFS is best suited to the task, or if this is something that's more suited to Samba.&lt;br /&gt;&lt;br /&gt;The default umask set in /etc/profile of an Ubuntu workstation is 022. This lets users read and write their own files, and allow other users in any group to read their files. This is perfectly fine in most situations; however, we need a shared workspace where users can edit each others' files. I could set the umask to 002, or even 000, but I doubt that's a good practice. This means that on each local system, other users could edit files in each others' home directories. Actually, I'm not even sure if this is true, if the proper permissions are set on users' top-level home directories, but files under those directories would have too-loose permissions set on them.&lt;br /&gt;&lt;br /&gt;In general, I want to keep the default umask of 022, but I want a specific share (whether it's NFS, Samba, or something else entirely) to behave like umask 000. I know I could do this in Samba, but my instincts tell me that there is probably a better way.&lt;br /&gt;&lt;br /&gt;Could you please share how you provide this service on your networks? What are some good practices to follow? Are there any risks to providing this type of service that aren't immediately apparent?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9144864480315874152-4595120013752939941?l=frontiertechnologist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frontiertechnologist.blogspot.com/feeds/4595120013752939941/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://frontiertechnologist.blogspot.com/2010/08/collaborative-network-shares-without.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/4595120013752939941'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/4595120013752939941'/><link rel='alternate' type='text/html' href='http://frontiertechnologist.blogspot.com/2010/08/collaborative-network-shares-without.html' title='Collaborative network shares without compromising security'/><author><name>Stephan Stachurski</name><uri>http://www.blogger.com/profile/18429374901205223065</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9144864480315874152.post-1957271161944828438</id><published>2010-08-16T15:38:00.003-04:00</published><updated>2010-11-05T09:23:42.852-04:00</updated><title type='text'>NFS On Lucid Lynx</title><content type='html'>&lt;a href="https://help.ubuntu.com/community/SettingUpNFSHowTo"&gt;Ubuntu Docs: Setting Up NFS&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The above Ubuntu guide is pretty thorough. The following is a summary of the parts that were relative to me.&lt;br /&gt;&lt;br /&gt;Firstly, servers must install the package nfs-kernel-server and clients must install nfs-client.&lt;br /&gt;&lt;br /&gt;Some best practices to follow are to export nfs shares from /export, and shares in here are mounted bound to other file systems, like so:&lt;br /&gt;&lt;blockquote&gt;&lt;tt&gt;# mount --bind /home/users /export/users&lt;/tt&gt;&lt;/blockquote&gt;or, in fstab:&lt;br /&gt;&lt;blockquote&gt;&lt;tt&gt;/media/maxtor/apt-mirror /export/apt-mirror    none    bind    0   0&lt;/tt&gt;&lt;/blockquote&gt;Also, a line has to be added to /etc/exports corresponding to the export path, like so:&lt;br /&gt;&lt;blockquote&gt;&lt;tt&gt;/export/apt-mirror 10.1.10.0/24(rw,nohide,insecure,no_subtree_check,async)&lt;/tt&gt;&lt;/blockquote&gt;Restart the nfs service, and the server is all set up. To set up the client, add a line to /etc/fstab like so:&lt;br /&gt;&lt;blockquote&gt;&lt;tt&gt;10.1.10.94:/export/apt-mirror   /var/spool/apt-mirror/mirror    nfs     rw      0       0&lt;/tt&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9144864480315874152-1957271161944828438?l=frontiertechnologist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frontiertechnologist.blogspot.com/feeds/1957271161944828438/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://frontiertechnologist.blogspot.com/2010/08/nfs-on-lucid-lynx.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/1957271161944828438'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/1957271161944828438'/><link rel='alternate' type='text/html' href='http://frontiertechnologist.blogspot.com/2010/08/nfs-on-lucid-lynx.html' title='NFS On Lucid Lynx'/><author><name>Stephan Stachurski</name><uri>http://www.blogger.com/profile/18429374901205223065</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9144864480315874152.post-6194336269775894671</id><published>2010-07-29T00:10:00.049-04:00</published><updated>2010-07-29T09:04:26.930-04:00</updated><title type='text'>Learning RT from scratch</title><content type='html'>RT is a self-proclaimed hairy beast. The documentation doesn't provide a concise introduction to the concepts, so here is my attempt at providing the most concise, but all-encompassing description of RT. It's pretty directly ripped from the &lt;a href="http://wiki.bestpractical.com/view/HomePage"&gt;RT wiki&lt;/a&gt;, with some fluff cut out.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;a href="http://wiki.bestpractical.com/view/UserManual"&gt;The wiki home page&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;it's big, and learning how to set it up can take some time.&lt;br /&gt;&lt;br /&gt;please plan to spend some quality time with the &lt;a href="http://wiki.bestpractical.com/view/UserManual"&gt;UserManual&lt;/a&gt; before you try to go live; RT is big and hairy, and you probably can't get your head around all of it in one sitting.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;a href="http://wiki.bestpractical.com/view/ManualIntroduction"&gt;manual introduction&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;A Ticket is the central object in RT, the thing that needs to get done. Tickets have metadata attached to them such as an owner, status, and queue - we'll get to all that in a minute.&lt;br /&gt;&lt;br /&gt;A Queue is the central administrative domain of RT; it keeps things organized. As the name implies, it's a line of tickets waiting to be worked on, but it's also, to some extent, the ticket's category. For instance, you might have the right to create, delete, and comment on tickets in the Foo queue, but only the right to comment on tickets in the Bar queue.&lt;br /&gt;&lt;br /&gt;A ticket's history is what it sounds like: everything that's happened to a ticket. Facets of ticket history could include when the ticket was created, how it has changed, and any comments about it or replies to it. Like real history, ticket history cannot be changed (at least not without messing up the space-time continuum), so be aware that any comments you make about a ticket are permanent.&lt;br /&gt;&lt;br /&gt;Ticket updates can take one of two forms. A reply is a public remark that a requestor can see. A comment is a private note for staff not visible to the requestor. This is useful when you want to be tactful but still convey important information, like, "This requestor is an investor, so be nice" or "This user's request mentioned his 'PC' but he really has a Mac."&lt;br /&gt;&lt;br /&gt;Priority, how important a ticket is, is represented as numerical scale from 0-99, with 99 being the highest priority. &lt;a href="http://wiki.bestpractical.com/view/ManualAdministration"&gt;ManualAdministration&lt;/a&gt; contains a useful model for setting organizational policy for priority.&lt;br /&gt;&lt;br /&gt;The status drop-down menu offers several choices for classifying each ticket. Here's what they mean:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;NEW: the ticket has just been created and hasn't been touched yet.&lt;/li&gt;&lt;li&gt;OPEN: the ticket is getting worked on&lt;/li&gt;&lt;li&gt;STALLED: due to circumstances beyond your control (waiting for the requestor to respond, waiting for the owner to return from Sri Lanka), the ticket isn't getting worked on right now. It will open again when someone adds a comment or reply.&lt;/li&gt;&lt;li&gt;RESOLVED: hooray! Work on the ticket has been completed and is out of everyone's hair.&lt;/li&gt;&lt;li&gt;REJECTED: the ticket is not the staff's problem and is not going to be resolved, but is, for some reason, worth recording in the system. For instance, if an employee asks approval for something ridiculous, you can reject the ticket, but it will stay in the database as evidence that the employee makes silly requests.&lt;/li&gt;&lt;li&gt;DELETED: the ticket never should have been in the system (maybe it was spam, a list of passwords, etc) -- and is now being zapped for good.&lt;/li&gt;&lt;/ul&gt;A watcher is someone who is interested in a ticket. You'll find these filed under "People" when you're looking at a ticket. A watcher of a ticket normally gets email-copies of all the replies to the ticket. The watchers who are staff-members get copies of the comments too. There are several types, or roles, of watchers:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;OWNER: the person responsible for the ticket and its resolution. Each ticket can have only one owner. As a ticket it worked on, it may be passed from one owner to another.&lt;/li&gt;&lt;li&gt;REQUESTOR: the person or people who asked for something to get done; the ticket's reason for being. The Requestor normally gets copies of all replies to the ticket, but no comments.&lt;/li&gt;&lt;li&gt;CC: someone (or someones) who should get copies of any replies that go to the requestor. This might be the requestor's boss, sales rep, etc. This person will see the emails but doesn't necessarily have the right to work on the ticket.&lt;/li&gt;&lt;li&gt;ADMINCC: a Cc or Ccs that also gets copies of comments and generally are allowed to work on the ticket.&lt;/li&gt;&lt;/ul&gt;You can also, as you work on a ticket, define its relationship to something. Relationships in RT can be ticket-to-ticket, but can also link tickets to external items like URLs or FedEx shipping numbers. For the sake of simplicity, we'll refer only to tickets in the following explanation of relationship types:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;DEPENDS ON: the ticket can't be resolved unless another ticket is also resolved. The converse is depended on by.&lt;/li&gt;&lt;li&gt;REFERS TO: the ticket doesn't need the other ticket, but it would sure be useful for you to look at it. The converse is referred to by.&lt;/li&gt;&lt;li&gt;PARENT: a big, general ticket ("Move house.")&lt;/li&gt;&lt;li&gt;CHILD: a subproject of a parent ("Hire movers." "Pack." "Eat pizza.")&lt;/li&gt;&lt;/ul&gt;&lt;a href="http://wiki.bestpractical.com/view/CustomField"&gt;CustomFields&lt;/a&gt; are, yes, database fields that your organization can make up according to its needs. For details, see the Custom Fields section in ManualAdministration. An example custom field might be Resolution: FIXED, WORKSFORME, WONTFIX, UPSTREAM, etc, etc... (If you think that example was stolen from Bugzilla, you have much to go on :-)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://wiki.bestpractical.com/view/Scrip"&gt;Scrips&lt;/a&gt; are custom notifications that will automatically take Action X in response to Condition Y. You could have RT notify the Requestor when a ticket is resolved, for instance, or have RT page you when your boss submits a request. RT comes with many standard scrips, and you can define your own. For details, see the Scrips section in &lt;a href="http://wiki.bestpractical.com/view/ManualAdministration"&gt;ManualAdministration&lt;/a&gt;. And no, we didn't misspell "scripts." We made up a new word. Try it, it's fun.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9144864480315874152-6194336269775894671?l=frontiertechnologist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frontiertechnologist.blogspot.com/feeds/6194336269775894671/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://frontiertechnologist.blogspot.com/2010/07/learning-rt-from-scratch.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/6194336269775894671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/6194336269775894671'/><link rel='alternate' type='text/html' href='http://frontiertechnologist.blogspot.com/2010/07/learning-rt-from-scratch.html' title='Learning RT from scratch'/><author><name>Stephan Stachurski</name><uri>http://www.blogger.com/profile/18429374901205223065</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9144864480315874152.post-8526298804823907494</id><published>2010-06-15T23:16:00.001-04:00</published><updated>2010-06-15T23:17:32.157-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='book review'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Book review: Beginning Ubuntu Linux, Fourth Edition</title><content type='html'>This is a book review of &lt;i&gt;Beginning Ubuntu Linux: From Novice to Professional, Fourth Edition&lt;/i&gt;. The print ISBN is 978-1-4302-1999-6 and the web ISBN is 1-4302-1999-8.&lt;br /&gt;&lt;br /&gt;I read the contents of this book almost cover to cover; I only skipped the multimedia section. I read this because I was interested in reading &lt;i&gt;Automating Linux and Unix System Administration&lt;/i&gt;, which apparently is last in a sequence that starts with this book, &lt;i&gt;Beginning Ubuntu Linux&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;In short, &lt;i&gt;Beginning Ubuntu&lt;/i&gt; is an above average introduction to the world of Linux. Anybody who's a windows power user can probably poke around and figure out most things on there own, but parts 4 and 7, &lt;i&gt;The Shell and Beyond&lt;/i&gt; and &lt;i&gt;Keeping Your System Running&lt;/i&gt;, should be mandatory reading for new Linux users. Part 3, &lt;i&gt;The No Nonsense Starting Guide&lt;/i&gt; has some parts which only apply in specific situation, but it's worth reading once.&lt;br /&gt;&lt;br /&gt;Part 4, &lt;i&gt;The Shell and Beyond&lt;/i&gt;, is a concise and clear introduction to the BASH shell, the Filesystem Hierarchy Standard, and in general, the UNIX way of doing things.&lt;br /&gt;&lt;br /&gt;It's not the kind of book I would want to keep around as a reference, at least not for very long. It's not thorough enough on any one subject to make it a good reference. The tone is easy and almost conversational. If you are savvy enough to keep a Windows installation running virus free, and perhaps if you feel comfortable re-installing windows from scratch, then you could probably digest this book pretty easily.&lt;br /&gt;&lt;br /&gt;There are two things I think are missing from this book. One is a procedure for surviving a major upgrade. Every ubuntu user is going to do this sooner or later. A novice could use some advice interpreting the various dialogs that will pop up during a distribution upgrade.&lt;br /&gt;&lt;br /&gt;The second missing piece is a guide about compiling programs from source. Even if it didn't get a full chapter, novices deserve an overview of how programs are built.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9144864480315874152-8526298804823907494?l=frontiertechnologist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frontiertechnologist.blogspot.com/feeds/8526298804823907494/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://frontiertechnologist.blogspot.com/2010/06/book-review-beginning-ubuntu-linux.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/8526298804823907494'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/8526298804823907494'/><link rel='alternate' type='text/html' href='http://frontiertechnologist.blogspot.com/2010/06/book-review-beginning-ubuntu-linux.html' title='Book review: Beginning Ubuntu Linux, Fourth Edition'/><author><name>Stephan Stachurski</name><uri>http://www.blogger.com/profile/18429374901205223065</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9144864480315874152.post-8594266509719649032</id><published>2010-06-07T08:31:00.010-04:00</published><updated>2010-06-10T20:39:17.422-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='apt'/><category scheme='http://www.blogger.com/atom/ns#' term='air gap'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Sneakernet Ubuntu Server Updates</title><content type='html'>After initially deploying an ubuntu server &lt;a href="http://en.wikipedia.org/wiki/Air_gap_(networking)"&gt;high side of an air gap (wikipedia)&lt;/a&gt;, there will come a time when packages need to be added and/or updated. This article attempts to outline a process to build and keep up-to-date a private local repository.&lt;br /&gt;&lt;br /&gt;In short, I will configure the packages on an internet-facing staging server, and copy the downloaded packages to the private server. The packages themselves contain enough data to build the private repository. I've adapted the procedure from &lt;a href="http://odzangba.wordpress.com/2006/10/13/how-to-build-local-apt-repositories/"&gt;Odzangba's &lt;i&gt;How To&lt;/i&gt;&lt;/a&gt;. The main requirement for this to work is that you have access to a staging server on the low side, which will maintain an identical package configuration. This requirement wasn't bad for me, because a staging server is useful for a million other reasons. I run it in a virtual machine on my internet-facing development workstation. Either the low and high servers have to start in an identical configuration, or you have to be assured that &lt;tt&gt;/var/cache/apt/archives&lt;/tt&gt; hasn't been cleared since they may have diverged. For the following procedure we'll assume the two servers are identical. You also need some medium of transferring data between the two hosts. This is where the term "sneakernet" originated. I'm lucky that I don't have to run floppies between two server rooms; thanks to the wonders of modern technology, all i have to do is shift a thumb drive from one USB hub to another. If you are going to be doing this frequently, I would suggest making the sneakernet step as quick and easy as possible.&lt;br /&gt;&lt;br /&gt;Lastly, you will also need to get &lt;tt&gt;build-essentials&lt;/tt&gt;. It is required to have this on the private server before you get started.&lt;br /&gt;&lt;br /&gt;Just so there is no ambiguity, I'll refer to the private host as &lt;span style="font-style: italic;"&gt;high&lt;/span&gt; and the internet-facing host as &lt;span style="font-style: italic;"&gt;low. lowadmin &lt;/span&gt;is the user on the low side, and &lt;i&gt;highadmin &lt;/i&gt;is the user on the high side. &lt;tt&gt;/home/highadmin/localrepo&lt;/tt&gt; is the path to the repository on the high side, and this must be added to &lt;tt&gt;/etc/apt/sources.list&lt;/tt&gt;. The only line the the &lt;tt&gt;sources.list&lt;/tt&gt; file on my high server is&lt;br /&gt;&lt;div&gt;&lt;blockquote&gt;&lt;tt&gt;deb file:/home/highadmin/localrepo/ /&lt;/tt&gt;&lt;/blockquote&gt;OK! So, assuming &lt;i&gt;low &lt;/i&gt;and &lt;i&gt;high &lt;/i&gt;have matching package configurations, this is how to add and/or update packages to the low side and sync those changes to the high side.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The low and high servers are identical. I want to add and/or update packages, so I'll execute the following commands on the low host...&lt;br /&gt;&lt;blockquote&gt;&lt;tt&gt;sudo apt-get update&lt;/tt&gt;&amp;nbsp;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;sudo apt-get upgrade&lt;/span&gt;&lt;/blockquote&gt;and maybe...&lt;br /&gt;&lt;blockquote&gt;&lt;tt&gt;sudo apt-get install foobar spam&lt;/tt&gt;&lt;/blockquote&gt;&lt;/li&gt;&lt;li&gt;Again, on the low host...&lt;br /&gt;&lt;blockquote&gt;&lt;tt&gt;rsync /var/cache/apt/archives/*.deb /media/thumbdrive&lt;/tt&gt;&lt;/blockquote&gt;I also like to add -vh (verbose, human-readable). Maybe &lt;tt&gt;rsync&lt;/tt&gt; isn't necessary here, but I'm just in the habit of using it all the time. Also, my thumbdrive isn't usually passed directly to the virtual staging server, so my command looks more like this...&lt;br /&gt;&lt;blockquote&gt;&lt;tt&gt;rsync -vh /var/cache/apt/archives/*.deb lowadmin@devbox:/media/thumbdrive&lt;/tt&gt;&lt;/blockquote&gt;&lt;/li&gt;&lt;li&gt;Sneakernet step. I move the thumbdrive two inches into another hub, and mount it on the high side server, then...&lt;br /&gt;&lt;blockquote&gt;&lt;tt&gt;rsync -vh /media/thumbdrive/*.deb /home/highadmin/localrepo/&lt;/tt&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;tt&gt;sudo dpkg-scanpackages /home/highadmin/localrepo/ /dev/null | gzip -9c &amp;gt; Packages.gz&lt;/tt&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;tt&gt;sudo apt-get update&lt;/tt&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;tt&gt;sudo apt-get upgrade&lt;/tt&gt;&lt;/blockquote&gt;This is where the magic happens. The second command uses &lt;tt&gt;dpkg-scanpackges&lt;/tt&gt; to create the crucial Packages file. For further reference, see the &lt;a href="http://manpages.ubuntu.com/manpages/lucid/en/man1/dpkg-scanpackages.1.html"&gt;man page&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;That's it; the high side is now up-to-date.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9144864480315874152-8594266509719649032?l=frontiertechnologist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frontiertechnologist.blogspot.com/feeds/8594266509719649032/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://frontiertechnologist.blogspot.com/2010/06/ubuntu-getting-packages-through-air-gap.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/8594266509719649032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/8594266509719649032'/><link rel='alternate' type='text/html' href='http://frontiertechnologist.blogspot.com/2010/06/ubuntu-getting-packages-through-air-gap.html' title='Sneakernet Ubuntu Server Updates'/><author><name>Stephan Stachurski</name><uri>http://www.blogger.com/profile/18429374901205223065</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9144864480315874152.post-8661412326251273705</id><published>2010-03-27T04:24:00.001-04:00</published><updated>2010-11-05T09:21:29.383-04:00</updated><title type='text'>Ubuntu, vim and python</title><content type='html'>Until now, I had never used vi or vim as anything more than an emergency configuration file editor. The following two posts helped me leverage some of the more advanced features and plugins of vim to make it a nice python, fully-featured python editor. All credit goes to the following two posts. Most of the content below is copy-pasted directly from them. It's not my intention to plagiarize; this is just a spot for me to take notes, so that I could repeat the vim configuration process as painlessly as possible.&lt;br /&gt;&lt;br /&gt;http://dancingpenguinsoflight.com/2009/02/python-and-vim-make-your-own-ide/&lt;br /&gt;http://henry.precheur.org/2008/4/18/Indenting_Python_with_VIM.html&lt;br /&gt;&lt;br /&gt;Create the directory ~/.vim/ftplugin; create a file named ~/.vim/ftplugin/python.vim containing:&lt;br /&gt;&lt;br /&gt;setlocal tabstop=4&lt;br /&gt;setlocal softtabstop=4&lt;br /&gt;setlocal shiftwidth=4&lt;br /&gt;setlocal textwidth=80&lt;br /&gt;setlocal smarttab&lt;br /&gt;setlocal expandtab&lt;br /&gt;&lt;br /&gt;To get this working, simply add:&lt;br /&gt;&lt;br /&gt;syntax on&lt;br /&gt;set number&lt;br /&gt;filetype plugin indent on&lt;br /&gt;&lt;br /&gt;to your ~/.vimrc file&lt;br /&gt;&lt;br /&gt;Additionally, you need to download the latest version of &lt;a href="http://www.vim.org/scripts/script.php?script_id=974"&gt;this script&lt;/a&gt;, placing it in ~/.vim/indent/python.vim. This will make indentation much less of a chore, and more of a pleasure. Be sure to also check out &lt;a href="http://henry.precheur.org/2008/4/18/Indenting_Python_with_VIM.html"&gt;this blog post&lt;/a&gt;, wherein Henry Prêcheur explains how to improve indentation for comments as well.&lt;br /&gt;&lt;br /&gt;To improve the formatting and display of improper indentation, as well as special highlighting for things like string formatting, download the latest version of &lt;a href="http://www.vim.org/scripts/script.php?script_id=790"&gt;this script&lt;/a&gt;, and place it in ~/.vim/syntax/python.vim.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9144864480315874152-8661412326251273705?l=frontiertechnologist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frontiertechnologist.blogspot.com/feeds/8661412326251273705/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://frontiertechnologist.blogspot.com/2010/03/ubuntu-vim-and-python.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/8661412326251273705'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/8661412326251273705'/><link rel='alternate' type='text/html' href='http://frontiertechnologist.blogspot.com/2010/03/ubuntu-vim-and-python.html' title='Ubuntu, vim and python'/><author><name>Stephan Stachurski</name><uri>http://www.blogger.com/profile/18429374901205223065</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9144864480315874152.post-3785893353478973636</id><published>2009-12-13T16:11:00.001-05:00</published><updated>2010-11-05T09:14:22.699-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='project management'/><title type='text'>Philosophy of Managing Programmers</title><content type='html'>http://it.toolbox.com/blogs/irm-blog/theory-p-the-philosophy-of-managing-programmers-4993&lt;br /&gt;&lt;br /&gt;This article gave me some insight in to my own behavior.&lt;br /&gt;&lt;br /&gt;Some of the commenters on his site have pointed out that he portrays programmers in a negative light; I disagree and think that this article contains advice that would effectively help protect a business from making the wrong decision about projects.&lt;br /&gt;&lt;br /&gt;It also contains advice for programmers explaining how to avoid making some bad business mistakes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9144864480315874152-3785893353478973636?l=frontiertechnologist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frontiertechnologist.blogspot.com/feeds/3785893353478973636/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://frontiertechnologist.blogspot.com/2009/12/philosophy-of-managing-programmers.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/3785893353478973636'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/3785893353478973636'/><link rel='alternate' type='text/html' href='http://frontiertechnologist.blogspot.com/2009/12/philosophy-of-managing-programmers.html' title='Philosophy of Managing Programmers'/><author><name>Stephan Stachurski</name><uri>http://www.blogger.com/profile/18429374901205223065</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9144864480315874152.post-787826062455822221</id><published>2009-12-13T15:23:00.003-05:00</published><updated>2010-06-10T00:46:01.268-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='cli'/><category scheme='http://www.blogger.com/atom/ns#' term='bash'/><title type='text'>Search your command history</title><content type='html'>&lt;span style="font-style:italic;"&gt;history&lt;/span&gt; is the command to "utilize information from previous lines" (from the man page). My most common usage is like this:&lt;br /&gt;&lt;blockquote&gt;history | grep -i &lt;span style="font-style:italic;"&gt;pattern&lt;/span&gt;&lt;/blockquote&gt;Maybe now that I've recorded it here, I will remember it, and won't have to reference it for the millionth time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9144864480315874152-787826062455822221?l=frontiertechnologist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frontiertechnologist.blogspot.com/feeds/787826062455822221/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://frontiertechnologist.blogspot.com/2009/12/blog-post.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/787826062455822221'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/787826062455822221'/><link rel='alternate' type='text/html' href='http://frontiertechnologist.blogspot.com/2009/12/blog-post.html' title='Search your command history'/><author><name>Stephan Stachurski</name><uri>http://www.blogger.com/profile/18429374901205223065</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9144864480315874152.post-2071642020253742965</id><published>2009-11-19T23:21:00.000-05:00</published><updated>2009-11-20T01:32:15.794-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gpg'/><category scheme='http://www.blogger.com/atom/ns#' term='backblaze'/><category scheme='http://www.blogger.com/atom/ns#' term='s3'/><category scheme='http://www.blogger.com/atom/ns#' term='encryption'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><category scheme='http://www.blogger.com/atom/ns#' term='privacy'/><title type='text'>Finding the strongest security and best value in remote storage</title><content type='html'>&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Data can be priceless. No expense should be spared to prioritize the following two objectives:&lt;/span&gt;&lt;/span&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Information privacy&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Information safety and redundancy&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;I'm trying to come up with a strategy that addresses these needs, and I'd like a little feedback. Also, corrections are much appreciated and I'll do my best to keep this up to date based on any information in the comments.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Data needs to be private. Businesses count on trade secrets, and keeping information private is what keeps a business running. Eventually, sensitive information will end up on a host that is in contact with the internet. The contact could be indirect, temporal, or both. Your privacy should be hedged on the assumption that any host is in danger of being compromised if it's ever in contact with an internet-facing network. The only way to design a system with the highest-possible degree of security is to operate with this assumption in mind. Information also needs to be safe. Nothing less than nuclear holocaust should lead to information loss.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;With the right application of freely available software, this is not only possible, but cheap.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;The most important program needed is the GNU Privacy Guard, or, best known by it's command-line name, &lt;/span&gt;&lt;/span&gt;&lt;a href="http://www.gnupg.org/"&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;gpg&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;. gpg is a free implementation of the OpenPGP standard. When it comes to keeping your information private, OpenPGP is the de facto standard on the cutting edge of computer science. As far as academia is concerned, even &lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;theoretical&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; liabilities have all been weeded out since 1996. This encryption is invulnerable, except possibly to&lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;the military, or corporate black ops. The proof is statistical; if you applied every supercomputer in the world to the task of analyzing a data with this encryption, it would take lifetimes to find the decode. OpenPGP also provides a second layer of privacy; it allows you to sign your data so that it is protected from alteration in transit and in storage. With OpenPGP you are assured that data you store is meaningless to anyone without the key. You are assured that the data you retrieve is identical to the data in your original source &lt;/span&gt;&lt;/span&gt;&lt;a href="http://www.amazon.com/Applied-Cryptography-Protocols-Algorithms-Source/dp/0471117099"&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="line-height: 17px; "&gt;&lt;a href="http://www.amazon.com/Applied-Cryptography-Protocols-Algorithms-Source/dp/0471117099"&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Schneier, Bruce&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://www.amazon.com/Applied-Cryptography-Protocols-Algorithms-Source/dp/0471117099"&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; (1995-10-09). &lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;i&gt;&lt;a href="http://www.amazon.com/Applied-Cryptography-Protocols-Algorithms-Source/dp/0471117099"&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Applied Cryptography&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/i&gt;&lt;a href="http://www.amazon.com/Applied-Cryptography-Protocols-Algorithms-Source/dp/0471117099"&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://www.amazon.com/Applied-Cryptography-Protocols-Algorithms-Source/dp/0471117099"&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;New York&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://www.amazon.com/Applied-Cryptography-Protocols-Algorithms-Source/dp/0471117099"&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;: &lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://www.amazon.com/Applied-Cryptography-Protocols-Algorithms-Source/dp/0471117099"&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Wiley&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://www.amazon.com/Applied-Cryptography-Protocols-Algorithms-Source/dp/0471117099"&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;. p. 587. &lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://www.amazon.com/Applied-Cryptography-Protocols-Algorithms-Source/dp/0471117099"&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;ISBN&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://www.amazon.com/Applied-Cryptography-Protocols-Algorithms-Source/dp/0471117099"&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://www.amazon.com/Applied-Cryptography-Protocols-Algorithms-Source/dp/0471117099"&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;0471117099&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://www.amazon.com/Applied-Cryptography-Protocols-Algorithms-Source/dp/0471117099"&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;.)&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 17px; "&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 17px; "&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;The benefit of secure encryption, from the perspective of remote backup, is that you do not need to trust ANY hosts outside of your network with your information. If your storage provider is in the news because the security was cracked by hackers, you know your data will stay private because you've already taken precautions against the host becoming compromised.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 17px; "&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 17px; "&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Encryption is still very much relevant to locally stored, physical media. Locks can be picked. Cars can be stolen. Packages can get lost. Every piece of media that is not bolted down, and even some that are, could be the source of a potential leak.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 17px; "&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 17px; "&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;The next topic is a discussion of value. The industry benchmark when it comes to the cost of storage is &lt;/span&gt;&lt;/span&gt;&lt;a href="http://aws.amazon.com/"&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Amazon Simple Storage Service (S3)&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;. To back up a total of 1TB of data, and transfer in 100GB of data per month results in a cost of &lt;/span&gt;&lt;/span&gt;&lt;a href="http://calculator.s3.amazonaws.com/calc5.html"&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;$1920&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; per year. S3 features a pay-what-you-use model, which means your needs are guaranteed to be met as they grow. A cheaper option is to use a less permissive backup solution like &lt;/span&gt;&lt;/span&gt;&lt;a href="http://www.backblaze.com/"&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Backblaze&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;. With Backblaze, you are purchasing an unlimited backup license for one computer for $50 per year. This computer must be running a Microsoft Windows operating system, so there is a one-time investment in a Windows license, and there must be a Windows host on your network. The disadvantage of requiring a Windows computer on your network is small compared to the license terms: if the computer you license to Backblaze provides services in your intranet, your complacency with Backblaze's terms is questionable, and your service could be terminated depending on the interpretation of their license agreement.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 17px; "&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 17px; "&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;So, the cost range of acquiring third-party remote storage services has a wide range of $50 to about $2000 per year. The cost of implementing the same solution in house is somewhere in between these two numbers, but it's harder to pin down because it involves man-hours designing, building and maintaining storage systems with a wide range of strict requirements for data integrity.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 17px; "&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 17px; "&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;When using third-party remote storage, you're basically covered if you subscribe to two distinct services; if one suffers a catastrophic failure, your data is still hosted on another site, and hopefully locally as well. When implementing backup first-party, it's your responsibility to maintain data integrity as well as the physical integrity of the system. Parts and computers must be maintained, software must be updated, and the whole system must be protected from physical harm, such as a fire.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 17px; "&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 17px; "&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Let's estimate the cost in hardware to backup, redundantly, 1TB of data to be $800. At a rate of $18/hour, it only takes 60 hours over the course of a year to match the cost of Amazon S3 services, and an additional 100 man hours to match the cost of having two distinctly located buckets with S3. Consider that in order to approach the data safety offered by a service like S3, you would have maintain distinctly located data repositories. This involves maintaining remote hosts and connections between the hosts. Alternatively, data could be physically moved on a regular schedule, but this puts an increased strain on the hardware and results in a higher hardware cost to protect the data from physical shock, purchase special cases, or increase hardware redundancy. From this perspective, S3 seems like a bargain. Costs of S3 are also likely to fall in proportion to the decreased cost of storage, but the cost of man hours puts a price floor on the service; in other words, don't expect prices of S3 storage to fall below $1000 per TB in the next three to five years.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 17px; "&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 17px; "&gt;&lt;span class="Apple-style-span"  style="font-family:verdana;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;For any organization that depends on data, information privacy and safety are crucial. Here is everything I need to know (I think) to make sure that these issues are addressed and policies are in place to meet these needs for a business.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9144864480315874152-2071642020253742965?l=frontiertechnologist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frontiertechnologist.blogspot.com/feeds/2071642020253742965/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://frontiertechnologist.blogspot.com/2009/11/finding-strongest-security-and-best.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/2071642020253742965'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/2071642020253742965'/><link rel='alternate' type='text/html' href='http://frontiertechnologist.blogspot.com/2009/11/finding-strongest-security-and-best.html' title='Finding the strongest security and best value in remote storage'/><author><name>Stephan Stachurski</name><uri>http://www.blogger.com/profile/18429374901205223065</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9144864480315874152.post-2670918474344388529</id><published>2009-10-16T17:19:00.001-04:00</published><updated>2009-10-16T17:21:54.408-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='django'/><category scheme='http://www.blogger.com/atom/ns#' term='model'/><title type='text'>First apps and models are validated!</title><content type='html'>My very first apps and models have been validated. I could have saved a lot of frustration had I only read through the entire tutorial. So, the moral of the story is, &lt;a href="http://en.wikipedia.org/wiki/RTFM"&gt;RTFM&lt;/a&gt;.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Specifically, I needed to use functions that are included as part of manage.py, and not try to make any glue myself.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I will add to this post, on Monday, with details on how exactly I got my first Django project started.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9144864480315874152-2670918474344388529?l=frontiertechnologist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frontiertechnologist.blogspot.com/feeds/2670918474344388529/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://frontiertechnologist.blogspot.com/2009/10/first-apps-and-models-are-validated.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/2670918474344388529'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/2670918474344388529'/><link rel='alternate' type='text/html' href='http://frontiertechnologist.blogspot.com/2009/10/first-apps-and-models-are-validated.html' title='First apps and models are validated!'/><author><name>Stephan Stachurski</name><uri>http://www.blogger.com/profile/18429374901205223065</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9144864480315874152.post-2740266052285420158</id><published>2009-10-15T17:11:00.001-04:00</published><updated>2009-10-15T17:29:45.070-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='server administration'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Installing python packages</title><content type='html'>There is a vast library of python code available to tap into. It's all available at the &lt;a href="http://pypi.python.org/pypi"&gt;Python Package Index (pypi)&lt;/a&gt;.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In order to connect the Django app to the PostgreSQL database, I had to install psycopg2, which is Python's PostgreSQL database adapter.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Debian makes this easy for us because python-psycopg2 is maintained as part of Debian's repos. If this was not the case, then I would have to wget the tarball, extract it, and run 'python setup.py install' for the package. In order for that command to work, one has to have the dev package for your version of python installed. In my case, that would be 'python2.5-dev.' This package provides header files for building your own modules from scratch.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There's a lot of jargon in this post which would be familiar to any intermediate Linux user. I will come back at a later date and provide a glossary similar to the bullet points I added to my git post.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9144864480315874152-2740266052285420158?l=frontiertechnologist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frontiertechnologist.blogspot.com/feeds/2740266052285420158/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://frontiertechnologist.blogspot.com/2009/10/installing-python-packages.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/2740266052285420158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/2740266052285420158'/><link rel='alternate' type='text/html' href='http://frontiertechnologist.blogspot.com/2009/10/installing-python-packages.html' title='Installing python packages'/><author><name>Stephan Stachurski</name><uri>http://www.blogger.com/profile/18429374901205223065</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9144864480315874152.post-1389048201229022691</id><published>2009-10-15T16:31:00.000-04:00</published><updated>2009-10-15T16:46:00.889-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='git'/><title type='text'>Version control</title><content type='html'>I will be tracking this project with the &lt;a href="http://git-scm.com/"&gt;git version control system&lt;/a&gt;.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://en.wikipedia.org/wiki/Revision_control"&gt;Revision Control&lt;/a&gt;, as it is sometimes called, allows you to &lt;b&gt;commit &lt;/b&gt;a group of documents to a &lt;b&gt;repository&lt;/b&gt;, in order to keep track of every &lt;b&gt;revision&lt;/b&gt;.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;repository - &lt;/b&gt;the server/location that collects and keeps track of your project&lt;/li&gt;&lt;li&gt;&lt;b&gt;commit - &lt;/b&gt;to push a snapshot of the current state of your project&lt;/li&gt;&lt;li&gt;&lt;b&gt;revision - &lt;/b&gt;a serial index that tracks every commit you make to the repository&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Revision Control has many benefits. The first is that you store every revision of your project, so that you can roll back to any revision number. The next benefit is the ability to branch your code. Your mainline code is typically called the &lt;b&gt;trunk&lt;/b&gt;. If you decide to change some things around, or start writing a new module to your project, you can create a &lt;b&gt;branch&lt;/b&gt; which can be tracked separately, and then &lt;b&gt;merged&lt;/b&gt; with the trunk. Git allows you to &lt;b&gt;diff&lt;/b&gt; any two versions of a file, which highlights all of the differences between the two files in a way that's easy to browse and understand. Many users can &lt;b&gt;clone&lt;/b&gt; your repository, work on the same files simultaneously, and git provides you with a very nice set of tools to merge all the changes in a way that makes sense. The last benefit to using git is that it's a distributed system: every clone is a complete copy of the entire repository, which is securely copied (i.e. the data is verified as it's copied). This makes &lt;b&gt;git clone&lt;/b&gt; an excellent tool to back up a project.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I will be using git to keep track of different versions, to document my work, and to back it up.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9144864480315874152-1389048201229022691?l=frontiertechnologist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frontiertechnologist.blogspot.com/feeds/1389048201229022691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://frontiertechnologist.blogspot.com/2009/10/version-control.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/1389048201229022691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/1389048201229022691'/><link rel='alternate' type='text/html' href='http://frontiertechnologist.blogspot.com/2009/10/version-control.html' title='Version control'/><author><name>Stephan Stachurski</name><uri>http://www.blogger.com/profile/18429374901205223065</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9144864480315874152.post-9166540278691136440</id><published>2009-10-15T11:56:00.000-04:00</published><updated>2009-10-15T12:23:49.489-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='django'/><category scheme='http://www.blogger.com/atom/ns#' term='mvc'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='model'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><title type='text'>Django - Design Your Model</title><content type='html'>The first step that I'm going to take to designing my web app is to start building up the model. Reference for this section starts with the &lt;i&gt;Design Your Model&lt;/i&gt; section of the &lt;a href="http://docs.djangoproject.com/en/dev/intro/overview/#intro-overview"&gt;Django overview&lt;/a&gt;, and also the related section &lt;a href="http://docs.djangoproject.com/en/dev/topics/db/models/#topics-db-models"&gt;Data-Model Syntax&lt;/a&gt;.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The model is one of three parts that build up the &lt;a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller"&gt;Model-View-Controller&lt;/a&gt; architectural pattern. Basically, the model is a description of your data. Let's say you're designing a social networking application. In plain English, your model would start off something like, "The basic unit of data that we are working with is a member of the site. A member has a first name, last name, password and chosen user name. Members are related to other members in a many-to-many relationship. Members can be friends with other members, they can ignore other members, etc. By default, a member's list of friends is sorted by the order in which they were added..." and your model would continue. The formal model is nothing more than a translation of this natural language model into python.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The view component of an MVC web app tells the browser how pages are displayed. Mostly, the view is made up of templates that have components of the model plugged in.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The controller of an MVC web app handles page requests and decides what to do with components of the model. For example, if you went to visit the home page of our social networking example, it would check to see if you had an existing session, and if not, it will grab a log in page provided by the view. After a user enters this info, the controller takes care of several steps:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;It attempts to authenticate the user against existing users in the database&lt;/li&gt;&lt;li&gt;If authentication is successful, it grabs the appropriate components of the model&lt;/li&gt;&lt;li&gt;It plugs those components into a template provided by the view&lt;/li&gt;&lt;li&gt;It sends the template, complete with info composed from the database, to the user's browser.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Armed with this information, I am going to begin writing parts of the model, and then write some python scripts to import my existing data into my Django web app.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For further reference, see &lt;i&gt;Interacting with a Database: Models&lt;/i&gt; from &lt;i&gt;Definitive Guide to Django&lt;/i&gt;; however, please note that, although this text is less than two years old, different versions of Django can change dramatically. The most up-to-date reference is always available at &lt;a href="http://www.djangoproject.com/"&gt;http://www.djangoproject.com/&lt;/a&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9144864480315874152-9166540278691136440?l=frontiertechnologist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frontiertechnologist.blogspot.com/feeds/9166540278691136440/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://frontiertechnologist.blogspot.com/2009/10/django-design-your-model.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/9166540278691136440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/9166540278691136440'/><link rel='alternate' type='text/html' href='http://frontiertechnologist.blogspot.com/2009/10/django-design-your-model.html' title='Django - Design Your Model'/><author><name>Stephan Stachurski</name><uri>http://www.blogger.com/profile/18429374901205223065</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9144864480315874152.post-3959190059875383476</id><published>2009-10-14T11:37:00.000-04:00</published><updated>2009-10-15T11:56:45.509-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='reference'/><category scheme='http://www.blogger.com/atom/ns#' term='server administration'/><category scheme='http://www.blogger.com/atom/ns#' term='architecture'/><title type='text'>Server setup</title><content type='html'>&lt;div&gt;I'm going to attempt to chronicle the events of me learning how to create web apps. As of now, I'm responsible for creating everything from scratch. At this point, I've already sketched a very rough outline of how my first web app is going to turn out; I have chosen to build it on the Django framework, with a PostgreSQL database, running on a Debian server. All of those are new to me. Well, I have had some experience running Ubuntu on my home desktop, and as a simple SSH/file server, so Debian isn't entirely new to me.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;So far, I have installed Debian with kernel 2.6.26-2-amd64, and all of the software I need. Hopefully, by today, I should have some equivalent of "Hello, world" that I can access through a browser from some other computer on the LAN, and maybe start populating the database with some sample data.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'm skimming &lt;i&gt;Dive Into Python&lt;/i&gt;, &lt;i&gt;The &lt;/i&gt;&lt;i&gt;Definitive Guide to Django&lt;/i&gt;, and the PostgreSQL docs as I go along.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9144864480315874152-3959190059875383476?l=frontiertechnologist.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frontiertechnologist.blogspot.com/feeds/3959190059875383476/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://frontiertechnologist.blogspot.com/2009/10/server-setup.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/3959190059875383476'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9144864480315874152/posts/default/3959190059875383476'/><link rel='alternate' type='text/html' href='http://frontiertechnologist.blogspot.com/2009/10/server-setup.html' title='Server setup'/><author><name>Stephan Stachurski</name><uri>http://www.blogger.com/profile/18429374901205223065</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
