Tag Archives: howto

Splitting up Git Commits

Human review of code takes a bunch of time. It takes even longer if the proposed code has a bunch of unrelated things going on in it. A very common piece of review commentary is “this is unrelated, please put it in a different patch”. You may be thinking to yourself “gah, so much work”, but turns out git has built in tools to do this. Let me introduce you to git add -p.

Lets look at this Grenade review – https://review.openstack.org/#/c/109122/1. This was the result of a days worth of hacking to get some things in order. Joe correctly pointed out there was at least 1 unrelated change in that patch (I think he was being nice, there were probably at least 4 things going that should have been separate). Those things are:

  • The quiece time for shutdown, that actually fixes bug 1285323 all on it’s own.
  • The reordering on the directory creates so it works on a system without /opt/stack
  • The conditional upgrade function
  • The removal of the stop short circuits (which probably shouldn’t have been done)

So how do I turn this 1 patch, which is at the bottom of a patch series, into 3 patches, plus drop out the bit that I did wrong?

Step 1: rebase -i master

Start by running git rebase -i master on your tree to put myself into the interactive rebase mode. In this case I want to be editing the first commit to split it out.

screenshot_171

Step 2: reset the changes

git reset ##### will unstage all the changes back to the referenced commit, so I’ll be working from a blank slate to add the changes back in. So in this case I need to figure out the last commit before the one I want to change, and do a git reset to that hash.

screenshot_173

Step 3: commit in whole files

Unrelated change #1 was fully isolated in a whole file (stop-base), so that’s easy enough to do a git add stop-base and then git commit to build a new commit with those changes. When splitting commits always do the easiest stuff first to get it out of the way for tricky things later.

Step 4: git add -p 

In this change grenade.sh needs to be split up all by itself, so I ran git add -p to start the interactive git add process. You will be presented with a series of patch hunks and a prompt about what to do with them. y = yes add it, n = no don’t, and lots of other options to be trickier.

screenshot_176

In my particular case the first hunk is actually 2 different pieces of function, so y/n isn’t going to cut it. In that case I can type ‘e’ (edit), and I’m dumping into my editor staring at the patch, which I can interactively modify to be the patch I want.

screenshot_177

I can then delete the pieces I don’t want in this commit. Those deleted pieces will still exist in the uncommitted work, so I’m not losing any work, I’m just not yet dealing with it.

screenshot_178

Ok, that looks like just the part I want, as I’ll come back to the upgrade_service function in patch #3. So save it, and final all the other hunks in the file that are related to that change to add them to this patch as well.

screenshot_179

Yes, to both of these, as well as one other towards the end, and this commit is ready to be ‘git commit’ed.

Now what’s left is basically just the upgrade_service function changes, which means I can git add grenade.sh as a whole. I actually decided to fix up the stop calls before doing that just by editing grenade.sh before adding the final changes. After it’s done, git rebase –continue rebases the rest of the changes on this, giving me a new shiney 5 patch series that’s a lot more clear than the 3 patch one I had before.

Step 5: Don’t forget the idempotent ID

One last important thing. This was a patch to gerrit before, which means when I started I had an idempotent ID on every change. In splitting 1 change into 3, I added that id back to patch #3 so that reviewers would understand this was an update to something they had reviewed before.

It’s almost magic

As a git user, git add -p is one of those things like git rebase -i that you really need in your toolkit to work with anything more than trivial patches. It takes practice to have the right intuition here, but once you do, you can really slice up patches in a way that are much easier for reviewers to work with, even if that wasn’t how the code was written the first time.

Code that is easier for reviewers to review wins you lots of points, and will help with landing your patches in OpenStack faster. So taking the time upfront to get used to this is well worth your time.

Using a foreign Sim in a Verizon Samsung Galaxy S3

One of the the things I was testing on this vacation was getting a foreign sim card to work on my Verizon Samsung Galaxy S3. LTE phones on Verizon all take sim cards now, and as of the 4.1 update for the S3 it’s supposedly unlocked as a world phone, at least the internet largely said so. As a dry run for the Hong Kong OpenStack summit I wanted to figure out if this was true or not by trying it in Canada.

Adventure #1: finding a Rogers

Rogers is one of the big telcos in Canada, and has a pay as you go plan with data. This seemed to be the best bet to figure this all out. Finding an actual Rogers though, turned out harder than expected. The address we had for Saint John didn’t have anything obvious, and unlike the states, there wasn’t a cell phone store in every little town. That meant that by the time we actually found a Rogers it was about 3 days into Canada, in Truro, in the mall.

The last time I did this was with a pre-smart phone in Germany, where their were telco stores in every transit hub, so I hadn’t actually expected the stores to be that sparse.

Adventure #2: the sim

Apparently the way I read everything online was only about half of what’s actually going on with Rogers. The prepaid plans existed, were a little differently structured than I expected.

The Rogers rep was very skeptical that a Verizon phone was going to take a Rogers sim, but they popped one out anyway, we rebooted the phone, and it didn’t lock out. It just showed a little funny icon in the notification area that there was a non-verizon sim in there.

 

This isn’t actually a problem, and you can long hold on it, realize the Setup Wizard is the app causing it, and kill it. Then you don’t need to look at it until a reboot, or about a week (it came back later for me which is how I got the screen shot).

Some time on the phone from the Rogers office and I had a Halifax number, a 500 MB data allowance, and some credit for overruns on phone and texting. It cost me about $60 CAD. The cell phone was on their network, Rogers sent me a few texts with my number, and off we went to Cape Breton.

Adventure #3: data

On the drive to Cape Breton, I realized there was no data service on the phone. That was kind of the point of all this, to have data. Of course without internet, it was hard to debug. Also, complicating things, was the fact that Cape Breton is a bit sparse on cell coverage. Which meant even if I could figure out a fix, it wasn’t really testable up there. A couple days in I started searching to figure out what the deal was, and eventually I got to the bottom of it.

While the Rogers sim did everything correct to get on the phone network, and the radios all worked for that, to get on the data network you need to define an APN. Pre Android 4.0 there were APIs for this. Post Android 4.0 there are not, however on the S3 you can manually create an APN. There is this good app in the market called Offline SIM APN Database which has all these settings, and lets you copy and paste them easily. A couple of minutes later you’ll have defined an APN. After that, reboot, it doesn’t really like to take APN definitions live.

So when we were leaving Cape Breton headed to Halifax, on the highway, back in civilization I finally had data on the phone. Just let it prefer Global mode and it was working. However, pretty quickly I noticed it was edge only.

Adventure #4: edge

Edge is basically the GSM version of 1xRTT (for people that live in CDMA land), and is slow. More searching basically led me to the fact that this was as good as it was getting on the S3. While the S3 was eventually opened up to be a global phone, it didn’t start that way, and it wasn’t really a design point for the Verizon version which added the 700 Mhz LTE radio. So the silicon doesn’t have 2100 Mhz, which is basically where most GSM telcos implement HSPA, their 3G. So we were on Edge for the whole trip where we had data.

Things that work fine on edge (even though they are slow): Google Maps, Foursquare, Facebook, Gmail

Things that get goofy on edge: Untappd, Accuweather (both seem way to data hunger, and not very happy if things reset connections).

I turned off sync while on the Rogers sim. Given the slowness of data this was very helpful for battery life, and for not having something else in the way when I wanted the data connection.

Conclusion: it works

At the end of the day, this all worked. Not having 3G was annoying, but fine. From what I can tell the S4 has all the radios to do 3G on GSM, as do some of the more recent Motorola phones on Verizon.

Alternatives: Verizon International Plans

When I finally figured out the APN issue, I also found my way to Verizon’s international plans. They aren’t actually all that bad, especially if you are trapped on edge, so data isn’t going to be used all that heavily. And even more so with Canada, which after you add the international plan, all the calls and texts are free.

I think that for future Canada trips (especially if we’re there for something shorter) we’ll just enable that on our phones instead of doing the sim route. However, on this trip the sim route was a learning experience as much as anything else.

Update (Jan 4 2014): Hong Kong

Because this post is getting a bunch of new finds on “the google”, I wanted to add a little more data. I went to Hong Kong a couple months after this. There I was able to get a 7 day unlimitted data sim for ~ $12 US. They set it up in the kiosk and I was online in about 5 minutes.

In Hong Kong I actually had 3G (HSPA+). So realize that 3G bands vary by country, and whether you’ll get 3G on your phone is actually hard to completely figure out in advance.

Also, I’m on Verizon stock firmware, and I’ve had friends have difficulty with this on Cyanogen mod on Verizon phones.

Getting my head around Drupal: mhvlug.org version 4 a detailed guide

Over the past couple of weeks I redid the MHVLUG site as a Drupal site.  Drupal is a content management system, which is a fancy way of saying it’s a website, that lets you modify most of it’s parts via a web interface, and contains semi structured data.  I wrote a bit about it in the past.

The Motivation

I got motivated to redo the MHVLUG website after working on the farmproject website redesign, which also uses Drupal.  The MHVLUG website had had 3 previous iterations: static html stored in CVS, MoinMoin wiki, and Mediawiki.  The reasons for each previous switch are beyond the scope here, but each time I felt we took a step forward.

While the wiki approach worked ok for the LUG, the biggest set of edits on the wiki was around monthly meetings.  Before each meeting I’d need to move the meeting content into the front page.  After each meeting someone would need to copy and paste that into it’s own page (sometimes this got lost).  Meetings would get presentations added after the fact, but because it was a wiki, content and presentation were all wrapped up together.  Having the meeting data stored separate from presentation, and being able to create different slices of it for the site (next meeting on frontpage, full meeting pages for the archives, lists of past meetings, lists of future events, in calendars) was enough to get me over the hump.

Drupal Basics

The basic Drupal environment is a lot more bare bones than you would imagine.  It would make an ok blog out of the box, but that’s about it.  Before you get started with any real Drupal project you’ll need at least the following addon modules:

  • cck – content contruction kit, this lets you define custom types with custom fields
  • views2 – this is a basic query builder that lets you create custom slices of data to display as pages, blocks, or in a number of other ways.
  • devel – this gives you a really handy set of add on functions for debugging your types and views
  • admin menu – this will save you a lot of time

I’m giving you my wisdom in hindsight here.  I didn’t have devel or admin menu during the first bits of launching the new mhvlug.org… and man would they have saved me a bunch of time.

Meetings and Events

Beyond basic pages and stories (aka news), the mhvlug site has 2 main special types of data: Meetings and Events.  You could coax the 2 into 1 type, which simplifies some things, but meetings have enough extra bits of data (uploaded presentations, presenter info) that I chose to not do it that way.  Meetings and events are both a collection of a place, a time, and content.  After installing the date module, I had the functionality that I needed on the time front.  I added some custom fields for presenter and presentation on the meeting front, and with a not too complicated set of views had it so the next meeting showed on the front page automatically.  When Jan 7 rolls around, no one will have to go adjust the front page any more.  At this early stage I already had the win I was looking for.

Locations

While I had the time and content portions worked out pretty quickly for our Meetings, location was a bit more challenging.  We only have about 6 locations that we ever use for MHVLUG events or meetings, so I didn’t want to add addresses manually to each piece of content.  Fortunately with cck Drupal has the concept of a node link, which lets you build a relationship to another piece of content.  So now I had a 3rd custom type, Location.

Given that this is 2009, the minute you have an address, you want to have a google map to go along with it.  I spent a couple of days trying all manner of various google map modules before I threw up my hands on this one.  Every single module I experimented with didn’t do quite what I wanted, and needed an aweful lot of configuration.

Eventually, I went for the simple way out.  I just made a text field that I could embedded a google my map chunk of iframe code.  When the field is printed out, you get the map.  This turns out to be particularly useful as some of our locations don’t really have geocodable addresses.  So this challenges was overcome without any new modules.

Custom Display of Meetings

Although you can get a certain amount of customization out cck for custom node types, I found I couldn’t really get what I wanted when it came to the display for meetings.  Fortunately Drupal provides a mechanism for dealing with this, which is custom templates per node type.  By default the core content of each page is rendered using the node.tpl.php in your theme.  If you create note-meeting.tpl.php, it will use that to render meeting types instead.  This works for any custom node type.

It occurred to me that if someone was looking at a meeting or event in that was coming up, they’d immediately want to know where it was.  I wanted to do more than just print the name of the location, I wanted to pull in and display the map as well.  This was where I learned a few really important tricks.

dprint_r is the first one.  If you have the devel module enabled, you get access to some functions that you can use to help debug what’s going on in drupal.  dprint_r spits out a nicely formated version of the data structure you pass it in html.  You can thus use it in your templates to see whats going on.  As someone that thinks in data, this was critical to getting my head wrapped around what drupal was actually doing.

When you load an event page, drupal loads all the data for the event object you are accessing, and it loads the id, tile, and url for any referenced objects, in my case location.  To get more you use the node_load function, which loads any arbitrary object in drupal by it’s node id.  This let me pull in the whole location object and embed the map on meetings pages.  node_load has performance implications, so don’t use it everywhere all the time, but in this case it turned out to be cheap and powerful.

The php templates are just php code, so you can get even trickier.  Meeting location is only interesting prior to the meeting, so I adjusted the template so it only displayed when the meeting/event date was in the future.  Then the archive isn’t polluted with maps.  Works great once you figure out the chaining of date, time, datime objects you need.  Plus, make sure to get your timezone right! 🙂

The Calendar

I went live with basically the functionality above, but I realized that if I could get drupal to spit back out ical, I could get rid of my parallel calendar site I was maintaining.  There is a lot of documentation on how to do this with the calendar module… it’s all very confusing.  Once you have both date and calendar installed you’ll have the option in the administration panel to use the Date Wizard to create your calendar.  Do it!  It creates 8 linked views that give you a calendar at all levels (year, month, week, day), upcoming lists, an ical feed.  If you don’t like the date field it’s creating, just get rid of it after the fact.  Building those views by hand is just going to be a pain, and it’s much easier to tweak them after the fact.

I finally hit a point here where I needed to dive into code, because the ical specific portions of drupal are lacking.  Here are the bugs I found, fixed, and submitted patches upstream for.

In english, Drupal isn’t doing the required wrapping for multiline fields like it should in the spec.  ical wrapping is odd, so I understand why people haven’t fully implemented it yet.  You wrap at > 60 characters, and not on wordbreaks.  That’s right, cutting up a word in the middle is part of the spec, and things actually work better when you do that.  New lines need to start with “rn “, which is really important.  The other issue is that no one tested the recurrence rules much in drupal.  It turns out that in default drupal you can only have 1 event that follows a recurrence rule, i.e. every 2nd Tuesday of the month.  The processor bails before it gets to the second rule.

I fixed all this locally, built the patches, and sent them upstream.  This is the only time I had to dive into the code and fix things.  While it would have been great to not even have to dive in here, I’ve yet to pick up an ical base that I didn’t need to go tweek yet.  I had the same amount of work on the ruby icalendar stack when I played with it.  iCal is just a weird specification, that doesn’t look like what you’d expect.  This is what you get when Lotus and Microsoft build an interchange protocol in the late 90s.

Why iCal?  We found that 50% of our users are using Google Calendar now.  Export to iCal is required for anything that is time based, as Google Calendar is the defacto client for this (though Lightning in Thunderbird does a quite nice job as well).

Mailing List integration

MHVLUG has a mailman mailing list where most of our communication takes place.  Previously you needed to have an account on the website to edit, and a different account on the mailing list.  Through the user mailman manager you can let people easily subscribe and manage their list subscriptions.  This works really nicely, and has already gotten a few people on our mailing list that didn’t ever join before.

Fighting the Spam Bots

The moment you open up registration to the web, you get spam bots trying to login in, and post Chinese drug company links on your website.  It is the price we pay for such an open medium.  Spam bots nearly killed us under the moin wiki.  Media wiki faired better, but I still needed to go and revert a couple of pages every couple of months.  I found that in the first 2 days of drupal being up we had 3 bots signing up, never a good sign.

So here is the formula I’m using for drupal that seems to be quite effective:

  • Require that users confirm their registration via email activation.  This is the default for drupal, and helps quite a bit.
  • Adding Captcha and Recaptcha modules to prevent bots from bothering you with partial registrations in the first place.
  • And finally, use LoginToboggin to put non confirmed users into a penalty box group, which it will automatically purge after 30 days.

While the first 2 actions will protect your site, you’ll still pile up plenty of partial registrations, which just clutters up user management.  Having the system auto purge nonconfirmed accounts makes it all the more self tending.

Better URLs and URL migrations

Out of the box drupal has this totally ugly node/# model for urls.  While it is valid, it really sucks to look at, and google often penalizes you for that as well.  While there is some support for pretty urls out of the box, you really want to install path_auto right off the bat, which builds the url from the title of the node.

Specific to this migration was that we had over a hundred pages in the old media wiki (mostly meetings).  Which means people are going to have linked to something in the past, and not find it in the new site.  There was no way I was going to url map every old url to the new ones.  There is a interesting partial solution which seems to be work well, the search404 module.  When an unknown url comes in it breaks up the url path into words and runs it through the search engine.  If it’s 1 hit, it just takes you there.  If it’s more or less, it leaves you at the search404 page with the search results provided.  It’s not perfect, but I’m hoping it eases the transition (though I’m still getting hits from search for urls from the moin wiki, so some amount of that isn’t going to go away any time soon.)

Sending out Announcements

This is one place where I didn’t find anything in Drupal out of the box that did what I wanted, which is to take the meeting or event text, wrap it in a template with standard boiler plate, and email it to the mailing list.  I tried a few things, like simplenews, which turned out to be anything but.  I wasn’t at the point where I yet want to build a module from scratch (though I’ll probably get there at some point), so I did the next best thing, and hacked the crap out of it do what I want.  The module I hacked up with the print module.

Print provides printer friendly pages, as well as send by email functionality.  I just exposed the print function to the users, but send by email I kept as admin only, and gutted it so that for meeting node types it built me exactly the kind of boiler plate I wanted.  Using mimemail it sends it in both html and text, and looks pretty good.  It is a hack, but one I’m willing to live with for now.

Making Editing Pleasant

The last thing to mention is the fckeditor integration.  I added this early on just to make editing a lot easier on folks.  Drupal doesn’t use any special markup, it uses html under the covers.  Fckeditor is a quite good wysiwyg editor.  The only gotcha here is to make sure that you exclude certain administrative fields, because fckeditor will fix up your text into proper html (like wrapping it in P tags) on submit.  Some times you really don’t want that.  It’s actually quite amazing how good visual editors in javascript have gotten now a days, and what will come over in a copy and paste.

Pulling it all together

With the modules and configuration I’ve layed out here, I now have a quite good community site that supports events, calendars, users that edit pages, users able to manage their mailing lists subscriptions, and a front page that is always going to show the next meeting.  And beyond that, it’s just pretty.  I’ve also started playing with things like twitter integration, and sending email to the list on new news stories (which I’m manually doing now).

I learned a couple of lessons on Drupal in the process.  First, don’t be afraid of modules.  Drupal modules, especially the good ones, do a small amount of specific function.  To have a robust site that does what you want is going to take adding quite a few.  Building this up from scratch is what Drupal often gets dinged for compared to Joomla, but I actually like it better this way, as it provides more flexibility.

Second, sometimes there is no module to do what you want.  In that case you have 2 options, see if you can do it simpler (like I did on the map field), or see if you can hack up the function you need on a related module (like I did with the email announcement).  Both work, depending on what you are going for.

Lastly, the keystone to any site is really Views, CCK, and how you create your custom node types.  Think about this one the most.  What is a meeting?  What is an event?  You can always modify them later, but consider figuring out what your custom types are to be your first and most important mission when building a site.

Staying connected while you are away, using an IRC Proxy

Internet Relay Chat (IRC) has been around for just about ever.  In the 90s it was used for chat rooms and warez sites mostly.  For the past decade it’s become one of the key pillars of communication for the Open Source Community.  It has the advantage that the client and server are free and open, and there is an inherent redundancy system built in.

One of the challenges of IRC, over say email, is that you need to be online to see the discussion.  On a really global project this is a problem, because of the pesky fact that daytime is determined by facing the Sun, and living on an orb, only 1/2 the earth gets to do that at a time.  Life would be so much simpler if the flat earthers were actually right.  But there is a way to stay connected, even when you are not, which is using an IRC proxy.

Using an IRC Proxy

The get started you will need a Linux machine, that you can run code on, that is always on.  It doesn’t need to be on your network, but you need shell access.  If you are a Linux geek level 4 or higher, this is probably not an issue.  You probably either have a Linode or a home server that’s always on.  If not… well sorry… your journey ends here.  There is not, as of yet, a cloud service to provide this for you.  Please come back once you level up.

The next step is the actual IRC proxy.  IRC is a simple enough protocol, which goes over clear text, that many people have written a man in the middle server for it.  You connect the proxy to the IRC server as you, then you point your IRC client at the proxy.  When you are connected to the proxy, everything works as normal.  Your messages are sent back and forth in real time.  When you disconnect from the proxy, the proxy keeps you logged into irc and logs everything that goes on.  The moment you reconnect to the proxy all those messages are replayed to your client.  You now have a full offline ability.

My favorite IRC Proxy

There are many out there.  A few years back I spent some time trying to get one that I didn’t hate, and I landed on miau.  I’ve even packaged it for ubuntu, so if you are on that platform, it should be easy to install.  Once installed, read the same miaurc on configuration, it’s really well documented, and should be easy enough to get rolling.

Although miau supports a password to connect to it, I don’t really trust running another service connected to the internet that just has a password in clear text.  My solution here is to have miau only listen to localhost (127.0.0.1), and ssh proxy to the machine.  Pick a port (like 4098) on your local machine and have that forwarded whenever you connect to that server.  In linux this would look like the following in you .ssh/config.

Host your.server.name.com
LocalForward 4098 localhost:4098

The have your IRC client (like XChat) connect to localhost:4098.  This will mean that you will only be connect to IRC when you have an ssh link to your proxy server.  It works quite well, and is about as secure as you’ll get.

Why bother?

If you made it this far, you probably already know why.  When development conversations happen at 4am your time on IRC, you are probably never going to participate directly.  But, having access to the conversation when you connect in the morning is a very good thing, and I’ve walked people through this setup enough times in the past, writing it down for posterity seemed like a good thing.