#!/usr/bin/perl -w #---------------------------------------------------------------------- # vim: ft=perl ts=2 sw=2 et: #---------------------------------------------------------------------- # # Copyright (C) 2012-2013 - Marco Hess # # This file is part of the "Git Repositories" panel in the # SME Server server-manager panel to configure git repositories. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # #---------------------------------------------------------------------- package esmith; use strict; use Errno; use File::Find; use esmith::util; use esmith::templates; use esmith::GitDB; $ENV{'PATH'} = "/bin"; #---------------------------------------------------------------------- my $event = $ARGV [0]; my $gitRepositoryName = $ARGV [1]; die "event argument missing" unless defined ($event); die "gitRepositoryName argument missing" unless defined ($gitRepositoryName); #---------------------------------------------------------------------- my $git_db = esmith::GitDB->open_ro(); my $repository = $git_db->get($gitRepositoryName) or die "Couldn't find $gitRepositoryName record in SME Server Git database\n"; die "'$gitRepositoryName' is not an Git repository; git-repository-modify event failed.\n" unless ($repository->prop('type') eq 'repository'); #---------------------------------------------------------------------- my %properties = $repository->props; my $description = $properties{'description'}; my $effective_pull_users = $git_db->effective_users_list_from( $properties{'pull_groups'}, $properties{'pull_users'} ); my $effective_push_users = $git_db->effective_users_list_from( $properties{'push_groups'}, $properties{'push_users'} ); my $effective_pull_push_users = $git_db->effective_users_list_from( $properties{'push_groups'}, $properties{'push_users'}, $properties{'pull_groups'}, $properties{'pull_users'} ); if ($event eq 'git-repository-create') { #------------------------------------------------------------ # Create a bare git repository # We add the .git extension to the repository name to indicate # is a bare repository. Permssions are set such that the # repository is owned by admin and is accessible to the group # www (so Apache can access it) but not anybody else. #------------------------------------------------------------ # Create the bare repository system("/usr/bin/git", "init", "--bare", "--shared=0660", "/home/e-smith/files/git/$gitRepositoryName.git") == 0 or die "Error creating the initial bare git repository structure for /home/e-smith/files/git/$gitRepositoryName.git"; # Init the Git Description open(my $file, '>', "/home/e-smith/files/git/$gitRepositoryName.git/description"); print $file $repository->prop('description') . "\n"; # Create a 'post-update' hook open($file, '>', "/home/e-smith/files/git/$gitRepositoryName.git/hooks/post-update"); print $file "#!/bin/sh\n" . "# Hook script auto generated on repository create by SME server manager. Enables automatic markdown for README.md\n" . "# for viewing in gitweb as README.html.\n\n" . "rm -f README.html\n" . "git cat-file -e HEAD:README.md > /dev/null 2>&1\n" . "if [ \$? -eq 0 ]; then\n" . " git cat-file blob HEAD:README.md | perl /usr/share/markdown/Markdown.pl --html4tags > README.html\n" . " chmod 0440 README.html\n" . "fi\n\n" . "# Update GIT server info as well\n" . "git update-server-info\n"; close($file); chmod 0770, "/home/e-smith/files/git/$gitRepositoryName.git/hooks/post-update"; # Set Administrator as the effective owner of the repository chdir "/home/e-smith/files/git/$gitRepositoryName.git" or die "Could not chdir to /home/e-smith/files/git/$gitRepositoryName.git"; system("/usr/bin/git", "config", "--add", "gitweb.owner", "Administrator") == 0 or die "Could not change gitweb.owner setting in /home/e-smith/files/git/$gitRepositoryName.git"; # Create a 'post-receive-email' hook to send emails when PUSH actions occur system("/bin/ln", "-sf", "/usr/share/git-core/contrib/hooks/post-receive-email", "hooks/post-receive") == 0 or die "Could not link 'post-receive-email' hook in /home/e-smith/files/git/$gitRepositoryName.git"; system("/usr/bin/git", "config", "--add", "hooks.emailprefix", "[GIT] ") == 0 or die "Could not change hooks.emailprefix setting in /home/e-smith/files/git/$gitRepositoryName.git"; # Create the email list with the effective push & pull users. system("/usr/bin/git", "config", "--add", "hooks.mailinglist", $effective_pull_push_users ) == 0 or die "Could not create 'hooks.mailinglist' in /home/e-smith/files/git/$gitRepositoryName.git"; } elsif ($event eq 'git-repository-modify') { #------------------------------------------------------------ # Modify the Git repository #------------------------------------------------------------ # Update the Git description to match the setting in the server-manager interface open(my $file, '>', "/home/e-smith/files/git/$gitRepositoryName.git/description"); print $file $repository->prop('description') . "\n"; # Goto git repository chdir "/home/e-smith/files/git/$gitRepositoryName.git" or die "Could not chdir to /home/e-smith/files/git/$gitRepositoryName.git"; # Update the email list with the effective push & pull users. system("/usr/bin/git", "config", "--replace-all", "hooks.mailinglist", $effective_pull_push_users ) == 0 or die "Could not update 'hooks.mailinglist' in /home/e-smith/files/git/$gitRepositoryName.git"; # Run a "git update-server-info" action for good measure system("/usr/bin/git", "update-server-info") == 0 or die "Error running 'git-update-server-info' on repository /home/e-smith/files/git/$gitRepositoryName.git"; } #------------------------------------------------------------ # Default for both create and modify is to fix the ownership # to allow the webserver access to the repository # Ensure that files created are with gid set for the www group. #------------------------------------------------------------ chdir "/home/e-smith/files/git/$gitRepositoryName.git" or die "Could not chdir to /home/e-smith/files/git/$gitRepositoryName.git"; system("/bin/chown", "-R", "admin:www", "/home/e-smith/files/git/$gitRepositoryName.git") == 0 or die "Could not change ownership of /home/e-smith/files/git/$gitRepositoryName.git"; chmod 02770, "."; # Ensure that the git repository database is readable by the web server. system("/bin/chmod", "644", "/home/e-smith/db/git") == 0 or die "Could not change permissions on /home/e-smith/db/git"; # Ensure that the networks database is readable by the web server. system("/bin/chmod", "644", "/home/e-smith/db/networks") == 0 or die "Could not change permissions on /home/e-smith/db/networks";