<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jeff Blaine &#187; JB</title>
	<atom:link href="http://www.kickflop.net/blog/author/jb/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kickflop.net/blog</link>
	<description></description>
	<lastBuildDate>Thu, 19 Jan 2012 20:59:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Django: Taking note of ManyToManyField changes</title>
		<link>http://www.kickflop.net/blog/2012/01/18/django-taking-note-of-manytomanyfield-changes/</link>
		<comments>http://www.kickflop.net/blog/2012/01/18/django-taking-note-of-manytomanyfield-changes/#comments</comments>
		<pubDate>Thu, 19 Jan 2012 02:05:36 +0000</pubDate>
		<dc:creator>JB</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.kickflop.net/blog/?p=1417</guid>
		<description><![CDATA[I&#8217;ve gone through a bit of a mess lately, trying to do something I considered very possible, only to ultimately fail to find a working solution. This write-up will hopefully save someone else several hours of effort, asking for help, waiting, etc. Those reading the article, please be sure to also read any comments to [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve gone through a bit of a mess lately, trying to do something I considered very possible, only to ultimately fail to find a working solution.  This write-up will hopefully save someone else several hours of effort, asking for help, waiting, etc.</p>
<p>Those reading the article, please be sure to also read any comments to the article, as others may have additional ideas, solutions, or helpful information.</p>
<p>As you can see from the documentation links in this post, I am working with version 1.3.  I am not aware of any differences in 1.3.1 or 1.4.0 regarding the topic covered in this post.</p>
<h2>Scenario</h2>
<p>You have a <a href="https://docs.djangoproject.com/en/1.3/topics/db/models/">Django model</a>. That model has a field which is a <a href="https://docs.djangoproject.com/en/1.3/ref/models/fields/#manytomanyfield">ManyToManyField</a>. When an instance of your model is modified via any mechanism (custom web form, Django admin interface, code using the ORM, etc), you want to execute some custom code based on what happened to the model instance&#8217;s fields (including the ManyToManyField).</p>
<p>Specifically, what if you need to keep a non-Django source in sync with a Django model&#8217;s data? In my case, I have a &#8220;simple&#8221; need to push changes to a Django model&#8217;s data to an LDAP server.<span id="more-1417"></span></p>
<pre>
class Interface(models.Model):
    fqdn = models.CharField(primary=True,
                            verbose_name="Fully Qualified Domain Name",
                            max_length=80)

class Netgroup(models.Model):
    name = models.CharField(primary=True,
                            max_length=80)

    interfaces = models.ManyToManyField(model=Interface,
                                        null=True,
                                        blank=True)
</pre>
<p>Did <code>NetgroupInstance.interfaces</code> change? What changed? Was 1 interface removed from 500?  What was that 1 interface? Were 9 interfaces added to the existing 15 interfaces? What were the 9 interfaces?  Was this a brand new Netgroup creation with interfaces added at creation-time?  What were the interfaces?</p>
<h2>Solution 1?</h2>
<p>Just override the <code>Netgroup</code> save() method! Call the superclass&#8217;s save first, then run your custom code against the saved data.</p>
<p><strong>FAILS:</strong> The ManyToManyField data is not reliable at this point in the code flow for some reason. See the first few posts in <a href="http://groups.google.com/group/django-users/browse_thread/thread/8a179538637b2648">my thread here</a>.</p>
<h2>Solution 2?</h2>
<p>Maybe try Django&#8217;s <a href="https://docs.djangoproject.com/en/1.3/topics/signals/">signals</a>?  Register your custom code as a callback function for the Django <code>post_save</code> signal?</p>
<p><strong>FAILS:</strong> Does not work properly in the &#8216;Admin&#8217; interface at a minimum. Creating a new <code>Netgroup</code> with some <code>Interface</code> relations selected does not show the <code>Interface</code> relations inside the post_save callback function. Another similar case to above. See the <a href="http://groups.google.com/group/django-users/browse_thread/thread/b5c9ceb05ae3d178">final post here</a> (as of 1/18/2012).</p>
<h2>Solution 3?</h2>
<p>Try solution 2 in combination with another signal callback function for the <code><a href="https://docs.djangoproject.com/en/1.3/ref/signals/#m2m-changed">m2m_changed</a></code> Django signal. This was recommended to me in #django-users IRC as the way to do it.</p>
<p><strong>FAILS:</strong> Does not work properly in the &#8216;Admin&#8217; interface. Removing <code>Interface</code> relationships does not present itself as data associated with the <code>pre_remove</code> and/or <code>post_remove</code> &#8220;actions&#8221;. Instead, it appears the &#8216;Admin&#8217; interface clears all interfaces from the field and then adds the correct interfaces back in. See <a href="https://code.djangoproject.com/ticket/16073">bug 16073</a>, <a href="https://code.djangoproject.com/ticket/14482">bug 14482</a>, and this <a href="https://groups.google.com/forum/#!topic/django-developers/27PofpUfR_0">thread</a>.</p>
<h2>Sad Conclusion</h2>
<p>If there wasn&#8217;t a bug, we would obviously use solution 3, even though I find it goofy to have to catch an extra signal (<code>m2m_changed</code>) when a model happens to have a ManyToManyField on it.</p>
<p>As it is now, we just use &#8220;Solution 2&#8243; and tell users of the &#8216;Admin&#8217; interface, via extra <code><a href="https://docs.djangoproject.com/en/1.3/ref/forms/fields/#help-text">help_text</a></code> on the <code>Netgroup.name</code> field, to enter the name, save, <em>then</em> add items to the Netgroup instance.</p>
<pre>
class Interface(models.Model):
    fqdn = models.CharField(primary=True,
                            verbose_name="Fully Qualified Domain Name",
                            max_length=80)

class Netgroup(models.Model):
    name = models.CharField(primary=True,
                            max_length=80,
                            help_text="WARNING: save new netgroups with just the name, then add interfaces and save again.  Sorry!")

    interfaces = models.ManyToManyField(model=Interface,
                                        null=True,
                                        blank=True)

from django.db.models.signals import post_delete, post_save, m2m_changed

def netgroup_delete(sender, **kwargs):
    pass # DO STUFF HERE

def netgroup_save(sender, **kwargs):
    pass # DO STUFF HERE

post_delete.connect(netgroup_delete, sender=Netgroup,
                    dispatch_uid="netgroup_delete")
post_save.connect(netgroup_save, sender=Netgroup,
                  dispatch_uid="netgroup_save")
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.kickflop.net/blog/2012/01/18/django-taking-note-of-manytomanyfield-changes/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Thunderbird 8 rewrote my subject?</title>
		<link>http://www.kickflop.net/blog/2011/12/14/thunderbird-rewrote-my-subject/</link>
		<comments>http://www.kickflop.net/blog/2011/12/14/thunderbird-rewrote-my-subject/#comments</comments>
		<pubDate>Wed, 14 Dec 2011 17:41:46 +0000</pubDate>
		<dc:creator>JB</dc:creator>
				<category><![CDATA[Quality Control]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.kickflop.net/blog/?p=1403</guid>
		<description><![CDATA[I have no Thunderbird extensions installed. I sent this message (in blue below) with the subject shown. I received it too, as I was a recipient. I then selected it (as you see above) and replied to it (replying to my own message, to add new info). I didn&#8217;t touch the subject line. I sent [...]]]></description>
			<content:encoded><![CDATA[<p>I have no Thunderbird extensions installed.</p>
<p>I sent this message (in blue below) with the subject shown.  I received it too, as I was a recipient.</p>
<p><a rel="lightbox" href="http://www.kickflop.net/blog/wp-content/uploads/2011/12/thunderbird-odd.jpg"><img src="http://www.kickflop.net/blog/wp-content/uploads/2011/12/thunderbird-odd-300x46.jpg" alt="" title="thunderbird-odd" width="300" height="46" class="center size-medium wp-image-1406" /></a></p>
<p>I then selected it (as you see above) and replied to it (replying to my own message, to add new info).  I didn&#8217;t touch the subject line.  I sent the new reply out.  I receieved it too, as I was a recipient.  Here is how I received it.  Take note of the changed subject.</p>
<p><a rel="lightbox" href="http://www.kickflop.net/blog/wp-content/uploads/2011/12/thunderbird-odd2.jpg"><img src="http://www.kickflop.net/blog/wp-content/uploads/2011/12/thunderbird-odd2-300x46.jpg" alt="" title="thunderbird-odd2" width="300" height="46" class="center size-medium wp-image-1405" /></a></p>
<p><strong>Update</strong>: Testing shows that the subject is being altered by Thunderbird as soon as I click on the original message and hit reply.  The reply window appears with the subject altered.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kickflop.net/blog/2011/12/14/thunderbird-rewrote-my-subject/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Never assume customers will register complaints</title>
		<link>http://www.kickflop.net/blog/2011/11/21/never-assume-customers-will-register-complaints/</link>
		<comments>http://www.kickflop.net/blog/2011/11/21/never-assume-customers-will-register-complaints/#comments</comments>
		<pubDate>Mon, 21 Nov 2011 21:46:55 +0000</pubDate>
		<dc:creator>JB</dc:creator>
				<category><![CDATA[Sysadmin]]></category>

		<guid isPermaLink="false">http://www.kickflop.net/blog/?p=1400</guid>
		<description><![CDATA[We&#8217;re an enterprisey shop. Our department has no public-facing services. Our shop&#8217;s customers are engineer employees at our company, and you could basically consider our department a large lab operations group at a deep-but-slow think tank. This will be a pretty moronic post to anyone involved in providing performant web services for a salary, but [...]]]></description>
			<content:encoded><![CDATA[<p><em>We&#8217;re an enterprisey shop.  Our department has no public-facing services.  Our shop&#8217;s customers are engineer employees at our company, and you could basically consider our department a large lab operations group at a deep-but-slow think tank.  This will be a pretty moronic post to anyone involved in providing performant web services for a salary, but I&#8217;m always readily willing to look moronic to tell a story.</em></p>
<p>As an aside, in an unrelated ticket, a customer mentioned slow page load times for one of the pages served by our GForge Advanced Server instance.  He indicated that this particular page always takes nearly 20 seconds to load and offered that it might be tied to the fact that he is a member of roughly 20 projects hosted via that GForge server.</p>
<p>This aside from the customer was a remarkable coincidence, as I had created an internal task ticket 2-3 weeks ago for us to implement metrics gathering for this service because &#8220;we should&#8221;.  We already were performing the most basic of up/down monitoring for the host and service via Nagios.  Now we get to have a problematic baseline of metrics and watch things improve from here.</p>
<p>After tweaking our Apache logging to log request service time (<code>%D</code> via <a href="http://httpd.apache.org/docs/2.0/mod/mod_log_config.html">mod_log_config</a>, we noticed some (too many) problematic pages for certain users and projects.  One of those pages was, of course, the page the customer had reported.</p>
<p>So far, we&#8217;ve instrumented metric gathering for each block of PHP (&#8230;) code in the most commonly accessed problematic page and tracked down the specific section where the slowness happens.  The metric gathering is simplistic: for each major block of execution in the PHP file, store a start time, store an end time, and calculate total seconds to execute that block.  Finally, <code>syslog()</code> the accumulated metrics as one line.</p>
<p>Anyway, that&#8217;s not the point of this post.  The point is: <strong>Never stand up a service that works overall and assume your users will complain of slowness.  Turns out 10-20 users have been quietly suffering through seriously long page load times for years now without saying a word to us.</strong>  According to other admins in other departments (who responded to our nice-but-essentially &#8220;WTF people?&#8221; message to all customers of the GForge service), they&#8217;ve experienced the same phenomenom.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kickflop.net/blog/2011/11/21/never-assume-customers-will-register-complaints/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On Pithy Bullshit Analogies</title>
		<link>http://www.kickflop.net/blog/2011/11/14/on-pithy-bullshit-analogies/</link>
		<comments>http://www.kickflop.net/blog/2011/11/14/on-pithy-bullshit-analogies/#comments</comments>
		<pubDate>Mon, 14 Nov 2011 20:05:51 +0000</pubDate>
		<dc:creator>JB</dc:creator>
				<category><![CDATA[Sysadmin]]></category>

		<guid isPermaLink="false">http://www.kickflop.net/blog/?p=1397</guid>
		<description><![CDATA[I&#8217;ve had it with the pithy bullshit analogies, especially via Tweets. Belittling those who productively scrutinize and debate similar software offerings is LAME. I&#8217;m so sick of hearing people dismiss &#8220;Chef vs. Puppet&#8221; discussions (and hundreds of other very valid comparison-style blog posts, etc) as worthless, un-enlightened, and several other holier-than-thou attributions, as if the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve had it with the pithy bullshit analogies, especially via Tweets.</p>
<p>Belittling those who productively scrutinize and debate similar software offerings is LAME.</p>
<p>I&#8217;m so sick of hearing people dismiss &#8220;Chef vs. Puppet&#8221; discussions (and hundreds of other very valid comparison-style blog posts, etc) as worthless, un-enlightened, and several other holier-than-thou attributions, as if the content is a simplistic bantering about Coke vs. Pepsi.</p>
<p>My camel&#8217;s back broke when John Allspaw (<a href="https://twitter.com/#!/allspaw">@allspaw</a>) recently tweeted:</p>
<blockquote><p>Sometimes I imagine web engineers as carpenters; too busy being angry about each other&#8217;s brand of hammers to actually build the damn house.</p></blockquote>
<p>Greg Fodor (<a href="https://twitter.com/#!/gfodor">@gfodor</a>) replied with:</p>
<blockquote><p>amateurs argue over tools. journeymen argue over techniques. experts argue if we should be building the house in the first place.</p></blockquote>
<p>Both of these statements are nothing more than horriffic broccoli farts with the hive-minded in the DevOps world apparently smelling them as roses.  I don&#8217;t know Greg Fodor, but I&#8217;m pretty positive John Allspaw is a lot more intelligent than that bullshit tweet of his, and he should be concerned about saying what he actually means, in detail.  Because, you know, people listen to him.</p>
<p>Decisions are all based on something.  Just because you don&#8217;t need to bother yourself with making the &#8220;small&#8221; decisions anymore doesn&#8217;t give you a new license to be an asshole toward those involved in discussions about those &#8220;small&#8221; decisions.  Those people making the &#8220;small&#8221; decisions now, with debates and careful evaluations surrounding them, MAKE SHIT ULTIMATELY HAPPEN.  I understand that everyone, more and more, just wants stuff to magically happen, but the reality still is that things need to be planned, discussed, scrutinized, evaluated, and finally decided on.  Don&#8217;t get pissy because that part still has to happen and your Idea-to-Realization time can&#8217;t be measured in minutes.</p>
<p>God damn.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kickflop.net/blog/2011/11/14/on-pithy-bullshit-analogies/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Graphite for RHEL 5.7</title>
		<link>http://www.kickflop.net/blog/2011/11/01/graphite-for-rhel-5-7/</link>
		<comments>http://www.kickflop.net/blog/2011/11/01/graphite-for-rhel-5-7/#comments</comments>
		<pubDate>Wed, 02 Nov 2011 01:14:54 +0000</pubDate>
		<dc:creator>JB</dc:creator>
				<category><![CDATA[Sysadmin]]></category>

		<guid isPermaLink="false">http://www.kickflop.net/blog/?p=1392</guid>
		<description><![CDATA[Graphite install for RHEL 5.7 from scratch. Official Graphite documentation is at http://graphite.readthedocs.org/ export PATH=/usr/bin:/bin:/usr/sbin:/sbin mkdir -p /graphite/src cd /graphite/src # Download Python 2.7.x source from python.org # Unpackage cd Python-2.7.2 ./configure --prefix=/graphite make make install cd .. # Now make sure you get your python before RHEL's export PATH=/graphite/bin:$PATH # Download Django 1.x source [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://graphite.wikidot.com/">Graphite</a> install for RHEL 5.7 from scratch.</p>
<p>Official Graphite documentation is at <a href="http://graphite.readthedocs.org/">http://graphite.readthedocs.org/</a></p>
<pre>
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
mkdir -p /graphite/src
cd /graphite/src

# Download Python 2.7.x source from python.org
# Unpackage

cd Python-2.7.2
./configure --prefix=/graphite
make
make install
cd ..

# Now make sure you get your python before RHEL's

export PATH=/graphite/bin:$PATH

# Download Django 1.x source from django.org
# Unpackage

cd Django-1.3
python setup.py install
cd ..

# Download django-tagging from http://code.google.com/p/django-tagging/
# Unpackage

cd django-tagging-0.3.1
python setup.py install
cd ..

# Download Twisted 11.x source here from http://twistedmatrix.com/
# Unpackage

cd Twisted-11.0.0
python setup.py install
cd ..

# Download setuptools from http://pypi.python.org/pypi/setuptools
# Unpackage

cd setuptools-0.6c11
python setup.py install
cd ..

# Download pip from http://pypi.python.org/pypi/pip
# Unpackage

cd pip-1.0.2
python setup.py install
cd ..

# Now you have to build the Cairo graphics library, as RHEL's
# is too old for py2cairo's needs.

# Start with pixman, a dependency for building cairo!

# Download pixman from http://www.cairographics.org/releases/
# Unpackage

cd pixman-0.22.2
./configure --prefix=/graphite
make
make install

# Download cairo from http://www.cairographics.org/releases/
# Unpackage

cd cairo-1.10.2
# Make sure we find our shit and don't have runtime linker problems
export LDFLAGS="-L/graphite/lib -Xlinker -rpath -Xlinker /graphite/lib"
# PKG_CONFIG_PATH is set below so pixman is found
export PKG_CONFIG_PATH=/graphite/lib/pkgconfig
# Turn off all the X shit and gobject since RHEL glib2 is too old
./configure --prefix=/graphite --without-x --enable-xlib=no \
    --enable-xlib-xrender=no --enable-xcb-shm=no --enable-qt=no \
    --enable-gl=no --enable-gobject=no
make
make install

# Download Pycairo (aka py2cairo) from http://www.cairographics.org/pycairo/
# Unpackage

# Had to add these to LDFLAGS or ./waf configure bombs on Python.h test
# due to not including them when it should be in its test
export LDFLAGS="$LDFLAGS -lm -ldl -lutil"
cd py2cairo-1.10.0
./waf configure --prefix=/graphite
./waf build
./waf install
cd ..

# Download carbon, whisper, and graphite-web from
# https://launchpad.net/graphite
# Unpackage

cd whisper-0.9.9
python setup.py install
cd ..

cd carbon-0.9.9
python setup.py install
cd ..

cd graphite-web-0.9.9
./check-dependencies.py # Ignore WARNINGs as you see fit
python setup.py install
cd ..
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.kickflop.net/blog/2011/11/01/graphite-for-rhel-5-7/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Explaining Syslog to RH Support</title>
		<link>http://www.kickflop.net/blog/2011/11/01/explaining-syslog-to-rh-support/</link>
		<comments>http://www.kickflop.net/blog/2011/11/01/explaining-syslog-to-rh-support/#comments</comments>
		<pubDate>Tue, 01 Nov 2011 18:06:55 +0000</pubDate>
		<dc:creator>JB</dc:creator>
				<category><![CDATA[Sysadmin]]></category>

		<guid isPermaLink="false">http://www.kickflop.net/blog/?p=1388</guid>
		<description><![CDATA[Were my expectations too high? Support, what RHEL service is logging this? rhnsd? yum-updatesd? It should show the process name in the syslog output. Please fix? Oct 27 10:00:04 rcf-monitor : 4 updates available Response: I think that rfc-monitor is likely a third-party service of some sort. I haven&#8217;t been able to find any mention [...]]]></description>
			<content:encoded><![CDATA[<p>Were my expectations too high?</p>
<pre>
Support, what RHEL service is logging this?  rhnsd?  yum-updatesd?
It should show the process name in the syslog output.  Please fix?

Oct 27 10:00:04 rcf-monitor : 4 updates available</pre>
<p>Response:</p>
<blockquote name="SupportStaff"><p>I think that rfc-monitor is likely a third-party service of some sort. I haven&#8217;t been able to find any mention of it internally or any package or file with that name on RHN. So I don&#8217;t think that&#8217;s yum or rhnsd talking.
</p></blockquote>
<pre>
Support,

Syslog logs the hostname.  rcf-monitor is the hostname.

Proper syslogging looks like this, where you will note
"ntpd" as the service responsible for generating the
syslog line.

Nov  1 03:52:51 rcf-monitor ntpd[27018]: message here...
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.kickflop.net/blog/2011/11/01/explaining-syslog-to-rh-support/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>twm Shirt</title>
		<link>http://www.kickflop.net/blog/2011/08/26/twm-shirt/</link>
		<comments>http://www.kickflop.net/blog/2011/08/26/twm-shirt/#comments</comments>
		<pubDate>Sat, 27 Aug 2011 03:18:41 +0000</pubDate>
		<dc:creator>JB</dc:creator>
				<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[UNIX/Linux]]></category>

		<guid isPermaLink="false">http://www.kickflop.net/blog/?p=1373</guid>
		<description><![CDATA[Paying homage to the classic Tab/Tom&#8217;s Window Manager, it&#8217;s the twm shirt, available with no markup in cost toward my wallet. Designed by yours truly. If you&#8217;d like to do something else with the design, here it is in multiple formats, and I&#8217;d love to hear if you liked it. OpenDocument Drawing Big-ass PNG @ [...]]]></description>
			<content:encoded><![CDATA[<p>Paying homage to the classic Tab/Tom&#8217;s Window Manager, it&#8217;s the <a href="http://www.cafepress.com/cp/customize/product2.aspx?number=567528755">twm shirt</a>, available with no markup in cost toward my wallet.</p>
<p><a href="http://www.cafepress.com/cp/customize/product2.aspx?number=567528755"><img src="http://www.kickflop.net/blog/wp-content/uploads/2011/08/twm-small.png" alt="" title="twm-small" width="370" height="182" class="aligncenter size-full wp-image-1374" /></a></p>
<p>Designed by yours truly.  If you&#8217;d like to do something else with the design, here it is in multiple formats, and I&#8217;d love to hear if you liked it.</p>
<ul>
<li><a href='http://www.kickflop.net/blog/wp-content/uploads/2011/08/twm.odg'>OpenDocument Drawing</a></li>
<li><a href="http://www.kickflop.net/blog/wp-content/uploads/2011/08/twm.png">Big-ass PNG @ 300dpi</a></li>
<li><a href='http://www.kickflop.net/blog/wp-content/uploads/2011/08/twm.eps'>Encapsulated PostScript</a></li>
<li><a href='http://www.kickflop.net/blog/wp-content/uploads/2011/08/twm.plain.svg'>Plain SVG</a></li>
<li><a href='http://www.kickflop.net/blog/wp-content/uploads/2011/08/twm.svg'>Inkscape SVG</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.kickflop.net/blog/2011/08/26/twm-shirt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adjusting a PostgreSQL Sequence</title>
		<link>http://www.kickflop.net/blog/2011/08/08/adjusting-a-postgresql-sequence/</link>
		<comments>http://www.kickflop.net/blog/2011/08/08/adjusting-a-postgresql-sequence/#comments</comments>
		<pubDate>Mon, 08 Aug 2011 20:58:34 +0000</pubDate>
		<dc:creator>JB</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Sysadmin]]></category>

		<guid isPermaLink="false">http://www.kickflop.net/blog/?p=1365</guid>
		<description><![CDATA[I recently had the unfortunate task at work of copying most of a production PostgreSQL database to a development server. The whole database would have been simple. It&#8217;s the &#8220;most of&#8221; part that made things messy. At any rate, I ended up in a position where I needed to make various incorrect &#8220;sequence&#8221; definitions match [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had the unfortunate task at work of copying most of a production PostgreSQL database to a development server.  The whole database would have been simple.  It&#8217;s the &#8220;most of&#8221; part that made things messy.  At any rate, I ended up in a position where I needed to make various incorrect &#8220;sequence&#8221; definitions match their respective tables.  For example, the maximum <code>id</code> in table <code>principals</code> was 18133 and the sequence used for that primary key was currently at, well, 1.</p>
<p>I&#8217;d never ever delved into this sort of thing before (I had to look up what a PostgreSQL sequence was) as I&#8217;m not a DBA by trade.  I also won&#8217;t likely have to do this again for quite some time, so here are my notes:</p>
<p>Query the last value for the sequence (well call this <em>SEQLAST</em> below, and assume it returned 3):</p>
<pre>SELECT last_value FROM mytable_sequence;</pre>
<p>Query for the largest <code>id</code> (our primary key, we&#8217;ll call this <em>LARGESTID</em> below and assume it returned 18133):</p>
<pre>SELECT id FROM mytable ORDER BY id DESC;</pre>
<p>If <em>SEQLAST</em> and <em>LARGESTID</em> match, you&#8217;re all set.  If they don&#8217;t, you need to adjust <code>mytable_sequence</code> so that the next primary key issued is <em>LARGESTID</em> + 1 for <code>mytable</code>.  You do this with the <code>setval</code> sequence function.</p>
<pre>SELECT setval('mytable_sequence', 18133);</pre>
<p>This reads as, &#8220;Set the last value of <code>mytable_sequence</code> to 18133 and increment before handing out the next number when <code>nextval()</code> is called for this sequence.&#8221;  The incrementing is implied, though you could also specify the clearer and functionally equivalent statement via:</p>
<pre>SELECT setval('mytable_sequence', 18133, true);</pre>
<p>You could also specify &#8220;Set the next value of <code>mytable_sequence</code> to 18134 and do not increment before handing out the next number when <code>nextval()</code> is called for this sequence.&#8221;</p>
<pre>SELECT setval('mytable_sequence', 18134, false);</pre>
<p>Reference: <a href="http://www.google.com/search?hl=en&#038;safe=off&#038;q=site%3Apostgresql.org+postgresql+setval&#038;oq=site%3Apostgresql.org+postgresql+setval&#038;aq=f&#038;aqi=&#038;aql=&#038;gs_sm=e&#038;gs_upl=8000l13475l0l13730l20l15l0l0l0l2l180l1683l6.9l15l0">Google Search: site:postgresql.org postgresql setval</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.kickflop.net/blog/2011/08/08/adjusting-a-postgresql-sequence/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The First InterOp</title>
		<link>http://www.kickflop.net/blog/2011/08/07/the-first-interop/</link>
		<comments>http://www.kickflop.net/blog/2011/08/07/the-first-interop/#comments</comments>
		<pubDate>Sun, 07 Aug 2011 21:08:58 +0000</pubDate>
		<dc:creator>JB</dc:creator>
				<category><![CDATA[Sysadmin]]></category>

		<guid isPermaLink="false">http://www.kickflop.net/blog/?p=1361</guid>
		<description><![CDATA[I wasn&#8217;t aware of this and thought it was cool. From The Robustness Principle Reconsidered: The original InterOp conference was intended to allow vendors with Network File System (NFS) implementations to test interoperability and ultimately demonstrate publicly that they could interoperate. The first 11 days were limited to a small number of engineers so they [...]]]></description>
			<content:encoded><![CDATA[<p>I wasn&#8217;t aware of this and thought it was cool.</p>
<p>From <a href="http://cacm.acm.org/magazines/2011/8/114933-the-robustness-principle-reconsidered/fulltext">The Robustness Principle Reconsidered<a>:</p>
<blockquote><p>The original InterOp conference was intended to allow vendors with Network File System (NFS) implementations to test interoperability and ultimately demonstrate publicly that they could interoperate. The first 11 days were limited to a small number of engineers so they could get together in one room and actually make their stuff work together. When they walked into the room, the vendors worked mostly against only their own systems and possibly Sun&#8217;s (since as the original developer of NFS, Sun had the reference implementation at the time). Long nights were devoted to battles over ambiguities in the specification. At the end of those 11 days the doors were thrown open to customers, at which point most (but not all) of the systems worked against every other system. By the end of that session the NFS protocol was much better understood, many bugs had been fixed, and the standard was improved. This is an inevitable path for implementation-driven standards.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.kickflop.net/blog/2011/08/07/the-first-interop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On Home Renovation</title>
		<link>http://www.kickflop.net/blog/2011/06/26/on-home-renovation/</link>
		<comments>http://www.kickflop.net/blog/2011/06/26/on-home-renovation/#comments</comments>
		<pubDate>Sun, 26 Jun 2011 17:48:38 +0000</pubDate>
		<dc:creator>JB</dc:creator>
				<category><![CDATA[Home]]></category>
		<category><![CDATA[Products]]></category>

		<guid isPermaLink="false">http://www.kickflop.net/blog/?p=1318</guid>
		<description><![CDATA[A month or two ago, I finished up a pale blue and chocolate (trim) painting of my bedroom. I also replaced all of the 2-prong (but internally grounded) outlets with 3-prong outlets and replaced the window handles and lock. I was really enjoying my work and detail. I got to the door part of the [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="lightbox" href="http://www.kickflop.net/blog/wp-content/uploads/2011/06/300-paint-bedroom.jpg"><img src="http://www.kickflop.net/blog/wp-content/uploads/2011/06/300-paint-bedroom-150x150.jpg" alt="" title="300-paint-bedroom" width="150" height="150" class="alignright size-thumbnail wp-image-1330" /></a>A month or two ago, I finished up a pale blue and chocolate (trim) painting of my bedroom.  I also replaced all of the 2-prong (but internally grounded) outlets with 3-prong outlets and replaced the window handles and lock.  I was really enjoying my work and detail.  I got to the door part of the project and thought,</p>
<blockquote><p>Gee, before I paint this, let me make this cheap hollow <a href="http://www.insidewoodworking.com/luanplywood.html">luan</a>-sheeted door better with a new doorknob and door stop.</p>
<p>I&#8217;ll see if I can fill it with insulating foam, too, for sound-deadening.</p>
<p>Also, it&#8217;s sticking at the door-jamb between the hinges and messing up the previous paint, so I&#8217;ll fix that somehow too.</p></blockquote>
<p>See, new solid wood doors cost $320 or so from Lowes, and this house isn&#8217;t in a neighborhood where such investment would be returned at resale.<span id="more-1318"></span></p>
<p>The door stop was $3 and took 20 seconds to replace.  While at Lowes, I picked up a new door knob set.</p>
<p>I removed the old door, stripped it of its hinges and doorknob, and proceeded to drill 8 3/8&#8243; holes into each of its 2 long edges for spray insulating foam injection.  Six cans of foam, some clean up with razor and sandpaper, and 24 hours later, the inner side of the door and edges were ready to paint chocolate.  Painted out in the sun, laid on makeshift saw-horses, I noticed a bit of a bow developing in the door, but shrugged it off.  An hour later, my mother called to see what I was up to that fine Saturday.  I mentioned the bowing of the door.</p>
<blockquote><p>&#8220;Is it out in the sun?&#8221;<br />
&#8220;Yes&#8221;<br />
&#8220;That&#8217;ll do it.&#8221;</p></blockquote>
<p>Knowing there wasn&#8217;t really anything I could do about it now, I decided I&#8217;d just have to see how things settled after drying and test fitting.</p>
<p>After several days of being re-hinged and mounted, the door was still pinching at the door jamb about 6 inches from being fully closed.</p>
<p>Door removal, two Dremel sessions with a sanding drum later, and another separate sanding of the door edge surface to remove ~1mm, the door edge and jamb trim were finely honed to allow the door to close all the way.  I even shimmed under the hinges in strategic spots to perfectly center the door within the trim to allow as much room for paint as possible.</p>
<p>I repainted any sanded surfaces with chocolate, then, 2 weeks later, I motivated myself to finally get the paint and paint the outer surface of the door white to match the hallway.</p>
<blockquote><p>You&#8217;re not going to win, door.</p></blockquote>
<p>Having never installed a doorknob before, I read the instructions.  Turns out the semi-old doorknob was through a very rough 2 1/32&#8243; hole in the door and 2 1/8&#8243; is the standard.  I decided I&#8217;d have to drill a new hole.  It also turns out the old bolt receiving plate was at least an inch longer (its mating surface with the door jamb) than the new one, so I&#8217;d have some wood filling to do.</p>
<blockquote><p>How am I going to drill this new 2 1/8&#8243; hole when there&#8217;s no material for the centering bit in this hole saw to grab?  This saw is just going to jump all over the place and chew the hell out of the door everywhere but where I want.</p></blockquote>
<p>After, indeed, chewing the hell out of the doorknob area, I went to Lowes ready to pick up a new door slab/blank to start over with.  In the door aisle, I barely happened across a slick little <a href="http://www.irwin.com/tools/linear-edge/metal-wood-door-lock-installation-kits">door lock installation kit</a> which has a guide you mount to the door for receiving the hole saw.  Another <em>I-don&#8217;t-even-remember-anymore</em> dollars later, I was at home with the kit and not a new door.  I mounted the guide to the door and drilled a nice clean hole.  The area around the hole that was chewed up would have to get some wood filler, sanding, and repainting.</p>
<p>Min-Wax Performance Wood Filler to the rescue.<br />
<a rel="lightbox" href="http://www.kickflop.net/blog/wp-content/uploads/2011/06/400-paint-bedroom.jpg"><img src="http://www.kickflop.net/blog/wp-content/uploads/2011/06/400-paint-bedroom-150x150.jpg" alt="" title="400-paint-bedroom" width="150" height="150" class="alignright size-thumbnail wp-image-1333" /></a><br />
I filled in the entire receiving plate area and filled in the chewed area around the doorknob hole.  Though the directions call for only 30 minutes of dry time before sanding, I gave the filler a day to dry then sanded.  With some careful marking, Dremel, chisel, and paint work, everything got finished up.</p>
<h2>I win.</h2>
<div class="clear"></div>
]]></content:encoded>
			<wfw:commentRss>http://www.kickflop.net/blog/2011/06/26/on-home-renovation/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

