So, Dreamhost’s database connectivity from my VPS is proving pretty flaky. I hear that people run real workloads on their servers, but mine gets auth errors for 30-60 minutes a day. Not every day, but twice in the last three days for me. Previously, Dreamhost support has indicated that it was a transient problem with the server config, and even migrated me to a different MySQL database server. That fixed it for a little while, but the issue is occurring again, and support doesn’t seem interested in actually diagnosing and fixing it.

As an interim solution, I’ve decided to migrate my Rails application to AWS Lightsail. The catch is that Lightsail does not come with a free database like my Dreamhost account does, and I’m trying to keep costs down. Thus, this new copy of the production stack will backend with Sqlite3. I’m still using Passenger, this time with Nginx. During the migration, I ran into a few issues.

Migrating the data

This is how I wanted to roll – run mysqldump, maybe clean up the file a bit, then import it into sqlite3 on the commandline. Unfortunately, there seemed to be a number of commands that were incompatible, and frankly I’m not interested in becoming an expert on sqlite3 just for this.

So, my next attempt was to use Rails’ built-in tasks to dump the database in ruby form, and thus use ActiveRecord to reload the database on the new host using “rails db:setup”. That almost worked, except for two problems.

Time of Day Objects

For my Shift model, the start and end time are abstracted through the excellent ToD gem. The catch? When I run “rails db:dump”, it outputs the results in object notation, which can’t be reserialized with “rails db:seed”. The quickest solution was to write a ruby script to edit the resulting seed.rb file. This script would take in each line on $stdin, edit each #<Tod::TimeOfDay> object into a nice “HH:mm:ss” string, and write the results back to $stdout.

Bypassing User validation

I use the lovely “has_secure_password” method for my password-related fields. It works great… except that the seeds.rb file I generated by dumping the production database doesn’t have the original values for everyone’s password (obviously). And if you call User.create([{email: …, password_digest: …}]) like db:dump generates, you will get validation errors about missing values in password and password_confirmation. As best I can tell, the #create method does not have any way to bypass validation, but #save does. So, an addition to my script is necessary. This time, I need to take every record in the User.create( ) input array, and turn it into a pair of statements: u = User.new() and u.save(validate: false). Thus:

And we’re done! … almost. This still leaves the start and end of the old enormous User.create statement in place, which I felt it was easier to just delete manually. I’ll probably want to script it later, since I’ll need to run this procedure again when I migrate the service officially.

Summary

Unfortunately, the web services provided by this Rails application are consumed by mobile apps which are already published, and the app developer has hard-coded the hostname for the app. I am going to ask him to migrate to loading the hostname and base-path from our config.json file, which lives in S3. It’s already used to tell the app where to look for other things, so this would just be an incremental update to that logic. Once done, it will make it much easier to migrate the APIs to different hosts as we find a long-term home for this service.

In summary, thanks for the chore, Dreamhost. I’ll be cancelling my VPS services just as soon as I can migrate my users.

Late last week, Michelle and I decided to burn some time off this week. We further decided to kick it off with a short, relatively local, vacation. We booked a hotel in Coeur d’Alene, Idaho, on Friday night – there weren’t many left by then!

Saturday

We had a great time. We stopped in Packwood, WA on Saturday morning to browse their biannual community flea market. The town center was pack full of tents, but no one was selling blacksmithing gear. Oh well. The drive to and from Packwood added a bit of time to our drive, but Highway 12 is quite scenic! After lunch, we set out on the 5+ hour leg of the drive out to Idaho.

Part of the reason we chose Coeur d’Alene as our destination was a steakhouse that one of Michelle’s coworkers had recommended. We hit the Wolf Lodge Inn for dinner on Saturday. We got there right around 6pm, which meant there was a bit of a wait, complete with a regular playfully asking the hostess to be bumped up the queue. We spent some of the wait taking a walk down the road to a creek nearby. We took some pictures once I had completed the manadtory rock-throwing ritual.

Wolf Lodge Creek

Once we did get seated, the service was excellent. The appetizer and salad courses were delivered to the table right as we finished the previous dishes, but we had to wait a few minutes for the steaks to cook. We both had the filet mignon, and it was excellent. Certainly among the best steaks I’ve had, including in Texas. It was a bit pricey, but not nearly as expensive as the same size and quality steak would have been back in Seattle. They only serve large steaks, it seems: the filet was one of the smallest, at 10oz!

Sunday

On Sunday we headed to Farragut State Park.

The Brig at Farragut State Park

A monument to the trainees

It’s about a half hour drive from Coeur d’Alene, and the site of one of the largest US Navy training facilities during WWII. Apparently after the war the Navy recouped some costs by selling off the buildings. Literally – you could buy one of the buildings, but you had to haul it away yourself! The only building that’s still present is Farragut Naval Training Station’s brig, which has since been turned into a museum. I’ve found that one of the lovely parts of visiting a small museum right at opening time is a lot of attention from the docents. It might have been exacerbated by the lack of internet access out there, but the gent at the front desk spent quite a bit of time chatting with us about the exhibits.

Michelle in the brig

Chris in the brig

An exhibit of spoils from the Pacific, including a wakizashi and Japanese-issued Pesos.

Apparently the winter of 1942 in Farragut got down to -30, with 10 feet of snow! They didn’t really have any equipment prepared to deal with it, so they kept the paths from the barracks to the mess hall open by forcing the recruits to maintain a continuous march on the paths. One man from each unit would patrol back and forth until his limbs started freezing, then he would tag in someone else. It worked, albeit painfully. The next winter the Navy had issued longer peacoats to help protect the boots from frostbite better!

After we finished touring the Brig, we spent a few hours hiking some of the trails along the lakefront. It’s a beautiful park – I think we’ll need to come back again sometime for a camping trip.

Lake Pend Oreille via hiking trail

Lake Pend Oreille scenic overlook

Eventually, we got hungry. The nearest town is Bayview, where we found a small floating restaurant on the lake. Hot dogs, lemonade and sunshine.

Michelle at lunch

Monday

This was the most tenuous of our plans. I had booked us a horseback ride with a local horse ranch, but we were facing a strong chance of heavy rains cancelling it. Luck was with us, however, and the morning dawned with beautiful clear skies. The ranch was just up the street from the steakhouse we’d eaten at, so finding it wasn’t too hard. Plus, they’d set a few signs out, directing us down the “neighborhood” roads. There are a few ranch houses down that road – I guess a few ranches must intersect right there, because the one we visited was a few hundred acres.

After a bit of visiting and petting their dogs, we got a short training lecture, then mounted up! We were then lead on a trail ride on the forested part of their ranch for over an hour. It was great fun! The horses we rode needed a bit of driving, but were friendly and even-tempered.

Michelle by the barn

After the ride we had to head home. It was a long drive, but I foresee us doing it again!

So, my team has elected to write our test automation in Python. Fine, that’s a good excuse for me to finally bother to learn Python.

Good lord have I been spoiled by Ruby all these years. I never really appreciated it, since it’s been my go-to language for the last 8ish years.

First off, I discovered that my practice scripts were using an outdated version – you have to invoke the latest version by calling “python3” on the commandline, rather than just “python”. What the hell?

Anyway, I want to do this Python thing right, so the first thing I do is go learn how one properly organizes python code. Okay, so my unit test code lives in a sibling directory to my client library I’m writing.

In ruby, I would just tell the test’s ‘require’ command the path to the library to import. In python, I have to manually add the library root to the load path, then invoke ‘import’. What the hell? I guess I know why the ruby devs added ‘require_relative’ – so you wouldn’t have to encode knowledge about the directory structure of the project, or knowledge of where the script is invoked from, into the application. Ruby has had this feature since around 2011, and it’s been standard practice to use it for nearly that long.

What a weekend! To celebrate the summer solstice, we decided it would be appropriate to go do something sunny!

We eventually settled on a daytrip to a u-pick cherry orchard in eastern Washington. Thompson’s Farm in Naches was one of the few we could find, but it was great! Surprisingly crowded, but we picked about 10 pounds, a mix of Rainier, Bing and sour cherries. They don’t let you use ladders due to liability concerns by their insurance provider, so I hoisted Michelle up on my shoulders to get at a lot of the ripe cherries that hadn’t been cleared out already.

I think cherry picking is a lot more fun than blueberry, mostly because the cherry trees provide shade. It’s not easy to successfully hide from the sun behind blueberry bushes, but the cherry orchard was quite pleasant!

After picking cherries, we turned our attention to lunch. We drove back to Yakima to get internet access, and found ourselves in a Safeway parking lot. We started hitting Google and Yelp to find a Mexican place that sounded good, when we looked up and found that we were parked right next to one. Let’s try that!

Ay Caramba Mexican restaurant

Ay Caramba was fantastic! I had shredded beef in some tacos and enchiladas, and it was awesome! Michelle had, among other things, a chile relleno that was actually pretty spicy! She also had an excellent tamale, and a chicken taco. Their salsa was good, and the service was quick. We will most likely return here when we come back for peaches in August.

After lunch, we hit Owen’s Meats in Cle Elum for some beef jerky. We also picked up a leg of lamb that I haven’t decided how I’m going to cook yet.

On Sunday we pitted and canned all of those cherries. In addition to raw packing most of them, I attempted to make Maraschino cherries for the first time. I made two batches – one with sour cherries, the other with Rainier. We’ll see how it goes, but I’m hopeful!

Eight quarts of preserved cherries!

While Michelle was pitting the first batch of cherries, I lit my new forge to make some S-hooks. It took me an hour or so, but turned out pretty well. Not professional-quality, but easy and fun to make. I think perhaps I’ll make a bunch more just for the practice – maybe from square stock so I can add a twist in the middle?

My new forge gets plenty hot!

Forging the hooks

The completed result

The impetus for making these was to give our hanging tomato baskets a bit more room to grow – they were hitting the eaves already!

Today we slept in a bit, since our plan was to hit brunch at Miss Lucy’s, then meander up the road to Salt Pond Beach. Now, I remembered from my last trip here that Salt Pond’s trailhead was rather at the end of civilization for the island, so I was less worried about it being full by midday.

Miss Lucy’s brunch is apparenly famous, and so on the advice of an internet stranger, we showed up about 45 minutes before they opened. That proved to be a sound decision, as we were the first in line, and got the best table out in the open-air seating area.

Our table at Miss Lucy’s

It was a beautiful morning, and I greatly enjoyed sitting in the shade, listening to the waves and wind. Eventually, one of the local cats came over to say hello:

After an excellent brunch, we packed up to head over to Salt Pond. We passed a packed parking lot a few miles down the road, but skipped it, as I was expecting a dirt road, and an empty parking lot.

The paved road did eventually terminate into a Jeep trail. It was only occasionally maintained, it seems – there were plenty of potholes, several of which were large enough to park 4-5 jeeps in. Along those stretches, it was more pothole than road – like a sunken road with speedbumps in between to denote the end of one pothole and the start of the next.

Eventually we did come across a beach with only parking for 4-5 jeeps. We pulled over, and found a decent-looking beach, but not the spectacular one that I remembered Salt Pond being.

What the heck, we suited up and went snorkeling anyway. The snorkeling was pretty good – a fair number of rocky patches with fish – but the bay was not as protected as the others, and eventually Michelle decided she was done fighting the wind.

When we got home, we checked a map. That crowded parking area was Salt Pond beach’s trailhead, and the place we ended up at was Greater Lameshur Bay. We also learned that if we’d ventured a little farther down that jeep trail, we would have hit Little Lameshur Bay, which is apparently a better beach. Oh well, an adventure for another day!

Today we decided to return to the north shore and snorkel the famous Cinnamon Bay. The beach is probably the nicest one on the island – a long, smooth beach formed of soft, fine sand, plus calm, crystal-clear waters in the sheltered bay.

Absolutely gorgeous.

Cinnamon Bay beach

Cinnamon Bay beach

Michelle in Cinnamon Bay

Chris in Cinnamon Bay

The snorkeling here was less exciting – not as much coral and relatively few fish – but the visibility in the water was excellent. Michelle described it as a “Caribbean swimming pool”. At the end of the day, we judged the beach excellent and the swimming mediocre (comparatively to Trunk and Leinster).

So, having scouted out Leinster Bay via the short hiking trail from the Annaberg ruins the day before, we packed our snorkeling kit today.

We got up a bit earlier, and were the first people on the beach, which made Michelle nervous on the assumption that everyone else knew something we didn’t – she checked the USVI NOAA pages religiously every morning to check the riptide forcasts. Once I convinced her to relax, we set up camp and walked the beach.

Right off, we got a nice treat – there was a small nurse shark prowling the beach, maybe a meter from the surfline proper. We walked the whole beach, and saw him a few times – he seemed to be patrolling the whole beach, or at least the sandy part.

That settled, we slathered on our sunscreen and headed into the water. The shark swam nearby a few times, but never closer than a couple of meters from us. I only saw him at the edge of my visibility twice after we started swimming. That disappointed me slightly, but also made me feel better that he preferred to leave us alone, rather than assert ownership of the beach.

What we did see, however, was quite impressive. Quite a few different kinds of fish, including the only puffer fish I saw the whole time. There were a few different schools of smaller fish swimming about, and it seems we found another small barracuda every time we turned around. We were quite relieved that, like the shark, they preferred to swim away from us.

Our biggest treat was out a bit closer to the middle of the bay – Michelle spotted them first, but she got my attention quickly to watch a pair of sea turtles browsing the grass along the floor of the bay. We watched them for quite a while, including drifting pretty close to them (no sudden or fast movements to startle them). They didn’t seem to mind our presence much, and we kept a reasonable distance so as not to give alarm.

After a while, we decided it was about lunchtime, so we headed back to the beach. There was a delay getting back when we came across another turtle closer to the beach, and I got to watch a pelican diving into a school of fish from underwater!

When we got back, I found our bags pulled open, and most of our lunch missing – the local mongeese had smelled our food, and stolen our bag of chips alongside Michelle’s sandwich. That left me pretty cross, as I should have known better than to leave our food in just a backpack on the beach, but I hadn’t felt like lugging the cooler out on the hike. Another lesson learned the hard way.

The local birds that scavenge from tourists are pretty cute, though:

All in all, our best day’s snorkeling, despite the sand otters stealing most of lunch.

Owing to my nice new sunburned shoulder, we decided to do a shirts-on day today.

The most obvious activity to meet that requirement was to check out the ruins of the old Annaberg Sugar Factory. They have a nice park set up here, with some of the old structures slightly restored and helpfully labelled. A short tour, to be sure, but cool! Well, it was pretty hot in the sun, actually, so I mostly scurried from one shady spot to another, venturing out to admire the old windmill tower, or the sugar factory buildings.

The windmill would crush the sugar canes, and the juices flowed through a stone trough over to the boilers.

Apparently the wind isn’t as reliable here as I would expect – the original Dutch owners bothered to install a horse mill to crush the sugar cane on days when the windmill wasn’t generating enough power.

The park service had also labelled a few of the trees out here. The most amusing of them was the Turpentine Tree. It is covered with red, peeling bark, generating for itself the nickname “Tourist Tree” due to the similarity with my skin.

According to a sign we read at Trunk, the island used to be covered with sugar cane plantations – I believe they said something like 80-90 of them at the industry’s peak! Only Annaberg has had it’s facilities made into a park, though we did find another partially restored building at the trailhead near Little Lameshur bay.

After wandering about the ruins for a while, we decided to check out the nearby trail – it promised to be only 0.8 miles each way, so what the heck! I’d completely forgotten that it was the path down to Leinster Bay, which is rated as one of the best snorkeling spots on the island. Well, we hiked it today, decided that the beach looked nice enough, and vowed to come back another day with our snorkeling gear.

After hiking back to the trailhead, we decided we weren’t quite spent yet, and wandered over towards the north shore beaches again.

There is a small beach that overlooks the main beach on Trunk bay called Jumbie which has very limited parking and a short trail down from the road. We pulled out the beach chair and our lunch for a nice picnic:

After lunch we decided to check out Maho bay – Maho is generally rated as an excellent beach with mediocre snorkeling prospects, so we figured it would be a good spot for a day where we hadn’t brought our bathing suits. We managed to find a choice parking spot (which turned out to be pure luck), and ambled up and down one of St. John’s nicer beaches.

Historically, both Michelle and I have a mixed track record of insomnia the night after pulling an all-nighter. Our first night on St. John, we figured that would be exacerbated by the unfamiliar bed and surroundings. That fear proved unfounded – we crashed not too long after dinner and slept pretty well. After a breakfast of scrambled eggs and sausage, we decided that our first day of playtime should be on Trunk Bay beach. Apparently world-famous as an excellent beach, it lived up to both its reputation and my recollections.

Trunk has a cay just off the beach, which produces an extremely sheltered patch of water in its lee. This is apparently good for coral growth, and makes for idyllic snorkeling conditions. The US National Park service has also set up a small underwater snorkeling trail there with a series of markers on the seabed describing the different kinds of coral and fish that are frequently found there.

Besides that, the beach is beautiful! Fine white sand all the way from one end to the other:

We finished the day at home, with homemade burgers on the propane grill.

Once again, I crashed early this night, partially due to the energy-draining effects of my new sunburn.

After leaving home at 7:45pm on Monday, we finally arrived at our rented house on St. John at around 5pm on Tuesday. Twenty-one hours of travel time is a bit much, but we made it. Of course, I still apparently can’t sleep on planes, even in the exit row (because they wouldn’t let me recline the seat), so that made driving the rental car across St. Thomas that much more interesting.

We had prepared printed directions from Google Maps from the airport to the car barge terminal, but I hadn’t spent any time going over the route that had been selected – Google apparently selected the northern highway across the island, which required a series of turns to traverse across Charlotte Amalie. Sadly, they don’t really go in for labeling streets at intersections there, so we were rendered lost very quickly. Or, paraphrasing Daniel Boone, we weren’t lost, but we were a mite bewildered there for about an hour.

After some moderately successful navigation-by-wandering-around combined with the crude map that Budget had given us, we decided to abandon Google Maps’ suggested route, and take the southern highway across St. Thomas. As it turns out, that road goes more-or-less directly from the airport to the ferry and car barge terminals. When I rechecked Google Maps after our arrival at home, it turns out that Google thinks the complicated route is a few minutes shorter than the simple route, which is why it defaulted to it. Our property manager agreed that while the northern route is indeed slightly faster, it’s rarely worth the trouble of navigating Charlotte Amalie, even for a local like him.

Well, it was an adventure at times, but all’s well that ends well. The house we rented is great. Bright, clean space with a comfy couch and bed, and a spacious deck with a killer view:

That’s St. John’s East End, with Tortola further back. The back wall of the house has four large doors, three of which slide open to permit the steady trade winds to blow through. It keeps the house a nice steady temperature, and means that the house never lacks for ventilation. The winds are a bit strong, and leave us feeling weatherbeaten if we try to hang out on the deck for too long.

It turned out to be a good thing indeed that we took the general advice to rent a jeep when visiting St. John – the house we rented is up a steep dirt road with several interesting switchbacks. On Google Maps, you can see it as the one just to the north of MoonSwept Villa, here. Getting up here requires a 4×4 vehicle.

After settling in a bit, we climbed back down the mountain road for dinner at the Shipwreck Landing. Dinner was excellent, if a bit pricey.