Subscribe

Recent Articles

Updating Firmware on Sharp BD-HP20U Blu-ray Player

Updating the firmware on a Sharp BD-HP20U Blu-ray player using a USB stick and a Mac was not entirely straightforward for me. The process is a bit brittle, so I’m documenting it in the hopes that I (and others) won’t waste so much time dealing with it next time around.

Sharp distributes the firmware update as a ZIP archive. After you download and unpack it you will have a file with a .RVP extension, e.g., HP20U118.RVP. This file needs to be placed on the USB stick which will then be attached to the Blu-ray player, but the player will be finicky about the condition of the USB device.

The filesystem on the USB stick must be FAT16 — the player will not read FAT32. DiskUtility.app only seems able to do FAT32, so I had to drop into the shell and use /sbin/newfs_msdos to format the device. Plug the stick into your Mac and launch Terminal.app. From the terminal make sure the USB stick is unmounted (replace /dev/diskX with the actual device file of the USB stick):

$ diskutil umountdisk /dev/diskX

Next, format the USB stick with a FAT16 filesystem (again, replace /dev/diskX as appropriate):

$ newfs_msdos -F 16 -v FIRMWARE /dev/diskX

The -F 16 option specifies the FAT16 filesystem, and -v FIRMWARE assigns the label “FIRMWARE” to the new filesystem. You can use any 1-11 character string that adheres to DOS file-naming rules instead of “FIRMWARE”. Whatever you use will end up being all uppercase regardless of how you enter it. See the newfs_msdos man page for more information.

Now remount the USB stick:

$ diskutil mount /dev/diskX

This will mount the USB stick on /Volumes/FIRMWARE (the mount point is derived from the volume label).

Now copy the .RVP file onto the USB stick (replace /path/to/HP20U118.RVP with the actual path to whatever firmware version you downloaded):

$ cp /path/to/HP20U118.RVP /Volumes/FIRMWARE

Quickly ensure that there are no other files on the USB stick other than the .RVP file you just copied over:

$ ls -a /Volumes/FIRMWARE

Besides the firmware update, there may be several hidden files. They must be removed before the device can used by the Blu-ray player. If there are any, any other files on the disk besides the firmware update itself, the Blu-ray player will refuse to run the update complaining there are other files on the disk.

$ rm -rvf /Volumes/FIRMWARE/.[a-zA-Z0-9_]*

This command will verbosely remove any hidden files. If for any reason there are any regular files (files whose names do not begin with a dot) besides the firmware update, they should be remove as well.

Finally, unmount the USB device:

$ diskutil umountDisk /dev/diskX

When this completes the USB device can be safely unplugged from your Mac. Plug it into your Blu-ray player and follow the operating manual instructions for applying firmware updates. At the time of this writing the operating manual for the HP-BD20U is available here.

Pondering Pickled Patterns

For me Pickle is what made Cucumber make sense to me for integration testing. I had a hard time coping with the idea of spending so much time going between nearly English features and huge swaths of regular expressions. Pickle cuts down on a lot of the regular expression drudgery by defining some generic steps for working with models. If you haven’t tried Pickle out yet, I highly recommend it. Railscast 186 gives a great overview.

In addition to the generic step definitions Pickle provides, it also gives you access to the powerful regular expressions that drive those steps. I just spent some time hung up on one of those regexps, capture_model.

In the feature I was creating a labeled account and then visiting the users page for that account:

Given an account: "spectre" exists
When I go to the users page for the account: "spectre"

Then I was using capture_model in a pattern in features/support/paths.rb like so:

case page_name
# ...
when /the users page for #{capture_model}/
  account = model($1)
  users_path(:subdomain => account.subdomain)
# ...
end

Unfortunately, every time I ran the feature, #model would return nil. After banging my head into this for a while I finally determined that #capture_model was capturing an empty pattern, so I was passing "" to #model.

I printed out the the regexp returned by #capture_model to see what was going on (brace yourself):

/((?:(?:)|(?:(?:a|an|another|the|that) )?(?:(?:(?:(?:first|last|(?:\\d+(?:st|nd|rd|th))) )?(?:account|user))|(?:(?:account|user)(?::? \"(?:[^\\\"]|\\.)*\")))))/

The regular expression is built up programmatically at runtime based on the models which currently exist in your application. (As you can see above, in the application I was working on I only had Account and User models defined). The regexp is long and looks a little like Lisp code that’s been tweaking, but if you look closely you’ll probably come to realize (faster than I did) that it will happily match an empty string. In fact, in the pattern I was using in paths.rb #capture_model was matching an empty string and the rest of the line was being thrown away. Unfortunately that part — the account: "spectre" — was the most important part…

Realizing where I was going wrong I anchored my pattern to the end of the line:

when /the users page for #{capture_model}$/

Woo! Now the line only matches when everything between "the users page for " and the end of the line can be matched by #capture_model. With this addition, the regexp captured the model label account: "spectre" and #model finally returned the record. Allons-y!

The moral of the story: anchor your patterns whenever possible. It’s generally good practice if only to make sure you acting on the correct data.

How Do You Run Puppet with Ruby Enterprise Edition?

Sadly, the short answer is, “So far, I don’t.”

As I’ve posted before, I install Ruby Enterprise Edition and Passenger on my application servers. Installation is easy and scriptable, which makes it a task I’d prefer to automate.

I’ve also recently started evaluating both Chef and Puppet for use in automating server configuration. Both Chef and Puppet and written in Ruby (one of the reasons I picked those two for evaluation). This post isn’t about deciding between the two. They both have satisfied users and rightly so. They both have pros and cons. For me, choosing Puppet came down to the fact that I was able to get up to speed with it more easily than I was with Chef. (In my opinion, Chef has a lot of potential, but at this stage development is so rapid, I felt it would be easy for my crack sysadmin team of one to get left behind).

So eventually I arrived at the thought, if I was going to be using Puppet to deploy REE to all my servers, it may as well be running on the Puppet master as well. In fact, why bother with Ubuntu’s Ruby 1.8.6 packages at all?

So I started with two simple virtual machines running 32-bit Ubuntu 8.04 with up-to-date patches — one to be the Puppet master and one to be the client. I installed REE 1.8.7-2010.01 as well as the puppet 0.25.4 and facter 1.5.7 gems. I created some Puppet recipes and got ready to start my first Puppet run. I launched puppetmasterd on the server, and all appeared to be well. I then launched puppetd on the client. This is where it stopped being fun.

As soon as the client connected, puppetmasterd crashed somewhere in /opt/ruby-enterprise/lib/ruby/1.8/i686-linux/openssl.so with undefined symbol: sk_x509_num. Curiosly, only puppetmasterd crashed. The instance of puppetd on the client only complained that the server sent a bum response. I tried installing REE through dpkg instead of building from source. Nothing worked, and unfortunately, I couldn’t find any mention of this problem on the web.

As a control, I proceeded to install the OS Ruby packages (ruby1.8, libruby1.8, ruby1.8-dev and libopenssl-ruby1.8 among others). I then installed Rubygems from source, the puppet and facter gems and fired up puppetmasterd (from the newly-installed puppet gem). Finally I launched puppetd on the client once more. Success!

At this point the client was still running Puppet with REE. Only the Puppet master had the OS Ruby packages installed. So where did I go wrong? My guess is I should be able to get the Puppet master using REE, but I’ll need to rebuild it with different build flags to make sure openssl.so has everything it needs. Of course if you already know what I did wrong, please feel free to leave a comment…

Next time: I’ll be writing about the hoops I had to jump through to get a secondary gem package provider working in Puppet alongside the existing provider. (Hint: the GEM_HOME environment variable is set when Puppet installs gems).