Showing posts with label git. Show all posts
Showing posts with label git. Show all posts

Sunday, 22 February 2009

Watching /etc

I need to be able to watch the /etc directory of a host over time so that I know when any changes have been made. The main aims are to ensure that changes are not made by the sysadmins without our knowledge and to ensure that changes we do request are actually implemented. I also need to compare the /etc directories on multiple hosts to ensure that they are as close to identical as possible.

Since I am a non-root user I can't use something like Joey Hess' etc-keeper (announcement), although I can re-use the idea of storing the files from /etc in a Git repository, using metastore called from hook scripts to store the file meta-data which isn't normally stored by Git itself.

The current plan is to do something like (untested):

$ cd /path/to
$ export HOSTNAME=$(uname -n)
$ git clone git://repos/config
$ cd config
$ git branch $HOSTNAME
$ git checkout $HOSTNAME
$ rsync -a /etc .
$ git add etc
$ git commit -m"date '+%F %T'"

Then I should be able to run commands like:

$ git diff thishost thathost

to see the differences between the hostname branches.

I can also look at the HEAD commit on each branch on a daily basis to see what has changed.

We will see if this works when I implement it :-)

git fine-grained access control

If we are going to switch from CVS to Git we are going to need to implement the fine-grained access control features we have now. For example:
  • only certain users are allowed to commit to each branch.
  • only certain paths can be committed to on each branch.
  • only certain users are allowed to create tags in the central repository. (I'd like to get rid of this limitation, but it's there now. Perhaps only limit tag names that match a particular set of regular expressions.)
Since all of the software modules are released at similar times it makes sense it keep them all in one repository, and for internal security reasons the repository is probably only going to be accessible via HTTPS. This means that we won't be able to use Gitosis, which currently only works for SSH access.

Junio Hamano and Carl Baldwin have an update-hook-example that describes how to implement an access control hook script, so we will base things on that. Their example assumes that the user has logged in using ssh so they can use username=$(id -u -n) but since we are coming in via the web we'd have to use the REMOTE_USER environment variable instead.

I think it makes sense to use a configuration file that is similar to the Gitosis config file, which people are familiar with. This is just an ini file that can be parsed using Config::IniFiles or something similar to Gitosis::Config, so this shouldn't be difficult.

Something else worth looking at is gerrit, which describes itself as follows:

Gerrit is a web based code review system, facilitating online code reviews for projects using the Git version control system.

Gerrit makes reviews easier by showing changes in a side-by-side display, and allowing inline comments to be added by any reviewer.

Gerrit simplifies Git based project maintainership by permitting any authorized user to submit changes to the master Git repository, rather than requiring all approved changes to be merged in by hand by the project maintainer. This functionality enables a more centralized usage of Git.

Merge individual git commits to "future" branches

At work we are currently looking at moving from CVS to Git. After reading Pragmatic Version Control with Git I am convinced that skipping Subversion and going directly to Git is the best way forward. This book is highly recommended - I bought the electronic book for myself and a paper copy to pass around to key people in the office.

With CVS we currently have a feature that enables developers to check in changes on an older branch and have then automatically applied to future branches, unless they explicitly say otherwise. For example if a developer commits a change to the 08_04_10 branch it will be automatically applied to the 08_04_11 and 08_04_12 branches, if they exists.

Replicating this feature in Git looks like it will be easy using a script run from post-commit hook. The script could either apply the commits to future branches immediately or just make a note of the commit id and branch so that an external script can apply the commits at a later stage. I expect that we'd go with the latter so that the "merge forward" functionality can't adversely affect the commit, but we may end up with a hybrid approach.

Some quick-and-dirty pseudo-code for the above:

In post-commit hook:
BRANCH_NAME=TPL_8_4_12
COMMIT_ID=$(git-rev-parse HEAD)
DATE=$(date +%s)
echo $COMMIT_ID > /path/to/$BRANCH_NAME/todo/

In merge_forward script:
#!/usr/bin/env perl

my $base_dir = "/var/tmp/$$";
mkdir( "$base_dir" );

my %todo{'TPL_8_4_10'} = ( 'TPL_9_1', 'TPL_9_2' );

foreach my $branch (keys %todo {
opendir(TODO, "git clone '$future_branch'") == 0 ) {
foreach my $commit_id (@commit_ids) {
system("git cherry-pick -x $commit_id");
}
}
}
}

I found the git-rev-parse HEAD command above in a mailing list discussion about whether or not the post-commit hook scripts should be passed the commit id. Also take a look an Benjamin Meyer's blog entry about commit hooks for how to get the list of files that have changed.

Labels