failed to update RubyGems 0.9.5 to 1.0.0

I don’t have a fix for it yet (admittedly, I haven’t bothered looking since I don’t have a problem with 0.9.5 as of yet), just posting

% sudo gem update –system
Updating RubyGems…
Attempting remote update of rubygems-update
Successfully installed rubygems-update-1.0.0
1 gem installed
Updating version of RubyGems to 1.0.0
Installing RubyGems 1.0.0
./lib/rubygems.rb:77: uninitialized constant Gem::RbConfig (NameError)
        from setup.rb:19

Advertisements

Pros/Cons with Rails

I’ll probably just keep updating this post as I run across more things.  It’s ostensibly as a comparison to ASP.NET 3.5 with the upcoming extensions.

Good things / Pros

  • Migrations
    • Actually a ActiveRecord thing, so it can be used outside of Rails easily enough (gem install activerecord).  It’s a great way of tracking changes to schemas and codifying how to upgrade/downgrade between schemas. 
  • rake, and the built-in rake tasks
    • lots of useful things in the box, including things like db:create/db:reset.
  • MVC architecture
    • Definitely not unique to Rails, but it generates a lot of the right kinds of structure for you, keeping you from having to consciously/forcefully implement MVC yourself – it makes the easiest thing to do the right thing to do, especially with the scripts it comes with.
  • Comes with script.aculo.us, prototype, etc
    • Also not unique to Rails, but it’s nice to come with excellent client javascript libraries that make things like ajax updates and DOM manipulation so simple.
  • RSpec
    • Behavior Driven Development, indeed.  It’s a great way to describe code behavior, and it’s a nice higher-level way to work about normal unit tests.
  • Console
    • Based on irb, it lets you interact with your project via the command-line and that makes life very nice for doing some isolated ad-hoc testing.  Just ask Amy.  I have to agree – the sandbox mode alone is Freakin’ Sweet!  Check the mix tape for additional love.
  • Cross-platform
    • While you can do ASP.NET on Mono to be sure, it’s not the “supported standard” like Windows is, while Rails (and Ruby, obviously) works as well on my Linux machine (and obviously on OSX) as it does on Windows.

Bad things / Cons

  • No “great” IDE as of yet
    • the editor of choice for Rails developers is clearly TextMate.  However, there’s a lack of a good (sorry, but Visual Studio-level) IDE.  Aptana (built on Eclipse) comes the closest from what I’ve seen so far, but the debugging and editing experience there still leaves a bit to be desired – it’s far short of Eclipse for Java or even Visual Studio for C#/VB.  I’m toggling between Aptana for debug-type work and vim-ruby / rails.vim / cream for more mainstream editing (couldn’t get rubycomplete to act right for me).
  • No “great” WYSIWYG view editing
    • I haven’t found anything yet that gives the kind of split-view development I get when creating ASP.NET apps with VS2008, especially with the built-in CSS, html, asp.net, and javascript intellisense.  It’s not a requirement, but it makes life a lot easier, at least for me and my typical stumble-through-it HTML/CSS creation methodology.
  • Ruby, take it or leave it
    • It’s clear from the DLR / Silverlight / IronPython / IronRuby / etc work that you can target ASP.NET with more than just a single language now, and more languages are likely on the way.  C# and VB are still likely to be the first-class citizens for awhile, but there’s at least a choice.  Don’t get me wrong, I like Ruby a lot, but if you happen to have a team that’s not got a lot of Ruby experience and you don’t want to take the training and learning-curve hit, Rails is off the table.

    Push

    • Out-of-the-box scaffolding
      • Rails has had this for ages, but it’s clear that ASP.NET 3.5 extensions is looking to fill the gap, especially with the new Dynamic Data web site option.
    • Don’t need to recompile
      • Like with JSP, ASP.NET automatically recompiles any parts needed (.aspx files, whatever) on the next request as needed.  I’m not going to penalize Ruby for being interpreted here, since my target isn’t really deployment per se, but development.
  • if it quacks like a roll of tape…

    I’ve found a surprising number of sites (even Ruby ones) that think it’s duct typing instead of Duck typing

    I wonder why they think it’s called “duct”?  Because it holds everything together like the force?

    On a related note, I like how Boo allows you to choose whether you want Duck typing or not.  This is a nice compromise, and it would be nice to have something like it in C#. πŸ™‚

    Along with the normal types like object, int, string…boo has a special type called “duck”. The term is inspired by the ruby programming language’s duck typing feature (“If it walks like a duck and quacks like a duck, it must be a duck”).

    If you declare an object as type duck or cast to type duck (or turn on the implicit duck typing option, see below), then boo will not try to resolve any methods or operations you call on that object at compile time. Instead it will convert those operations into methods that do not resolve until runtime. So at compile time it simply trusts that you know what you are doing (“it walks like a duck so it must be a duck”).

    /etc/mysql/debian-log-rotate.conf: No such file or directory

    As part of starting some Rails development on my linux dev box, I installed mysql-server which was up and running fine.  However, once a day I was getting an email from cron about a failure:

    /etc/cron.daily/mysql-server:
    /etc/cron.daily/mysql-server: line 26: /etc/mysql/debian-log-rotate.conf: No such file or directory
    run-parts: /etc/cron.daily/mysql-server exited with return code 1

    So, apparently the daily cron script for mysql to do log rotation needs a fail /etc/mysql/debian-log-rotate.conf to exist.  If that’s true, it seems like it should have come in one of the packages, so I check to see what package should have installed it:

    % dpkg -S debian-log-rotate.conf
    dpkg: *debian-log-rotate.conf* not found.

    So, none of my packages own a file by that name, in /etc/mysql or anywhere else.  So, it’s a bug that the file is needed but not present.  Whatever, this is 6.06 so I’m not going to bother reporting it since I’m pretty sure this is fixed more recently in the 3 released versions since.

    What to do?  Well, let’s check out that script (/etc/cron.daily/mysql-server) around line 26 to see what it’s trying to do:

    # Read config and see if we should rotate at all.
    . /etc/mysql/debian-log-rotate.conf
    if [ “$KEEP_BINARY_LOGS” -eq 0 ]; then
      my_exit 0
    fi

    Since this is just a server to play around with and not a production system, I don’t care about keeping any logs around (I can re-create the schema, sans data, at any time with “rake db:reset:all“)

    sudo vim /etc/mysql/debian-log-rotate.conf

    I insert a single line of

    KEEP_BINARY_LOGS=0

    And that’s it – now the script will exit early, but succeed fine.  And I won’t get any more cron emails about this particular failure πŸ™‚

    how NOT to do tutorials

    First hit for “monorail tutorial” says “Work in progress“.

    Go to their trunk and hit the documentation, and there’s 3 links under “Tutorials and Hands-on labs”.  Great!

    Except, you know, all 3 say “Work in progress”.  Monorail as a project has been around awhile.  They’re very close to 1.0, even since they’re at 1.0 RC2 as I write this.

    The most useful hit was at #4, a video on how to pull off the monorail move with a diabolo.

    Rails 2.0 and following DHH's build-a-blog screencast

    Now that I had gotten Rails 2.0 installed, it was time to make a Rails 2.0 app.  I decided to go back to the original screencasts (tons of more recent ones at railscasts) and see if I could follow DHH‘s original “build a blog in 15 minutes” screencast.  There’s some things that don’t work any more, and more importantly, a good number of things that are significantly better/easier in 2.0 now.  Here’s a list based on following the video:

    File extensions

    While you can still use index.rhtml, the preferred naming separates the mime-type from the rendering mechanism, so you’d be better off using index.html.erb.

    http://weblog.rubyonrails.org/2007/12/7/rails-2-0-it-s-done

    We’ve separated the format of the template from its rendering engine. So show.rhtml now becomes show.html.erb, which is the template that’ll be rendered by default for a show action that has declared format.html in its respond_to. And you can now have something like show.csv.erb, which targets text/csv, but also uses the default ERB renderer.

    Database needed even for Hello World

    In the video, he didn’t set up the database until after he already had a controller created, handling an index action (that did a render :text), and then the index.rhtml view.  In Rails 2.0, you can’t do that any more, because you’ll immediately get an error on that /blog hit. 

    No such file or directory – /tmp/mysql.sock

    You have to have the database setup before you have a working controller, even if no database access is involved at all.  I’m fine with that, of course, since you need to get the database config fixed eventually for anything interesting.

    Database server setup

    While I don’t know for sure whether this is a Rails 2.0 thing or not, the database.yml file in the video doesn’t have a socket: line, so I’m leaning towards this being a 2.0 thing, although I’m happy to hear otherwise if that’s not the case πŸ™‚

    From the above error, it’s relatively obvious that rails is trying to talk to a mysql server via a socket located at /tmp/mysql.sock.

    • First step, actually go install mysql-server (I didn’t have it installed already – d’oh! – so sudo apt-get install mysql-server) and start it (sudo /etc/init.d/mysql start)
    • Confirmed that it was listening on localhost port 3306 (not really needed, but a sanity check)
      • % sudo netstat -tunap|grep -i 3306
        tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN     6309/mysqld
    • Restarted WEBrick hoping it would at least contact mysql via that port if the socket failed, but no such luck, even though “host: localhost” is in the database.yml file
    • While I could have dug into it to figure out how to get the tcp port working, the google searches on mysql.sock made it clear that I could add socket: with the local path to the mysql.sock to get that to work. Who knows, maybe someone out there thinks it’s a good idea based on a security concern, even though mysql’s default TCP bind is localhost-only.
    • /tmp/mysql.sock didn’t exist, so I checked /etc/mysql/my.cnf to see where the socket was getting opened
      • [client]
        port            = 3306
        socket          = /var/run/mysqld/mysqld.sock
    • So, I added “socket: /var/run/mysqld/mysqld.sock” to each of the development/test/production stanzas in database.yml, restarted WEBrick (script/server), and I was past that error and rails could connect to the mysql server.
    • I learned later on (when running rails to create the app after mysql was installed and running), that the socket: line is already in place and I wouldn’t have had to do this by hand if I had already installed MySQL first πŸ™‚

    Database creation

    In the video, you see him using a MySQL gui a lot for creating the database and tables and then turning around and creating the model based on it.  As many others apparently agree, that’s pretty ugly that with a database abstraction layer in place, we’re still having to interact directly with the database (especially since ActiveRecord Migrations exist)

    Thankfully, that’s gone in 2.0, thanks to Matt Aimonetti, and you can create the current database or all of them in a single rake command (or drop, or drop and re-create).  I chose to create all 3 of them and ran rake db:create:all.  Very nice!

    Table creation

    Also in the video, you see him use the MySQL gui for the creation of a table, as mentioned above.  When I got to the “generate model Post” step, I realized this isn’t necessary any more.

    Now generating the model will also generate the migration script to create the relevant table!  That’s awesome!  You just go edit the migration script that was generated for creating the table, which already has a shell create_table in self.up (with t.timestamps already in place!  nice!) and the necessary drop_table in self.down.

    % script/generate model Post
          create  app/models/
          create  test/unit/
          create  test/fixtures/
          create  app/models/post.rb
          create  test/unit/post_test.rb
          create  test/fixtures/posts.yml
          create  db/migrate
          create  db/migrate/001_create_posts.rb

    % cat db/migrate/001_create_posts.rb
    class CreatePosts < ActiveRecord::Migration
      def self.up
        create_table :posts do |t|

          t.timestamps
        end
      end

      def self.down
        drop_table :posts
      end
    end

    Yes, of course, this is using the new Sexy Migrations syntax, so all I had to add to the create_table was:

    t.string :title
    t.text :body

    (UPDATE: I now know that I could have just added title:string and body:text onto the end of the generate model command line)

    Then, just run db:migrate and I had a great posts table in my database!  I really like the 2 columns that t.timestamps gives you – that’s a nice touch.  And notice that I didn’t have to create the id column like he did in the video.

    mysql> desc posts;
    +————+————–+——+—–+———+—————-+
    | Field      | Type         | Null | Key | Default | Extra          |
    +————+————–+——+—–+———+–
    ————–+
    | id         | int(11)      | NO   | PRI | NULL    | auto_increment |
    | title      | varchar(255) | YES  |     | NULL    |                |
    | body       | text         | YES  |     | NULL    |                |
    | created_at | datetime     | YES  |     | NULL    |                |
    | updated_at | datetime     | YES  |     | NULL    |                |
    +————+————–+——+—–+———+—————-+
    5 rows in set (0.01 sec)

    Most importantly, I never had to interact with MySQL directly – heck, except for the database.yml settings, I don’t even *know* that the backend is MySQL.

    However, I ended up removing this migration and model due to the change in scaffolding, which I’ll cover now:

    Scaffolding

    In the video, he gets the scaffolding (wiki page, API doc) going in the blog controller with “scaffold :post” in the blog controller.  That doesn’t work in Rails 2.0 any more.  If you try to use it, you’ll get:

    undefined method `scaffold' for BlogController:Class

    This wasn’t covered in the 2.0 blog posts I ran across, but some other hits thought that scaffold had been removed in 2.0.  Rather than guess, I checked out the changelog located at /usr/lib/ruby/gems/1.8/gems/actionpack-2.0.1/CHANGELOG to confirm, and sure enough it was intentionally removed by DHH himself.

    * Removed ActionController::Base.scaffold — it went through the whole idea of scaffolding (card board walls you remove and tweak one by one).
    Use the scaffold generator instead (it does resources too now!) [DHH]

    So, checking the output of “script/generate scaffold” I see our example in there already:

    Description:
        Scaffolds an entire resource, from model and migration to controller and
        views, along with a full test suite. The resource is ready to use as a
        starting point for your restful, resource-oriented application.

        Pass the name of the model, either CamelCased or under_scored, as the first
        argument, and an optional list of attribute pairs.

        Attribute pairs are column_name:sql_type arguments specifying the
        model’s attributes. Timestamps are added by default, so you don’t have to
        specify them by hand as ‘created_at:datetime updated_at:datetime’.

        You don’t have to think up every attribute up front, but it helps to
        sketch out a few so you can start working with the resource immediately.

        For example, `scaffold post title:string body:text published:boolean`
        gives you a model with those three attributes, a controller that handles
        the create/show/update/destroy, forms to create and edit your posts, and
        an index that lists them all, as well as a map.resources :posts
        declaration in config/routes.rb.

    Examples:
        `./script/generate scaffold post` # no attributes, view will be anemic
        `./script/generate scaffold post title:string body:text published:boolean`
        `./script/generate scaffold purchase order_id:integer amount:decimal`

    Since it generates the model, migration, and controller, I go ahead and rake db:drop:all and just start the app over from scratch.  As per the above, I didn’t need to add the socket: lines this time around, so right after running “rails”, I ran the above “generate scaffold” and then “rake db:create:all” and “rake db:migrate”  – I end up with the same table as the first time, except now I have another column (of mysql type tinyint(1)) called “published” since I included that from the example.

    Since the “generate scaffold” also generates the controller, I don’t need to create a controller myself, but it’s called PostsController instead of BlogController, so when we start the server again and hit the url, it’s /posts and not /blog.  However, hitting it with the Firefox I already had running ends up with an error:

    CGI::Session::CookieStore::TamperedWithCookie

    We can see one of the Rails 2.0 security measures in action here – nice!  I’m sure this is because my Firefox has an existing cookie from the previous incarnation of the rails app, so I’ll just clear the cookie.  Tools -> Options -> Show Cookies, and I remove the cookie there:

    image

    Now I can hit /posts again and it works!

    image

    Then, adding a new post has a form now:

    image

    And clicking create shows the new post (at /posts/1), including the flash of “successfully created” – yay!

    image

    Clicking Back to get to the full list:

    image

    Adding comments

    As with the first time we generated a model (even though we threw that one away), when we “script/generate model Comment”, we automatically get the migration file for adding the comments table. All we need to add is:

    t.text :body
    t.integer :post_id

    (UPDATE: I now know that I could have just added body:text and post_id:integer onto the end of the generate model command line)

    Since the screencast manually inserts the first comment, I follow that same pattern here, just for the sake of it.  It’s not needed, since the next step includes creating the form that allows for inserting new comments, but I do it anyway πŸ™‚

    mysql> insert into comments (body, post_id) values (‘my first comment!’, 1);
    Query OK, 1 row affected (0.02 sec)

    Following that and the edits to app/views/posts/show.html.erb, I have my comment shown and the enter-a-comment form!

    image

    Running unit tests

    In the video, he mentions that tests are created when models get created and he runs “rake test_units” to run the existing unit tests, which runs fine with 2 tests, 0 failures.  That fails in 2.0, unfortunately.

    Don’t know how to build task ‘test_units’

    Fortunately, I’ve noticed a pattern in other places where underscores were replaced with colons, since “rake db_migrate” is now “rake db:migrate”, and “rake test:units” works fine with the expected results.

    Finished in 0.346111 seconds.

    2 tests, 2 assertions, 0 failures, 0 errors

    I went to change the test_truth test in test/unit/post_test.rb like his and came to realize a few of things:

    1. since test/test_helper.rb defaults to use_instantiated_fixtures = false, I probably needed to use a local variable instead of a class variable to hold the post.
    2. Since test/test_helper.rb defaults to use_transactional_fixtures = true, running the test wouldn’t actually commit a new comment.  This is certainly best-practice for database-backed (non-mocked) tests these days, and it’s great to see.

    One thing I noticed after doing the initial run of the tests is that running the test:units created the tables and inserted the fixture data already – nice!

    mysql> select * from posts;
    +———–+———-+——–+———–+———————+———————+
    | id        | title    | body   | published | created_at          | updated_at          |
    +———–+———-+——–+———–+———————+———————+
    | 953125641 | MyString | MyText |         0 | 2007-12-14 14:51:48 | 2007-12-14 14:51:48 |
    | 996332877 | MyString | MyText |         0 | 2007-12-14 14:51:48 | 2007-12-14 14:51:48 |
    +———–+———-+——–+———–+———————+———————+
    2 rows in set (0.00 sec)

    This data comes from the default fixture file created back when I did the scaffolding:

    % cat test/fixtures/posts.yml
    # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html

    one:
      title: MyString
      body: MyText
      published: false

    two:
      title: MyString
      body: MyText
      published: false

    Nice – so, I pick the id of one of the posts that was inserted and use that for my test:

    def test_adding_comment
      post = Post.find(953125641)
      post.comments.create :body => ‘new comment’
      post.reload
      assert_equal 1, post.comments.length
    end

    Run the tests again, and it passes.  I change the post id to 1 for a moment just to make sure it fails, and it does πŸ™‚

    script/console

    I try ./script/console like in the screencast, only to get an error of irb: command not found.  Easy enough to fix with sudo apt-get install irb πŸ™‚

    I do the same interaction with doing a Post.find to get the post, modifying its title, saving it, then checking /posts/1 to see that the change is reflected.  Then I also did the p.comments.create :body => ‘this comment comes via console’, and that showed up fine as well (didn’t need to p.save – I guess the save is implied if you’re making a change through a relationship?  i’ll figure that out later).  Nice.

    That’s it!

    Ok, this blog post has gone on long enough.  Hopefully someone finds it useful, even if only as a brain dump from me going through this process. πŸ™‚

    Phishing attack and identification – Amazon.com

    image

    Dear Amazon.com customer,
    We recently noticed one or more attempts to log in to your account from a foreign IP address. If you accessed your account while travelling, the unusual login attempts may have been initiated by you. However, if you did not initiate the logins, please visit
    Amazon.com Inc. as soon as possible to verify your identity.
    This is a security measure that will ensure that you are the only person who can access your Amazon account. Thank you for your patience as we work together to protect your account.
    To get started, please click the link below and login to your account:
    https://www.amazon.com/gp/yourstore/ref=pd_irl_gw/ie=UTF8&signIn=1
    Best Regards,
    Amazon.com Inc. Security Center

    At least at first glance, it looks pretty believable (I’ll ignore the misspelled “traveling” as a hint, since “real” companies misspell as well, even AMZN I’d imagine :).  It sounds like a legitimate security concern, and certainly something a “regular user” would potentially believe.

    So, let’s investigate this email and find the hints that this is a phishing attack and not an actual security email from Amazon.

    Who is it from?

    Clicking show details at the top, I can see more of the email headers, and that’s our first hint, as Amazon wouldn’t be sending email from a place that’s not an Amazon domain, certainly not a Lycos domain in the UK.

    image

    Next step, let’s hover over that link near the bottom of the email to see where it would actually take us.  Another red flag, as it goes to a different address than it appears to go to via the text in the link – the destination isn’t even on amazon.com.  Smells phishy!

    image

    This particular hint can be foiled in the general case as links can have attributes that change what the status text is when they’re hovered over.  Maybe gmail prevents that?  Don’t know, but I wouldn’t trust it just if it happened to match.

    Next step – let’s view the “raw” original email:

    image

    Scanning the headers of the original, here’s some that stick out to me:

    X-MSMail-Priority: Normal
    X-Mailer: Microsoft Outlook Express 6.00.2600.0000
    X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000
    X-Virus-Scanned: Symantec AntiVirus Scan Engine

    No sizable company, especially Amazon, is going to be sending emails like that via Outlook Express.  Are you kidding me?  I would say that them using Windows for

    <a href="http://www.amazrock.byethost13.com" target=_blank>https://www.amazon.com/gp/yourstore/ref=pd_irl_gw/ie=UTF8&signIn=1</a>

    There’s the link that actually takes you to the phishing site.

    Let’s look at the last (in the order in the email) Received header, since that’s where the email originated from:

    Received: from User (cpe-74-74-67-247.stny.res.rr.com [74.74.67.247])
    	by ms-smtp-02.nyroc.rr.com (8.13.6/8.13.6) with SMTP id lBECfmVg008564;
    	Fri, 14 Dec 2007 07:42:08 -0500 (EST)
    Message-Id: 200712141242.lBECfmVg008564@ms-smtp-02.nyroc.rr.com

    It would be pretty hard to believe the Seattle-based Amazon (or again, any company of that size) would be sending email from a residential cable modem (RoadRunner), especially one in the state of New York.

    Date: Fri, 14 Dec 2007 14:42:09 +0200

    A timezone of GMT+2 is definitely another cause for suspicion since Seattle is currently GMT-8 and New York is currently GMT-5 (we’re not in Daylight Saving Time any more).  It lines up far better with the UK email address (which points to the stny.res.rr.com probably being an open mail proxy, perhaps).

    Anyway, hopefully that’s enough identification points.  Now to let gmail know it’s a phishing attack:

    image

    then confirming:

    image

    Rails 2.0 onto Ubuntu 6.06 LTS (Dapper Drake)

    My server machines run Drake server edition because of the 5 years of support (not a fan of upgrading all the servers every 6 months – the machines used to run Debian stable), which as you can tell comes with (ancient) rails 1.1.2 and nothing of rubygems (the vim version is even 6.4, although you can get vim 7.0 via the dapper backports).  I wanted to start playing around with rails, so I installed it and made a simple enough app. 

    However, after reading about some of the new things in 2.0, I decided that I didn’t want to learn on 1.1.2 and then have to learn 2.0 differences, and might as well just start with 2.0.

    Steps to get Rails 2.0 onto a Dapper Drake machine

    1. sudo apt-get remove rails

      • I don’t want apt/dpkg thinking I have rails installed and causing problems during any updates/upgrades in the future.
      • Obviously not an issue if you don’t have rails installed already πŸ™‚
    2. went to rubygems.org, clicked downloads which took me here, then downloaded rubygems-0.9.5.tgz
    3. Extracted (tar xvzf) the tgz into /tmp
    4. sudo ruby setup.rb
      • This actually failed to fully complete since the ri (Ruby Info) docs had a problem.
        • Installing rubygems-0.9.5 ri into /usr/lib/ruby/gems/1.8/doc/rubygems-0.9.5/ri…
          File ‘.’ not readable
      • Failed the same way on the second attempt
      • However, the actual binaries installed fine, so I ignored that failure.  If I actually have some need for reading docs about gem, I’ll jfgi
    5. sudo gem install rails
      • A lot of existing docs will say you need to use -y or –install-dependencies, but that’s now (at least as of 0.9.5 πŸ™‚ the default so you don’t have to specify it.
        • INFO:  `gem install -y` is now default and will be removed
          INFO:  use –ignore-dependencies to install only the gems you list
      • This failed the first time with a 404
      • After a google search (and apparently the particular .gem file it will fail on varies a bit), a couple of places said to just try it again and sure enough, it worked fine the second time.  I’m guessing they have a problem with their web farm or mirrors or something.  Whatever.
        • Successfully installed rails-2.0.1

    That’s it – rails 2.0 is installed, so it was time to kick the tires and try a rails 2.0 app.