commit 35bdb5882b1690a23e3ef13439e144d17b3a5af4
parent b2e775044d4def727650a3f599955c7459fe7e38
Author: tg(x) <*@tg-x.net>
Date: Sun, 27 Feb 2011 01:12:30 +0100
made repo name independent from user name (thx loupgaroublond), renamed some config variables, gitzone-shell: default repo dir changed to ~/zones/$LOGNAME
Diffstat:
4 files changed, 51 insertions(+), 45 deletions(-)
diff --git a/README.org b/README.org
@@ -28,10 +28,10 @@ key management.
- create a zones repo for each user and set receive.denyCurrentBranch to ignore,
this allows pushing to a checked out repository. The checked out files are
used for incrementing serials and validating the zones with named-checkzone.
- : # cd ~$user
- : # git init zones
- : # ln -s zones $username # needed for named-checkzone
- : # cd zones
+ : # mkdir -p ~$user/zones
+ : # cd ~$user/zones
+ : # git init $user
+ : # cd $user
: # git config receive.denyCurrentBranch ignore
: # cd hooks
: # ln -s /usr/libexec/gitzone/pre-receive
@@ -80,6 +80,8 @@ use the auto increment feature you also need to pull after a push as the receive
hooks on the server make commits to the repository during a push.
#+BEGIN_EXAMPLE
+ % git clone ns.example.net:zones/$user zones
+ % # or if you're using gitzone-shell you can use any path:
% git clone ns.example.net:zones
% cd zones
% # edit files
diff --git a/bin/gitzone b/bin/gitzone
@@ -12,14 +12,17 @@ use warnings;
use strict;
use POSIX qw/strftime/;
use Cwd qw/cwd realpath/;
-use File::Basename qw/fileparse/;
+use File::Basename qw/fileparse basename/;
-our ($zone_dir, $git, $named_checkzone, $rndc, $class, $default_view, $update_record, $user_includes, $max_depth, $zones, $verbosity);
+@ARGV >= 2 or die "Usage: gitzone /path/to/gitzone.conf <command>\n";
+basename(realpath) eq '.git' or die "gitzone has to be run from a .git directory\n";
+chdir '..';
+
+our ($zone_dir, $git, $named_checkzone, $rndc, $class, $default_view, $update_record, $unrestricted_includes, $max_depth, $repos, $verbosity);
our $user = getpwuid $<;
+our $repo = basename realpath;
-@ARGV >= 2 or die "Usage: gitzone /path/to/gitzone.conf <command>\n";
my ($config_file, $cmd) = @ARGV;
-
do $config_file or die "Can't load config: $!\n";
my $lock_file = realpath '.gitzone-lock';
@@ -58,20 +61,20 @@ sub git {
return $_;
}
-# Load BIND config files specified in the $zones config variable.
-# First load the -default key, then the $user key.
-sub load_zones_config {
+# Load BIND config files specified in the $repos config variable.
+# First load the -default key, then the $repo key.
+sub load_repos_config {
my $key = shift || '-default';
# move files not in a dir to a . dir for easier processing
- for my $file (keys %{$zones->{$key}}) {
- next if ref $zones->{$key}->{$file} eq 'HASH';
- $zones->{$key}->{'.'}->{$file} = $zones->{$key}->{$file};
- delete $zones->{$key}->{$file};
+ for my $file (keys %{$repos->{$key}}) {
+ next if ref $repos->{$key}->{$file} eq 'HASH';
+ $repos->{$key}->{'.'}->{$file} = $repos->{$key}->{$file};
+ delete $repos->{$key}->{$file};
}
- for my $dir (keys %{$zones->{$key}}) {
- my $d = $zones->{$key}->{$dir};
+ for my $dir (keys %{$repos->{$key}}) {
+ my $d = $repos->{$key}->{$dir};
for my $file (keys %$d) {
$d->{$file} = $default_view if $d->{$file} eq 1;
$d->{$file} = [$d->{$file}] if ref $d->{$file} ne 'ARRAY';
@@ -80,7 +83,7 @@ sub load_zones_config {
open FILE, '<', $file or die $!;
while (<FILE>) {
if (/^\s*zone\s+"([^"]+)"/) {
- $zones->{$user}->{$dir}->{$1} = $d->{$file};
+ $repos->{$repo}->{$dir}->{$1} = $d->{$file};
}
}
close FILE;
@@ -89,7 +92,7 @@ sub load_zones_config {
}
}
- load_zones_config($user) if $key eq '-default';
+ load_zones_config($repo) if $key eq '-default';
}
sub process_files {
@@ -122,11 +125,11 @@ sub process_file {
$changed = 1;
} elsif (/^(\W*\$INCLUDE\W+)(\S+)(.*)$/) {
my ($a,$inc_file,$z) = ($1,$2,$3);
- if ($user_includes) {
- # check $INCLUDE lines for files outside the user dir
- unless ($inc_file =~ m,^$user/, && $inc_file !~ /\.\./) {
+ unless ($unrestricted_includes) {
+ # check $INCLUDE lines for files outside the repo dir
+ unless ($inc_file =~ m,^$repo/, && $inc_file !~ /\.\./) {
close FILE;
- die "Error in $file:$n: invalid included file name, it should start with: $user/\n";
+ die "Error in $file:$n: invalid included file name, it should start with: $repo/\n";
}
}
} else {
@@ -186,13 +189,9 @@ sub check_zones {
# skip files with errors and those that are not in the config
my ($zone, $dir) = fileparse $file;
$dir = substr $dir, 0, -1;
- next unless $files{$file} > 0 && exists $zones->{$user}->{$dir}->{$zone};
+ next unless $files{$file} > 0 && exists $repos->{$repo}->{$dir}->{$zone};
- if ($user_includes) {
- print `$named_checkzone -w .. '$zone' '$user/$file'`;
- } else {
- print `$named_checkzone '$zone' '$file'`;
- }
+ print `$named_checkzone -w .. '$zone' '$repo/$file'`;
clean_exit 1 if $?; # error, reject push
push @zones, $file;
}
@@ -206,7 +205,7 @@ sub install_zones {
git 'checkout -f master';
git 'reset --hard new';
- chdir "$zone_dir/$user" or die $!;
+ chdir "$zone_dir/$repo" or die $!;
git "clone $cwd ." unless -d '.git';
git 'fetch';
git 'reset --hard remotes/origin/master';
@@ -214,7 +213,7 @@ sub install_zones {
for my $file (@zones) {
my ($zone, $dir) = fileparse $file;
$dir = substr $dir, 0, -1;
- my $view = $zones->{$user}->{$dir}->{$zone};
+ my $view = $repos->{$repo}->{$dir}->{$zone};
print "$_/$zone: ", `$rndc reload '$zone' $class $_` for @$view;
}
@@ -223,7 +222,6 @@ sub install_zones {
sub pre_receive {
my ($old, $new, $ref);
- chdir '..';
while (<STDIN>) { # <old-value> SP <new-value> SP <ref-name> LF
print if $verbosity >= 1;
@@ -246,7 +244,7 @@ sub pre_receive {
# parse diff output, add only valid zone names to %files for parsing
$files{$1} = 0 while m,^:(?:[\w.]+\s+){5}([a-z0-9./-]+)$,gm;
- load_zones_config;
+ load_repos_config;
process_files;
if (@zones) {
@@ -266,13 +264,12 @@ sub pre_receive {
sub post_receive {
print "\n";
- chdir '..';
open FILE, '<', $list_file or die $!;
push @zones, split /[\s\n\r]+/ while <FILE>;
close FILE;
- load_zones_config;
+ load_repos_config;
install_zones;
print "Done. Don't forget to pull if you use auto increment.\n";
}
@@ -286,7 +283,6 @@ sub update_record {
my $changed = 0;
my @newfile;
- chdir $user;
git 'checkout -f master';
open FILE, '<', $file or die "$file: $!";
diff --git a/bin/gitzone-shell b/bin/gitzone-shell
@@ -1,7 +1,11 @@
#!/bin/sh
# only repo allowed for git pull/push
-repo='zones'
+repo=$LOGNAME
+# directory the repo is in, relative to $HOME
+repo_dir='zones'
+#repo_dir='.'
+
# allow ssh key add/del/list commands if this file exists
allow_key_mgmt_file='.ssh/authorized_keys_edit_allowed'
@@ -20,10 +24,11 @@ if [ "$1" != "-c" ]; then error; fi
cmd=$2
if [[ "$cmd" == git-upload-pack* ]]; then
- $git upload-pack $repo
+ $git upload-pack $repo_dir/$repo
elif [[ "$cmd" == git-receive-pack* ]]; then
- $git receive-pack $repo
+ $git receive-pack $repo_dir/$repo
elif [[ "$cmd" == update-record* ]]; then
+ cd $repo_dir/$repo/.git
$gitzone $config update-record "$cmd"
elif [ -f $allow_key_mgmt_file ]; then
if [ "$cmd" == list-keys ]; then
diff --git a/etc/gitzone.conf b/etc/gitzone.conf
@@ -4,6 +4,7 @@
#
# this file is parsed as Perl code and you can use the following variables:
# $user - name of the user gitzone is invoked by
+# $repo - name of the repository gitzone is invoked for
# directory where the zone files are copied to (no trailing slash)
# there should be one directory for each user here chowned to them
@@ -17,9 +18,10 @@ $rndc = '/usr/sbin/rndc';
# update-record command: 1 = enabled, 0 = disabled
$update_record = 1;
-# restrict includes to user directories
-# $INCLUDE file names should be prefixed with <username>/ in this case
-$user_includes = 1;
+# unrestricted includes: 1 = enabled, 0 = disabled (default)
+# by default a restriction applies to $INCLUDE file names,
+# they should be prefixed with <repo>/ and nothing else is allowed in parent dirs
+$unrestricted_includes = 0;
# max depth to follow INCLUDED_BY files
$max_depth = 256;
@@ -31,6 +33,7 @@ $verbosity = 0;
$class = 'IN';
# default view of the zones (optional)
$default_view = '';
+#$default_view = $repo;
# $zones defines which files in a user's repo can be loaded as zone files.
#
@@ -48,11 +51,11 @@ $default_view = '';
#
# The -default key is tried first for every user, then it's merged with the user-specific config.
-$zones = {
+$repos = {
# -default => {
-# "/etc/bind/users/$user.conf" => 1, # allow every zone from this file, use the default view for them
+# "/etc/bind/repos/$repo.conf" => 1, # allow every zone from this file, use the default view for them
# },
-# user1 => { # /etc/bind/users/user1.conf is loaded first and merged with the config below, as specified in -default above
+# user1 => { # /etc/bind/repos/user1.conf is loaded first and merged with the config below, as specified in -default above
# 'example.com' => 1, # allow example.com, use the default view for it
# 'example.net' => 'extern', # allow example.net, use the extern view for it
# 'example.org' => [qw(view1 view2)], # allow example.org, use both view1 & view2 for it