Start VCS/Git.pm
This commit is contained in:
parent
639c73a4cf
commit
59d27b9575
1 changed files with 307 additions and 0 deletions
307
ACU/VCS/Git.pm
Normal file
307
ACU/VCS/Git.pm
Normal file
|
|
@ -0,0 +1,307 @@
|
|||
#! /usr/bin/env perl
|
||||
|
||||
package Git;
|
||||
|
||||
use v5.10.1;
|
||||
use strict;
|
||||
use warnings;
|
||||
use File::Path;
|
||||
use File::Temp;
|
||||
|
||||
use ACU::LDAP;
|
||||
use ACU::Log;
|
||||
use ACU::API::Projects;
|
||||
|
||||
our $git_user = "git";
|
||||
our $git_server;
|
||||
our $git_adminrepo = "gitolite-admin.git";
|
||||
|
||||
our $configuration_directory = "/conf/";
|
||||
our $configuration_file = "subjects.conf";
|
||||
our $projects_directory = "subjects/";
|
||||
my $gitolite_directory;
|
||||
|
||||
# General part
|
||||
|
||||
sub init_conf(;$)
|
||||
{
|
||||
$git_server = $_ if (shift);
|
||||
|
||||
$gitolite_directory = mktemp("/tmp/git_manage_XXXX") unless(-d $gitolite_directory);
|
||||
|
||||
log INFO, "Cloning $git_user\@$git_server:$git_adminrepo to $gitolite_directory";
|
||||
|
||||
system ("git clone $git_user\@$git_server:$git_adminrepo $gitolite_directory");
|
||||
|
||||
chdir($gitolite_directory);
|
||||
|
||||
return $gitolite_directory;
|
||||
}
|
||||
|
||||
sub save_conf(;$)
|
||||
{
|
||||
chdir($gitolite_directory);
|
||||
|
||||
my $commit = shift;
|
||||
system ("git commit -am '$commit'") if ($commit);
|
||||
|
||||
log INFO, "Saving repositories configuration";
|
||||
|
||||
system ("git push");
|
||||
unlink ($gitolite_directory);
|
||||
$gitolite_directory = undef;
|
||||
}
|
||||
|
||||
|
||||
# Auth part: give to user right on repository
|
||||
|
||||
sub auth_add
|
||||
{
|
||||
my $rgroup = shift;
|
||||
my $rname = shift;
|
||||
my $accesss = shift;
|
||||
|
||||
init_conf() if (!$gitolite_directory);
|
||||
|
||||
say " repo $rname";
|
||||
for my $access (@{ $accesss })
|
||||
{
|
||||
say $access->gen_string("gitolite");
|
||||
#say " RW+ = \@admins \@$year-$project_name-$login";
|
||||
#say " RW+ = \@chefs \@resp-$year-$project_name";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
sub auth_update
|
||||
{
|
||||
init_conf() if (!$gitolite_directory);
|
||||
|
||||
}
|
||||
|
||||
sub auth_delete
|
||||
{
|
||||
init_conf() if (!$gitolite_directory);
|
||||
|
||||
}
|
||||
|
||||
sub auth_save
|
||||
{
|
||||
init_conf() if (!$gitolite_directory);
|
||||
|
||||
}
|
||||
|
||||
|
||||
# Repository part: manage repositories
|
||||
|
||||
# Gitolite manage repositories only if there are associated with rights
|
||||
|
||||
sub repository_add
|
||||
{
|
||||
}
|
||||
|
||||
sub repository_update
|
||||
{
|
||||
}
|
||||
|
||||
sub repository_delete
|
||||
{
|
||||
}
|
||||
|
||||
sub repository_group_add
|
||||
{
|
||||
my $g_name = shift; #group_name
|
||||
my $g_comp = shift; # complement, here respo rights
|
||||
my $skip_save = shift // 0;
|
||||
|
||||
if ($g_name !~ /^[a-zA-Z-_.]+$/) {
|
||||
log ERROR, "Group name ($g_name) does not respect expected format ; skip add.";
|
||||
return 0;
|
||||
}
|
||||
|
||||
init_conf() if (!$gitolite_directory);
|
||||
|
||||
if (-f $gitolite_directory.$configuration_directory.$projects_directory."/".$g_name.".conf") {
|
||||
log ERROR, "Cannot add new repository group: $g_name already exists!";
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
open my $g_conf, ">", $gitolite_directory.$configuration_directory.$projects_directory."/".$g_name.".conf";
|
||||
say $g_conf $g_conf;
|
||||
close $g_conf;
|
||||
|
||||
open $g_conf, ">>", $gitolite_directory.$configuration_directory.$configuration_file;
|
||||
say $g_conf "include \"$projects_directory/$g_name.conf\"";
|
||||
close $g_conf;
|
||||
}
|
||||
|
||||
save_conf("Add repositories group $g_name") unless($skip_save);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub repository_group_delete
|
||||
{
|
||||
my $g_name = shift; #group_name
|
||||
my $skip_save = shift // 0;
|
||||
|
||||
if ($g_name !~ /^[a-zA-Z-_.]+$/) {
|
||||
log ERROR, "Group name ($g_name) does not respect expected format ; skip add.";
|
||||
return 0;
|
||||
}
|
||||
|
||||
init_conf() if (!$gitolite_directory);
|
||||
|
||||
my $configuration_path = $gitolite_directory.$configuration_directory.$configuration_file;
|
||||
|
||||
if (-f $gitolite_directory.$configuration_directory.$projects_directory."/".$g_name.".conf") {
|
||||
open my $g_conf, "<", $configuration_path;
|
||||
my @contents = <$g_conf>;
|
||||
close $g_conf;
|
||||
|
||||
@contents = grep !/^include "\Q$projects_directory\/$g_name.conf\E"$/, @contents; #";
|
||||
|
||||
open $g_conf, '>', $configuration_path or die $!;
|
||||
print $g_conf @contents;
|
||||
close $g_conf;
|
||||
|
||||
unlink($gitolite_directory.$configuration_directory.$projects_directory."/".$g_name.".conf");
|
||||
}
|
||||
else {
|
||||
log WARN, "Repository group $g_name not found.";
|
||||
return 0;
|
||||
}
|
||||
|
||||
save_conf("Delete repositories group $g_name") unless($skip_save);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub repository_group_update
|
||||
{
|
||||
my $g_name = shift;
|
||||
|
||||
repository_group_delete($g_name, 1);
|
||||
if (!repository_group_add($g_name, shift, 1)) {
|
||||
log ERROR, "Unable to readd $g_name group repository. Configuration not saved.";
|
||||
return 0;
|
||||
}
|
||||
|
||||
# ...;
|
||||
auth_add();
|
||||
|
||||
save_conf("Delete repositories group $g_name") unless(shift);
|
||||
}
|
||||
|
||||
# User part: manage user authentication (password, keys, ...)
|
||||
|
||||
sub user_add
|
||||
{
|
||||
my $login = shift;
|
||||
my $skip_save = shift // 0;
|
||||
my $multiple = shift // 0;
|
||||
|
||||
if (!$login or $login !~ /^(\*|[a-zA-Z0-9._-]+)$/) {
|
||||
log WARN, "Login required in user_add";
|
||||
return 0;
|
||||
}
|
||||
|
||||
init_conf() if (!$gitolite_directory);
|
||||
|
||||
# First, remove all user keys
|
||||
user_delete($login, 1, $multiple);
|
||||
|
||||
# Then, extract user keys
|
||||
my @entries = LDAP::search_dns(undef, "ou=users", "&(uid=$login)(sshPublicKey=*)", [ "uid", "sshPublicKey" ]);
|
||||
|
||||
if ($#entries > 1 && !$multiple) { log WARN, "Found multiple user $login, aborting keys update."; return 0; }
|
||||
|
||||
for my $entry (@entries)
|
||||
{
|
||||
my $login = $entry->get_value("uid");
|
||||
if ($login)
|
||||
{
|
||||
my $i = 0;
|
||||
my @keys = $entry->get_value("sshPublicKey");
|
||||
log INFO, "Updating ".($#keys+1)." keys for $login.";
|
||||
for my $key (@keys)
|
||||
{
|
||||
chomp $key;
|
||||
|
||||
mkdir $gitolite_directory."/keydir/$i" unless (-d $gitolite_directory."/keydir/$i");
|
||||
|
||||
open my $kf, ">", $gitolite_directory."/keydir/$i/$login.pub";
|
||||
print $kf $key;
|
||||
close $kf;
|
||||
|
||||
system("git add $gitolite_directory/keydir/$i/$login.pub");
|
||||
$i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($multiple) {
|
||||
save_conf("Update users keys from LDAP") unless ($skip_save);
|
||||
}
|
||||
else {
|
||||
save_conf("Update $login keys from LDAP") unless ($skip_save);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub user_delete
|
||||
{
|
||||
my $login = shift;
|
||||
my $skip_save = shift // 0;
|
||||
my $multiple = shift // 0;
|
||||
|
||||
if (!$login) {
|
||||
log WARN, "Login required in user_add";
|
||||
return 0;
|
||||
}
|
||||
|
||||
init_conf() if (!$gitolite_directory);
|
||||
|
||||
opendir(my $dh, "$gitolite_directory/keydir/") || die "can't opendir keydir: $!";
|
||||
for my $f (readdir $dh)
|
||||
{
|
||||
if($multiple)
|
||||
{
|
||||
if ($f =~ /^[0-9]/ && -d "$gitolite_directory/keydir/$f") {
|
||||
log INFO, "Removing $f directory";
|
||||
rmtree("$gitolite_directory/keydir/$f");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (-f "$gitolite_directory/keydir/$f/$login.pub") {
|
||||
log INFO, "Removing $f/$login.pub";
|
||||
unlink("$gitolite_directory/keydir/$f/$login.pub");
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir $dh;
|
||||
|
||||
save_conf("Remove $login keys") unless ($skip_save);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub user_update
|
||||
{
|
||||
return user_add(@_);
|
||||
}
|
||||
|
||||
sub users_update
|
||||
{
|
||||
return user_add("*", (shift // 0), 1);
|
||||
}
|
||||
|
||||
sub users_del
|
||||
{
|
||||
return user_del("*", (shift // 0), 1);
|
||||
}
|
||||
|
||||
1;
|
||||
Reference in a new issue