Changing Elastic Beanstalk (Ruby) Passenger ngnix Config

January 19, 2014 16:20 by docbliny 

Is that title geeky enough for you? If so, keep reading…

Problem

I had to get Amazon CloudFront CDN configured this weekend for a Ruby project. This was mostly straightforward, and there are plenty of instructions on the web on how to go about that.

However, static assets are delivered by Phusion Passenger Standalone under the Ruby container for Amazon Elastic Beanstalk. This means you can’t set headers for those files in Ruby. Why is this an issue? Well, if you’ve got custom fonts, you’ll need to set CORS headers for those fonts to work on Internet Explorer and Firefox:

Access-Control-Allow-Origin: *

Solution

OK, this is where it gets to the usual “I just lost a day” situation. All the pieces were available, but getting everything glued together, and going through a rather slow deployment to test each iteration was a time sink. What you need to do is:

  1. Change the nginx configuration to add the CORS header to all font files by patching the Passenger config.erb template file.
  2. Patch Amazon’s broken /etc/init.d/passenger file so you can actually restart the service.

Note: I'm leaving the layout of this page broken in the file examples below to avoid confusion with line wrapping.

Modifying the nginx config template

You’ll need to create a file in the projects .ebextensions folder similar to the following:

00-passenger.config

files:
  "/home/ec2-user/inject_headers.sh" :
    mode: "000777"
    owner: ec2-user
    group: ec2-user
    content: |
      #!/bin/bash
      CONFIG_FILE=$(passenger-config --root)/resources/templates/standalone/config.erb
      MATCH=$(grep '(eot)|(ttf)|(woff)' $CONFIG_FILE)
      if [ -z "$MATCH" ]; then
        cp -f $CONFIG_FILE $CONFIG_FILE.bak
        sed -e'/location @static_asset {/a \\t if ($request_filename ~* ^.*?\.(eot)|(ttf)|(woff)$){ add_header Access-Control-Allow-Origin *; }' $CONFIG_FILE.bak >$CONFIG_FILE
      fi
commands:
  00-inject-font-headers:
    command: sh /home/ec2-user/inject_headers.sh
    cwd: /home/ec2-user

Then patch /etc/init.d/passenger:

01-patch-passenger.config

commands:
  01-patch-passenger-init:
    command: sed -i 's/passenger stop \$OPTS/passenger stop -p \$EB_CONFIG_HTTP_PORT --pid-file \$EB_CONFIG_APP_PIDS\/passenger.pid/' /etc/init.d/passenger

...and finally restart passenger so this goes into effect before CloudFront can hit font files and cache them without the correct headers:

02-restart-passenger.config

commands:
  02-restart-passenger:
    command: /etc/init.d/passenger restart

notes

  • This was done on the 64bit Amazon Linux 2013.09 running Ruby 1.9.3 container.
  • The real runtime nginx configuration file ends up under /tmp/passenger-standalone.[random]/config. Check it to make sure the changes are applied.
  • /log/var/cfn-init.log is your friend when debugging the .ebextensions.
  • I was having issues with the initial deployment for a newly created environment not being applied (I just got the placeholder page from Amazon). This was always resolved by pushing the same application version again to the environment. The error in the Beanstalk event console was: The following instances have not responded in the allowed command timeout time (they might still finish eventually on their own)

Latest Google Chrome kills “Most Recent Tabs” feature

September 27, 2013 12:59 by docbliny 

UPDATE 2/22/2014: Google kills the workaround without fixing the original issue. Total cluster-fail. #chromefail

Well, not completely (unless you’re an unlucky sod like me), but makes it unusable. You now have to reopen each previously closed tab one-by-one. No more clicking on “21 closed tabs” to open up what you were working on previously. Unfortunately, the new menu item is greyed out completely for me and doesn’t show _any_ recently closed tabs.

Luckily, there’s a way to disable this new feature (along with the new big search box and not seeing Chrome Apps in the start window):

  1. Open a new tab, and enter chrome://flags .
  2. Search for Enable Instant Extended API for Mac, Windows, Chrome OS.
  3. Select Disabled from the dropdown.
  4. Restart Chrome.

Wave licensing center suddenly think you’re on a different machine?

September 15, 2013 16:02 by docbliny 

I started up Cubase for the first time in a few weeks, and I immediately got an error from my Waves plug-ins stating that its licenses couldn’t be found. This obviously freaked me out; I started the Wave License Center, and noticed that it couldn’t identify my machine anymore, and all my old licenses were listed under View All Licenses under the real name of the computer.

Long story short, I’d installed Visual Studio 2013 Pro Preview and along with that the Windows Phone dev kit (Don’t get me started how bad an idea it is to have everything on one machine…). Anyway, Waves didn’t recognize the machine because the network traffic was going through the Hyper-V vEthernet (External Switch) adapter with a different MAC address.

The fix:

  1. Start Hyper-V Manager.
  2. Click Virtual Switch Manager under the Actions pane.
  3. Select External Switch under the Virtual Switches pane/group.
  4. Select Internal Network, and then click OK.
  5. Close the Hyper-V Manager control panel.
  6. Open up your Network Connections control panel, and then disable vEthernet (External Switch) and vEthernet (Internal … Windows Phone Emulator…).
  7. Reboot (to be safe).

After a restart (and writing this post), I was good to go (but where’d my musical inspiration run off to in the meantime?)


Surface Pro and Screen Rotation Issue

February 17, 2013 10:10 by docbliny 

I was having the rather irritating issue with my Surface Pro where I’d hop on the train for my morning or afternoon commute, and the screen wouldn’t rotate (change the orientation) when I was trying to read with my Kindle app. What made it frustrating was that it’d start working again when I arrived. I read the troubleshooting document and then contacted Microsoft support and they weren’t able to reproduce the issue. This morning, I finally figured out what was going on.

More...


Recovering Vista ICM devices.tar.gz and style.tar.gz

September 22, 2012 07:32 by docbliny 

Several people reported that they had attempted to use the auto-update feature in the Vista ICM, and that doing that had removed the files required to display devices.

It seems the auto-update procedure is buggy and erases the flash storage before checking if it’s able to successfully load any available updates. Since the device has been discontinued and (I think) In2Networks has gone out of business (or at least has shut down the related servers). This means that the auto-update feature is now an “auto-destruct” feature.

My ICM was still intact (though I did have to factory reset it since it wasn’t responding), I did some hunting and pecking, and in the end I was able to pull out the files from flash file. I’ve attached them below. You can use the Advanced / File System page to upload and save them to flash under http://[ipaddress]/setup. As usual: Use at your own risk.

Thanks to Norman for agreeing to be the guinea pig to test these files out!

Other

Now for some geeky stuff:

1. To download files from the device, you can create files in the /var/fusion/web folder. The other option is to create a symbolic link to an existing file. This is especially useful for larger files. You can then download the file(s) with a browser from http://[ipaddress]/web/[filename].

2. I wasn’t able to download all of the flash files. In any case they are in /dev/flash:

  • all
  • boot
  • bootarg
  • config
  • ethmac
  • image
  • settings
  • storage

The reason I couldn’t get some of the larger files out is that the embedded shell does not support IO redirection, so I couldn’t cat to gzip to minimize the size.

3. I pulled the devices.tar.gz and style.tar.gz out of a flash image located at /dev/flash/storage. Since they were combined in a flash image, I had to remove a few bytes of the header before the first gzip file, and then split it into two (one for styles and one for devices). A test with 7Zip on Windows said the files were valid. I was also able to use gunzip on the ICM to extract the contained tar. However, tar failed as it ran out of space about halfway through (normally they packages are on another disk so the extraction works when it happens on startup.


Hack of the Day: QClock

July 21, 2012 11:22 by docbliny 

I spent a moment this morning slapping together another application for the Nexus Q. This one is really simple, and all it does is to use the LEDs to show the time. There are three “hands” that show the hour in white, minutes in blue, and seconds in red.

The video doesn’t do full justice to the ability to read the time. The camera picked up too much light around each hand due to the diffusion the LEDs have. For example, the second hand looks fully red in real life, and doesn’t have the rainbow band around it as seen on the video.


QRemote REST API Documentation

July 14, 2012 19:20 by docbliny 

The QRemote REST API documentation is now bundled into the application itself, but here’s a copy/paste for reference.

More...


QRemote Source Code Now Available

July 14, 2012 19:10 by docbliny 

ic_launcher-web

I just finished setting up a repo on GitHub for QRemote: https://github.com/docBliny/qremote

It includes the source for both the Android application and the web interface.

I also updated the installable APK with the rough API documentation.


QRemote Nexus Q Application

July 8, 2012 06:11 by docbliny 

UPDATE July 14, 2012: I updated the APK to contain rough API documentation. Just navigate to http://192.168.1.1:8080/api.html adjusting the IP address to match your Q.

OK, it’s late (I mean early), but here’s a very rough alpha version of QRemote which let let you control the Nexus Q via a RESTful-ish API and your web browser. It’s developer-only friendly at the moment, but that shouldn’t a problem since only Google I/O attendees have them. If you’re brave enough to test it and have feedback, hit me up via Twitter, Google+, or email. I’m lazy at approving comments here on the site. Anyway, to the point…

GALLERY

Here it is in all it's glory.

QRemote-Screenshot

Installation

  • Download QRemote.apk here.
  • Upload the file using adb with the following command: adb install QRemote.apk

Running

Unfortunately, you’ll have to manually start the application every time you power on the Nexus Q. I’m working on to get the boot message receiver to work with a signed package (seems to work fine with a debug build).

  • Start the application with the following command: adb shell am start -a android.intent.action.MAIN -n com.blinnikka.android.qremote/.StartServiceActivity
  • Open up a browser and navigate to port 8080. For example, http://192.168.1.1:8080/

Known Issues

  • You need to start it manually every time you power up the Nexus Q.
  • You have to know your Q’s IP address.
  • You need to load up a playlist with the Play application on an Android device.
  • Videos are not supported.

Uninstalling

  • Run the following command: adb uninstall com.blinnikka.android.qremote

Upgrading

You will need to uninstall and re-install the application if you had the initial Alpha version as I changed the keys used to sign the application. Just follow the instructions above to uninstall and install again.


Teaser: Controlling Nexus Q LEDs over API

July 5, 2012 18:58 by docbliny 

The video says it all.