Skip to content

Instantly share code, notes, and snippets.

@samrocketman
Last active May 29, 2017 04:32
Show Gist options
  • Save samrocketman/7473924 to your computer and use it in GitHub Desktop.
Save samrocketman/7473924 to your computer and use it in GitHub Desktop.
A sane admin workflow for managing your GitLab instance.

Sane GitLab management for an Admin

I've seen it asked a couple of times in #gitlab on freenode about upgrading GitLab and what is a good method or recommended method. While GitLab HQ does not recommend a specific workflow for their upgrades I am here to introduce you to my work flow. Feel free to use it or adapt it to your own style. Please note I wrote the majority of this around GitLab 6.0 but GitLab 6.2 is currently released. This will likely apply to any future GitLab release if they stick to the same model of releasing via SCM.

If you'd like to follow other stuff I write about randomly I have a LinuxQuestions.org blog under the user sag47 or you can look at my recent posts on LinuxQuestions.org by doing an advanced search and search by user name. I try to make them all informative.

A GitLab major version is released on the 22nd of each month. Each release has it's own upgrade notes normally which should be reviewed. I recommend offsetting your upgrade by half a month so that stable release upgrade bugs can be ironed out by the community. Regular downtime should be scheduled monthly for this upgrade maintenance to avoid having to upgrade several versions consecutively. GitLab normally publishes each release with a issue milestone.

Iron Clad Rules

I have a few iron clad rules for distributed workflow which I tend to follow. Some of it comes from the gitflow branching model and some of it has come from my own personal experiences. I have tailored these rules to apply to GitLab management. Realistically following these rules would work with any upstream vendor providing software via distributed SCM.

  1. Never develop in a branch in a forked repository that exists in the upstream parent repository. Without following this rule it will be very hard to update the parent repository branches. This includes integrating parent branch changes into your own development.
  2. This rule is more naming convention than anything following rule 1. Whenever you're using a stable version of GitLab be sure to fork off of the stable branch into X-X-stable-yourorganization. This will ensure that your production stable branch stays the same and allows you to test integrating changes in the GitLab stable branches. If you have multiple instances then perhaps name the organization after the domain name of the server.
  3. When upgrading fork off of your organization stable branch into an update "Integration" branch. Integrate the changes from the branch you wish to upgrade to. Upon successful integration you can merge the integrated branch back into your organization stable branch.
  4. For major updates the integration branch being forked will be named X-X-stable-yourorganization from your current stable production branch. However, this new branch will be a new version and it is good to keep around your old stable production branch as well. When updating major versions it's good to utilize a recursive merge to avoid conflicts and migrate your customizations to the new version. For minor updates a regular merge is usually good enough without merge conflicts.
  5. Follow the recommended upgrade procedures provided by GitLab. These are located in the docs/upgrade folder of the repository.

Example workflow

I'll give you an example for how I manage my stable branches in gitlab. All commands I'm running under the system user git unless otherwise specified. Log into git user using sudo -i -u git.

When I cloned gitlab and set it up. First I cloned the repository, checked out the 6-0-stable branch and then branched off of that with my own branch.

git clone https://github.com/gitlabhq/gitlabhq.git gitlab

Now the cloned repo is in a gitlab directory with the path of /home/git/gitlab.

cd gitlab
git ls-remote | grep heads

ls-remote is used to list the remote branches of the origin remote. Alternatively you can specify the remote...

git ls-remote origin | grep heads

Now let's get to the point. Comments start with #.

git checkout 6-0-stable
#now working in the 6-0-stable branch.
git checkout -b 6-0-stable-drexel
#now working in the 6-0-stable-drexel-branch forked from the 6-0-stable branch
git branch -v

You can use git branch -v to show branch names as well as sha1 commit id's for what commit the brances are at. If you notice 6-0-stable and 6-0-stable-drexel branches have the same commit ID because they're related. Also note that when you git branch -v the branch with a * next to it is your current working branch.

Now I set up my gitlab from the 6-0-stable-drexel branch. From now on upgrading and integrating will be much easier. You can test upgrades before integrating them into your production stable 6-0-stable-drexel branch.

Example of a minor GitLab upgrade

The scenario will be upgrading from 6.0 to the latest 6.0 version (i.e. to 6.0.1 or to 6.0.2). First create a backup of your gitlab with the backup rake command (in my case rather than that I take a virtual machine snapshot).

Note: If you're taking a VM snapshot then it is best to shut down GitLab before the snapshot so that users don't try to commit work either during or after the snapshot. Since I contributed my Apache httpd config (rather than nginx) my users see a friendly "Deploy in progress" message.

In any case, before you start your upgrade or working with the new branches be sure to shut down your GitLab service /etc/init.d/gitlab stop. Comments start with #.

#Currently working in the 6-0-stable-drexel branch
git checkout 6-0-stable
git pull origin 6-0-stable
#Currently working in the 6-0-stable branch

Your 6-0-stable branch is now up to the latest version. Test starting the server is optional but I'll include it. Go ahead and start your gitlab server. Test and see if it works (i.e. log into it). If it works then stop your server and integrate the upgraded changes by merging the 6-0-stable branch into the 6-0-stable-drexel branch.

#Current working in the 6-0-stable branch
git checkout 6-0-stable-drexel
#Currently working in the 6-0-stable-drexel branch
git merge 6-0-stable

That's basically my workflow for upgrading minor versions of GitLab.

Example of a major GitLab upgrade

Major upgrades are a little more tricky. Especially if you customized some of the GitLab source code for your own purposes and you want to preserve those changes in the new major version of GitLab (at least preserve customizations as much as possible). Major versions of GitLab sometimes include drastic changes such as prerequisites being modified (i.e. a new version of Ruby or puma instead of Unicorn or visa versa). Major upgrades tend to also have database upgrades which tend to make reverting back to your previous configuration very hard. This is where backing up your gitlab and following the instructions in docs/upgrade extremely important.

This is where VM snapshots come in most handy because you don't have to worry about resetting up all of your prerequisites if you snapshot it. If you have a physical host and you used LVM for your system partitions then LVM supports snapshotting the filesystem. You can snapshot it and revert the system back using the snapshot if need be. In any case, for this example I'm only going to assume the following for brevity...

  • No prerequisites change
  • There may or may not be database schema upgrades (I won't cover rolling back the database)
  • You have integrated your own customizations into the GitLab source which would be difficult to fully rewrite in the new version.
  • We're going to pretend to upgrade from 6.0 to 6.1.

Let's get on with the workflow. First thing to do is check out an integration branch.

#Currently working in 6-0-stable-drexel branch
git checkout -b 6-1-stable-drexel-integrate
#Currently working in 6-1-stable-drexel-integrate branch

Now if you try to simply merge the 6-1-stable branch into your integration branch then you're going to get a lot of merge conflicts even with something as simple as the VERSION file having two different version numbers in it (I kid you not). Luckily, git merge has this really cool feature called merge strategies. We can use merge strategies to tell git to automatically determine what to do in the case of merge conflicts. For my merge strategy all I need is the recursive theirs strategy. If you need it there's other more complicated strategies but I won't cover them here. So let's get on with it.

#Currently working in the 6-1-stable-drexel-integrate
#Using options from git help merge
git merge -s recursive -X theirs 6-1-stable

Now walk through all of your customizations and verify that they successfully migrated. If they weren't (which tends to happen when files are renamed or the code is moved into a different file) then you'll have to manually rewrite your changes into the new location of the code (or decide to discard it if GitLab HQ fixed it for you). Assuming everything went fine you then need to follow the doc/update/6.0-6.1.md file. Be sure to not skip any steps and back up where appropriate.

Assuming you've finished upgrading and you've migrated all of your changes. Also assuming you successfully started the GitLab service and was able to use the new version it's time to create (or rename) your new stable branch!

#Currently working in the 6-1-stable-drexel-integrate
git branch -m 6-1-stable-drexel

And that's it! It's my general workflow for handling major upgrades in GitLab.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment