Sunday, July 21, 2019

Beware the Ominous Cloud




Friday, February 17, 2017

Bazel + Go + Google App Engine

In my previous post, I shared some of my Bazel rules for external dependencies with bazel for go. While I got my code to compile, Deployment to the Google App Engine Flex Environment failed due to missing dependencies.

I primarily want to use Bazel because I want to have deterministic dependencies. Vendoring in Go by default pull from head, which isn't the behavior I want - especially when working with a remote team. I initially used govendor to pull deps at a specific commit into a vendor directory in my source tree - that commit was defined in the Bazel file. This turned out to be clunky - I was pulling deps twice.

Since the App Engine Flex Environment allows you to deploy any Docker container in Google Container Registry, I decided instead to use Bazel's docker_build rule to just build my container.

This is mostly straight forward. The only catch is that I wanted to have the base layer of y container be the GAE Go base layer. There isn't currently any way to define a remote base layer in Bazel's rules. The solution here is to build a tarball using the base layer, and then use a new_http_archive rule to pull down the tarball. Here are the steps to do that:

$ gcloud docker pull gcr.io/google-appengine/golang:1.6
$ docker save gcr.io/google-appengine/golang -o aegolang1.6
$ gzip aegolang1.6.tar

I then uploaded the tarball to a Google Cloud Storage bucket. And added the following modifications to my Bazel files.

in WORKSPACE:

new_http_archive(
    name = "appengine_go",
    url = "https://storage.googleapis.com/path_to_tarball/base_image.tar.gz",
    type = "tar.gz",
    build_file = "appenginego.BUILD",
)

Notice I've defined a build_file above. So now we have to fill that in as well - so I created a new file called appenginego.BUILD with the following contents:

load("@bazel_tools//tools/build_defs/docker:docker.bzl", "docker_build")

# Extract .xz files
genrule(
    name = "aego_tar",
    srcs = ["aegolang1.6.tar.gz"],
    outs = ["aego_tar.tar"],
    cmd = "cat $< | gunzip >$@",
)

docker_build(
    name = "aego",
    tars = [":aego_tar"],
    visibility = ["//visibility:public"],
)

And then I use that in my application build file:

load("@bazel_tools//tools/build_defs/docker:docker.bzl", "docker_build")

docker_build(
    name = "aego",
    base = "@appengine_go//:aego",
)

docker_build(
    name = "image",
    files = [":api"],
    entrypoint = ["/api"],
    base = ":aego",
    ports = ["8080"],
    repository = "gcr.io/your_repo"
)

The final steps for deployment here are to upload the new container to GCR and then deploy. 

First you'll want to load your image into docker. You can do this by running the following command:

$ bazel run src/path/to/your/build/rule:image

Now issuing a "docker images" call should list your newly built image as gcr.io/your_repo/path_to_your_build. 

Next, do the actual push to gcr:

$ gcloud docker push gcr.io/your_repo/path_to_your_build

Finally to deploy your awesome new container you'll run:

$ gcloud app deploy --image-url=gcr.io/your_repo/path_to_your_build:image

And that's it.  This allows you to completely use Bazel for building and handling external deps without worrying about manual vendoring work.  ᕕ( ᐛ )ᕗ







Saturday, February 4, 2017

Bazel with Go

I've spent a bit of time this afternoon trying to get bazel working with Go.

The bazel documentation isn't entirely clear at this point, so I'm doing a short writeup of my experience here.

I essentially want to bazel-ise the Google Cloud Enpoints with Go Tutorial. I'm working in a private repo, so I won't be sharing links to my repo.

The first issue I came across was how to handle external dependencies. In the sample app.go has a dependency on "github.com/gorilla/mux".

Its not too difficult to handle external dependencies. In your WORKSPACE file at the root of your repo, you'll want to include:

load("@io_bazel_rules_go//go:def.bzl", "new_go_repository")
new_go_repository(
  name = "com_github_gorilla_mux",
  importpath = "github.com/gorilla/mux",
  commit = "392c28fe23e1c45ddba891b0320b3b5df220beea",
)


I chose the commit hash of the most recent tagged version. You can specify tag here instead of commit if you prefer.

Next up, in your BUILD file that sits next to your code, you'll need to actually add a dependency to mux. Below is the entirety of my BUILD file, as it currently stands.

load("@io_bazel_rules_go//go:def.bzl", "go_binary", "new_go_repository")

go_binary(
    name = "api",
    srcs = ["app.go"],
    deps = ["@com_github_gorilla_mux//:go_default_library"]
)

It compiles! Hooray! That's it for now, I'll add more posts as I progress with this.

Monday, April 13, 2015

2015 Sleepy Hollow Half

I'm a little late on this blog post!  Three weeks ago, Alek and I ran the Sleepy Hollow half marathon.  I've done this race before and knew to expect a very hilly course.  Given that the race date was March 21, we weren't really expecting the spring snow when we woke in the morning.

Winter wonderland in Brooklyn (on our way there)

Despite the winter wonderland outside, by morning the temperature was fairly warm and it turned out to be good race conditions - we really lucked out this winter!

Overall, this was a good race.  The snow really made the course quite pretty and the course was slightly different from the last time I ran.  This year there was no out and back along the highway.  We simply ran for a stretch on the highway, having done the out on local roads.  This change was definitely for the better.  

Winter wonderland on course


The only thing I would have changed about the race were the water stops.  Our first water stop was at about 4 miles, and the next wasn't until mile 7.  After that they were frequent.  I definitely didn't drink enough prior to the race and was feeling the lack of water as I ran.  I started to get a headache right before the first stop.  From there I took three cups of water to offset some of the dehydration.

About 1 mile down!


I was happy with our time, while we didn't do better than the Love Rox Half in February, this was a much harder course!   We finished in 2:34:52.  

This year's race shirt was a technical shirt (I'm wearing it in the photo above).  The medal was much nicer than the 2012 medal as well!  




Wednesday, February 25, 2015

Love Rox Half Marathon

This past weekend, Alek and I trekked down to Richmond, VA for the Love Rox Half Marathon.  When we selected a race in Richmond, we expected that by going a few hundred miles south we could escape the cold and snow that may be plaguing New York at the end of February.  Also, the race was followed by a wine expo!

We left for Richmond from my cousin's place in Northern, VA around noon on Saturday.  Packet pickup for the race ended at 3pm.  Under normal conditions, it would have been a 2 hour drive to Richmond.  However, conditions were far from normal.  There was a lot of snow coming down in a state where plows don't keep the roads as clear as we're used to.


We pressed on and made it to the packet pickup at 3:30 PM.  The folks from Richmond Multisports were packing up the race day stuff and getting ready to head out.  They were kind enough to grab our bibs, but they asked us to get our shirts and wine expo tickets either before or after the race.  

The snowstorm spared Richmond, so once we got there driving was fine.  As we arrived at the hotel, we saw people slipping and falling.  It was incredibly icy in a city that doesn't understand that spreading salt will resolve ice issues.  

After settling into the hotel, we made the treacherous 3 block walk to the Penny Lane Pub for dinner.   The pub had tasty food - including a "Grown-Up Grilled Cheese".  Alek ordered it, I had a bite.  Best grilled cheese ever!

On race morning, we were just 2 blocks from the start line, which was also right outside of the convention center where the wine expo was held.  We walked up around 8 to get the remainder of our race stuff and then walked back to the hotel to finish getting ready.  

Love Rox long sleeve technical shirt


It was considerably warmer  on Sunday, which made for mostly great running conditions.  The race was supposed to start at 9:30, but I think it was closer to 10 by the time we started running.  It was a two lap course, around richmond that included crossing a small canal through a park and then crossing the James River over some traffic bridges.  There were a few hills, but nothing horrible.  There was still some ice in the park and around bridges, so we all had to be careful when running.  However, the worst part of the race were partial road closures on busy streets where cars were idling and runners were breathing exhaust fumes.  

The course

The park with some icy patches



Race Start


Frozen Canal


The Richmond Police were out in full force directing traffic.  The officers were saw were all happiness and smiles.  It was great to have their support along with that of the Richmond Multisport volunteers while we were out there.

Alek and I finished in 2:33:19, shaving 17 minutes off of our Manhattan Half Marathon time.  That's a huge improvement for one month!  The course was less hilly than Central Park, but I think we made bigger gains in speed from actually training.  I'll write a bit more about my personal training experiences later this week.  

Finisher medal and bib


After my 21st half marathon, it seemed appropriate that we go taste some wines!  


Wine Expo!

Monday, February 23, 2015

Winter Vacation 2015: I'm on a boat MotherF#%$

If you’ve ever been on a cruise, then you’ll already know that they mean tons of eating, frozen drinks, and for most people, weight gain.  When we set off on the JOCO cruise, I didn’t want to set myself back by over eating, drinking too much, and not working out.  My plan was to drink only red wine, as frozen tropical drinks pack tons of calories.  And red wine has definite health benefits (although I'll admit that I may occasionally over state them).  I also planned to try to have salads as much as possible, and to remain active.

I was mostly successful, although I did indulge in one frozen mudslide.  

My trainer, Julia, gave me a routine of squats, planks, and pushups to do daily.  This routine took me less than 15 minutes, and was a good compliment to whatever the main activity of the day was. 

When we were at sea, the main activity was typically running on the ship’s track.  On the track it took 4.5 laps to run one mile.  The longest track run I did was 6 miles or 27 laps around the track.  While the ship was moving the wind was blowing at about 45mph.  The wind tripped me (blowing my feet around while running), blew my shirt up, and when running directly into it I felt like I was running in place.  A group of sunbathing women next to the track cheered me on as I passed them during every lap of the 6 mile run.  I was pretty happy for the entertainment.

Independence of the seas, you can see her track toward the top, right edge of the ship.


Despite the wind, I was pretty happy to be running outside, especially since winter in New York has be pretty unpleasant.

The ship’s gym was quite large with a lot of equipment, so on days when I just wanted to take a short run without the wind I would use the treadmill.

Both the gym and the track afforded some beautiful views of the open ocean, which was pretty neat and different from the scenery at home!

The view as we left Haiti.  Kayaking that day was easy, so Alek and I also did a 5k on the ship.



Port days were a different story, we did some kayaking in St. Kitts and Labadee, Haiti.  In San Juan we walked for much of the day roaming around San Cristobal and playing with all of the cats that love to hang out in Old San Juan.  At St. Maarten, we swam with a dolphin.  These were all really fun activities.  Since a picture is worth 1000 words, I’ll leave you to enjoy these photos rather than providing further descriptions.  We haven't yet taken the photos of kayaking off of the GoPro, so I'll share them some other time.

A lighthouse at El Morro.

The lawn at El Morro.

Caaaats!


How did it all work out?  I came back one pound heavier than I left.  It was a setback, but not nearly as bad as it would have been if I had indulged in all of the frozen drinks that the ship had to offer.

Wednesday, February 18, 2015

Winter Vacation 2015: Running in Ft Lauderdale

From January 31 through February 8,  Alek and I, along with Tammy, Chris, Nate, and Matt went on the JOCO Cruise Crazy, an 8 night Caribbean cruise with some amazing entertainers including Jonathan Coulton, Paul & Storm, Pat Rothfuss, John Scalzi, Matthew Inman, The Both, and many others.  If you're curious about this cruise, I don't think I can summarize better than John Scalzi, so please head over to Whatever and take a look at his post.

I have a few things to say about trying to get workouts in on vacation, so I'll share them over the course of a few posts.

We flew into Ft Lauderdale on January 30 just to avoid any stress with airport to ship transfers.  We stayed at The Hilton Ft Lauderdale Marina.  Alek and I decided to get up and get a run in before meeting the group for brunch, or for me and Alek, elevensies, since we’d already eaten breakfast prior to the run.

Finding a running route in an unfamiliar city can be tricky.  We wanted to run in a pretty area, and avoid being next to traffic as much as possible.  As we were heading out, Nate was on his way back in from his morning run (he seemed to have skipped first breakfast).  Naturally we asked him for a good running route.  After Nate described his route to us and walked away, a helpful hotel employee came by and gave us a Hilton Branded pocket map with a few different running routes.  

We went outside to use the map.  This thing had clearly not been proofread by anyone  before printing.  It contradicted itself everywhere.  We set off on what was maybe the 4 mile blue route, but could easily have been the 6 mile blue route or the 6 mile red route.  After two miles of not arriving at the cross street we were planning to turn left on to, we crossed the street and turned back.  On the other side of the street there was a better activity path and it was closer to the beach.  The views were pretty.  The run itself was fairly easy, with a the only hill being right outside the hotel as we had to cross a bridge to get over some water.

Nice beach front view - check out the kite surfer.


Hotel running maps are awesome things to have, but would be much better without all of the confusion!