Listing & Downgrading Unstable/Testing Debian Packages

Posted by ryan
at 2:44 PM on Monday, October 31, 2005



I like to keep my debian machines pretty true to the stable release – but every once and awhile I’ll make an exception for some piece of software I really feel I need and install from the testing or unstable repository. Most of the time I end up not really needing or using that application, but that’s besides the point. The point is that I like to take a quick monthly inventory of what installed packages are not from the stable source, and usually downgrade to the stable if not completely remove the unstable package. Here’s how I do it:

  1. Install the apt-show-versions command:
    apt-get install apt-show-versions
  2. List the stable and testing packages:
    apt-show-versions | grep /testing
    apt-show-versions | grep /unstable
At this point I usually go through and remove individual packages making sure that there’s nothing important in their dependencies. However, this is pretty inconvenient and when I’m feeling particularly saucy I will downgrade my whole machine to stable. This is much easier and you can always cancel when apt-get confirms what packages are being downgraded:
  1. Edit your /etc/apt/preferences file and change the “Pin-Priority” value of the stable section to 1001. Some of you may not already have this file, so I’ll just put the contents of mine (the majority of which comes from the apt-pinning guide):
    <b>Package: *
    Pin: release a=stable
    Pin-Priority: 1001</b>
    
    Package: *
    Pin: release a=testing
    Pin-Priority: 650
    
    Package: *
    Pin: release a=unstable
    Pin-Priority: 600
  2. Do an upgrade to perform the downgrade (somewhat oxy-moronish, but you do go the start menu to stop Windows too…):
    apt-get upgrade
    Reading Package Lists... Done
    Building Dependency Tree... Done
    The following packages will be DOWNGRADED:
      binfmt-support ...

Basically, to downgrade debian packages, set the pin-priority to 1001 for the stable packages in your /etc/apt/preferences. Similarly, to downgrade an individual package you can set up a similar section in your preferences file for that package. Let’s say I want to downgrade the “libxrender1” package from unstable to stable. I could do this by adding this section to my /etc/apt/preferences file:
Package: libxrender1
Pin: release a=stable
Pin-Priority: 700
This says to ensure (or “pin”) that the libxrender1 package is a stable package w/ priority 700 (this number just needs to be above the unstable and testing priorities if you’re apt-pinning). Now an upgrade will make sure this package is downgraded to the stable version:
apt-get upgrade
Reading Package Lists... Done
Building Dependency Tree... Done
The following packages will be DOWNGRADED:
  libxrender1
0 upgraded, 0 newly installed, 1 downgraded, 0 to remove and ...

At this point you may see that you still have some unstable or testing packages still installed (using apt-show-versions | grep /unstable). This occurs either when there are no stable versions of these packages available OR another package that cannot be downgraded depends on that version of the package. After doing the mass downgrade I will usually go through and remove a remaining individual unstable package and do a downgrade again. Often removing one of the remaining unstable packages will resolve the bottle neck and a subsequent downgrade will clear out a lot of stuff.

For the more sinister amongst us here is any easy way to remove ALL packages of a certain package:

apt-get remove `apt-show-versions -b | grep testing`
or
apt-get remove `apt-show-versions -b | grep unstable`
If you’re knee-deep in non-stable packages this will often want to remove your whole system, so it is only helpful if you have a few packages with minimal dependencies to remove.

Remember that when push comes to shove you can always remove and re-install a particularly stubborn package – apt-get will keep the config files for a package unless told otherwise so you don’t lose any of your data or setup files.

RoR, Learning Ruby the Wrong Way

Posted by ryan
at 10:20 AM on Monday, October 31, 2005



Like most people that have recently jumped on the Ruby on Rails bandwagon (or at least given it a try), one of the first things I did was read the Ruby on Rails book and jump into developing my own web app. Well, here I am a few months later looking at my initial version of the app – and I am completely disappointed. The code is crap – it’s inelegant, somewhat procedural and completely un Ruby-like. And I blame it all on Ruby on Rails.

You see, in my rush to stay with the hype I’ve jumped into Ruby on Rails without spending due time learning Ruby. I suspect many people have done the same thing and what you will begin to see is a dilution of the talent in the Ruby community as more people come into the language the wrong way – through RoR.

It’s not a bad thing that Ruby on Rails has brought exposure to Ruby, but it’s obscuring the language itself which is unfortunate. In an attempt to rectify my mis-education I have taken a step back and am starting to explore the language before proceeding on with more RoR. Until developing with Ruby becomes intuitive to me I shouldn’t be working w/ RoR. I mean how many people successfully learn Java by learning Struts first?

My hope is that I am amongst the minority, but I suspect there are others who have made the same mistake as I have.

Book Review: "The Ruby Way" by Hal Fulton

Posted by ryan
at 9:34 PM on Sunday, October 09, 2005



If you’ve ever bought a learning ruby book, there’s a good chance it was the “pickaxe book” – Dave Thomas’ “Programming Ruby: The Pragmatic Programmers’ Guide”. I’ve read it myself and it is as billed, an excellent book to learn Ruby from.

However, I’m actually finding that Hal Fulton’s book, The Ruby Way is a better read for me. I’m coming from Java and while the Pragmatic book will set you on your way to learning the ruby syntax and some idioms, it doesn’t do much more than that. I need to see how to use Ruby, concrete examples of common problems and how to solve them. I have no doubt that this need stems from my own ignorance and not on the lack of merit of the pragmatic book, but it has been my experience none-the-less. So, if you’re pining for more Ruby lovin’ after reading the pragmatic guide, give the Ruby Way a try, it may be the book that fills that void in your life.

Ruby On Rails caching, part 2

Posted by ryan
at 4:36 PM on Thursday, October 06, 2005



It’s pretty obvious what phase I’m at with my app given my recent postings: that’s right, figuring out an appropriate caching strategy.

It seems as though I’ve run across another nuance with caching – if you use the “caches_page” method in your controller for an action that is invoked via XMLHttpRequest (i.e. via AJAX), it won’t get cached. For instance, building on my last issue:

class UsersController < ApplicationController

  caches_page :find, <b>find_simple</b>

  def find
    @user = User.find(params[:id)
  end

  <b>def find_simple
    @user = User.find(params[:id])
    render(:action => 'find', :layout => false)    
  end</b>

end

The “find_simple” method is the action that will be invoked via AJAX and, despite the caches_page directive, it does not get cached. A look at the logs reveals this, as does a look at the cache directory on your filesystem (there will be no users/find_simple/id.html).

The solution is pretty simple, use “caches_action” instead of “caches_page”:

class UsersController < ApplicationController

  caches_page :find
  <b>caches_action :find_simple</b>

  def find
    @user = User.find(params[:id)
  end

  def find_simple
    @user = User.find(params[:id])
    render(:action => 'find', :layout => false)    
  end

end

The ramification of this switch is that now all your action filters will get executed for every request. However, as AJAX calls are usually pretty lightweight, action caching should be quite sufficient.

I know the “caches_page” method adds an ‘after’ filter to the controller for each of its actions – this issue seems to imply that the filter is bypassed when a request comes in via XMLHttpRequest. It would also imply that the app server/RoR knows the difference between a ‘normal’ request and an XMLHttpRequest one – which is not what I would have expected. Anyway, no skin off my back as the solution is quite reasonable.

Ruby on Rails/WEBrick - Using "caches_page" with a different base directory 1

Posted by ryan
at 1:52 PM on Thursday, October 06, 2005



I’ve come across a situation in my little sandbox ruby on rails app that might get some people. I’m trying to add caching to my controllers using the “caches_page” method, which will capture the complete output of the action being cached and store it as an html file in your filesystem. It’s setup like so in your controller:

class UsersController < ApplicationController
  <b>caches_page :find</b>
  def find
    @user = User.find(params[:id)
  end
end

Without any monkeying around with the configs or the location of the cached output, it works great. I execute the controller the first time and see the SQL output in the debug log statements, and execute it again and see nothing (indicating it didn’t even hit the controller and pulled the page straight from the cache). Perfect. I can even see the html output in “public/users/find/1.html.

However, I moved the location on my filesystem of the cached output to a different directory by adding this line to “config/environments/development.rb”:

ActionController::Base.page_cache_directory = "/tmp/ror/cache" 

Great, now when I hit the same page and then go look in the new cache directory I can see the same “users/find/1.html” file. However, upon closer inspection of my log files I see that it’s never pulling and using the cached file for output – obviously defeating the purpose of such an endeavor.

To understand the problem we have to understand how the caching works. All the “caches_page” call does is take the raw HTML output from the full execution of the action (filters and action) and put it on the filesystem in a place where WEBrick is looking for static files. By default they’re placed in the “public” directory, which is where WEBrick looks for static files first before handing off to RoR. Well, with my changed config that static place has moved, but WEBrick doesn’t know about it – hence the cache not being hit on identical requests.

So it appears there are limited options. I’ve looked in the “scripts/server” file that bootstraps WEBrick and tells where WEBrick should serve files from, and it appears that you can only specify one such directory:

OPTIONS = {
  :port        => 3000,
  :ip          => "0.0.0.0",
  :environment => "development",
  <b>:server_root => File.expand_path(File.dirname(__FILE__) + "/../public/"),</b>
  :server_type => WEBrick::SimpleServer
}

So, adding another root to that path won’t work (to have WEBrick serve from both “public” and the new cache directory ”/tmp/ror/cache”). It would appear that our only viable options are to combine the cache and public directories into one physical location – either move the files in “public” to your cache directory or leave the config as it is out of the box and have your cached output sent to “public”. This is the option I’m going with for now until I can figure out a better solution, although it’s quite a pain to not commit the cache files into subversion after the cache has been used…