From 580564e358241d22decfe697d9baa21334cd7886 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 14 Sep 2013 09:35:56 +0200 Subject: [PATCH 001/364] Add command to publish traces --- commands/project/pub_traces.pl | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 commands/project/pub_traces.pl diff --git a/commands/project/pub_traces.pl b/commands/project/pub_traces.pl new file mode 100644 index 0000000..0268b33 --- /dev/null +++ b/commands/project/pub_traces.pl @@ -0,0 +1,20 @@ +#! /usr/bin/env perl + +use v5.10.1; +use strict; +use warnings; + +use lib "../../"; + +use ACU::API::Base; +use ACU::API::Projects; + + +if ($#ARGV == 1) +{ + API::Projects::add_traces($ARGV[0], $ARGV[1]); +} +else +{ + say "$0 "; +} From 82789d394fd0cdfdf4cbbf9428ed619582caf32e Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 14 Sep 2013 09:37:22 +0200 Subject: [PATCH 002/364] Add a script to launch screens on each server --- Makefile | 4 ++++ process/launch.sh | 52 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100755 process/launch.sh diff --git a/Makefile b/Makefile index 88bc57c..94efeb2 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,10 @@ MAKEDIR=mkdir PROVER=prove -f RM=rm TESTDIR=t +SHELL=/bin/sh + +launch: + $(SHELL) process/launch.sh install: $(MAKEDIR) -p $(DEST) diff --git a/process/launch.sh b/process/launch.sh new file mode 100755 index 0000000..21dcceb --- /dev/null +++ b/process/launch.sh @@ -0,0 +1,52 @@ +#! /bin/sh + +cd $(dirname "$0") + +GREP='/bin/egrep' +SCREEN='/usr/bin/screen' +SED='/bin/sed -E' +PERL='/usr/bin/env perl' + +if [ -z "$1" ] +then + HOSTNAME="$1" +else + HOSTNAME=`/bin/hostname` +fi + +# Kill old liblersorf screen sessions +$SCREEN -ls | $GREP '[0-9]+\.lerdorf_[a-zA-Z0-9_-]+' | +while read LINE +do + SNAME=`echo $LINE | $SED "s/^[^0-9]*([0-9]+\.[^ \t]+).*$/\1/"` + $SCREEN -S "$SNAME" -X kill +done + +case $HOSTNAME in + + cpp) + $SCREEN -S lerdorf_process_ldap_sync_ssh_keys_forge -d -m bash -c "while true; do $PERL process/ldap/sync_ssh_keys_forge.pl; done" + ;; + + hamano) + $SCREEN -S lerdorf_process_ldap_sync_ssh_keys_git -d -m bash -c "while true; do $PERL process/ldap/sync_ssh_keys_git.pl; done" + ;; + + moore) + $SCREEN -S lerdorf_process_ldap_check_ssh_key -d -m bash -c "while true; do $PERL process/ldap/check_ssh_key.pl; done" + $SCREEN -S lerdorf_process_ldap_sync_ssh_keys -d -m bash -c "while true; do $PERL process/ldap/sync_ssh_keys.pl; done" + $SCREEN -S lerdorf_process_ldap_update_group -d -m bash -c "while true; do $PERL process/ldap/update_group.pl; done" + $SCREEN -S lerdorf_process_ldap_update_user -d -m bash -c "while true; do $PERL process/ldap/update_user.pl; done" + + $SCREEN -S lerdorf_process_files_intradata_get -d -m bash -c "while true; do $PERL process/files/intradata_get.pl; done" + ;; + + noyce) + $SCREEN -S lerdorf_process_files_intradata_get -d -m bash -c "while true; do $PERL process/files/intradata_get.pl; done" + ;; + + *) + echo "No process to launch for $HOSTNAME" >&2 + exit 1 + ;; +esac \ No newline at end of file From 4857a0b228350fd5e6701d1c26ef43213381960a Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 14 Sep 2013 10:52:59 +0200 Subject: [PATCH 003/364] Add a script to install requirements --- Makefile | 10 +++++++++- commands/first-install.sh | 26 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100755 commands/first-install.sh diff --git a/Makefile b/Makefile index 94efeb2..ee1e2a7 100644 --- a/Makefile +++ b/Makefile @@ -1,21 +1,29 @@ COPY=cp -v DEST=/usr/local/share/perl/`ls -1 /usr/lib/perl/ | tail -1`/ +GIT=/usr/bin/git GITOLITE_DEST=/usr/share/gitolite/hooks/common MAKEDIR=mkdir PROVER=prove -f RM=rm TESTDIR=t SHELL=/bin/sh +SU=/bin/su launch: - $(SHELL) process/launch.sh + $(SU) -c "$(SHELL) process/launch.sh" intradmin install: + $(SHELL) commands/first-install.sh $(MAKEDIR) -p $(DEST) $(COPY) -r ACU/ $(DEST) test -d $(GITOLITE_DEST) && $(MAKEDIR) -p $(GITOLITE_DEST)/update.secondary.d test -d $(GITOLITE_DEST) && $(COPY) hooks/* $(GITOLITE_DEST)/update.secondary.d/ +update: unstall install + +upgrade: + $GIT pull + unstall: $(RM) -r $(DEST)/ACU/ test -d $(GITOLITE_DEST) && $(RM) -rf $(GITOLITE_DEST)/update.secondary.d diff --git a/commands/first-install.sh b/commands/first-install.sh new file mode 100755 index 0000000..ae4e3b1 --- /dev/null +++ b/commands/first-install.sh @@ -0,0 +1,26 @@ +#! /bin/bash + +# Install missing packets +PACKAGES_LIST="libnet-ldap-perl libxml-libxml-perl" + +if ! whereis dpkg > /dev/null 2> /dev/null +then + aptitude install dpkg +fi + +for PK in $PACKAGES_LIST +do + if ! dpkg -l | grep "^ii" | grep "$PK" > /dev/null 2> /dev/null + then + aptitude install "$PK" + fi +done + + +# Add intradmin user if missing +if ! getent passwd | grep "intradmin:" > /dev/null 2> /dev/null +then + useradd --shell /bin/false --uid 942 intradmin +fi + +echo "System ready!" \ No newline at end of file From 1e3c92e46a1f6f7df2a371012163b45486fa8795 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 14 Sep 2013 10:56:31 +0200 Subject: [PATCH 004/364] Fix Makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ee1e2a7..eb20ff1 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ install: update: unstall install upgrade: - $GIT pull + $(GIT) pull unstall: $(RM) -r $(DEST)/ACU/ From 7c233e1873dc9468687ef085f5730ef6702b4490 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 14 Sep 2013 11:00:36 +0200 Subject: [PATCH 005/364] Force /bin/sh to intradmin user --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index eb20ff1..ef5974b 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ SHELL=/bin/sh SU=/bin/su launch: - $(SU) -c "$(SHELL) process/launch.sh" intradmin + $(SU) -s /bin/sh -c "$(SHELL) process/launch.sh" intradmin install: $(SHELL) commands/first-install.sh From 1f55ca1bfe5ee47b35896fa4e8498351045d7bb7 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 14 Sep 2013 11:05:18 +0200 Subject: [PATCH 006/364] Fix install script --- commands/first-install.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/commands/first-install.sh b/commands/first-install.sh index ae4e3b1..f4a8d42 100755 --- a/commands/first-install.sh +++ b/commands/first-install.sh @@ -20,7 +20,9 @@ done # Add intradmin user if missing if ! getent passwd | grep "intradmin:" > /dev/null 2> /dev/null then - useradd --shell /bin/false --uid 942 intradmin + useradd --shell /bin/false --uid 942 intradmin && + mkdir -p /home/intradmin && + chown -R intradmin:intradmin /home/intradmin fi echo "System ready!" \ No newline at end of file From 9353d1d4e6b8895d47cce5874070499563bfa0ae Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 14 Sep 2013 11:16:00 +0200 Subject: [PATCH 007/364] Always call chown intradmin after update --- Makefile | 7 ++++--- commands/first-install.sh | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index ef5974b..cb888a7 100644 --- a/Makefile +++ b/Makefile @@ -19,10 +19,11 @@ install: test -d $(GITOLITE_DEST) && $(MAKEDIR) -p $(GITOLITE_DEST)/update.secondary.d test -d $(GITOLITE_DEST) && $(COPY) hooks/* $(GITOLITE_DEST)/update.secondary.d/ -update: unstall install - -upgrade: +update: $(GIT) pull + $(SHELL) commands/first-install.sh + +upgrade: install unstall: $(RM) -r $(DEST)/ACU/ diff --git a/commands/first-install.sh b/commands/first-install.sh index f4a8d42..52a3045 100755 --- a/commands/first-install.sh +++ b/commands/first-install.sh @@ -21,8 +21,9 @@ done if ! getent passwd | grep "intradmin:" > /dev/null 2> /dev/null then useradd --shell /bin/false --uid 942 intradmin && - mkdir -p /home/intradmin && - chown -R intradmin:intradmin /home/intradmin + mkdir -p /home/intradmin fi +chown -R intradmin:intradmin /home/intradmin + echo "System ready!" \ No newline at end of file From a90638153eeaee2e788c17e5719c514d9e2b69a3 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 14 Sep 2013 11:19:06 +0200 Subject: [PATCH 008/364] Fix process launch --- process/launch.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/process/launch.sh b/process/launch.sh index 21dcceb..e04a4bc 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -9,9 +9,9 @@ PERL='/usr/bin/env perl' if [ -z "$1" ] then - HOSTNAME="$1" -else HOSTNAME=`/bin/hostname` +else + HOSTNAME="$1" fi # Kill old liblersorf screen sessions From ecf03827c19e4cfbb9e220cafeb04cdd3ffd08f6 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 14 Sep 2013 17:40:23 +0200 Subject: [PATCH 009/364] Hook subject OK --- hooks/subjects.pl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index 30e2cf1..eecec36 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -31,7 +31,7 @@ if ($ref =~ m<^refs/tags(/.+)$>) my $tag = $1; my @args; - while ($tag =~ m<[:/]([^:]+)>g) { + while ($tag =~ m<[,/]([^,]+)>g) { push @args, $1; } @@ -65,7 +65,7 @@ sub check_xml sub repository_name { my $repo = $ENV{GL_REPO}; - $repo =~ s/^subjects\\(.*)/$1/; + $repo =~ s#^subjects/(.*)#$1#; return $repo; } @@ -143,8 +143,12 @@ sub tag_project # Send data to intradata log INFO, "Attente d'un processus de publication..."; - log ERROR, "Erreur durant le processus de publication : $_" - if (Process::Client::launch("intradata_get", { action => "update", type => "project", id => $project_id, "year" => $year }, { "butler.xml" => $content })); + if (my $err = Process::Client::launch("intradata_get", { action => "update", type => "project", id => $project_id, "year" => $year }, { "butler.xml" => $content })) + { + if (${ $err } ne "Ok") { + log ERROR, "Erreur durant le processus de publication : " . ${ $err }; + } + } # Call API log ERROR, $_ if(API::Projects::add($project_id, $year)); From 5b8456fa69e716eed4ea8a31241c5d2d4ee135d9 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 14 Sep 2013 17:57:40 +0200 Subject: [PATCH 010/364] Errors are best saved and shown --- ACU/API/Base.pm | 4 ++-- hooks/subjects.pl | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ACU/API/Base.pm b/ACU/API/Base.pm index 716c7e6..abfd95e 100644 --- a/ACU/API/Base.pm +++ b/ACU/API/Base.pm @@ -50,8 +50,8 @@ sub parse($$) if ($@) { $parsed->{result} = 256; - $parsed->{message} = "Erreur du parser."; - log WARN, "Erreur du parser"; + $parsed->{message} = "Erreur du parser : $@"; + log WARN, "Erreur du parser."; } if (! exists $parsed->{result}) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index eecec36..fdb8ced 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -3,11 +3,12 @@ use strict; use warnings; use v5.10; +use File::Basename; use ACU::API::Projects; use ACU::LDAP; use ACU::Log; -$ACU::Log::log_file = undef; +$ACU::Log::log_file = "/var/log/hooks/" . basename($0) . ".log"; use ACU::Process; # First, check if the repository is in the subjects/ directory From 9b53b5d7e86c49336d64c9ec3ef0612fcaa4b204 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 14 Sep 2013 18:06:42 +0200 Subject: [PATCH 011/364] Check certificate --- ACU/API/Base.pm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ACU/API/Base.pm b/ACU/API/Base.pm index abfd95e..f772a10 100644 --- a/ACU/API/Base.pm +++ b/ACU/API/Base.pm @@ -70,6 +70,8 @@ sub get($$) my $url = shift; my $ua = LWP::UserAgent->new; + $ua->ssl_opts(SSL_ca_file => "/etc/ldap/cacert.pem"); + log(DEBUG, 'GET Request to ', API_URL, $url); my $req = GET API_URL . $url; @@ -86,6 +88,8 @@ sub send($$$) my $url = shift; my $ua = LWP::UserAgent->new; + $ua->ssl_opts(SSL_ca_file => "/etc/ldap/cacert.pem"); + log(DEBUG, 'POST Request to ', API_URL, $url); my $req = POST API_URL . $url, shift; From d9bc49c5d782cccf94da8cc883a0269d8a736e26 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 14 Sep 2013 18:35:08 +0200 Subject: [PATCH 012/364] Generate token before saving butler.xml --- hooks/subjects.pl | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index fdb8ced..0ad91a5 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -3,6 +3,7 @@ use strict; use warnings; use v5.10; +use Digest::SHA qw(sha1_base64); use File::Basename; use ACU::API::Projects; @@ -57,7 +58,7 @@ sub check_xml else { open $fh, "|xmllint --noout -"; } - print $fh $content; + print $fh ${ $content }; close $fh; return $?; @@ -134,13 +135,32 @@ sub tag_project } # Check DTD validity - if (check_xml($content, "http://acu.epita.fr/dtd/project.dtd")) { + if (check_xml(\$content, "http://acu.epita.fr/dtd/project.dtd")) { log ERROR, "Corrigez les erreurs du fichier project.xml avant de lancer la création du projet."; } # TODO: check user permissions # Generate token for VCS submission + my $dom = XML::LibXML->load_xml(string => (\$content)); + my $mod = 0; + for $vcs ($dom->documentElement()->getElementsByTagName("vcs")) + { + if (! $vcs->hasAttribute("token")) + { + my $token; + do { + $token = sha1_base64(rand); + $token =~ s/[^a-zA-Z0-9]//g; + } while (length $token >= 12); + $vcs->setAttribute("token", $token); + $mod = 1; + } + } + + if ($mod) { + $content = $dom->toString(); + } # Send data to intradata log INFO, "Attente d'un processus de publication..."; From b6aaf11ae2fe4c418f5a0ed6eca4060e726e9723 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 14 Sep 2013 18:43:46 +0200 Subject: [PATCH 013/364] Warn only if project already exists --- hooks/subjects.pl | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index 0ad91a5..19eb80d 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -171,11 +171,26 @@ sub tag_project } } + log INFO, "Information de l'intranet..."; # Call API - log ERROR, $_ if(API::Projects::add($project_id, $year)); + eval { + API::Projects::add($project_id, $year); + }; + if ($@) + { + if ($@ =~ /apP]roject [aA]ll?ready [eE]xists/) { + log WARN, $@; + } + else { + log ERROR, $@; + } + } # FIXME: Remove next line after 2016 piscine: ça ne devrait pas être fait à ce moment là - log ERROR, $_ if(API::Projects::gen_groups($project_id, $year)); + eval { + API::Projects::gen_groups($project_id, $year); + }; + log ERROR, $_ if($@); } else { From feb69dd6f09af425dd6113d7a0f5ca1989ebd6ca Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 14 Sep 2013 18:44:22 +0200 Subject: [PATCH 014/364] Fix typo --- hooks/subjects.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index 19eb80d..265aa0a 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -144,7 +144,7 @@ sub tag_project # Generate token for VCS submission my $dom = XML::LibXML->load_xml(string => (\$content)); my $mod = 0; - for $vcs ($dom->documentElement()->getElementsByTagName("vcs")) + for my $vcs ($dom->documentElement()->getElementsByTagName("vcs")) { if (! $vcs->hasAttribute("token")) { From 905cc5f2e222f601e23cc416bde30230e36e75fa Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 14 Sep 2013 18:54:01 +0200 Subject: [PATCH 015/364] Fix token generation --- ACU/Log.pm | 2 ++ hooks/subjects.pl | 13 ++++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ACU/Log.pm b/ACU/Log.pm index 0a522c2..a7b2ebf 100644 --- a/ACU/Log.pm +++ b/ACU/Log.pm @@ -34,6 +34,8 @@ sub log($@) { my $level = shift; + if ($#_ < 0) { return; } + if (!$log_fd && $log_file) { open ($log_fd, ">>", $log_file) or die("Unable to open log ($log_file) file for writing"); say $log_fd strftime("%a %b %e %H:%M:%S %Y", localtime), " START new logging session "; diff --git a/hooks/subjects.pl b/hooks/subjects.pl index 265aa0a..eae20dc 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -152,7 +152,7 @@ sub tag_project do { $token = sha1_base64(rand); $token =~ s/[^a-zA-Z0-9]//g; - } while (length $token >= 12); + } while (length $token < 12); $vcs->setAttribute("token", $token); $mod = 1; } @@ -178,11 +178,12 @@ sub tag_project }; if ($@) { - if ($@ =~ /apP]roject [aA]ll?ready [eE]xists/) { - log WARN, $@; + my $err = $@; + if ($err =~ /[pP]roject [aA]ll?ready [eE]xists/) { + log WARN, $err; } else { - log ERROR, $@; + log ERROR, $err; } } @@ -190,7 +191,9 @@ sub tag_project eval { API::Projects::gen_groups($project_id, $year); }; - log ERROR, $_ if($@); + if($@) { + log ERROR, $_; + } } else { From e2f8d2389d28393d5e3ada8770bf993307fe0a50 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 15 Sep 2013 12:32:10 +0200 Subject: [PATCH 016/364] New log level: DONE --- ACU/Log.pm | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/ACU/Log.pm b/ACU/Log.pm index a7b2ebf..0ebb577 100644 --- a/ACU/Log.pm +++ b/ACU/Log.pm @@ -3,6 +3,7 @@ package ACU::Log; use v5.10.1; use strict; use warnings; +use Carp; use Data::Dumper; use Exporter 'import'; use POSIX qw(strftime); @@ -12,15 +13,15 @@ use constant { FATAL => 1, ERROR2 => 2, ERROR => 3, - WARN4 => 4, - WARN => 5, + WARN => 4, + DONE => 5, USAGE => 6, INFO => 7, DEBUG => 8, TRACE => 9, }; -our @EXPORT = qw(log FATAL ERROR2 ERROR WARN4 WARN USAGE INFO DEBUG TRACE); +our @EXPORT = qw(log FATAL ERROR2 ERROR WARN DONE USAGE INFO DEBUG TRACE); our $display_level = 7; our $save_level = 9; @@ -35,6 +36,10 @@ sub log($@) my $level = shift; if ($#_ < 0) { return; } + if (!$_[0]) { + $Carp::Verbose = 1; + croak "Empty log message, this should not append!"; + } if (!$log_fd && $log_file) { open ($log_fd, ">>", $log_file) or die("Unable to open log ($log_file) file for writing"); @@ -92,7 +97,8 @@ sub leveldisp($) return BOLD, ON_RED, YELLOW, "/!\\", RESET, " ", BOLD if ($level == 1); return BOLD, ON_RED, ">>>", RESET, " ", BOLD if ($level == 2); return BOLD, RED, ">>>", RESET, " ", BOLD if ($level == 3); - return BOLD, YELLOW, ">>>", RESET, " ", BOLD if ($level == 5 or $level == 4); + return BOLD, YELLOW, ">>>", RESET, " ", BOLD if ($level == 4); + return BOLD, GREEN, ">>>", RESET, " ", BOLD if ($level == 5); return BOLD, MAGENTA, " * ", RESET, " ", BOLD if ($level == 6); return BOLD, CYAN, " * ", RESET, " " if ($level == 7); return BOLD, BLUE, " % ", RESET, " " if ($level == 8); From aebef9850ea59bfc48486292ace0e311eadaa120 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 15 Sep 2013 12:32:50 +0200 Subject: [PATCH 017/364] Extract list of users by year --- commands/ldap/extract_students.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/commands/ldap/extract_students.pl b/commands/ldap/extract_students.pl index a1badb5..b9966e3 100644 --- a/commands/ldap/extract_students.pl +++ b/commands/ldap/extract_students.pl @@ -10,11 +10,11 @@ use lib "../../"; use ACU::Log; use ACU::LDAP; -sub get_students() +sub get_students { my $ldap = LDAP::ldap_connect(); - my $year = LDAP::get_year($ldap); + my $year = shift // LDAP::get_year($ldap); return LDAP::search_dns($ldap, "ou=$year,ou=users", "objectClass=epitaAccount", "cn", "uid", "uidNumber"); } @@ -25,7 +25,7 @@ if ($#ARGV == -1) { } elsif ($ARGV[0] eq "csv") { - for my $student (get_students) + for my $student (get_students $ARGV[1]) { print $student->get_value("cn"); print ","; From 13f85455f82d4191d08fe48989830ee0e6989367 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 15 Sep 2013 12:33:34 +0200 Subject: [PATCH 018/364] Create long tag after project creation --- hooks/subjects.pl | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index eae20dc..0d36a26 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -153,7 +153,7 @@ sub tag_project $token = sha1_base64(rand); $token =~ s/[^a-zA-Z0-9]//g; } while (length $token < 12); - $vcs->setAttribute("token", $token); + $vcs->setAttribute("token", substr($token, 2, 23)); $mod = 1; } } @@ -187,12 +187,18 @@ sub tag_project } } - # FIXME: Remove next line after 2016 piscine: ça ne devrait pas être fait à ce moment là - eval { - API::Projects::gen_groups($project_id, $year); - }; - if($@) { - log ERROR, $_; + log DONE, "Projet créé/mis à jour avec succès."; + + # Add full tag + if (!$_[3]) + { + my $proj_id = $_[2] // ""; + my $year = $_[3] // LDAP::get_year(); + my $tag = "project,$proj_id,$year"; + qx(git tag -f $tag); + if (! $?) { + log INFO, "Tag long créé : $tag."; + } } } else From 85008adfdf103f3b4c96e7cd2f02f7c9100b4152 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 15 Sep 2013 12:42:05 +0200 Subject: [PATCH 019/364] Remove full tag when requested --- hooks/subjects.pl | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index 0d36a26..c9c2bab 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -122,6 +122,14 @@ sub tag_project $year = LDAP::get_year; } + # Determine full tag + my $long_tag; + if (!$_[3]) + { + my $proj_id = $_[2] // ""; + $long_tag = "project,$proj_id,$year"; + } + if ($creation) { my $newref = $ARGV[2]; @@ -189,21 +197,31 @@ sub tag_project log DONE, "Projet créé/mis à jour avec succès."; - # Add full tag - if (!$_[3]) + if ($long_tag) { - my $proj_id = $_[2] // ""; - my $year = $_[3] // LDAP::get_year(); - my $tag = "project,$proj_id,$year"; - qx(git tag -f $tag); + qx(git tag -f $long_tag); if (! $?) { - log INFO, "Tag long créé : $tag."; + log INFO, "Tag long créé : $long_tag."; } } } else { + # Is the long tag existing + qx(git tag | egrep "^$long_tag$"); + if ($?) { + log ERROR, "Tag long correspondant introuvable : $long_tag."; + } + log USAGE, "Suppression du projet !"; + + if ($long_tag) + { + qx(git tag -d $long_tag); + if (! $?) { + log INFO, "Tag long supprimé : $long_tag."; + } + } } } From 01e0f10c381caf9350ab5649e6d83af07319bde5 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 15 Sep 2013 12:43:25 +0200 Subject: [PATCH 020/364] Fix unterminated quoted string --- hooks/subjects.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index c9c2bab..a94380e 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -208,7 +208,7 @@ sub tag_project else { # Is the long tag existing - qx(git tag | egrep "^$long_tag$"); + qx(git tag | egrep "^$long_tag\$"); if ($?) { log ERROR, "Tag long correspondant introuvable : $long_tag."; } From 639c73a4cf52d7cb4b5eb59189d94ef44b96c774 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 15 Sep 2013 12:52:20 +0200 Subject: [PATCH 021/364] New deployment script --- Makefile | 3 +-- process/launch.sh | 26 ++++++++++++++++---------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index cb888a7..4131e7d 100644 --- a/Makefile +++ b/Makefile @@ -7,10 +7,9 @@ PROVER=prove -f RM=rm TESTDIR=t SHELL=/bin/sh -SU=/bin/su launch: - $(SU) -s /bin/sh -c "$(SHELL) process/launch.sh" intradmin + $(SHELL) ./process/launch.sh install: $(SHELL) commands/first-install.sh diff --git a/process/launch.sh b/process/launch.sh index e04a4bc..65ca9df 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -5,8 +5,14 @@ cd $(dirname "$0") GREP='/bin/egrep' SCREEN='/usr/bin/screen' SED='/bin/sed -E' +SU='/bin/su -s /bin/sh' PERL='/usr/bin/env perl' +launch_screen() +{ + $SU -c "$SCREEN -S '$1' -d -m bash -c '$2'" intradmin +} + if [ -z "$1" ] then HOSTNAME=`/bin/hostname` @@ -15,34 +21,34 @@ else fi # Kill old liblersorf screen sessions -$SCREEN -ls | $GREP '[0-9]+\.lerdorf_[a-zA-Z0-9_-]+' | +$SU -c "$SCREEN -ls" intradmin | $GREP '[0-9]+\.lerdorf_[a-zA-Z0-9_-]+' | while read LINE do SNAME=`echo $LINE | $SED "s/^[^0-9]*([0-9]+\.[^ \t]+).*$/\1/"` - $SCREEN -S "$SNAME" -X kill + $SU -c "$SCREEN -S \"$SNAME\" -X kill" intradmin done case $HOSTNAME in cpp) - $SCREEN -S lerdorf_process_ldap_sync_ssh_keys_forge -d -m bash -c "while true; do $PERL process/ldap/sync_ssh_keys_forge.pl; done" + launch_screen "lerdorf_process_ldap_sync_ssh_keys_forge" "while true; do $PERL process/ldap/sync_ssh_keys_forge.pl; done" ;; hamano) - $SCREEN -S lerdorf_process_ldap_sync_ssh_keys_git -d -m bash -c "while true; do $PERL process/ldap/sync_ssh_keys_git.pl; done" + launch_screen "lerdorf_process_ldap_sync_ssh_keys_git" "while true; do $PERL process/ldap/sync_ssh_keys_git.pl; done" ;; moore) - $SCREEN -S lerdorf_process_ldap_check_ssh_key -d -m bash -c "while true; do $PERL process/ldap/check_ssh_key.pl; done" - $SCREEN -S lerdorf_process_ldap_sync_ssh_keys -d -m bash -c "while true; do $PERL process/ldap/sync_ssh_keys.pl; done" - $SCREEN -S lerdorf_process_ldap_update_group -d -m bash -c "while true; do $PERL process/ldap/update_group.pl; done" - $SCREEN -S lerdorf_process_ldap_update_user -d -m bash -c "while true; do $PERL process/ldap/update_user.pl; done" + launch_screen "lerdorf_process_ldap_check_ssh_key" "while true; do $PERL process/ldap/check_ssh_key.pl; done" + launch_screen "lerdorf_process_ldap_sync_ssh_keys" "while true; do $PERL process/ldap/sync_ssh_keys.pl; done" + launch_screen "lerdorf_process_ldap_update_group" "while true; do $PERL process/ldap/update_group.pl; done" + launch_screen "lerdorf_process_ldap_update_user" "while true; do $PERL process/ldap/update_user.pl; done" - $SCREEN -S lerdorf_process_files_intradata_get -d -m bash -c "while true; do $PERL process/files/intradata_get.pl; done" + launch_screen "lerdorf_process_files_intradata_get" "while true; do $PERL process/files/intradata_get.pl; done" ;; noyce) - $SCREEN -S lerdorf_process_files_intradata_get -d -m bash -c "while true; do $PERL process/files/intradata_get.pl; done" + launch_screen "lerdorf_process_files_intradata_get" "while true; do $PERL process/files/intradata_get.pl; done" ;; *) From 59d27b9575204ae07e58bc03ca65ecc5ce230375 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 15 Sep 2013 13:22:47 +0200 Subject: [PATCH 022/364] Start VCS/Git.pm --- ACU/VCS/Git.pm | 307 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 307 insertions(+) create mode 100644 ACU/VCS/Git.pm diff --git a/ACU/VCS/Git.pm b/ACU/VCS/Git.pm new file mode 100644 index 0000000..4426083 --- /dev/null +++ b/ACU/VCS/Git.pm @@ -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; From 34b72a4f4eb522db9d1578af13c70c6e2e41dd07 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 15 Sep 2013 13:23:04 +0200 Subject: [PATCH 023/364] Deployment script ok --- process/launch.sh | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/process/launch.sh b/process/launch.sh index 65ca9df..a8fa970 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -10,9 +10,30 @@ PERL='/usr/bin/env perl' launch_screen() { + CMD=$2 + if [ -n "$3" ] && [ -f "$3" ] + then + CMD="source $3; $CMD" + fi + $SU -c "$SCREEN -S '$1' -d -m bash -c '$2'" intradmin } +ask_ssh_key() +{ + TMP=`mktemp` + ssh-agent > "$TMP" + . "$TMP" > /dev/null + chown intradmin "$TMP" + if ssh-add "$1" + then + chown intradmin "$SSH_AUTH_SOCK" + chown intradmin `dirname "$SSH_AUTH_SOCK"` + + echo "$TMP" + fi +} + if [ -z "$1" ] then HOSTNAME=`/bin/hostname` @@ -31,24 +52,24 @@ done case $HOSTNAME in cpp) - launch_screen "lerdorf_process_ldap_sync_ssh_keys_forge" "while true; do $PERL process/ldap/sync_ssh_keys_forge.pl; done" + launch_screen "lerdorf_process_ldap_sync_ssh_keys_forge" "while true; do $PERL ~/liblerdorf/process/ldap/sync_ssh_keys_forge.pl; done" `ask_ssh_key "$HOME/.ssh/git"` ;; hamano) - launch_screen "lerdorf_process_ldap_sync_ssh_keys_git" "while true; do $PERL process/ldap/sync_ssh_keys_git.pl; done" + launch_screen "lerdorf_process_ldap_sync_ssh_keys_git" "while true; do $PERL ~/liblerdorf/process/ldap/sync_ssh_keys_git.pl; done" `ask_ssh_key "$HOME/.ssh/git"` ;; moore) - launch_screen "lerdorf_process_ldap_check_ssh_key" "while true; do $PERL process/ldap/check_ssh_key.pl; done" - launch_screen "lerdorf_process_ldap_sync_ssh_keys" "while true; do $PERL process/ldap/sync_ssh_keys.pl; done" - launch_screen "lerdorf_process_ldap_update_group" "while true; do $PERL process/ldap/update_group.pl; done" - launch_screen "lerdorf_process_ldap_update_user" "while true; do $PERL process/ldap/update_user.pl; done" + launch_screen "lerdorf_process_ldap_check_ssh_key" "while true; do $PERL ~/liblerdorf/process/ldap/check_ssh_key.pl; done" + launch_screen "lerdorf_process_ldap_sync_ssh_keys" "while true; do $PERL ~/liblerdorf/process/ldap/sync_ssh_keys.pl; done" + launch_screen "lerdorf_process_ldap_update_group" "while true; do $PERL ~/liblerdorf/process/ldap/update_group.pl; done" + launch_screen "lerdorf_process_ldap_update_user" "while true; do $PERL ~/liblerdorf/process/ldap/update_user.pl; done" - launch_screen "lerdorf_process_files_intradata_get" "while true; do $PERL process/files/intradata_get.pl; done" + launch_screen "lerdorf_process_files_intradata_get" "while true; do $PERL ~/liblerdorf/process/files/intradata_get.pl; done" ;; noyce) - launch_screen "lerdorf_process_files_intradata_get" "while true; do $PERL process/files/intradata_get.pl; done" + launch_screen "lerdorf_process_files_intradata_get" "while true; do $PERL ~/liblerdorf/process/files/intradata_get.pl; done" ;; *) From 2a79cf1e6a82d877448941ce5932bd4401892bfe Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 15 Sep 2013 14:39:56 +0200 Subject: [PATCH 024/364] Ready for deployement --- ACU/LDAP.pm | 2 +- process/launch.sh | 28 +++++++++------------------- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/ACU/LDAP.pm b/ACU/LDAP.pm index d9ecf3d..cbda989 100644 --- a/ACU/LDAP.pm +++ b/ACU/LDAP.pm @@ -21,7 +21,7 @@ my $bindsecret = ""; sub ldap_get_password { - return Password::get_password "/home/2014/mercie_d/.secret_ldap"; + return Password::get_password "/home/intradmin/.secret_ldap"; } our $secret_search = \&ldap_get_password; diff --git a/process/launch.sh b/process/launch.sh index a8fa970..64ee951 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -13,25 +13,15 @@ launch_screen() CMD=$2 if [ -n "$3" ] && [ -f "$3" ] then - CMD="source $3; $CMD" + TMP=`$SU -c 'mktemp' intradmin` + $SU -c "ssh-agent" intradmin > "$TMP" + $SU -c ". $TMP; ssh-add '$3'" intradmin + CMD=". $TMP; ssh-add -l; echo; $CMD" fi - $SU -c "$SCREEN -S '$1' -d -m bash -c '$2'" intradmin -} - -ask_ssh_key() -{ - TMP=`mktemp` - ssh-agent > "$TMP" - . "$TMP" > /dev/null - chown intradmin "$TMP" - if ssh-add "$1" - then - chown intradmin "$SSH_AUTH_SOCK" - chown intradmin `dirname "$SSH_AUTH_SOCK"` - - echo "$TMP" - fi + $SU -c "$SCREEN -S '$1' -d -m bash -c '$CMD'" intradmin + sleep 1 + /bin/rm "$TMP" } if [ -z "$1" ] @@ -52,11 +42,11 @@ done case $HOSTNAME in cpp) - launch_screen "lerdorf_process_ldap_sync_ssh_keys_forge" "while true; do $PERL ~/liblerdorf/process/ldap/sync_ssh_keys_forge.pl; done" `ask_ssh_key "$HOME/.ssh/git"` + launch_screen "lerdorf_process_ldap_sync_ssh_keys_forge" "while true; do $PERL ~/liblerdorf/process/ldap/sync_ssh_keys_forge.pl; done" ~intradmin/.ssh/git ;; hamano) - launch_screen "lerdorf_process_ldap_sync_ssh_keys_git" "while true; do $PERL ~/liblerdorf/process/ldap/sync_ssh_keys_git.pl; done" `ask_ssh_key "$HOME/.ssh/git"` + launch_screen "lerdorf_process_ldap_sync_ssh_keys_git" "while true; do $PERL ~/liblerdorf/process/ldap/sync_ssh_keys_git.pl; done" ~intradmin/.ssh/git ;; moore) From 01e723db5e8674e6a4edd88ab88f0f5214a84ab4 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 15 Sep 2013 14:48:42 +0200 Subject: [PATCH 025/364] Add new dependancy --- commands/first-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/first-install.sh b/commands/first-install.sh index 52a3045..0e598f1 100755 --- a/commands/first-install.sh +++ b/commands/first-install.sh @@ -1,7 +1,7 @@ #! /bin/bash # Install missing packets -PACKAGES_LIST="libnet-ldap-perl libxml-libxml-perl" +PACKAGES_LIST="libnet-ldap-perl libxml-libxml-perl libgearman-client-perl" if ! whereis dpkg > /dev/null 2> /dev/null then From 5aecf8b8b1160ffc9b3d98238e3e71de56930d9a Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 15 Sep 2013 14:51:25 +0200 Subject: [PATCH 026/364] Add a command to generate pass --- commands/gen_pass.pl | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 commands/gen_pass.pl diff --git a/commands/gen_pass.pl b/commands/gen_pass.pl new file mode 100644 index 0000000..ed099d3 --- /dev/null +++ b/commands/gen_pass.pl @@ -0,0 +1,14 @@ +#! /usr/bin/env perl + +use v5.10.1; +use strict; +use warnings; +use Pod::Usage; + +BEGIN { + push @INC, "../"; +} + +use ACU::Password; + +say Password::gen_password($ARGV[0], $ARGV[1]); From 0001a466862c123d23fc177a0d15a4cdfbcbbcb6 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 15 Sep 2013 14:54:36 +0200 Subject: [PATCH 027/364] Fix rm of an unexisting file --- process/launch.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/process/launch.sh b/process/launch.sh index 64ee951..cb127cd 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -20,8 +20,12 @@ launch_screen() fi $SU -c "$SCREEN -S '$1' -d -m bash -c '$CMD'" intradmin - sleep 1 - /bin/rm "$TMP" + + if [ -f "$TMP" ] + then + sleep 1 + /bin/rm "$TMP" + fi } if [ -z "$1" ] From 7b2a4185c9fb558440636db36ed95d8677dae1ee Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 15 Sep 2013 15:27:05 +0200 Subject: [PATCH 028/364] New script to manage servers --- commands/first-install.sh | 2 +- commands/manage-server.sh | 26 +++++++++++++ process/launch.sh | 82 +++++++++++++++++++++++---------------- 3 files changed, 75 insertions(+), 35 deletions(-) create mode 100644 commands/manage-server.sh diff --git a/commands/first-install.sh b/commands/first-install.sh index 0e598f1..4b16021 100755 --- a/commands/first-install.sh +++ b/commands/first-install.sh @@ -1,7 +1,7 @@ #! /bin/bash # Install missing packets -PACKAGES_LIST="libnet-ldap-perl libxml-libxml-perl libgearman-client-perl" +PACKAGES_LIST="libnet-ldap-perl libxml-libxml-perl libgearman-client-perl libmailtools-perl libmail-sendmail-perl" if ! whereis dpkg > /dev/null 2> /dev/null then diff --git a/commands/manage-server.sh b/commands/manage-server.sh new file mode 100644 index 0000000..66bbe72 --- /dev/null +++ b/commands/manage-server.sh @@ -0,0 +1,26 @@ +#! /bin/sh + +cd $(dirname "$0") + +SRV_LIST="moore noyce hamano cpp" + +ACTIONS="start stop restart" + +for ACT in $ACTIONS +do + if [ -n "$1" ] && [ "$1" == "$ACT" ] + then + ACTION="$ACT" + break + fi +done + +if [ -z "$ACTION" ] +then + echo "Usage: $0 [$ACTIONS]" +fi + +for SRV in $SRV_LIST +do + ssh root@$SRV ~/liblerdorf/process/launch.sh "$ACTION" +done \ No newline at end of file diff --git a/process/launch.sh b/process/launch.sh index cb127cd..e585a81 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -30,44 +30,58 @@ launch_screen() if [ -z "$1" ] then - HOSTNAME=`/bin/hostname` + ACTION="restart" else - HOSTNAME="$1" + ACTION="$1" fi -# Kill old liblersorf screen sessions -$SU -c "$SCREEN -ls" intradmin | $GREP '[0-9]+\.lerdorf_[a-zA-Z0-9_-]+' | -while read LINE -do - SNAME=`echo $LINE | $SED "s/^[^0-9]*([0-9]+\.[^ \t]+).*$/\1/"` - $SU -c "$SCREEN -S \"$SNAME\" -X kill" intradmin -done +if [ -z "$2" ] +then + HOSTNAME=`/bin/hostname` +else + HOSTNAME="$2" +fi -case $HOSTNAME in +if [ "$ACTION" == "stop" ] || [ "$ACTION" == "restart" ] +then + # Kill old liblersorf screen sessions + $SU -c "$SCREEN -ls" intradmin | $GREP '[0-9]+\.lerdorf_[a-zA-Z0-9_-]+' | + while read LINE + do + SNAME=`echo $LINE | $SED "s/^[^0-9]*([0-9]+\.[^ \t]+).*$/\1/"` + $SU -c "$SCREEN -S \"$SNAME\" -X kill" intradmin + done +fi - cpp) - launch_screen "lerdorf_process_ldap_sync_ssh_keys_forge" "while true; do $PERL ~/liblerdorf/process/ldap/sync_ssh_keys_forge.pl; done" ~intradmin/.ssh/git - ;; - hamano) - launch_screen "lerdorf_process_ldap_sync_ssh_keys_git" "while true; do $PERL ~/liblerdorf/process/ldap/sync_ssh_keys_git.pl; done" ~intradmin/.ssh/git - ;; +if [ "$ACTION" == "start" ] || [ "$ACTION" == "restart" ] +then + case $HOSTNAME in - moore) - launch_screen "lerdorf_process_ldap_check_ssh_key" "while true; do $PERL ~/liblerdorf/process/ldap/check_ssh_key.pl; done" - launch_screen "lerdorf_process_ldap_sync_ssh_keys" "while true; do $PERL ~/liblerdorf/process/ldap/sync_ssh_keys.pl; done" - launch_screen "lerdorf_process_ldap_update_group" "while true; do $PERL ~/liblerdorf/process/ldap/update_group.pl; done" - launch_screen "lerdorf_process_ldap_update_user" "while true; do $PERL ~/liblerdorf/process/ldap/update_user.pl; done" - - launch_screen "lerdorf_process_files_intradata_get" "while true; do $PERL ~/liblerdorf/process/files/intradata_get.pl; done" - ;; - - noyce) - launch_screen "lerdorf_process_files_intradata_get" "while true; do $PERL ~/liblerdorf/process/files/intradata_get.pl; done" - ;; - - *) - echo "No process to launch for $HOSTNAME" >&2 - exit 1 - ;; -esac \ No newline at end of file + cpp) + launch_screen "lerdorf_process_ldap_sync_ssh_keys_forge" "while true; do $PERL ~/liblerdorf/process/ldap/sync_ssh_keys_forge.pl; done" ~intradmin/.ssh/git + ;; + + hamano) + launch_screen "lerdorf_process_ldap_sync_ssh_keys_git" "while true; do $PERL ~/liblerdorf/process/ldap/sync_ssh_keys_git.pl; done" ~intradmin/.ssh/git + ;; + + moore) + launch_screen "lerdorf_process_ldap_check_ssh_key" "while true; do $PERL ~/liblerdorf/process/ldap/check_ssh_key.pl; done" + launch_screen "lerdorf_process_ldap_sync_ssh_keys" "while true; do $PERL ~/liblerdorf/process/ldap/sync_ssh_keys.pl; done" + launch_screen "lerdorf_process_ldap_update_group" "while true; do $PERL ~/liblerdorf/process/ldap/update_group.pl; done" + launch_screen "lerdorf_process_ldap_update_user" "while true; do $PERL ~/liblerdorf/process/ldap/update_user.pl; done" + + launch_screen "lerdorf_process_files_intradata_get" "while true; do $PERL ~/liblerdorf/process/files/intradata_get.pl; done" + ;; + + noyce) + launch_screen "lerdorf_process_files_intradata_get" "while true; do $PERL ~/liblerdorf/process/files/intradata_get.pl; done" + ;; + + *) + echo "No process to launch for $HOSTNAME" >&2 + exit 1 + ;; + esac +fi From e44db62e10ae877a817bfcc8e16529bcbe85f0a2 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 15 Sep 2013 15:40:09 +0200 Subject: [PATCH 029/364] New arg to update all servers --- commands/manage-server.sh | 30 ++++++++++++++++++++++++++---- process/launch.sh | 4 ++-- 2 files changed, 28 insertions(+), 6 deletions(-) mode change 100644 => 100755 commands/manage-server.sh diff --git a/commands/manage-server.sh b/commands/manage-server.sh old mode 100644 new mode 100755 index 66bbe72..1fc889f --- a/commands/manage-server.sh +++ b/commands/manage-server.sh @@ -1,10 +1,12 @@ -#! /bin/sh +#! /bin/bash cd $(dirname "$0") SRV_LIST="moore noyce hamano cpp" -ACTIONS="start stop restart" +ACTIONS="start stop restart update" + +LOG=`mktemp` for ACT in $ACTIONS do @@ -20,7 +22,27 @@ then echo "Usage: $0 [$ACTIONS]" fi +FAIL=0 for SRV in $SRV_LIST do - ssh root@$SRV ~/liblerdorf/process/launch.sh "$ACTION" -done \ No newline at end of file + if [ "$ACTION" == "update" ] + then + ssh root@$SRV "make -C liblerdorf update upgrade" + else + ssh root@$SRV '~'/liblerdorf/process/launch.sh "$ACTION" + fi + + if [ $? -eq 0 ] + then + echo -e "\e[1;32m>>>\e[0m $ACTION success on $SRV" | tee -a "$LOG" + else + echo -e "\e[1;31m>>>\e[0m $ACTION fails on $SRV" | tee -a "$LOG" + FAIL=1 + fi +done + +echo + +cat "$LOG" + +exit $FAIL \ No newline at end of file diff --git a/process/launch.sh b/process/launch.sh index e585a81..e3a212a 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -42,7 +42,7 @@ else HOSTNAME="$2" fi -if [ "$ACTION" == "stop" ] || [ "$ACTION" == "restart" ] +if [ "$ACTION" = "stop" ] || [ "$ACTION" = "restart" ] then # Kill old liblersorf screen sessions $SU -c "$SCREEN -ls" intradmin | $GREP '[0-9]+\.lerdorf_[a-zA-Z0-9_-]+' | @@ -54,7 +54,7 @@ then fi -if [ "$ACTION" == "start" ] || [ "$ACTION" == "restart" ] +if [ "$ACTION" = "start" ] || [ "$ACTION" = "restart" ] then case $HOSTNAME in From 0d88ff8eb60cbb61eb5f625435f86f3f25229a64 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 15 Sep 2013 15:44:47 +0200 Subject: [PATCH 030/364] Use basename instead of full path name --- commands/manage-server.sh | 4 ++-- process/ldap/update_group.pl | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/commands/manage-server.sh b/commands/manage-server.sh index 1fc889f..30e0320 100755 --- a/commands/manage-server.sh +++ b/commands/manage-server.sh @@ -25,6 +25,7 @@ fi FAIL=0 for SRV in $SRV_LIST do + echo -e "\e[1;33m>>>\e[0m $ACTION on $SRV" | tee -a "$LOG" if [ "$ACTION" == "update" ] then ssh root@$SRV "make -C liblerdorf update upgrade" @@ -39,10 +40,9 @@ do echo -e "\e[1;31m>>>\e[0m $ACTION fails on $SRV" | tee -a "$LOG" FAIL=1 fi + echo done -echo - cat "$LOG" exit $FAIL \ No newline at end of file diff --git a/process/ldap/update_group.pl b/process/ldap/update_group.pl index c537e6f..01bdb1b 100644 --- a/process/ldap/update_group.pl +++ b/process/ldap/update_group.pl @@ -3,6 +3,7 @@ use v5.10.1; use strict; use warnings; +use File::Basename; use Mail::Internet; use Pod::Usage; @@ -293,11 +294,11 @@ sub process_user return "Ok"; } -if ($0 =~ /^update_group/) { +if (basename($0) =~ /^update_group/) { $_get_type = \&group_get_type; Process::register("update_group", \&process_group); } -elsif ($0 =~ /^update_user/) { +elsif (basename($0) =~ /^update_user/) { $_get_type = \&user_get_type; Process::register("update_user", \&process_user); } From 62550a59afccea67678f6d43835efe8eb61dbefe Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 15 Sep 2013 16:32:51 +0200 Subject: [PATCH 031/364] Remove intradata_get from moore --- commands/manage-server.sh | 2 +- process/launch.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/commands/manage-server.sh b/commands/manage-server.sh index 30e0320..900b465 100755 --- a/commands/manage-server.sh +++ b/commands/manage-server.sh @@ -25,7 +25,7 @@ fi FAIL=0 for SRV in $SRV_LIST do - echo -e "\e[1;33m>>>\e[0m $ACTION on $SRV" | tee -a "$LOG" + echo -e "\e[1;34m>>>\e[0m $ACTION on $SRV" if [ "$ACTION" == "update" ] then ssh root@$SRV "make -C liblerdorf update upgrade" diff --git a/process/launch.sh b/process/launch.sh index e3a212a..b96728b 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -72,7 +72,7 @@ then launch_screen "lerdorf_process_ldap_update_group" "while true; do $PERL ~/liblerdorf/process/ldap/update_group.pl; done" launch_screen "lerdorf_process_ldap_update_user" "while true; do $PERL ~/liblerdorf/process/ldap/update_user.pl; done" - launch_screen "lerdorf_process_files_intradata_get" "while true; do $PERL ~/liblerdorf/process/files/intradata_get.pl; done" + #launch_screen "lerdorf_process_files_intradata_get" "while true; do $PERL ~/liblerdorf/process/files/intradata_get.pl; done" ;; noyce) From e492b3f67e7a24b858ccd89bc50753494bae49a9 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 15 Sep 2013 17:12:48 +0200 Subject: [PATCH 032/364] Fix check_ssh_key --- process/ldap/check_ssh_key.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/ldap/check_ssh_key.pl b/process/ldap/check_ssh_key.pl index be5121e..99584a1 100644 --- a/process/ldap/check_ssh_key.pl +++ b/process/ldap/check_ssh_key.pl @@ -18,7 +18,7 @@ sub check_key($) { my $filename = shift; # Call ssh-keygen - if (`ssh-keygen -l -f $filename 2> /dev/null` =~ /^([0-9]+) [0-9a-f:]+ [a-zA-Z0-9\/_-]+ \(([A-Z]+)\)$/) + if (`ssh-keygen -l -f $filename 2> /dev/null` =~ /^([0-9]+) +[0-9a-f:]+ +.+ +\(([A-Z]+)\)$/) { log INFO, "Receive valid key: type $2, size $1"; if ($2 eq "RSA") { From b47dc439fae2f4d9a5563e69b3d9b46c4fdb391c Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 15 Sep 2013 17:49:05 +0200 Subject: [PATCH 033/364] Recognize lowercase request --- process/ldap/update_group.pl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/process/ldap/update_group.pl b/process/ldap/update_group.pl index 01bdb1b..efb515b 100644 --- a/process/ldap/update_group.pl +++ b/process/ldap/update_group.pl @@ -127,13 +127,18 @@ sub user_update($$) LDAP::update_attribute($ldap, $dn, "l", $args->{param}{l}) if ($args->{param}{l}); LDAP::update_attribute($ldap, $dn, "mail", $args->{param}{mail}) if ($args->{param}{mail}); LDAP::update_attribute($ldap, $dn, "postalAddress", $args->{param}{postalAddress}) if ($args->{param}{postalAddress}); + LDAP::update_attribute($ldap, $dn, "postalAddress", $args->{param}{postaladdress}) if ($args->{param}{postaladdress}); LDAP::update_attribute($ldap, $dn, "postalCode", $args->{param}{postalCode}) if ($args->{param}{postalCode}); + LDAP::update_attribute($ldap, $dn, "postalCode", $args->{param}{postalcode}) if ($args->{param}{postalcode}); LDAP::update_attribute($ldap, $dn, "sn", $args->{param}{sn}) if ($args->{param}{sn}); LDAP::update_attribute($ldap, $dn, "telephoneNumber", $args->{param}{telephoneNumber}) if ($args->{param}{telephoneNumber}); + LDAP::update_attribute($ldap, $dn, "telephoneNumber", $args->{param}{telephonenumber}) if ($args->{param}{telephonenumber}); LDAP::update_attribute($ldap, $dn, "strongAuthKey", $args->{param}{strongAuthKey}) if ($args->{param}{strongAuthKey}); + LDAP::update_attribute($ldap, $dn, "strongAuthKey", $args->{param}{strongauthkey}) if ($args->{param}{strongauthkey}); LDAP::update_attribute($ldap, $dn, "c", $args->{param}{c}) if ($args->{param}{c}); LDAP::update_attribute($ldap, $dn, "title", $args->{param}{title}) if ($args->{param}{title}); LDAP::update_attribute($ldap, $dn, "intraTheme", $args->{param}{intraTheme}) if ($args->{param}{intraTheme}); + LDAP::update_attribute($ldap, $dn, "intraTheme", $args->{param}{intratheme}) if ($args->{param}{intratheme}); LDAP::update_attribute($ldap, $dn, "birthdate", $args->{param}{birthdate}) if ($args->{param}{birthdate}); } From 29c9b0e694c9523151af3dcc099d1b6f6d935b39 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 15 Sep 2013 21:47:33 +0200 Subject: [PATCH 034/364] Add description to users --- process/ldap/update_group.pl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/process/ldap/update_group.pl b/process/ldap/update_group.pl index efb515b..eeb3582 100644 --- a/process/ldap/update_group.pl +++ b/process/ldap/update_group.pl @@ -233,6 +233,9 @@ sub user_get_type($) elsif ($type eq "sshkeys") { return "sshPublicKey" ; } + elsif ($type eq "descriptions") { + return "description" ; + } elsif ($type eq "userInfos") { return "userInfos" ; } From 885b0f8efbdcf39bdef32f48d17e6a0c80e6af24 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 15 Sep 2013 22:30:27 +0200 Subject: [PATCH 035/364] Write logs in file without buffering --- ACU/Log.pm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ACU/Log.pm b/ACU/Log.pm index 0ebb577..53645cc 100644 --- a/ACU/Log.pm +++ b/ACU/Log.pm @@ -46,7 +46,9 @@ sub log($@) say $log_fd strftime("%a %b %e %H:%M:%S %Y", localtime), " START new logging session "; } - if ($level <= $save_level and $log_fd) { + if ($level <= $save_level and $log_fd) + { + local $| = 1; print $log_fd strftime("%a %b %e %H:%M:%S %Y", localtime), " ", levelstr($level), " "; if ($level >= TRACE) { @@ -83,7 +85,8 @@ sub levelstr($) return "FATAL" if ($level == 1); return "ERROR" if ($level == 3 or $level == 2); - return "WARN " if ($level == 5 or $level == 4); + return "WARN " if ($level == 4); + return "DONE " if ($level == 5); return "USAGE" if ($level == 6); return "INFO " if ($level == 7); return "DEBUG" if ($level == 8); From 29c5a66d25d96b3439e4f8893717752ea2bdfec5 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 15 Sep 2013 23:47:21 +0200 Subject: [PATCH 036/364] Really do an update for user --- process/ldap/update_group.pl | 99 +++++++++++++++++++++++++++++------- 1 file changed, 81 insertions(+), 18 deletions(-) diff --git a/process/ldap/update_group.pl b/process/ldap/update_group.pl index eeb3582..3ef58f7 100644 --- a/process/ldap/update_group.pl +++ b/process/ldap/update_group.pl @@ -122,24 +122,87 @@ sub user_update($$) my $dn = shift; my $args = shift; - LDAP::update_attribute($ldap, $dn, "cn", $args->{param}{cn}) if ($args->{param}{cn}); - LDAP::update_attribute($ldap, $dn, "cn", $args->{param}{firstname}." ".$args->{param}{lastname}) if ($args->{param}{firstname} && $args->{param}{lastname}); - LDAP::update_attribute($ldap, $dn, "l", $args->{param}{l}) if ($args->{param}{l}); - LDAP::update_attribute($ldap, $dn, "mail", $args->{param}{mail}) if ($args->{param}{mail}); - LDAP::update_attribute($ldap, $dn, "postalAddress", $args->{param}{postalAddress}) if ($args->{param}{postalAddress}); - LDAP::update_attribute($ldap, $dn, "postalAddress", $args->{param}{postaladdress}) if ($args->{param}{postaladdress}); - LDAP::update_attribute($ldap, $dn, "postalCode", $args->{param}{postalCode}) if ($args->{param}{postalCode}); - LDAP::update_attribute($ldap, $dn, "postalCode", $args->{param}{postalcode}) if ($args->{param}{postalcode}); - LDAP::update_attribute($ldap, $dn, "sn", $args->{param}{sn}) if ($args->{param}{sn}); - LDAP::update_attribute($ldap, $dn, "telephoneNumber", $args->{param}{telephoneNumber}) if ($args->{param}{telephoneNumber}); - LDAP::update_attribute($ldap, $dn, "telephoneNumber", $args->{param}{telephonenumber}) if ($args->{param}{telephonenumber}); - LDAP::update_attribute($ldap, $dn, "strongAuthKey", $args->{param}{strongAuthKey}) if ($args->{param}{strongAuthKey}); - LDAP::update_attribute($ldap, $dn, "strongAuthKey", $args->{param}{strongauthkey}) if ($args->{param}{strongauthkey}); - LDAP::update_attribute($ldap, $dn, "c", $args->{param}{c}) if ($args->{param}{c}); - LDAP::update_attribute($ldap, $dn, "title", $args->{param}{title}) if ($args->{param}{title}); - LDAP::update_attribute($ldap, $dn, "intraTheme", $args->{param}{intraTheme}) if ($args->{param}{intraTheme}); - LDAP::update_attribute($ldap, $dn, "intraTheme", $args->{param}{intratheme}) if ($args->{param}{intratheme}); - LDAP::update_attribute($ldap, $dn, "birthdate", $args->{param}{birthdate}) if ($args->{param}{birthdate}); + if ($args->{param}{cn}) { + LDAP::update_attribute($ldap, $dn, "cn", $args->{param}{cn}); + } elsif ($args->{param}{firstname} && $args->{param}{lastname}) { + LDAP::update_attribute($ldap, $dn, "cn", $args->{param}{firstname}." ".$args->{param}{lastname}); + } + + if ($args->{param}{l}) { + LDAP::update_attribute($ldap, $dn, "l", $args->{param}{l}); + } else { + LDAP::delete_attribute($ldap, $dn, "l"); + } + + if ($args->{param}{mail}) { + LDAP::update_attribute($ldap, $dn, "mail", $args->{param}{mail}); + } else { + LDAP::delete_attribute($ldap, $dn, "mail"); + } + + if ($args->{param}{postalAddress}) { + LDAP::update_attribute($ldap, $dn, "postalAddress", $args->{param}{postalAddress}); + } elsif ($args->{param}{postaladdress}) { + LDAP::update_attribute($ldap, $dn, "postalAddress", $args->{param}{postaladdress}); + } else { + LDAP::delete_attribute($ldap, $dn, "postalAddress"); + } + + if ($args->{param}{postalCode}) { + LDAP::update_attribute($ldap, $dn, "postalCode", $args->{param}{postalCode}); + } elsif ($args->{param}{postalcode}) { + LDAP::update_attribute($ldap, $dn, "postalCode", $args->{param}{postalcode}); + } else { + LDAP::delete_attribute($ldap, $dn, "postalCode"); + } + + if ($args->{param}{sn}) { + LDAP::update_attribute($ldap, $dn, "sn", $args->{param}{sn}); + } else { + LDAP::delete_attribute($ldap, $dn, "sn"); + } + + if ($args->{param}{telephoneNumber}) { + LDAP::update_attribute($ldap, $dn, "telephoneNumber", $args->{param}{telephoneNumber}); + } elsif ($args->{param}{telephonenumber}) { + LDAP::update_attribute($ldap, $dn, "telephoneNumber", $args->{param}{telephonenumber}); + } else { + LDAP::delete_attribute($ldap, $dn, "telephoneNumber"); + } + + if ($args->{param}{strongAuthKey}) { + LDAP::update_attribute($ldap, $dn, "strongAuthKey", $args->{param}{strongAuthKey}); + } elsif ($args->{param}{strongauthkey}) { + LDAP::update_attribute($ldap, $dn, "strongAuthKey", $args->{param}{strongauthkey}); + } else { + LDAP::delete_attribute($ldap, $dn, "strongAuthKey"); + } + + if ($args->{param}{c}) { + LDAP::update_attribute($ldap, $dn, "c", $args->{param}{c}); + } else { + LDAP::delete_attribute($ldap, $dn, "c"); + } + + if ($args->{param}{title}) { + LDAP::update_attribute($ldap, $dn, "title", $args->{param}{title}); + } else { + LDAP::delete_attribute($ldap, $dn, "title"); + } + + if ($args->{param}{intraTheme}) { + LDAP::update_attribute($ldap, $dn, "intraTheme", $args->{param}{intraTheme}); + } elsif ($args->{param}{intratheme}) { + LDAP::update_attribute($ldap, $dn, "intraTheme", $args->{param}{intratheme}); + } else { + LDAP::delete_attribute($ldap, $dn, "intraTheme"); + } + + if ($args->{param}{birthdate}) { + LDAP::update_attribute($ldap, $dn, "birthdate", $args->{param}{birthdate}); + } else { + LDAP::delete_attribute($ldap, $dn, "birthdate"); + } } sub alert_mail($$$$@) From 0accbacdf2b67e3d578c478c2e109cb5fbd925dc Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 16 Sep 2013 00:03:40 +0200 Subject: [PATCH 037/364] Same :( --- process/ldap/update_group.pl | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/process/ldap/update_group.pl b/process/ldap/update_group.pl index 3ef58f7..efc6b84 100644 --- a/process/ldap/update_group.pl +++ b/process/ldap/update_group.pl @@ -131,13 +131,13 @@ sub user_update($$) if ($args->{param}{l}) { LDAP::update_attribute($ldap, $dn, "l", $args->{param}{l}); } else { - LDAP::delete_attribute($ldap, $dn, "l"); + LDAP::flush_attribute($ldap, $dn, "l"); } if ($args->{param}{mail}) { LDAP::update_attribute($ldap, $dn, "mail", $args->{param}{mail}); } else { - LDAP::delete_attribute($ldap, $dn, "mail"); + LDAP::flush_attribute($ldap, $dn, "mail"); } if ($args->{param}{postalAddress}) { @@ -145,7 +145,7 @@ sub user_update($$) } elsif ($args->{param}{postaladdress}) { LDAP::update_attribute($ldap, $dn, "postalAddress", $args->{param}{postaladdress}); } else { - LDAP::delete_attribute($ldap, $dn, "postalAddress"); + LDAP::flush_attribute($ldap, $dn, "postalAddress"); } if ($args->{param}{postalCode}) { @@ -153,13 +153,13 @@ sub user_update($$) } elsif ($args->{param}{postalcode}) { LDAP::update_attribute($ldap, $dn, "postalCode", $args->{param}{postalcode}); } else { - LDAP::delete_attribute($ldap, $dn, "postalCode"); + LDAP::flush_attribute($ldap, $dn, "postalCode"); } if ($args->{param}{sn}) { LDAP::update_attribute($ldap, $dn, "sn", $args->{param}{sn}); } else { - LDAP::delete_attribute($ldap, $dn, "sn"); + LDAP::flush_attribute($ldap, $dn, "sn"); } if ($args->{param}{telephoneNumber}) { @@ -167,7 +167,7 @@ sub user_update($$) } elsif ($args->{param}{telephonenumber}) { LDAP::update_attribute($ldap, $dn, "telephoneNumber", $args->{param}{telephonenumber}); } else { - LDAP::delete_attribute($ldap, $dn, "telephoneNumber"); + LDAP::flush_attribute($ldap, $dn, "telephoneNumber"); } if ($args->{param}{strongAuthKey}) { @@ -175,19 +175,19 @@ sub user_update($$) } elsif ($args->{param}{strongauthkey}) { LDAP::update_attribute($ldap, $dn, "strongAuthKey", $args->{param}{strongauthkey}); } else { - LDAP::delete_attribute($ldap, $dn, "strongAuthKey"); + LDAP::flush_attribute($ldap, $dn, "strongAuthKey"); } if ($args->{param}{c}) { LDAP::update_attribute($ldap, $dn, "c", $args->{param}{c}); } else { - LDAP::delete_attribute($ldap, $dn, "c"); + LDAP::flush_attribute($ldap, $dn, "c"); } if ($args->{param}{title}) { LDAP::update_attribute($ldap, $dn, "title", $args->{param}{title}); } else { - LDAP::delete_attribute($ldap, $dn, "title"); + LDAP::flush_attribute($ldap, $dn, "title"); } if ($args->{param}{intraTheme}) { @@ -195,13 +195,13 @@ sub user_update($$) } elsif ($args->{param}{intratheme}) { LDAP::update_attribute($ldap, $dn, "intraTheme", $args->{param}{intratheme}); } else { - LDAP::delete_attribute($ldap, $dn, "intraTheme"); + LDAP::flush_attribute($ldap, $dn, "intraTheme"); } if ($args->{param}{birthdate}) { LDAP::update_attribute($ldap, $dn, "birthdate", $args->{param}{birthdate}); } else { - LDAP::delete_attribute($ldap, $dn, "birthdate"); + LDAP::flush_attribute($ldap, $dn, "birthdate"); } } From fbef87cb09a95a3e3e6ea5a536e45a2a45a179a0 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 16 Sep 2013 00:20:26 +0200 Subject: [PATCH 038/364] Same :( --- ACU/LDAP.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ACU/LDAP.pm b/ACU/LDAP.pm index cbda989..bbee587 100644 --- a/ACU/LDAP.pm +++ b/ACU/LDAP.pm @@ -227,7 +227,7 @@ sub flush_attribute($$@) my $ldap = shift // ldap_connect(); my $dn = shift; - my $mesg = $ldap->modify($dn, delete => \@_)->code; + my $mesg = $ldap->modify($dn, delete => \@_); if ($mesg->code != 0) { log(WARN, $mesg->error); return 0; } From 9210d07fda856f02551170701a6201fce5fa0d6d Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 16 Sep 2013 04:24:27 +0200 Subject: [PATCH 039/364] Start submission hook --- ACU/API/Base.pm | 1 + ACU/API/Projects.pm | 12 ++++++++--- hooks/submissions.pl | 47 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 hooks/submissions.pl diff --git a/ACU/API/Base.pm b/ACU/API/Base.pm index f772a10..ef99cbb 100644 --- a/ACU/API/Base.pm +++ b/ACU/API/Base.pm @@ -40,6 +40,7 @@ sub parse($$) my $sax_handler; $sax_handler = ResultHandler->new($parsed) if ($mod eq "ResultHandler"); + return XML::LibXML->load_xml(string => shift) if ($mod eq "ProjectHandler"); $sax_handler = ProjectMemberHandler->new($parsed) if ($mod eq "ProjectMemberHandler"); my $parser = XML::SAX::ParserFactory->parser( Handler => $sax_handler ); diff --git a/ACU/API/Projects.pm b/ACU/API/Projects.pm index 521c127..fc54b33 100644 --- a/ACU/API/Projects.pm +++ b/ACU/API/Projects.pm @@ -35,11 +35,17 @@ sub get($;$) my $project_name = shift; my $year = shift; - my $res = API::Base::get('ProjectMemberHandler', - "projects/projects/get/$project_name.xml"); + my $url; + if ($year) { + $url = "projects/projects/get/$project_name/$year.xml"; + } else { + $url = "projects/projects/get/$project_name.xml"; + } + + my $res = API::Base::get('ProjectHandler', $url); if ($res->{result} ne '0') { - croak "Erreur durant l'ajout : " . $res->{message}; + croak "Erreur durant la récupération du projet : " . $res->{message}; } return $res; diff --git a/hooks/submissions.pl b/hooks/submissions.pl new file mode 100644 index 0000000..4abc19d --- /dev/null +++ b/hooks/submissions.pl @@ -0,0 +1,47 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use v5.10; +use Date::Manip; + +use ACU::API::Projects; +use ACU::API::Submission; +use ACU::LDAP; +use ACU::Log; +$ACU::Log::log_file = "/var/log/hooks/" . basename($0) . ".log"; +use ACU::Process; + +# First, check if the repository is in the YYYY/ directory +exit 0 if ($ENV{GL_REPO} !~ /^2[0-9]{3}\/.+\/.+/); + +my ($ref, $oldsha, $newsha) = @ARGV; + +my $promo = $1 if ($ENV{'GL_REPO'} =~ m/([0-9]{4}).*/); +my $id_project = $1 if ($ENV{'GL_REPO'} =~ m/.*\/(.*)\//); +my $repo_login = $1 if ($ENV{'GL_REPO'} =~ m/.*\/.*\/(.*)/); + +log WARN, "This is a project!"; + +if ($ref =~ m<^refs/tags/(.+)$>) +{ + my $tag = $1; + log INFO, "Pushed tag for repository $ENV{GL_REPO}: $tag"; + + # Get project informations + my $project; + eval { + $project = API::Projects::get($id_project, $promo); + }; + if ($@ or !$project) { + my $err = $@; + log TRACE, $err; + log ERROR, "Impossible d'envoyer de tags. Passer au laboratoire si le problème persiste."; + exit 1; + } + + log TRACE, $project; +} + +exit 1; +exit 0; From 7c92cd044a635cfdd6fb1afaeceeddaba25e912f Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 16 Sep 2013 04:27:37 +0200 Subject: [PATCH 040/364] New dependancy --- commands/first-install.sh | 2 +- hooks/submissions.pl | 0 2 files changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 hooks/submissions.pl diff --git a/commands/first-install.sh b/commands/first-install.sh index 4b16021..89b7812 100755 --- a/commands/first-install.sh +++ b/commands/first-install.sh @@ -1,7 +1,7 @@ #! /bin/bash # Install missing packets -PACKAGES_LIST="libnet-ldap-perl libxml-libxml-perl libgearman-client-perl libmailtools-perl libmail-sendmail-perl" +PACKAGES_LIST="libnet-ldap-perl libxml-libxml-perl libgearman-client-perl libmailtools-perl libmail-sendmail-perl libdate-manip-perl" if ! whereis dpkg > /dev/null 2> /dev/null then diff --git a/hooks/submissions.pl b/hooks/submissions.pl old mode 100644 new mode 100755 From 73513d2c0c73dde473c73a271ea3c094605099f8 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 16 Sep 2013 04:29:54 +0200 Subject: [PATCH 041/364] Typo in submission.pl --- hooks/submissions.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hooks/submissions.pl b/hooks/submissions.pl index 4abc19d..277c91b 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -4,6 +4,7 @@ use strict; use warnings; use v5.10; use Date::Manip; +use File::Basename; use ACU::API::Projects; use ACU::API::Submission; @@ -36,7 +37,7 @@ if ($ref =~ m<^refs/tags/(.+)$>) if ($@ or !$project) { my $err = $@; log TRACE, $err; - log ERROR, "Impossible d'envoyer de tags. Passer au laboratoire si le problème persiste."; + log ERROR, "Impossible d'envoyer de tags ; si le problème persiste, passez au laboratoire."; exit 1; } From 0e22becfb68659bad6bc174037405b7809859890 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 16 Sep 2013 04:31:41 +0200 Subject: [PATCH 042/364] Fix installation --- commands/first-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/commands/first-install.sh b/commands/first-install.sh index 89b7812..a222a7e 100755 --- a/commands/first-install.sh +++ b/commands/first-install.sh @@ -26,4 +26,11 @@ fi chown -R intradmin:intradmin /home/intradmin +# Git ? +if egrep '^git:' /etc/passwd > /dev/null +then + mkdir -p /var/log/hooks/ && + chown git /var/log/hooks/ +fi + echo "System ready!" \ No newline at end of file From 3678b130556c7608544a0804e0da89224c082b97 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 16 Sep 2013 06:43:17 +0200 Subject: [PATCH 043/364] Works on old LWP::UserAgent --- ACU/API/Base.pm | 16 ++++++++++--- ACU/LDAP.pm | 3 ++- commands/ldap/extract_students.pl | 8 ++++++- hooks/submissions.pl | 37 +++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 5 deletions(-) diff --git a/ACU/API/Base.pm b/ACU/API/Base.pm index ef99cbb..0fc698b 100644 --- a/ACU/API/Base.pm +++ b/ACU/API/Base.pm @@ -40,7 +40,11 @@ sub parse($$) my $sax_handler; $sax_handler = ResultHandler->new($parsed) if ($mod eq "ResultHandler"); - return XML::LibXML->load_xml(string => shift) if ($mod eq "ProjectHandler"); + if ($mod eq "ProjectHandler") + { + use ACU::Project; + $sax_handler = ProjectHandler->new($parsed); + } $sax_handler = ProjectMemberHandler->new($parsed) if ($mod eq "ProjectMemberHandler"); my $parser = XML::SAX::ParserFactory->parser( Handler => $sax_handler ); @@ -71,7 +75,10 @@ sub get($$) my $url = shift; my $ua = LWP::UserAgent->new; - $ua->ssl_opts(SSL_ca_file => "/etc/ldap/cacert.pem"); + # Some old version of LWP::UserAgent doesn't support ssl_opts, this is not required + eval { + $ua->ssl_opts(SSL_ca_file => "/etc/ldap/cacert.pem"); + }; log(DEBUG, 'GET Request to ', API_URL, $url); my $req = GET API_URL . $url; @@ -89,7 +96,10 @@ sub send($$$) my $url = shift; my $ua = LWP::UserAgent->new; - $ua->ssl_opts(SSL_ca_file => "/etc/ldap/cacert.pem"); + # Some old version of LWP::UserAgent doesn't support ssl_opts, this is not required + eval { + $ua->ssl_opts(SSL_ca_file => "/etc/ldap/cacert.pem"); + }; log(DEBUG, 'POST Request to ', API_URL, $url); my $req = POST API_URL . $url, shift; diff --git a/ACU/LDAP.pm b/ACU/LDAP.pm index bbee587..f2c2295 100644 --- a/ACU/LDAP.pm +++ b/ACU/LDAP.pm @@ -21,7 +21,8 @@ my $bindsecret = ""; sub ldap_get_password { - return Password::get_password "/home/intradmin/.secret_ldap"; + return Password::get_password "/home/2014/mercie_d/.secret_ldap"; +# return Password::get_password "/home/intradmin/.secret_ldap"; } our $secret_search = \&ldap_get_password; diff --git a/commands/ldap/extract_students.pl b/commands/ldap/extract_students.pl index b9966e3..9927081 100644 --- a/commands/ldap/extract_students.pl +++ b/commands/ldap/extract_students.pl @@ -21,7 +21,7 @@ sub get_students if ($#ARGV == -1) { log(USAGE, "$0 format"); - say "format can be csv" + say "format can be csv or login" } elsif ($ARGV[0] eq "csv") { @@ -35,3 +35,9 @@ elsif ($ARGV[0] eq "csv") say ",Present"; } } +elsif ($ARGV[0] eq "login") +{ + for my $student (get_students $ARGV[1]) { + say $student->get_value("uid"); + } +} diff --git a/hooks/submissions.pl b/hooks/submissions.pl index 277c91b..80e6f19 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -42,6 +42,43 @@ if ($ref =~ m<^refs/tags/(.+)$>) } log TRACE, $project; + + # Extract lot of data + my @rendus = grep { + exists $_->{vcs} and $_->{vcs}{tag} eq $tag; + } @{ $project->{submissions} }; + + my $date = $ENV{'GL_TS'}; + $date =~ s/\./ /; + my $glts = ParseDate($date); + + chomp (my $tokengiven = `git cat-file tag $newsha | sed -e '1,/^\$/d'`); + for my $rendu (@rendus) + { + my $open = ParseDate($rendu->{period}{begin}); + my $close = ParseDate($rendu->{period}{end}); + + # TODO: check exceptions by login/group + + if ((Date_Cmp($glts, $open) == -1)) + { + print "[ACU] Tag not allowed: upload not yet opened!\n"; + exit(4); + } + + if ((Date_Cmp($glts, $close) == 1)) + { + print "[ACU] Tag not allowed: upload closed!\n"; + exit(5); + } + + my $token = $rendu->{vcs}{token}; + if ($token ne "" and $token ne $tokengiven) + { + print "[ACU] Error 0x65cd58: Bad token.\n"; + exit(6); + } + } } exit 1; From 0825ca12e0cb850d1dde4dca582e42df83f99fce Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 16 Sep 2013 06:43:33 +0200 Subject: [PATCH 044/364] Parse project.xml --- ACU/Project.pm | 183 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 ACU/Project.pm diff --git a/ACU/Project.pm b/ACU/Project.pm new file mode 100644 index 0000000..1a25064 --- /dev/null +++ b/ACU/Project.pm @@ -0,0 +1,183 @@ +#! /usr/bin/env perl + +package Project; + +use v5.10.1; +use strict; +use warnings; +use Carp; +use XML::LibXML; +use XML::SAX::ParserFactory; + +use ACU::Log; + +package ProjectHandler; + +use strict; +use warnings; +use Carp; + +my @stack_tags = ( + "manager", + "submission", + "slides", + "subject", + "tutorial", +); +my @stackonce_tags = ( + "period", + + "upload", + "vcs", + + "news", + "documents", +); +my @value_tags = ( + "result", + "message", + "name", + "firstname", + "lastname", + "login", + "begin", + "end", + "date", + "tag", + "newsgroup" +); + +sub new ($$) +{ + my $class = shift; + my $self = { + parsed => shift, + saveChars => 0, + stack => [], + values => "" + }; + + bless $self, $class; + + return $self; +} + +sub start_element +{ + my ($self, $element) = @_; + + if ($element->{Name} eq "project" || $element->{Name} eq "Project") { + $self->{parsed}{name} = $element->{Attributes}{"{}name"}{Value} if ($element->{Attributes}{"{}name"}); + } + elsif (grep { /^\Q$element->{Name}\E$/ } @stack_tags) + { + my $data = {}; + + $data->{name} = $element->{Attributes}{"{}name"}{Value} if ($element->{Attributes}{"{}name"}); + $data->{type} = $element->{Attributes}{"{}type"}{Value} if ($element->{Attributes}{"{}type"}); + $data->{written_in} = $element->{Attributes}{"{}written_in"}{Value} if ($element->{Attributes}{"{}written_in"}); + + push @{ $self->{stack} }, $data; + } + elsif (grep { /^\Q$element->{Name}\E$/ } @value_tags) { + $self->{saveChars} = 1; + $self->{values} = ""; + } + elsif ($element->{Name} eq "vcs") { + push @{ $self->{stack} }, { + url => $element->{Attributes}{"{}url"}{Value}, + tag => $element->{Attributes}{"{}tag"}{Value}, + token => $element->{Attributes}{"{}token"}{Value} // 0, + quota => $element->{Attributes}{"{}quota"}{Value} // 20, + type => $element->{Attributes}{"{}type"}{Value} // "git", + }; + } + elsif ($element->{Name} eq "upload") { + push @{ $self->{stack} }, { + format => $element->{Attributes}{"{}format"}{Value}, + url => $element->{Attributes}{"{}url"}{Value}, + identifier => $element->{Attributes}{"{}identifier"}{Value}, + quota => $element->{Attributes}{"{}quota"}{Value} // 10, + }; + } + elsif (grep { /^\Q$element->{Name}\E$/ } @stackonce_tags) { + push @{ $self->{stack} }, { }; + } +} + +sub characters +{ + my ($self, $characters) = @_; + + if ($self->{saveChars}) { + $self->{values} .= $characters->{Data}; + } +} + +sub end_element +{ + my ($self, $element) = @_; + + if ($self->{saveChars}) + { + if (@{ $self->{stack} } == 0) { + $self->{parsed}{$element->{Name}} = $self->{values}; + } + else { + my $pop = pop @{ $self->{stack} }; + $pop->{$element->{Name}} = $self->{values}; + push @{ $self->{stack} }, $pop; + } + + $self->{saveChars} = 0; + } + + elsif (grep { /^\Q$element->{Name}\E$/ } @stack_tags) + { + my $item = pop @{ $self->{stack} }; + my $pop = pop @{ $self->{stack} }; + + if ($element->{Name} eq "submission") { + push @{ $self->{stack} }, $pop; + $item->{doc} = "$pop->{name}"; + $pop = undef; + } + + if ($pop) + { + if (!exists $pop->{$element->{Name}."s"}) { + $pop->{$element->{Name}."s"} = []; + } + push @{ $pop->{$element->{Name}."s"} }, $item; + push @{ $self->{stack} }, $pop; + } + else + { + if (!exists $self->{parsed}{$element->{Name}."s"}) { + $self->{parsed}{$element->{Name}."s"} = []; + } + push @{ $self->{parsed}{$element->{Name}."s"} }, $item; + } + } + + elsif (grep { /^\Q$element->{Name}\E$/ } @stackonce_tags) + { + my $item = pop @{ $self->{stack} }; + my $pop = pop @{ $self->{stack} }; + + if ($pop) + { + $pop->{$element->{Name}} = $item; + push @{ $self->{stack} }, $pop; + } + else { + $self->{parsed}{$element->{Name}} = $item; + } + } + + else { + return; + } +} + +1; From 17ea229729796fe2d59671dc9786ca97c53c7c6e Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 16 Sep 2013 07:09:23 +0200 Subject: [PATCH 045/364] Submissions Ok --- ACU/API/Submission.pm | 7 ++----- hooks/submissions.pl | 28 ++++++++++++++++++++-------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/ACU/API/Submission.pm b/ACU/API/Submission.pm index 1dd9ceb..898bef1 100644 --- a/ACU/API/Submission.pm +++ b/ACU/API/Submission.pm @@ -18,11 +18,8 @@ sub add($$$$$) my $res = API::Base::send('ResultHandler', "projects/submissions/add.xml", [ leader_login => $user, project_name => $project, year => $year, log => $log, tag => $tag ]); - if ($res->{result} == '0') { - say "Rendu ok"; - } - else { - say "Rendu non ok : retour de l'API non nul."; + if ($res->{result} != '0') { + croak "Erreur durant le rendu : ".$res->{message}; } } diff --git a/hooks/submissions.pl b/hooks/submissions.pl index 80e6f19..f1a2fd3 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -22,12 +22,10 @@ my $promo = $1 if ($ENV{'GL_REPO'} =~ m/([0-9]{4}).*/); my $id_project = $1 if ($ENV{'GL_REPO'} =~ m/.*\/(.*)\//); my $repo_login = $1 if ($ENV{'GL_REPO'} =~ m/.*\/.*\/(.*)/); -log WARN, "This is a project!"; - if ($ref =~ m<^refs/tags/(.+)$>) { my $tag = $1; - log INFO, "Pushed tag for repository $ENV{GL_REPO}: $tag"; + log DEBUG, "Pushed tag for repository $ENV{GL_REPO}: $tag"; # Get project informations my $project; @@ -52,7 +50,7 @@ if ($ref =~ m<^refs/tags/(.+)$>) $date =~ s/\./ /; my $glts = ParseDate($date); - chomp (my $tokengiven = `git cat-file tag $newsha | sed -e '1,/^\$/d'`); + chomp (my $tokengiven = `git cat-file tag $newsha 2> /dev/null | sed -e '1,/^\$/d'`); for my $rendu (@rendus) { my $open = ParseDate($rendu->{period}{begin}); @@ -60,26 +58,40 @@ if ($ref =~ m<^refs/tags/(.+)$>) # TODO: check exceptions by login/group + say "[ACU] Date courante: ", $glts; + say "[ACU] Date fermeture: ", $close; + if ((Date_Cmp($glts, $open) == -1)) { - print "[ACU] Tag not allowed: upload not yet opened!\n"; + say "[ACU] Tag not allowed: upload not yet opened!"; exit(4); } if ((Date_Cmp($glts, $close) == 1)) { - print "[ACU] Tag not allowed: upload closed!\n"; + say "[ACU] Tag not allowed: upload closed!"; exit(5); } my $token = $rendu->{vcs}{token}; if ($token ne "" and $token ne $tokengiven) { - print "[ACU] Error 0x65cd58: Bad token.\n"; + say "[ACU] Error 0x65cd58: Bad token."; exit(6); } } + + # Send data to API + my $last_commit = `git log -1 --name-status`; + eval { + API::Submission::add($promo, $id_project, $tag, $repo_login, $last_commit); + }; + if ($@) { + my $err = $@; + log DEBUG, "ERROR: ".$err; + } + + log DONE, "[ACU] UPLOAD successful, please check this information on the intranet"; } -exit 1; exit 0; From 4ced1e540ed679b3a5628d773a6a8669835046d4 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 16 Sep 2013 07:10:39 +0200 Subject: [PATCH 046/364] Add Carp to Submission API --- ACU/API/Submission.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/ACU/API/Submission.pm b/ACU/API/Submission.pm index 898bef1..fa1b182 100644 --- a/ACU/API/Submission.pm +++ b/ACU/API/Submission.pm @@ -5,6 +5,7 @@ package API::Submission; use v5.10.1; use strict; use warnings; +use Carp; use ACU::API::Base; From 4649360306ef525a7c92d769376a6749ab594f1b Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 16 Sep 2013 18:56:48 +0200 Subject: [PATCH 047/364] Use FQDN instead of relative domain in sync_ssh_keys --- hooks/submissions.pl | 15 ++++++++++++++- process/ldap/sync_ssh_keys.pl | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/hooks/submissions.pl b/hooks/submissions.pl index f1a2fd3..ad909b5 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -24,8 +24,11 @@ my $repo_login = $1 if ($ENV{'GL_REPO'} =~ m/.*\/.*\/(.*)/); if ($ref =~ m<^refs/tags/(.+)$>) { + my $ip = $1 if ($ENV{'SSH_CLIENT'} =~ m/([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*/); + say "[ACU] Your IP is: $ENV{'SSH_CLIENT'}."; + my $tag = $1; - log DEBUG, "Pushed tag for repository $ENV{GL_REPO}: $tag"; + log DEBUG, "Pushed tag for repository $ENV{GL_REPO}: $tag with IP $ENV{'SSH_CLIENT'}"; # Get project informations my $project; @@ -95,3 +98,13 @@ if ($ref =~ m<^refs/tags/(.+)$>) } exit 0; + +sub ip2long +{ + return unpack("l*", pack("l*", unpack("N*", inet_aton(shift)))); +} + +sub long2ip +{ + return inet_ntoa(pack("N*", shift)); +} diff --git a/process/ldap/sync_ssh_keys.pl b/process/ldap/sync_ssh_keys.pl index 1653feb..c67221b 100644 --- a/process/ldap/sync_ssh_keys.pl +++ b/process/ldap/sync_ssh_keys.pl @@ -109,7 +109,7 @@ if ($0 =~ /^(?:.*\/)?sync_ssh_keys_(?:([a-zA-Z0-9]+)_)?([a-zA-Z0-9]+).pl$/) { if ($service eq "git") { - $Git::git_server = $2; + $Git::git_server = $2.".acu.epita.fr"; log INFO, "Start by syncing all users key..."; From b03703bf96e50003d0c530fc72246045f322a47f Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 16 Sep 2013 18:58:36 +0200 Subject: [PATCH 048/364] Kill others ssh-agent before relaunching one --- process/launch.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/process/launch.sh b/process/launch.sh index b96728b..27c7533 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -14,6 +14,7 @@ launch_screen() if [ -n "$3" ] && [ -f "$3" ] then TMP=`$SU -c 'mktemp' intradmin` + $SU -c "killall ssh-agent" intradmin $SU -c "ssh-agent" intradmin > "$TMP" $SU -c ". $TMP; ssh-add '$3'" intradmin CMD=". $TMP; ssh-add -l; echo; $CMD" From 03470f00befc2e0d583e5615eeb5ba69a39b0be6 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 16 Sep 2013 19:00:37 +0200 Subject: [PATCH 049/364] APL get password from ~mercie_d --- ACU/LDAP.pm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ACU/LDAP.pm b/ACU/LDAP.pm index f2c2295..bd94e5f 100644 --- a/ACU/LDAP.pm +++ b/ACU/LDAP.pm @@ -21,8 +21,11 @@ my $bindsecret = ""; sub ldap_get_password { - return Password::get_password "/home/2014/mercie_d/.secret_ldap"; -# return Password::get_password "/home/intradmin/.secret_ldap"; + if (`hostname` eq "apl") { + return Password::get_password "/home/2014/mercie_d/.secret_ldap"; + } else { + return Password::get_password "/home/intradmin/.secret_ldap"; + } } our $secret_search = \&ldap_get_password; From 8e4aab39408ef5e5e5b7fe29df2c3ea9943166ab Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 18 Sep 2013 05:03:38 +0200 Subject: [PATCH 050/364] Fix tag submission --- hooks/submissions.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hooks/submissions.pl b/hooks/submissions.pl index ad909b5..0855b95 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -24,12 +24,12 @@ my $repo_login = $1 if ($ENV{'GL_REPO'} =~ m/.*\/.*\/(.*)/); if ($ref =~ m<^refs/tags/(.+)$>) { - my $ip = $1 if ($ENV{'SSH_CLIENT'} =~ m/([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*/); - say "[ACU] Your IP is: $ENV{'SSH_CLIENT'}."; - my $tag = $1; log DEBUG, "Pushed tag for repository $ENV{GL_REPO}: $tag with IP $ENV{'SSH_CLIENT'}"; + my $ip = $1 if ($ENV{'SSH_CLIENT'} =~ m/([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*/); + say "[ACU] Your IP is: $ENV{'SSH_CLIENT'}."; + # Get project informations my $project; eval { From 188931f0d42fbb67e01bf9982442521d5b6fc0ee Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 18 Sep 2013 07:54:34 +0200 Subject: [PATCH 051/364] Can gen_groups in different years --- commands/project/gen_groups.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/commands/project/gen_groups.pl b/commands/project/gen_groups.pl index c3428a4..31f7474 100644 --- a/commands/project/gen_groups.pl +++ b/commands/project/gen_groups.pl @@ -10,11 +10,11 @@ use ACU::API::Base; use ACU::API::Projects; -if ($#ARGV == 0) +if ($#ARGV == 0 or $#ARGV == 1) { - API::Projects::gen_groups($ARGV[0]); + API::Projects::gen_groups($ARGV[0], $ARGV[1]); } else { - say "$0 "; + say "$0 [year]"; } From 9038f499048d38f2cf77f5c893f997e2f9610e17 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 19 Sep 2013 04:52:29 +0200 Subject: [PATCH 052/364] Check IP before submission --- commands/first-install.sh | 60 ++++++++++++++++++++++++++++----------- commands/manage-server.sh | 13 ++++++++- hooks/submissions.pl | 16 +++++++++-- 3 files changed, 70 insertions(+), 19 deletions(-) diff --git a/commands/first-install.sh b/commands/first-install.sh index a222a7e..40b0949 100755 --- a/commands/first-install.sh +++ b/commands/first-install.sh @@ -1,30 +1,58 @@ #! /bin/bash # Install missing packets -PACKAGES_LIST="libnet-ldap-perl libxml-libxml-perl libgearman-client-perl libmailtools-perl libmail-sendmail-perl libdate-manip-perl" +DEB_PACKAGES_LIST="libnet-ldap-perl libxml-libxml-perl libgearman-client-perl libmailtools-perl libmail-sendmail-perl libdate-manip-perl" +ARCH_PACKAGES_LIST="perl-io-socket-ssl perl-email-simple perl-email-mime perl-term-readkey perl-ldap perl-lwp-protocol-https" -if ! whereis dpkg > /dev/null 2> /dev/null +if [ -f "/etc/debian_version" ] then - aptitude install dpkg -fi -for PK in $PACKAGES_LIST -do - if ! dpkg -l | grep "^ii" | grep "$PK" > /dev/null 2> /dev/null + if ! whereis dpkg > /dev/null 2> /dev/null then - aptitude install "$PK" + aptitude install dpkg fi -done + + for PK in $DEB_PACKAGES_LIST + do + if ! dpkg -l | grep "^ii" | grep "$PK" > /dev/null 2> /dev/null + then + aptitude install "$PK" + fi + done -# Add intradmin user if missing -if ! getent passwd | grep "intradmin:" > /dev/null 2> /dev/null + # Add intradmin user if missing + if ! getent passwd | grep "intradmin:" > /dev/null 2> /dev/null + then + useradd --shell /bin/false --uid 942 intradmin && + mkdir -p /home/intradmin + fi + + chown -R intradmin:intradmin /home/intradmin + +elif [ -f "/etc/arch-release" ] then - useradd --shell /bin/false --uid 942 intradmin && - mkdir -p /home/intradmin -fi -chown -R intradmin:intradmin /home/intradmin + for PK in $ARCH_PACKAGES_LIST + do + if ! pacman -Qi "$PK" > /dev/null 2> /dev/null + then + pacman -S "$PK" + fi + done + +elif [ -f "/etc/freebsd-update.conf" ] +then + + echo "TODO: FreeBSD" + exit 1; + +else + + echo "Unknown operating system :(" + exit 1; + +fi # Git ? if egrep '^git:' /etc/passwd > /dev/null @@ -33,4 +61,4 @@ then chown git /var/log/hooks/ fi -echo "System ready!" \ No newline at end of file +echo "System ready!" diff --git a/commands/manage-server.sh b/commands/manage-server.sh index 900b465..ca7b7bb 100755 --- a/commands/manage-server.sh +++ b/commands/manage-server.sh @@ -2,6 +2,7 @@ cd $(dirname "$0") +WKS_LIST="apl" SRV_LIST="moore noyce hamano cpp" ACTIONS="start stop restart update" @@ -43,6 +44,16 @@ do echo done +for WKS in $WKS_LIST +do + echo -e "\e[1;34m>>>\e[0m $ACTION on $WKS" + if [ "$ACTION" == "update" ] + then + ssh root@$SRV "make -C liblerdorf update upgrade" + fi + echo +done + cat "$LOG" -exit $FAIL \ No newline at end of file +exit $FAIL diff --git a/hooks/submissions.pl b/hooks/submissions.pl index 0855b95..e3e3280 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -28,14 +28,26 @@ if ($ref =~ m<^refs/tags/(.+)$>) log DEBUG, "Pushed tag for repository $ENV{GL_REPO}: $tag with IP $ENV{'SSH_CLIENT'}"; my $ip = $1 if ($ENV{'SSH_CLIENT'} =~ m/([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*/); - say "[ACU] Your IP is: $ENV{'SSH_CLIENT'}."; + say "[ACU] Your IP is: $ip."; + + $ip = ip2long($ip); + + my $net = ip2long("10.41.0.0"); + my $mask = ip2long("255.255.0.0"); + + if (($ip & $mask) != ($net & $mask)) + { + log ERROR, "[ACU] You are not authorized to push from this IP. This will be reported."; + exit 1; + } # Get project informations my $project; eval { $project = API::Projects::get($id_project, $promo); }; - if ($@ or !$project) { + if ($@ or !$project) + { my $err = $@; log TRACE, $err; log ERROR, "Impossible d'envoyer de tags ; si le problème persiste, passez au laboratoire."; From b470057ae70bf418c2d0eeb106ae80aa24948181 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 19 Sep 2013 04:55:22 +0200 Subject: [PATCH 053/364] Fix use Socket --- hooks/submissions.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/hooks/submissions.pl b/hooks/submissions.pl index e3e3280..0925fd0 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -5,6 +5,7 @@ use warnings; use v5.10; use Date::Manip; use File::Basename; +use Socket; use ACU::API::Projects; use ACU::API::Submission; From b5851bf5eda2490562564edb623e2f2479412d05 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 19 Sep 2013 05:02:40 +0200 Subject: [PATCH 054/364] Remove gate from authorized address space --- hooks/submissions.pl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hooks/submissions.pl b/hooks/submissions.pl index 0925fd0..94b7c9f 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -42,6 +42,15 @@ if ($ref =~ m<^refs/tags/(.+)$>) exit 1; } + $net = ip2long("10.41.253.0"); + $mask = ip2long("255.255.255.0"); + + if (($ip & $mask) == ($net & $mask)) + { + log ERROR, "[ACU] You are not authorized to push from this IP. This will be reported."; + exit 1; + } + # Get project informations my $project; eval { From 3ab8661fbfc697f575d2a74226ac6ba8f4dabeb6 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 19 Sep 2013 20:57:47 +0200 Subject: [PATCH 055/364] No more use Email::Sender::Simple --- utils/lpt | 50 ++++++++++++++++---------------------------------- 1 file changed, 16 insertions(+), 34 deletions(-) diff --git a/utils/lpt b/utils/lpt index c5309ab..d55864c 100755 --- a/utils/lpt +++ b/utils/lpt @@ -12,7 +12,6 @@ use Net::LDAP::Util qw(ldap_error_text); use Pod::Usage; use Term::ANSIColor qw(:constants); use Term::ReadKey; -use Quota; #use Cwd 'abs_path'; #use File::Basename; @@ -1403,7 +1402,8 @@ sub cmd_ssh_keys_without_passphrase_warn(@) print $entry->get_value("uid")."\n"; # create the message - use Email::MIME; + use Mail::Internet; + my $body = "Bonjour ".$entry->get_value("cn").", Un outil automatique a découvert une clé sans passphrase sur votre compte @@ -1429,23 +1429,14 @@ PS: Ce message est g -- Les roots ACU"; - my $message = Email::MIME->create( - header_str => [ - From => 'root@acu.epita.fr', - To => $entry->get_value("mailAlias"), - Cc => 'root@acu.epita.fr', - Subject => '[LAB][SSH-PASSPHRASE] Clef SSH non protégée', - ], - attributes => { - encoding => 'quoted-printable', - charset => 'UTF-8', - }, - body_str => $body, - ); - # send the message - use Email::Sender::Simple qw(sendmail); - sendmail($message); + my $email = Mail::Internet->new(); + $email->body($body); + $email->add( "To", $entry->get_value("mailAlias") ); + $email->add( "Cc", "" ); + $email->add( "From", "Roots assistants " ); + $email->add( "Subject", "[LAB][SSH-PASSPHRASE] Clef SSH non protégée" ); + $email->send(); }; cmd_ssh_keys_without_passphrase_generic(\&$process); @@ -1494,23 +1485,14 @@ PS: Ce message est g -- Les roots ACU"; - my $message = Email::MIME->create( - header_str => [ - From => 'root@acu.epita.fr', - To => $entry->get_value("aliasmail"), - Cc => 'root@acu.epita.fr', - Subject => '[LAB][SSH-PASSPHRASE] Clé SSH non protégée supprimée', - ], - attributes => { - encoding => 'quoted-printable', - charset => 'UTF-8', - }, - body_str => $body, - ); - # send the message - use Email::Sender::Simple qw(sendmail); - sendmail($message); + my $email = Mail::Internet->new(); + $email->body($body); + $email->add( "To", $entry->get_value("mailAlias") ); + $email->add( "Cc", "" ); + $email->add( "From", "Roots assistants " ); + $email->add( "Subject", "[LAB][SSH-PASSPHRASE] Clef SSH non protégée supprimée" ); + $email->send(); }; cmd_ssh_keys_without_passphrase_generic(\&$process); From 751afab04ff6a1589bbbfc911eba5c17e20feb6c Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 19 Sep 2013 21:56:57 +0200 Subject: [PATCH 056/364] If there is an error with submission API, don't ask to check on the intranet --- hooks/submissions.pl | 6 ++++-- utils/lpt | 7 +++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/hooks/submissions.pl b/hooks/submissions.pl index 94b7c9f..b51e278 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -114,9 +114,11 @@ if ($ref =~ m<^refs/tags/(.+)$>) if ($@) { my $err = $@; log DEBUG, "ERROR: ".$err; + log DONE, "[ACU] Upload successful"; + } + else { + log DONE, "[ACU] Upload successful, please check this information on the intranet"; } - - log DONE, "[ACU] UPLOAD successful, please check this information on the intranet"; } exit 0; diff --git a/utils/lpt b/utils/lpt index d55864c..1afd324 100755 --- a/utils/lpt +++ b/utils/lpt @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl use v5.10.1; use strict; @@ -17,9 +17,8 @@ use Term::ReadKey; #use File::Basename; #use File::Find; -BEGIN { - push @INC, "../"; -} +# Avoid installation of liblerdorf on workstations +use lib "/sgoinfre/root/new_intra/"; use ACU::LDAP; use ACU::Log; From bad4dd3766837c483a7fad39108653d822b69697 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 18 Sep 2013 07:53:50 +0200 Subject: [PATCH 057/364] Start defense tag hook --- hooks/subjects.pl | 66 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index a94380e..89c2c16 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -74,7 +74,73 @@ sub repository_name sub tag_defense { + my $creation = shift; + # From here, we have: + # 1: "defense" + # 2: $version + # 3: $id + # 4: $path + # 5: $year + + my $version = $_[3] // 1; + + my $project_id = repository_name(); + if ($_[3]) + { + # Check on ID/flavour_id + if ($_[3] =~ /^\d+$/) { + log ERROR, "defense:* tag can't take version. Tag format: defense:version:id:year"; + } + + $project_id .= "-" . $_[3]; + } + $project_id = lc $project_id; + $project_id =~ s/[^a-z0-9-_]/_/g; + + + my $year; + if ($_[5]) + { + # Check on year + if ($_[5] !~ /^\d+$/) { + log ERROR, "project:*:* second argument is the year. Tag format: project:id:year"; + } + + $year = $_[5]; + } + else { + $year = LDAP::get_year; + } + + if ($creation) + { + my $newref = $ARGV[2]; + + my $path; + if ($_[4]) { + $path = $_[4]; + } + else + { + + } + + log INFO, "Création/mise à jour de la soutenance..."; + + my $content = qx(git show $newref:project.xml); + # Check file exists + if ($?) { + log ERROR, "Créez un fichier project.xml à la racine du dépôt."; + } + + # Check DTD validity + if (check_xml(\$content, "http://acu.epita.fr/dtd/defense.dtd")) { + log ERROR, "Corrigez les erreurs du fichier XXX.xml avant de lancer la création du projet."; + } + + # TODO: check user permissions + } } sub tag_document From 951470b06b5db1b846057a6533e90bdc9d5e72ca Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 20 Sep 2013 02:01:39 +0200 Subject: [PATCH 058/364] Tag defense,... done --- ACU/Defense.pm | 447 +++++++++++++++++-- ACU/Grading.pm | 8 +- ACU/Trace.pm | 2 +- commands/defenses/prepare_xml.pl | 93 ++++ defenses/prepare_xml.pl | 158 ------- hooks/subjects.pl | 75 +++- {defenses => migration}/defense_converter.pl | 0 process/files/intradata_get.pl | 50 +++ 8 files changed, 601 insertions(+), 232 deletions(-) create mode 100644 commands/defenses/prepare_xml.pl delete mode 100644 defenses/prepare_xml.pl rename {defenses => migration}/defense_converter.pl (100%) diff --git a/ACU/Defense.pm b/ACU/Defense.pm index 6c941d5..386a49d 100644 --- a/ACU/Defense.pm +++ b/ACU/Defense.pm @@ -17,14 +17,16 @@ sub new ($$) { my $class = shift; my $self = { - ids => {}, + groups => [], infos => {}, comments => {}, who => {}, }; bless $self, $class; - $self->_initialize(@_); + if ($#_ >= 0) { + $self->_initialize(@_); + } return $self; } @@ -33,10 +35,63 @@ sub _initialize ($$) { my $self = shift; - my $sax_handler = DefenseHandler->new($self); - my $parser = XML::SAX::ParserFactory->parser( Handler => $sax_handler ); + my $dom = XML::LibXML->load_xml(string => shift); + $self->{groups} = $self->parseDefense($dom->documentElement()); + $self->{version} = $dom->documentElement()->getAttribute("version") // "1"; + $self->{duration} = $dom->documentElement()->getAttribute("duration") if $dom->documentElement()->hasAttribute("duration"); + $self->{type} = $dom->documentElement()->getAttribute("type") if $dom->documentElement()->hasAttribute("type"); + $self->{"strict-time"} = $dom->documentElement()->getAttribute("strict-time") if $dom->documentElement()->hasAttribute("strict-time"); + $self->{"can-correct"} = $dom->documentElement()->getAttribute("can-correct") if $dom->documentElement()->hasAttribute("can-correct"); + $self->{"operator"} = $dom->documentElement()->getAttribute("operator") if $dom->documentElement()->hasAttribute("operator"); +} - $parser->parse_file(shift); +sub parseDefense ($$) +{ + my $self = shift; + my $ret = []; + my $node = shift; + + foreach my $group ($node->childNodes()) + { + if ($group->nodeName eq "group") + { + my $g = Defense::Group->new( + $group->getAttribute("id"), + $group->getAttribute("title"), + $group->getAttribute("questions") + ); + $g->addQuestion( + $g->parseQuestions($group->getElementsByTagName("question")) + ); + push @$ret, $g; + } + } + + return $ret; +} + +sub toString ($) +{ + my $self = shift; + + my $doc = XML::LibXML::Document->new('1.0'); + + my $root = $doc->createElement("defense"); + + $root->addChild( $doc->createAttribute("version", $self->{version}) ); + $root->addChild( $doc->createAttribute("duration", $self->{duration}) ); + $root->addChild( $doc->createAttribute("type", $self->{type}) ) if ($self->{type}); + $root->addChild( $doc->createAttribute("strict-time", $self->{"strict-time"}) ) if ($self->{"strict-time"}); + $root->addChild( $doc->createAttribute("can-correct", $self->{"can-correct"}) ) if ($self->{"can-correct"}); + $root->addChild( $doc->createAttribute("operator", $self->{"operator"}) ) if ($self->{"operator"}); + + for my $group (@{ $self->{groups} }) { + $group->toString($doc, $root, $root); + } + + $doc->setDocumentElement( $root ); + + return $doc->toString(); } sub getVersion ($) @@ -48,71 +103,365 @@ sub getVersion ($) sub getIds ($) { my $self = shift; - return $self->{ids}; + + my %ids; + + for my $group (@{ $self->{groups} }) + { + $ids{ $group->{id} } = 1 if ($group->{id}); + + for my $question (@{ $group->{questions_list} }) + { + $ids{ $question->{id} } = 1 if ($question->{id}); + + for my $answer (@{ $question->{answers} }) + { + $ids{ $answer->{id} } = $answer->{value} if ($answer->{id}); + } + } + } + + return %ids; +} + +sub genIds ($) +{ + my $self = shift; + my @ids; + + my $grp_i = 0; + for my $group (@{ $self->{groups} }) + { + my $cur_gid; + if (! $group->{id} || grep { /^\Q$group->{id}\E$/ } @ids) + { + do { + $cur_gid = "defg".$grp_i; + $grp_i += 1; + } while (grep {$_ eq $cur_gid} @ids); + $group->{id} = $cur_gid; + } + else { + $grp_i += 1; + } + + my $qst_i = 0; + for my $question (@{ $group->{questions_list} }) + { + my $cur_qid; + if (! $question->{id} || grep { /^\Q$question->{id}\E$/ } @ids) + { + do { + $cur_qid = $cur_gid."q".$qst_i; + $qst_i += 1; + } while (grep {$_ eq $cur_qid} @ids); + $question->{id} = $cur_qid; + } + else { + $qst_i += 1; + } + + my $ans_i = 0; + for my $answer (@{ $question->{answers} }) + { + if (! $answer->{id} || grep { /^\Q$answer->{id}\E$/ } @ids) + { + my $cur_aid; + do { + $cur_aid = $cur_qid."a".$ans_i; + $ans_i += 1; + } while (grep {$_ eq $cur_aid} @ids); + $answer->{id} = $cur_aid; + } + else { + $ans_i += 1; + } + } + } + } } -package DefenseHandler; +package Defense::Group; +use v5.10.1; +use strict; +use warnings; use Carp; -use constant NO_ID_VALUE => "__#"; -use ACU::Log; - -sub new ($$) +sub new { my $class = shift; my $self = { - parsed => shift, - inComment => "", - inEval => "", - inInfo => "", - inValue => "", - inWho => "", - values => "" + id => shift, + title => shift, + questions => shift, + questions_list => [] }; - bless $self, $class; - - return $self; + return bless $self; } -sub start_element +sub addQuestion($@) { - my ($self, $element) = @_; + my $self = shift; - if ($element->{Name} eq "defense") { - $self->{parsed}{version} = $element->{Attributes}{"{}version"}{Value}; - $self->{parsed}{duration} = $element->{Attributes}{"{}duration"}{Value}; + push @{ $self->{questions_list} }, @_; +} + +sub parseQuestions($@) +{ + my $self = shift; + my @ret; + + for my $question (@_) + { + my $q = Defense::Question->new( + @{ $question->getElementsByTagName("ask") }[0]->textContent, + @{ $question->getElementsByTagName("explanation") }[0]->textContent // "", + $question->getAttribute("id"), + $question->getAttribute("title"), + $question->getAttribute("type"), + $question->getAttribute("difficulty"), + $question->getAttribute("weight"), + $question->getAttribute("imposed"), + $question->getAttribute("mandatory"), + $question->getAttribute("shuffled-answers") + ); + $q->addAnswer( + $q->parseAnswers($question->getElementsByTagName("answer")) + ); + $q->addInput( + $q->parseInputs($question->getElementsByTagName("input")) + ); + + push @ret, $q; } - elsif ($element->{Name} eq "question") { - if ($element->{Attributes}{"{}id"}{Value}) { - $self->{parsed}{ids}{ $element->{Attributes}{"{}id"}{Value} } = 0; - } - else { - log WARN, "Question without ID!"; - } - } - elsif ($element->{Name} eq "answer") { - if ($element->{Attributes}{"{}id"}{Value}) { - $self->{parsed}{ids}{ $element->{Attributes}{"{}id"}{Value} } = $element->{Attributes}{"{}value"}{Value} // $element->{Attributes}{"{}mark"}{Value} // 0; - } - else { - log WARN, "Answer without ID!"; - } - } - elsif ($element->{Name} ne "group" && $element->{Name} ne "ask" && $element->{Name} ne "answer" && $element->{Name} ne "explanation") { - croak "Not a valid defense XML: unknown tag ".$element->{Name}; + + return @ret; +} + +sub toString ($$$) +{ + my $self = shift; + my $doc = shift; + my $parent = shift; + + my $group = $doc->createElement("group"); + $group->addChild( $doc->createAttribute("id", $self->{id}) ); + $group->addChild( $doc->createAttribute("title", $self->{title}) ); + $group->addChild( $doc->createAttribute("questions", $self->{questions}) ) if ($self->{questions}); + $parent->appendChild($group); + + for my $item (@{ $self->{questions_list} }) { + $item->toString($doc, $group); } } -sub characters -{ - my ($self, $characters) = @_; - if ($self->{inValue} || $self->{inInfo} || $self->{inComment} || $self->{inWho}) { - $self->{values} .= $characters->{Data}; +package Defense::Question; + +use v5.10.1; +use strict; +use warnings; +use Carp; + +sub new +{ + my $class = shift; + my $self = { + ask => shift, + explanation => shift, + + id => shift, + title => shift, + type => shift, + difficulty => shift, + weight => shift, + imposed => shift, + mandatory => shift, + "shuffled-answers" => shift, + + answers => [] + }; + + return bless $self; +} + +sub addAnswer($@) +{ + my $self = shift; + + push @{ $self->{answers} }, @_; +} + +sub addInput($@) +{ + my $self = shift; + + push @{ $self->{answers} }, @_; +} + +sub parseAnswers($@) +{ + my $self = shift; + my @ret; + + for my $answer (@_) + { + my $a = Defense::Answer->new( + $answer->textContent, + $answer->getAttribute("id"), + $answer->getAttribute("value"), + $answer->getAttribute("next") + ); + + push @ret, $a; } + + return @ret; +} + +sub parseInputs($@) +{ + my $self = shift; + my @ret; + + for my $input (@_) + { + my $a = Defense::Input->new( + $input->getAttribute("label"), + $input->getAttribute("id"), + $input->getAttribute("type"), + $input->getAttribute("value"), + $input->getAttribute("maxlength"), + $input->getAttribute("pattern"), + $input->getAttribute("placeholder"), + $input->getAttribute("min"), + $input->getAttribute("max"), + $input->getAttribute("step") + ); + + push @ret, $a; + } + + return @ret; +} + +sub toString ($$$) +{ + my $self = shift; + my $doc = shift; + my $parent = shift; + + my $question = $doc->createElement("question"); + $question->addChild( $doc->createAttribute("id", $self->{id}) ); + $question->addChild( $doc->createAttribute("title", $self->{title}) ); + $question->addChild( $doc->createAttribute("type", $self->{type}) ) if ($self->{type}); + $question->addChild( $doc->createAttribute("difficulty", $self->{difficulty}) ) if ($self->{difficulty}); + $question->addChild( $doc->createAttribute("weight", $self->{weight}) ) if ($self->{weight}); + $question->addChild( $doc->createAttribute("imposed", $self->{imposed}) ) if ($self->{imposed}); + $question->addChild( $doc->createAttribute("mandatory", $self->{mandatory}) ) if ($self->{mandatory}); + $question->addChild( $doc->createAttribute("shuffled-answers", $self->{"shuffled-answers"}) ) if ($self->{"shuffled-answers"}); + $parent->appendChild($question); + + my $ask = $doc->createElement("ask"); + $ask->appendText($self->{ask}); + $question->appendChild($ask); + + for my $item (@{ $self->{answers} }) { + $item->toString($doc, $question); + } + + if ($self->{explanation}) + { + my $expl = $doc->createElement("explanation"); + $expl->appendText($self->{explanation}); + $question->appendChild($expl); + } +} + + +package Defense::Answer; + +use v5.10.1; +use strict; +use warnings; +use Carp; + +sub new +{ + my $class = shift; + my $self = { + text => shift, + + id => shift, + value => shift, + "next" => shift, + }; + + return bless $self; +} + +sub toString ($$$) +{ + my $self = shift; + my $doc = shift; + my $parent = shift; + + my $answer = $doc->createElement("answer"); + $answer->appendText($self->{text}); + $answer->addChild( $doc->createAttribute("id", $self->{id}) ); + $answer->addChild( $doc->createAttribute("value", $self->{value}) ) if ($self->{"value"}); + $answer->addChild( $doc->createAttribute("next", $self->{"next"}) ) if ($self->{"next"}); + $parent->appendChild($answer); +} + + +package Defense::Input; + +use v5.10.1; +use strict; +use warnings; +use Carp; + +sub new +{ + my $class = shift; + my $self = { + label => shift, + id => shift, + type => shift, + value => shift, + maxlength => shift, + pattern => shift, + placeholder => shift, + min => shift, + max => shift, + step => shift + }; + + return bless $self; +} + +sub toString ($$$) +{ + my $self = shift; + my $doc = shift; + my $parent = shift; + + my $answer = $doc->createElement("answer"); + $answer->addChild( $doc->createAttribute("label", $self->{label}) ); + $answer->addChild( $doc->createAttribute("id", $self->{id}) ); + $answer->addChild( $doc->createAttribute("type", $self->{type}) ) if ($self->{"type"}); + $answer->addChild( $doc->createAttribute("value", $self->{value}) ) if ($self->{"value"}); + $answer->addChild( $doc->createAttribute("maxlength", $self->{maxlength}) ) if ($self->{"maxlength"}); + $answer->addChild( $doc->createAttribute("pattern", $self->{pattern}) ) if ($self->{"pattern"}); + $answer->addChild( $doc->createAttribute("placeholder", $self->{placeholder}) ) if ($self->{"placeholder"}); + $answer->addChild( $doc->createAttribute("min", $self->{min}) ) if ($self->{"min"}); + $answer->addChild( $doc->createAttribute("max", $self->{max}) ) if ($self->{"max"}); + $answer->addChild( $doc->createAttribute("step", $self->{step}) ) if ($self->{"step"}); + $parent->appendChild($answer); } 1; diff --git a/ACU/Grading.pm b/ACU/Grading.pm index 37cd294..16aad74 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -107,13 +107,13 @@ sub insert ($$$) $self->{ids}{$_[0]} = $_[1]; } -sub fill ($$) +sub fill ($%) { my $self = shift; - my $ids = shift; + my %ids = shift; - for my $k (keys %{ $ids }) { - $self->{ids}{$k} = $ids->{$k}; + for my $k (keys %ids) { + $self->{ids}{$k} = $ids{$k}; } } diff --git a/ACU/Trace.pm b/ACU/Trace.pm index bf2b998..aaa4189 100644 --- a/ACU/Trace.pm +++ b/ACU/Trace.pm @@ -101,7 +101,7 @@ sub getValue ($$) sub getIds ($) { my $self = shift; - return $self->{ids}; + return %{ $self->{ids} }; } diff --git a/commands/defenses/prepare_xml.pl b/commands/defenses/prepare_xml.pl new file mode 100644 index 0000000..3a8a1e4 --- /dev/null +++ b/commands/defenses/prepare_xml.pl @@ -0,0 +1,93 @@ +#! /usr/bin/env perl + +use v5.10.1; +use strict; +use warnings; +use Getopt::Long; +use Pod::Usage; +use XML::LibXML; + +use lib "../"; + +use ACU::Defense; + +# Parse arguments +my $input; my $output; +my $help; my $man; +GetOptions ("output|O=s" => \$output, + "help|h|?" => \$help, + "man" => \$man, + "" => \$input) + or pod2usage(2); +pod2usage(1) if $help; +pod2usage(-exitval => 0, -verbose => 2) if $man; + +# Open defense XML file +my $xmlin; +if (defined $input || $#ARGV == -1) { + $xmlin = *STDIN; +} +else { + open $xmlin, "<", $ARGV[0] or die $!; +} + +binmode $xmlin; + +my $str; +$str .= $_ while(<$xmlin>); + +my $defense = Defense->new($str); +close $xmlin unless $xmlin eq *STDIN; + +$defense->genIds; + +# Save defense XML file +my $xmlout; +if (defined $output) { + open $xmlout, '>', $output; + binmode $xmlout; +} +else { + $xmlout = *STDOUT; +} +print {$xmlout} $defense->toString(); +close $xmlout unless $xmlout eq *STDOUT; + +__END__ + +=head1 NAME + +prepare_xml.pl - Prepare defense XML by adding id to groups, questions and answers + +=head1 SYNOPSIS + +prepare_xml.pl [options] [file] + +=head1 DESCRIPTION + +Parse the XML file given (or stdin if no file is given) and add id to groups, questions and answers that have any or duplicate id. + + Options: + -output=file.xml save prepared XML to this location + -help brief help message + -man full documentation + +=head1 OPTIONS + +=over 8 + +=item B<-output=file.xml> + +Save the prepared XML to a file instead of printing it on standard output. + +=item B<-help> + +Print a brief help message and exits. + +=item B<-man> + +Prints the manual page and exits. + +=back + +=cut diff --git a/defenses/prepare_xml.pl b/defenses/prepare_xml.pl deleted file mode 100644 index a519bd5..0000000 --- a/defenses/prepare_xml.pl +++ /dev/null @@ -1,158 +0,0 @@ -#! /usr/bin/env perl - -use v5.10.1; -use strict; -use warnings; -use Getopt::Long; -use Pod::Usage; -use XML::LibXML; - -# Extract IDs and remove duplicates -sub extract_ids (\@@) -{ - my $ids = shift @_; - - foreach my $node (@_) - { - my $att = $node->getAttribute("id"); - if (defined $att) - { - if (grep {$_ eq $att} @$ids) { - $node->removeAttribute("id"); - } - else { - push @$ids, $att; - } - } - } -} - -# Parse arguments -my $input; my $output; -my $help; my $man; -GetOptions ("output|O=s" => \$output, - "help|h|?" => \$help, - "man" => \$man, - "" => \$input) - or pod2usage(2); -pod2usage(1) if $help; -pod2usage(-exitval => 0, -verbose => 2) if $man; - -# Open defense XML file -my $xmlin; -if (defined $input || $#ARGV == -1) { - $xmlin = *STDIN; -} -else { - open $xmlin, "<", $ARGV[0] or die $!; -} - -binmode $xmlin; -my $dom = XML::LibXML->load_xml(IO => $xmlin); -close $xmlin unless $xmlin eq *STDIN; - -# First, get all existing ID and remove duplicates -my @ids; -extract_ids @ids, $dom->getElementsByTagName("group"); -extract_ids @ids, $dom->getElementsByTagName("question"); -extract_ids @ids, $dom->getElementsByTagName("answer"); - -# Then, attribute an ID to node that hasn't -my $grp_i = 0; -foreach my $group ($dom->getElementsByTagName("group")) -{ - my $cur_gid = $group->getAttribute("id"); - if (!defined $cur_gid) { - do { - $cur_gid = "defg".$grp_i; - $grp_i += 1; - } while (grep {$_ eq $cur_gid} @ids); - $group->setAttribute("id", $cur_gid); - } - else { - $grp_i += 1; - } - - my $qst_i = 0; - foreach my $question ($group->getElementsByTagName("question")) - { - my $cur_qid = $question->getAttribute("id"); - if (!defined $cur_qid) { - do { - $cur_qid = $cur_gid."q".$qst_i; - $qst_i += 1; - } while (grep {$_ eq $cur_qid} @ids); - $question->setAttribute("id", $cur_qid); - } - else { - $qst_i += 1; - } - - my $ans_i = 0; - foreach my $answer ($question->getElementsByTagName("answer")) - { - my $cur_aid = $answer->getAttribute("id"); - if (!defined $cur_aid) { - do { - $cur_aid = $cur_qid."a".$ans_i; - $ans_i += 1; - } while (grep {$_ eq $cur_aid} @ids); - $answer->setAttribute("id", $cur_aid); - } - else { - $ans_i += 1; - } - } - } -} - -# Save defense XML file -my $xmlout; -if (defined $output) { - open $xmlout, '>', $output; - binmode $xmlout; -} -else { - $xmlout = *STDOUT; -} -print {$xmlout} $dom->toString(); -close $xmlout unless $xmlout eq *STDOUT; - -__END__ - -=head1 NAME - -prepare_xml.pl - Prepare defense XML by adding id to groups, questions and answers - -=head1 SYNOPSIS - -prepare_xml.pl [options] [file] - -=head1 DESCRIPTION - -Parse the XML file given (or stdin if no file is given) and add id to groups, questions and answers that have any or duplicate id. - - Options: - -output=file.xml save prepared XML to this location - -help brief help message - -man full documentation - -=head1 OPTIONS - -=over 8 - -=item B<-output=file.xml> - -Save the prepared XML to a file instead of printing it on standard output. - -=item B<-help> - -Print a brief help message and exits. - -=item B<-man> - -Prints the manual page and exits. - -=back - -=cut diff --git a/hooks/subjects.pl b/hooks/subjects.pl index 89c2c16..3e81370 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -7,6 +7,7 @@ use Digest::SHA qw(sha1_base64); use File::Basename; use ACU::API::Projects; +use ACU::Defense; use ACU::LDAP; use ACU::Log; $ACU::Log::log_file = "/var/log/hooks/" . basename($0) . ".log"; @@ -83,7 +84,7 @@ sub tag_defense # 4: $path # 5: $year - my $version = $_[3] // 1; + my $version = $_[2] // 1; my $project_id = repository_name(); if ($_[3]) @@ -97,7 +98,37 @@ sub tag_defense } $project_id = lc $project_id; $project_id =~ s/[^a-z0-9-_]/_/g; - + + my $path; + if ($_[4]) + { + if ($_[4] =~ /(?:defenses\/)?([a-zA-Z0-9\/]+)(?:.xml)/) { + $path = "defenses/".$1.".xml"; + } else { + $path = $_[4]; + } + } + else { + # Looking for an uniq defense file in defenses/ + $path = qx(git ls-tree -r --name-only HEAD defenses/ | egrep '\.xml\$'); + my $nb_defenses = $path =~ tr/\n//; + if ($nb_defenses > 1) { + log ERROR, "Veuillez préciser le chemin de la soutenance à utiliser"; + exit 1; + } + elsif ($nb_defenses == 0) { + log ERROR, "Aucune soutenance n'a été trouvée dans le dossier defenses/"; + exit 1; + } + chomp($path); + } + + my $defense_id; + if ($_[4] =~ /(?:defenses\/)?([a-zA-Z0-9\/]+)(?:.xml)/) { + $defense_id = $1; + } else { + log ERROR, "Déplacez votre soutenance dans le dossier defenses ou simplifiez le nom du fichier."; + } my $year; if ($_[5]) @@ -117,40 +148,44 @@ sub tag_defense { my $newref = $ARGV[2]; - my $path; - if ($_[4]) { - $path = $_[4]; - } - else - { - - } - - log INFO, "Création/mise à jour de la soutenance..."; - - my $content = qx(git show $newref:project.xml); + log INFO, "Looking for $path..."; # Check file exists + my $content = qx(git show $newref:$path); if ($?) { - log ERROR, "Créez un fichier project.xml à la racine du dépôt."; + log ERROR, "Impossible de trouver la soutenance."; } # Check DTD validity if (check_xml(\$content, "http://acu.epita.fr/dtd/defense.dtd")) { - log ERROR, "Corrigez les erreurs du fichier XXX.xml avant de lancer la création du projet."; + log ERROR, "Corrigez les erreurs du fichier $path avant de publier la soutenance."; } # TODO: check user permissions + + # Generate questions and answer id + my $defense = Defense->new(\$content); + $defense->genIds(); + + # Send data to intradata + log INFO, "Attente d'un processus de publication..."; + if (my $err = Process::Client::launch("intradata_get", { action => "update", type => "defense", id => $project_id, "year" => $year, "defense_id" => $defense_id, "version" => $version }, { "$defense_id.xml" => $defense->toString() })) + { + if (${ $err } ne "Ok") { + log ERROR, "Erreur durant le processus de publication : " . ${ $err }; + } + } + } } sub tag_document { - + } sub tag_grades { - + } sub tag_project @@ -293,10 +328,10 @@ sub tag_project sub tag_ref { - + } sub tag_tests { - + } diff --git a/defenses/defense_converter.pl b/migration/defense_converter.pl similarity index 100% rename from defenses/defense_converter.pl rename to migration/defense_converter.pl diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index 9c3e8ce..7619ede 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -18,6 +18,9 @@ my %actions = ( "create" => \&update_project, "update" => \&update_project, "delete" => \&delete_project, + }, + "defense" => { + "update" => \&update_defense, } ); @@ -71,6 +74,53 @@ sub update_project return "Ok"; } +sub update_defense +{ + my $args = shift; + + my $project_id = $args->{param}{id}; + my $year = $args->{param}{year} // LDAP::get_year; + + if (! $project_id) { + log ERROR, "No project_id given."; + return "No project_id given"; + } + + my $defense_id = $args->{param}{defense_id}; + + if (! $defense_id) { + log ERROR, "No defense_id given."; + return "No defense_id given"; + } + + my $defense; + if (exists $args->{files}{"$defense_id.xml"}) { + $defense = $args->{files}{"$defense_id.xml"}; + } + if (! $defense) { + log ERROR, "Invalid $defense_id.xml received!"; + return "Invalid $defense_id.xml received!"; + } + + log INFO, "Update $year/$project_id/defenses/$defense_id.xml"; + + if (! -e "$basedir/$year/$project_id/defenses/") { + mkdir "$basedir/$year/$project_id/defenses/"; + } + if (! -e "$basedir/$year/$project_id/traces/") { + mkdir "$basedir/$year/$project_id/traces/"; + } + if (! -e "$basedir/$year/$project_id/traces/defense_$defense_id/") { + mkdir "$basedir/$year/$project_id/traces/defense_$defense_id/"; + } + + open my $out, ">", "$basedir/$year/$project_id/defenses/$defense_id.xml"; + print $out $defense; + close $out; + + return "Ok"; +} + sub delete_project { log WARN, "delete_project: not implemented." From 42a73c90312a448a62c82525e656efa059402b6a Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 20 Sep 2013 02:50:12 +0200 Subject: [PATCH 059/364] Long tag for defense --- hooks/subjects.pl | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index 3e81370..ef18267 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -87,13 +87,7 @@ sub tag_defense my $version = $_[2] // 1; my $project_id = repository_name(); - if ($_[3]) - { - # Check on ID/flavour_id - if ($_[3] =~ /^\d+$/) { - log ERROR, "defense:* tag can't take version. Tag format: defense:version:id:year"; - } - + if ($_[3]) { $project_id .= "-" . $_[3]; } $project_id = lc $project_id; @@ -144,6 +138,13 @@ sub tag_defense $year = LDAP::get_year; } + # Determine full tag + my $long_tag; + { + my $proj_id = $_[3] // ""; + $long_tag = "defense,$version,$proj_id,$path,$year"; + } + if ($creation) { my $newref = $ARGV[2]; @@ -175,6 +176,29 @@ sub tag_defense } } + if ($long_tag) + { + qx(git tag -f $long_tag); + if (! $?) { + log INFO, "Tag long créé : $long_tag."; + } + } + } + else + { + # Is the long tag existing + qx(git tag | egrep "^$long_tag\$"); + if ($?) { + log ERROR, "Tag long correspondant introuvable : $long_tag."; + } + + if ($long_tag) + { + qx(git tag -d $long_tag); + if (! $?) { + log INFO, "Tag long supprimé : $long_tag."; + } + } } } From a5fb66040bb2f4d90d0e11a14cefb3a9ae3f82d8 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 20 Sep 2013 03:35:53 +0200 Subject: [PATCH 060/364] Start moulette_get process --- hooks/subjects.pl | 107 ++++++++++++++++++++++++++++++++++ process/files/moulette_get.pl | 91 +++++++++++++++++++++++++++++ 2 files changed, 198 insertions(+) create mode 100644 process/files/moulette_get.pl diff --git a/hooks/subjects.pl b/hooks/subjects.pl index ef18267..79db388 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -163,6 +163,8 @@ sub tag_defense # TODO: check user permissions + # TODO: check presence in project.xml + # Generate questions and answer id my $defense = Defense->new(\$content); $defense->genIds(); @@ -352,7 +354,112 @@ sub tag_project sub tag_ref { + my $creation = shift; + # From here, we have: + # 1: "ref" + # 2: $id + # 3: rendu-X + # 4: $year + + my $project_id = repository_name(); + if ($_[2]) { + + # Check on ID/flavour_id + if ($_[2] =~ /^\d+$/) { + log ERROR, "ref,* tag can't take version. Tag format: ref,id,rendu,year"; + } + + $project_id .= "-" . $_[2]; + } + $project_id = lc $project_id; + $project_id =~ s/[^a-z0-9-_]/_/g; + + my $rendu; + if ($_[3]) { + $rendu = $_[3]; + } + else { + $rendu = "*"; + } + + my $year; + if ($_[4]) { + # Check on year + if ($_[4] !~ /^\d+$/) { + log ERROR, "ref,*,*,* third argument is the year. Tag format: ref,id,rendu,year"; + } + + $year = $_[4]; + } + else { + $year = LDAP::get_year; + } + + # Determine full tag + my $long_tag; + { + my $proj_id = $_[2] // ""; + $long_tag = "ref,$proj_id,$rendu,$year"; + } + + if ($creation) + { + my $newref = $ARGV[2]; + + log INFO, "Création/mise à jour de la ref..."; + + my $content = qx(git show $newref:ref/Makefile); + # Check file exists + if ($?) { + log ERROR, "Un fichier Makefile est requis pour pouvoir compiler et exécuter la ref."; + } + + log INFO, "Création de la tarball..."; + + my $archive = qx(git archive --format=tgz $newref ref/); + + # Send data to moulette + log INFO, "Attente d'un processus de compilation..."; + if (my $err = Process::Client::launch("moulette_get", { + type => "ref", + id => $project_id, + "year" => $year, + "rendu" => $rendu, + "file" => "ref_$rendu.tgz" + }, { "ref_$rendu.tgz" => $archive })) + { + if (${ $err } ne "Ok") { + log ERROR, "Erreur durant le processus de compilation : " . ${ $err }; + } + } + + if ($long_tag) + { + qx(git tag -f $long_tag); + if (! $?) { + log INFO, "Tag long créé : $long_tag."; + } + } + } + else + { + # Is the long tag existing + qx(git tag | egrep "^$long_tag\$"); + if ($?) { + log ERROR, "Tag long correspondant introuvable : $long_tag."; + } + + log USAGE, "Suppression du projet !"; + + if ($long_tag) + { + qx(git tag -d $long_tag); + if (! $?) { + log INFO, "Tag long supprimé : $long_tag."; + } + } + } } sub tag_tests diff --git a/process/files/moulette_get.pl b/process/files/moulette_get.pl new file mode 100644 index 0000000..f5d48df --- /dev/null +++ b/process/files/moulette_get.pl @@ -0,0 +1,91 @@ +#! /usr/bin/env perl + +use v5.10.1; +use strict; +use warnings; +use Pod::Usage; +use File::Temp; + +use ACU::Log; +use ACU::Process; + +my %actions = ( + "tar" => \&receive_tar, + "git" => \&receive_tar, # \&receive_git + + "tests" => \&create_testsuite, + "moulette" => \&moulette, +); + +sub receive_tar +{ + my $project_id = $args->{param}{id}; + my $year = $args->{param}{year}; + my $rendu = $args->{param}{rendu}; + my $file = $args->{param}{file}; + + if (!exists $args->{files}{$file}) { + return "No file named '$file' given". + } + + ($fh, $filename) = tempfile(SUFFIX => $file); + binmode($fh); + print $fh $args->{files}{$file}; + close $fh; + + # TODO: Call Fact for create .ff + + return "Ok" +} + +sub create_testsuite +{ + my $project_id = $args->{param}{id}; + my $year = $args->{param}{year}; + my $rendu = $args->{param}{rendu}; + my $file = $args->{param}{file}; + + ($fh, $filename) = tempfile(); + + if (!exists $args->{files}{$file}) { + return "No file named '$file' given". + } + + ($fh, $filename) = tempfile(SUFFIX => $file); + binmode($fh); + print $fh $args->{files}{$file}; + close $fh; + + # TODO: Call Fact to create testsuite + + return "Ok" +} + +sub moulette +{ + my $project_id = $args->{param}{id}; + my $year = $args->{param}{year}; + my $rendu = $args->{param}{rendu}; + my $login = $args->{param}{login}; + + # TODO: Call Fact to launch student tarball + + return "Ok" +} + + +sub process_get +{ + my ($given_args, $args) = @_; + + my $type = $args->{param}{type}; + + if (! exists $actions{$type}) { + log WARN, "Unknown type '$type'"; + return "Unknown type '$type'."; + } + + return $actions{$type}($args); +} + +Process::register("moulette_get", \&process_get); From 01b8f4327ae0a04d7cf4d71616df39ed65c4ce31 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 20 Sep 2013 03:39:10 +0200 Subject: [PATCH 061/364] Launch on ksh --- commands/first-install.sh | 4 ++-- process/launch.sh | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/commands/first-install.sh b/commands/first-install.sh index 40b0949..59e38d8 100755 --- a/commands/first-install.sh +++ b/commands/first-install.sh @@ -1,8 +1,8 @@ #! /bin/bash # Install missing packets -DEB_PACKAGES_LIST="libnet-ldap-perl libxml-libxml-perl libgearman-client-perl libmailtools-perl libmail-sendmail-perl libdate-manip-perl" -ARCH_PACKAGES_LIST="perl-io-socket-ssl perl-email-simple perl-email-mime perl-term-readkey perl-ldap perl-lwp-protocol-https" +DEB_PACKAGES_LIST="screen libnet-ldap-perl libxml-libxml-perl libgearman-client-perl libmailtools-perl libmail-sendmail-perl libdate-manip-perl" +ARCH_PACKAGES_LIST="screen perl-io-socket-ssl perl-email-simple perl-email-mime perl-term-readkey perl-ldap perl-lwp-protocol-https" if [ -f "/etc/debian_version" ] then diff --git a/process/launch.sh b/process/launch.sh index 27c7533..6c88575 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -80,6 +80,10 @@ then launch_screen "lerdorf_process_files_intradata_get" "while true; do $PERL ~/liblerdorf/process/files/intradata_get.pl; done" ;; + ksh) + launch_screen "lerdorf_process_files_moulette_get" "while true; do $PERL ~/liblerdorf/process/files/moulette_get.pl; done" + ;; + *) echo "No process to launch for $HOSTNAME" >&2 exit 1 From 78d733669f34cce0deed4f06e968a01a16af726a Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 20 Sep 2013 08:18:09 +0200 Subject: [PATCH 062/364] Preserve token between two commit --- hooks/subjects.pl | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index 79db388..cdbeab0 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -261,8 +261,6 @@ sub tag_project { my $newref = $ARGV[2]; - log INFO, "Création/mise à jour du projet..."; - my $content = qx(git show $newref:project.xml); # Check file exists if ($?) { @@ -276,6 +274,19 @@ sub tag_project # TODO: check user permissions + # Project already online? + my $project; + eval { + $project = API::Project::get($project_id, $year); + }; + + if ($project) { + log INFO, "Mise à jour du projet $project_id"; + } + else { + log INFO, "Création du projet $project_id"; + } + # Generate token for VCS submission my $dom = XML::LibXML->load_xml(string => (\$content)); my $mod = 0; @@ -283,6 +294,21 @@ sub tag_project { if (! $vcs->hasAttribute("token")) { + if ($project) + { + # Looking for an old token + my @rendus = grep { + exists $_->{vcs} and $_->{vcs}{tag} eq $tag; + } @{ $project->{submissions} }; + + if (@rendus == 1) { + log INFO, "Use existing token: ".$rendus[0]->{vcs}{token}; + $vcs->setAttribute("token", substr($rendus[0]->{vcs}{token}, 2, 23)); + $mod = 1; + next; + } + } + my $token; do { $token = sha1_base64(rand); From 476df5a6224d4d1ad2ef21c89f4497eb26aa2343 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 20 Sep 2013 08:31:18 +0200 Subject: [PATCH 063/364] Fix tag used named --- hooks/subjects.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index cdbeab0..3390340 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -298,7 +298,7 @@ sub tag_project { # Looking for an old token my @rendus = grep { - exists $_->{vcs} and $_->{vcs}{tag} eq $tag; + exists $_->{vcs} and $_->{vcs}{tag} eq $vcs->hasAttribute("tag"); } @{ $project->{submissions} }; if (@rendus == 1) { From 59ef2e199405635f71a51f3e52c9821ff1af12a7 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 20 Sep 2013 08:34:23 +0200 Subject: [PATCH 064/364] Fix location to find defense --- hooks/subjects.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index 3390340..4bc9557 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -118,7 +118,7 @@ sub tag_defense } my $defense_id; - if ($_[4] =~ /(?:defenses\/)?([a-zA-Z0-9\/]+)(?:.xml)/) { + if ($path =~ /(?:defenses\/)?([a-zA-Z0-9\/]+)(?:.xml)/) { $defense_id = $1; } else { log ERROR, "Déplacez votre soutenance dans le dossier defenses ou simplifiez le nom du fichier."; From 37e095bb2e2d6b97190a6e7dc67a80b05b4f7f29 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 20 Sep 2013 08:47:17 +0200 Subject: [PATCH 065/364] chown trace directory for defense --- process/files/intradata_get.pl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index 7619ede..3160906 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -112,6 +112,8 @@ sub update_defense } if (! -e "$basedir/$year/$project_id/traces/defense_$defense_id/") { mkdir "$basedir/$year/$project_id/traces/defense_$defense_id/"; + my ($login, $pass, $uid, $gid) = getpwnam("www-data"); + chown $uid, $gid, "$basedir/$year/$project_id/traces/defense_$defense_id/"; } open my $out, ">", "$basedir/$year/$project_id/defenses/$defense_id.xml"; From 55e0870936f1aa4b14c38e4c1c878a27a4dc6412 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 20 Sep 2013 08:51:47 +0200 Subject: [PATCH 066/364] chmod for www-data write --- process/files/intradata_get.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index 3160906..86a5636 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -114,6 +114,7 @@ sub update_defense mkdir "$basedir/$year/$project_id/traces/defense_$defense_id/"; my ($login, $pass, $uid, $gid) = getpwnam("www-data"); chown $uid, $gid, "$basedir/$year/$project_id/traces/defense_$defense_id/"; + chmod 0775, "$basedir/$year/$project_id/traces/defense_$defense_id/"; } open my $out, ">", "$basedir/$year/$project_id/defenses/$defense_id.xml"; From 88eaf60cc5322d98d76a8d79f4596a7d72ad871f Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 20 Sep 2013 17:40:36 +0200 Subject: [PATCH 067/364] Install package in FreeBSD --- commands/first-install.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/commands/first-install.sh b/commands/first-install.sh index 59e38d8..b7c1ba5 100755 --- a/commands/first-install.sh +++ b/commands/first-install.sh @@ -3,6 +3,7 @@ # Install missing packets DEB_PACKAGES_LIST="screen libnet-ldap-perl libxml-libxml-perl libgearman-client-perl libmailtools-perl libmail-sendmail-perl libdate-manip-perl" ARCH_PACKAGES_LIST="screen perl-io-socket-ssl perl-email-simple perl-email-mime perl-term-readkey perl-ldap perl-lwp-protocol-https" +FBSD_PACKAGES_LIST="screen p5-IO-Socket-SSL p5-Email-Simple p5-Email-MIME p5-Term-ANSIColor p5-Term-ReadKey p5-LWP-Protocol-https" if [ -f "/etc/debian_version" ] then @@ -44,8 +45,13 @@ then elif [ -f "/etc/freebsd-update.conf" ] then - echo "TODO: FreeBSD" - exit 1; + for PK in $FBSD_PACKAGES_LIST + do + if ! pkg info "$PK" > /dev/null 2> /dev/null + then + pkg install "$PK" + fi + done else From de06d5fd0d3d8c3663b74e9e25f2d93318d828b7 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 20 Sep 2013 17:43:12 +0200 Subject: [PATCH 068/364] intradata can get bonus/malus point --- ACU/Trace.pm | 46 ++++++++++++++- process/files/intradata_get.pl | 100 ++++++++++++++++++++++++++++----- 2 files changed, 128 insertions(+), 18 deletions(-) diff --git a/ACU/Trace.pm b/ACU/Trace.pm index aaa4189..5516bcb 100644 --- a/ACU/Trace.pm +++ b/ACU/Trace.pm @@ -11,7 +11,7 @@ use open qw(:encoding(UTF-8) :std); use XML::LibXML; use XML::SAX::ParserFactory; -sub new ($$) +sub new { my $class = shift; my $self = { @@ -22,7 +22,9 @@ sub new ($$) }; bless $self, $class; - $self->_initialize(@_); + if ($#_ >= 0) { + $self->_initialize(@_); + } return $self; } @@ -104,6 +106,44 @@ sub getIds ($) return %{ $self->{ids} }; } +sub addId($$;$) +{ + my $self = shift; + my $key = shift; + my $value = shift // 1; + + $self->{ids}{$key} = $value; +} + +sub toString ($;$) +{ + my $self = shift; + my $main_grp = shift // "bonus_malus"; + + my $doc = XML::LibXML::Document->new('1.0'); + + my $root = $doc->createElement("trace"); + + my $group = $doc->createElement("group"); + $group->addChild( $doc->createAttribute("id", $main_grp) ); + + for my $k (keys %{ $self->{ids} }) { + my $e = $doc->createElement("eval"); + my $v = $doc->createElement("value"); + + $e->addChild( $doc->createAttribute("id", $k) ); + $v->appendText( $self->{ids}{$k} ); + + $e->appendChild( $v ); + $group->appendChild( $e ); + } + + $root->appendChild( $group ); + $doc->setDocumentElement( $root ); + + return $doc->toString(); +} + package TraceHandler; @@ -162,7 +202,7 @@ sub start_element } else { $self->{inValue} = NO_ID_VALUE; } - + $self->{values} = ""; } elsif ($element->{Name} ne "group" && $element->{Name} ne "name" && $element->{Name} ne "statut" && $element->{Name} ne "status" && $element->{Name} ne "log") { diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index 86a5636..603b9ee 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -14,13 +14,16 @@ use ACU::Process; our $basedir = "/intradata"; my %actions = ( + "defense" => { + "update" => \&update_defense, + }, + "grades" => { + "new_bonus" => \&grades_new_bonus, + }, "project" => { "create" => \&update_project, "update" => \&update_project, "delete" => \&delete_project, - }, - "defense" => { - "update" => \&update_defense, } ); @@ -42,7 +45,7 @@ sub create_tree($$) } -sub update_project +sub grades_new_bonus { my $args = shift; @@ -54,22 +57,57 @@ sub update_project return "No project_id given"; } - my $butler; - if (exists $args->{files}{"butler.xml"}) { - $butler = $args->{files}{"butler.xml"}; + if (! -e "$basedir/$year/$project_id/traces/") { + mkdir "$basedir/$year/$project_id/traces/"; } - if (! $butler) { - log ERROR, "Invalid butler.xml received!"; - return "Invalid butler.xml received!"; + if (! -e "$basedir/$year/$project_id/traces/bonus/") { + mkdir "$basedir/$year/$project_id/traces/bonus/"; } - log INFO, "Update $year/$project_id/butler.xml"; + for my $kfile (keys %{ $args->{files} }) + { + my $kbonus = $kfile; + $kbonus =~ s/[^a-zA-Z0-9_-]/_/g; - return $_ if (create_tree($year, $project_id)); + my @lines = ($args->{files}{$kfile} =~ tr/\n//); - open my $out, ">", "$basedir/$year/$project_id/butler.xml"; - print $out $butler; - close $out; + my $value = 1; + # Looking for a global value + if ($lines[0] =~ /^\d+$/) { + $value = $1; + log INFO, "Setting global value to $value"; + shift @lines; + } + + for my $line (@lines) + { + if ($line =~ /^([a-z0-9_-]+)(?:\s*:\s*(\d+))?$/) + { + my $login = $1; + my $tvalue = $2 // $value; + my $trace; + + if (-e "$basedir/$year/$project_id/traces/bonus/$login.xml") { + open my $xml, "<", "$basedir/$year/$project_id/traces/bonus/$login.xml" or croak $!; + binmode $xml; + $trace = Trace->new($xml); + close $xml; + } + else { + $trace = Trace->new(); + } + + $trace->addId($kbonus, $tvalue); + + open my $xml, ">", "$basedir/$year/$project_id/traces/bonus/$login.xml" or croak $!; + print $xml $trace->toString(); + close $xml + } + else { + log WARN, "Invalid login $line, line skiped"; + } + } + } return "Ok"; } @@ -124,6 +162,38 @@ sub update_defense return "Ok"; } +sub update_project +{ + my $args = shift; + + my $project_id = $args->{param}{id}; + my $year = $args->{param}{year} // LDAP::get_year; + + if (! $project_id) { + log ERROR, "No project_id given."; + return "No project_id given"; + } + + my $butler; + if (exists $args->{files}{"butler.xml"}) { + $butler = $args->{files}{"butler.xml"}; + } + if (! $butler) { + log ERROR, "Invalid butler.xml received!"; + return "Invalid butler.xml received!"; + } + + log INFO, "Update $year/$project_id/butler.xml"; + + return $_ if (create_tree($year, $project_id)); + + open my $out, ">", "$basedir/$year/$project_id/butler.xml"; + print $out $butler; + close $out; + + return "Ok"; +} + sub delete_project { log WARN, "delete_project: not implemented." From 2037cf531b9f8c0639ce472a6f3d5f4cbb6c92f4 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 20 Sep 2013 17:58:38 +0200 Subject: [PATCH 069/364] Add some debug string --- process/files/intradata_get.pl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index 603b9ee..8027d16 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -66,6 +66,8 @@ sub grades_new_bonus for my $kfile (keys %{ $args->{files} }) { + log DEBUG, "Reading file $kfile"; + my $kbonus = $kfile; $kbonus =~ s/[^a-zA-Z0-9_-]/_/g; @@ -87,6 +89,8 @@ sub grades_new_bonus my $tvalue = $2 // $value; my $trace; + log DEBUG, "Applying bonus for $login:$tvalue"; + if (-e "$basedir/$year/$project_id/traces/bonus/$login.xml") { open my $xml, "<", "$basedir/$year/$project_id/traces/bonus/$login.xml" or croak $!; binmode $xml; @@ -99,6 +103,8 @@ sub grades_new_bonus $trace->addId($kbonus, $tvalue); + log DEBUG, "Updating $basedir/$year/$project_id/traces/bonus/$login.xml"; + open my $xml, ">", "$basedir/$year/$project_id/traces/bonus/$login.xml" or croak $!; print $xml $trace->toString(); close $xml From a380b4abbc5b45adf016b263b2d4a61d231d5f4c Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 20 Sep 2013 18:03:40 +0200 Subject: [PATCH 070/364] Fix value determination --- process/files/intradata_get.pl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index 8027d16..a3f48db 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -75,12 +75,14 @@ sub grades_new_bonus my $value = 1; # Looking for a global value - if ($lines[0] =~ /^\d+$/) { + if ($lines[0] =~ /^(\d+)$/) { $value = $1; log INFO, "Setting global value to $value"; shift @lines; } + log TRACE, @lines; + for my $line (@lines) { if ($line =~ /^([a-z0-9_-]+)(?:\s*:\s*(\d+))?$/) From 13434c4dcf20f72d16c6388e30429c761d2c7e37 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 20 Sep 2013 18:05:19 +0200 Subject: [PATCH 071/364] Add some debug string --- process/files/intradata_get.pl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index a3f48db..9fb0b2c 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -73,6 +73,8 @@ sub grades_new_bonus my @lines = ($args->{files}{$kfile} =~ tr/\n//); + log TRACE, $args->{files}{$kfile}; + my $value = 1; # Looking for a global value if ($lines[0] =~ /^(\d+)$/) { From 61913763628fc78f6293a590a21f03074b91118a Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 20 Sep 2013 18:06:34 +0200 Subject: [PATCH 072/364] Add some debug string --- process/files/intradata_get.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index 9fb0b2c..7051d65 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -74,6 +74,7 @@ sub grades_new_bonus my @lines = ($args->{files}{$kfile} =~ tr/\n//); log TRACE, $args->{files}{$kfile}; + log TRACE, @lines; my $value = 1; # Looking for a global value From a5f6916df4aa8566b3cfed744dddce55e0dd30aa Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 20 Sep 2013 18:13:10 +0200 Subject: [PATCH 073/364] Separate lines --- process/files/intradata_get.pl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index 7051d65..886fe29 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -71,7 +71,7 @@ sub grades_new_bonus my $kbonus = $kfile; $kbonus =~ s/[^a-zA-Z0-9_-]/_/g; - my @lines = ($args->{files}{$kfile} =~ tr/\n//); + my @lines = split(/\n/, $args->{files}{$kfile}); log TRACE, $args->{files}{$kfile}; log TRACE, @lines; @@ -84,8 +84,6 @@ sub grades_new_bonus shift @lines; } - log TRACE, @lines; - for my $line (@lines) { if ($line =~ /^([a-z0-9_-]+)(?:\s*:\s*(\d+))?$/) From a036432edd1d04bd56fffa431f5962e7cd2d4003 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 20 Sep 2013 18:14:38 +0200 Subject: [PATCH 074/364] Import Trace module --- process/files/intradata_get.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index 886fe29..2a4eff8 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -10,6 +10,7 @@ use lib "../../"; use ACU::Log; use ACU::LDAP; use ACU::Process; +use ACU::Trace; our $basedir = "/intradata"; From b34f3db7505210da786e5b503daa1aa78f8cc2d8 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 21 Sep 2013 15:34:30 +0200 Subject: [PATCH 075/364] Add way to generate grades to intradata-get --- ACU/Grading.pm | 2 +- process/files/intradata_get.pl | 89 ++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/ACU/Grading.pm b/ACU/Grading.pm index 16aad74..9844adb 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -30,7 +30,7 @@ sub _initialize { my $self = shift; - my $dom = XML::LibXML->load_xml(IO => shift); + my $dom = XML::LibXML->load_xml(string => shift); $self->{tree} = $self->parseGrade($dom->documentElement()); $self->{max} = $dom->documentElement()->getAttribute("max") // "20"; } diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index 2a4eff8..f00e27b 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -9,6 +9,7 @@ use lib "../../"; use ACU::Log; use ACU::LDAP; +use ACU::Grading; use ACU::Process; use ACU::Trace; @@ -20,6 +21,7 @@ my %actions = ( }, "grades" => { "new_bonus" => \&grades_new_bonus, + "generate" => \&grades_generate, }, "project" => { "create" => \&update_project, @@ -46,6 +48,93 @@ sub create_tree($$) } +sub grades_generate +{ + my $args = shift; + + my $project_id = $args->{param}{id}; + my $year = $args->{param}{year} // LDAP::get_year; + + if (! $project_id) { + log ERROR, "No project_id given."; + return "No project_id given"; + } + + if (! -e "$basedir/$year/$project_id/grades/") { + mkdir "$basedir/$year/$project_id/grades/"; + } + + log DEBUG, "Generate list of students"; + + # Create list of students to generate + my @logins; + if ($args->{unamed}) + { + for (my $i = $args->{unamed}; $i > 0; $i--) { + push @logins, $args->{param}{$i}; + } + } + else + { + opendir(my $dh, "$basedir/$year/$project_id/traces/") or croak "can't opendir $some_dir: $!"; + for my $dir (grep { ( ! /^\./ ) && -d "$basedir/$year/$project_id/traces/$_" } readdir($dh)) + { + opendir(my $dhm, "$basedir/$year/$project_id/traces/$dir") or croak "can't opendir $some_dir: $!"; + + for my $login (grep { ( ! /^\./ ) && -f "$basedir/$year/$project_id/traces/$dir/$_" } readdir($dhm)) + { + if (! grep { /^\Q$login\E$/ } @logins) { + push @logins, $login; + } + } + + closedir $dhm; + } + closedir $dh; + } + + log TRACE, @logins; + + # Load grading file + my $grading; + if (exists $args->{files}{"grading.xml"}) { + $grading = $args->{files}{"grading.xml"}; + } + if (! $grading) { + log ERROR, "Invalid grading.xml received!"; + return "Invalid grading.xml received!"; + } + + my $grading = Grading->new($grading); + + opendir(my $dh, "$basedir/$year/$project_id/traces/") or croak "can't opendir $some_dir: $!"; + @trace_dirs = grep { ( ! /^\./ ) && -d "$basedir/$year/$project_id/traces/$_" } readdir($dh); + closedir $dh; + + for my $login (@login) + { + for my $dir (@trace_dirs) + { + if (-f "$basedir/$year/$project_id/traces/$dir/$login.xml") + { + open my $xmltrace, "<", "$basedir/$year/$project_id/traces/$dir/$login.xml" or croak "traces/$dir/$login.xml: $!"; + binmode $xmltrace; + my $trace = Trace->new($xmltrace); + close $xmltrace; + + $grading->fill($trace->getIds); + } + } + + open my $xmlgrade, ">", "$basedir/$year/$project_id/grades/$login.xml" or croak "grades/$login.xml"; + binmode $xmlgrade; + print $xmlgrade $grade->computeXML($login); + close $xmlgrade; + } + + return "Ok"; +} + sub grades_new_bonus { my $args = shift; From f4ce8c79e0aa301830357050ecc9e10edc7d7d6b Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 21 Sep 2013 15:59:46 +0200 Subject: [PATCH 076/364] Add grades tag --- hooks/subjects.pl | 86 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index 4bc9557..5cca7c1 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -211,7 +211,93 @@ sub tag_document sub tag_grades { + my $creation = shift; + # From here, we have: + # 1: "defense" + # 2: $version + # 3: $id + # 4: $year + + my $version = $_[2] // 1; + + my $project_id = repository_name(); + if ($_[3]) { + $project_id .= "-" . $_[3]; + } + $project_id = lc $project_id; + $project_id =~ s/[^a-z0-9-_]/_/g; + + my $year; + if ($_[4]) { + # Check on year + if ($_[4] !~ /^\d+$/) { + log ERROR, "project:*:* second argument is the year. Tag format: project:id:year"; + } + + $year = $_[4]; + } + else { + $year = LDAP::get_year; + } + + # Determine full tag + my $long_tag; + { + my $proj_id = $_[3] // ""; + $long_tag = "grades,$version,$proj_id,$year"; + } + + if ($creation) + { + my $newref = $ARGV[2]; + + # Check file exists + my $content = qx(git show $newref:grades/grades.xml); + if ($?) { + log ERROR, "Impossible de trouver le fichier de notation."; + } + + # Check DTD validity + if (check_xml(\$content, "http://acu.epita.fr/dtd/grading.dtd")) { + log ERROR, "Corrigez les erreurs du fichier grades.xml avant de lancer la génération des notes."; + } + + # TODO: check user permissions + + # Send data to intradata + log INFO, "Attente d'un processus de publication..."; + if (my $err = Process::Client::launch("intradata_get", { action => "generate", type => "grades", id => $project_id, "year" => $year, "version" => $version }, { "grading.xml" => $content })) + { + if (${ $err } ne "Ok") { + log ERROR, "Erreur durant le processus de publication : " . ${ $err }; + } + } + + if ($long_tag) + { + qx(git tag -f $long_tag); + if (! $?) { + log INFO, "Tag long créé : $long_tag."; + } + } + } + else + { + # Is the long tag existing + qx(git tag | egrep "^$long_tag\$"); + if ($?) { + log ERROR, "Tag long correspondant introuvable : $long_tag."; + } + + if ($long_tag) + { + qx(git tag -d $long_tag); + if (! $?) { + log INFO, "Tag long supprimé : $long_tag."; + } + } + } } sub tag_project From 8ecbd779d07c9adf47f7e91973c5a778d3dc5876 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 21 Sep 2013 16:16:34 +0200 Subject: [PATCH 077/364] Integrate final grade into grade.xml --- ACU/Grading.pm | 7 +------ process/files/intradata_get.pl | 16 +++++++++------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/ACU/Grading.pm b/ACU/Grading.pm index 9844adb..5623401 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -161,16 +161,11 @@ sub computeXML ($;$) my $doc = XML::LibXML::Document->new('1.0'); my $root = $doc->createElement("grading"); - my $final = $doc->createElement("grade"); for my $grade (@{ $self->{tree} }) { - my $tmp = $grade->compute($self->{operators}, $self->{ids}, $doc, $final); + my $tmp = $grade->compute($self->{operators}, $self->{ids}, $doc, $root); } - $final->addChild( $doc->createAttribute("value", $self->compute()) ); - $final->addChild( $doc->createAttribute("name", "Note finale") ); - - $root->appendChild( $final ); $root->addChild( $doc->createAttribute("max", $self->{max}) ); $doc->setDocumentElement( $root ); diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index f00e27b..ac7bae7 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -3,6 +3,7 @@ use v5.10.1; use strict; use warnings; +use Carp; use Pod::Usage; use lib "../../"; @@ -76,13 +77,14 @@ sub grades_generate } else { - opendir(my $dh, "$basedir/$year/$project_id/traces/") or croak "can't opendir $some_dir: $!"; + opendir(my $dh, "$basedir/$year/$project_id/traces/") or croak "can't opendir $basedir/$year/$project_id/traces/: $!"; for my $dir (grep { ( ! /^\./ ) && -d "$basedir/$year/$project_id/traces/$_" } readdir($dh)) { - opendir(my $dhm, "$basedir/$year/$project_id/traces/$dir") or croak "can't opendir $some_dir: $!"; + opendir(my $dhm, "$basedir/$year/$project_id/traces/$dir") or croak "can't opendir $basedir/$year/$project_id/traces/$dir: $!"; for my $login (grep { ( ! /^\./ ) && -f "$basedir/$year/$project_id/traces/$dir/$_" } readdir($dhm)) { + $login = s/\.xml$//; if (! grep { /^\Q$login\E$/ } @logins) { push @logins, $login; } @@ -105,13 +107,13 @@ sub grades_generate return "Invalid grading.xml received!"; } - my $grading = Grading->new($grading); + $grading = Grading->new($grading); - opendir(my $dh, "$basedir/$year/$project_id/traces/") or croak "can't opendir $some_dir: $!"; - @trace_dirs = grep { ( ! /^\./ ) && -d "$basedir/$year/$project_id/traces/$_" } readdir($dh); + opendir(my $dh, "$basedir/$year/$project_id/traces/") or croak "can't opendir $basedir/$year/$project_id/traces/: $!"; + my @trace_dirs = grep { ( ! /^\./ ) && -d "$basedir/$year/$project_id/traces/$_" } readdir($dh); closedir $dh; - for my $login (@login) + for my $login (@logins) { for my $dir (@trace_dirs) { @@ -128,7 +130,7 @@ sub grades_generate open my $xmlgrade, ">", "$basedir/$year/$project_id/grades/$login.xml" or croak "grades/$login.xml"; binmode $xmlgrade; - print $xmlgrade $grade->computeXML($login); + print $xmlgrade $grading->computeXML($login); close $xmlgrade; } From b6b1c02dd09c67e6401ec1a3c1b9d1fa354d362a Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 21 Sep 2013 16:23:41 +0200 Subject: [PATCH 078/364] Fix substitution --- process/files/intradata_get.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index ac7bae7..793d403 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -84,7 +84,7 @@ sub grades_generate for my $login (grep { ( ! /^\./ ) && -f "$basedir/$year/$project_id/traces/$dir/$_" } readdir($dhm)) { - $login = s/\.xml$//; + $login =~ s/\.xml$//; if (! grep { /^\Q$login\E$/ } @logins) { push @logins, $login; } From c9c74a2a22e0768649f02d9183c2a0fe052b9cab Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 21 Sep 2013 16:33:49 +0200 Subject: [PATCH 079/364] Reset after grading --- process/files/intradata_get.pl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index 793d403..64d7c62 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -115,8 +115,10 @@ sub grades_generate for my $login (@logins) { + log DEBUG, "Generating grades for $login"; for my $dir (@trace_dirs) { + log DEBUG, "Generating grades from $dir"; if (-f "$basedir/$year/$project_id/traces/$dir/$login.xml") { open my $xmltrace, "<", "$basedir/$year/$project_id/traces/$dir/$login.xml" or croak "traces/$dir/$login.xml: $!"; @@ -124,14 +126,21 @@ sub grades_generate my $trace = Trace->new($xmltrace); close $xmltrace; + log DEBUG, "Fill from file: traces/$dir/$login.xml"; + log TRACE, $trace->getIds; + $grading->fill($trace->getIds); } } + log DEBUG, "Computed grades: ".$grading->compute(); + open my $xmlgrade, ">", "$basedir/$year/$project_id/grades/$login.xml" or croak "grades/$login.xml"; binmode $xmlgrade; print $xmlgrade $grading->computeXML($login); close $xmlgrade; + + $grading->reset(); } return "Ok"; From 73e52f441d0d91ab48c8cd2ba07cf738d0aeba63 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 21 Sep 2013 16:46:58 +0200 Subject: [PATCH 080/364] Pass Ids by reference --- ACU/Grading.pm | 6 +++--- ACU/Trace.pm | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ACU/Grading.pm b/ACU/Grading.pm index 5623401..315058b 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -107,12 +107,12 @@ sub insert ($$$) $self->{ids}{$_[0]} = $_[1]; } -sub fill ($%) +sub fill ($$) { my $self = shift; - my %ids = shift; + my $ids = shift; - for my $k (keys %ids) { + for my $k (keys %{ $ids }) { $self->{ids}{$k} = $ids{$k}; } } diff --git a/ACU/Trace.pm b/ACU/Trace.pm index 5516bcb..3c5e28f 100644 --- a/ACU/Trace.pm +++ b/ACU/Trace.pm @@ -103,7 +103,7 @@ sub getValue ($$) sub getIds ($) { my $self = shift; - return %{ $self->{ids} }; + return $self->{ids}; } sub addId($$;$) From 6b64c6c0a2bba8d6434f0ddd368538dbcd788890 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 21 Sep 2013 16:48:26 +0200 Subject: [PATCH 081/364] Pass Ids by reference --- ACU/Grading.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ACU/Grading.pm b/ACU/Grading.pm index 315058b..8173606 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -113,7 +113,7 @@ sub fill ($$) my $ids = shift; for my $k (keys %{ $ids }) { - $self->{ids}{$k} = $ids{$k}; + $self->{ids}{$k} = $ids->{$k}; } } From b3f61617f3ee80b94e3febf1d313c641586780cd Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 21 Sep 2013 16:56:43 +0200 Subject: [PATCH 082/364] Always return a valid integer --- ACU/Grading.pm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ACU/Grading.pm b/ACU/Grading.pm index 8173606..b880883 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -157,13 +157,12 @@ sub compute ($) sub computeXML ($;$) { my $self = shift; - my $sum = 0; my $doc = XML::LibXML::Document->new('1.0'); my $root = $doc->createElement("grading"); for my $grade (@{ $self->{tree} }) { - my $tmp = $grade->compute($self->{operators}, $self->{ids}, $doc, $root); + $grade->compute($self->{operators}, $self->{ids}, $doc, $root); } $root->addChild( $doc->createAttribute("max", $self->{max}) ); @@ -268,7 +267,6 @@ sub compute ($$$;$$) $grade->addChild( $doc->createAttribute("value", $res) ) if ($grade); - return $grade if ($grade); return $res; } From 9fe8a83c2eddf0652eeb105c4fc257c7dd8f846b Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 21 Sep 2013 18:29:17 +0200 Subject: [PATCH 083/364] Fix point without conditions --- ACU/Grading.pm | 7 ++++--- grades/generate.pl | 4 +++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ACU/Grading.pm b/ACU/Grading.pm index b880883..0dcc961 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -253,7 +253,7 @@ sub compute ($$$;$$) $res = reduce { $cpt->share('$a'); $cpt->share('$b'); - $cpt->reval($operators->{ $operator }) or die $@; + $cpt->reval($operators->{ $operator }) or die "Safe alert: $@"; } @current; } @@ -315,7 +315,7 @@ sub getValue ($$;$) my $ids = shift; my $justMatch = shift; - if (!$justMatch && !$ids->{ $self->{ref} } // 0) { + if ($self->{ref} && !$justMatch && !$ids->{ $self->{ref} } // 0) { return 0; } elsif ($self->{value} eq "") { @@ -337,7 +337,8 @@ sub compute ($$$;$$) $ret = $self->getValue( $ids ); } - if ($self->{not}) { + if ($self->{not}) + { if ($ret) { $ret = undef; } else { diff --git a/grades/generate.pl b/grades/generate.pl index 62ebc53..bed3e06 100644 --- a/grades/generate.pl +++ b/grades/generate.pl @@ -34,7 +34,9 @@ else { open $xmlgrading, "<", shift or die $!; } binmode $xmlgrading; -my $grade = Grading->new($xmlgrading); +my $str; +$str .= $_ while(<$xmlgrading>); +my $grade = Grading->new($str); close $xmlgrading unless $xmlgrading eq *STDIN; my $who = ""; From 664617171e6257765f04c30fafd7108ae16863f3 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 21 Sep 2013 19:13:25 +0200 Subject: [PATCH 084/364] New command to send bonus and malus --- commands/grades/send_bonusmalus.pl | 48 ++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 commands/grades/send_bonusmalus.pl diff --git a/commands/grades/send_bonusmalus.pl b/commands/grades/send_bonusmalus.pl new file mode 100644 index 0000000..8875701 --- /dev/null +++ b/commands/grades/send_bonusmalus.pl @@ -0,0 +1,48 @@ +#! /usr/bin/env perl + +use v5.10.1; +use strict; +use warnings; +use File::Basename; + +use lib "../../"; + +use ACU::LDAP; +use ACU::Process; + + +if ($#ARGV >= 1) +{ + my $project_id = shift; + my $year = shift; + + if ($year !~ /^[0-9]{4}$/) + { + unshift $year; + $year = LDAP::get_year(); + } + + my %files; + for my $f (@_) + { + open my $input, "<", $f or die("$f: $@"); + + my $cnt; + $cnt .= $_ while (<$input>); + + close $input unless $input eq *STDIN; + + $file{ basename($f, ".txt", ".lst", ".list", ".xml") } = $cnt; + } + + if (my $err = Process::Client::launch("intradata_get", { action => "new_bonus", type => "grades", id => $project_id, "year" => $year }, \%files)) + { + if (${ $err } ne "Ok") { + log ERROR, "Erreur durant le processus de publication : " . ${ $err }; + } + } +} +else +{ + say "$0 [project_year] [files ...]"; +} From d7092970027007836b1ffbbe895d055fe9eda448 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 21 Sep 2013 22:26:39 +0200 Subject: [PATCH 085/364] Zero values are now treated as valid computation --- ACU/Grading.pm | 11 ++++++----- commands/grades/send_bonusmalus.pl | 5 +++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/ACU/Grading.pm b/ACU/Grading.pm index 0dcc961..d926970 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -238,9 +238,10 @@ sub compute ($$$;$$) $parent->appendChild( $grade ); } - for my $node (@{ $self->{tree} }) { + for my $node (@{ $self->{tree} }) + { my $t = $node->compute($operators, $ids, $doc, $grade); - push @current, $t if $t; + push @current, $t if (defined $t); } my $res; @@ -249,11 +250,11 @@ sub compute ($$$;$$) my $operator = $self->{operator}; my $cpt = new Safe; - $cpt->permit_only(qw(:base_core :base_mem :base_loop padany)); + $cpt->permit_only(qw(:base_core :base_mem :base_loop padany rv2gv)); $res = reduce { $cpt->share('$a'); $cpt->share('$b'); - $cpt->reval($operators->{ $operator }) or die "Safe alert: $@"; + $cpt->reval($operators->{ $operator }) // die "Safe alert: $@"; } @current; } @@ -333,7 +334,7 @@ sub compute ($$$;$$) my $ids = shift; my $ret = undef; - if ((not $self->{ref}) || $self->{ref} ~~ $ids) { + if ((not $self->{ref}) || grep { $self->{ref} eq $_ } keys %$ids) { $ret = $self->getValue( $ids ); } diff --git a/commands/grades/send_bonusmalus.pl b/commands/grades/send_bonusmalus.pl index 8875701..8b7e1e3 100644 --- a/commands/grades/send_bonusmalus.pl +++ b/commands/grades/send_bonusmalus.pl @@ -8,6 +8,7 @@ use File::Basename; use lib "../../"; use ACU::LDAP; +use ACU::Log; use ACU::Process; @@ -18,7 +19,7 @@ if ($#ARGV >= 1) if ($year !~ /^[0-9]{4}$/) { - unshift $year; + unshift @_, $year; $year = LDAP::get_year(); } @@ -32,7 +33,7 @@ if ($#ARGV >= 1) close $input unless $input eq *STDIN; - $file{ basename($f, ".txt", ".lst", ".list", ".xml") } = $cnt; + $files{ basename($f, ".txt", ".lst", ".list", ".xml") } = $cnt; } if (my $err = Process::Client::launch("intradata_get", { action => "new_bonus", type => "grades", id => $project_id, "year" => $year }, \%files)) From fe467fdd93ba28a1dae6bc027b294be779973a3d Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 22 Sep 2013 00:51:54 +0200 Subject: [PATCH 086/364] Exception for pietri_a --- hooks/submissions.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/submissions.pl b/hooks/submissions.pl index b51e278..379b4f4 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -86,7 +86,7 @@ if ($ref =~ m<^refs/tags/(.+)$>) say "[ACU] Date courante: ", $glts; say "[ACU] Date fermeture: ", $close; - if ((Date_Cmp($glts, $open) == -1)) + if ((Date_Cmp($glts, $open) == -1) or $ENV{'GL_USER'} eq "pietri_a") { say "[ACU] Tag not allowed: upload not yet opened!"; exit(4); From cfd1cfd2e91d37c5921e61ca950d329343065a83 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 22 Sep 2013 06:11:02 +0200 Subject: [PATCH 087/364] Launch grading in background --- hooks/subjects.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index 5cca7c1..7b54abc 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -232,7 +232,7 @@ sub tag_grades if ($_[4]) { # Check on year if ($_[4] !~ /^\d+$/) { - log ERROR, "project:*:* second argument is the year. Tag format: project:id:year"; + log ERROR, "grades,*,*,* second argument is the year. Tag format: grades,version,id,year"; } $year = $_[4]; @@ -267,7 +267,7 @@ sub tag_grades # Send data to intradata log INFO, "Attente d'un processus de publication..."; - if (my $err = Process::Client::launch("intradata_get", { action => "generate", type => "grades", id => $project_id, "year" => $year, "version" => $version }, { "grading.xml" => $content })) + if (my $err = Process::Client::launch("intradata_get", { action => "generate", type => "grades", id => $project_id, "year" => $year, "version" => $version }, { "grading.xml" => $content }, 1)) { if (${ $err } ne "Ok") { log ERROR, "Erreur durant le processus de publication : " . ${ $err }; From 39758b9e4bd1b9daf6c8a65d811dcb142b174f7c Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 22 Sep 2013 06:12:40 +0200 Subject: [PATCH 088/364] Fix grading launch --- hooks/subjects.pl | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index 7b54abc..fac3d68 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -267,12 +267,7 @@ sub tag_grades # Send data to intradata log INFO, "Attente d'un processus de publication..."; - if (my $err = Process::Client::launch("intradata_get", { action => "generate", type => "grades", id => $project_id, "year" => $year, "version" => $version }, { "grading.xml" => $content }, 1)) - { - if (${ $err } ne "Ok") { - log ERROR, "Erreur durant le processus de publication : " . ${ $err }; - } - } + Process::Client::launch("intradata_get", { action => "generate", type => "grades", id => $project_id, "year" => $year, "version" => $version }, { "grading.xml" => $content }, 1); if ($long_tag) { From 59aff8677a0ceadc75ee3f5ea9b33e6eb5272cf1 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 22 Sep 2013 15:10:32 +0200 Subject: [PATCH 089/364] Fix grading generation from defenses --- ACU/API/Projects.pm | 2 +- ACU/Defense.pm | 9 ++++++--- ACU/Grading.pm | 16 +++++++++------- grades/gen_grading.pl | 7 +++++-- utils/lpt | 30 +++++++++++++++--------------- 5 files changed, 36 insertions(+), 28 deletions(-) diff --git a/ACU/API/Projects.pm b/ACU/API/Projects.pm index fc54b33..1395ff1 100644 --- a/ACU/API/Projects.pm +++ b/ACU/API/Projects.pm @@ -79,7 +79,7 @@ sub add_grades($;$) ); $data{year} = $_ if (shift); - my $res = API::Base::get('ResultHandler', "projects/groups/generate.xml"); + my $res = API::Base::send('ResultHandler', "projects/notes/add.xml", \%data); if ($res->{result} ne '0') { croak "Erreur durant l'ajout : " . $res->{message}; diff --git a/ACU/Defense.pm b/ACU/Defense.pm index 386a49d..d295a3f 100644 --- a/ACU/Defense.pm +++ b/ACU/Defense.pm @@ -116,12 +116,12 @@ sub getIds ($) for my $answer (@{ $question->{answers} }) { - $ids{ $answer->{id} } = $answer->{value} if ($answer->{id}); + $ids{ $answer->{id} } = $answer->{value} // 0 if ($answer->{id}); } } } - return %ids; + return \%ids; } sub genIds ($) @@ -216,9 +216,12 @@ sub parseQuestions($@) for my $question (@_) { + my $expl; + $expl = @{ $question->getElementsByTagName("explanation") }[0]->textContent if $question->getElementsByTagName("explanation"); + my $q = Defense::Question->new( @{ $question->getElementsByTagName("ask") }[0]->textContent, - @{ $question->getElementsByTagName("explanation") }[0]->textContent // "", + $expl // "", $question->getAttribute("id"), $question->getAttribute("title"), $question->getAttribute("type"), diff --git a/ACU/Grading.pm b/ACU/Grading.pm index d926970..34601ad 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -44,9 +44,11 @@ sub create_from_trace ($$) my $g = Grade->new($trace_id, $trace_name); - for my $id (sort( keys %{ $trace->{ids} } )) + my $ids = $trace->getIds(); + + for my $id (sort( keys %{ $ids } )) { - my $p = Point->new($trace->{ids}{$id}, $id, 0, 0); + my $p = Point->new($ids->{$id}, $id, 0, 0); push @{ $g->{tree} }, $p; } @@ -117,7 +119,7 @@ sub fill ($$) } } -sub to_string ($) +sub toString ($) { my $self = shift; @@ -133,7 +135,7 @@ sub to_string ($) } for my $grade (@{ $self->{tree} }) { - $grade->to_string($doc, $root, $root); + $grade->toString($doc, $root, $root); } $doc->setDocumentElement( $root ); @@ -195,7 +197,7 @@ sub new ($$$;$$) return bless $self; } -sub to_string ($$$) +sub toString ($$$) { my $self = shift; my $doc = shift; @@ -209,7 +211,7 @@ sub to_string ($$$) $parent->appendChild($grade); for my $item (@{ $self->{tree} }) { - $item->to_string($doc, $grade); + $item->toString($doc, $grade); } } @@ -296,7 +298,7 @@ sub new ($$$$$) return bless $self; } -sub to_string ($$$) +sub toString ($$$) { my $self = shift; my $doc = shift; diff --git a/grades/gen_grading.pl b/grades/gen_grading.pl index 5889b8b..6d9c9d9 100644 --- a/grades/gen_grading.pl +++ b/grades/gen_grading.pl @@ -41,8 +41,11 @@ do { open $xml, "<", $file or die $!; binmode $xml; + my $str; + $str .= $_ while (<$xml>); + eval { - $trace = Defense->new($xml); + $trace = Defense->new($str); }; if ($@) { log ERROR, "Unknown file type: $file"; @@ -55,4 +58,4 @@ do { } while ($#ARGV >= 0); -print $grade->to_string(); +print $grade->toString(); diff --git a/utils/lpt b/utils/lpt index 1afd324..0f08a1b 100755 --- a/utils/lpt +++ b/utils/lpt @@ -1401,7 +1401,7 @@ sub cmd_ssh_keys_without_passphrase_warn(@) print $entry->get_value("uid")."\n"; # create the message - use Mail::Internet; + #use Mail::Internet; my $body = "Bonjour ".$entry->get_value("cn").", @@ -1429,13 +1429,13 @@ PS: Ce message est g -- Les roots ACU"; - my $email = Mail::Internet->new(); - $email->body($body); - $email->add( "To", $entry->get_value("mailAlias") ); - $email->add( "Cc", "" ); - $email->add( "From", "Roots assistants " ); - $email->add( "Subject", "[LAB][SSH-PASSPHRASE] Clef SSH non protégée" ); - $email->send(); + #my $email = Mail::Internet->new(); + #$email->body($body); + #$email->add( "To", $entry->get_value("mailAlias") ); + #$email->add( "Cc", "" ); + #$email->add( "From", "Roots assistants " ); + #$email->add( "Subject", "[LAB][SSH-PASSPHRASE] Clef SSH non protégée" ); + #$email->send(); }; cmd_ssh_keys_without_passphrase_generic(\&$process); @@ -1485,13 +1485,13 @@ PS: Ce message est g -- Les roots ACU"; - my $email = Mail::Internet->new(); - $email->body($body); - $email->add( "To", $entry->get_value("mailAlias") ); - $email->add( "Cc", "" ); - $email->add( "From", "Roots assistants " ); - $email->add( "Subject", "[LAB][SSH-PASSPHRASE] Clef SSH non protégée supprimée" ); - $email->send(); + #my $email = Mail::Internet->new(); + #$email->body($body); + #$email->add( "To", $entry->get_value("mailAlias") ); + #$email->add( "Cc", "" ); + #$email->add( "From", "Roots assistants " ); + #$email->add( "Subject", "[LAB][SSH-PASSPHRASE] Clef SSH non protégée supprimée" ); + #$email->send(); }; cmd_ssh_keys_without_passphrase_generic(\&$process); From dd088dd210efedb55d6ea8fd7d9dbfb69493f278 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 24 Sep 2013 00:24:47 +0200 Subject: [PATCH 090/364] Fix bad index to create defense --- hooks/subjects.pl | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index fac3d68..3921a3c 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -78,36 +78,36 @@ sub tag_defense my $creation = shift; # From here, we have: - # 1: "defense" - # 2: $version - # 3: $id - # 4: $path - # 5: $year + # 0: "defense" + # 1: $version + # 2: $id + # 3: $path + # 4: $year - my $version = $_[2] // 1; + my $version = $_[1] // 1; my $project_id = repository_name(); - if ($_[3]) { - $project_id .= "-" . $_[3]; + if ($_[2]) { + $project_id .= "-" . $_[2]; } $project_id = lc $project_id; $project_id =~ s/[^a-z0-9-_]/_/g; my $path; - if ($_[4]) + if ($_[3]) { - if ($_[4] =~ /(?:defenses\/)?([a-zA-Z0-9\/]+)(?:.xml)/) { + if ($_[3] =~ /(?:defenses\/)?([a-zA-Z0-9\/]+)(?:.xml)/) { $path = "defenses/".$1.".xml"; } else { - $path = $_[4]; + $path = $_[3]; } } else { # Looking for an uniq defense file in defenses/ - $path = qx(git ls-tree -r --name-only HEAD defenses/ | egrep '\.xml\$'); + $path = qx(git ls-tree -r --name-only $ARGV[2] defenses/ | egrep '\.xml\$'); my $nb_defenses = $path =~ tr/\n//; if ($nb_defenses > 1) { - log ERROR, "Veuillez préciser le chemin de la soutenance à utiliser"; + log ERROR, "Veuillez préciser le chemin de la soutenance à utiliser avec un tag : defense,$_[1],$_[2],file_to_use"; exit 1; } elsif ($nb_defenses == 0) { @@ -125,14 +125,14 @@ sub tag_defense } my $year; - if ($_[5]) + if ($_[4]) { # Check on year - if ($_[5] !~ /^\d+$/) { + if ($_[4] !~ /^\d+$/) { log ERROR, "project:*:* second argument is the year. Tag format: project:id:year"; } - $year = $_[5]; + $year = $_[4]; } else { $year = LDAP::get_year; @@ -141,7 +141,7 @@ sub tag_defense # Determine full tag my $long_tag; { - my $proj_id = $_[3] // ""; + my $proj_id = $_[2] // ""; $long_tag = "defense,$version,$proj_id,$path,$year"; } From 9f7a2f1f150ba74b61b1c5af9fa8a188fe4bbf71 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 24 Sep 2013 00:27:20 +0200 Subject: [PATCH 091/364] Fix empty arg to tags --- hooks/subjects.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index 3921a3c..96dd7cb 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -34,7 +34,7 @@ if ($ref =~ m<^refs/tags(/.+)$>) my $tag = $1; my @args; - while ($tag =~ m<[,/]([^,]+)>g) { + while ($tag =~ m<[,/]([^,]*)>g) { push @args, $1; } From feb887d1058294f5c4be97ec2719184eec325e58 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 24 Sep 2013 00:28:22 +0200 Subject: [PATCH 092/364] Can give defense file without .xml --- hooks/subjects.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index 96dd7cb..9a19595 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -118,7 +118,7 @@ sub tag_defense } my $defense_id; - if ($path =~ /(?:defenses\/)?([a-zA-Z0-9\/]+)(?:.xml)/) { + if ($path =~ /(?:defenses\/)?([a-zA-Z0-9\/]+)(?:.xml)?/) { $defense_id = $1; } else { log ERROR, "Déplacez votre soutenance dans le dossier defenses ou simplifiez le nom du fichier."; From e60879ca6e9ba7582b666e3e58b491593199995f Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 24 Sep 2013 00:41:56 +0200 Subject: [PATCH 093/364] Can give defense file without .xml --- hooks/subjects.pl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index 9a19595..4072d11 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -5,6 +5,7 @@ use warnings; use v5.10; use Digest::SHA qw(sha1_base64); use File::Basename; +use utf8; use ACU::API::Projects; use ACU::Defense; @@ -102,7 +103,8 @@ sub tag_defense $path = $_[3]; } } - else { + else + { # Looking for an uniq defense file in defenses/ $path = qx(git ls-tree -r --name-only $ARGV[2] defenses/ | egrep '\.xml\$'); my $nb_defenses = $path =~ tr/\n//; @@ -118,7 +120,7 @@ sub tag_defense } my $defense_id; - if ($path =~ /(?:defenses\/)?([a-zA-Z0-9\/]+)(?:.xml)?/) { + if ($path =~ /^(?:defenses\/)?([a-zA-Z0-9\/]+)(?:.xml)?$/) { $defense_id = $1; } else { log ERROR, "Déplacez votre soutenance dans le dossier defenses ou simplifiez le nom du fichier."; From 89f9c5c6d3a85a3f303039e5d0d9cbfdaf1f7131 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 24 Sep 2013 00:43:02 +0200 Subject: [PATCH 094/364] Can give defense file without .xml --- hooks/subjects.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index 4072d11..cf671e0 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -97,7 +97,7 @@ sub tag_defense my $path; if ($_[3]) { - if ($_[3] =~ /(?:defenses\/)?([a-zA-Z0-9\/]+)(?:.xml)/) { + if ($_[3] =~ /^(?:defenses\/)?([a-zA-Z0-9\/]+)(?:.xml)?$/) { $path = "defenses/".$1.".xml"; } else { $path = $_[3]; From d346848b90d81c29500c5abd951bd4974eb57cf3 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 24 Sep 2013 01:40:10 +0200 Subject: [PATCH 095/364] Fix index in hook --- hooks/subjects.pl | 74 ++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index cf671e0..67393da 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -216,28 +216,28 @@ sub tag_grades my $creation = shift; # From here, we have: - # 1: "defense" - # 2: $version - # 3: $id - # 4: $year + # 0: "defense" + # 1: $version + # 2: $id + # 3: $year - my $version = $_[2] // 1; + my $version = $_[1] // 1; my $project_id = repository_name(); - if ($_[3]) { - $project_id .= "-" . $_[3]; + if ($_[2]) { + $project_id .= "-" . $_[2]; } $project_id = lc $project_id; $project_id =~ s/[^a-z0-9-_]/_/g; my $year; - if ($_[4]) { + if ($_[3]) { # Check on year - if ($_[4] !~ /^\d+$/) { + if ($_[3] !~ /^\d+$/) { log ERROR, "grades,*,*,* second argument is the year. Tag format: grades,version,id,year"; } - $year = $_[4]; + $year = $_[3]; } else { $year = LDAP::get_year; @@ -246,7 +246,7 @@ sub tag_grades # Determine full tag my $long_tag; { - my $proj_id = $_[3] // ""; + my $proj_id = $_[2] // ""; $long_tag = "grades,$version,$proj_id,$year"; } @@ -302,31 +302,31 @@ sub tag_project my $creation = shift; # From here, we have: - # 1: "project" - # 2: $id - # 3: $year + # 0: "project" + # 1: $id + # 2: $year my $project_id = repository_name(); - if ($_[2]) { + if ($_[1]) { # Check on ID/flavour_id - if ($_[2] =~ /^\d+$/) { + if ($_[1] =~ /^\d+$/) { log ERROR, "project:* tag can't take version. Tag format: project:id:year"; } - $project_id .= "-" . $_[2]; + $project_id .= "-" . $_[1]; } $project_id = lc $project_id; $project_id =~ s/[^a-z0-9-_]/_/g; my $year; - if ($_[3]) { + if ($_[2]) { # Check on year - if ($_[3] !~ /^\d+$/) { + if ($_[2] !~ /^\d+$/) { log ERROR, "project:*:* second argument is the year. Tag format: project:id:year"; } - $year = $_[3]; + $year = $_[2]; } else { $year = LDAP::get_year; @@ -334,9 +334,9 @@ sub tag_project # Determine full tag my $long_tag; - if (!$_[3]) + if (!$_[2]) { - my $proj_id = $_[2] // ""; + my $proj_id = $_[1] // ""; $long_tag = "project,$proj_id,$year"; } @@ -393,7 +393,8 @@ sub tag_project } my $token; - do { + do + { $token = sha1_base64(rand); $token =~ s/[^a-zA-Z0-9]//g; } while (length $token < 12); @@ -466,40 +467,41 @@ sub tag_ref my $creation = shift; # From here, we have: - # 1: "ref" - # 2: $id - # 3: rendu-X - # 4: $year + # 0: "ref" + # 1: $id + # 2: rendu-X + # 3: $year my $project_id = repository_name(); - if ($_[2]) { + if ($_[1]) { # Check on ID/flavour_id - if ($_[2] =~ /^\d+$/) { + if ($_[1] =~ /^\d+$/) { log ERROR, "ref,* tag can't take version. Tag format: ref,id,rendu,year"; } - $project_id .= "-" . $_[2]; + $project_id .= "-" . $_[1]; } $project_id = lc $project_id; $project_id =~ s/[^a-z0-9-_]/_/g; my $rendu; - if ($_[3]) { - $rendu = $_[3]; + if ($_[2]) { + $rendu = $_[2]; } else { $rendu = "*"; } my $year; - if ($_[4]) { + if ($_[3]) + { # Check on year - if ($_[4] !~ /^\d+$/) { + if ($_[3] !~ /^\d+$/) { log ERROR, "ref,*,*,* third argument is the year. Tag format: ref,id,rendu,year"; } - $year = $_[4]; + $year = $_[3]; } else { $year = LDAP::get_year; @@ -508,7 +510,7 @@ sub tag_ref # Determine full tag my $long_tag; { - my $proj_id = $_[2] // ""; + my $proj_id = $_[1] // ""; $long_tag = "ref,$proj_id,$rendu,$year"; } From 488c2bbbb8087821243e14f3068a4edf71e26fc7 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 24 Sep 2013 01:48:53 +0200 Subject: [PATCH 096/364] Can receive a process without XML format --- ACU/Process.pm | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/ACU/Process.pm b/ACU/Process.pm index cde2956..f0cc632 100644 --- a/ACU/Process.pm +++ b/ACU/Process.pm @@ -67,6 +67,26 @@ sub do_work ($$$@) return $subref->($given_args, $args); } +sub register_no_parse ($$;$) +{ + my $funcname = shift; + my $subref = shift; + my $given_arg = shift; + + my $worker = Gearman::Worker->new; + + $worker->job_servers('gearmand:4730'); + $worker->register_function($funcname => sub { return $subref->($given_arg, $_[0]{argref}); }); + + # Disable exit on warning or error + $ACU::Log::fatal_warn = 0; + $ACU::Log::fatal_error = 0; + + log DEBUG, "$funcname registered"; + + $worker->work while 1; +} + sub register ($$;$$) { my $funcname = shift; From 0f385f383853bca064c6b7d878a96a86cc442a68 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 24 Sep 2013 02:14:11 +0200 Subject: [PATCH 097/364] Handle comma in bonus/malus files --- process/files/intradata_get.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index 64d7c62..b6c896b 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -187,7 +187,7 @@ sub grades_new_bonus for my $line (@lines) { - if ($line =~ /^([a-z0-9_-]+)(?:\s*:\s*(\d+))?$/) + if ($line =~ /^([a-z0-9_-]+)(?:\s*:\s*([0-9.]+))?$/) { my $login = $1; my $tvalue = $2 // $value; From 3f337f9eb91ebe6d4249fdc7bcb1232f16efb7c2 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 24 Sep 2013 04:19:44 +0200 Subject: [PATCH 098/364] Group with id have now a completed ID --- ACU/Trace.pm | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/ACU/Trace.pm b/ACU/Trace.pm index 3c5e28f..98f2970 100644 --- a/ACU/Trace.pm +++ b/ACU/Trace.pm @@ -154,6 +154,7 @@ sub new ($$) { my $class = shift; my $self = { + groups => [], parsed => shift, inComment => "", inEval => "", @@ -205,7 +206,11 @@ sub start_element $self->{values} = ""; } - elsif ($element->{Name} ne "group" && $element->{Name} ne "name" && $element->{Name} ne "statut" && $element->{Name} ne "status" && $element->{Name} ne "log") { + elsif ($element->{Name} eq "group") + { + push @{ $self->{groups} }, ($element->{Attributes}{"{}id"}{Value} // ""); + } + elsif ($element->{Name} ne "name" && $element->{Name} ne "statut" && $element->{Name} ne "status" && $element->{Name} ne "log") { croak "Not a valid trace XML: unknown tag ".$element->{Name}; } } @@ -231,6 +236,10 @@ sub end_element if ($self->{inValue} ne NO_ID_VALUE and $1) { $self->{parsed}{ids}{ $self->{inValue} } = $1; } + if ($self->{groups}) { + my $key = @{ $self->{groups} }[$#{ $self->{groups} }]; + $self->{parsed}{ids}{ $key } += $1; + } } $self->{inValue} = ""; } @@ -260,6 +269,10 @@ sub end_element } $self->{inInfo} = ""; } + elsif ($element->{Name} eq "group") + { + pop @{ $self->{groups} }; + } } 1; From ea7d623eaef5b2c18fb206dc889b1bbfabe3df4f Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 24 Sep 2013 04:54:09 +0200 Subject: [PATCH 099/364] Add new process for generating grading XML --- ACU/Grading.pm | 10 ++--- grades/gen_grading.pl | 2 +- process/launch.sh | 1 + process/projects/gen_grading.pl | 72 +++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 process/projects/gen_grading.pl diff --git a/ACU/Grading.pm b/ACU/Grading.pm index 34601ad..300fbac 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -35,17 +35,17 @@ sub _initialize $self->{max} = $dom->documentElement()->getAttribute("max") // "20"; } -sub create_from_trace ($$) +sub create_from_ids { my $self = shift; - my $trace_id = shift; my $trace_name = shift; - my $trace = shift; + my $ids = shift; + + my $trace_id = $trace_name; + $trace_id =~ s/[^a-zA-Z0-9_]/_/g; my $g = Grade->new($trace_id, $trace_name); - my $ids = $trace->getIds(); - for my $id (sort( keys %{ $ids } )) { my $p = Point->new($ids->{$id}, $id, 0, 0); diff --git a/grades/gen_grading.pl b/grades/gen_grading.pl index 6d9c9d9..5c9b613 100644 --- a/grades/gen_grading.pl +++ b/grades/gen_grading.pl @@ -54,7 +54,7 @@ do { close $xml unless $xml eq *STDIN; - $grade->create_from_trace($id_name, $name, $trace); + $grade->create_from_ids($id_name, $name, $trace); } while ($#ARGV >= 0); diff --git a/process/launch.sh b/process/launch.sh index 6c88575..92da68a 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -78,6 +78,7 @@ then noyce) launch_screen "lerdorf_process_files_intradata_get" "while true; do $PERL ~/liblerdorf/process/files/intradata_get.pl; done" + launch_screen "lerdorf_process_projects_gen_grading" "while true; do $PERL ~/liblerdorf/process/projects/gen_grading.pl; done" ;; ksh) diff --git a/process/projects/gen_grading.pl b/process/projects/gen_grading.pl new file mode 100644 index 0000000..825a9f7 --- /dev/null +++ b/process/projects/gen_grading.pl @@ -0,0 +1,72 @@ +#! /usr/bin/env perl + +use v5.10.1; +use strict; +use warnings; +use Carp; +use Pod::Usage; + +use lib "../../"; + +use ACU::Defense; +use ACU::Grading; +use ACU::Log; +use ACU::LDAP; +use ACU::Process; +use ACU::Trace; + +our $basedir = "/intradata"; + +sub process +{ + my $given_args = shift; + my @args = shift; + + my $project_id = shift @args; + my $year = shift @args // LDAP::get_year(); + + # Project existing? + if (! -d "$basedir/$year/$project_id") + { + log ERROR, "Unable to find $project_id in $year"; + return "Unable to find $project_id in $year"; + } + + my $grade = Grading->new(); + + # Create defenses groups + opendir(my $dh, "$basedir/$year/$project_id/defenses/") or croak "can't opendir $basedir/$year/$project_id/defenses/: $!"; + for my $sout (grep { ( ! /^\./ ) && -f "$basedir/$year/$project_id/defenses/$_" } readdir($dh)) + { + my $defense = Defense->new("$basedir/$year/$project_id/defenses/$_"); + + $grade->create_from_ids($sout, $defense->getIds()); + } + closedir $dh; + + # Create traces groups + opendir($dh, "$basedir/$year/$project_id/traces/") or croak "can't opendir $basedir/$year/$project_id/traces/: $!"; + for my $dir (grep { ( ! /^\./ ) && -d "$basedir/$year/$project_id/traces/$_" } readdir($dh)) + { + my $ids = {}; + + opendir(my $dhm, "$basedir/$year/$project_id/traces/$dir") or croak "can't opendir $basedir/$year/$project_id/traces/$dir: $!"; + for my $login (grep { ( ! /^\./ ) && -f "$basedir/$year/$project_id/traces/$dir/$_" } readdir($dhm)) + { + my $trace = Trace->new("$basedir/$year/$project_id/traces/$dir/$_"); + + my %tids = %{ $trace->getIds() }; + for my $kid (keys %tids) + { + $ids->{ $kid } = $tids{ $kid }; + } + } + + $grade->create_from_ids($_, $ids); + } + closedir $dh; + + return $grade->toString; +} + +Process::register_no_parse("gen_grading", \&process); From 80147e449f24bbf24cc4dbdd6bb8eaec3158830b Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 24 Sep 2013 05:14:16 +0200 Subject: [PATCH 100/364] Grading generation ok --- process/projects/gen_grading.pl | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/process/projects/gen_grading.pl b/process/projects/gen_grading.pl index 825a9f7..2aee444 100644 --- a/process/projects/gen_grading.pl +++ b/process/projects/gen_grading.pl @@ -5,6 +5,7 @@ use strict; use warnings; use Carp; use Pod::Usage; +use Text::ParseWords; use lib "../../"; @@ -20,10 +21,10 @@ our $basedir = "/intradata"; sub process { my $given_args = shift; - my @args = shift; + my @args = shellwords(${ shift() }); my $project_id = shift @args; - my $year = shift @args // LDAP::get_year(); + my $year = shift @args // LDAP::get_year; # Project existing? if (! -d "$basedir/$year/$project_id") @@ -38,7 +39,13 @@ sub process opendir(my $dh, "$basedir/$year/$project_id/defenses/") or croak "can't opendir $basedir/$year/$project_id/defenses/: $!"; for my $sout (grep { ( ! /^\./ ) && -f "$basedir/$year/$project_id/defenses/$_" } readdir($dh)) { - my $defense = Defense->new("$basedir/$year/$project_id/defenses/$_"); + open my $xml, "<", "$basedir/$year/$project_id/defenses/$sout" or die $!; + binmode $xml; + + my $str; + $str .= $_ while (<$xml>); + + my $defense = Defense->new($str); $grade->create_from_ids($sout, $defense->getIds()); } @@ -53,7 +60,10 @@ sub process opendir(my $dhm, "$basedir/$year/$project_id/traces/$dir") or croak "can't opendir $basedir/$year/$project_id/traces/$dir: $!"; for my $login (grep { ( ! /^\./ ) && -f "$basedir/$year/$project_id/traces/$dir/$_" } readdir($dhm)) { - my $trace = Trace->new("$basedir/$year/$project_id/traces/$dir/$_"); + open my $xml, "<", "$basedir/$year/$project_id/traces/$dir/$login" or die $!; + binmode $xml; + + my $trace = Trace->new($xml); my %tids = %{ $trace->getIds() }; for my $kid (keys %tids) @@ -62,7 +72,7 @@ sub process } } - $grade->create_from_ids($_, $ids); + $grade->create_from_ids($dir, $ids); } closedir $dh; From 9c1c537e3c35b4f62e70dce326538296d51d6066 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 24 Sep 2013 05:41:32 +0200 Subject: [PATCH 101/364] Remove pietri_a expcetion --- hooks/submissions.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/submissions.pl b/hooks/submissions.pl index 379b4f4..b51e278 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -86,7 +86,7 @@ if ($ref =~ m<^refs/tags/(.+)$>) say "[ACU] Date courante: ", $glts; say "[ACU] Date fermeture: ", $close; - if ((Date_Cmp($glts, $open) == -1) or $ENV{'GL_USER'} eq "pietri_a") + if ((Date_Cmp($glts, $open) == -1)) { say "[ACU] Tag not allowed: upload not yet opened!"; exit(4); From 237cafc34e08109ab8cd4b586a5bc176876f71a1 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 24 Sep 2013 19:36:58 +0200 Subject: [PATCH 102/364] Fix grading condition resolving --- ACU/Grading.pm | 44 +++++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/ACU/Grading.pm b/ACU/Grading.pm index 300fbac..ab3c607 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -312,21 +312,16 @@ sub toString ($$$) $parent->appendChild($point); } -sub getValue ($$;$) +sub getValue ($$) { my $self = shift; my $ids = shift; - my $justMatch = shift; - if ($self->{ref} && !$justMatch && !$ids->{ $self->{ref} } // 0) { - return 0; - } - elsif ($self->{value} eq "") { - return $ids->{ $self->{ref} } // 0; - } - else { - return $self->{value}; - } + # Return the point node value if exists + return $self->{value} if ($self->{value} ne ""); + + # Else return pointed ref value + return $ids->{ $self->{ref} }; } sub compute ($$$;$$) @@ -336,23 +331,23 @@ sub compute ($$$;$$) my $ids = shift; my $ret = undef; - if ((not $self->{ref}) || grep { $self->{ref} eq $_ } keys %$ids) { - $ret = $self->getValue( $ids ); - } + my $result = ( + # No condition on refs nor qversion? + not $self->{ref} + # Condition on refs + || grep { $self->{ref} eq $_ } keys %$ids + ); - if ($self->{not}) - { - if ($ret) { - $ret = undef; - } else { - $ret = $self->getValue( $ids ); - } - } + # Handel not + $result = !$result if ($self->{not}); + + # ret is valued only if all conditions passed + $ret = $self->getValue( $ids ) if ($result); if ($main::debug) { - my $str = "not=".($self->{not}//0).", qversion".($self->{qversion}//"*").", ref=".($self->{ref}//"").",\tvalue=".$self->getValue( $ids, 1 ).", got=".($ret // 0); - if ($ret) { + my $str = "not=".($self->{not}//0).", qversion".($self->{qversion}//"*").", ref=".($self->{ref}//"").",\tvalue=".($ids->{ $self->{ref}//"" } // "undef").", got=".($ret // 0); + if ($result) { say GREEN, ">>>", RESET, " Matching point: ", $str; } else { say RED, " * ", RESET, " Skipped point: ", $str; @@ -362,5 +357,4 @@ sub compute ($$$;$$) return $ret; } - 1; From 243a1c922406db2e05861cfdeaeeed09c1c34281 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 24 Sep 2013 19:49:23 +0200 Subject: [PATCH 103/364] Fix undefined variable use --- ACU/Grading.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ACU/Grading.pm b/ACU/Grading.pm index ab3c607..ba83918 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -333,7 +333,7 @@ sub compute ($$$;$$) my $result = ( # No condition on refs nor qversion? - not $self->{ref} + ! defined $self->{ref} # Condition on refs || grep { $self->{ref} eq $_ } keys %$ids ); From 780f189cd4384f232df941defde32c27c68c070a Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 24 Sep 2013 20:18:23 +0200 Subject: [PATCH 104/364] Tag the good commit --- hooks/subjects.pl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index 67393da..3d5ec03 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -109,7 +109,7 @@ sub tag_defense $path = qx(git ls-tree -r --name-only $ARGV[2] defenses/ | egrep '\.xml\$'); my $nb_defenses = $path =~ tr/\n//; if ($nb_defenses > 1) { - log ERROR, "Veuillez préciser le chemin de la soutenance à utiliser avec un tag : defense,$_[1],$_[2],file_to_use"; + log ERROR, "Veuillez préciser le chemin de la soutenance à utiliser avec un tag : defense,", $_[1] // "", ",", $_[2] // "", ",file_to_use"; exit 1; } elsif ($nb_defenses == 0) { @@ -182,7 +182,7 @@ sub tag_defense if ($long_tag) { - qx(git tag -f $long_tag); + qx(git tag -f $long_tag $newref); if (! $?) { log INFO, "Tag long créé : $long_tag."; } @@ -273,7 +273,7 @@ sub tag_grades if ($long_tag) { - qx(git tag -f $long_tag); + qx(git tag -f $long_tag $newref); if (! $?) { log INFO, "Tag long créé : $long_tag."; } @@ -436,7 +436,7 @@ sub tag_project if ($long_tag) { - qx(git tag -f $long_tag); + qx(git tag -f $long_tag $newref); if (! $?) { log INFO, "Tag long créé : $long_tag."; } @@ -547,7 +547,7 @@ sub tag_ref if ($long_tag) { - qx(git tag -f $long_tag); + qx(git tag -f $long_tag $newref); if (! $?) { log INFO, "Tag long créé : $long_tag."; } From adfb686d041967c081e76e7e5da016d335f33366 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 25 Sep 2013 19:41:05 +0200 Subject: [PATCH 105/364] Remove empty identifier --- ACU/Trace.pm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ACU/Trace.pm b/ACU/Trace.pm index 98f2970..2cf448b 100644 --- a/ACU/Trace.pm +++ b/ACU/Trace.pm @@ -230,7 +230,7 @@ sub end_element if ($element->{Name} eq "value") { - if ($self->{values} =~ /(-?[0-9]+(.[0-9]+)?)/) + if ($self->{values} =~ /([-+]?[0-9]+(.[0-9]+)?)/) { $self->{parsed}{ids}{ $self->{inEval} } += $1; if ($self->{inValue} ne NO_ID_VALUE and $1) { @@ -245,7 +245,8 @@ sub end_element } elsif ($element->{Name} eq "eval") { - #delete $self->{parsed}{ids}{ $self->{inEval} } if (!$self->{parsed}{ids}{ $self->{inEval} }); + # Remove empty identifier + delete $self->{parsed}{ids}{ $self->{inEval} } if (!$self->{parsed}{ids}{ $self->{inEval} }); $self->{inEval} = ""; } elsif ($element->{Name} eq "comment") @@ -271,7 +272,9 @@ sub end_element } elsif ($element->{Name} eq "group") { - pop @{ $self->{groups} }; + my $key = pop @{ $self->{groups} }; + # Remove empty identifier + delete $self->{parsed}{ids}{ $key } if ($key && !$self->{parsed}{ids}{ $key }); } } From 9160fa0fb22065908888a0f05f33f24a4452359b Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 25 Sep 2013 19:41:24 +0200 Subject: [PATCH 106/364] Change allow defense filename --- hooks/subjects.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index 3d5ec03..b793ca4 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -97,7 +97,7 @@ sub tag_defense my $path; if ($_[3]) { - if ($_[3] =~ /^(?:defenses\/)?([a-zA-Z0-9\/]+)(?:.xml)?$/) { + if ($_[3] =~ /^(?:defenses\/)?([a-zA-Z0-9_.\/-]+)(?:.xml)?$/) { $path = "defenses/".$1.".xml"; } else { $path = $_[3]; From 025e9383549ff397678a1e031f5c9982655cd076 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 26 Sep 2013 01:05:31 +0200 Subject: [PATCH 107/364] Handel $LOGIN in grades --- ACU/Grading.pm | 30 ++++++++++++++++++++---------- process/files/intradata_get.pl | 2 +- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/ACU/Grading.pm b/ACU/Grading.pm index ba83918..a88424c 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -143,13 +143,14 @@ sub toString ($) return $doc->toString(); } -sub compute ($) +sub compute ($;$) { my $self = shift; + my $login = shift; my $sum = 0; for my $grade (@{ $self->{tree} }) { - my $tmp = $grade->compute($self->{operators}, $self->{ids}); + my $tmp = $grade->compute($self->{operators}, $self->{ids}, $login); $sum += $tmp if $tmp; } @@ -159,12 +160,13 @@ sub compute ($) sub computeXML ($;$) { my $self = shift; + my $login = shift; my $doc = XML::LibXML::Document->new('1.0'); my $root = $doc->createElement("grading"); for my $grade (@{ $self->{tree} }) { - $grade->compute($self->{operators}, $self->{ids}, $doc, $root); + $grade->compute($self->{operators}, $self->{ids}, $login, $doc, $root); } $root->addChild( $doc->createAttribute("max", $self->{max}) ); @@ -222,11 +224,12 @@ sub append ($@) push @{ $self->{tree} }, @_; } -sub compute ($$$;$$) +sub compute ($$$;$$$) { my $self = shift; my $operators = shift; my $ids = shift; + my $login = shift; my $doc = shift; my $parent = shift; my @current = (); @@ -324,18 +327,25 @@ sub getValue ($$) return $ids->{ $self->{ref} }; } -sub compute ($$$;$$) +sub compute ($$$;$$$) { my $self = shift; my $operators = shift; my $ids = shift; + my $login = shift; + + my $ref = $self->{ref}; + if ($login && $ref) { + $ref =~ s/\$LOGIN/$login/; + } + my $ret = undef; my $result = ( # No condition on refs nor qversion? - ! defined $self->{ref} + ! defined $ref # Condition on refs - || grep { $self->{ref} eq $_ } keys %$ids + || grep { $ref eq $_ } keys %$ids ); # Handel not @@ -346,11 +356,11 @@ sub compute ($$$;$$) if ($main::debug) { - my $str = "not=".($self->{not}//0).", qversion".($self->{qversion}//"*").", ref=".($self->{ref}//"").",\tvalue=".($ids->{ $self->{ref}//"" } // "undef").", got=".($ret // 0); + my $str = "not=".($self->{not}//0).", qversion".($self->{qversion}//"*").", ref=".($ref//"").",\tvalue=".($ids->{ $ref//"" } // "undef").", "; if ($result) { - say GREEN, ">>>", RESET, " Matching point: ", $str; + say GREEN, ">>>", RESET, " Matching point: ", $str, BOLD, "got=".($ret // 0), RESET; } else { - say RED, " * ", RESET, " Skipped point: ", $str; + say RED, " * ", RESET, " Skipped point: ", $str, BOLD, "got=".($ret // 0), RESET; } } diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index b6c896b..9c6890c 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -133,7 +133,7 @@ sub grades_generate } } - log DEBUG, "Computed grades: ".$grading->compute(); + log DEBUG, "Computed grades: ".$grading->compute($login); open my $xmlgrade, ">", "$basedir/$year/$project_id/grades/$login.xml" or croak "grades/$login.xml"; binmode $xmlgrade; From 5257595639f06138e5021b19e71970d6c1bfef99 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 26 Sep 2013 01:38:05 +0200 Subject: [PATCH 108/364] Pass $ref to functions --- ACU/Grading.pm | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/ACU/Grading.pm b/ACU/Grading.pm index a88424c..81fd4aa 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -239,13 +239,13 @@ sub compute ($$$;$$$) { $grade = $doc->createElement("grade"); $grade->addChild( $doc->createAttribute("factor", $self->{factor}) ); - $grade->addChild( $doc->createAttribute("name", $self->{title}) ); + $grade->addChild( $doc->createAttribute("name", $self->{title}) ) if ($self->{title}); $parent->appendChild( $grade ); } for my $node (@{ $self->{tree} }) { - my $t = $node->compute($operators, $ids, $doc, $grade); + my $t = $node->compute($operators, $ids, $login, $doc, $grade); push @current, $t if (defined $t); } @@ -315,16 +315,17 @@ sub toString ($$$) $parent->appendChild($point); } -sub getValue ($$) +sub getValue ($$$) { my $self = shift; my $ids = shift; + my $ref = shift; # Return the point node value if exists return $self->{value} if ($self->{value} ne ""); # Else return pointed ref value - return $ids->{ $self->{ref} }; + return $ids->{ $ref }; } sub compute ($$$;$$$) @@ -352,15 +353,15 @@ sub compute ($$$;$$$) $result = !$result if ($self->{not}); # ret is valued only if all conditions passed - $ret = $self->getValue( $ids ) if ($result); + $ret = $self->getValue( $ids, $ref ) if ($result); if ($main::debug) { - my $str = "not=".($self->{not}//0).", qversion".($self->{qversion}//"*").", ref=".($ref//"").",\tvalue=".($ids->{ $ref//"" } // "undef").", "; + my $str = "not=".($self->{not}//0).", qversion".($self->{qversion}//"*").", ref=".($ref//"").",\tvalue=".($ids->{ $ref//"" } // "undef"); if ($result) { - say GREEN, ">>>", RESET, " Matching point: ", $str, BOLD, "got=".($ret // 0), RESET; + say GREEN, ">>>", RESET, " Matching point: ", $str, ", ", BOLD, "got=".($ret // 0), RESET; } else { - say RED, " * ", RESET, " Skipped point: ", $str, BOLD, "got=".($ret // 0), RESET; + say RED, " * ", RESET, " Skipped point: ", $str; } } From 3ec51c56fc763f92b930c06299838d4059865b32 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 26 Sep 2013 03:32:09 +0200 Subject: [PATCH 109/364] Skip defense traces --- process/projects/gen_grading.pl | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/process/projects/gen_grading.pl b/process/projects/gen_grading.pl index 2aee444..d6c65ff 100644 --- a/process/projects/gen_grading.pl +++ b/process/projects/gen_grading.pl @@ -35,10 +35,13 @@ sub process my $grade = Grading->new(); + my @defenses; # Create defenses groups opendir(my $dh, "$basedir/$year/$project_id/defenses/") or croak "can't opendir $basedir/$year/$project_id/defenses/: $!"; for my $sout (grep { ( ! /^\./ ) && -f "$basedir/$year/$project_id/defenses/$_" } readdir($dh)) { + push @defenses, $sout; + open my $xml, "<", "$basedir/$year/$project_id/defenses/$sout" or die $!; binmode $xml; @@ -47,7 +50,12 @@ sub process my $defense = Defense->new($str); - $grade->create_from_ids($sout, $defense->getIds()); + my $ids = $defense->getIds(); + + $ids->{'def_end_$LOGIN'} = undef; + $ids->{'def_end_group'} = undef; + + $grade->create_from_ids($sout, $ids); } closedir $dh; @@ -55,6 +63,8 @@ sub process opendir($dh, "$basedir/$year/$project_id/traces/") or croak "can't opendir $basedir/$year/$project_id/traces/: $!"; for my $dir (grep { ( ! /^\./ ) && -d "$basedir/$year/$project_id/traces/$_" } readdir($dh)) { + next if (! grep { $dir eq "defense_$_" } @defenses); + my $ids = {}; opendir(my $dhm, "$basedir/$year/$project_id/traces/$dir") or croak "can't opendir $basedir/$year/$project_id/traces/$dir: $!"; From 899fd189f541bb7179e0f176dad2c0f1b8228296 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 26 Sep 2013 04:32:31 +0200 Subject: [PATCH 110/364] Generate defense ids for multiple defense --- ACU/Defense.pm | 5 +++-- process/projects/gen_grading.pl | 16 +++++++++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/ACU/Defense.pm b/ACU/Defense.pm index d295a3f..6150716 100644 --- a/ACU/Defense.pm +++ b/ACU/Defense.pm @@ -124,9 +124,10 @@ sub getIds ($) return \%ids; } -sub genIds ($) +sub genIds ($;$) { my $self = shift; + my $def_i = shift // 1; my @ids; my $grp_i = 0; @@ -136,7 +137,7 @@ sub genIds ($) if (! $group->{id} || grep { /^\Q$group->{id}\E$/ } @ids) { do { - $cur_gid = "defg".$grp_i; + $cur_gid = "def".$def_i."g".$grp_i; $grp_i += 1; } while (grep {$_ eq $cur_gid} @ids); $group->{id} = $cur_gid; diff --git a/process/projects/gen_grading.pl b/process/projects/gen_grading.pl index d6c65ff..09666ea 100644 --- a/process/projects/gen_grading.pl +++ b/process/projects/gen_grading.pl @@ -39,8 +39,10 @@ sub process # Create defenses groups opendir(my $dh, "$basedir/$year/$project_id/defenses/") or croak "can't opendir $basedir/$year/$project_id/defenses/: $!"; for my $sout (grep { ( ! /^\./ ) && -f "$basedir/$year/$project_id/defenses/$_" } readdir($dh)) - { - push @defenses, $sout; + { + my $sid; + ($sid = $sout) =~ s/\.xml$//; + push @defenses, $sid; open my $xml, "<", "$basedir/$year/$project_id/defenses/$sout" or die $!; binmode $xml; @@ -52,8 +54,12 @@ sub process my $ids = $defense->getIds(); - $ids->{'def_end_$LOGIN'} = undef; - $ids->{'def_end_group'} = undef; + my @keys = keys %$ids; + my $def_i = $keys[0]; + $def_i =~ s/^(.+)g.*$/\1/; + + $ids->{$def_i.'_end_$LOGIN'} = undef; + $ids->{$def_i.'_end_group'} = undef; $grade->create_from_ids($sout, $ids); } @@ -63,7 +69,7 @@ sub process opendir($dh, "$basedir/$year/$project_id/traces/") or croak "can't opendir $basedir/$year/$project_id/traces/: $!"; for my $dir (grep { ( ! /^\./ ) && -d "$basedir/$year/$project_id/traces/$_" } readdir($dh)) { - next if (! grep { $dir eq "defense_$_" } @defenses); + next if (grep { $dir eq "defense_$_" } @defenses); my $ids = {}; From 188650aeaf3350275c6c628f41b73bd38924e5fb Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 26 Sep 2013 07:07:54 +0200 Subject: [PATCH 111/364] Process.pm: catch errors in processes and log it --- ACU/Process.pm | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/ACU/Process.pm b/ACU/Process.pm index f0cc632..13ed468 100644 --- a/ACU/Process.pm +++ b/ACU/Process.pm @@ -62,9 +62,23 @@ sub do_work ($$$@) my $sax_handler = ProcessHandler->new($args); my $parser = XML::SAX::ParserFactory->parser( Handler => $sax_handler ); - $parser->parse_string(${ $_[0]{argref} }); + eval { + $parser->parse_string(${ $_[0]{argref} }); + } + if ($@) { + my $err = "Parse error: $@"; + log ERROR, $err; + return $err; + } - return $subref->($given_args, $args); + eval { + return $subref->($given_args, $args); + } + if ($@) { + my $err = $@; + log ERROR, $err; + return $err; + } } sub register_no_parse ($$;$) @@ -76,13 +90,23 @@ sub register_no_parse ($$;$) my $worker = Gearman::Worker->new; $worker->job_servers('gearmand:4730'); - $worker->register_function($funcname => sub { return $subref->($given_arg, $_[0]{argref}); }); + $worker->register_function($funcname => sub + { + eval { + return $subref->($given_arg, $_[0]{argref}); + } + if ($@) { + my $err = $@; + log ERROR, $err; + return $err; + } + }); # Disable exit on warning or error $ACU::Log::fatal_warn = 0; $ACU::Log::fatal_error = 0; - log DEBUG, "$funcname registered"; + log INFO, "$funcname registered"; $worker->work while 1; } @@ -103,7 +127,7 @@ sub register ($$;$$) $ACU::Log::fatal_warn = 0; $ACU::Log::fatal_error = 0; - log DEBUG, "$funcname registered"; + log INFO, "$funcname registered"; $worker->work while 1; } From babf3f7850927fbd941658abf4f6294c6e737bf0 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 26 Sep 2013 07:08:41 +0200 Subject: [PATCH 112/364] Working on moulette launching script --- process/files/moulette_get.pl | 120 ++++++++++++++++++++++++++++------ 1 file changed, 99 insertions(+), 21 deletions(-) diff --git a/process/files/moulette_get.pl b/process/files/moulette_get.pl index f5d48df..8a3ff12 100644 --- a/process/files/moulette_get.pl +++ b/process/files/moulette_get.pl @@ -3,74 +3,144 @@ use v5.10.1; use strict; use warnings; +use Carp; use Pod::Usage; -use File::Temp; +use File::Copy; +use File::Path qw(remove_tree); +use File::Temp qw/tempfile tempdir/; use ACU::Log; use ACU::Process; my %actions = ( "tar" => \&receive_tar, - "git" => \&receive_tar, # \&receive_git + "git" => \&receive_git, "tests" => \&create_testsuite, "moulette" => \&moulette, ); +sub prepare_dir +{ + my $year = shift; + my $project_id = shift; + my $rendu = shift; + + # TODO: replace ~calvair by the destination directory + my $dir = "~calvair/$year-$project_id-$rendu/"; + + if (! -d $dir) { + mkpath($destdir) or croak "An error occurs while creating directory: $!"; + } + + return $dir; +} + sub receive_tar { + my $args = shift; my $project_id = $args->{param}{id}; my $year = $args->{param}{year}; my $rendu = $args->{param}{rendu}; my $file = $args->{param}{file}; + my $login = $args->{param}{login} // "ref"; - if (!exists $args->{files}{$file}) { - return "No file named '$file' given". - } + croak "No file named '$file' given" if (!exists $args->{files}{$file}); - ($fh, $filename) = tempfile(SUFFIX => $file); + my ($fh, $filename) = tempfile(SUFFIX => $file); binmode($fh); print $fh $args->{files}{$file}; close $fh; + my $destdir = prepare_dir($year, $project_id, $file); # TODO: Call Fact for create .ff + # qx(Fact package create $filename $destdir/$login.ff) + croak "Cannot create $login.ff" if ($?); - return "Ok" + # Clean + unlink $filename; +} + +sub receive_git +{ + my $args = shift; + my $project_id = $args->{param}{id}; + my $year = $args->{param}{year}; + my $rendu = $args->{param}{rendu}; + my $file = $args->{param}{file}; + my $login = $args->{param}{login} // "ref"; + + croak "No file named '$file' given" if (!exists $args->{files}{$file}); + + my $tempdir = tempdir(); + open my $fh, "|tar -xz -C '$tempdir'"; + print $fh $args->{files}{$file}; + close $fh; + + croak "An error occurs while extracting the tarball" if ($?); + + my $destdir = prepare_dir($year, $project_id, $file); + # TODO: Call Fact for create .ff + # qx(Fact package create $tempdir $destdir/$login.ff) + croak "Cannot create $login.ff" if ($?); + + # Clean + remove_tree($tempdir); } sub create_testsuite { + my $args = shift; my $project_id = $args->{param}{id}; my $year = $args->{param}{year}; my $rendu = $args->{param}{rendu}; my $file = $args->{param}{file}; - ($fh, $filename) = tempfile(); + croak "No file named '$file' given" if (!exists $args->{files}{$file}); - if (!exists $args->{files}{$file}) { - return "No file named '$file' given". - } - - ($fh, $filename) = tempfile(SUFFIX => $file); - binmode($fh); + my $tempdir = tempdir(); + open my $fh, "|tar -xz -C '$tempdir'"; print $fh $args->{files}{$file}; close $fh; - # TODO: Call Fact to create testsuite + croak "An error occurs while extracting the tarball" if ($?); - return "Ok" + qx(make -C $tempdir/tests/); + croak "An error occurs while making the testsuite" if ($?); + + my $destdir = prepare_dir($year, $project_id, $rendu); + copy("$tempdir/tests/tests.ff", "$destdir/tests.ff") or croak "An error occurs while coping the testsuite: $!"; + copy("$tempdir/tests/test.ft", "$destdir/test.ft") or croak "An error occurs while coping test.ft: $!"; + + # Clean + remove_tree($tempdir); } sub moulette { + my $args = shift; my $project_id = $args->{param}{id}; my $year = $args->{param}{year}; my $rendu = $args->{param}{rendu}; - my $login = $args->{param}{login}; - # TODO: Call Fact to launch student tarball + my $testdir = prepare_dir($year, $project_id, $rendu); - return "Ok" + chdir($testdir); + for (my $i = $args->{unamed}; $i > 0; $i--) + { + my $login = $args->{param}{$i} + + open my $fhin, "<", "$testdir/test.ft"; + open my $fhout, ">", "$testdir/$login.ft"; + print $fhout s/#LOGIN_X/$login/g while (<$fhin>); + close $fhin; + close $fhout; + + # TODO: Call Fact to launch student tarball + # qx(Fact system manager $login.ft) + + log WARN, "An error occurs while starting tests for $login on $year-$project_id-$rendu" if ($?); + } } @@ -78,14 +148,22 @@ sub process_get { my ($given_args, $args) = @_; - my $type = $args->{param}{type}; + my $type = $args->{param}{type} // ""; if (! exists $actions{$type}) { log WARN, "Unknown type '$type'"; return "Unknown type '$type'."; } - return $actions{$type}($args); + eval { + $actions{$type}($args); + } + if ($@) { + my $err = $@; + log ERROR, $err; + return $err; + } + return "Ok"; } Process::register("moulette_get", \&process_get); From a40d249fd6a93c0c59de94de631c288259085fd5 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 26 Sep 2013 08:58:49 +0200 Subject: [PATCH 113/364] Add a tinyglobing package --- ACU/Tinyglob.pm | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ ACU/t/tinyglob.t | 22 ++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 ACU/Tinyglob.pm create mode 100644 ACU/t/tinyglob.t diff --git a/ACU/Tinyglob.pm b/ACU/Tinyglob.pm new file mode 100644 index 0000000..d400ead --- /dev/null +++ b/ACU/Tinyglob.pm @@ -0,0 +1,52 @@ +#! /usr/bin/env perl + +package Tinyglob; + +use v5.10.1; +use strict; +use warnings; +use Carp; +use Exporter 'import'; + +our @EXPORT = qw(tinyglob); + +sub tinyglob +{ + my @str = split("", quotemeta(shift)); + my $res = ""; + + my $metaescape = 0; + + for (my $i = 0; $i <= $#str; $i++) + { + if ($str[$i] eq '\\') + { + $i += 1; + if ($str[$i] eq '\\') + { + $metaescape = ! $metaescape; + $res .= $str[$i]; + } + elsif ($metaescape && ($str[$i] eq '*' || $str[$i] eq '?')) { + $res .= $str[$i]; + $metaescape = 0; + } + elsif ($str[$i] eq '?') { + $res .= '.'; + } + elsif ($str[$i] eq '*') { + $res .= '.*'; + } + else { + croak "Invalid number of \\"; + } + } + else { + $res .= $str[$i]; + } + } + + return $res; +} + +1; diff --git a/ACU/t/tinyglob.t b/ACU/t/tinyglob.t new file mode 100644 index 0000000..9d497c5 --- /dev/null +++ b/ACU/t/tinyglob.t @@ -0,0 +1,22 @@ +use v5.10.1; +use strict; +use warnings; + +use Test::More; + +use lib "../"; + +BEGIN { + diag("Testing Tinyglob on perl $]"); + use_ok('ACU::Tinyglob'); +} + +use ACU::Tinyglob; + +is(Tinyglob::tinyglob("test"), "test"); +is(Tinyglob::tinyglob("\\*"), "\\*"); +is(Tinyglob::tinyglob("\\\\*"), "\\\\.*"); +is(Tinyglob::tinyglob("\\?"), "\\?"); +is(Tinyglob::tinyglob("\\\\?"), "\\\\."); + +done_testing(); From 5fa70f72d84d52dea8438dd1e2cfdd5b01593f1b Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 26 Sep 2013 10:07:17 +0200 Subject: [PATCH 114/364] Tinyglob: add function to match --- ACU/Tinyglob.pm | 8 ++++++++ ACU/t/tinyglob.t | 30 ++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/ACU/Tinyglob.pm b/ACU/Tinyglob.pm index d400ead..3c19a5a 100644 --- a/ACU/Tinyglob.pm +++ b/ACU/Tinyglob.pm @@ -49,4 +49,12 @@ sub tinyglob return $res; } +sub match +{ + my $glob = tinyglob(shift); + my $str = shift; + + return $str =~ /$glob/; +} + 1; diff --git a/ACU/t/tinyglob.t b/ACU/t/tinyglob.t index 9d497c5..b3d27cb 100644 --- a/ACU/t/tinyglob.t +++ b/ACU/t/tinyglob.t @@ -19,4 +19,34 @@ is(Tinyglob::tinyglob("\\\\*"), "\\\\.*"); is(Tinyglob::tinyglob("\\?"), "\\?"); is(Tinyglob::tinyglob("\\\\?"), "\\\\."); +ok(! Tinyglob::match("?", "")); +ok(! Tinyglob::match("b", "a")); +ok(! Tinyglob::match("b*", "a")); +ok(! Tinyglob::match("b?", "a")); +ok(Tinyglob::match("*", "")); + +ok(Tinyglob::match("a", "a")); +ok(Tinyglob::match("?", "a")); +ok(Tinyglob::match("*", "a")); + +ok(Tinyglob::match("ab", "ab")); +ok(Tinyglob::match("?b", "ab")); +ok(Tinyglob::match("*b", "ab")); +ok(Tinyglob::match("*", "ab")); + +ok(Tinyglob::match("b?", "ba")); +ok(Tinyglob::match("b*", "ba")); +ok(Tinyglob::match("*", "abcdef")); + +ok(Tinyglob::match("a?b", "acb")); +ok(Tinyglob::match("a*b", "acb")); +ok(Tinyglob::match("a*b", "acdefb")); + +ok(Tinyglob::match("a*b*", "acdefblkjgd")); +ok(! Tinyglob::match("a?b*", "acdefblkjgd")); +ok(Tinyglob::match("a?b*", "acblkjgd")); +ok(Tinyglob::match("a?b*", "abblkjgd")); +ok(! Tinyglob::match("a*b?", "abblkjgd")); +ok(Tinyglob::match("a*b?", "aasdasbd")); + done_testing(); From 375640dba8768b47bafb89c61a3b549f1921aec5 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 26 Sep 2013 10:53:34 +0200 Subject: [PATCH 115/364] gen_grading: new method to generate name --- process/projects/gen_grading.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/projects/gen_grading.pl b/process/projects/gen_grading.pl index 09666ea..61b8f33 100644 --- a/process/projects/gen_grading.pl +++ b/process/projects/gen_grading.pl @@ -61,7 +61,7 @@ sub process $ids->{$def_i.'_end_$LOGIN'} = undef; $ids->{$def_i.'_end_group'} = undef; - $grade->create_from_ids($sout, $ids); + $grade->create_from_ids($sid, $ids); } closedir $dh; From 6952c85c5bbb4ad0d0057f07600ea2ffc1c954f0 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 26 Sep 2013 10:55:56 +0200 Subject: [PATCH 116/364] Use globing in notation --- ACU/Grading.pm | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ACU/Grading.pm b/ACU/Grading.pm index 81fd4aa..af1f112 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -7,6 +7,8 @@ use strict; use warnings; use XML::LibXML; +use ACU::Tinyglob; + sub new { my $class = shift; @@ -340,6 +342,14 @@ sub compute ($$$;$$$) $ref =~ s/\$LOGIN/$login/; } + my $glob = Tinyglob::tinyglob($ref); + if ($glob ne $ref) + { + my $value = 0; + $value += $ids->{$_} while (grep { /^$glob$/ } keys %$ids); + $ids->{ $ref } = $value; + } + my $ret = undef; my $result = ( From 4e289ec4425e867de3975dffc0486eeb5503ff4f Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 26 Sep 2013 11:03:24 +0200 Subject: [PATCH 117/364] Add ; after eval --- ACU/Process.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ACU/Process.pm b/ACU/Process.pm index 13ed468..a1473d3 100644 --- a/ACU/Process.pm +++ b/ACU/Process.pm @@ -64,7 +64,7 @@ sub do_work ($$$@) eval { $parser->parse_string(${ $_[0]{argref} }); - } + }; if ($@) { my $err = "Parse error: $@"; log ERROR, $err; @@ -73,7 +73,7 @@ sub do_work ($$$@) eval { return $subref->($given_args, $args); - } + }; if ($@) { my $err = $@; log ERROR, $err; @@ -94,7 +94,7 @@ sub register_no_parse ($$;$) { eval { return $subref->($given_arg, $_[0]{argref}); - } + }; if ($@) { my $err = $@; log ERROR, $err; From 20d78c5dae8666fc3be9b72e83091f4b239dd5ad Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 26 Sep 2013 11:38:17 +0200 Subject: [PATCH 118/364] Search globing if ref is defined --- ACU/Grading.pm | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/ACU/Grading.pm b/ACU/Grading.pm index af1f112..4c4fa22 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -342,12 +342,15 @@ sub compute ($$$;$$$) $ref =~ s/\$LOGIN/$login/; } - my $glob = Tinyglob::tinyglob($ref); - if ($glob ne $ref) + if (defined $ref) { - my $value = 0; - $value += $ids->{$_} while (grep { /^$glob$/ } keys %$ids); - $ids->{ $ref } = $value; + my $glob = Tinyglob::tinyglob($ref); + if ($glob ne $ref) + { + my $value = 0; + $value += $ids->{$_} while (grep { /^$glob$/ } keys %$ids); + $ids->{ $ref } = $value; + } } my $ret = undef; From 316f0d6bd98e5e0371c0a870f0fdc7b2e8764acf Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 26 Sep 2013 12:58:31 +0200 Subject: [PATCH 119/364] Add compatibility with FreeBSD site --- commands/first-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/first-install.sh b/commands/first-install.sh index b7c1ba5..92be843 100755 --- a/commands/first-install.sh +++ b/commands/first-install.sh @@ -49,7 +49,7 @@ then do if ! pkg info "$PK" > /dev/null 2> /dev/null then - pkg install "$PK" + PACKAGESITE="ttp://canon.acu.epita.fr/repo-lab" pkg install "$PK" fi done From c9e4aa3279600e3e3e0ab7c3787374cc4a6cb5be Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 26 Sep 2013 12:58:42 +0200 Subject: [PATCH 120/364] Fix --- ACU/Grading.pm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ACU/Grading.pm b/ACU/Grading.pm index 4c4fa22..dd1d64f 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -348,7 +348,9 @@ sub compute ($$$;$$$) if ($glob ne $ref) { my $value = 0; - $value += $ids->{$_} while (grep { /^$glob$/ } keys %$ids); + for my $r (grep { /^$glob$/ } keys %$ids) { + $value += $ids->{ $r }; + } $ids->{ $ref } = $value; } } From dbfd12ec9d04a9a1aee71786f6d2b71d6bac2565 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 27 Sep 2013 14:32:38 +0200 Subject: [PATCH 121/364] Fix process --- ACU/Process.pm | 8 ++++++-- commands/first-install.sh | 24 ++++++++++++------------ 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/ACU/Process.pm b/ACU/Process.pm index a1473d3..4298e8f 100644 --- a/ACU/Process.pm +++ b/ACU/Process.pm @@ -71,14 +71,16 @@ sub do_work ($$$@) return $err; } + my $ret; eval { - return $subref->($given_args, $args); + $ret = $subref->($given_args, $args); }; if ($@) { my $err = $@; log ERROR, $err; return $err; } + return $ret; } sub register_no_parse ($$;$) @@ -92,14 +94,16 @@ sub register_no_parse ($$;$) $worker->job_servers('gearmand:4730'); $worker->register_function($funcname => sub { + my $ret; eval { - return $subref->($given_arg, $_[0]{argref}); + $ret = $subref->($given_arg, $_[0]{argref}); }; if ($@) { my $err = $@; log ERROR, $err; return $err; } + return $ret; }); # Disable exit on warning or error diff --git a/commands/first-install.sh b/commands/first-install.sh index 92be843..1ababf0 100755 --- a/commands/first-install.sh +++ b/commands/first-install.sh @@ -5,7 +5,18 @@ DEB_PACKAGES_LIST="screen libnet-ldap-perl libxml-libxml-perl libgearman-client- ARCH_PACKAGES_LIST="screen perl-io-socket-ssl perl-email-simple perl-email-mime perl-term-readkey perl-ldap perl-lwp-protocol-https" FBSD_PACKAGES_LIST="screen p5-IO-Socket-SSL p5-Email-Simple p5-Email-MIME p5-Term-ANSIColor p5-Term-ReadKey p5-LWP-Protocol-https" -if [ -f "/etc/debian_version" ] +if [ `uname -s` = "FreeBSD" ] +then + + for PK in $FBSD_PACKAGES_LIST + do + if ! pkg info "$PK" > /dev/null 2> /dev/null + then + PACKAGESITE="ttp://canon.acu.epita.fr/repo-lab" pkg install "$PK" + fi + done + +elif [ -f "/etc/debian_version" ] then if ! whereis dpkg > /dev/null 2> /dev/null @@ -42,17 +53,6 @@ then fi done -elif [ -f "/etc/freebsd-update.conf" ] -then - - for PK in $FBSD_PACKAGES_LIST - do - if ! pkg info "$PK" > /dev/null 2> /dev/null - then - PACKAGESITE="ttp://canon.acu.epita.fr/repo-lab" pkg install "$PK" - fi - done - else echo "Unknown operating system :(" From 440f298d1472c6d6294cc01f93459e90574f50e4 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 28 Sep 2013 04:53:24 +0200 Subject: [PATCH 122/364] Improve migration script: scoped-include, \file, ... --- migration/repo.sh | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/migration/repo.sh b/migration/repo.sh index 7c0332a..b86774d 100755 --- a/migration/repo.sh +++ b/migration/repo.sh @@ -25,10 +25,10 @@ clean_tex() bi=`basename "$i"` echo -e "\e[1;34m>>>\e[1;37m Trying to convert $i to Markdown...\e[0m" - sed -Ei 's/\\include *\{([^}]+)}/\\verb+~include(\1)+/gi' "$i" - sed -Ei 's/\\input *\{([^}]+)}/\\verb+~include(\1)+/gi' "$i" - sed -Ei 's/\{\\include *([^}]+)}/\\verb+~include(\1)+/gi' "$i" - sed -Ei 's/\{\\input *([^}]+)}/\\verb+~include(\1)+/gi' "$i" + sed -Ei 's/\\include *\{([^}]+)}/\\verb+%%scoped-include(\1)+/gi' "$i" + sed -Ei 's/\\input *\{([^}]+)}/\\verb+%%scoped-include(\1)+/gi' "$i" + sed -Ei 's/\{\\include *([^}]+)}/\\verb+%%scoped-include(\1)+/gi' "$i" + sed -Ei 's/\{\\input *([^}]+)}/\\verb+%%scoped-include(\1)+/gi' "$i" sed -Ei 's/\\lstinline *\{([^}]+)}/\\verb+\1+/gi' "$i" sed -Ei 's/\\begin *\{correction\}/\\begin\{verbatim\}/g' "$i" sed -Ei 's/\\end *\{correction\}/\\end\{verbatim\}/g' "$i" @@ -41,6 +41,11 @@ clean_tex() sed -Ei 's/\\begin *\{cartouche_nospaces\}/\\begin\{verbatim\}/g' "$i" sed -Ei 's/\\end *\{cartouche_nospaces\}/\\end\{verbatim\}/g' "$i" + # Special macros + sed -Ei 's/\\file *\{([^}]+)}/\\verb+\1+/gi' "$i" + sed -Ei 's/\\begin *\{assistant\}/\\verb+%%assistant-begin+/g' "$i" + sed -Ei 's/\\end *\{assistant\}/\\verb+%%assistant-end+/g' "$i" + # Convert Beamer sed -Ei 's/\\begin\[[^]]+\]\{frame\}\{([^}]+)\}/\\subsection\{\1\}/g' "$i" sed -Ei 's/\\begin\{frame\}\{([^}]+)\}\[[^]]+\]/\\subsection\{\1\}/g' "$i" @@ -64,7 +69,7 @@ clean_tex() git rm -f "$i" > /dev/null fi - sed -Ei 's/`~?include\(([^)]+)\)`/~include(\1)/gi' "../${bi%%.tex}.md" + sed -Ei 's/`%%([a-z-])\(([^)]+)\)`/%%\1(\2)/gi' "../${bi%%.tex}.md" done if [ `find | wc -l` -gt 1 ] then From 1a142a9759b4e134f9a2ff699110bd01732df19e Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 28 Sep 2013 11:09:47 +0200 Subject: [PATCH 123/364] Log: ERROR2 is now ALERT --- ACU/Log.pm | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/ACU/Log.pm b/ACU/Log.pm index 53645cc..e33be5e 100644 --- a/ACU/Log.pm +++ b/ACU/Log.pm @@ -11,7 +11,7 @@ use Term::ANSIColor qw(:constants); use constant { FATAL => 1, - ERROR2 => 2, + ALERT => 2, ERROR => 3, WARN => 4, DONE => 5, @@ -21,7 +21,7 @@ use constant { TRACE => 9, }; -our @EXPORT = qw(log FATAL ERROR2 ERROR WARN DONE USAGE INFO DEBUG TRACE); +our @EXPORT = qw(log FATAL ALERT ERROR WARN DONE USAGE INFO DEBUG TRACE); our $display_level = 7; our $save_level = 9; @@ -31,7 +31,7 @@ our $fatal_warn = 0; our $log_file = $0.".log"; my $log_fd; -sub log($@) +sub log { my $level = shift; @@ -42,7 +42,7 @@ sub log($@) } if (!$log_fd && $log_file) { - open ($log_fd, ">>", $log_file) or die("Unable to open log ($log_file) file for writing"); + open ($log_fd, ">>", $log_file) or croak("Unable to open log ($log_file) file for writing"); say $log_fd strftime("%a %b %e %H:%M:%S %Y", localtime), " START new logging session "; } @@ -63,18 +63,15 @@ sub log($@) } if ($fatal_warn && $level <= WARN){ - #TODO Thibaut - #log(INFO, "Program stopped due to warning"); + log(INFO, "Program stopped due to warning"); exit 125; } elsif ($fatal_error && $level <= ERROR) { - #TODO Thibaut - #log(INFO, "Program stopped due to error"); + log(INFO, "Program stopped due to error"); exit 126; } elsif ($level <= FATAL) { - #TODO Thibaut - #log(INFO, "Program stopped due to fatal error"); + log(INFO, "Program stopped due to fatal error"); exit 127; } } @@ -84,7 +81,8 @@ sub levelstr($) my $level = shift; return "FATAL" if ($level == 1); - return "ERROR" if ($level == 3 or $level == 2); + return "ALERT" if ($level == 2); + return "ERROR" if ($level == 3); return "WARN " if ($level == 4); return "DONE " if ($level == 5); return "USAGE" if ($level == 6); From d5052ca23981b95dc25b3bc0433ec8009352bbd3 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 28 Sep 2013 11:12:30 +0200 Subject: [PATCH 124/364] Project: simplify code --- ACU/API/Submission.pm | 4 ++-- ACU/Project.pm | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ACU/API/Submission.pm b/ACU/API/Submission.pm index fa1b182..ecca803 100644 --- a/ACU/API/Submission.pm +++ b/ACU/API/Submission.pm @@ -9,7 +9,7 @@ use Carp; use ACU::API::Base; -sub add($$$$$) +sub add { my $year = shift; my $project = shift; @@ -24,7 +24,7 @@ sub add($$$$$) } } -sub get($$$$) +sub get { my $year = shift; my $project = shift; diff --git a/ACU/Project.pm b/ACU/Project.pm index 1a25064..f00ac0d 100644 --- a/ACU/Project.pm +++ b/ACU/Project.pm @@ -69,7 +69,7 @@ sub start_element if ($element->{Name} eq "project" || $element->{Name} eq "Project") { $self->{parsed}{name} = $element->{Attributes}{"{}name"}{Value} if ($element->{Attributes}{"{}name"}); } - elsif (grep { /^\Q$element->{Name}\E$/ } @stack_tags) + elsif (grep { $element->{Name} eq $_ } @stack_tags) { my $data = {}; @@ -79,7 +79,7 @@ sub start_element push @{ $self->{stack} }, $data; } - elsif (grep { /^\Q$element->{Name}\E$/ } @value_tags) { + elsif (grep { $element->{Name} eq $_ } @value_tags) { $self->{saveChars} = 1; $self->{values} = ""; } @@ -100,7 +100,7 @@ sub start_element quota => $element->{Attributes}{"{}quota"}{Value} // 10, }; } - elsif (grep { /^\Q$element->{Name}\E$/ } @stackonce_tags) { + elsif (grep { $element->{Name} eq $_ } @stackonce_tags) { push @{ $self->{stack} }, { }; } } @@ -132,7 +132,7 @@ sub end_element $self->{saveChars} = 0; } - elsif (grep { /^\Q$element->{Name}\E$/ } @stack_tags) + elsif (grep { $element->{Name} eq $_ } @stack_tags) { my $item = pop @{ $self->{stack} }; my $pop = pop @{ $self->{stack} }; @@ -160,7 +160,7 @@ sub end_element } } - elsif (grep { /^\Q$element->{Name}\E$/ } @stackonce_tags) + elsif (grep { $element->{Name} eq $_ } @stackonce_tags) { my $item = pop @{ $self->{stack} }; my $pop = pop @{ $self->{stack} }; From d8a7ce5ecfcd016aea7be3a80718c6b4d7ab611b Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 28 Sep 2013 11:13:07 +0200 Subject: [PATCH 125/364] Improving migration script --- migration/repo.sh | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/migration/repo.sh b/migration/repo.sh index b86774d..46dd4f0 100755 --- a/migration/repo.sh +++ b/migration/repo.sh @@ -25,6 +25,7 @@ clean_tex() bi=`basename "$i"` echo -e "\e[1;34m>>>\e[1;37m Trying to convert $i to Markdown...\e[0m" + sed -Ei 's/\\includegraphics *\{([^}]+)}/\\verb+%%image(\1)+/gi' "$i" sed -Ei 's/\\include *\{([^}]+)}/\\verb+%%scoped-include(\1)+/gi' "$i" sed -Ei 's/\\input *\{([^}]+)}/\\verb+%%scoped-include(\1)+/gi' "$i" sed -Ei 's/\{\\include *([^}]+)}/\\verb+%%scoped-include(\1)+/gi' "$i" @@ -40,9 +41,10 @@ clean_tex() sed -Ei 's/\\end *\{cartouche\}/\\end\{verbatim\}/g' "$i" sed -Ei 's/\\begin *\{cartouche_nospaces\}/\\begin\{verbatim\}/g' "$i" sed -Ei 's/\\end *\{cartouche_nospaces\}/\\end\{verbatim\}/g' "$i" + sed -Ei 's/\\verb ([^+]+) /\\verb+\1+/g' "$i" # Special macros - sed -Ei 's/\\file *\{([^}]+)}/\\verb+\1+/gi' "$i" + sed -Ei 's/\\(file|email|command) *\{([^}]+)}/\\verb+\1+/gi' "$i" sed -Ei 's/\\begin *\{assistant\}/\\verb+%%assistant-begin+/g' "$i" sed -Ei 's/\\end *\{assistant\}/\\verb+%%assistant-end+/g' "$i" @@ -70,6 +72,7 @@ clean_tex() fi sed -Ei 's/`%%([a-z-])\(([^)]+)\)`/%%\1(\2)/gi' "../${bi%%.tex}.md" + sed -Ei 's/\\$/\n/' "../${bi%%.tex}.md" done if [ `find | wc -l` -gt 1 ] then @@ -150,7 +153,7 @@ then echo -e "\e[1;34m>>>\e[1;37m Creating moulette branch...\e[0m" git checkout -b moulette - find -mindepth 1 -maxdepth 1 ! -name moulette ! -name .git -exec git rm -rf {} \; + find -mindepth 1 -maxdepth 1 ! -name moulette ! -name tests ! -name .git -exec git rm -rf {} \; git rm -f moulette/DESC 2> /dev/null git commit -am "Converting HG to Git" > /dev/null @@ -178,6 +181,7 @@ echo echo -e "\e[1;31m##\e[1;37m Removing old and temporary files \e[1;31m##\e[0m" git rm -f AUTHORS git rm -f README +git rm -f UPDATE git rm -f Makefile git rm -f files/list git rm -f "files/*.pdf" @@ -186,6 +190,7 @@ find -name 'ChangeLog' -exec git rm -fr {} \; find -name 'DESC' -exec git rm -fr {} \; find -name '*.old' -exec git rm -fr {} \; find -name '*.bak' -exec git rm -fr {} \; +find -name '*.vrb' -exec git rm -fr {} \; find -name '*~' -exec git rm -fr {} \; find -name '#*#' -exec git rm -fr {} \; echo -e "\e[1;31m## ## ## ## ##\e[0m" @@ -202,7 +207,7 @@ do do if [ -f "$D/template.xml" ] then - ~/new_intra/defenses/defense_converter.pl -o "$D.xml" "$D/template.xml" + `dirname $0`/defense_converter.pl -o "$D.xml" "$D/template.xml" git add "$D.xml" echo -e "\e[1;35m>>>\e[1;37m Defense converted:\e[0m $D" fi @@ -219,6 +224,13 @@ do echo -e "\e[1;36m## ## ## ## ##\e[0m" echo + elif [ "$DIR" = "tests" ] + then + echo -e "\e[1;33m##\e[1;37m Find directory $DIR for moulette \e[1;33m##\e[0m" + git rm -rf "$DIR" + echo -e "\e[1;33m## ## ## ## ##\e[0m" + echo + elif find "$DIR" -type f -name '*.yml' | grep yml > /dev/null then echo -e "\e[1;33m##\e[1;37m Find directory $DIR with some .yml files \e[1;33m##\e[0m" From 8f5cd9a6bef09edbce5ea07468dd78ddaf9ebedb Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 28 Sep 2013 11:14:45 +0200 Subject: [PATCH 126/364] New packages and improve installation quality --- Makefile | 8 ++--- commands/first-install.sh | 76 ++++++++++++++++++++++----------------- 2 files changed, 48 insertions(+), 36 deletions(-) diff --git a/Makefile b/Makefile index 4131e7d..29f7c7c 100644 --- a/Makefile +++ b/Makefile @@ -15,8 +15,8 @@ install: $(SHELL) commands/first-install.sh $(MAKEDIR) -p $(DEST) $(COPY) -r ACU/ $(DEST) - test -d $(GITOLITE_DEST) && $(MAKEDIR) -p $(GITOLITE_DEST)/update.secondary.d - test -d $(GITOLITE_DEST) && $(COPY) hooks/* $(GITOLITE_DEST)/update.secondary.d/ + ! test -d $(GITOLITE_DEST) || $(MAKEDIR) -p $(GITOLITE_DEST)/update.secondary.d + ! test -d $(GITOLITE_DEST) || $(COPY) hooks/* $(GITOLITE_DEST)/update.secondary.d/ update: $(GIT) pull @@ -26,8 +26,8 @@ upgrade: install unstall: $(RM) -r $(DEST)/ACU/ - test -d $(GITOLITE_DEST) && $(RM) -rf $(GITOLITE_DEST)/update.secondary.d - test -d $(GITOLITE_DEST) && $(MAKEDIR) -p $(GITOLITE_DEST)/update.secondary.d + ! test -d $(GITOLITE_DEST) || $(RM) -rf $(GITOLITE_DEST)/update.secondary.d + ! test -d $(GITOLITE_DEST) || $(MAKEDIR) -p $(GITOLITE_DEST)/update.secondary.d test: $(PROVER) $(TESTDIR) diff --git a/commands/first-install.sh b/commands/first-install.sh index 1ababf0..9a3d158 100755 --- a/commands/first-install.sh +++ b/commands/first-install.sh @@ -1,58 +1,70 @@ #! /bin/bash -# Install missing packets -DEB_PACKAGES_LIST="screen libnet-ldap-perl libxml-libxml-perl libgearman-client-perl libmailtools-perl libmail-sendmail-perl libdate-manip-perl" -ARCH_PACKAGES_LIST="screen perl-io-socket-ssl perl-email-simple perl-email-mime perl-term-readkey perl-ldap perl-lwp-protocol-https" -FBSD_PACKAGES_LIST="screen p5-IO-Socket-SSL p5-Email-Simple p5-Email-MIME p5-Term-ANSIColor p5-Term-ReadKey p5-LWP-Protocol-https" +# Install missing packages +DEB_PACKAGES_LIST="screen libnet-ldap-perl libxml-libxml-perl libgearman-client-perl libmailtools-perl libmail-sendmail-perl libdatetime-format-iso8601-perl libnet-ip-perl" +ARCH_PACKAGES_LIST="screen perl-io-socket-ssl perl-email-simple perl-email-mime perl-term-readkey perl-ldap perl-lwp-protocol-https perl-datetime-format-iso8601 perl-net-ip" +FBSD_PACKAGES_LIST="screen p5-IO-Socket-SSL p5-Email-Simple p5-Email-MIME p5-Term-ANSIColor p5-Term-ReadKey p5-LWP-Protocol-https p5-DateTime-Format-ISO8601 p5-Net-IP" -if [ `uname -s` = "FreeBSD" ] +KERNEL=`uname -s` + +if [ "$KERNEL" = "FreeBSD" ] then for PK in $FBSD_PACKAGES_LIST do if ! pkg info "$PK" > /dev/null 2> /dev/null then - PACKAGESITE="ttp://canon.acu.epita.fr/repo-lab" pkg install "$PK" + PACKAGESITE="http://canon.acu.epita.fr/repo-lab" pkg install "$PK" fi done -elif [ -f "/etc/debian_version" ] +elif [ "$KERNEL" = "Linux"] then - if ! whereis dpkg > /dev/null 2> /dev/null + if [ -f "/etc/debian_version" ] then - aptitude install dpkg - fi - for PK in $DEB_PACKAGES_LIST - do - if ! dpkg -l | grep "^ii" | grep "$PK" > /dev/null 2> /dev/null + if ! whereis dpkg > /dev/null 2> /dev/null then - aptitude install "$PK" + aptitude install dpkg fi - done + + for PK in $DEB_PACKAGES_LIST + do + if ! dpkg -l | grep "^ii" | grep "$PK" > /dev/null 2> /dev/null + then + aptitude install "$PK" + fi + done - # Add intradmin user if missing - if ! getent passwd | grep "intradmin:" > /dev/null 2> /dev/null + # Add intradmin user if missing + if ! getent passwd | grep "intradmin:" > /dev/null 2> /dev/null + then + useradd --shell /bin/false --uid 942 intradmin && + mkdir -p /home/intradmin + fi + + chown -R intradmin:intradmin /home/intradmin + + elif [ -f "/etc/arch-release" ] then - useradd --shell /bin/false --uid 942 intradmin && - mkdir -p /home/intradmin + + for PK in $ARCH_PACKAGES_LIST + do + if ! pacman -Qi "$PK" > /dev/null 2> /dev/null + then + pacman -S "$PK" + fi + done + + else + + echo "Unknown distribution :(" + exit 1; + fi - chown -R intradmin:intradmin /home/intradmin - -elif [ -f "/etc/arch-release" ] -then - - for PK in $ARCH_PACKAGES_LIST - do - if ! pacman -Qi "$PK" > /dev/null 2> /dev/null - then - pacman -S "$PK" - fi - done - else echo "Unknown operating system :(" From a1e0e62b9cff5aa233cce0215bacf759bf670eac Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 28 Sep 2013 11:15:31 +0200 Subject: [PATCH 127/364] Check IP in gl-pre-git hook --- hooks/gl-pre-git | 38 ++++++++++++++++++ hooks/submissions.pl | 96 ++++++++++++++++++-------------------------- 2 files changed, 76 insertions(+), 58 deletions(-) create mode 100755 hooks/gl-pre-git diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git new file mode 100755 index 0000000..97946b3 --- /dev/null +++ b/hooks/gl-pre-git @@ -0,0 +1,38 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use v5.10; +use File::Basename; +use Net::IP; + +use ACU::Log; +$ACU::Log::log_file = "/var/log/hooks/" . basename($0) . ".log"; + +# First, check if the repository is in the YYYY/ directory +exit 0 if ($ENV{GL_REPO} !~ /^2[0-9]{3}\/.+\/.+/); + + +my $ip = $1 if ($ENV{'SSH_CLIENT'} =~ m/([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*/); +say "Votre IP est : $ip."; + +$ip = Net::IP->new($ip) or die ("IP invalide"); + +my $schoolnetwork = Net::IP->new('192.168.0.0/16'); + +if ($ip->overlaps($schoolnetwork) != $IP_A_IN_B_OVERLAP) +{ + log ERROR, "Vous n'êtes pas autorisé à envoyer vos modifications depuis cette IP."; + exit 1; +} + +my $sshnetwork = Net::IP->new('10.41.253.0/24'); + +if ($ip->overlaps($sshnetwork) == $IP_A_IN_B_OVERLAP) +{ + log ERROR, "Vous n'êtes pas autorisé à envoyer vos modifications depuis cette IP."; + exit 1; +} + + +exit 0; diff --git a/hooks/submissions.pl b/hooks/submissions.pl index b51e278..3032555 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -3,8 +3,10 @@ use strict; use warnings; use v5.10; -use Date::Manip; +use DateTime::Format::ISO8601; use File::Basename; +use Net::IP; +use POSIX qw(strftime); use Socket; use ACU::API::Projects; @@ -28,29 +30,6 @@ if ($ref =~ m<^refs/tags/(.+)$>) my $tag = $1; log DEBUG, "Pushed tag for repository $ENV{GL_REPO}: $tag with IP $ENV{'SSH_CLIENT'}"; - my $ip = $1 if ($ENV{'SSH_CLIENT'} =~ m/([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*/); - say "[ACU] Your IP is: $ip."; - - $ip = ip2long($ip); - - my $net = ip2long("10.41.0.0"); - my $mask = ip2long("255.255.0.0"); - - if (($ip & $mask) != ($net & $mask)) - { - log ERROR, "[ACU] You are not authorized to push from this IP. This will be reported."; - exit 1; - } - - $net = ip2long("10.41.253.0"); - $mask = ip2long("255.255.255.0"); - - if (($ip & $mask) == ($net & $mask)) - { - log ERROR, "[ACU] You are not authorized to push from this IP. This will be reported."; - exit 1; - } - # Get project informations my $project; eval { @@ -71,64 +50,65 @@ if ($ref =~ m<^refs/tags/(.+)$>) exists $_->{vcs} and $_->{vcs}{tag} eq $tag; } @{ $project->{submissions} }; - my $date = $ENV{'GL_TS'}; - $date =~ s/\./ /; - my $glts = ParseDate($date); + my $glts = DateTime::Format::ISO8601->parse_datetime( + do { + my $t = $ENV{'GL_TS'}; + $t =~ tr/./T/; + $t + }); chomp (my $tokengiven = `git cat-file tag $newsha 2> /dev/null | sed -e '1,/^\$/d'`); for my $rendu (@rendus) { - my $open = ParseDate($rendu->{period}{begin}); - my $close = ParseDate($rendu->{period}{end}); + my $open = DateTime::Format::ISO8601->parse_datetime($rendu->{period}{begin}); + my $close = DateTime::Format::ISO8601->parse_datetime($rendu->{period}{end}); # TODO: check exceptions by login/group - say "[ACU] Date courante: ", $glts; - say "[ACU] Date fermeture: ", $close; + say "Date courante : ", $glts->strftime("%d/%m/%Y %H:%M:%S"); - if ((Date_Cmp($glts, $open) == -1)) + if (DateTime->compare($glts, $open) == -1) { - say "[ACU] Tag not allowed: upload not yet opened!"; + say "Date d'ouverture : ", $open->strftime("%d/%m/%Y %H:%M:%S"); + log ERROR, "Tag rejeté : le rendu n'est pas encore ouvert."; exit(4); } - if ((Date_Cmp($glts, $close) == 1)) + say "Date de fermeture : ", $close->strftime("%d/%m/%Y %H:%M:%S"); + + if (DateTime->compare($glts, $close) == 1) { - say "[ACU] Tag not allowed: upload closed!"; + log ERROR, "Tag rejeté : le rendu est clos."; exit(5); } my $token = $rendu->{vcs}{token}; - if ($token ne "" and $token ne $tokengiven) + if ($token ne "" and $token ne $tokengiven and $newsha ne '0' x 40) { - say "[ACU] Error 0x65cd58: Bad token."; + log ERROR, "Tag rejeté : mauvais token."; exit(6); } } - # Send data to API - my $last_commit = `git log -1 --name-status`; - eval { - API::Submission::add($promo, $id_project, $tag, $repo_login, $last_commit); - }; - if ($@) { - my $err = $@; - log DEBUG, "ERROR: ".$err; - log DONE, "[ACU] Upload successful"; + if ($newsha eq '0' x 40) { + log USAGE, "Mais pour quelle raison voudriez-vous supprimer un tag ?!"; } - else { - log DONE, "[ACU] Upload successful, please check this information on the intranet"; + else + { + # Send data to API + my $last_commit = `git log $newsha -1 --decorate --tags`; + eval { + API::Submission::add($promo, $id_project, $tag, $repo_login, $last_commit); + }; + if ($@) { + my $err = $@; + log DEBUG, "ERROR: ".$err; + log DONE, "Tag '$tag' effectué avec succès !"; + } + else { + log DONE, "Tag '$tag' effectué avec succès ! Vérifiez-le sur l'intranet."; + } } } exit 0; - -sub ip2long -{ - return unpack("l*", pack("l*", unpack("N*", inet_aton(shift)))); -} - -sub long2ip -{ - return inet_ntoa(pack("N*", shift)); -} From d7686f68c0cac4381711ee8cf2784f1a617f6e9e Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 28 Sep 2013 11:15:31 +0200 Subject: [PATCH 128/364] Check IP in gl-pre-git hook --- commands/first-install.sh | 2 +- hooks/gl-pre-git | 38 ++++++++++++++++ hooks/submissions.pl | 96 ++++++++++++++++----------------------- 3 files changed, 77 insertions(+), 59 deletions(-) create mode 100755 hooks/gl-pre-git diff --git a/commands/first-install.sh b/commands/first-install.sh index 9a3d158..706e3e1 100755 --- a/commands/first-install.sh +++ b/commands/first-install.sh @@ -18,7 +18,7 @@ then fi done -elif [ "$KERNEL" = "Linux"] +elif [ "$KERNEL" = "Linux" ] then if [ -f "/etc/debian_version" ] diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git new file mode 100755 index 0000000..97946b3 --- /dev/null +++ b/hooks/gl-pre-git @@ -0,0 +1,38 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use v5.10; +use File::Basename; +use Net::IP; + +use ACU::Log; +$ACU::Log::log_file = "/var/log/hooks/" . basename($0) . ".log"; + +# First, check if the repository is in the YYYY/ directory +exit 0 if ($ENV{GL_REPO} !~ /^2[0-9]{3}\/.+\/.+/); + + +my $ip = $1 if ($ENV{'SSH_CLIENT'} =~ m/([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*/); +say "Votre IP est : $ip."; + +$ip = Net::IP->new($ip) or die ("IP invalide"); + +my $schoolnetwork = Net::IP->new('192.168.0.0/16'); + +if ($ip->overlaps($schoolnetwork) != $IP_A_IN_B_OVERLAP) +{ + log ERROR, "Vous n'êtes pas autorisé à envoyer vos modifications depuis cette IP."; + exit 1; +} + +my $sshnetwork = Net::IP->new('10.41.253.0/24'); + +if ($ip->overlaps($sshnetwork) == $IP_A_IN_B_OVERLAP) +{ + log ERROR, "Vous n'êtes pas autorisé à envoyer vos modifications depuis cette IP."; + exit 1; +} + + +exit 0; diff --git a/hooks/submissions.pl b/hooks/submissions.pl index b51e278..3032555 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -3,8 +3,10 @@ use strict; use warnings; use v5.10; -use Date::Manip; +use DateTime::Format::ISO8601; use File::Basename; +use Net::IP; +use POSIX qw(strftime); use Socket; use ACU::API::Projects; @@ -28,29 +30,6 @@ if ($ref =~ m<^refs/tags/(.+)$>) my $tag = $1; log DEBUG, "Pushed tag for repository $ENV{GL_REPO}: $tag with IP $ENV{'SSH_CLIENT'}"; - my $ip = $1 if ($ENV{'SSH_CLIENT'} =~ m/([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*/); - say "[ACU] Your IP is: $ip."; - - $ip = ip2long($ip); - - my $net = ip2long("10.41.0.0"); - my $mask = ip2long("255.255.0.0"); - - if (($ip & $mask) != ($net & $mask)) - { - log ERROR, "[ACU] You are not authorized to push from this IP. This will be reported."; - exit 1; - } - - $net = ip2long("10.41.253.0"); - $mask = ip2long("255.255.255.0"); - - if (($ip & $mask) == ($net & $mask)) - { - log ERROR, "[ACU] You are not authorized to push from this IP. This will be reported."; - exit 1; - } - # Get project informations my $project; eval { @@ -71,64 +50,65 @@ if ($ref =~ m<^refs/tags/(.+)$>) exists $_->{vcs} and $_->{vcs}{tag} eq $tag; } @{ $project->{submissions} }; - my $date = $ENV{'GL_TS'}; - $date =~ s/\./ /; - my $glts = ParseDate($date); + my $glts = DateTime::Format::ISO8601->parse_datetime( + do { + my $t = $ENV{'GL_TS'}; + $t =~ tr/./T/; + $t + }); chomp (my $tokengiven = `git cat-file tag $newsha 2> /dev/null | sed -e '1,/^\$/d'`); for my $rendu (@rendus) { - my $open = ParseDate($rendu->{period}{begin}); - my $close = ParseDate($rendu->{period}{end}); + my $open = DateTime::Format::ISO8601->parse_datetime($rendu->{period}{begin}); + my $close = DateTime::Format::ISO8601->parse_datetime($rendu->{period}{end}); # TODO: check exceptions by login/group - say "[ACU] Date courante: ", $glts; - say "[ACU] Date fermeture: ", $close; + say "Date courante : ", $glts->strftime("%d/%m/%Y %H:%M:%S"); - if ((Date_Cmp($glts, $open) == -1)) + if (DateTime->compare($glts, $open) == -1) { - say "[ACU] Tag not allowed: upload not yet opened!"; + say "Date d'ouverture : ", $open->strftime("%d/%m/%Y %H:%M:%S"); + log ERROR, "Tag rejeté : le rendu n'est pas encore ouvert."; exit(4); } - if ((Date_Cmp($glts, $close) == 1)) + say "Date de fermeture : ", $close->strftime("%d/%m/%Y %H:%M:%S"); + + if (DateTime->compare($glts, $close) == 1) { - say "[ACU] Tag not allowed: upload closed!"; + log ERROR, "Tag rejeté : le rendu est clos."; exit(5); } my $token = $rendu->{vcs}{token}; - if ($token ne "" and $token ne $tokengiven) + if ($token ne "" and $token ne $tokengiven and $newsha ne '0' x 40) { - say "[ACU] Error 0x65cd58: Bad token."; + log ERROR, "Tag rejeté : mauvais token."; exit(6); } } - # Send data to API - my $last_commit = `git log -1 --name-status`; - eval { - API::Submission::add($promo, $id_project, $tag, $repo_login, $last_commit); - }; - if ($@) { - my $err = $@; - log DEBUG, "ERROR: ".$err; - log DONE, "[ACU] Upload successful"; + if ($newsha eq '0' x 40) { + log USAGE, "Mais pour quelle raison voudriez-vous supprimer un tag ?!"; } - else { - log DONE, "[ACU] Upload successful, please check this information on the intranet"; + else + { + # Send data to API + my $last_commit = `git log $newsha -1 --decorate --tags`; + eval { + API::Submission::add($promo, $id_project, $tag, $repo_login, $last_commit); + }; + if ($@) { + my $err = $@; + log DEBUG, "ERROR: ".$err; + log DONE, "Tag '$tag' effectué avec succès !"; + } + else { + log DONE, "Tag '$tag' effectué avec succès ! Vérifiez-le sur l'intranet."; + } } } exit 0; - -sub ip2long -{ - return unpack("l*", pack("l*", unpack("N*", inet_aton(shift)))); -} - -sub long2ip -{ - return inet_ntoa(pack("N*", shift)); -} From ba75c5c8fde19d86041edbec1d895f27c609d5a4 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 28 Sep 2013 13:39:31 +0200 Subject: [PATCH 129/364] manage_server: Add new command to view log remotely --- commands/manage-server.sh | 110 +++++++++++++++++++++++++++----------- process/view_log.sh | 67 +++++++++++++++++++++++ 2 files changed, 145 insertions(+), 32 deletions(-) create mode 100644 process/view_log.sh diff --git a/commands/manage-server.sh b/commands/manage-server.sh index ca7b7bb..36673f8 100755 --- a/commands/manage-server.sh +++ b/commands/manage-server.sh @@ -5,53 +5,99 @@ cd $(dirname "$0") WKS_LIST="apl" SRV_LIST="moore noyce hamano cpp" -ACTIONS="start stop restart update" +KNOWN_ACTIONS="start stop restart update log viewlog view_log" LOG=`mktemp` -for ACT in $ACTIONS +ACTIONS= +DESTS= +USED=1 +while [ $# -gt 0 ] && [ $USED -eq 1 ] do - if [ -n "$1" ] && [ "$1" == "$ACT" ] + + USED=0 + + for ACT in $KNOWN_ACTIONS + do + if [ -n "$1" ] && [ "$1" == "$ACT" ] + then + ACTIONS="$ACTIONS $ACT" + USED=1 + break + fi + done + + for DEST in $WKS_LIST $SRV_LIST + do + if [ -n "$1" ] && [ "$1" == "$DEST" ] + then + DESTS="$DESTS $DEST" + USED=1 + break + fi + done + + if [ "$1" == "@srv" ] then - ACTION="$ACT" - break + DESTS="$DESTS $SRV_LIST" + USED=1 + elif [ "$1" == "@wks" ] + then + DESTS="$DESTS $WKS_LIST" + USED=1 fi + + if [ $USED -eq 1 ] + then + shift + fi + done -if [ -z "$ACTION" ] + +if [ -z "$ACTIONS" ] then - echo "Usage: $0 [$ACTIONS]" + echo "Usage: $0 [where] <`echo $KNOWN_ACTIONS | sed 's/ /|/g'`> [options]" + exit 1 fi -FAIL=0 -for SRV in $SRV_LIST -do - echo -e "\e[1;34m>>>\e[0m $ACTION on $SRV" - if [ "$ACTION" == "update" ] - then - ssh root@$SRV "make -C liblerdorf update upgrade" - else - ssh root@$SRV '~'/liblerdorf/process/launch.sh "$ACTION" - fi +if [ -z "$DESTS" ] +then + DESTS="$SRV_LIST $WKS_LIST" +fi - if [ $? -eq 0 ] - then - echo -e "\e[1;32m>>>\e[0m $ACTION success on $SRV" | tee -a "$LOG" - else - echo -e "\e[1;31m>>>\e[0m $ACTION fails on $SRV" | tee -a "$LOG" - FAIL=1 - fi - echo +OPTIONS= +while [ $# -gt 0 ] +do + OPTIONS="$OPTIONS $1" + shift done -for WKS in $WKS_LIST +FAIL=0 +for ACTION in $ACTIONS do - echo -e "\e[1;34m>>>\e[0m $ACTION on $WKS" - if [ "$ACTION" == "update" ] - then - ssh root@$SRV "make -C liblerdorf update upgrade" - fi - echo + for DEST in $DESTS + do + echo -e "\e[1;34m>>>\e[0m \e[33m$ACTION\e[0m on \e[1m$DEST\e[0m" + if [ "$ACTION" == "update" ] + then + ssh root@$DEST "make -C liblerdorf update upgrade" + elif [ "$ACTION" == "log" ] || [ "$ACTION" == "viewlog" ] || [ "$ACTION" == "view_log" ] + then + ssh root@$DEST '~'/liblerdorf/process/view_log.sh $OPTIONS + else + ssh root@$DEST '~'/liblerdorf/process/launch.sh "$ACTION" + fi + + if [ $? -eq 0 ] + then + echo -e "\e[1;32m>>>\e[0m \e[33m$ACTION\e[0m success on \e[1m$DEST\e[0m" | tee -a "$LOG" + else + echo -e "\e[1;31m>>>\e[0m \e[33m$ACTION\e[0m fails on \e[1m$DEST\e[0m" | tee -a "$LOG" + FAIL=1 + fi + echo + done done cat "$LOG" diff --git a/process/view_log.sh b/process/view_log.sh new file mode 100644 index 0000000..7b7347f --- /dev/null +++ b/process/view_log.sh @@ -0,0 +1,67 @@ +#! /bin/sh + +cd `dirname $0`/.. + +UN=$1 +if [ "$1" = "full" ] +then + CMD=cat + shift +elif echo "$1" | grep -e '^-' > /dev/null +then + CMD="tail -n `echo $1 | cut -d '-' -f 2-`" + shift +else + CMD="tail -n 50" +fi + +TMP=`mktemp` + +DIRS="./" +if [ -d "/var/log/hooks/" ] +then + DIRS="$DIRS /var/log/hooks/" +fi + +if [ $# -eq 0 ] +then + + for D in $DIRS + do + for I in `find "$D" -name '*.log'` + do + /bin/echo -e "`dirname ${I#$D}`/\e[1m`basename $I`\e[0m" + done + done + +else + + LIST=`mktemp` + + find $DIRS -name '*.log' > $LIST + + while [ $# -gt 0 ] + do + + NB=`grep "/$1" "$LIST" | wc -l` + if [ $NB = 1 ] + then + $CMD `grep "/$1" "$LIST"` + echo + elif [ $NB -gt 1 ] + then + echo "Too much matching file for '$1':" + for I in `grep "$1" "$LIST" | sed -E 's#^./##'` + do + /bin/echo -e "`dirname $I`/\e[1m`basename $I`\e[0m" + done + else + echo "Unable to find '$1' log file" + exit 1 + fi + shift + + done + + rm -rf "$LIST"; +fi From 56af84d6cbb94b939eba916c63dcfad2b733432a Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 28 Sep 2013 13:43:27 +0200 Subject: [PATCH 130/364] Fix log function --- ACU/Log.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ACU/Log.pm b/ACU/Log.pm index e33be5e..30752cc 100644 --- a/ACU/Log.pm +++ b/ACU/Log.pm @@ -63,15 +63,15 @@ sub log } if ($fatal_warn && $level <= WARN){ - log(INFO, "Program stopped due to warning"); + #log(INFO, "Program stopped due to warning"); exit 125; } elsif ($fatal_error && $level <= ERROR) { - log(INFO, "Program stopped due to error"); + #log(INFO, "Program stopped due to error"); exit 126; } elsif ($level <= FATAL) { - log(INFO, "Program stopped due to fatal error"); + #log(INFO, "Program stopped due to fatal error"); exit 127; } } From c4620ac241df517e83e7aaee0b72d7dacb5c07bc Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 28 Sep 2013 13:47:08 +0200 Subject: [PATCH 131/364] Add execution write to view_log --- process/view_log.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 process/view_log.sh diff --git a/process/view_log.sh b/process/view_log.sh old mode 100644 new mode 100755 From 8132fdb3e1f9359cc7b8d8d925a0963733d65f66 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 28 Sep 2013 18:39:15 +0200 Subject: [PATCH 132/364] Manage_server: can clean logs --- process/view_log.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/process/view_log.sh b/process/view_log.sh index 7b7347f..8b75f6e 100755 --- a/process/view_log.sh +++ b/process/view_log.sh @@ -3,7 +3,11 @@ cd `dirname $0`/.. UN=$1 -if [ "$1" = "full" ] +if [ "$1" = "clean" ] +then + CMD=rm + shift +elif [ "$1" = "full" ] then CMD=cat shift From 672740685c2583fa018bb176236a6931d6921c9f Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 28 Sep 2013 18:52:38 +0200 Subject: [PATCH 133/364] Sanities LDAP code --- ACU/LDAP.pm | 201 ++++++++++++++++++++++++---------------------------- 1 file changed, 93 insertions(+), 108 deletions(-) diff --git a/ACU/LDAP.pm b/ACU/LDAP.pm index bd94e5f..94dc996 100644 --- a/ACU/LDAP.pm +++ b/ACU/LDAP.pm @@ -42,7 +42,8 @@ sub ldap_connect() log(DEBUG, "Connect to LDAP with $binddn"); if ($mesg->code) { - log(FATAL, "An error occurred: " .ldap_error_text($mesg->code)); + log(ERROR, "An error occurred: " .ldap_error_text($mesg->code)); + croak "An error occurred: " .ldap_error_text($mesg->code); } return $ldap; @@ -56,7 +57,8 @@ sub ldap_connect_anon() log(DEBUG, "Connect to LDAP anonymously"); if ($mesg->code) { - log(FATAL, "An error occurred: " .ldap_error_text($mesg->code)); + log(ERROR, "An error occurred: " .ldap_error_text($mesg->code)); + croak "An error occurred: " .ldap_error_text($mesg->code); } return $ldap; @@ -87,29 +89,6 @@ sub add_group($$$;$) return $dn; } -sub delete_group($$;$) -{ - my $cn = shift; - my $year = shift; - my $ou = shift // "intra"; # expected roles or intra - - my $ldap = ldap_connect(); - - log(DEBUG, "Delete group ou=groups,dc=acu,dc=epita,dc=fr"); - - my $mesg = $ldap->search( # search - base => "ou=groups,dc=acu,dc=epita,dc=fr", - filter => "cn=$cn", - scope => "sub" - ); - if ($mesg->code != 0) { log(WARN, $mesg->error); return 0; } - if ($mesg->count != 1) { log(WARN, "$cn not found or multiple entries match"); return 0; } - - $ldap->delete( $mesg->entry(0)->dn ); - - $ldap->unbind or log(WARN, "couldn't disconnect correctly"); -} - sub get_year(;$) { my $ldap = shift // ldap_connect_anon(); @@ -117,6 +96,90 @@ sub get_year(;$) return get_attribute($ldap, "cn=year,dc=acu,dc=epita,dc=fr", "year"); } +sub get_rights($) +{ + my $login = shift; + my @rights; + + my $ldap = ldap_connect_anon(); + + my $mesg = $ldap->search( # search + base => "ou=roles,ou=groups,dc=acu,dc=epita,dc=fr", + filter => "&(memberUid=$login)(objectClass=intraGroup)", + attrs => [ 'intraRight' ], + scope => "sub" + ); + if ($mesg->code != 0) { die $mesg->error; } + + for my $entry ($mesg->entries) + { + for my $r ($entry->get_value('intraRight')) + { + if ($r =~ /^!(.*)$/) { + @rights = grep { $r ne $_ } @rights; + } + else { + push @rights, Right->new($r); + } + } + } + + + $mesg = $ldap->search( # search + base => "ou=intra,ou=groups,dc=acu,dc=epita,dc=fr", + filter => "&(memberUid=$login)(objectClass=intraGroup)", + attrs => [ 'intraRight' ], + scope => "sub" + ); + if ($mesg->code != 0) { die $mesg->error; } + if ($mesg->count != 1) { die "User $login not found or multiple presence"; } + + for my $entry ($mesg->entries) + { + for my $r ($entry->get_value('intraRight')) { + push @rights, Right->new($r); + } + } + + + $mesg = $ldap->search( # search + base => "ou=users,dc=acu,dc=epita,dc=fr", + filter => "&(uid=$login)(objectClass=intraAccount)", + attrs => [ 'intraRight' ], + scope => "sub" + ); + if ($mesg->code != 0) { die $mesg->error; } + if ($mesg->count != 1) { die "User $login not found or multiple presence"; } + + for my $r ($mesg->entry(0)->get_value('intraRight')) { + push @rights, Right->new($r); + } + + + $ldap->unbind or die ("couldn't disconnect correctly"); + + return @rights; +} + +sub has_right($$) +{ + my $login = shift; + my $right = shift; + + my $ok = 0; + + for my $r (get_rights($login)) + { + if ($r->{right} eq $right) + { + return 0 if ($r->{negate}); + $ok = $r; + } + } + + return $ok; +} + ## Low level functions @@ -154,7 +217,8 @@ sub add_attribute($$$@) my @data = $entry->get_value($what); for my $value (@_) { - if (! grep { /^\Q$value\E$/ } @data) { + if (! grep { $value eq $_ } @data) + { $mod = 1; log(DEBUG, "Add attribute $value to $dn"); @@ -192,10 +256,11 @@ sub delete_attribute($$$@) my @data = $entry->get_value($what); for my $value (@_) { - if (grep { /^\Q$value\E$/ } @data) { + if (grep { $value eq $_ } @data) + { log(DEBUG, "Remove attribute $what ($value) from $dn"); - @data = grep { ! /^\Q$value\E$/ } @data; + @data = grep { ! $value eq $_ } @data; $mod = 1; } else { @@ -310,84 +375,4 @@ sub update_attribute($$$@) return 1; } - -sub has_right($$) -{ - my $login = shift; - my $right = shift; - - my $ok = 0; - - for my $r (get_rights($login)) { - if ($r->{right} eq $right) { - return 0 if ($r->{negate}); - $ok = $r; - } - } - - return $ok; -} - -sub get_rights($) -{ - my $login = shift; - my @rights; - - my $ldap = ldap_connect_anon(); - - my $mesg = $ldap->search( # search - base => "ou=roles,ou=groups,dc=acu,dc=epita,dc=fr", - filter => "&(memberUid=$login)(objectClass=intraGroup)", - attrs => [ 'intraRight' ], - scope => "sub" - ); - if ($mesg->code != 0) { die $mesg->error; } - - for my $entry ($mesg->entries) { - for my $r ($entry->get_value('intraRight')) { - if ($r =~ /^!(.*)$/) { - @rights = grep { ! /^\Q$r\E$/ } @rights; - } - else { - push @rights, Right->new($r); - } - } - } - - - $mesg = $ldap->search( # search - base => "ou=intra,ou=groups,dc=acu,dc=epita,dc=fr", - filter => "&(memberUid=$login)(objectClass=intraGroup)", - attrs => [ 'intraRight' ], - scope => "sub" - ); - if ($mesg->code != 0) { die $mesg->error; } - if ($mesg->count != 1) { die "User $login not found or multiple presence"; } - - for my $entry ($mesg->entries) { - for my $r ($entry->get_value('intraRight')) { - push @rights, Right->new($r); - } - } - - - $mesg = $ldap->search( # search - base => "ou=users,dc=acu,dc=epita,dc=fr", - filter => "&(uid=$login)(objectClass=intraAccount)", - attrs => [ 'intraRight' ], - scope => "sub" - ); - if ($mesg->code != 0) { die $mesg->error; } - if ($mesg->count != 1) { die "User $login not found or multiple presence"; } - - for my $r ($mesg->entry(0)->get_value('intraRight')) { - push @rights, Right->new($r); - } - - - $ldap->unbind or die ("couldn't disconnect correctly"); - - return @rights; -} - 1; From b951c4dc041442377f5f3d2c6cfd45956b218a92 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 28 Sep 2013 23:11:46 +0200 Subject: [PATCH 134/364] Patch for FreeBSD --- ACU/LDAP.pm | 1 + Makefile | 18 +++++++++--------- commands/manage-server.sh | 28 +++++++++++++++++++++++++--- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/ACU/LDAP.pm b/ACU/LDAP.pm index 94dc996..0bc0131 100644 --- a/ACU/LDAP.pm +++ b/ACU/LDAP.pm @@ -5,6 +5,7 @@ package LDAP; use v5.10.1; use strict; use warnings; +use Carp; use Net::LDAPS; use Net::LDAP::Util qw(ldap_error_text); diff --git a/Makefile b/Makefile index 29f7c7c..8391b1e 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,12 @@ -COPY=cp -v -DEST=/usr/local/share/perl/`ls -1 /usr/lib/perl/ | tail -1`/ -GIT=/usr/bin/git -GITOLITE_DEST=/usr/share/gitolite/hooks/common -MAKEDIR=mkdir -PROVER=prove -f -RM=rm -TESTDIR=t -SHELL=/bin/sh +COPY?=cp -v +DEST?=/usr/local/share/perl/`ls -1 /usr/lib/perl/ | tail -1`/ +GIT?=/usr/bin/git +GITOLITE_DEST?=/usr/share/gitolite/hooks/common +MAKEDIR?=mkdir +PROVER?=prove -f +RM?=rm +TESTDIR?=t +SHELL?=/bin/sh launch: $(SHELL) ./process/launch.sh diff --git a/commands/manage-server.sh b/commands/manage-server.sh index 36673f8..8081d2b 100755 --- a/commands/manage-server.sh +++ b/commands/manage-server.sh @@ -4,6 +4,7 @@ cd $(dirname "$0") WKS_LIST="apl" SRV_LIST="moore noyce hamano cpp" +SCP_LIST="ksh" KNOWN_ACTIONS="start stop restart update log viewlog view_log" @@ -27,7 +28,7 @@ do fi done - for DEST in $WKS_LIST $SRV_LIST + for DEST in $WKS_LIST $SRV_LIST $SCP_LIST do if [ -n "$1" ] && [ "$1" == "$DEST" ] then @@ -63,7 +64,7 @@ fi if [ -z "$DESTS" ] then - DESTS="$SRV_LIST $WKS_LIST" + DESTS="$SRV_LIST $WKS_LIST $SCP_LIST" fi OPTIONS= @@ -81,7 +82,28 @@ do echo -e "\e[1;34m>>>\e[0m \e[33m$ACTION\e[0m on \e[1m$DEST\e[0m" if [ "$ACTION" == "update" ] then - ssh root@$DEST "make -C liblerdorf update upgrade" + SCP=0 + for D in $SCP_LIST + do + if [ $D == $DEST ] + then + SCP=1 + break + fi + done + + if [ $SCP -eq 0 ] + then + ssh root@$DEST "make -C liblerdorf update upgrade" + else + cd .. + git archive -o ./liblerdorf.tbz2 master + scp ./liblerdorf.tbz2 root@$DEST: + cd - + ssh root@$DEST mkdir -p liblerdorf + ssh root@$DEST tar xf ./liblerdorf.tbz2 -C liblerdorf + ssh root@$DEST "DEST=/usr/local/lib/perl5/5.14/ACU make -C liblerdorf upgrade" + fi elif [ "$ACTION" == "log" ] || [ "$ACTION" == "viewlog" ] || [ "$ACTION" == "view_log" ] then ssh root@$DEST '~'/liblerdorf/process/view_log.sh $OPTIONS From 8ef18c4a3f18b7d1e75c62f2d1a6c35300043ab5 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 29 Sep 2013 04:34:11 +0200 Subject: [PATCH 135/364] Add guantanamo: a way to execute command in an unknown environnement --- ACU/Process.pm | 25 ++++- process/exec/guantanamo.pl | 175 ++++++++++++++++++++++++++++++++ process/exec/guantanamo_node.pl | 108 ++++++++++++++++++++ 3 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 process/exec/guantanamo.pl create mode 100644 process/exec/guantanamo_node.pl diff --git a/ACU/Process.pm b/ACU/Process.pm index 4298e8f..68e7638 100644 --- a/ACU/Process.pm +++ b/ACU/Process.pm @@ -320,6 +320,30 @@ sub getFirstChild ($) return $self->{children}[0]; } +sub recreateNode +{ + my $self = shift; + my $doc = shift; + my $parent = shift; + + my $node = $doc->createElement($self->{nodeName}); + for my $attkey (keys %{ $self->{attributes} }) + { + $node->addChild( $doc->createAttribute($attkey, $self->{attributes}{ $attkey }) ); + } + + for my $child (@{ $self->{children} }) + { + $child->recreateNode($doc, $node); + } + + if ($self->{nodeValue}) { + $node->appendText( $self->{nodeValue} ); + } + + $parent->appendChild($node); +} + package ProcessHandler; @@ -399,7 +423,6 @@ sub end_element { my $item = pop @{ $self->{subtreeStack} }; $item->{nodeValue} .= $self->{values}; - $item->{nodeValue} =~ s/\n+/ /g; $item->{nodeValue} =~ s/ +/ /g; if (@{ $self->{subtreeStack} } > 0) { push @{ $self->{subtreeStack}[-1]->{children} }, $item; diff --git a/process/exec/guantanamo.pl b/process/exec/guantanamo.pl new file mode 100644 index 0000000..745a120 --- /dev/null +++ b/process/exec/guantanamo.pl @@ -0,0 +1,175 @@ +#!/usr/bin/env perl + +use v5.10.1; +use strict; +use warnings; +use Gearman::Worker; +use MIME::Base64; +use XML::LibXML; + +use ACU::LDAP; +use ACU::Log; +use ACU::Process; + +my %master_actions = +( + "launch" => \&master_launch, + "register" => \&master_register, +); + +my @nodes; + +sub master_register +{ + my $args = shift; + + if ($args->{param}{nodename}) { + my $nodename = $args->{param}{nodename}; + + log INFO, "New node: $nodename"; + push @nodes, "$nodename"; + } + else { + log WARN, "nodename empty, cannot register new node"; + } +} + +sub build_task_xml +{ + my $files = shift; + my $subtree = shift; + + my $doc = XML::LibXML::Document->new('1.0'); + my $root = $doc->createElement("guantanamo"); + $doc->setDocumentElement( $root ); + + log TRACE, $subtree; + + if ($files) + { + log TRACE, $files; + + for my $key (keys %{ $files }) + { + my $file = $doc->createElement("file"); + $file->addChild( $doc->createAttribute("name", $key) ); + $file->addChild( $doc->createAttribute("encoding", "base64") ); + $file->appendText(encode_base64($files->{$key})); + $root->appendChild($file); + } + } + + if ($subtree) { + $subtree->recreateNode($doc, $root); + } + + my $ret = $doc->toString(); + log TRACE, $ret; + return $ret; +} + +sub master_launch +{ + my $args = shift; + + my @lnodes; + my @warn; + + if ($args->{unamed}) + { + for (my $i = $args->{unamed}; $i > 0; $i--) + { + if (grep { $args->{param}{$i} eq $_ } @nodes) { + push @lnodes, $args->{param}{$i}; + } else { + push @warn, $args->{param}{$i}." not a currently launched architecture."; + } + } + } + else { + @lnodes = @nodes; + } + + log DEBUG, "Launching nodes..."; + + my %ret; + + my $client = Gearman::Client->new; + $client->job_servers('gearmand:4730'); + my $taskset = $client->new_task_set; + for my $node (@lnodes) + { + log DEBUG, "Launching $node..."; + + $taskset->add_task( + "guantanamo_".$node => build_task_xml($args->{files}, $args->{subtree}), + { + on_complete => sub { + my $dom = XML::LibXML->load_xml(string => ${ $_[0] }); + $ret{ $node } = $dom; + } + }); + } + $taskset->wait; + + if ($args->{subtree}->hasAttribute("output") && $args->{subtree}->getAttribute("output") eq "text") + { + my $output = ""; + + for my $w (@warn) { + $output .= $w."\n"; + } + + for my $node (@lnodes) { + my $o = $ret{$node}->documentElement->getElementsByTagName("out"); + if ($o) { + $output .= $o[0]->firstChild->nodeValue; + } + + $e = $ret{$node}->documentElement->getElementsByTagName("err"); + if ($e) { + $output .= $e[0]->firstChild->nodeValue; + } + $output .= $e[0]->firstChild->nodeValue; + } + + return $output; + } + else + { + my $doc = XML::LibXML::Document->new('1.0'); + my $root = $doc->createElement("process"); + $doc->setDocumentElement( $root ); + + for my $w (@warn) + { + my $warning = $doc->createElement("warning"); + $warning->appendText($w); + $root->appendChild($warning); + } + + for my $k (keys %ret) + { + $root->appendChild($ret{ $k }->documentElement); + } + + return $doc->toString(); + } +} + +sub process_master +{ + my ($given_args, $args) = @_; + + my $action = $args->{param}{action} // "launch"; + + if (! exists $master_actions{$action}) { + log WARN, "Unknown action '$action' for guantanamo master process."; + } + return $master_actions{$action}($args); +} + + +log INFO, "Starting guantanamo.pl as master process"; + +Process::register("guantanamo", \&process_master); diff --git a/process/exec/guantanamo_node.pl b/process/exec/guantanamo_node.pl new file mode 100644 index 0000000..0e0cdeb --- /dev/null +++ b/process/exec/guantanamo_node.pl @@ -0,0 +1,108 @@ +#!/usr/bin/env perl + +use v5.10.1; +use strict; +use warnings; +use Carp; +use File::Path qw(make_path remove_tree); +use File::Temp qw/tempfile tempdir/; +use IPC::Open3; +use XML::LibXML; + +use ACU::LDAP; +use ACU::Log; +use ACU::Process; + +my %node_actions = +( + "launch" => \&node_launch, +); + +sub node_launch +{ + my $args = shift; + + # First, create a temporary directory + my $dir = tempdir(); + chdir( $dir ); + + # Extract all files to current directory + for my $filename (keys %{ $args->{files} }) + { + open my $fh, ">", $filename or croak("$filename: $!"); + print $fh $args->{files}{$filename}; + close $fh; + } + + my $doc = XML::LibXML::Document->new('1.0'); + my $root = $doc->createElement("target"); + $root->addChild( $doc->createAttribute("name", $ARGV[0]) ); + $doc->setDocumentElement( $root ); + + for my $c ($args->{subtree}->getElementsByTagName("command")) + { + if (! exists $c->{attributes}{target} || + index($c->{attributes}{target}, $ARGV[0]) != -1) { + + my $cmd = $doc->createElement("cmd"); + if (! exists $c->{attributes}{hide}) { + $root->appendChild($cmd); + } + + my $command = $doc->createElement("command"); + $command->appendText($c->{nodeValue}); + $cmd->appendChild($command); + + my($wtr, $rdr, $stderr); + my $pid = open3($wtr, $rdr, $stderr, $c->{nodeValue}); + waitpid( $pid, 0 ); + my $rv = $? >> 8; + + my $out = $doc->createElement("out"); + my $str = ""; + if ($rdr) { + $str .= $_ while (<$rdr>); + } + $out->appendText($str); + $cmd->appendChild($out); + + my $err = $doc->createElement("err"); + $str = ""; + if ($stderr) { + $str .= $_ while (<$stderr>); + } + $err->appendText($str); + $cmd->appendChild($err); + + my $ret = $doc->createElement("return"); + $ret->appendText($rv); + $cmd->appendChild($ret); + } + } + + chdir(); + remove_tree( $dir ); + + return $doc->toString(); +} + +sub process_node +{ + my ($given_args, $args) = @_; + + my $action = $args->{param}{action} // "launch"; + + if (! exists $node_actions{$action}) { + log WARN, "Unknown action '$action' for guantanamo node process."; + } + return $node_actions{$action}($args); +} + +if ($#ARGV == 0) +{ + log INFO, "Starting guantanamo.pl as node process"; + + Process::Client::launch("guantanamo", {"action" => "register", "nodename" => $ARGV[0]}); + + Process::register("guantanamo_".$ARGV[0], \&process_node); +} From 266190ac0388959a145e447219f035f1d186aaf2 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 30 Sep 2013 10:27:44 +0200 Subject: [PATCH 136/364] Allow SM to clone and push --- hooks/gl-pre-git | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git index 97946b3..581494a 100755 --- a/hooks/gl-pre-git +++ b/hooks/gl-pre-git @@ -18,7 +18,7 @@ say "Votre IP est : $ip."; $ip = Net::IP->new($ip) or die ("IP invalide"); -my $schoolnetwork = Net::IP->new('192.168.0.0/16'); +my $schoolnetwork = Net::IP->new('10.41.0.0/16'); if ($ip->overlaps($schoolnetwork) != $IP_A_IN_B_OVERLAP) { From 1f52c35bd68ff3e9f4868f6901cf21c5e9927f31 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 30 Sep 2013 10:52:58 +0200 Subject: [PATCH 137/364] Fix migration script --- migration/repo.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migration/repo.sh b/migration/repo.sh index 46dd4f0..695fdf1 100755 --- a/migration/repo.sh +++ b/migration/repo.sh @@ -44,7 +44,7 @@ clean_tex() sed -Ei 's/\\verb ([^+]+) /\\verb+\1+/g' "$i" # Special macros - sed -Ei 's/\\(file|email|command) *\{([^}]+)}/\\verb+\1+/gi' "$i" + sed -Ei 's/\\(file|email|command) *\{([^{]*\{[^}]*\})*([^}]*)}/\\verb+\2\3+/gi' "$i" sed -Ei 's/\\begin *\{assistant\}/\\verb+%%assistant-begin+/g' "$i" sed -Ei 's/\\end *\{assistant\}/\\verb+%%assistant-end+/g' "$i" From 4ae0d9f6e02006fa1dff2219d846781dd68c1985 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 30 Sep 2013 10:53:21 +0200 Subject: [PATCH 138/364] Add debug information in gl-pre-git hook --- hooks/gl-pre-git | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git index 581494a..62d352e 100755 --- a/hooks/gl-pre-git +++ b/hooks/gl-pre-git @@ -9,11 +9,14 @@ use Net::IP; use ACU::Log; $ACU::Log::log_file = "/var/log/hooks/" . basename($0) . ".log"; +my $ip = $1 if ($ENV{'SSH_CLIENT'} =~ m/([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*/); + +log DEBUG, "Connection to $ENV{GL_REPO} from $ip"; + # First, check if the repository is in the YYYY/ directory exit 0 if ($ENV{GL_REPO} !~ /^2[0-9]{3}\/.+\/.+/); -my $ip = $1 if ($ENV{'SSH_CLIENT'} =~ m/([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*/); say "Votre IP est : $ip."; $ip = Net::IP->new($ip) or die ("IP invalide"); From 326ce946179040991e5946a62ab5e7705c4dc6cf Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 30 Sep 2013 10:55:09 +0200 Subject: [PATCH 139/364] Remove liblerdorf directory before untarring sources --- commands/manage-server.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/commands/manage-server.sh b/commands/manage-server.sh index 8081d2b..145bed9 100755 --- a/commands/manage-server.sh +++ b/commands/manage-server.sh @@ -100,6 +100,7 @@ do git archive -o ./liblerdorf.tbz2 master scp ./liblerdorf.tbz2 root@$DEST: cd - + ssh root@$DEST rm -rf liblerdorf ssh root@$DEST mkdir -p liblerdorf ssh root@$DEST tar xf ./liblerdorf.tbz2 -C liblerdorf ssh root@$DEST "DEST=/usr/local/lib/perl5/5.14/ACU make -C liblerdorf upgrade" From 7a192c47323c7dc6910cb43e783c60158cb5849b Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 30 Sep 2013 13:08:33 +0200 Subject: [PATCH 140/364] Globbing in grading is not critical --- ACU/Grading.pm | 20 +++++++++++++------- ACU/Tinyglob.pm | 5 +++-- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/ACU/Grading.pm b/ACU/Grading.pm index dd1d64f..6eae26c 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -344,14 +344,20 @@ sub compute ($$$;$$$) if (defined $ref) { - my $glob = Tinyglob::tinyglob($ref); - if ($glob ne $ref) - { - my $value = 0; - for my $r (grep { /^$glob$/ } keys %$ids) { - $value += $ids->{ $r }; + eval { + my $glob = Tinyglob::tinyglob($ref); + if ($glob ne $ref) + { + my $value = 0; + for my $r (grep { /^$glob$/ } keys %$ids) { + $value += $ids->{ $r }; + } + $ids->{ $ref } = $value; } - $ids->{ $ref } = $value; + }; + if ($@) { + my $err = $@; + log ERROR, $@; } } diff --git a/ACU/Tinyglob.pm b/ACU/Tinyglob.pm index 3c19a5a..6fc9ed8 100644 --- a/ACU/Tinyglob.pm +++ b/ACU/Tinyglob.pm @@ -12,7 +12,8 @@ our @EXPORT = qw(tinyglob); sub tinyglob { - my @str = split("", quotemeta(shift)); + my $orig = shift; + my @str = split("", quotemeta($orig)); my $res = ""; my $metaescape = 0; @@ -38,7 +39,7 @@ sub tinyglob $res .= '.*'; } else { - croak "Invalid number of \\"; + croak "Invalid number of \\ in '$orig'"; } } else { From 6fa013ff149ae43a696ef5bd23410a41440ac2a5 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 30 Sep 2013 13:08:33 +0200 Subject: [PATCH 141/364] Globbing in grading is not critical --- ACU/Grading.pm | 22 +++++++++++++++------- ACU/Tinyglob.pm | 5 +++-- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/ACU/Grading.pm b/ACU/Grading.pm index dd1d64f..b01693c 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -290,6 +290,8 @@ use strict; use warnings; use Term::ANSIColor qw(:constants); +use ACU::Log; + sub new ($$$$$) { my $class = shift; @@ -344,14 +346,20 @@ sub compute ($$$;$$$) if (defined $ref) { - my $glob = Tinyglob::tinyglob($ref); - if ($glob ne $ref) - { - my $value = 0; - for my $r (grep { /^$glob$/ } keys %$ids) { - $value += $ids->{ $r }; + eval { + my $glob = Tinyglob::tinyglob($ref); + if ($glob ne $ref) + { + my $value = 0; + for my $r (grep { /^$glob$/ } keys %$ids) { + $value += $ids->{ $r }; + } + $ids->{ $ref } = $value; } - $ids->{ $ref } = $value; + }; + if ($@) { + my $err = $@; + log ERROR, $@; } } diff --git a/ACU/Tinyglob.pm b/ACU/Tinyglob.pm index 3c19a5a..6fc9ed8 100644 --- a/ACU/Tinyglob.pm +++ b/ACU/Tinyglob.pm @@ -12,7 +12,8 @@ our @EXPORT = qw(tinyglob); sub tinyglob { - my @str = split("", quotemeta(shift)); + my $orig = shift; + my @str = split("", quotemeta($orig)); my $res = ""; my $metaescape = 0; @@ -38,7 +39,7 @@ sub tinyglob $res .= '.*'; } else { - croak "Invalid number of \\"; + croak "Invalid number of \\ in '$orig'"; } } else { From 140be16b5c001111a199873a9eb5e874b3f3ad27 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 1 Oct 2013 00:08:40 +0200 Subject: [PATCH 142/364] Fix for loop for FreeBSD --- commands/first-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/first-install.sh b/commands/first-install.sh index 706e3e1..8cfad19 100755 --- a/commands/first-install.sh +++ b/commands/first-install.sh @@ -10,7 +10,7 @@ KERNEL=`uname -s` if [ "$KERNEL" = "FreeBSD" ] then - for PK in $FBSD_PACKAGES_LIST + for PK in `echo $FBSD_PACKAGES_LIST` do if ! pkg info "$PK" > /dev/null 2> /dev/null then From 0d26658a35acb019723b42fb5d163efffd531c27 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 1 Oct 2013 04:35:35 +0200 Subject: [PATCH 143/364] Add hook on tests to create the testsuite --- hooks/subjects.pl | 113 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 110 insertions(+), 3 deletions(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index b793ca4..32bb8ff 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -19,7 +19,7 @@ exit 0 if ($ENV{GL_REPO} !~ /^subjects\//); my ($ref, $oldsha, $newsha) = @ARGV; -log WARN, "This is a subject!"; +log DONE, "This is a subject repository!"; my %known_tags = ( "defense" => \&tag_defense, @@ -533,7 +533,8 @@ sub tag_ref # Send data to moulette log INFO, "Attente d'un processus de compilation..."; if (my $err = Process::Client::launch("moulette_get", { - type => "ref", + type => "tar", + login => "ref", id => $project_id, "year" => $year, "rendu" => $rendu, @@ -561,7 +562,7 @@ sub tag_ref log ERROR, "Tag long correspondant introuvable : $long_tag."; } - log USAGE, "Suppression du projet !"; + log USAGE, "Suppression du tag de ref !"; if ($long_tag) { @@ -575,5 +576,111 @@ sub tag_ref sub tag_tests { + my $creation = shift; + # From here, we have: + # 0: "tests" + # 1: $id + # 2: rendu-X + # 3: $year + + my $project_id = repository_name(); + if ($_[1]) { + + # Check on ID/flavour_id + if ($_[1] =~ /^\d+$/) { + log ERROR, "tests,* tag can't take version. Tag format: tests,id,rendu,year"; + } + + $project_id .= "-" . $_[1]; + } + $project_id = lc $project_id; + $project_id =~ s/[^a-z0-9-_]/_/g; + + my $rendu; + if ($_[2]) { + $rendu = $_[2]; + } + else { + $rendu = "*"; + } + + my $year; + if ($_[3]) + { + # Check on year + if ($_[3] !~ /^\d+$/) { + log ERROR, "tests,*,*,* third argument is the year. Tag format: tests,id,rendu,year"; + } + + $year = $_[3]; + } + else { + $year = LDAP::get_year; + } + + # Determine full tag + my $long_tag; + { + my $proj_id = $_[1] // ""; + $long_tag = "tests,$proj_id,$rendu,$year"; + } + + if ($creation) + { + my $newref = $ARGV[2]; + + log INFO, "Création/mise à jour de la testsuite..."; + + my $content = qx(git show $newref:tests/Makefile); + # Check file exists + if ($?) { + log ERROR, "Un fichier Makefile est requis pour pouvoir compiler la testsuite."; + } + + log INFO, "Création de la tarball..."; + + my $archive = qx(git archive --format=tgz $newref tests/); + + # Send data to moulette + log INFO, "Attente d'un processus de compilation..."; + if (my $err = Process::Client::launch("moulette_get", { + type => "tests", + id => $project_id, + "year" => $year, + "rendu" => $rendu, + "file" => "tests_$rendu.tgz" + }, { "tests_$rendu.tgz" => $archive })) + { + if (${ $err } ne "Ok") { + log ERROR, "Erreur durant le processus de compilation : " . ${ $err }; + } + } + + if ($long_tag) + { + qx(git tag -f $long_tag $newref); + if (! $?) { + log INFO, "Tag long créé : $long_tag."; + } + } + } + else + { + # Is the long tag existing + qx(git tag | egrep "^$long_tag\$"); + if ($?) { + log ERROR, "Tag long correspondant introuvable : $long_tag."; + } + + log USAGE, "Suppression du tag de la testsuite !"; + + if ($long_tag) + { + qx(git tag -d $long_tag); + if (! $?) { + log INFO, "Tag long supprimé : $long_tag."; + } + } + } } From 05537dc903871a18ff5687fa6b22b3be2d48a04f Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 1 Oct 2013 04:37:15 +0200 Subject: [PATCH 144/364] Use /usr/bin/env instead of raw path, for compatibility between Linux and FreeBSD systems --- process/launch.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/process/launch.sh b/process/launch.sh index 92da68a..96c1838 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -2,10 +2,10 @@ cd $(dirname "$0") -GREP='/bin/egrep' -SCREEN='/usr/bin/screen' -SED='/bin/sed -E' -SU='/bin/su -s /bin/sh' +GREP='/usr/bin/env grep -E' +SCREEN='/usr/bin/env screen' +SED='/usr/bin/env sed -E' +SU='/usr/bin/env su -s /bin/sh' PERL='/usr/bin/env perl' launch_screen() From 5ccc30daba7bda1c47da7c1144c59fd66866d138 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 1 Oct 2013 04:57:52 +0200 Subject: [PATCH 145/364] Display error message on installation error --- commands/first-install.sh | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/commands/first-install.sh b/commands/first-install.sh index 8cfad19..7de5fff 100755 --- a/commands/first-install.sh +++ b/commands/first-install.sh @@ -3,6 +3,7 @@ # Install missing packages DEB_PACKAGES_LIST="screen libnet-ldap-perl libxml-libxml-perl libgearman-client-perl libmailtools-perl libmail-sendmail-perl libdatetime-format-iso8601-perl libnet-ip-perl" ARCH_PACKAGES_LIST="screen perl-io-socket-ssl perl-email-simple perl-email-mime perl-term-readkey perl-ldap perl-lwp-protocol-https perl-datetime-format-iso8601 perl-net-ip" +GENTOO_PACKAGES_LIST="app-misc/screen dev-perl/IO-Socket-SSL dev-perl/Email-Simple dev-perl/Email-MIME dev-perl/TermReadKey dev-perl/perl-ldap dev-perl/LWP-Protocol-https dev-perl/DateTime-Format-ISO8601 dev-perl/Net-IP" FBSD_PACKAGES_LIST="screen p5-IO-Socket-SSL p5-Email-Simple p5-Email-MIME p5-Term-ANSIColor p5-Term-ReadKey p5-LWP-Protocol-https p5-DateTime-Format-ISO8601 p5-Net-IP" KERNEL=`uname -s` @@ -14,7 +15,11 @@ then do if ! pkg info "$PK" > /dev/null 2> /dev/null then - PACKAGESITE="http://canon.acu.epita.fr/repo-lab" pkg install "$PK" + if ! PACKAGESITE="http://canon.acu.epita.fr/repo-lab" pkg install "$PK" + then + echo "Error during installation of $PK" + exit 1 + fi fi done @@ -26,7 +31,11 @@ then if ! whereis dpkg > /dev/null 2> /dev/null then - aptitude install dpkg + if ! aptitude install dpkg + then + echo "Error during installation of $PK" + exit 1 + fi fi for PK in $DEB_PACKAGES_LIST @@ -54,20 +63,39 @@ then do if ! pacman -Qi "$PK" > /dev/null 2> /dev/null then - pacman -S "$PK" + if ! pacman -S "$PK" + then + echo "Error during installation of $PK" + exit 1 + fi + fi + done + + elif [ -f "/etc/gentoo-release" ] + then + + for PK in $GENTOO_PACKAGES_LIST + do + if ! equery list "$PK" > /dev/null 2> /dev/null + then + if ! emerge "$PK" + then + echo "Error during installation of $PK" + exit 1 + fi fi done else - echo "Unknown distribution :(" + echo "Unsupported GNU/Linux distribution :(" exit 1; fi else - echo "Unknown operating system :(" + echo "Unsupported operating system :(" exit 1; fi From ed690a4c2d04dea69cb8f1b2dde8abf03198cc37 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 1 Oct 2013 05:30:41 +0200 Subject: [PATCH 146/364] Fix Make file --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8391b1e..4dc640e 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ COPY?=cp -v -DEST?=/usr/local/share/perl/`ls -1 /usr/lib/perl/ | tail -1`/ +DEST?=/usr/local/share/perl/`ls -1 /usr/local/share/perl/ | grep "^5." | tail -1`/ GIT?=/usr/bin/git GITOLITE_DEST?=/usr/share/gitolite/hooks/common MAKEDIR?=mkdir From 8eb6b143a1ed8212a8e16420a03bb4a185f358ec Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 2 Oct 2013 18:26:01 +0200 Subject: [PATCH 147/364] New process: get_csv to get grades --- process/launch.sh | 1 + process/projects/gen_grading.pl | 2 +- process/projects/get_csv.pl | 93 +++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 process/projects/get_csv.pl diff --git a/process/launch.sh b/process/launch.sh index 96c1838..bd98c91 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -79,6 +79,7 @@ then noyce) launch_screen "lerdorf_process_files_intradata_get" "while true; do $PERL ~/liblerdorf/process/files/intradata_get.pl; done" launch_screen "lerdorf_process_projects_gen_grading" "while true; do $PERL ~/liblerdorf/process/projects/gen_grading.pl; done" + launch_screen "lerdorf_process_projects_get_csv" "while true; do $PERL ~/liblerdorf/process/projects/get_csv.pl; done" ;; ksh) diff --git a/process/projects/gen_grading.pl b/process/projects/gen_grading.pl index 61b8f33..dacdaeb 100644 --- a/process/projects/gen_grading.pl +++ b/process/projects/gen_grading.pl @@ -30,7 +30,7 @@ sub process if (! -d "$basedir/$year/$project_id") { log ERROR, "Unable to find $project_id in $year"; - return "Unable to find $project_id in $year"; + return "Unable to find $project_id in $year\n"; } my $grade = Grading->new(); diff --git a/process/projects/get_csv.pl b/process/projects/get_csv.pl new file mode 100644 index 0000000..29a4311 --- /dev/null +++ b/process/projects/get_csv.pl @@ -0,0 +1,93 @@ +#! /usr/bin/env perl + +use v5.10.1; +use strict; +use warnings; +use Carp; +use Pod::Usage; +use Text::ParseWords; +use XML::LibXML; + +use ACU::Log; +use ACU::LDAP; +use ACU::Process; + +our $basedir = "/intradata"; + +sub process +{ + my $given_args = shift; + my @args = shellwords(${ shift() }); + + my $project_id = shift @args; + my $year = shift @args // LDAP::get_year; + + # Project existing? + if (! -d "$basedir/$year/$project_id") + { + log ERROR, "Unable to find $project_id in $year"; + return "Unable to find $project_id in $year\n"; + } + + my %grades; + my @headers; + + opendir(my $dh, "$basedir/$year/$project_id/grades/") or croak "can't opendir $basedir/$year/$project_id/grades/: $!"; + for my $gfile (grep { ( ! /^\./ ) && -f "$basedir/$year/$project_id/grades/$_" } readdir($dh)) + { + my $login; + ($login = $gfile) =~ s/\.xml$//; + + open my $xml, "<", "$basedir/$year/$project_id/grades/$gfile" or die $!; + binmode $xml; + my $dom = XML::LibXML->load_xml(IO => $xml); + close $xml; + + my @ugrades = @headers; + for my $grade ($dom->documentElement()->getElementsByTagName("grade")) + { + my $i; + for ($i = 0; $i <= $#ugrades; $i++) + { + if ($ugrades[$i] == $grade->getAttribute("name")) + { + $ugrades[$i] = $grade->getAttribute("value"); + last; + } + } + + if ($i > $#ugrades) + { + push @headers, $grade->getAttribute("name"); + push @ugrades, $grade->getAttribute("value"); + } + } + + $grades{$login} = \@ugrades; + } + closedir $dh; + + # Print CSV + my $out = "login"; + + for my $header (@headers) { + $out .= ",$header"; + } + $out .= "\n"; + + for my $login (keys %grades) { + $out .= "$login"; + my @ugrades = \$grades{$login}; + for my $header (@headers) + { + my $g = shift @ugrades; + $out .= $g if ($g && $g ne $header); + $out .= ","; + } + $out .= "\n"; + } + + return $out; +} + +Process::register_no_parse("get_csv", \&process); From 663a77a084acf523970e8fd66eb75ac327d8385e Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 2 Oct 2013 18:30:53 +0200 Subject: [PATCH 148/364] Fix cast --- process/projects/get_csv.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/projects/get_csv.pl b/process/projects/get_csv.pl index 29a4311..f751391 100644 --- a/process/projects/get_csv.pl +++ b/process/projects/get_csv.pl @@ -77,7 +77,7 @@ sub process for my $login (keys %grades) { $out .= "$login"; - my @ugrades = \$grades{$login}; + my @ugrades = @{ $grades{$login} }; for my $header (@headers) { my $g = shift @ugrades; From f3904e62b2dd0993010a1e18c3296d5c2f0114cc Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 2 Oct 2013 19:45:48 +0200 Subject: [PATCH 149/364] Add a way to remove bonus/malus --- ACU/Trace.pm | 8 ++++++++ commands/grades/send_bonusmalus.pl | 3 ++- process/files/intradata_get.pl | 26 ++++++++++++++++++++++---- process/projects/gen_grading.pl | 2 +- 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/ACU/Trace.pm b/ACU/Trace.pm index 2cf448b..fba6621 100644 --- a/ACU/Trace.pm +++ b/ACU/Trace.pm @@ -115,6 +115,14 @@ sub addId($$;$) $self->{ids}{$key} = $value; } +sub delId($$) +{ + my $self = shift; + my $key = shift; + + delete $self->{ids}{$key}; +} + sub toString ($;$) { my $self = shift; diff --git a/commands/grades/send_bonusmalus.pl b/commands/grades/send_bonusmalus.pl index 8b7e1e3..f618d5a 100644 --- a/commands/grades/send_bonusmalus.pl +++ b/commands/grades/send_bonusmalus.pl @@ -45,5 +45,6 @@ if ($#ARGV >= 1) } else { - say "$0 [project_year] [files ...]"; + say "$0 [-d] [project_year] [files ...]"; + say "\t-d: delete bonus for listed logins (matching value if given)" } diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index 9c6890c..fdde9b0 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -151,6 +151,7 @@ sub grades_new_bonus my $args = shift; my $project_id = $args->{param}{id}; + my $delete = $args->{param}{delete} // 0; my $year = $args->{param}{year} // LDAP::get_year; if (! $project_id) { @@ -177,7 +178,9 @@ sub grades_new_bonus log TRACE, $args->{files}{$kfile}; log TRACE, @lines; - my $value = 1; + my $value; + $value = 1 if (!$delete); + # Looking for a global value if ($lines[0] =~ /^(\d+)$/) { $value = $1; @@ -193,7 +196,11 @@ sub grades_new_bonus my $tvalue = $2 // $value; my $trace; - log DEBUG, "Applying bonus for $login:$tvalue"; + if ($delete) { + log DEBUG, "Deleting bonus for $login"; + } else { + log DEBUG, "Applying bonus for $login:$tvalue"; + } if (-e "$basedir/$year/$project_id/traces/bonus/$login.xml") { open my $xml, "<", "$basedir/$year/$project_id/traces/bonus/$login.xml" or croak $!; @@ -201,17 +208,28 @@ sub grades_new_bonus $trace = Trace->new($xml); close $xml; } + elsif ($delete) { + next; + } else { $trace = Trace->new(); } - $trace->addId($kbonus, $tvalue); + if ($delete) { + if ($tvalue && $tvalue == $trace->getIds($kbonus)) { + $trace->delId($kbonus); + } else { + $trace->delId($kbonus); + } + } else { + $trace->addId($kbonus, $tvalue); + } log DEBUG, "Updating $basedir/$year/$project_id/traces/bonus/$login.xml"; open my $xml, ">", "$basedir/$year/$project_id/traces/bonus/$login.xml" or croak $!; print $xml $trace->toString(); - close $xml + close $xml; } else { log WARN, "Invalid login $line, line skiped"; diff --git a/process/projects/gen_grading.pl b/process/projects/gen_grading.pl index dacdaeb..6c04c57 100644 --- a/process/projects/gen_grading.pl +++ b/process/projects/gen_grading.pl @@ -56,7 +56,7 @@ sub process my @keys = keys %$ids; my $def_i = $keys[0]; - $def_i =~ s/^(.+)g.*$/\1/; + $def_i =~ s/^(.+)g.*$/$1/; $ids->{$def_i.'_end_$LOGIN'} = undef; $ids->{$def_i.'_end_group'} = undef; From 81cb7194171fee2537c40a0167910350fe441109 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 2 Oct 2013 20:12:45 +0200 Subject: [PATCH 150/364] Fix comma position --- process/files/intradata_get.pl | 2 +- process/projects/get_csv.pl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index fdde9b0..c76621a 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -151,7 +151,7 @@ sub grades_new_bonus my $args = shift; my $project_id = $args->{param}{id}; - my $delete = $args->{param}{delete} // 0; + my $delete = $args->{param}{delete}; my $year = $args->{param}{year} // LDAP::get_year; if (! $project_id) { diff --git a/process/projects/get_csv.pl b/process/projects/get_csv.pl index f751391..0172e34 100644 --- a/process/projects/get_csv.pl +++ b/process/projects/get_csv.pl @@ -81,8 +81,8 @@ sub process for my $header (@headers) { my $g = shift @ugrades; - $out .= $g if ($g && $g ne $header); $out .= ","; + $out .= $g if ($g && $g ne $header); } $out .= "\n"; } From 5de36e170900f5d783260aec65dbaec0dda0328d Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 2 Oct 2013 22:02:36 +0200 Subject: [PATCH 151/364] New method for launching through su --- process/launch.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/process/launch.sh b/process/launch.sh index bd98c91..db40664 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -13,14 +13,14 @@ launch_screen() CMD=$2 if [ -n "$3" ] && [ -f "$3" ] then - TMP=`$SU -c 'mktemp' intradmin` - $SU -c "killall ssh-agent" intradmin - $SU -c "ssh-agent" intradmin > "$TMP" - $SU -c ". $TMP; ssh-add '$3'" intradmin + TMP=`echo mktemp | $SU intradmin` + echo "killall ssh-agent" | $SU intradmin + echo "ssh-agent" | $SU intradmin > "$TMP" + echo ". $TMP; ssh-add '$3'" | $SU intradmin CMD=". $TMP; ssh-add -l; echo; $CMD" fi - $SU -c "$SCREEN -S '$1' -d -m bash -c '$CMD'" intradmin + echo "$SCREEN -S '$1' -d -m bash -c '$CMD'" | $SU intradmin if [ -f "$TMP" ] then @@ -46,11 +46,11 @@ fi if [ "$ACTION" = "stop" ] || [ "$ACTION" = "restart" ] then # Kill old liblersorf screen sessions - $SU -c "$SCREEN -ls" intradmin | $GREP '[0-9]+\.lerdorf_[a-zA-Z0-9_-]+' | + echo "$SCREEN -ls" intradmin | $GREP '[0-9]+\.lerdorf_[a-zA-Z0-9_-]+' | $SU | while read LINE do SNAME=`echo $LINE | $SED "s/^[^0-9]*([0-9]+\.[^ \t]+).*$/\1/"` - $SU -c "$SCREEN -S \"$SNAME\" -X kill" intradmin + echo "$SCREEN -S \"$SNAME\" -X kill" | $SU intradmin done fi From 0951d36451d109feb96b634212d5314dbc2d5480 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 2 Oct 2013 22:08:42 +0200 Subject: [PATCH 152/364] Fix launching on FreeBSD --- process/launch.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/process/launch.sh b/process/launch.sh index db40664..231c506 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -5,7 +5,11 @@ cd $(dirname "$0") GREP='/usr/bin/env grep -E' SCREEN='/usr/bin/env screen' SED='/usr/bin/env sed -E' -SU='/usr/bin/env su -s /bin/sh' +if [ `uname -s` = "FreeBSD" ]; then + SU='/usr/bin/env su' +else + SU='/usr/bin/env su -s /bin/sh' +fi PERL='/usr/bin/env perl' launch_screen() From e6c9c1251bdebf5ae2eb2ec96013a48c02f741bc Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 4 Oct 2013 19:04:55 +0200 Subject: [PATCH 153/364] Fix process stopping --- process/launch.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/launch.sh b/process/launch.sh index 231c506..91b78da 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -50,7 +50,7 @@ fi if [ "$ACTION" = "stop" ] || [ "$ACTION" = "restart" ] then # Kill old liblersorf screen sessions - echo "$SCREEN -ls" intradmin | $GREP '[0-9]+\.lerdorf_[a-zA-Z0-9_-]+' | $SU | + echo "$SCREEN -ls" | $SU intradmin | $GREP '[0-9]+\.lerdorf_[a-zA-Z0-9_-]+' | while read LINE do SNAME=`echo $LINE | $SED "s/^[^0-9]*([0-9]+\.[^ \t]+).*$/\1/"` From 9981ac3346ff9e87d20ce744f1703f4ee4ad2248 Mon Sep 17 00:00:00 2001 From: Nicolas Geniteau Date: Sat, 5 Oct 2013 15:58:46 +0200 Subject: [PATCH 154/364] Fix long tag name for testsuite --- hooks/subjects.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index 32bb8ff..4bdfa99 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -602,7 +602,7 @@ sub tag_tests $rendu = $_[2]; } else { - $rendu = "*"; + $rendu = ""; } my $year; From b126a0400a063eb1a2894d1ba645136e97ffff20 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 5 Oct 2013 22:00:54 +0200 Subject: [PATCH 155/364] Fix scripts for FreeBSD --- commands/first-install.sh | 5 +++++ process/view_log.sh | 11 +++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/commands/first-install.sh b/commands/first-install.sh index 7de5fff..ca42951 100755 --- a/commands/first-install.sh +++ b/commands/first-install.sh @@ -23,6 +23,11 @@ then fi done + if ! getent passwd | grep "intradmin:" > /dev/null 2> /dev/null + then + pw useradd intradmin -u 942 -d /data -s /bin/false + fi + elif [ "$KERNEL" = "Linux" ] then diff --git a/process/view_log.sh b/process/view_log.sh index 8b75f6e..dbb9fe9 100755 --- a/process/view_log.sh +++ b/process/view_log.sh @@ -19,8 +19,6 @@ else CMD="tail -n 50" fi -TMP=`mktemp` - DIRS="./" if [ -d "/var/log/hooks/" ] then @@ -40,9 +38,14 @@ then else - LIST=`mktemp` + if [ `uname -s` = "FreeBSD" ] + then + LIST=`mktemp lerdorf_log_XXXXX` + else + LIST=`mktemp` + fi - find $DIRS -name '*.log' > $LIST + find $DIRS -name '*.log' > "$LIST" while [ $# -gt 0 ] do From ad9c91497c8e16bf2be2523e6e56da2c99f93223 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 7 Oct 2013 16:42:02 +0200 Subject: [PATCH 156/364] Install gl-pre-git at the right place --- Makefile | 5 ++++- hooks/gl-pre-git | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4dc640e..1d62a40 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,9 @@ install: $(MAKEDIR) -p $(DEST) $(COPY) -r ACU/ $(DEST) ! test -d $(GITOLITE_DEST) || $(MAKEDIR) -p $(GITOLITE_DEST)/update.secondary.d - ! test -d $(GITOLITE_DEST) || $(COPY) hooks/* $(GITOLITE_DEST)/update.secondary.d/ + ! test -d $(GITOLITE_DEST) || $(COPY) hooks/gl-pre-git $(GITOLITE_DEST)/ + ! test -d $(GITOLITE_DEST) || $(COPY) hooks/subjects.pl $(GITOLITE_DEST)/update.secondary.d/ + ! test -d $(GITOLITE_DEST) || $(COPY) hooks/submissions.pl $(GITOLITE_DEST)/update.secondary.d/ update: $(GIT) pull @@ -26,6 +28,7 @@ upgrade: install unstall: $(RM) -r $(DEST)/ACU/ + ! test -d $(GITOLITE_DEST) || $(RM) -rf $(GITOLITE_DEST)/gl-pre-git ! test -d $(GITOLITE_DEST) || $(RM) -rf $(GITOLITE_DEST)/update.secondary.d ! test -d $(GITOLITE_DEST) || $(MAKEDIR) -p $(GITOLITE_DEST)/update.secondary.d diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git index 62d352e..2a2b69f 100755 --- a/hooks/gl-pre-git +++ b/hooks/gl-pre-git @@ -11,6 +11,8 @@ $ACU::Log::log_file = "/var/log/hooks/" . basename($0) . ".log"; my $ip = $1 if ($ENV{'SSH_CLIENT'} =~ m/([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*/); +exit 0 if (!$ip); + log DEBUG, "Connection to $ENV{GL_REPO} from $ip"; # First, check if the repository is in the YYYY/ directory From 3347f080115b0fde3baa88056d9e92a892536644 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 7 Oct 2013 20:19:07 +0200 Subject: [PATCH 157/364] Differenciate R and W access to repo --- hooks/gl-pre-git | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git index 2a2b69f..ee29bec 100755 --- a/hooks/gl-pre-git +++ b/hooks/gl-pre-git @@ -19,6 +19,9 @@ log DEBUG, "Connection to $ENV{GL_REPO} from $ip"; exit 0 if ($ENV{GL_REPO} !~ /^2[0-9]{3}\/.+\/.+/); +my $read = ($ARGV[0] =~ /R/); +my $write = ($ARGV[0] =~ /W/); + say "Votre IP est : $ip."; $ip = Net::IP->new($ip) or die ("IP invalide"); @@ -27,7 +30,8 @@ my $schoolnetwork = Net::IP->new('10.41.0.0/16'); if ($ip->overlaps($schoolnetwork) != $IP_A_IN_B_OVERLAP) { - log ERROR, "Vous n'êtes pas autorisé à envoyer vos modifications depuis cette IP."; + log ERROR, "Vous n'êtes pas autorisé à envoyer vos modifications depuis cette IP." if ($write); + log ERROR, "Vous n'êtes pas autorisé à accéder à ce dépôt depuis cette IP." if ($read); exit 1; } @@ -35,7 +39,8 @@ my $sshnetwork = Net::IP->new('10.41.253.0/24'); if ($ip->overlaps($sshnetwork) == $IP_A_IN_B_OVERLAP) { - log ERROR, "Vous n'êtes pas autorisé à envoyer vos modifications depuis cette IP."; + log ERROR, "Vous n'êtes pas autorisé à envoyer vos modifications depuis cette IP." if ($write); + log ERROR, "Vous n'êtes pas autorisé à accéder à ce dépôt depuis cette IP." if ($read); exit 1; } From b3acb0ba54842499754d93247714d08381cf15ff Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 12 Oct 2013 02:44:41 +0200 Subject: [PATCH 158/364] Process: change root tag name to process --- ACU/Process.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ACU/Process.pm b/ACU/Process.pm index 68e7638..1c94d27 100644 --- a/ACU/Process.pm +++ b/ACU/Process.pm @@ -154,7 +154,7 @@ sub build_task_xml($;$) my $files = shift; my $doc = XML::LibXML::Document->new('1.0'); - my $root = $doc->createElement("sync_ssh_keys"); + my $root = $doc->createElement("process"); $doc->setDocumentElement( $root ); log TRACE, $params; From 4979456cd0125002ae302ac1618d85bb5485325a Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 12 Oct 2013 02:47:57 +0200 Subject: [PATCH 159/364] gl-pre-git: display IP only if not authorized --- hooks/gl-pre-git | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git index ee29bec..2c1e36d 100755 --- a/hooks/gl-pre-git +++ b/hooks/gl-pre-git @@ -22,7 +22,10 @@ exit 0 if ($ENV{GL_REPO} !~ /^2[0-9]{3}\/.+\/.+/); my $read = ($ARGV[0] =~ /R/); my $write = ($ARGV[0] =~ /W/); -say "Votre IP est : $ip."; +my $promo = $1 if ($ENV{'GL_REPO'} =~ m/([0-9]{4}).*/); +my $id_project = $1 if ($ENV{'GL_REPO'} =~ m/.*\/(.*)\//); +my $repo_login = $1 if ($ENV{'GL_REPO'} =~ m/.*\/.*\/(.*)/); + $ip = Net::IP->new($ip) or die ("IP invalide"); @@ -30,6 +33,8 @@ my $schoolnetwork = Net::IP->new('10.41.0.0/16'); if ($ip->overlaps($schoolnetwork) != $IP_A_IN_B_OVERLAP) { + say "Votre IP est : $ip."; + log ERROR, "Vous n'êtes pas autorisé à envoyer vos modifications depuis cette IP." if ($write); log ERROR, "Vous n'êtes pas autorisé à accéder à ce dépôt depuis cette IP." if ($read); exit 1; @@ -39,6 +44,8 @@ my $sshnetwork = Net::IP->new('10.41.253.0/24'); if ($ip->overlaps($sshnetwork) == $IP_A_IN_B_OVERLAP) { + say "Votre IP est : $ip."; + log ERROR, "Vous n'êtes pas autorisé à envoyer vos modifications depuis cette IP." if ($write); log ERROR, "Vous n'êtes pas autorisé à accéder à ce dépôt depuis cette IP." if ($read); exit 1; From 3f265bd9d64f46b926f772e7052ead3c0a2a947a Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 12 Oct 2013 02:49:15 +0200 Subject: [PATCH 160/364] Migration: fix cd from deleted directory --- migration/repo.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/migration/repo.sh b/migration/repo.sh index 695fdf1..53d9fcf 100755 --- a/migration/repo.sh +++ b/migration/repo.sh @@ -78,7 +78,7 @@ clean_tex() then git mv * .. fi - cd .. + cd - > /dev/null if [ -f "mySubject.md" ] then @@ -124,9 +124,9 @@ then exit 4 fi -cd .. +cd - > /dev/null -rm -rf "$1" +mv "$1" "$1.hg" git clone "$TMPDIR/repo.git" "$1" @@ -207,13 +207,13 @@ do do if [ -f "$D/template.xml" ] then - `dirname $0`/defense_converter.pl -o "$D.xml" "$D/template.xml" + perl `dirname $0`/defense_converter.pl -o "$D.xml" "$D/template.xml" git add "$D.xml" echo -e "\e[1;35m>>>\e[1;37m Defense converted:\e[0m $D" fi git rm -rf "$D" > /dev/null done - cd .. + cd - > /dev/null echo -e "\e[1;35m## ## ## ## ##\e[0m" echo @@ -270,7 +270,7 @@ do git rm -rf "$f" > /dev/null fi done - cd .. + cd - > /dev/null fi done From a3fca0f62246cb76f0a342a4d281b64bc13f2909 Mon Sep 17 00:00:00 2001 From: Nicolas Geniteau Date: Thu, 17 Oct 2013 15:00:34 +0200 Subject: [PATCH 161/364] Change hook to send a specific action for ref --- hooks/subjects.pl | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index 4bdfa99..edd7cd5 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -511,7 +511,11 @@ sub tag_ref my $long_tag; { my $proj_id = $_[1] // ""; - $long_tag = "ref,$proj_id,$rendu,$year"; + if ($rendu eq "*") { + $long_tag = "ref,$proj_id,,$year"; + } else { + $long_tag = "ref,$proj_id,$rendu,$year"; + } } if ($creation) @@ -533,8 +537,7 @@ sub tag_ref # Send data to moulette log INFO, "Attente d'un processus de compilation..."; if (my $err = Process::Client::launch("moulette_get", { - type => "tar", - login => "ref", + type => "ref", id => $project_id, "year" => $year, "rendu" => $rendu, @@ -602,7 +605,7 @@ sub tag_tests $rendu = $_[2]; } else { - $rendu = ""; + $rendu = "*"; } my $year; @@ -623,7 +626,11 @@ sub tag_tests my $long_tag; { my $proj_id = $_[1] // ""; - $long_tag = "tests,$proj_id,$rendu,$year"; + if ($rendu eq "*") { + $long_tag = "tests,$proj_id,,$year"; + } else { + $long_tag = "tests,$proj_id,$rendu,$year"; + } } if ($creation) From ad866e3a57ef56f40171ed163a85a8e82b9ca3c3 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 18 Oct 2013 04:15:17 +0200 Subject: [PATCH 162/364] Add trace_update --- process/files/intradata_get.pl | 57 +++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index c76621a..b3a9039 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -28,7 +28,10 @@ my %actions = ( "create" => \&update_project, "update" => \&update_project, "delete" => \&delete_project, - } + }, + "trace" => { + "update" => \&update_trace, + }, ); sub create_tree($$) @@ -322,6 +325,58 @@ sub update_project return "Ok"; } +sub update_trace +{ + my $args = shift; + + my $project_id = $args->{param}{id}; + my $year = $args->{param}{year} // LDAP::get_year; + + if (! $project_id) { + log ERROR, "No project_id given."; + return "No project_id given"; + } + + my $rendu_id = $args->{param}{rendu}; + + if (! $rendu_id) { + log ERROR, "No rendu_id given."; + return "No rendu_id given"; + } + + my $login = $args->{param}{login}; + + if (! $login) { + log ERROR, "No login given."; + return "No login given"; + } + + my $trace; + if (exists $args->{files}{"$login.xml"}) { + $trace = $args->{files}{"$login.xml"}; + } + if (! $trace) { + log ERROR, "Invalid $login.xml received!"; + return "Invalid $login.xml received!"; + } + + log INFO, "Update $year/$project_id/traces/$rendu_id/$login.xml"; + + if (! -e "$basedir/$year/$project_id/traces/") { + mkdir "$basedir/$year/$project_id/traces/"; + } + if (! -e "$basedir/$year/$project_id/traces/$rendu_id/") { + mkdir "$basedir/$year/$project_id/traces/$rendu_id/"; + chmod 0755, "$basedir/$year/$project_id/traces/$rendu_id/"; + } + + open my $out, ">", "$basedir/$year/$project_id/traces/$rendu_id/$login.xml"; + print $out $trace; + close $out; + + return "Ok"; +} + sub delete_project { log WARN, "delete_project: not implemented." From aab3e767c0eeb9550f7abbf912a929ba7d20c65d Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 18 Oct 2013 04:16:18 +0200 Subject: [PATCH 163/364] Migration: handle subdirectory form for big projects --- migration/repo.sh | 91 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 25 deletions(-) diff --git a/migration/repo.sh b/migration/repo.sh index 53d9fcf..ab66770 100755 --- a/migration/repo.sh +++ b/migration/repo.sh @@ -6,25 +6,20 @@ then exit 1 fi -clean_tex() +tex2md() { - for f in data Makefile images/acu.pdf images/assistants.pdf images/assistants-subject.pdf images/assistants-slides.pdf images/assistants.png images/epita.pdf images/epita.png images/epita-invert.pdf images/assistants-invert.pdf images/epita-invert.png *.cls *.sty *.tex - do - if [ -f "$f" ] - then - git rm -f "$f" > /dev/null - elif [ -d "$f" ] - then - git rm -fr "$f" > /dev/null - fi - done + if [ -z "$1" ] + then + echo "tex2md: No argument given" + exit 2 + fi + DEST="$1" - cd include for i in `find -type f -name '*.tex'` do bi=`basename "$i"` echo -e "\e[1;34m>>>\e[1;37m Trying to convert $i to Markdown...\e[0m" - + sed -Ei 's/\\includegraphics *\{([^}]+)}/\\verb+%%image(\1)+/gi' "$i" sed -Ei 's/\\include *\{([^}]+)}/\\verb+%%scoped-include(\1)+/gi' "$i" sed -Ei 's/\\input *\{([^}]+)}/\\verb+%%scoped-include(\1)+/gi' "$i" @@ -64,22 +59,20 @@ clean_tex() sed -Ei 's/\\frame//g' "$i" sed -Ei 's/\\item( *)<[^>]+>/\\item\1/g' "$i" - if pandoc -o ../${bi%%.tex}.md $i + if pandoc -o "$DEST"/${bi%%.tex}.md $i then - git add ../${bi%%.tex}.md + git add "$DEST"/${bi%%.tex}.md git checkout "$i" git rm -f "$i" > /dev/null fi - sed -Ei 's/`%%([a-z-])\(([^)]+)\)`/%%\1(\2)/gi' "../${bi%%.tex}.md" - sed -Ei 's/\\$/\n/' "../${bi%%.tex}.md" + sed -Ei 's/`%%([a-z-])\(([^)]+)\)`/%%\1(\2)/gi' "$DEST/${bi%%.tex}.md" + sed -Ei 's/\\$/\n/' "$DEST/${bi%%.tex}.md" done - if [ `find | wc -l` -gt 1 ] - then - git mv * .. - fi - cd - > /dev/null +} +maintex2md() +{ if [ -f "mySubject.md" ] then git mv "mySubject.md" "main.md" @@ -93,8 +86,57 @@ clean_tex() then git mv "myTutorial.md" "main.md" fi +} - rmdir include +clean_tex() +{ + if [ -z "$1" ] || ! [ -d "$1" ] + then + echo "NON" + exit 1; + fi + + for f in data Makefile images/acu.pdf images/assistants.pdf images/assistants-subject.pdf images/assistants-slides.pdf images/assistants.png images/epita.pdf images/epita.png images/epita-invert.pdf images/assistants-invert.pdf images/epita-invert.png images/assistants-bg.png images/logo_epita.jpg images/acu-bottom.png images/acu-bottom.pdf images/acu-bg.pdf images/acu2011.png images/acu.png *.cls *.sty *.tex + do + if [ -f "$f" ] + then + git rm -f "$f" > /dev/null + elif [ -d "$f" ] + then + git rm -fr "$f" > /dev/null + fi + done + + if [ -d "include" ] + then + cd include + tex2md .. + + if [ `find | wc -l` -gt 1 ] + then + git mv * .. + fi + + cd "$1" + tex2md . + maintex2md + rmdir include 2> /dev/null + elif [ `find -mindepth 1 -maxdepth 1 -name '*.tex' | wc -l` -gt 0 ] + then + tex2md . + + else + for i in * + do + if [ -d "$i" ] + then + echo -e "\e[1;32m>>>\e[1;37m Subsubject found: $i\e[0m" + cd "$i" + clean_tex "$1/$i" "$1" + fi + done + fi + cd "$2" } TMPDIR=`mktemp -d` @@ -242,8 +284,7 @@ do then echo -e "\e[1;32m##\e[1;37m Find directory $DIR with some .tex files \e[1;32m##\e[0m" cd "$DIR" - clean_tex "$DIR" - cd .. + clean_tex `pwd` `readlink -f "$(pwd)/.."` echo -e "\e[1;32m## ## ## ## ##\e[0m" echo From adb450343fb35f5a824e16840697151184aefeec Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 18 Oct 2013 04:18:38 +0200 Subject: [PATCH 164/364] LPT: handle intra groups: can create, remove, change known attribute, view, ... --- utils/lpt | 441 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 253 insertions(+), 188 deletions(-) diff --git a/utils/lpt b/utils/lpt index 0f08a1b..5fc2f31 100755 --- a/utils/lpt +++ b/utils/lpt @@ -76,7 +76,6 @@ my %cmds_account = "services" => \&cmd_account_services, "shell" => \&cmd_account_shell, "view" => \&cmd_account_view, - "view" => \&cmd_account_view, "grant-intra" => \&cmd_account_grantintra, "grant-lab" => \&cmd_account_grantlab, @@ -85,9 +84,9 @@ my %cmds_account = my %cmds_group = ( - "list" => \&cmd_group_list, - "add" => \&cmd_group_add, - "remove" => \&cmd_group_remove, + "view" => \&cmd_group_view, + "members" => \&cmd_group_members, + "rights" => \&cmd_group_rights, "create" => \&cmd_group_create, "delete" => \&cmd_group_delete ); @@ -767,9 +766,16 @@ sub cmd_account_view($@) sub cmd_group(@) { my $gname = shift; + my $year; + + if ($gname && $gname =~ /^(20[0-9]{2})$/) + { + $year = $1; + $gname = shift; + } if (! $gname) { - log(USAGE, "lpt group [arguments ...]"); + log(USAGE, "lpt group [year] [arguments ...]"); return 1; } @@ -784,209 +790,268 @@ sub cmd_group(@) return 1; } - return $cmds_group{$subcmd}($gname, @_); + return $cmds_group{$subcmd}($gname, $year, @_); } -sub cmd_group_list(@) +sub cmd_group_multiple_vieworchange { - if ($#ARGV > 0) - { - log(USAGE, " group list [group]"); - exit(1); - } - - my $group = $ARGV[0]; - my $ldap = LDAP::ldap_connect_anon(); - if ($#ARGV == 0) - { - my $mesg = $ldap->search( # search a group - base => "cn=$group,ou=groups,dc=acu,dc=epita,dc=fr", - filter => "objectClass=posixGroup", - attrs => ['memberUid'] - ); - $mesg->code && die $mesg->error; - $mesg->count > 0 || return -1; - - foreach my $entry ($mesg->sorted('memberUid')) - { - foreach my $user ($entry->get_value("memberUid")) - { - print "$user\n"; - } - } - } - else - { - my $mesg = $ldap->search( # list groups - base => "ou=groups,dc=acu,dc=epita,dc=fr", - filter => "objectClass=posixGroup", - attrs => ['cn', 'gidNumber'] - ); - - - $mesg->code && die $mesg->error; - $mesg->count > 0 || return -1; - - foreach my $entry ($mesg->sorted('gidNumber')) - { - print $entry->get_value("cn")." --->"; - print $entry->get_value("gidNumber")."\n"; - } - } - - $ldap->unbind; # take down session -} - -sub cmd_group_add(@) -{ - my $group = shift; - - if ($#_ < 0) - { - log(USAGE, " group add "); - exit(1); - } - - my $login = shift; - - my $ldap = LDAP::ldap_connect(); - - my $mesg = $ldap->search( # search a group - base => "cn=$group,ou=system,ou=groups,dc=acu,dc=epita,dc=fr", - filter => "objectClass=posixGroup", - attrs => ['memberUid'] - ) or die $!; - $mesg->code && die $mesg->error; - $mesg->count > 0 || return -1; - - foreach my $entry ($mesg->entries) - { - my @mem = $entry->get_value("memberUid"); - - foreach my $member (@mem) - { - if ($member eq $login) - { - log WARN, "$login est déjà dans le groupe $group"; - $ldap->unbind; - exit 1; - } - } - - push @mem, $login; - $entry->replace("memberUid" => \@mem); - $entry->update($ldap); - - log INFO, "$login ajouté au groupe $group avec succès."; - } - $ldap->unbind; # take down session -} - -sub cmd_group_remove(@) -{ - if ($#ARGV < 1) - { - log(USAGE, " group remove "); - exit(1); - } - - my $group = $ARGV[0]; - my $login = $ARGV[1]; - - my $ldap = LDAP::ldap_connect(); - - my $mesg = $ldap->search( # search a group - base => "cn=$group,ou=groups,dc=acu,dc=epita,dc=fr", - filter => "objectClass=posixGroup", - attrs => ['memberUid'] - ); - $mesg->code && die $mesg->error; - $mesg->count > 0 || return -1; - - foreach my $entry ($mesg->sorted('memberUid')) - { - my @mem = $entry->get_value("memberUid"); - my $found = 0; - foreach my $user (@mem) - { - if ($user eq $login) - { - $found = 1; - } - } - - if ($found) - { - @mem = grep(!/$login$/, @mem); - $entry->replace("memberUid" => [@mem]); - $entry->update($ldap); - } - else - { - print "$login n'est pas dans le groupe $group\n"; - } - - print "Nouvelle liste des membres de $group :\n"; - foreach my $user (@mem) - { - print "$user\n"; - } - - } - $ldap->unbind; # take down session - - system('service nscd restart'); -} - -sub cmd_group_create($$) -{ - if ($#_ != 1) - { - log(USAGE, " group create "); - exit(1); - } - my $type = shift; - my $year = shift; - my $cn = $type . $year; - my $gid; - if ($type eq "acu") { - $gid = $year; + my $typeName = shift; + my $gname = shift; + my $year = shift // LDAP::get_year(); + my $action = shift // "list"; + my $change = shift; + + if (($action ne "list" and $action ne "add" and $action ne "del" and $action ne "flush") or (!$change and $action ne "list" and $action ne "flush")) { + log(USAGE, " group $typeName [list|add|del|flush] [string]"); + return 1; } - elsif ($type eq "yaka") { - $gid = $year - 1000; + + my $ldap; + $ldap = LDAP::ldap_connect() if ($action ne "list"); + $ldap = LDAP::ldap_connect_anon() if ($action eq "list"); + my $mesg = $ldap->search( # search + base => "ou=groups,dc=acu,dc=epita,dc=fr", + filter => "cn=$gname", + attrs => [ $type ], + scope => "sub" + ); + if ($mesg->code != 0) { + log(ERROR, $mesg->error); + } + if ($mesg->count != 1) { + log(ERROR, "Group $gname not found or multiple presence"); + } + + if ($action eq "add") { + log(INFO, "Adding $change as ".$typeName."s for $gname ..."); + + my @data = $mesg->entry(0)->get_value($type); + + if (! grep(/^$change$/, @data)) { + push @data, $change; + $mesg->entry(0)->replace($type => \@data) or die $!; + $mesg->entry(0)->update($ldap) or die $!; + + log(INFO, "Done!"); + } + else { + log(WARN, "$gname has already $change $typeName."); + } + } + elsif ($action eq "del") { + log(INFO, "Checking if $change is a ".$typeName."s of $gname ..."); + my @data = $mesg->entry(0)->get_value($type); + if (grep(/^$change$/, @data)) { + log(INFO, "Deleting $change as $typeName for $gname ..."); + + @data = grep(!/$change$/, @data); + + $mesg->entry(0)->replace($type => \@data) or die $!; + $mesg->entry(0)->update($ldap) or die $!; + + log(INFO, "Done!"); + } + else { + log(WARN, "$change is not a $typeName for $gname."); + } + } + elsif ($action eq "flush") { + $ldap->modify($mesg->entry(0)->dn, delete => [$type]); + log(INFO, "$gname have no more $typeName."); } else { - log(ERROR, "Error: type must be acu or yaka!"); + if ($mesg->entry(0)->get_value($type)) { + log(INFO, $gname."'s ".$typeName."s are:"); + for my $val ($mesg->entry(0)->get_value($type)) { + say " - $val"; + } + } + else { + log(INFO, "$gname have no $typeName."); + } } - my $ldap = LDAP::ldap_connect(); + $ldap->unbind or die ("couldn't disconnect correctly"); + return 0; +} - my $mesg = $ldap->add( "cn=$cn,ou=groups,dc=acu,dc=epita,dc=fr", - attrs => [ - objectclass => "posixGroup", - gidNumber => $gid, - cn => $cn, - ] +sub cmd_group_vieworchange +{ + my $type = shift; + my $typeName = shift; + my $gname = shift; + my $year = shift // LDAP::get_year(); + + if ($#_ > 0) { + log(USAGE, " group $typeName [new_string]"); + return 1; + } + + my $change = shift; + + my $ldap; + $ldap = LDAP::ldap_connect() if ($change); + $ldap = LDAP::ldap_connect_anon() if (!$change); + + my $mesg = $ldap->search( # search + base => "ou=groups,dc=acu,dc=epita,dc=fr", + filter => "uid=$gname", + attrs => [ $type ], + scope => "sub" ); - if ($mesg->code != 0) { die $mesg->error; } + if ($mesg->code != 0) { + log(ERROR, $mesg->error); + } + if ($mesg->count != 1) { + log(ERROR, "User $gname not found or multiple presence"); + } + + if ($change) { + log(INFO, "Setting $typeName to $change for $gname ..."); + + $mesg->entry(0)->replace($type => $change) or die $!; + $mesg->entry(0)->update($ldap) or die $!; + + log(INFO, "Done!"); + } + elsif ($mesg->entry(0)->get_value($type)) { + log(INFO, $gname."'s $typeName is ".$mesg->entry(0)->get_value($type)."."); + } + else { + log(INFO, $gname."'s has no $typeName."); + } $ldap->unbind or die ("couldn't disconnect correctly"); + return 0; +} - log(INFO, "group added: $cn"); +sub cmd_group_view +{ + my $gname = shift; + my $year = shift; + if ($year) { + $year = "ou=$year,"; + } else { + $year = ""; + } + + my $ldap = LDAP::ldap_connect_anon(); + + my $mesg = $ldap->search(base => $year."ou=intra,ou=groups,dc=acu,dc=epita,dc=fr", + filter => "cn=$gname", + attrs => ['objectClass']); + + $mesg->code && log(ERROR, $mesg->error); + log(ERROR, "No such group!") if ($mesg->count <= 0); + + log(DEBUG, "objectClasses:\t" . join(', ', $mesg->entry(0)->get_value("objectClass"))); + + my @attrs = ['dn']; + if ($#_ >= 0) { + push @attrs, @_; + } + else { + if (grep { "intraGroup" } $mesg->entry(0)->get_value("objectClass")) { + push @attrs, 'intraRight'; + } + if (grep { "posixGroup" } $mesg->entry(0)->get_value("objectClass")) { + push @attrs, 'cn', 'memberUid'; + } + } + + log(DEBUG, "attrs to get: " . join(', ', @attrs)); + + $mesg = $ldap->search(base => $year."ou=intra,ou=groups,dc=acu,dc=epita,dc=fr", + filter => "cn=$gname", + attrs => \@attrs); + $mesg->code && die $mesg->error; + + shift @attrs; # Remove dn + my $nb = 0; + for my $entry ($mesg->entries) + { + if ($nb > 0) { + say "=="; + } + say BOLD, YELLOW, "dn: ", RESET, YELLOW, $entry->dn, RESET; + + for my $attr (@attrs) { + if ($#attrs < 3) { + for my $entry ($entry->get_value($attr)) { + say CYAN, "$attr: ", RESET , $entry; + } + } + else { + say CYAN, "$attr: ", RESET , join(', ', $entry->get_value($attr)); + } + } + + $nb++; + } + + if ($nb > 1) { + say "\n$nb groups displayed"; + } + + $ldap->unbind or die ("couldn't disconnect correctly"); + return 0; +} + +sub cmd_group_members($@) +{ + return cmd_group_multiple_vieworchange('memberUid', 'member', @_); +} + +sub cmd_group_rights($@) +{ + return cmd_group_multiple_vieworchange('intraRight', 'right', @_); +} + +sub cmd_group_create +{ + my $gname = shift; + my $year = shift // LDAP::get_year(); + + log(DEBUG, "Adding dn: cn=$gname,ou=$year,ou=intra,ou=groups,dc=acu,dc=epita,dc=fr ..."); + + my $ldap = LDAP::ldap_connect(); + my $mesg = $ldap->add( "cn=$gname,ou=$year,ou=intra,ou=groups,dc=acu,dc=epita,dc=fr", + attrs => [ + objectclass => [ "top", "intraGroup" ], + cn => $gname, + ] + ); + + #$ldap->unbind or die ("couldn't disconnect correctly"); + + if ($mesg->code == 0) { + log(INFO, "Group added: $gname"); + return 0; + } + else { + log(ERROR, "Unable to add: $gname: ", RESET, $mesg->error); + } } sub cmd_group_delete(@) { - if ($#ARGV != 1) - { - log(USAGE, " group delete "); - exit(1); + my $gname = shift; + my $year = shift // LDAP::get_year(); + + my $dn = "cn=$gname,ou=$year,ou=intra,ou=groups,dc=acu,dc=epita,dc=fr"; + + log(DEBUG, "Deletinging dn: $dn ..."); + + my $ldap = LDAP::ldap_connect(); + if (LDAP::delete_entry($ldap, $dn)) { + log DONE, "Group $gname successfully deleted."; + } else { + log ERROR, "Unable to delete group $gname."; + return 1; } - print "TODO!"; - print "hint: ldapdelete -v -h ldap.acu.epita.fr -x -w \$LDAP_PASSWD -D 'cn=admin,dc=acu,dc=epita,dc=fr' 'cn=yaka2042,ou=groups,dc=acu,dc=epita,dc=fr'"; - exit(1); + return 0; } From 15790db5772e344a3278cc4f3047e406062cc452 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 18 Oct 2013 04:54:28 +0200 Subject: [PATCH 165/364] intradata_get: croak instead of log+return --- process/files/intradata_get.pl | 97 +++++++++++----------------------- 1 file changed, 31 insertions(+), 66 deletions(-) diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index b3a9039..b095300 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -39,16 +39,11 @@ sub create_tree($$) my $year = shift; my $project_id = shift; - if (! -d "$basedir/$year/") { - log ERROR, "No directory for year $year. Ask a root to create it."; - return "No directory for year $year. Ask a root to create it."; - } + croak "No directory for year $year. Ask a root to create it." if (! -d "$basedir/$year/"); if (! -e "$basedir/$year/$project_id/") { mkdir "$basedir/$year/$project_id/"; } - - return 0; } @@ -59,10 +54,7 @@ sub grades_generate my $project_id = $args->{param}{id}; my $year = $args->{param}{year} // LDAP::get_year; - if (! $project_id) { - log ERROR, "No project_id given."; - return "No project_id given"; - } + croak "No project_id given." if (! $project_id); if (! -e "$basedir/$year/$project_id/grades/") { mkdir "$basedir/$year/$project_id/grades/"; @@ -105,10 +97,7 @@ sub grades_generate if (exists $args->{files}{"grading.xml"}) { $grading = $args->{files}{"grading.xml"}; } - if (! $grading) { - log ERROR, "Invalid grading.xml received!"; - return "Invalid grading.xml received!"; - } + croak "Invalid grading.xml received!" if (! $grading); $grading = Grading->new($grading); @@ -146,7 +135,7 @@ sub grades_generate $grading->reset(); } - return "Ok"; + return 1; } sub grades_new_bonus @@ -157,10 +146,7 @@ sub grades_new_bonus my $delete = $args->{param}{delete}; my $year = $args->{param}{year} // LDAP::get_year; - if (! $project_id) { - log ERROR, "No project_id given."; - return "No project_id given"; - } + croak "No project_id given" if (! $project_id); if (! -e "$basedir/$year/$project_id/traces/") { mkdir "$basedir/$year/$project_id/traces/"; @@ -240,7 +226,7 @@ sub grades_new_bonus } } - return "Ok"; + return 1; } sub update_defense @@ -250,26 +236,17 @@ sub update_defense my $project_id = $args->{param}{id}; my $year = $args->{param}{year} // LDAP::get_year; - if (! $project_id) { - log ERROR, "No project_id given."; - return "No project_id given"; - } + croak "No project_id given" if (! $project_id); my $defense_id = $args->{param}{defense_id}; - if (! $defense_id) { - log ERROR, "No defense_id given."; - return "No defense_id given"; - } + croak "No defense_id given" if (! $defense_id); my $defense; if (exists $args->{files}{"$defense_id.xml"}) { $defense = $args->{files}{"$defense_id.xml"}; } - if (! $defense) { - log ERROR, "Invalid $defense_id.xml received!"; - return "Invalid $defense_id.xml received!"; - } + croak "Invalid $defense_id.xml received!" if (! $defense); log INFO, "Update $year/$project_id/defenses/$defense_id.xml"; @@ -290,7 +267,7 @@ sub update_defense print $out $defense; close $out; - return "Ok"; + return 1; } sub update_project @@ -300,29 +277,23 @@ sub update_project my $project_id = $args->{param}{id}; my $year = $args->{param}{year} // LDAP::get_year; - if (! $project_id) { - log ERROR, "No project_id given."; - return "No project_id given"; - } + croak "No project_id given" if (! $project_id); my $butler; if (exists $args->{files}{"butler.xml"}) { $butler = $args->{files}{"butler.xml"}; } - if (! $butler) { - log ERROR, "Invalid butler.xml received!"; - return "Invalid butler.xml received!"; - } + croak "Invalid butler.xml received!" if (! $butler); log INFO, "Update $year/$project_id/butler.xml"; - return $_ if (create_tree($year, $project_id)); + create_tree($year, $project_id); open my $out, ">", "$basedir/$year/$project_id/butler.xml"; print $out $butler; close $out; - return "Ok"; + return 1; } sub update_trace @@ -332,33 +303,21 @@ sub update_trace my $project_id = $args->{param}{id}; my $year = $args->{param}{year} // LDAP::get_year; - if (! $project_id) { - log ERROR, "No project_id given."; - return "No project_id given"; - } + croak "No project_id given" if (! $project_id); my $rendu_id = $args->{param}{rendu}; - if (! $rendu_id) { - log ERROR, "No rendu_id given."; - return "No rendu_id given"; - } + croak "No rendu_id given" if (! $rendu_id); my $login = $args->{param}{login}; - if (! $login) { - log ERROR, "No login given."; - return "No login given"; - } + croak "No login given" if (! $login); my $trace; if (exists $args->{files}{"$login.xml"}) { $trace = $args->{files}{"$login.xml"}; } - if (! $trace) { - log ERROR, "Invalid $login.xml received!"; - return "Invalid $login.xml received!"; - } + croak "Invalid $login.xml received!" if (! $trace); log INFO, "Update $year/$project_id/traces/$rendu_id/$login.xml"; @@ -370,11 +329,11 @@ sub update_trace chmod 0755, "$basedir/$year/$project_id/traces/$rendu_id/"; } - open my $out, ">", "$basedir/$year/$project_id/traces/$rendu_id/$login.xml"; + open my $out, ">", "$basedir/$year/$project_id/traces/$rendu_id/$login.xml" or croak(""); print $out $trace; close $out; - return "Ok"; + return 1; } sub delete_project @@ -390,12 +349,18 @@ sub process_get my $type = $args->{param}{type}; my $action = $args->{param}{action} // "update"; - if (! exists $actions{$type}{$action}) { - log WARN, "Unknown action '$action' for $type."; - return "Unknown action '$action' for $type."; - } + croak "Unknown action '$action' for $type." if (! exists $actions{$type}{$action}); + + eval { + $actions{$type}{$action}($args); + }; + if ($@) { + my $err = $@; + log ERROR, $err; + return $err; + } + return "Ok"; - return $actions{$type}{$action}($args); } Process::register("intradata_get", \&process_get); From 4bff8d88ebae7313dc5c35fa376ecd2be094a6b7 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 18 Oct 2013 04:57:37 +0200 Subject: [PATCH 166/364] Error message if unable to write to the trace directory --- process/files/intradata_get.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index b095300..e077d58 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -329,7 +329,7 @@ sub update_trace chmod 0755, "$basedir/$year/$project_id/traces/$rendu_id/"; } - open my $out, ">", "$basedir/$year/$project_id/traces/$rendu_id/$login.xml" or croak(""); + open my $out, ">", "$basedir/$year/$project_id/traces/$rendu_id/$login.xml" or croak("Unable to write to $rendu_id/$login.xml"); print $out $trace; close $out; From 335b03768dc31527c24bdd6a8556409a2372c7a0 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 18 Oct 2013 07:34:33 +0200 Subject: [PATCH 167/364] moulette_get: Add jexec statements, monitor filesystem to send traces to intranet --- process/files/moulette_get.pl | 265 +++++++++++++++++++++++++++++----- 1 file changed, 225 insertions(+), 40 deletions(-) diff --git a/process/files/moulette_get.pl b/process/files/moulette_get.pl index 8a3ff12..c03c834 100644 --- a/process/files/moulette_get.pl +++ b/process/files/moulette_get.pl @@ -3,11 +3,13 @@ use v5.10.1; use strict; use warnings; +#use threads; use Carp; -use Pod::Usage; +use File::Basename; use File::Copy; -use File::Path qw(remove_tree); +use File::Path qw(remove_tree mkpath); use File::Temp qw/tempfile tempdir/; +use Sys::Gamin; use ACU::Log; use ACU::Process; @@ -16,24 +18,76 @@ my %actions = ( "tar" => \&receive_tar, "git" => \&receive_git, + "ref" => \&receive_ref, "tests" => \&create_testsuite, "moulette" => \&moulette, ); +my $fm = new Sys::Gamin; +my %project_paths; + +sub jail_exec +{ + my $cmd = shift; + + qx(jexec moulette1 /bin/sh -c "FACT='/usr/local/bin/mono /usr/local/fact/FactExe.exe' $cmd"); + croak "Erreur while executing '$cmd'" if ($?); +} + +sub fact_exec +{ + my $cmd = shift; + my $rundir = shift; + jail_exec("cd $rundir && /usr/local/bin/mono /usr/local/fact/FactExe.exe $cmd"); +} + sub prepare_dir { my $year = shift; my $project_id = shift; my $rendu = shift; - # TODO: replace ~calvair by the destination directory - my $dir = "~calvair/$year-$project_id-$rendu/"; + my @dirs = ("/data/work/$year-$project_id-$rendu/", "/data/output/$year-$project_id-$rendu/"); - if (! -d $dir) { - mkpath($destdir) or croak "An error occurs while creating directory: $!"; + for my $dir (@dirs) + { + if (! -d $dir) { + mkpath($dir) or croak "An error occurs while creating directory: $!"; + } + my ($login, $pass, $uid, $gid) = getpwnam("intradmin"); + chown $uid, $gid, $dir; + chmod 0770, $dir; } - return $dir; + return @dirs; +} + +sub receive_ref +{ + my $args = shift; + my $project_id = $args->{param}{id}; + my $year = $args->{param}{year}; + my $rendu = $args->{param}{rendu}; + my $file = $args->{param}{file}; + + croak "No file named '$file' given" if (!exists $args->{files}{$file}); + + my $tempdir = tempdir(DIR => '/data/tmp'); + + open my $fh, "|tar -xz -f - -C '$tempdir'"; + print $fh $args->{files}{$file}; + close $fh; + + croak "An error occurs while extracting the tarball" if ($?); + + jail_exec("gmake -C $tempdir/ref/ fact"); + croak "An error occurs while making the testsuite" if ($?); + + my $destdir = ( prepare_dir($year, $project_id, $rendu) )[0]; + copy("$tempdir/ref/ref.ff", "$destdir/ref.ff") or croak "An error occurs while coping ref.ff: $!"; + + # Clean + remove_tree($tempdir); } sub receive_tar @@ -47,18 +101,21 @@ sub receive_tar croak "No file named '$file' given" if (!exists $args->{files}{$file}); - my ($fh, $filename) = tempfile(SUFFIX => $file); + my ($fh, $filename) = tempfile(DIR => '/data/tmp', SUFFIX => $file); binmode($fh); print $fh $args->{files}{$file}; close $fh; + chmod 0644, $filename; - my $destdir = prepare_dir($year, $project_id, $file); - # TODO: Call Fact for create .ff - # qx(Fact package create $filename $destdir/$login.ff) + my $destdir = ( prepare_dir($year, $project_id, $rendu) )[0]; + fact_exec("package create $filename $destdir/$login.ff", $destdir); croak "Cannot create $login.ff" if ($?); + chmod 0666, "$destdir/$login.ff"; # Clean unlink $filename; + + run_moulette($project_id, $year, $rendu, $login); } sub receive_git @@ -72,20 +129,22 @@ sub receive_git croak "No file named '$file' given" if (!exists $args->{files}{$file}); - my $tempdir = tempdir(); - open my $fh, "|tar -xz -C '$tempdir'"; + my $tempdir = tempdir(DIR => '/data/tmp'); + open my $fh, "|tar -xz -f - -C '$tempdir'"; print $fh $args->{files}{$file}; close $fh; croak "An error occurs while extracting the tarball" if ($?); - my $destdir = prepare_dir($year, $project_id, $file); - # TODO: Call Fact for create .ff - # qx(Fact package create $tempdir $destdir/$login.ff) + my $destdir = ( prepare_dir($year, $project_id, $rendu) )[0]; + fact_exec("package create $tempdir $destdir/$login.ff", $destdir); croak "Cannot create $login.ff" if ($?); + chmod 0666, "$destdir/$login.ff"; # Clean remove_tree($tempdir); + + run_moulette($project_id, $year, $rendu, $login); } sub create_testsuite @@ -98,52 +157,173 @@ sub create_testsuite croak "No file named '$file' given" if (!exists $args->{files}{$file}); - my $tempdir = tempdir(); - open my $fh, "|tar -xz -C '$tempdir'"; + my $tempdir = tempdir(DIR => '/data/tmp'); + + open my $fh, "|tar -xz -f - -C '$tempdir'"; print $fh $args->{files}{$file}; close $fh; croak "An error occurs while extracting the tarball" if ($?); - qx(make -C $tempdir/tests/); + jail_exec("gmake -C $tempdir/tests/"); croak "An error occurs while making the testsuite" if ($?); - my $destdir = prepare_dir($year, $project_id, $rendu); + my $destdir = ( prepare_dir($year, $project_id, $rendu) )[0]; copy("$tempdir/tests/tests.ff", "$destdir/tests.ff") or croak "An error occurs while coping the testsuite: $!"; copy("$tempdir/tests/test.ft", "$destdir/test.ft") or croak "An error occurs while coping test.ft: $!"; + chmod 0660, "$destdir/tests.ff"; + chmod 0660, "$destdir/test.ft"; # Clean remove_tree($tempdir); + + run_moulette($project_id, $year, $rendu); +} + +sub run_moulette +{ + my $project_id = shift; + my $year = shift; + my $rendu = shift; + my @logins = @_; + + #TODO: find the right test dir, '' is most generic one + my $testdir = ( prepare_dir($year, $project_id, "") )[0]; + my ($submitdir, $outputdir) = prepare_dir($year, $project_id, $rendu); + + if ($#logins == -1) + { + # Get all submissions + opendir(my $dh, $submitdir) or die "Can't list files in $submitdir: $!"; + while (readdir($dh)) + { + if (/([a-zA-Z0-9_-]+).ff$/ && -f "$submitdir/$_") { + push @logins, $1; + } + } + closedir $dh; + } + + for my $login (@logins) + { + my $fhin; + if (-f "$testdir/$login.ft") { + open $fhin, "<", "$testdir/$login.ft" or croak "Unable to open $testdir/$login.ft: $!"; + } elsif (-f "$testdir/test.ft") { + open $fhin, "<", "$testdir/test.ft" or croak "Unable to open $testdir/test.ft: $!"; + } + + if ($fhin) + { + open my $fhout, ">", "$submitdir/$login.ft" or croak "Unable to update $submitdir/$login.ft file: $!"; + while (<$fhin>) + { + $_ =~ s/#LOGIN_X/$login/g; + $_ =~ s%#GLOBAL%/data/global/%g; + $_ =~ s/#PROJECT/$testdir/g; + $_ =~ s/#SUBMIT/$submitdir/g; + $_ =~ s/#OUTPUT/$outputdir/g; + print $fhout $_; + } + close $fhin; + close $fhout; + } + + croak "Unable to find a relevant $login.ft, abort moulette start." if (! -f "$submitdir/$login.ft"); + + log WARN, "There is no ref for $project_id $rendu" if (! -f "$testdir/ref.ff"); + log WARN, "There is no $login.ff for $project_id $rendu" if (! -f "$submitdir/$login.ff"); + + # Monitor the trace creation + if (! grep { $outputdir } %project_paths) + { + $project_paths{$outputdir} = { "id" => $project_id, "year" => $year, "rendu" => $rendu }; + $fm->monitor($outputdir); + } + + log INFO, "$submitdir/$login append to Fact manager"; + fact_exec("system manager $submitdir/$login.ft", $submitdir); + + log ERROR, "An error occurs while starting tests for $login on $year-$project_id-$rendu" if ($?); + } } sub moulette { my $args = shift; - my $project_id = $args->{param}{id}; - my $year = $args->{param}{year}; - my $rendu = $args->{param}{rendu}; - my $testdir = prepare_dir($year, $project_id, $rendu); - - chdir($testdir); - for (my $i = $args->{unamed}; $i > 0; $i--) + if ($args->{unamed} == 0) { - my $login = $args->{param}{$i} - - open my $fhin, "<", "$testdir/test.ft"; - open my $fhout, ">", "$testdir/$login.ft"; - print $fhout s/#LOGIN_X/$login/g while (<$fhin>); - close $fhin; - close $fhout; - - # TODO: Call Fact to launch student tarball - # qx(Fact system manager $login.ft) - - log WARN, "An error occurs while starting tests for $login on $year-$project_id-$rendu" if ($?); + # Run on all submissions + run_moulette($args->{param}{id}, + $args->{param}{year}, + $args->{param}{rendu}); + } + else + { + for (my $i = $args->{unamed}; $i > 0; $i--) + { + run_moulette($args->{param}{id}, + $args->{param}{year}, + $args->{param}{rendu}, + $args->{param}{$i}); + } } } +sub trace_send +{ + my $path = shift; + my $filename = shift; + my $login = shift; + my %infos = %{ $project_paths{ $path } }; + + return if (! -f "$path/$filename"); + + my $file_content; + open my $fh, "<", "$path/$filename" or croak("Unable to read $path/$filename: $!"); + $file_content .= $_ while(<$fh>); + close $fh; + + log INFO, "Send trace from $path/$filename to intranet ..."; + + # Send trace over Gearman + Process::Client::launch( + "intradata_get", + { "type" => "trace", + "action" => "update", + "id" => $infos{id}, + "year" => $infos{year}, + "rendu" => $infos{rendu}, + "login" => $login }, + { "$login.xml" => $file_content }, + 1 + ); + + # Remove transfered trace + unlink "$path/$filename"; +} + +sub monitor_traces +{ + my $event = shift; + + log DEBUG, "Pathname: ".$event->filename." Event: ".$event->type." Where: ".$fm->which($event); + + if (($event->type eq "create" || $event->type eq "change" || $event->type eq "exist") && + $event->filename =~ /([^\/\\]+)\.xml$/ && + grep { $fm->which($event) } %project_paths) + { + trace_send($fm->which($event), $event->filename, $1); + } +} + +sub monitor_start +{ + monitor_traces( $fm->next_event ) while (1); +} + sub process_get { my ($given_args, $args) = @_; @@ -157,7 +337,7 @@ sub process_get eval { $actions{$type}($args); - } + }; if ($@) { my $err = $@; log ERROR, $err; @@ -166,4 +346,9 @@ sub process_get return "Ok"; } +#threads->create('monitor_start'); Process::register("moulette_get", \&process_get); + +#$project_paths{'/data/output/2016-exam-c-0-rendu-1'} = { "id" => "exam-c-0", "year" => "2016", "rendu" => "rendu-1" }; +#$fm->monitor('/data/output/2016-exam-c-0-rendu-1'); +#monitor_start(); From 0e35a1a2e9f5a5ef19ce14b785b2b4027c20dd9b Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 18 Oct 2013 08:48:43 +0200 Subject: [PATCH 168/364] send_git: new process to send a student repository to moulette --- process/files/send_git.pl | 52 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 process/files/send_git.pl diff --git a/process/files/send_git.pl b/process/files/send_git.pl new file mode 100644 index 0000000..7322d39 --- /dev/null +++ b/process/files/send_git.pl @@ -0,0 +1,52 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use v5.10; +use File::Path qw(remove_tree); +use File::Temp qw/tempfile tempdir/; + +use ACU::Log; +use ACU::Process; + + +sub process +{ + my ($given_args, $args) = @_; + + my $year = $args->{param}{year}; + my $project_id = $args->{param}{id}; + my $rendu = $args->{param}{rendu}; + my $login = $args->{param}{login}; + + my $path = $args->{param}{path} // "/srv/git/repositories/$year/$project_id/$login.git"; + + return "$path is not a valid path." if (! -d $path); + + my $tempdir = tempdir(); + + qx/git clone -b '$rendu' '$path' '$tempdir'/; + + my $tar; + open my $fh, "tar -czf - -C '$tempdir' . |"; + $tar .= $_ while(<$fh>); + close $fh; + + # Clean + remove_tree($tempdir); + + return Process::Client::launch("moulette_get", + { + "type" => "std", + "id" => $project_id, + "year" => $year, + "rendu" => $rendu, + "login" => $login, + "file" => "rendu.tgz" + }, + { + "rendu.tgz" => $tar + }); +} + +Process::register("send_git", \&process); From 72800c21cc35a1352276e61125e7aaf896f0bb7b Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 18 Oct 2013 08:50:30 +0200 Subject: [PATCH 169/364] New command to send a directory to moulette --- commands/project/send_dir_to_moulette.sh | 39 ++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100755 commands/project/send_dir_to_moulette.sh diff --git a/commands/project/send_dir_to_moulette.sh b/commands/project/send_dir_to_moulette.sh new file mode 100755 index 0000000..ba45cec --- /dev/null +++ b/commands/project/send_dir_to_moulette.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +if [ "$#" -ne 3 ] +then + echo "Usage: $0 project rendu git_repo" + exit 1 +fi + +project_id="$1" +rendu="$2" +git_repo="$3" + +if ! whereis gearman > /dev/null 2> /dev/null +then + echo "gearman isn't installed on this machine. Please try another one." + exit 1 +fi + + if [ ! -d "$git_repo" ]; then + ls "$git_repo" + echo "$git_repo: file not found" + exit 2 +fi + +FILENAME=$(basename "$git_repo") +FILE="$(tar -czf - -C "$git_repo" . | base64 )" + +cat < + + std + $project_id + 2016 + $rendu + $FILENAME + $FILENAME +$FILE + +EOF From 18608fe325613b34ac99c3c74c6eefbee9ecad2a Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 18 Oct 2013 09:08:59 +0200 Subject: [PATCH 170/364] hooks/subject: * not allowed in tag --- hooks/subjects.pl | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index edd7cd5..34411d0 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -490,7 +490,7 @@ sub tag_ref $rendu = $_[2]; } else { - $rendu = "*"; + $rendu = ""; } my $year; @@ -511,11 +511,7 @@ sub tag_ref my $long_tag; { my $proj_id = $_[1] // ""; - if ($rendu eq "*") { - $long_tag = "ref,$proj_id,,$year"; - } else { - $long_tag = "ref,$proj_id,$rendu,$year"; - } + $long_tag = "ref,$proj_id,$rendu,$year"; } if ($creation) @@ -600,13 +596,7 @@ sub tag_tests $project_id = lc $project_id; $project_id =~ s/[^a-z0-9-_]/_/g; - my $rendu; - if ($_[2]) { - $rendu = $_[2]; - } - else { - $rendu = "*"; - } + my $rendu = $_[2]; my $year; if ($_[3]) @@ -626,11 +616,7 @@ sub tag_tests my $long_tag; { my $proj_id = $_[1] // ""; - if ($rendu eq "*") { - $long_tag = "tests,$proj_id,,$year"; - } else { - $long_tag = "tests,$proj_id,$rendu,$year"; - } + $long_tag = "tests,$proj_id,$rendu,$year"; } if ($creation) From b297e386d63f107d48de6339075a5ec4926e29c0 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 18 Oct 2013 09:09:31 +0200 Subject: [PATCH 171/364] Add Sys::Gamin to required packages --- commands/first-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/commands/first-install.sh b/commands/first-install.sh index ca42951..2a7e95e 100755 --- a/commands/first-install.sh +++ b/commands/first-install.sh @@ -1,10 +1,10 @@ #! /bin/bash # Install missing packages -DEB_PACKAGES_LIST="screen libnet-ldap-perl libxml-libxml-perl libgearman-client-perl libmailtools-perl libmail-sendmail-perl libdatetime-format-iso8601-perl libnet-ip-perl" -ARCH_PACKAGES_LIST="screen perl-io-socket-ssl perl-email-simple perl-email-mime perl-term-readkey perl-ldap perl-lwp-protocol-https perl-datetime-format-iso8601 perl-net-ip" +DEB_PACKAGES_LIST="screen libnet-ldap-perl libxml-libxml-perl libgearman-client-perl libmailtools-perl libmail-sendmail-perl libdatetime-format-iso8601-perl libnet-ip-perl libsys-gamin-perl" +ARCH_PACKAGES_LIST="screen perl-io-socket-ssl perl-email-simple perl-email-mime perl-term-readkey perl-ldap perl-lwp-protocol-https perl-datetime-format-iso8601 perl-net-ip" # aur/perl-sys-gamin GENTOO_PACKAGES_LIST="app-misc/screen dev-perl/IO-Socket-SSL dev-perl/Email-Simple dev-perl/Email-MIME dev-perl/TermReadKey dev-perl/perl-ldap dev-perl/LWP-Protocol-https dev-perl/DateTime-Format-ISO8601 dev-perl/Net-IP" -FBSD_PACKAGES_LIST="screen p5-IO-Socket-SSL p5-Email-Simple p5-Email-MIME p5-Term-ANSIColor p5-Term-ReadKey p5-LWP-Protocol-https p5-DateTime-Format-ISO8601 p5-Net-IP" +FBSD_PACKAGES_LIST="screen p5-IO-Socket-SSL p5-Email-Simple p5-Email-MIME p5-Term-ANSIColor p5-Term-ReadKey p5-LWP-Protocol-https p5-DateTime-Format-ISO8601 p5-Net-IP p5-Sys-Gamin" KERNEL=`uname -s` From 9fa92515900f10f24682552601d99c0902c49a14 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 18 Oct 2013 09:11:04 +0200 Subject: [PATCH 172/364] hooks/submission: send git to moulette --- hooks/submissions.pl | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/hooks/submissions.pl b/hooks/submissions.pl index 3032555..4fd4693 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -95,6 +95,21 @@ if ($ref =~ m<^refs/tags/(.+)$>) } else { + eval { + Process::Client::launch("send_git", + { + "year" => $promo, + "id" => $id_project, + "rendu" => $tag, + "login" => $repo_login, + "path" => $ENV{GL_REPO_BASE_ABS}."/".$ENV{GL_REPO}, + }); + }; + if ($@) { + my $err = $@; + log DEBUG, "ERROR: ".$err; + } + # Send data to API my $last_commit = `git log $newsha -1 --decorate --tags`; eval { From 9866ecde4595864f67b1252d082ca78fc99a3031 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 18 Oct 2013 09:11:43 +0200 Subject: [PATCH 173/364] moulette_get: Merge receive_tar and receive_git --- process/files/moulette_get.pl | 37 ++++------------------------------- 1 file changed, 4 insertions(+), 33 deletions(-) diff --git a/process/files/moulette_get.pl b/process/files/moulette_get.pl index c03c834..058cb11 100644 --- a/process/files/moulette_get.pl +++ b/process/files/moulette_get.pl @@ -15,10 +15,9 @@ use ACU::Log; use ACU::Process; my %actions = ( - "tar" => \&receive_tar, - "git" => \&receive_git, - + "std" => \&receive_std, #STuDent "ref" => \&receive_ref, + "tests" => \&create_testsuite, "moulette" => \&moulette, ); @@ -90,35 +89,7 @@ sub receive_ref remove_tree($tempdir); } -sub receive_tar -{ - my $args = shift; - my $project_id = $args->{param}{id}; - my $year = $args->{param}{year}; - my $rendu = $args->{param}{rendu}; - my $file = $args->{param}{file}; - my $login = $args->{param}{login} // "ref"; - - croak "No file named '$file' given" if (!exists $args->{files}{$file}); - - my ($fh, $filename) = tempfile(DIR => '/data/tmp', SUFFIX => $file); - binmode($fh); - print $fh $args->{files}{$file}; - close $fh; - chmod 0644, $filename; - - my $destdir = ( prepare_dir($year, $project_id, $rendu) )[0]; - fact_exec("package create $filename $destdir/$login.ff", $destdir); - croak "Cannot create $login.ff" if ($?); - chmod 0666, "$destdir/$login.ff"; - - # Clean - unlink $filename; - - run_moulette($project_id, $year, $rendu, $login); -} - -sub receive_git +sub receive_std { my $args = shift; my $project_id = $args->{param}{id}; @@ -137,7 +108,7 @@ sub receive_git croak "An error occurs while extracting the tarball" if ($?); my $destdir = ( prepare_dir($year, $project_id, $rendu) )[0]; - fact_exec("package create $tempdir $destdir/$login.ff", $destdir); + fact_exec("package create '$tempdir' '$destdir/$login.ff'", $destdir); croak "Cannot create $login.ff" if ($?); chmod 0666, "$destdir/$login.ff"; From 37db6f3256c33001766408bdf7e49d2f4ed50c2d Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 18 Oct 2013 09:12:24 +0200 Subject: [PATCH 174/364] Launch send_git process on hamano --- process/launch.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/process/launch.sh b/process/launch.sh index 91b78da..5e00e1c 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -69,6 +69,7 @@ then hamano) launch_screen "lerdorf_process_ldap_sync_ssh_keys_git" "while true; do $PERL ~/liblerdorf/process/ldap/sync_ssh_keys_git.pl; done" ~intradmin/.ssh/git + launch_screen "lerdorf_process_send_git" "while true; do $PERL ~/liblerdorf/process/files/send_git.pl; done" ;; moore) From 51257dd34b3c7c4b2f5ddb3ccb94d8b38afece94 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 18 Oct 2013 09:13:13 +0200 Subject: [PATCH 175/364] New process to send a trace to Intranet --- commands/project/send_trace.sh | 50 ++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 commands/project/send_trace.sh diff --git a/commands/project/send_trace.sh b/commands/project/send_trace.sh new file mode 100644 index 0000000..08c87be --- /dev/null +++ b/commands/project/send_trace.sh @@ -0,0 +1,50 @@ +#!/bin/sh + +if [ "$#" -ne 3 ] +then + echo "Usage: $0 project rendu [login] file" + exit 1 +fi + +project_id="$1" +rendu="$2" +if [ -z "$4" ] +then + login=`basename $3` + login="${login%%.xml}" + file="$3" +else + login="$3" + file="$4" +fi + +if ! whereis gearman > /dev/null 2> /dev/null +then + echo "gearman isn't installed on this machine. Please try another one." + exit 1 +fi + +if ! [ -f "$file" ]; then + echo "$file: File not found" + exit 2 +fi + +if [ -z "$login" ] +then + FILENAME=$(basename "$file") +else + FILENAME="$login.xml" +fi +FILE="$(base64 $file)" + +cat < + + trace + $project_id + 2016 + $rendu + $login +$FILE + +EOF From a9b720b355f5583d1ed6fdc1f24e303348dbaa94 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 18 Oct 2013 09:22:15 +0200 Subject: [PATCH 176/364] Fix IP displayed in gl-pre-init is now correct --- hooks/gl-pre-git | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git index 2c1e36d..ed9299a 100755 --- a/hooks/gl-pre-git +++ b/hooks/gl-pre-git @@ -13,27 +13,48 @@ my $ip = $1 if ($ENV{'SSH_CLIENT'} =~ m/([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0- exit 0 if (!$ip); -log DEBUG, "Connection to $ENV{GL_REPO} from $ip"; +log DEBUG, "Connection with $ARGV[0] to $ENV{GL_REPO} from $ip"; + +my $promo = qx(git config hooks.promo); +my $id_project = qx(git config hooks.idproject); +my $repo_login = qx(git config hooks.repologin); # First, check if the repository is in the YYYY/ directory -exit 0 if ($ENV{GL_REPO} !~ /^2[0-9]{3}\/.+\/.+/); +exit 0 if (($promo && $id_project && $repo_login) || $ENV{GL_REPO} !~ /^2[0-9]{3}\/.+\/.+/); +my ($ref, $oldsha, $newsha) = @ARGV; + +$promo = $1 if (!$promo && $ENV{'GL_REPO'} =~ m/([0-9]{4}).*/); +$id_project = $1 if (!$id_project && $ENV{'GL_REPO'} =~ m/.*\/(.*)\//); +$repo_login = $1 if (!$repo_login && $ENV{'GL_REPO'} =~ m/.*\/.*\/(.*)/); my $read = ($ARGV[0] =~ /R/); my $write = ($ARGV[0] =~ /W/); -my $promo = $1 if ($ENV{'GL_REPO'} =~ m/([0-9]{4}).*/); -my $id_project = $1 if ($ENV{'GL_REPO'} =~ m/.*\/(.*)\//); -my $repo_login = $1 if ($ENV{'GL_REPO'} =~ m/.*\/.*\/(.*)/); - $ip = Net::IP->new($ip) or die ("IP invalide"); -my $schoolnetwork = Net::IP->new('10.41.0.0/16'); +my $labnetwork = Net::IP->new('192.168.0.0/16'); -if ($ip->overlaps($schoolnetwork) != $IP_A_IN_B_OVERLAP) +if ($ip->overlaps($labnetwork) == $IP_A_IN_B_OVERLAP) { - say "Votre IP est : $ip."; + exit 0; +} +#else +#{ +# log ERROR, "Les dépôts Git sont en cours de maintenance, veuillez réessayer dans quelques minutes."; +# exit 1; +#} + +my $schoolnetwork = Net::IP->new('10.41.0.0/16'); +#my $vjschoolnetwork = Net::IP->new('10.3.0.0/16'); + +if ( + $ip->overlaps($schoolnetwork) != $IP_A_IN_B_OVERLAP +# && $ip->overlaps($vjschoolnetwork) != $IP_A_IN_B_OVERLAP + ) +{ + say "Votre IP est : ".$ip->print(); log ERROR, "Vous n'êtes pas autorisé à envoyer vos modifications depuis cette IP." if ($write); log ERROR, "Vous n'êtes pas autorisé à accéder à ce dépôt depuis cette IP." if ($read); @@ -44,7 +65,7 @@ my $sshnetwork = Net::IP->new('10.41.253.0/24'); if ($ip->overlaps($sshnetwork) == $IP_A_IN_B_OVERLAP) { - say "Votre IP est : $ip."; + say "Votre IP est : ".$ip->print(); log ERROR, "Vous n'êtes pas autorisé à envoyer vos modifications depuis cette IP." if ($write); log ERROR, "Vous n'êtes pas autorisé à accéder à ce dépôt depuis cette IP." if ($read); From 63c2543fc116cf76d60e6413f553a431a695ea46 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 18 Oct 2013 09:24:49 +0200 Subject: [PATCH 177/364] Fix IP displayed in gl-pre-init is now correct --- hooks/gl-pre-git | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git index ed9299a..8062ee2 100755 --- a/hooks/gl-pre-git +++ b/hooks/gl-pre-git @@ -54,7 +54,7 @@ if ( # && $ip->overlaps($vjschoolnetwork) != $IP_A_IN_B_OVERLAP ) { - say "Votre IP est : ".$ip->print(); + say "Votre IP est : ".$ip->ip(); log ERROR, "Vous n'êtes pas autorisé à envoyer vos modifications depuis cette IP." if ($write); log ERROR, "Vous n'êtes pas autorisé à accéder à ce dépôt depuis cette IP." if ($read); @@ -65,7 +65,7 @@ my $sshnetwork = Net::IP->new('10.41.253.0/24'); if ($ip->overlaps($sshnetwork) == $IP_A_IN_B_OVERLAP) { - say "Votre IP est : ".$ip->print(); + say "Votre IP est : ".$ip->ip(); log ERROR, "Vous n'êtes pas autorisé à envoyer vos modifications depuis cette IP." if ($write); log ERROR, "Vous n'êtes pas autorisé à accéder à ce dépôt depuis cette IP." if ($read); From cea68aa7a7891060b29b533fb2ca3865e20d4695 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 18 Oct 2013 18:15:11 +0200 Subject: [PATCH 178/364] gen_grading: checck if there is a defense or trace before generate --- process/projects/gen_grading.pl | 104 +++++++++++++++++--------------- 1 file changed, 55 insertions(+), 49 deletions(-) diff --git a/process/projects/gen_grading.pl b/process/projects/gen_grading.pl index 6c04c57..877bb8d 100644 --- a/process/projects/gen_grading.pl +++ b/process/projects/gen_grading.pl @@ -35,62 +35,68 @@ sub process my $grade = Grading->new(); - my @defenses; - # Create defenses groups - opendir(my $dh, "$basedir/$year/$project_id/defenses/") or croak "can't opendir $basedir/$year/$project_id/defenses/: $!"; - for my $sout (grep { ( ! /^\./ ) && -f "$basedir/$year/$project_id/defenses/$_" } readdir($dh)) - { - my $sid; - ($sid = $sout) =~ s/\.xml$//; - push @defenses, $sid; - - open my $xml, "<", "$basedir/$year/$project_id/defenses/$sout" or die $!; - binmode $xml; - - my $str; - $str .= $_ while (<$xml>); - - my $defense = Defense->new($str); - - my $ids = $defense->getIds(); - - my @keys = keys %$ids; - my $def_i = $keys[0]; - $def_i =~ s/^(.+)g.*$/$1/; - - $ids->{$def_i.'_end_$LOGIN'} = undef; - $ids->{$def_i.'_end_group'} = undef; - - $grade->create_from_ids($sid, $ids); - } - closedir $dh; - - # Create traces groups - opendir($dh, "$basedir/$year/$project_id/traces/") or croak "can't opendir $basedir/$year/$project_id/traces/: $!"; - for my $dir (grep { ( ! /^\./ ) && -d "$basedir/$year/$project_id/traces/$_" } readdir($dh)) + if (-d "$basedir/$year/$project_id/defenses/") { - next if (grep { $dir eq "defense_$_" } @defenses); + my @defenses; + # Create defenses groups + opendir(my $dh, "$basedir/$year/$project_id/defenses/") or croak "can't opendir $basedir/$year/$project_id/defenses/: $!"; + for my $sout (grep { ( ! /^\./ ) && -f "$basedir/$year/$project_id/defenses/$_" } readdir($dh)) + { + my $sid; + ($sid = $sout) =~ s/\.xml$//; + push @defenses, $sid; - my $ids = {}; - - opendir(my $dhm, "$basedir/$year/$project_id/traces/$dir") or croak "can't opendir $basedir/$year/$project_id/traces/$dir: $!"; - for my $login (grep { ( ! /^\./ ) && -f "$basedir/$year/$project_id/traces/$dir/$_" } readdir($dhm)) - { - open my $xml, "<", "$basedir/$year/$project_id/traces/$dir/$login" or die $!; + open my $xml, "<", "$basedir/$year/$project_id/defenses/$sout" or die $!; binmode $xml; - my $trace = Trace->new($xml); + my $str; + $str .= $_ while (<$xml>); - my %tids = %{ $trace->getIds() }; - for my $kid (keys %tids) - { - $ids->{ $kid } = $tids{ $kid }; - } + my $defense = Defense->new($str); + + my $ids = $defense->getIds(); + + my @keys = keys %$ids; + my $def_i = $keys[0]; + $def_i =~ s/^(.+)g.*$/$1/; + + $ids->{$def_i.'_end_$LOGIN'} = undef; + $ids->{$def_i.'_end_group'} = undef; + + $grade->create_from_ids($sid, $ids); } - - $grade->create_from_ids($dir, $ids); + closedir $dh; + } + + if (-d "$basedir/$year/$project_id/traces/") + { + # Create traces groups + opendir($dh, "$basedir/$year/$project_id/traces/") or croak "can't opendir $basedir/$year/$project_id/traces/: $!"; + for my $dir (grep { ( ! /^\./ ) && -d "$basedir/$year/$project_id/traces/$_" } readdir($dh)) + { + next if (grep { $dir eq "defense_$_" } @defenses); + + my $ids = {}; + + opendir(my $dhm, "$basedir/$year/$project_id/traces/$dir") or croak "can't opendir $basedir/$year/$project_id/traces/$dir: $!"; + for my $login (grep { ( ! /^\./ ) && -f "$basedir/$year/$project_id/traces/$dir/$_" } readdir($dhm)) + { + open my $xml, "<", "$basedir/$year/$project_id/traces/$dir/$login" or die $!; + binmode $xml; + + my $trace = Trace->new($xml); + + my %tids = %{ $trace->getIds() }; + for my $kid (keys %tids) + { + $ids->{ $kid } = $tids{ $kid }; + } + } + + $grade->create_from_ids($dir, $ids); + } + closedir $dh; } - closedir $dh; return $grade->toString; } From 791dfe65f6d548ecea892214d2c46f0f773839b8 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 18 Oct 2013 18:21:44 +0200 Subject: [PATCH 179/364] gen_grading: fix compilation errors --- process/projects/gen_grading.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/process/projects/gen_grading.pl b/process/projects/gen_grading.pl index 877bb8d..ba4327a 100644 --- a/process/projects/gen_grading.pl +++ b/process/projects/gen_grading.pl @@ -35,9 +35,9 @@ sub process my $grade = Grading->new(); + my @defenses; if (-d "$basedir/$year/$project_id/defenses/") { - my @defenses; # Create defenses groups opendir(my $dh, "$basedir/$year/$project_id/defenses/") or croak "can't opendir $basedir/$year/$project_id/defenses/: $!"; for my $sout (grep { ( ! /^\./ ) && -f "$basedir/$year/$project_id/defenses/$_" } readdir($dh)) @@ -71,7 +71,7 @@ sub process if (-d "$basedir/$year/$project_id/traces/") { # Create traces groups - opendir($dh, "$basedir/$year/$project_id/traces/") or croak "can't opendir $basedir/$year/$project_id/traces/: $!"; + opendir(my $dh, "$basedir/$year/$project_id/traces/") or croak "can't opendir $basedir/$year/$project_id/traces/: $!"; for my $dir (grep { ( ! /^\./ ) && -d "$basedir/$year/$project_id/traces/$_" } readdir($dh)) { next if (grep { $dir eq "defense_$_" } @defenses); From 4c55167314bfb1fb27b67c3ed3a0c4937cc82270 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 18 Oct 2013 18:33:34 +0200 Subject: [PATCH 180/364] hooks/subjects: Fix concatenation error --- hooks/subjects.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index 34411d0..f02c04e 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -596,7 +596,7 @@ sub tag_tests $project_id = lc $project_id; $project_id =~ s/[^a-z0-9-_]/_/g; - my $rendu = $_[2]; + my $rendu = $_[2] // ""; my $year; if ($_[3]) From caa5ff9243968f0742b0a07f123e94ca16a8c2a7 Mon Sep 17 00:00:00 2001 From: Kevin Houdebert Date: Sat, 19 Oct 2013 17:52:39 +0200 Subject: [PATCH 181/364] Fix brackets in \command latex --- migration/repo.sh | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/migration/repo.sh b/migration/repo.sh index ab66770..c43c28e 100755 --- a/migration/repo.sh +++ b/migration/repo.sh @@ -19,7 +19,7 @@ tex2md() do bi=`basename "$i"` echo -e "\e[1;34m>>>\e[1;37m Trying to convert $i to Markdown...\e[0m" - + sed -Ei 's/\\includegraphics *\{([^}]+)}/\\verb+%%image(\1)+/gi' "$i" sed -Ei 's/\\include *\{([^}]+)}/\\verb+%%scoped-include(\1)+/gi' "$i" sed -Ei 's/\\input *\{([^}]+)}/\\verb+%%scoped-include(\1)+/gi' "$i" @@ -38,11 +38,21 @@ tex2md() sed -Ei 's/\\end *\{cartouche_nospaces\}/\\end\{verbatim\}/g' "$i" sed -Ei 's/\\verb ([^+]+) /\\verb+\1+/g' "$i" + # BEGIN HACK! Need stacking + sed -Ei 's/\\distribution\{\}/FreeBSD 9/gi' "$i" + sed -Ei 's/\\\{/__OPEN_BRACKET_MINIROOT__/gi' "$i" + sed -Ei 's/\\\}/__CLOSE_BRACKET_MINIROOT__/gi' "$i" + # Special macros - sed -Ei 's/\\(file|email|command) *\{([^{]*\{[^}]*\})*([^}]*)}/\\verb+\2\3+/gi' "$i" + sed -Ei 's/-\{\}-//gi' "$i" + sed -Ei 's/\\(file|email|command) *\{([^}]*)\}/\\verb+\2+/gi' "$i" sed -Ei 's/\\begin *\{assistant\}/\\verb+%%assistant-begin+/g' "$i" sed -Ei 's/\\end *\{assistant\}/\\verb+%%assistant-end+/g' "$i" + # END HACK! + sed -Ei 's/__OPEN_BRACKET_MINIROOT__/\{/gi' "$i" + sed -Ei 's/__CLOSE_BRACKET_MINIROOT__/\}/gi' "$i" + # Convert Beamer sed -Ei 's/\\begin\[[^]]+\]\{frame\}\{([^}]+)\}/\\subsection\{\1\}/g' "$i" sed -Ei 's/\\begin\{frame\}\{([^}]+)\}\[[^]]+\]/\\subsection\{\1\}/g' "$i" From 73b1552199ae89e0a11f593f436d4dadb7197f31 Mon Sep 17 00:00:00 2001 From: Kevin Houdebert Date: Sat, 19 Oct 2013 19:29:29 +0200 Subject: [PATCH 182/364] Update repo.sh script --- migration/repo.sh | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/migration/repo.sh b/migration/repo.sh index c43c28e..4f97bbc 100755 --- a/migration/repo.sh +++ b/migration/repo.sh @@ -20,6 +20,15 @@ tex2md() bi=`basename "$i"` echo -e "\e[1;34m>>>\e[1;37m Trying to convert $i to Markdown...\e[0m" + # BEGIN HACK! Need stacking + sed -Ei 's/\\distribution\{\}/FreeBSD 9/gi' "$i" + sed -Ei 's/\\\{/__OPEN_BRACKET_MINIROOT__/gi' "$i" + sed -Ei 's/\\\}/__CLOSE_BRACKET_MINIROOT__/gi' "$i" + sed -Ei 's/-\{\}-//gi' "$i" + sed -Ei 's/\\_/_/gi' "$i" + + # DIRTY HACK + sed -Ei 's/\\includegraphics *\{([^}]+)}/\\verb+%%image(\1)+/gi' "$i" sed -Ei 's/\\include *\{([^}]+)}/\\verb+%%scoped-include(\1)+/gi' "$i" sed -Ei 's/\\input *\{([^}]+)}/\\verb+%%scoped-include(\1)+/gi' "$i" @@ -38,21 +47,11 @@ tex2md() sed -Ei 's/\\end *\{cartouche_nospaces\}/\\end\{verbatim\}/g' "$i" sed -Ei 's/\\verb ([^+]+) /\\verb+\1+/g' "$i" - # BEGIN HACK! Need stacking - sed -Ei 's/\\distribution\{\}/FreeBSD 9/gi' "$i" - sed -Ei 's/\\\{/__OPEN_BRACKET_MINIROOT__/gi' "$i" - sed -Ei 's/\\\}/__CLOSE_BRACKET_MINIROOT__/gi' "$i" - # Special macros - sed -Ei 's/-\{\}-//gi' "$i" - sed -Ei 's/\\(file|email|command) *\{([^}]*)\}/\\verb+\2+/gi' "$i" + sed -Ei 's/\\(file|email|command|code|bcode) *\{([^}]*)\}/\\verb+\2+/gi' "$i" sed -Ei 's/\\begin *\{assistant\}/\\verb+%%assistant-begin+/g' "$i" sed -Ei 's/\\end *\{assistant\}/\\verb+%%assistant-end+/g' "$i" - # END HACK! - sed -Ei 's/__OPEN_BRACKET_MINIROOT__/\{/gi' "$i" - sed -Ei 's/__CLOSE_BRACKET_MINIROOT__/\}/gi' "$i" - # Convert Beamer sed -Ei 's/\\begin\[[^]]+\]\{frame\}\{([^}]+)\}/\\subsection\{\1\}/g' "$i" sed -Ei 's/\\begin\{frame\}\{([^}]+)\}\[[^]]+\]/\\subsection\{\1\}/g' "$i" @@ -69,6 +68,10 @@ tex2md() sed -Ei 's/\\frame//g' "$i" sed -Ei 's/\\item( *)<[^>]+>/\\item\1/g' "$i" + # END HACK! + sed -Ei 's/__OPEN_BRACKET_MINIROOT__/\{/gi' "$i" + sed -Ei 's/__CLOSE_BRACKET_MINIROOT__/\}/gi' "$i" + if pandoc -o "$DEST"/${bi%%.tex}.md $i then git add "$DEST"/${bi%%.tex}.md From ff9c3a5ad22b8f05825ba35543094bcdb3ad2183 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 20 Oct 2013 02:15:12 +0200 Subject: [PATCH 183/364] Introduce Habitent loin people --- ACU/Tinyglob.pm | 8 +++++++- ACU/t/tinyglob.t | 3 +++ hooks/gl-pre-git | 4 ++++ process/files/moulette_get.pl | 2 +- process/ldap/update_group.pl | 2 -- 5 files changed, 15 insertions(+), 4 deletions(-) diff --git a/ACU/Tinyglob.pm b/ACU/Tinyglob.pm index 6fc9ed8..8db5379 100644 --- a/ACU/Tinyglob.pm +++ b/ACU/Tinyglob.pm @@ -38,8 +38,12 @@ sub tinyglob elsif ($str[$i] eq '*') { $res .= '.*'; } + elsif ($metaescape) { + $res .= $str[$i]; + $metaescape = 0; + } else { - croak "Invalid number of \\ in '$orig'"; + $res .= "\\".$str[$i]; } } else { @@ -55,6 +59,8 @@ sub match my $glob = tinyglob(shift); my $str = shift; + say $glob; + return $str =~ /$glob/; } diff --git a/ACU/t/tinyglob.t b/ACU/t/tinyglob.t index b3d27cb..35f6f7b 100644 --- a/ACU/t/tinyglob.t +++ b/ACU/t/tinyglob.t @@ -18,6 +18,9 @@ is(Tinyglob::tinyglob("\\*"), "\\*"); is(Tinyglob::tinyglob("\\\\*"), "\\\\.*"); is(Tinyglob::tinyglob("\\?"), "\\?"); is(Tinyglob::tinyglob("\\\\?"), "\\\\."); +is(Tinyglob::tinyglob("\\."), "\\."); +is(Tinyglob::tinyglob("\\\\."), "\\\\\\."); +is(Tinyglob::tinyglob("a*b?"), "a.*b."); ok(! Tinyglob::match("?", "")); ok(! Tinyglob::match("b", "a")); diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git index 8062ee2..46d80a9 100755 --- a/hooks/gl-pre-git +++ b/hooks/gl-pre-git @@ -19,6 +19,8 @@ my $promo = qx(git config hooks.promo); my $id_project = qx(git config hooks.idproject); my $repo_login = qx(git config hooks.repologin); +my @habitent_loin = ("amed_m", "bellev_m", "freima_m", "ikouna_l"); + # First, check if the repository is in the YYYY/ directory exit 0 if (($promo && $id_project && $repo_login) || $ENV{GL_REPO} !~ /^2[0-9]{3}\/.+\/.+/); @@ -46,6 +48,8 @@ if ($ip->overlaps($labnetwork) == $IP_A_IN_B_OVERLAP) # exit 1; #} +return 0 if (grep { /\Q$repo_login\E/ } @habitent_loin); + my $schoolnetwork = Net::IP->new('10.41.0.0/16'); #my $vjschoolnetwork = Net::IP->new('10.3.0.0/16'); diff --git a/process/files/moulette_get.pl b/process/files/moulette_get.pl index 058cb11..e88a4dc 100644 --- a/process/files/moulette_get.pl +++ b/process/files/moulette_get.pl @@ -168,7 +168,7 @@ sub run_moulette opendir(my $dh, $submitdir) or die "Can't list files in $submitdir: $!"; while (readdir($dh)) { - if (/([a-zA-Z0-9_-]+).ff$/ && -f "$submitdir/$_") { + if (/([a-zA-Z0-9_-]+).ff$/ && -f "$submitdir/$_" && ! /^tests\.ff$/) { push @logins, $1; } } diff --git a/process/ldap/update_group.pl b/process/ldap/update_group.pl index efc6b84..043522b 100644 --- a/process/ldap/update_group.pl +++ b/process/ldap/update_group.pl @@ -7,8 +7,6 @@ use File::Basename; use Mail::Internet; use Pod::Usage; -use lib "../../"; - use ACU::Log; use ACU::LDAP; use ACU::Process; From ef85ae270867bad7a48fa87bf3f50792f549e279 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 20 Oct 2013 09:47:13 +0200 Subject: [PATCH 184/364] Fix gl-pre-git --- hooks/gl-pre-git | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git index 46d80a9..cf194c8 100755 --- a/hooks/gl-pre-git +++ b/hooks/gl-pre-git @@ -48,7 +48,7 @@ if ($ip->overlaps($labnetwork) == $IP_A_IN_B_OVERLAP) # exit 1; #} -return 0 if (grep { /\Q$repo_login\E/ } @habitent_loin); +exit 0 if (grep { /\Q$repo_login\E/ } @habitent_loin); my $schoolnetwork = Net::IP->new('10.41.0.0/16'); #my $vjschoolnetwork = Net::IP->new('10.3.0.0/16'); From 8e3d6e5464cd36b4d47eb0948399078669dc11b9 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 21 Oct 2013 00:40:41 +0200 Subject: [PATCH 185/364] Pass the flavour to the Intranet when creating project --- ACU/API/Projects.pm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ACU/API/Projects.pm b/ACU/API/Projects.pm index 1395ff1..c5bcb9c 100644 --- a/ACU/API/Projects.pm +++ b/ACU/API/Projects.pm @@ -10,9 +10,10 @@ use Carp; use ACU::API::Base; use ACU::LDAP; -sub add($;$) +sub add($$;$) { my $project_name = shift; + my $falvour = shift; my $year = shift; if ($year and $year != LDAP::get_year) { @@ -21,7 +22,10 @@ sub add($;$) my $res = API::Base::send('ResultHandler', "projects/projects/add.xml", - [ project_name => $project_name ]); + [ + project_name => $project_name, + flavour => $flavour, + ]); if ($res->{result} ne '0') { croak "Erreur durant l'ajout : ".$res->{message}; From 279b9ea07ecd8efd12596cb133c0bb93c9ae55d7 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 21 Oct 2013 18:44:30 +0200 Subject: [PATCH 186/364] Typo in API/Projects.pm --- ACU/API/Projects.pm | 4 ++-- process/files/moulette_get.pl | 8 ++------ process/projects/gen_grading.pl | 6 +----- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/ACU/API/Projects.pm b/ACU/API/Projects.pm index c5bcb9c..02f61fa 100644 --- a/ACU/API/Projects.pm +++ b/ACU/API/Projects.pm @@ -13,7 +13,7 @@ use ACU::LDAP; sub add($$;$) { my $project_name = shift; - my $falvour = shift; + my $flavor = shift; my $year = shift; if ($year and $year != LDAP::get_year) { @@ -24,7 +24,7 @@ sub add($$;$) "projects/projects/add.xml", [ project_name => $project_name, - flavour => $flavour, + flavor => $flavor, ]); if ($res->{result} ne '0') { diff --git a/process/files/moulette_get.pl b/process/files/moulette_get.pl index e88a4dc..19903fa 100644 --- a/process/files/moulette_get.pl +++ b/process/files/moulette_get.pl @@ -3,7 +3,7 @@ use v5.10.1; use strict; use warnings; -#use threads; +use threads; use Carp; use File::Basename; use File::Copy; @@ -317,9 +317,5 @@ sub process_get return "Ok"; } -#threads->create('monitor_start'); +threads->create('monitor_start'); Process::register("moulette_get", \&process_get); - -#$project_paths{'/data/output/2016-exam-c-0-rendu-1'} = { "id" => "exam-c-0", "year" => "2016", "rendu" => "rendu-1" }; -#$fm->monitor('/data/output/2016-exam-c-0-rendu-1'); -#monitor_start(); diff --git a/process/projects/gen_grading.pl b/process/projects/gen_grading.pl index ba4327a..b365932 100644 --- a/process/projects/gen_grading.pl +++ b/process/projects/gen_grading.pl @@ -27,11 +27,7 @@ sub process my $year = shift @args // LDAP::get_year; # Project existing? - if (! -d "$basedir/$year/$project_id") - { - log ERROR, "Unable to find $project_id in $year"; - return "Unable to find $project_id in $year\n"; - } + croak "Unable to find $project_id in $year" if (! -d "$basedir/$year/$project_id"); my $grade = Grading->new(); From 9add1cf2f5fc3268b122682055932b2c0fa02a18 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 21 Oct 2013 23:45:05 +0200 Subject: [PATCH 187/364] Find test.ft in $submitdir --- process/files/moulette_get.pl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/process/files/moulette_get.pl b/process/files/moulette_get.pl index 19903fa..c4e7133 100644 --- a/process/files/moulette_get.pl +++ b/process/files/moulette_get.pl @@ -183,6 +183,10 @@ sub run_moulette } elsif (-f "$testdir/test.ft") { open $fhin, "<", "$testdir/test.ft" or croak "Unable to open $testdir/test.ft: $!"; } + #TODO: remove this + elsif (-f "$submit/test.ft") { + open $fhin, "<", "$testdir/test.ft" or croak "Unable to open $testdir/test.ft: $!"; + } if ($fhin) { From ddd63ece67470327408c7a122b5d6a550e4783e5 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 23 Oct 2013 06:54:14 +0200 Subject: [PATCH 188/364] New Habitent loin --- hooks/gl-pre-git | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git index cf194c8..1b616ee 100755 --- a/hooks/gl-pre-git +++ b/hooks/gl-pre-git @@ -19,7 +19,7 @@ my $promo = qx(git config hooks.promo); my $id_project = qx(git config hooks.idproject); my $repo_login = qx(git config hooks.repologin); -my @habitent_loin = ("amed_m", "bellev_m", "freima_m", "ikouna_l"); +my @habitent_loin = ("amed_m", "bellev_m", "faure_n", "freima_m", "ikouna_l", "simon_j"); # First, check if the repository is in the YYYY/ directory exit 0 if (($promo && $id_project && $repo_login) || $ENV{GL_REPO} !~ /^2[0-9]{3}\/.+\/.+/); From b5806fac12480f002e7f193f5f6f7734dd26f645 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 23 Oct 2013 06:57:13 +0200 Subject: [PATCH 189/364] Add hook for conferences repository --- Makefile | 1 + hooks/conferences.pl | 49 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 hooks/conferences.pl diff --git a/Makefile b/Makefile index 1d62a40..12886aa 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,7 @@ install: ! test -d $(GITOLITE_DEST) || $(MAKEDIR) -p $(GITOLITE_DEST)/update.secondary.d ! test -d $(GITOLITE_DEST) || $(COPY) hooks/gl-pre-git $(GITOLITE_DEST)/ ! test -d $(GITOLITE_DEST) || $(COPY) hooks/subjects.pl $(GITOLITE_DEST)/update.secondary.d/ + ! test -d $(GITOLITE_DEST) || $(COPY) hooks/conferences.pl $(GITOLITE_DEST)/update.secondary.d/ ! test -d $(GITOLITE_DEST) || $(COPY) hooks/submissions.pl $(GITOLITE_DEST)/update.secondary.d/ update: diff --git a/hooks/conferences.pl b/hooks/conferences.pl new file mode 100644 index 0000000..755d021 --- /dev/null +++ b/hooks/conferences.pl @@ -0,0 +1,49 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use v5.10; +use Digest::SHA qw(sha1_base64); +use File::Basename; +use utf8; + +use ACU::API::Projects; +use ACU::Defense; +use ACU::LDAP; +use ACU::Log; +$ACU::Log::log_file = "/var/log/hooks/" . basename($0) . ".log"; +use ACU::Process; + +# First, check if the repository is in the conferences/ directory +exit 0 if ($ENV{GL_REPO} !~ /^conferences\//); + +my ($ref, $oldsha, $newsha) = @ARGV; + +log DONE, "This is a conference repository!"; + +my %known_tags = ( + "subject" => \&tag_document, +); + +if ($ref =~ m<^refs/tags(/.+)$>) +{ + my $tag = $1; + my @args; + + while ($tag =~ m<[,/]([^,]*)>g) { + push @args, $1; + } + + my $create = ($newsha ne '0' x 40); + + if (exists $known_tags{$args[0]}) { + exit $known_tags{$args[0]}($create, @args); + } +} + +exit 0; + +sub tag_document +{ + +} From 37c02fedb26bdb259910ec1ebc88109276a066dc Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 25 Oct 2013 00:18:15 +0200 Subject: [PATCH 190/364] Fix LDAP attribute suppression --- ACU/LDAP.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ACU/LDAP.pm b/ACU/LDAP.pm index 0bc0131..900e4c7 100644 --- a/ACU/LDAP.pm +++ b/ACU/LDAP.pm @@ -261,7 +261,7 @@ sub delete_attribute($$$@) { log(DEBUG, "Remove attribute $what ($value) from $dn"); - @data = grep { ! $value eq $_ } @data; + @data = grep { $value ne $_ } @data; $mod = 1; } else { From 2d7c59694a261c7b7bf4836711ad3f890954e642 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 26 Oct 2013 17:46:46 +0200 Subject: [PATCH 191/364] Manual things --- hooks/gl-pre-git | 2 +- hooks/submissions.pl | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git index 1b616ee..5f6fd16 100755 --- a/hooks/gl-pre-git +++ b/hooks/gl-pre-git @@ -19,7 +19,7 @@ my $promo = qx(git config hooks.promo); my $id_project = qx(git config hooks.idproject); my $repo_login = qx(git config hooks.repologin); -my @habitent_loin = ("amed_m", "bellev_m", "faure_n", "freima_m", "ikouna_l", "simon_j"); +my @habitent_loin = ("abdeln_a", "amed_m", "bellev_m", "faure_n", "freima_m", "ikouna_l", "simon_j"); # First, check if the repository is in the YYYY/ directory exit 0 if (($promo && $id_project && $repo_login) || $ENV{GL_REPO} !~ /^2[0-9]{3}\/.+\/.+/); diff --git a/hooks/submissions.pl b/hooks/submissions.pl index 4fd4693..1a71310 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -64,6 +64,7 @@ if ($ref =~ m<^refs/tags/(.+)$>) my $close = DateTime::Format::ISO8601->parse_datetime($rendu->{period}{end}); # TODO: check exceptions by login/group + $open = DateTime::Format::ISO8601->parse_datetime("2013-10-16T16:00:00") if ($repo_login eq "ikouna_l"); say "Date courante : ", $glts->strftime("%d/%m/%Y %H:%M:%S"); From 5857719f9404651e4735e13d0a4bd11402479c7b Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 28 Oct 2013 15:11:04 +0100 Subject: [PATCH 192/364] LDAP: Fix for stabilization --- ACU/LDAP.pm | 63 ++++++++++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/ACU/LDAP.pm b/ACU/LDAP.pm index 900e4c7..5e7e229 100644 --- a/ACU/LDAP.pm +++ b/ACU/LDAP.pm @@ -8,16 +8,22 @@ use warnings; use Carp; use Net::LDAPS; +use Net::LDAP::Filter; use Net::LDAP::Util qw(ldap_error_text); use ACU::Password; use ACU::Right; use ACU::Log; +use constant { + BASE_DN => "dc=acu,dc=epita,dc=fr", + YEAR_DN => "cn=year,dc=acu,dc=epita,dc=fr", +}; + ## Connection functions our $ldaphost = "ldap.acu.epita.fr"; -our $binddn = "cn=intra,dc=acu,dc=epita,dc=fr"; +our $binddn = "cn=intra," . BASE_DN; my $bindsecret = ""; sub ldap_get_password @@ -42,10 +48,7 @@ sub ldap_connect() log(DEBUG, "Connect to LDAP with $binddn"); - if ($mesg->code) { - log(ERROR, "An error occurred: " .ldap_error_text($mesg->code)); - croak "An error occurred: " .ldap_error_text($mesg->code); - } + croak ldap_error_text($mesg->code) if ($mesg->code); return $ldap; } @@ -57,10 +60,7 @@ sub ldap_connect_anon() log(DEBUG, "Connect to LDAP anonymously"); - if ($mesg->code) { - log(ERROR, "An error occurred: " .ldap_error_text($mesg->code)); - croak "An error occurred: " .ldap_error_text($mesg->code); - } + croak ldap_error_text($mesg->code) if ($mesg->code); return $ldap; } @@ -75,7 +75,7 @@ sub add_group($$$;$) my $year = shift // get_year(); my $ou = shift // "intra"; # expected roles or intra - my $dn = "cn=$cn,ou=$year,ou=$ou,ou=groups,dc=acu,dc=epita,dc=fr"; + my $dn = "cn=$cn,ou=$year,ou=$ou,ou=groups," . BASE_DN; log(DEBUG, "Add group $dn"); @@ -94,7 +94,7 @@ sub get_year(;$) { my $ldap = shift // ldap_connect_anon(); - return get_attribute($ldap, "cn=year,dc=acu,dc=epita,dc=fr", "year"); + return get_attribute($ldap, YEAR_DN, "year"); } sub get_rights($) @@ -105,8 +105,8 @@ sub get_rights($) my $ldap = ldap_connect_anon(); my $mesg = $ldap->search( # search - base => "ou=roles,ou=groups,dc=acu,dc=epita,dc=fr", - filter => "&(memberUid=$login)(objectClass=intraGroup)", + base => "ou=roles,ou=groups," . BASE_DN, + filter => Net::LDAP::Filter->new("&(memberUid=$login)(objectClass=intraGroup)"), attrs => [ 'intraRight' ], scope => "sub" ); @@ -127,8 +127,8 @@ sub get_rights($) $mesg = $ldap->search( # search - base => "ou=intra,ou=groups,dc=acu,dc=epita,dc=fr", - filter => "&(memberUid=$login)(objectClass=intraGroup)", + base => "ou=intra,ou=groups," . BASE_DN, + filter => Net::LDAP::Filter->new("&(memberUid=$login)(objectClass=intraGroup)"), attrs => [ 'intraRight' ], scope => "sub" ); @@ -144,8 +144,8 @@ sub get_rights($) $mesg = $ldap->search( # search - base => "ou=users,dc=acu,dc=epita,dc=fr", - filter => "&(uid=$login)(objectClass=intraAccount)", + base => "ou=users," . BASE_DN, + filter => Net::LDAP::Filter->new("&(uid=$login)(objectClass=intraAccount)"), attrs => [ 'intraRight' ], scope => "sub" ); @@ -191,7 +191,7 @@ sub get_dn($$@) my $mesg = $ldap->search( # search base => "$dn", - filter => "(objectClass=*)", + filter => Net::LDAP::Filter->new("(objectClass=*)"), attrs => \@_, scope => "sub" ); @@ -321,18 +321,19 @@ sub search_dn($$@) my $base = shift; my $filter = shift; - if ($base) { - $base .= "," - } + $base .= "," if ($base); + + log (DEBUG, "Looking for $filter in $base" . BASE_DN); my $mesg = $ldap->search( # search - base => $base."dc=acu,dc=epita,dc=fr", - filter => $filter, + base => $base . BASE_DN, + filter => Net::LDAP::Filter->new($filter), attrs => [ ], scope => "sub" ); - if ($mesg->code != 0) { log(WARN, $mesg->error); return undef; } - if ($mesg->count != 1) { log(WARN, "$filter not found or multiple entries match"); return undef; } + croak($mesg->error) if ($mesg->code != 0); + croak("$filter not found") if ($mesg->count == 0); + croak("$filter not unique") if ($mesg->count > 1); return $mesg->entry(0)->dn; } @@ -343,17 +344,15 @@ sub search_dns($$$@) my $base = shift; my $filter = shift; - if ($base) { - $base .= "," - } + $base .= "," if ($base); my $mesg = $ldap->search( # search - base => $base."dc=acu,dc=epita,dc=fr", - filter => $filter, - attrs => @_, + base => $base . BASE_DN, + filter => Net::LDAP::Filter->new($filter), + attrs => \@_, scope => "sub" ); - if ($mesg->code != 0) { log(WARN, $mesg->error); return undef; } + if ($mesg->code != 0) { log(WARN, $mesg->error); return []; } return $mesg->entries; } From e5a23dc3e8821bc395c1737ade847c7aacec7c9e Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 30 Oct 2013 02:34:11 +0100 Subject: [PATCH 193/364] LPT v2 finalized --- utils/lpt | 1563 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 896 insertions(+), 667 deletions(-) diff --git a/utils/lpt b/utils/lpt index 5fc2f31..70c9d11 100755 --- a/utils/lpt +++ b/utils/lpt @@ -4,7 +4,9 @@ use v5.10.1; use strict; use warnings; -use Digest::SHA1; +use Digest::SHA; +use Email::MIME; +use File::Find; use IPC::Cmd qw[run]; use MIME::Base64; use Net::LDAPS; @@ -15,7 +17,6 @@ use Term::ReadKey; #use Cwd 'abs_path'; #use File::Basename; -#use File::Find; # Avoid installation of liblerdorf on workstations use lib "/sgoinfre/root/new_intra/"; @@ -29,9 +30,12 @@ use ACU::Log; # # ########################################################### +my $noconfirm = 0; + my $wksHomePrefix = "/home/"; my $nfsHomePrefix = "/srv/nfs/accounts/"; +my $shellFalse = "/bin/false"; my $shellValid = "/bin/zsh"; my $colorize = defined($ENV{'ENABLE_COLOR'}); @@ -55,6 +59,12 @@ my %cmds = "group" => \&cmd_group, "help" => \&cmd_help, "list" => \&cmd_list, + "role" => \&cmd_role, + "ssh-keys" => \&cmd_ssh_keys, + "strong-auth" => \&cmd_strong_auth, + "sync-quota" => \&cmd_sync_quota, + "system-group"=> \&cmd_systemgrp, + "year" => \&cmd_year, ); my %cmds_account = @@ -98,6 +108,27 @@ my %cmds_list = "roles" => \&cmd_list_roles, ); +my %cmds_strong_auth = +( + "view" => \&cmd_no_strong_auth_view, + "warn" => \&cmd_no_strong_auth_warn, + "close" => \&cmd_no_strong_auth_close, +); + +my %cmds_ssh_keys = +( + "view" => \&cmd_ssh_keys_without_passphrase_view, + "warn" => \&cmd_ssh_keys_without_passphrase_warn, + "remove" => \&cmd_ssh_keys_without_passphrase_remove, +); + +my %group_types = +( + "intra" => "ou=intra,ou=groups", + "roles" => "ou=roles,ou=groups", + "system" => "ou=system,ou=groups", +); + ###################################### # # @@ -144,17 +175,14 @@ sub cmd_account(@) my $login = shift; if (! $login) { - log(USAGE, "lpt account [arguments ...]"); - return 1; + pod2usage(-verbose => 99, + -sections => [ 'ACCOUNT COMMANDS' ], + -exitval => 1); } my $subcmd = shift // "view"; - if (! $subcmd) { - pod2usage(-verbose => 99, - -sections => [ 'ACCOUNT COMMANDS' ] ); - } - elsif (! exists $cmds_account{$subcmd}) { + if (! exists $cmds_account{$subcmd}) { log(USAGE, "Unknown command for account: ". $subcmd); return 1; } @@ -176,39 +204,39 @@ sub cmd_account_close($@) return -1; } - my $ldap = LDAP::ldap_connect(); + my $ldap; + eval { + $ldap = LDAP::ldap_connect(); + }; + log(ERROR, $@) if ($@); - my $mesg = $ldap->search( # search - base => "ou=users,dc=acu,dc=epita,dc=fr", - filter => "uid=$login", - attrs => ['objectClass', 'userPassword', 'loginShell'], - scope => "sub" - ); - if ($mesg->code != 0) { - log(ERROR, $mesg->error); - } - if ($mesg->count != 1) { - log(ERROR, "User $login not found or multiple presence"); - } + my $dn; + eval { + $dn = LDAP::search_dn($ldap, "ou=users", "uid=$login"); + }; + log(ERROR, $@) if ($@); + my $entry = LDAP::get_dn($ldap, $dn, 'objectClass', 'userPassword', 'loginShell'); - if (grep { "epitaAccount" } $mesg->entry(0)->get_value("objectClass")) { - log(INFO, "Invalidating password for $login ..."); + if (grep { "epitaAccount" } $entry->get_value("objectClass")) + { + log(INFO, "Invalidating password for ", YELLOW, $login, RESET, " ..."); - my $passwd = $mesg->entry(0)->get_value("userPassword"); + my $passwd = $entry->get_value("userPassword"); $passwd =~ s/^(\{[^\}]+\})/$1!/ if ($passwd !~ /^\{[^\}]+\}!/); - $mesg->entry(0)->replace("userPassword" => $passwd); - $mesg->entry(0)->update($ldap); + $entry->replace("userPassword" => $passwd); + $entry->update($ldap); } $ldap->unbind or die ("couldn't disconnect correctly"); - if (grep { "posixAccount" } $mesg->entry(0)->get_value("objectClass")) { + if (grep { "posixAccount" } $entry->get_value("objectClass")) + { log(DEBUG, "Setting shell for $login ..."); cmd_account_shell($login, "/bin/false"); } - log(WARN, "Done. Don't forget to restart nscd on servers and workstations!"); + log(DONE, "Done; don't forget to restart nscd on servers and workstations!"); return 0; } @@ -262,9 +290,9 @@ sub cmd_account_grantintra($@) my $dn = LDAP::search_dn($ldap, "ou=users", "uid=$login"); - LDAP::add_attribute($ldap, $dn, "objectClass", "intraAccount"); - - log(INFO, "$login now grants to use the intranet."); + if (LDAP::add_attribute($ldap, $dn, "objectClass", "intraAccount")) { + log(INFO, "$login now grants to use the intranet."); + } $ldap->unbind or die ("couldn't disconnect correctly"); } @@ -329,58 +357,49 @@ sub cmd_account_nopass($@) { my $login = shift; - my $ldap = LDAP::ldap_connect(); + my $ldap; + eval { + $ldap = LDAP::ldap_connect(); + }; + log(ERROR, $@) if ($@); - my $mesg = $ldap->search( # search - base => "ou=users,dc=acu,dc=epita,dc=fr", - filter => "uid=$login", - attrs => ['userPassword'], - scope => "sub" - ); - if ($mesg->code != 0) { - log(ERROR, $mesg->error); - } - if ($mesg->count != 1) { - log(ERROR, "User $login not found"); - } + my $dn; + eval { + $dn = LDAP::search_dn($ldap, "ou=users", "uid=$login"); + }; + log(ERROR, $@) if ($@); + my @pass = LDAP::get_attribute($ldap, $dn, 'userPassword'); - my $pass = $mesg->entry(0)->get_value("userPassword"); - - if (! $pass || $pass eq "{crypt}!toto") { - $mesg = $ldap->unbind; + if (@pass == 1 && $pass[0] eq "{crypt}!toto") + { + $ldap->unbind; log(WARN, "Password already empty"); return 2; } - else { - printf(STDERR "Are you sure you want to reset password for $login? [y/N] "); - if (getc(STDIN) ne "y") { - log(DEBUG, "y response expected to continue; leaving."); - log(WARN, "Password unchanged for $login."); - return 2; + else + { + if (!$noconfirm) + { + print STDERR "Are you sure you want to reset password for ", YELLOW, $login, RESET, "? [", GREEN, "y", RESET, "/", RED, "N", RESET, "] "; + my $go = ; + chomp $go; + if ($go ne "y" and $go ne "yes") + { + log(DEBUG, "y response expected to continue, leaving."); + log(WARN, "Password unchanged for $login."); + return 2; + } } - $mesg = $ldap->search( # search - base => "ou=users,dc=acu,dc=epita,dc=fr", - filter => "uid=$login", - attrs => ['userPassword'], - scope => "sub" - ); - if ($mesg->code != 0) { - log(ERROR, $mesg->error); + if (LDAP::update_attribute($ldap, $dn, 'userPassword', "{crypt}!toto")) + { + log(DONE, YELLOW, $login, RESET, " have no more password."); } - if ($mesg->count != 1) { - log(ERROR, "User $login not found"); - } - - $mesg->entry(0)->replace("userPassword" => "{crypt}!toto"); - $mesg->entry(0)->update($ldap); - - log(INFO, "$login have no more password."); - - $ldap->unbind or die ("couldn't disconnect correctly"); - - return 0; } + + $ldap->unbind or die ("couldn't disconnect correctly"); + + return 0; } sub cmd_account_passgen($@) @@ -393,26 +412,28 @@ sub cmd_account_passgen($@) return 1; } -#printf(STDERR "Are you sure you want to change password for $login? [y/N] "); -# my $go = ; -# chomp $go; -# if ($go ne "y" and $go ne "yes") { -# log(DEBUG, "y response expected to continue, leaving."); -# log(WARN, "Password unchanged for $login."); -# return 2; -# } -# + if (!$noconfirm) + { + print STDERR "Are you sure you want to change password for ", YELLOW, $login, RESET, "? [", GREEN, "y", RESET, "/", RED, "N", RESET, "] "; + my $go = ; + chomp $go; + if ($go ne "y" and $go ne "yes") + { + log(DEBUG, "y response expected to continue, leaving."); + log(WARN, "Password unchanged for $login."); + return 2; + } + } + log(DEBUG, "Generating a $nb_char chars password..."); my $pass = ""; - open (HANDLE, "pwgen -s -n -c -y -1 $nb_char 1 |"); - while() { - $pass = $_; - } - close(HANDLE); + open (my $fh, "pwgen -s -n -c -y -1 $nb_char 1 |"); + $pass = <$fh>; + close($fh); chomp($pass); - log(DEBUG, "Setting $pass password to $login..."); + log(DEBUG, "Setting $pass password to ", YELLOW, $login, RESET, "..."); if (cmd_account_password($login, $pass)) { return 3; } @@ -432,53 +453,46 @@ sub cmd_account_password($@) } my $pass = shift; - if (! $pass) { - say "Changing password for $login."; + if (! $pass) + { + say STDERR "Changing password for ", YELLOW, $login, RESET, "."; ReadMode("noecho"); - print "new password: "; my $pass1 = ; - print "\nretype new password: "; my $pass2 = ; + print STDERR "New password: "; my $pass1 = ; + print STDERR "\nRetype new password: "; my $pass2 = ; ReadMode("restore"); - print "\n"; + print STDERR "\n"; log(DEBUG, "Read passwords: $pass1 and $pass2"); $pass1 eq $pass2 || log(ERROR, "Passwords did not match."); $pass = $pass1; } - - if ($pass eq "") { - log(ERROR, "Empty password refused."); - } - chomp($pass); + + log(FATAL, "Empty password refused.") if ($pass eq ""); + my $salt = join '', ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64, rand 64, rand 64]; - my $ctx = Digest::SHA1->new; + my $ctx = Digest::SHA->new(1); $ctx->add($pass); $ctx->add($salt); my $enc_password = "{SSHA}" . encode_base64($ctx->digest . $salt ,''); - my $ldap = LDAP::ldap_connect(); + my $ldap; + eval { + $ldap = LDAP::ldap_connect(); + }; + log(ERROR, $@) if ($@); - my $mesg = $ldap->search( # search - base => "ou=users,dc=acu,dc=epita,dc=fr", - filter => "uid=$login", - attrs => ['userPassword'], - scope => "sub" - ); - if ($mesg->code != 0) { - log(ERROR, $mesg->error); - } - if ($mesg->count != 1) { - log(ERROR, "User $login not found"); - } + my $dn; + eval { + $dn = LDAP::search_dn($ldap, "ou=users", "uid=$login"); + }; + log(ERROR, $@) if ($@); - $mesg->entry(0)->replace("userPassword" => $enc_password); - $mesg->entry(0)->update($ldap); - $ldap->unbind or die ("couldn't disconnect correctly"); - return 0; + return !LDAP::update_attribute($ldap, $dn, 'userPassword', $enc_password); } sub cmd_account_photo($@) @@ -495,42 +509,42 @@ sub cmd_account_reopen(@) return 1; } - my $ldap = LDAP::ldap_connect(); + my $ldap; + eval { + $ldap = LDAP::ldap_connect(); + }; + log(ERROR, $@) if ($@); - my $mesg = $ldap->search( # search - base => "ou=users,dc=acu,dc=epita,dc=fr", - filter => "uid=$login", - attrs => ['objectClass', 'cn', 'userPassword', 'loginShell'], - scope => "sub" - ); - if ($mesg->code != 0) { - log(ERROR, $mesg->error); - } - if ($mesg->count != 1) { - log(ERROR, "User $login not found or multiple presence"); - } + my $dn; + eval { + $dn = LDAP::search_dn($ldap, "ou=users", "uid=$login"); + }; + log(ERROR, $@) if ($@); + my $entry = LDAP::get_dn($ldap, $dn, 'objectClass', 'cn', 'userPassword', 'loginShell'); - if (grep { "epitaAccount" } $mesg->entry(0)->get_value("objectClass")) { + if (grep { "epitaAccount" } $entry->get_value("objectClass")) + { # update password - my $passwd = $mesg->entry(0)->get_value("userPassword"); - if ($passwd =~ /^\{[^\}]+\}!/) { - log(INFO, "Restoring password for $login ..."); + my $passwd = $entry->get_value("userPassword"); + if ($passwd =~ /^\{[^\}]+\}!/) + { + log(INFO, "Restoring password for ", YELLOW, $login, RESET, " ..."); $passwd =~ s/^(\{[^\}]+\})!/$1/; - $mesg->entry(0)->replace("userPassword" => $passwd); - $mesg->entry(0)->update($ldap); + LDAP::update_attribute($ldap, "userPassword", $passwd); } } $ldap->unbind or die ("couldn't disconnect correctly"); - if (grep { "posixAccount" } $mesg->entry(0)->get_value("objectClass")) { + if (grep { "posixAccount" } $entry->get_value("objectClass")) + { log(DEBUG, "Setting shell for $login ..."); cmd_account_shell($login, $shellValid); } - log(WARN, "Done. Don't forget to restart nscd on servers and workstations!"); + log(DONE, "Done; don't forget to restart nscd on servers and workstations!"); return 0; } @@ -558,72 +572,55 @@ sub cmd_account_multiple_vieworchange($$$@) my $change = shift; if (($action ne "list" and $action ne "add" and $action ne "del" and $action ne "flush") or (!$change and $action ne "list" and $action ne "flush")) { - log(USAGE, " account $typeName [list|add|del|flush] [string]"); + log(USAGE, "lpt account $typeName [list|add|del|flush] [string]"); return 1; } my $ldap; - $ldap = LDAP::ldap_connect() if ($action ne "list"); - $ldap = LDAP::ldap_connect_anon() if ($action eq "list"); - my $mesg = $ldap->search( # search - base => "ou=users,dc=acu,dc=epita,dc=fr", - filter => "uid=$login", - attrs => [ $type ], - scope => "sub" - ); - if ($mesg->code != 0) { - log(ERROR, $mesg->error); - } - if ($mesg->count != 1) { - log(ERROR, "User $login not found or multiple presence"); - } + eval { + $ldap = LDAP::ldap_connect() if ($action ne "list"); + $ldap = LDAP::ldap_connect_anon() if ($action eq "list"); + }; + log(ERROR, $@) if ($@); - if ($action eq "add") { - log(INFO, "Adding $change as ".$typeName."s for $login ..."); + my $dn; + eval { + $dn = LDAP::search_dn($ldap, "ou=users", "uid=$login"); + }; + log(ERROR, $@) if ($@); + my @attr = LDAP::get_attribute($ldap, $dn, $type); - my @data = $mesg->entry(0)->get_value($type); + if ($action eq "add") + { + log(INFO, "Adding ", BOLD, YELLOW, $change, RESET, " as ".$typeName."s for ", YELLOW, $login, RESET, " ..."); - if (! grep(/^$change$/, @data)) { - push @data, $change; - $mesg->entry(0)->replace($type => \@data) or die $!; - $mesg->entry(0)->update($ldap) or die $!; - - log(INFO, "Done!"); - } - else { - log(WARN, "$login has already $change $typeName."); + if (LDAP::add_attribute($ldap, $dn, $type, $change)) { + log(DONE, "Done!"); } } - elsif ($action eq "del") { - log(INFO, "Checking if $change is a ".$typeName."s of $login ..."); - my @data = $mesg->entry(0)->get_value($type); - if (grep(/^$change$/, @data)) { - log(INFO, "Deleting $change as $typeName for $login ..."); + elsif ($action eq "del") + { + log(INFO, "Deleting ", BOLD, YELLOW, $change, RESET, " as ".$typeName."s for ", YELLOW, $login, RESET, " ..."); - @data = grep(!/$change$/, @data); - - $mesg->entry(0)->replace($type => \@data) or die $!; - $mesg->entry(0)->update($ldap) or die $!; - - log(INFO, "Done!"); - } - else { - log(WARN, "$change is not a $typeName for $login."); + if (LDAP::delete_attribute($ldap, $dn, $type, $change)) { + log(DONE, "Done!"); } } - elsif ($action eq "flush") { - $ldap->modify($mesg->entry(0)->dn, delete => [$type]); - log(INFO, "$login have no more $typeName."); + elsif ($action eq "flush") + { + log(DONE, YELLOW, $login, RESET, " have no more $typeName.") if LDAP::flush_attribute($ldap, $dn, $type); } - else { - if ($mesg->entry(0)->get_value($type)) { - log(INFO, $login."'s ".$typeName."s are:"); - for my $val ($mesg->entry(0)->get_value($type)) { - say " - $val"; + else + { + if (@attr) + { + log(INFO, BOLD, YELLOW, $login, RESET, "'s ".$typeName."s are:"); + for my $val (@attr) { + say " - ", BOLD, $val, RESET; } } else { - log(INFO, "$login have no $typeName."); + log(INFO, YELLOW, $login, RESET, " have no $typeName."); } } @@ -638,42 +635,39 @@ sub cmd_account_vieworchange($$@) my $login = shift; if ($#_ > 0) { - log(USAGE, " account $typeName [new_string]"); + log(USAGE, "lpt account $typeName [new_$typeName]"); return 1; } my $change = shift; my $ldap; - $ldap = LDAP::ldap_connect() if ($change); - $ldap = LDAP::ldap_connect_anon() if (!$change); + eval { + $ldap = LDAP::ldap_connect() if ($change); + $ldap = LDAP::ldap_connect_anon() if (!$change); + }; + log(ERROR, $@) if ($@); - my $mesg = $ldap->search( # search - base => "ou=users,dc=acu,dc=epita,dc=fr", - filter => "uid=$login", - attrs => [ $type ], - scope => "sub" - ); - if ($mesg->code != 0) { - log(ERROR, $mesg->error); + my $dn; + eval { + $dn = LDAP::search_dn($ldap, "ou=users", "uid=$login"); + }; + log(ERROR, $@) if ($@); + my $attr = LDAP::get_attribute($ldap, $dn, $type); + + if ($change) + { + log(INFO, "Setting $typeName to ", YELLOW, BOLD, $change, RESET " for ", YELLOW, $login, " ..."); + + LDAP::update_attribute($ldap, $dn, $type, $change); + + log(DONE, "Done!"); } - if ($mesg->count != 1) { - log(ERROR, "User $login not found or multiple presence"); - } - - if ($change) { - log(INFO, "Setting $typeName to $change for $login ..."); - - $mesg->entry(0)->replace($type => $change) or die $!; - $mesg->entry(0)->update($ldap) or die $!; - - log(INFO, "Done!"); - } - elsif ($mesg->entry(0)->get_value($type)) { - log(INFO, $login."'s $typeName is ".$mesg->entry(0)->get_value($type)."."); + elsif ($attr) { + log(INFO, YELLOW, $login, RESET, "'s $typeName is ", BOLD, YELLOW, $attr, RESET, "."); } else { - log(INFO, $login."'s has no $typeName."); + log(INFO, YELLOW, $login, RESET, "'s has no $typeName."); } $ldap->unbind or die ("couldn't disconnect correctly"); @@ -686,71 +680,54 @@ sub cmd_account_view($@) my $ldap = LDAP::ldap_connect_anon(); - my $mesg = $ldap->search(base => "ou=users,dc=acu,dc=epita,dc=fr", - filter => "uid=$login", - attrs => ['objectClass']); + my $dn; + eval { + $dn = LDAP::search_dn($ldap, "ou=users", "uid=$login"); + }; + log(ERROR, $@) if ($@); + my @classes = LDAP::get_attribute($ldap, $dn, 'objectClass'); - $mesg->code && log(ERROR, $mesg->error); - if ($mesg->count <= 0) { - log(ERROR, "No such account!"); - } + log(DEBUG, "objectClasses: ", join(', ', @classes)); - log(DEBUG, "objectClasses:\t" . join(', ', $mesg->entry(0)->get_value("objectClass"))); - - my @attrs = ['dn', 'ou']; + my @attrs; if ($#_ >= 0) { push @attrs, @_; } - else { - if (grep { "epitaAccount" } $mesg->entry(0)->get_value("objectClass")) { - push @attrs, 'uid', 'cn', 'mail', 'uidNumber'; - } - if (grep { "posixAccount" } $mesg->entry(0)->get_value("objectClass")) { - push @attrs, 'gecos', 'loginShell', 'homeDirectory', 'gidNumber'; - } - if (grep { "labAccount" } $mesg->entry(0)->get_value("objectClass")) { - push @attrs, 'labService', 'quotaHomeBlock', 'quotaHomeFile', 'quotaSgoinfreBlock', 'quotaSgoinfreFile'; - } - if (grep { "intraAccount" } $mesg->entry(0)->get_value("objectClass")) { - push @attrs, 'intraRight'; - } - if (grep { "MailAccount" } $mesg->entry(0)->get_value("objectClass")) { - push @attrs, 'mailAlias'; - } + else + { + push @attrs, 'uid', 'cn', 'mail', 'uidNumber' if (grep { "epitaAccount" } @classes); + push @attrs, 'gecos', 'loginShell', 'homeDirectory', 'gidNumber' if (grep { "posixAccount" } @classes); + push @attrs, 'labService', 'quotaHomeBlock', 'quotaHomeFile', 'quotaSgoinfreBlock', 'quotaSgoinfreFile' if (grep { "labAccount" } @classes); + push @attrs, 'intraRight' if (grep { "intraAccount" } @classes); + push @attrs, 'mailAlias' if (grep { "MailAccount" } @classes); } log(DEBUG, "attrs to get: " . join(', ', @attrs)); - $mesg = $ldap->search(base => "ou=users,dc=acu,dc=epita,dc=fr", - filter => "uid=$login", - attrs => \@attrs); - $mesg->code && die $mesg->error; + my @res = LDAP::get_dn($ldap, $dn, @attrs); - shift @attrs; # Remove dn my $nb = 0; - for my $entry ($mesg->entries) + for my $entry (@res) { - if ($nb > 0) { - say "=="; - } + say "==" if ($nb > 0); say BOLD, YELLOW, "dn: ", RESET, YELLOW, $entry->dn, RESET; - for my $attr (@attrs) { - if ($#attrs < 3) { + for my $attr (@attrs) + { + if ($#attrs < 3) + { for my $entry ($entry->get_value($attr)) { - say CYAN, "$attr: ", RESET , $entry; + say CYAN, "$attr: ", RESET, $entry; } } else { - say CYAN, "$attr: ", RESET , join(', ', $entry->get_value($attr)); + say CYAN, "$attr: ", RESET, join(', ', $entry->get_value($attr)); } } $nb++; } - if ($nb > 1) { - say "\n$nb users displayed"; - } + say "\n$nb users displayed" if ($nb > 1); $ldap->unbind or die ("couldn't disconnect correctly"); return 0; @@ -765,110 +742,105 @@ sub cmd_account_view($@) sub cmd_group(@) { - my $gname = shift; - my $year; + return cmd_groups($group_types{intra}, @_); +} - if ($gname && $gname =~ /^(20[0-9]{2})$/) +sub cmd_role(@) +{ + return cmd_groups($group_types{roles}, @_); +} + +sub cmd_systemgrp(@) +{ + return cmd_groups($group_types{system}, @_); +} + +sub cmd_groups($@) +{ + my $ou = shift; + my $gname = shift; + + if ($gname && $gname =~ /^(2[0-9]{3})$/) { - $year = $1; + $ou = "year=$1,$ou"; $gname = shift; } if (! $gname) { - log(USAGE, "lpt group [year] [arguments ...]"); - return 1; + pod2usage(-verbose => 99, + -sections => [ 'GROUP COMMANDS' ], + -exitval => 1); } my $subcmd = shift // "view"; - if (! $subcmd) { - pod2usage(-verbose => 99, - -sections => [ 'GROUP COMMANDS' ] ); - } - elsif (! exists $cmds_group{$subcmd}) { + if (! exists $cmds_group{$subcmd}) { log(USAGE, "Unknown command for group: ". $subcmd); return 1; } - return $cmds_group{$subcmd}($gname, $year, @_); + return $cmds_group{$subcmd}($ou, $gname, @_); } sub cmd_group_multiple_vieworchange { my $type = shift; my $typeName = shift; + my $ou = shift; my $gname = shift; - my $year = shift // LDAP::get_year(); my $action = shift // "list"; my $change = shift; if (($action ne "list" and $action ne "add" and $action ne "del" and $action ne "flush") or (!$change and $action ne "list" and $action ne "flush")) { - log(USAGE, " group $typeName [list|add|del|flush] [string]"); + log(USAGE, "lpt group [year] $typeName [list|add|del|flush] [string]"); return 1; } my $ldap; - $ldap = LDAP::ldap_connect() if ($action ne "list"); - $ldap = LDAP::ldap_connect_anon() if ($action eq "list"); - my $mesg = $ldap->search( # search - base => "ou=groups,dc=acu,dc=epita,dc=fr", - filter => "cn=$gname", - attrs => [ $type ], - scope => "sub" - ); - if ($mesg->code != 0) { - log(ERROR, $mesg->error); - } - if ($mesg->count != 1) { - log(ERROR, "Group $gname not found or multiple presence"); - } + eval { + $ldap = LDAP::ldap_connect() if ($action ne "list"); + $ldap = LDAP::ldap_connect_anon() if ($action eq "list"); + }; + log(ERROR, $@) if ($@); - if ($action eq "add") { - log(INFO, "Adding $change as ".$typeName."s for $gname ..."); + my $dn; + eval { + $dn = LDAP::search_dn($ldap, $ou, "cn=$gname"); + }; + log(ERROR, $@) if ($@); + my @attr = LDAP::get_attribute($ldap, $dn, $type); - my @data = $mesg->entry(0)->get_value($type); + if ($action eq "add") + { + log(INFO, "Adding ", BOLD, YELLOW, $change, RESET, " as ", $typeName, "s for ", YELLOW, $gname, RESET, " ..."); - if (! grep(/^$change$/, @data)) { - push @data, $change; - $mesg->entry(0)->replace($type => \@data) or die $!; - $mesg->entry(0)->update($ldap) or die $!; - - log(INFO, "Done!"); - } - else { - log(WARN, "$gname has already $change $typeName."); + if (LDAP::add_attribute($ldap, $dn, $type, $change)) { + log(DONE, "Done!"); } } - elsif ($action eq "del") { - log(INFO, "Checking if $change is a ".$typeName."s of $gname ..."); - my @data = $mesg->entry(0)->get_value($type); - if (grep(/^$change$/, @data)) { - log(INFO, "Deleting $change as $typeName for $gname ..."); + elsif ($action eq "del") + { + log(INFO, "Deleting ", BOLD, YELLOW, $change, RESET, " as ".$typeName."s for ", YELLOW, $gname, RESET, " ..."); - @data = grep(!/$change$/, @data); - - $mesg->entry(0)->replace($type => \@data) or die $!; - $mesg->entry(0)->update($ldap) or die $!; - - log(INFO, "Done!"); - } - else { - log(WARN, "$change is not a $typeName for $gname."); + if (LDAP::delete_attribute($ldap, $dn, $type, $change)) { + log(DONE, "Done!"); } } - elsif ($action eq "flush") { - $ldap->modify($mesg->entry(0)->dn, delete => [$type]); - log(INFO, "$gname have no more $typeName."); + elsif ($action eq "flush") + { + log(DONE, YELLOW, $gname, RESET, " have no more $typeName.") if LDAP::flush_attribute($ldap, $dn, $type); } - else { - if ($mesg->entry(0)->get_value($type)) { - log(INFO, $gname."'s ".$typeName."s are:"); - for my $val ($mesg->entry(0)->get_value($type)) { + else + { + if (@attr) + { + log(INFO, BOLD, YELLOW, $gname, RESET, "'s ".$typeName."s are:"); + for my $val (@attr) { say " - $val"; } } else { - log(INFO, "$gname have no $typeName."); + log(INFO, YELLOW, $gname, RESET, " have no $typeName."); } } @@ -880,8 +852,8 @@ sub cmd_group_vieworchange { my $type = shift; my $typeName = shift; + my $ou = shift; my $gname = shift; - my $year = shift // LDAP::get_year(); if ($#_ > 0) { log(USAGE, " group $typeName [new_string]"); @@ -891,35 +863,32 @@ sub cmd_group_vieworchange my $change = shift; my $ldap; - $ldap = LDAP::ldap_connect() if ($change); - $ldap = LDAP::ldap_connect_anon() if (!$change); + eval { + $ldap = LDAP::ldap_connect() if ($change); + $ldap = LDAP::ldap_connect_anon() if (!$change); + }; + log(ERROR, $@) if ($@); - my $mesg = $ldap->search( # search - base => "ou=groups,dc=acu,dc=epita,dc=fr", - filter => "uid=$gname", - attrs => [ $type ], - scope => "sub" - ); - if ($mesg->code != 0) { - log(ERROR, $mesg->error); + my $dn; + eval { + $dn = LDAP::search_dn($ldap, $ou, "cn=$gname"); + }; + log(ERROR, $@) if ($@); + my $attr = LDAP::get_attribute($ldap, $dn, $type); + + if ($change) + { + log(INFO, "Setting $typeName to ", YELLOW, BOLD, $change, RESET " for ", YELLOW, $gname, " ..."); + + LDAP::update_attribute($ldap, $dn, $type, $change); + + log(DONE, "Done!"); } - if ($mesg->count != 1) { - log(ERROR, "User $gname not found or multiple presence"); - } - - if ($change) { - log(INFO, "Setting $typeName to $change for $gname ..."); - - $mesg->entry(0)->replace($type => $change) or die $!; - $mesg->entry(0)->update($ldap) or die $!; - - log(INFO, "Done!"); - } - elsif ($mesg->entry(0)->get_value($type)) { - log(INFO, $gname."'s $typeName is ".$mesg->entry(0)->get_value($type)."."); + elsif ($attr) { + log(INFO, YELLOW, $gname, RESET, "'s $typeName is ", BOLD, YELLOW, $attr, RESET, "."); } else { - log(INFO, $gname."'s has no $typeName."); + log(INFO, YELLOW, $gname, RESET, "'s has no $typeName."); } $ldap->unbind or die ("couldn't disconnect correctly"); @@ -928,56 +897,43 @@ sub cmd_group_vieworchange sub cmd_group_view { + my $ou = shift; my $gname = shift; - my $year = shift; - if ($year) { - $year = "ou=$year,"; - } else { - $year = ""; - } my $ldap = LDAP::ldap_connect_anon(); - my $mesg = $ldap->search(base => $year."ou=intra,ou=groups,dc=acu,dc=epita,dc=fr", - filter => "cn=$gname", - attrs => ['objectClass']); + my $dn; + eval { + $dn = LDAP::search_dn($ldap, $ou, "cn=$gname"); + }; + log(ERROR, $@) if ($@); + my @classes = LDAP::get_attribute($ldap, $dn, 'objectClass'); - $mesg->code && log(ERROR, $mesg->error); - log(ERROR, "No such group!") if ($mesg->count <= 0); + log(DEBUG, "objectClasses: ", join(', ', @classes)); - log(DEBUG, "objectClasses:\t" . join(', ', $mesg->entry(0)->get_value("objectClass"))); - - my @attrs = ['dn']; + my @attrs; if ($#_ >= 0) { push @attrs, @_; } - else { - if (grep { "intraGroup" } $mesg->entry(0)->get_value("objectClass")) { - push @attrs, 'intraRight'; - } - if (grep { "posixGroup" } $mesg->entry(0)->get_value("objectClass")) { - push @attrs, 'cn', 'memberUid'; - } + else + { + push @attrs, 'intraRight' if (grep { "intraGroup" } @classes); + push @attrs, 'cn', 'memberUid' if (grep { "posixGroup" } @classes); } log(DEBUG, "attrs to get: " . join(', ', @attrs)); + my @res = LDAP::get_dn($ldap, $dn, @attrs); - $mesg = $ldap->search(base => $year."ou=intra,ou=groups,dc=acu,dc=epita,dc=fr", - filter => "cn=$gname", - attrs => \@attrs); - $mesg->code && die $mesg->error; - - shift @attrs; # Remove dn my $nb = 0; - for my $entry ($mesg->entries) + for my $entry (@res) { - if ($nb > 0) { - say "=="; - } + say "==" if ($nb > 0); say BOLD, YELLOW, "dn: ", RESET, YELLOW, $entry->dn, RESET; - for my $attr (@attrs) { - if ($#attrs < 3) { + for my $attr (@attrs) + { + if ($#attrs < 3) + { for my $entry ($entry->get_value($attr)) { say CYAN, "$attr: ", RESET , $entry; } @@ -990,9 +946,7 @@ sub cmd_group_view $nb++; } - if ($nb > 1) { - say "\n$nb groups displayed"; - } + say "\n$nb groups displayed" if ($nb > 1); $ldap->unbind or die ("couldn't disconnect correctly"); return 0; @@ -1010,23 +964,35 @@ sub cmd_group_rights($@) sub cmd_group_create { + my $ou = shift; my $gname = shift; - my $year = shift // LDAP::get_year(); - log(DEBUG, "Adding dn: cn=$gname,ou=$year,ou=intra,ou=groups,dc=acu,dc=epita,dc=fr ..."); + log(DEBUG, "Adding dn: cn=$gname,ou=intra,ou=groups,dc=acu,dc=epita,dc=fr ..."); - my $ldap = LDAP::ldap_connect(); - my $mesg = $ldap->add( "cn=$gname,ou=$year,ou=intra,ou=groups,dc=acu,dc=epita,dc=fr", + my $dn = "cn=$gname,$ou,dc=acu,dc=epita,dc=fr"; + + my $class; + $class = "intraGroup" if ($ou ne $group_types{system}); + $class = "posixGroup" if ($ou eq $group_types{system}); + + my $ldap; + eval { + $ldap = LDAP::ldap_connect(); + }; + log(ERROR, $@) if ($@); + + my $mesg = $ldap->add( $dn, attrs => [ - objectclass => [ "top", "intraGroup" ], + objectclass => [ "top", $class ], cn => $gname, ] ); - #$ldap->unbind or die ("couldn't disconnect correctly"); + $ldap->unbind or die ("couldn't disconnect correctly"); - if ($mesg->code == 0) { - log(INFO, "Group added: $gname"); + if ($mesg->code == 0) + { + log(DONE, "Group added: ", YELLOW, $gname, RESET); return 0; } else { @@ -1036,22 +1002,24 @@ sub cmd_group_create sub cmd_group_delete(@) { + my $ou = shift; my $gname = shift; - my $year = shift // LDAP::get_year(); - my $dn = "cn=$gname,ou=$year,ou=intra,ou=groups,dc=acu,dc=epita,dc=fr"; + my $dn = "cn=$gname,$ou,dc=acu,dc=epita,dc=fr"; - log(DEBUG, "Deletinging dn: $dn ..."); + log(DEBUG, "Deleting dn: $dn ..."); my $ldap = LDAP::ldap_connect(); - if (LDAP::delete_entry($ldap, $dn)) { - log DONE, "Group $gname successfully deleted."; - } else { - log ERROR, "Unable to delete group $gname."; + if (LDAP::delete_entry($ldap, $dn)) + { + log DONE, "Group ", YELLOW, $gname, RESET, " successfully deleted."; + return 0; + } + else + { + log ERROR, "Unable to delete group ", YELLOW, $gname, RESET, "."; return 1; } - - return 0; } @@ -1079,79 +1047,123 @@ sub cmd_list(@) sub cmd_list_accounts(@) { - if ($#_ > 1) - { - log(USAGE, " list account [open|close|services]"); - exit(1); - } - my $action = shift // "open"; + my $ou = "ou=users"; + my $action = shift // "all"; - my $shellFalse = "/bin/false"; - my $ldap = LDAP::ldap_connect(); + if ($action =~ /^2[0-9{3}]$/) + { + $ou = "ou=$action,$ou"; + $action = shift // "all"; + } - if ($action eq "open") - { - my $mesg = $ldap->search(base => "ou=users,dc=acu,dc=epita,dc=fr", - filter => "&(!(loginShell=$shellFalse))(|(objectClass=posixAccount)(objectClass=epitaAccount))", - attrs => [ 'dn', 'userPassword' ]); - $mesg->code && die $mesg->error; - if ($mesg->count == 0) { - log(WARN, "No account found"); - } - else { - for my $entry ($mesg->entries) { - if (! $entry->get_value("userPassword") or $entry->get_value("userPassword") =~ /^\{[^\}]\}!/) { - print YELLOW, "Partially closed:\t", RESET; - } else { - print CYAN, "Opened:\t", RESET; - } - say $entry->dn; - } - } - } - elsif ($action eq "close") - { - my $mesg = $ldap->search(base => "ou=users,dc=acu,dc=epita,dc=fr", - filter => "&(loginShell=$shellFalse)(|(objectClass=posixAccount)(objectClass=epitaAccount))", - attrs => [ 'userPassword' ]); - $mesg->code && die $mesg->error; - if ($mesg->count == 0) { - log(WARN, "No account found"); - } - else { - for my $entry ($mesg->entries) { - if ($entry->get_value("userPassword") =~ /^\{[^\}]\}!/) { - print YELLOW, "Partially closed:\t", RESET; - } else { - print RED, "Closed:\t", RESET; - } - say $entry->dn; - } - } - } - elsif ($action eq "services") + my $ldap; + eval { + $ldap = LDAP::ldap_connect_anon() if ($action eq "services"); + $ldap = LDAP::ldap_connect() if ($action ne "services"); + }; + log(ERROR, $@) if ($@); + + if ($action eq "services") { my $service = shift // "*"; - my $mesg = $ldap->search(base => "ou=users,dc=acu,dc=epita,dc=fr", - filter => "&(labService=$service)(|(objectClass=posixAccount)(objectClass=epitaAccount))", - attrs => [ 'uid', 'labService' ]); - $mesg->code && die $mesg->error; - if ($mesg->count == 0) { + my @entries = LDAP::search_dns($ldap, + $ou, + "&(labService=$service)(|(objectClass=posixAccount)(objectClass=epitaAccount))", + 'uid', + 'labService'); + + if ($#entries < 0) { log(WARN, "No account found!"); } - else { - for my $entry ($mesg->entries) { + else + { + for my $entry (@entries) { say YELLOW, $entry->get_value("uid"), "\t", RESET, join(", ", $entry->get_value("labService")); } } } + else + { + my $filter; + if ($action eq "open") { + $filter = "&(!(loginShell=$shellFalse))(|(objectClass=posixAccount)(objectClass=epitaAccount))"; + } + elsif ($action eq "close") { + $filter = "&(!(loginShell=$shellFalse))(|(objectClass=posixAccount)(objectClass=epitaAccount))"; + } + elsif ($action eq "posix") { + $filter = "objectClass=posixAccount"; + } + elsif ($action eq "intra") { + $filter = "objectClass=intraAccount"; + } + elsif ($action eq "all") { + $filter = "|(objectClass=posixAccount)(objectClass=epitaAccount)"; + } + my @entries = LDAP::search_dns($ldap, + $ou, + $filter, + 'userPassword', + 'loginShell'); + + if ($#entries < 0) { + log(WARN, "No account found"); + } + else + { + for my $entry (@entries) + { + my $closed = 0; + $closed++ if (!$entry->get_value("userPassword") || $entry->get_value("userPassword") =~ /^\{[^\}]\}!/); + $closed++ if (!$entry->get_value("loginShell") || $entry->get_value("loginShell") eq $shellFalse); + + if ($closed == 0) { + print GREEN, "Opened:\t", RESET; + } elsif ($closed == 2) { + print RED, "Closed:\t", RESET; + } else { + print YELLOW, "Partially closed:\t", RESET; + } + say $entry->dn; + } + } + } $ldap->unbind or die ("couldn't disconnect correctly"); return 0; } +###################################### +# # +# YEAR BLOCK # +# # +###################################### + +sub cmd_year(@) +{ + my $year = shift; + + if ($year) + { + if ($year =~ /^[0-9]{4}$/) + { + say BOLD, MAGENTA, ">>>", RESET, " Changing current year to: ", YELLOW, BOLD, $year, RESET; + log (DONE, "Done!") if (LDAP::update_attribute(undef, LDAP::YEAR_DN, "year", $year)) + } + else { + say BOLD, RED, ">>>", WHITE, " $year is not a valid year.", RESET; + return 1; + } + } + else { + say BOLD, BLUE, ">>>", RESET, " Current year: ", YELLOW, BOLD, LDAP::get_year(), RESET; + } + return 0 +} + + ###################################### # # # QUOTA COMMAND # @@ -1162,16 +1174,23 @@ sub cmd_account_quota($@) { my $login = shift; - my $action = shift; + my $action = shift // "view"; - if ($#_ >= 0) { - cmd_account_quota_set($login, $action, @_); + if ($action eq "view") { + cmd_account_quota_view($login, @_); } - elsif ($action eq "sync") { + elsif ($action eq "sync") + { + if (! -d $nfsHomePrefix) + { + log(FATAL, "Quota sychronization can only be performed on the NFS server."); + return 1; + } + cmd_account_quota_sync($login, @_); } else { - cmd_account_quota_view($login, @_); + cmd_account_quota_set($login, $action, @_); } } @@ -1179,30 +1198,24 @@ sub cmd_account_quota_view($@) { my $login = shift; - my $ldap = LDAP::ldap_connect_anon(); - my $mesg = $ldap->search( - base => "ou=users,dc=acu,dc=epita,dc=fr", - filter => "uid=$login", - attrs => [ 'quotaHomeBlock', 'quotaHomeFile', 'quotaSgoinfreBlock', 'quotaSgoinfreFile' ] - ); + my $ldap; + eval { + $ldap = LDAP::ldap_connect_anon(); + }; + log(ERROR, $@) if ($@); - $mesg->code && die $mesg->error; - $mesg->count > 0 || return -1; + my $dn; + eval { + $dn = LDAP::search_dn($ldap, "ou=users", "uid=$login"); + }; + log(ERROR, $@) if ($@); + my $entry = LDAP::get_dn($ldap, $dn, 'quotaHomeBlock', 'quotaHomeFile', 'quotaSgoinfreBlock', 'quotaSgoinfreFile'); - my $nb = 0; - foreach my $entry ($mesg->entries) - { - if ($nb > 0) { - say "=="; - } - say BOLD, YELLOW, "dn: ", RESET, YELLOW, $entry->dn, ":", RESET; - say " - ", BLUE, "Home blocks:\t\t", RESET, ($entry->get_value("quotaHomeBlock") or "(standard)"); - say " - ", BLUE, "Home files:\t\t", RESET, ($entry->get_value("quotaHomeFile") or "(standard)"); - say " - ", BLUE, "Sgoinfre blocks:\t", RESET, ($entry->get_value("quotaSgoinfreBlock") or "(standard)"); - say " - ", BLUE, "Sgoinfre files:\t", RESET, ($entry->get_value("quotaSgoinfreFile") or "(standard)"); - - $nb++; - } + say BOLD, YELLOW, "dn: ", RESET, YELLOW, $entry->dn, ":", RESET; + say " - ", BLUE, "Home blocks:\t\t", RESET, ($entry->get_value("quotaHomeBlock") or "(standard)"); + say " - ", BLUE, "Home files:\t\t", RESET, ($entry->get_value("quotaHomeFile") or "(standard)"); + say " - ", BLUE, "Sgoinfre blocks:\t", RESET, ($entry->get_value("quotaSgoinfreBlock") or "(standard)"); + say " - ", BLUE, "Sgoinfre files:\t", RESET, ($entry->get_value("quotaSgoinfreFile") or "(standard)"); $ldap->unbind or die ("couldn't disconnect correctly"); } @@ -1211,9 +1224,10 @@ sub cmd_account_quota_set($@) { my $login = shift; - if ($#_ > 2) + if ($#_ < 2 || $#_ > 2) { log(USAGE, " account quota "); + say " With:\n\tvolume := home | sgoinfre\n\ttype := file | block\n\tvalue := [+-]?[0-9]+[TGMk]?"; return 1; } @@ -1222,12 +1236,8 @@ sub cmd_account_quota_set($@) my $value = shift; # check args - if (!($volume eq "home" || $volume eq "sgoinfre")) { - log(ERROR, "Volume must be home or sgoinfre; given: $volume"); - } - if (!($type eq "file" || $type eq "block")) { - log(ERROR, "Type must be file or block; given: $type"); - } + log(ERROR, "Volume must be home or sgoinfre; given: $volume") if (!($volume eq "home" || $volume eq "sgoinfre")); + log(ERROR, "Type must be file or block; given: $type") if (!($type eq "file" || $type eq "block")); # generate quotaName my $quotaName = "quota"; @@ -1237,56 +1247,60 @@ sub cmd_account_quota_set($@) $quotaName .= "Block" if ($type eq "block"); my $ldap; - $ldap = LDAP::ldap_connect() if ($value); - $ldap = LDAP::ldap_connect_anon() if (!$value); - my $mesg = $ldap->search( # search - base => "ou=users,dc=acu,dc=epita,dc=fr", - filter => "uid=$login", - attrs => [ $quotaName ], - scope => "sub" - ); - if ($mesg->code != 0) { log(ERROR, $mesg->error); } - if ($mesg->count != 1) { log(ERROR, "user $login not found or multiple presence"); } + eval { + $ldap = LDAP::ldap_connect() if ($value); + $ldap = LDAP::ldap_connect_anon() if (!$value); + }; + log(ERROR, $@) if ($@); - my $old_value = $mesg->entry(0)->get_value($quotaName); - if (!$old_value) { - $old_value = $def_quota{$type}{$volume}; - } + my $dn; + eval { + $dn = LDAP::search_dn($ldap, "ou=users", "uid=$login"); + }; + log(ERROR, $@) if ($@); + my $entry = LDAP::get_dn($ldap, $dn, $quotaName); - if (!$value) { - say YELLOW, "dn: ", $mesg->entry(0)->dn, RESET; + my $old_value = $entry->get_value($quotaName) // $def_quota{$type}{$volume}; + + if (!$value) + { + say YELLOW, "dn: ", $entry->dn, RESET; say BLUE, $quotaName, ": ", RESET, $old_value; return 0; } - if ($value =~ '^\+([0-9]+)([MKGTmkgt]?)$') { - my $t = $1; - $t *= 1024 if ($2 eq "K" or $2 eq "k"); - $t *= 1048576 if ($2 eq "M" or $2 eq "m"); - $t *= 1073741824 if ($2 eq "G" or $2 eq "g"); - $t *= 1099511627776 if ($2 eq "T" or $2 eq "t"); - $value = $old_value + $t; + my $nb; + if ($value =~ '([0-9]+)([MKGTmkgt]?)$') + { + my $nb = $1; + $nb *= 1024 if ($2 eq "K" or $2 eq "k"); + $nb *= 1048576 if ($2 eq "M" or $2 eq "m"); + $nb *= 1073741824 if ($2 eq "G" or $2 eq "g"); + $nb *= 1099511627776 if ($2 eq "T" or $2 eq "t"); } - elsif ($value =~ '^-([0-9]+)([MKGTmkgt]?)$') { - my $t = $1; - $t *= 1024 if ($2 eq "K" or $2 eq "k"); - $t *= 1048576 if ($2 eq "M" or $2 eq "m"); - $t *= 1073741824 if ($2 eq "G" or $2 eq "g"); - $t *= 1099511627776 if ($2 eq "T" or $2 eq "t"); - $value = $old_value - $t; + + if ($value =~ '^\+([0-9]+)([MKGTmkgt]?)$') + { + $value = $old_value + $nb; } - elsif ($value !~ /^[0-9]+$/) { + elsif ($value =~ '^-([0-9]+)([MKGTmkgt]?)$') + { + $value = $old_value - $nb; + } + elsif ($value !~ /^[0-9]+[MKGTmkgt]?$/) { log(ERROR, "Value must be an integer or +i or -i"); } + else { + $value = $nb; + } log(INFO, "Changing quota of $quotaName of $login to $value..."); - $mesg->entry(0)->replace($quotaName => $value) or die $!; - $mesg->entry(0)->update($ldap) or die $!; + if (LDAP::update_attribute($ldap, $dn, $quotaName, $value)) { + log(DONE, "Done!"); + } $ldap->unbind; - - log(INFO, "Done!"); } sub cmd_account_quota_sync($;$) @@ -1294,29 +1308,35 @@ sub cmd_account_quota_sync($;$) my $login = shift; my $nosync = shift; - my $ldap = LDAP::ldap_connect_anon(); - my $mesg = $ldap->search( - base => "ou=users,dc=acu,dc=epita,dc=fr", - filter => "(&(uid=$login)(objectClass=labAccount))", - attrs => [ 'uid', 'uidNumber', - 'quotaHomeBlock', 'quotaHomeFile', - 'quotaSgoinfreBlock', 'quotaSgoinfreFile' ] - ); - $mesg->code && die $mesg->error; - $mesg->count == 1 || log(ERROR, "User $login not found or multiple presence"); + my $ldap; + eval { + $ldap = LDAP::ldap_connect_anon(); + }; + log(ERROR, $@) if ($@); - my $quotaHomeBlock = $mesg->entry(0)->get_value("quotaHomeBlock") // $def_quota{block}{home}; - my $quotaHomeFile = $mesg->entry(0)->get_value("quotaHomeFile") // $def_quota{file}{home}; - my $quotaSgoinfreBlock = $mesg->entry(0)->get_value("quotaSgoinfreBlock") // $def_quota{block}{sgoinfre}; - my $quotaSgoinfreFile = $mesg->entry(0)->get_value("quotaSgoinfreFile") // $def_quota{file}{sgoinfre}; + my $dn; + eval { + $dn = LDAP::search_dn($ldap, "ou=users", "(&(uid=$login)(objectClass=labAccount))"); + }; + log(ERROR, $@) if ($@); + my $entry = LDAP::get_dn($ldap, $dn, + 'uid', 'uidNumber', + 'quotaHomeBlock', 'quotaHomeFile', + 'quotaSgoinfreBlock', 'quotaSgoinfreFile'); - if (Quota::setqlim($dev_quota{home}, $mesg->entry(0)->get_value("uidNumber"), int(0.9 * $quotaHomeBlock), $quotaHomeBlock, int(0.9 * $quotaHomeFile), $quotaHomeFile, 1, 0) == 0 and - Quota::setqlim($dev_quota{sgoinfre}, $mesg->entry(0)->get_value("uidNumber"), int(0.9 * $quotaHomeBlock), $quotaHomeBlock, int(0.9 * $quotaHomeFile), $quotaHomeFile, 1, 0) == 0) { - log(INFO, $login."'s quota synchronized!"); + my $quotaHomeBlock = $entry->get_value("quotaHomeBlock") // $def_quota{block}{home}; + my $quotaHomeFile = $entry->get_value("quotaHomeFile") // $def_quota{file}{home}; + my $quotaSgoinfreBlock = $entry->get_value("quotaSgoinfreBlock") // $def_quota{block}{sgoinfre}; + my $quotaSgoinfreFile = $entry->get_value("quotaSgoinfreFile") // $def_quota{file}{sgoinfre}; + + eval 'use Quota; 1'; + + if (Quota::setqlim($dev_quota{home}, $entry->get_value("uidNumber"), int(0.9 * $quotaHomeBlock), $quotaHomeBlock, int(0.9 * $quotaHomeFile), $quotaHomeFile, 1, 0) == 0 and + Quota::setqlim($dev_quota{sgoinfre}, $entry->get_value("uidNumber"), int(0.9 * $quotaSgoinfreBlock), $quotaSgoinfreBlock, int(0.9 * $quotaSgoinfreFile), $quotaSgoinfreFile, 1, 0) == 0) { + log(DONE, YELLOW, $login, RESET, "'s quota synchronized!"); } else { - log(ERROR, "An error occurs during quota synchronization:"); - Quota::strerr(); + log(ERROR, "An error occurs during quota synchronization: ", Quota::strerr()); return 2; } @@ -1332,43 +1352,208 @@ sub cmd_account_quota_sync($;$) sub cmd_sync_quota(@) { - my $ldap = LDAP::ldap_connect_anon(); - my $mesg = $ldap->search( - base => "ou=users,dc=acu,dc=epita,dc=fr", - filter => "(objectClass=labAccount)", - attrs => [ 'uid' ] - ); - $mesg->code && die $mesg->error; + eval 'use Quota; 1'; + + # Set root quota + Quota::setqlim($dev_quota{home}, 0, 0, 0, 0, 0, 1, 0); + Quota::setqlim($dev_quota{sgoinfre}, 0, 0, 0, 0, 0, 1, 0); + + my $ldap; + eval { + $ldap = LDAP::ldap_connect_anon(); + }; + log(ERROR, $@) if ($@); + + my @entries = LDAP::search_dns($ldap, "ou=users", "(objectClass=labAccount)", "uid"); $ldap->unbind or die ("couldn't disconnect correctly"); - for my $entry ($mesg->entries) { + for my $entry (@entries) { cmd_account_quota_sync($entry->get_value("uid"), 1); } + + Quota::sync($dev_quota{home}); + Quota::sync($dev_quota{sgoinfre}); } ###################################### # # -# QUOTA COMMAND # +# STRONG_AUTH COMMAND # # # ###################################### +sub cmd_strong_auth(@) +{ + my $subcmd = shift // "view"; + + if (! exists $cmds_strong_auth{$subcmd}) { + log(USAGE, "Unknown command for strong_auth: ". $subcmd); + return 1; + } + + return $cmds_strong_auth{$subcmd}(@_); +} + +sub get_no_strong_auth_user() +{ + my @faulty_users; + + my $ldap; + eval { + $ldap = LDAP::ldap_connect_anon(); + }; + log(ERROR, $@) if ($@); + + my @entries = LDAP::search_dns($ldap, "ou=users", "&(&(objectClass=labAccount)(!(homeDirectory=/dev/null)))(!(loginShell=/bin/false))", + 'uid', 'cn', 'mailAlias', 'homeDirectory', 'labService'); + + foreach my $entry (@entries) + { + my $home = $entry->get_value("homeDirectory"); + $home =~ s#^$wksHomePrefix#$nfsHomePrefix#; + my $token = $home . "/.google_authenticator"; + my $login = $entry->get_value("uid"); + + push @faulty_users, $entry if (! -f $token || -s $token < 100); + } + + $ldap->unbind or die ("couldn't disconnect correctly"); + + return @faulty_users; +} + +sub cmd_no_strong_auth_view(@) +{ + for my $entry (get_no_strong_auth_user()) + { + print $entry->get_value("uid"); + print " ", GREEN, "ACK", RESET if (grep { $_ eq "no-strong-auth" } $entry->get_value('labService')); + print "\n"; + } +} + +sub cmd_no_strong_auth_warn(@) +{ + for my $entry (get_no_strong_auth_user()) + { + next if (grep { $_ eq "no-strong-auth" } $entry->get_value('labService')); + + say $entry->get_value("uid"); + + my $body = "Bonjour ".$entry->get_value("cn").", + +Vous n'avez pas activé l'authentification forte pour SSH. + +Pour connaître la marche à suivre pour l'activer, consultez : +https://www.acu.epita.fr/wiki/index.php?title=Ssh_double_factor_auth + +Merci de rectifier la situation au plus vite ou votre compte sera mis +en suspens. + +Cordialement, + +PS: Ce message est généré automatiquement, les roots sont en copie. + Pour toute demande, merci de faire un ticket à admin\@acu.epita.fr + +-- +Les roots ACU"; + + # create the message + eval "use Email::Sender::Simple qw(sendmail); 1"; + + my $mail = Email::MIME->create( + header_str => [ + From => "Roots assistants ", + To => $entry->get_value("mailAlias"), + Cc => 'Roots assistants ', + Subject => "[PILA][AUTH-FORTE] Authentification forte SSH non active" + ], + attributes => { + encoding => 'quoted-printable', + charset => 'utf-8', + format => 'flowed', + }, + body_str => $body, + ); + sendmail($mail); + } +} + +sub cmd_no_strong_auth_close(@) +{ + for my $entry (get_no_strong_auth_user()) + { + next if (grep { $_ eq "no-strong-auth" } $entry->get_value('labService')); + + say $entry->get_value("uid"); + + my $body = "Bonjour ".$entry->get_value("cn").", + +Après plusieurs relance de notre part, vous n'avez toujours pas activé +l'authentification forte pour SSH. Votre compte a donc été suspendu. + +Nous vous invitons à passer au laboratoire pour faire réactiver votre +compte. + +Cordialement, + +-- +Les roots ACU"; + + # create the message + eval "use Email::Sender::Simple qw(sendmail); 1"; + + my $mail = Email::MIME->create( + header_str => [ + From => "Roots assistants ", + To => $entry->get_value("mailAlias"), + Cc => 'Roots assistants ', + Subject => "[PILA][ACCES] Compte suspendu" + ], + attributes => { + encoding => 'quoted-printable', + charset => 'utf-8', + format => 'flowed', + }, + body_str => $body, + ); + sendmail($mail); + } +} + +###################################### +# # +# SSH_KEYS COMMAND # +# # +###################################### + +sub cmd_ssh_keys(@) +{ + my $subcmd = shift // "view"; + + if (! exists $cmds_ssh_keys{$subcmd}) { + log(USAGE, "Unknown command for ssh_keys: ". $subcmd); + return 1; + } + + return $cmds_ssh_keys{$subcmd}(@_); +} + sub get_ssh_keys_unprotected() { my %keys_unprotected = qw(); - my $ldap = LDAP::ldap_connect_anon(); - my $mesg = $ldap->search( - base => "ou=users,dc=acu,dc=epita,dc=fr", - filter => "(objectClass=posixAccount)", - attrs => ['uid','cn', 'homeDirectory'] - ); + my $ldap; + eval { + $ldap = LDAP::ldap_connect_anon(); + }; + log(ERROR, $@) if ($@); - $mesg->code && die $mesg->error; - $mesg->count > 0 || return -1; + my @entries = LDAP::search_dns($ldap, "ou=users", "&(objectClass=posixAccount)(!(homeDirectory=/dev/null))", + 'uid', 'cn', 'homeDirectory'); - foreach my $entry ($mesg->sorted('uid')) + foreach my $entry (@entries) { my $home = $entry->get_value("homeDirectory"); $home =~ s#^$wksHomePrefix#$nfsHomePrefix#; @@ -1379,7 +1564,8 @@ sub get_ssh_keys_unprotected() { my $process_file = sub() { my $file = $_; - if (-f $file) { + if (-f $file) + { open my $fh, '<', $file or die $!; my @lines = <$fh>; close $fh; @@ -1387,12 +1573,9 @@ sub get_ssh_keys_unprotected() { if (! grep { chomp; $_ =~ /ENCRYPTED/ } @lines ) { - if (!exists $keys_unprotected{$login}) - { + if (!exists $keys_unprotected{$login}) { $keys_unprotected{$login} = [$file]; - } - else - { + } else { push(@{$keys_unprotected{$login}}, $file); } } @@ -1414,20 +1597,20 @@ sub cmd_ssh_keys_without_passphrase_generic(@) my $func = shift; my %keys_unprotected = get_ssh_keys_unprotected(); - my $ldap = LDAP::ldap_connect_anon(); + my $ldap; + eval { + $ldap = LDAP::ldap_connect_anon(); + }; + log(ERROR, $@) if ($@); foreach my $login (keys %keys_unprotected) { - my $mesg = $ldap->search( - base => "ou=users,dc=acu,dc=epita,dc=fr", - filter => "uid=$login", - attrs => [ 'uid', 'cn', 'mailAlias' ] - ); - - $mesg->code && die $mesg->error; - $mesg->count > 0 || return -1; - - my $entry = $mesg->entry(0); + my $dn; + eval { + $dn = LDAP::search_dn($ldap, "ou=users", "(uid=$login)"); + }; + log(ERROR, $@) if ($@); + my $entry = LDAP::get_dn($ldap, $dn, 'uid', 'cn', 'mailAlias'); # Apply func &$func($entry, \@{$keys_unprotected{$login}}); @@ -1437,17 +1620,16 @@ sub cmd_ssh_keys_without_passphrase_generic(@) } # list unprotected keys -sub cmd_ssh_keys_without_passphrase_show(@) +sub cmd_ssh_keys_without_passphrase_view(@) { my $process = sub() { my $entry = shift; my $keys = shift; # Display - print $entry->get_value("cn").":\n"; - foreach my $key (@$keys) - { - print " * $key\n"; + say $entry->get_value("cn"), ":"; + for my $key (@$keys) { + say " * $key"; } print "\n"; }; @@ -1463,16 +1645,13 @@ sub cmd_ssh_keys_without_passphrase_warn(@) my $keys = shift; # Display - print $entry->get_value("uid")."\n"; - - # create the message - #use Mail::Internet; + say $entry->get_value("uid"); my $body = "Bonjour ".$entry->get_value("cn").", -Un outil automatique a découvert une clé sans passphrase sur votre compte +Un outil automatique a découvert une clef sans passphrase sur votre compte du laboratoire. Il est impératif de mettre une passphrase chiffrant votre -clé pour des raisons de sécurité. +clef pour des raisons de sécurité. Les clefs non protégées sont les suivantes :\n"; foreach my $key (@$keys) @@ -1491,16 +1670,27 @@ Cordialement, PS: Ce message est généré automatiquement, les roots sont en copie. Pour toute demande, merci de faire un ticket à admin\@acu.epita.fr --- +-- Les roots ACU"; - #my $email = Mail::Internet->new(); - #$email->body($body); - #$email->add( "To", $entry->get_value("mailAlias") ); - #$email->add( "Cc", "" ); - #$email->add( "From", "Roots assistants " ); - #$email->add( "Subject", "[LAB][SSH-PASSPHRASE] Clef SSH non protégée" ); - #$email->send(); + # create the message + eval "use Email::Sender::Simple qw(sendmail); 1"; + + my $mail = Email::MIME->create( + header_str => [ + From => "Roots assistants ", + To => $entry->get_value("mailAlias"), + Cc => 'Roots assistants ', + Subject => "[PILA][SSH-KEY] Clef SSH non protégée" + ], + attributes => { + encoding => 'quoted-printable', + charset => 'utf-8', + format => 'flowed', + }, + body_str => $body, + ); + sendmail($mail); }; cmd_ssh_keys_without_passphrase_generic(\&$process); @@ -1514,10 +1704,9 @@ sub cmd_ssh_keys_without_passphrase_remove(@) my $keys = shift; # Display - print $entry->get_value("uid")."\n"; + say $entry->get_value("uid"); # create the message - use Email::MIME; my $body = "Bonjour ".$entry->get_value("cn").", Un outil automatique a découvert une clef sans passphrase sur votre @@ -1529,7 +1718,7 @@ d Pour information, voici l'empreinte de chacune des clefs supprimée :\n"; foreach my $key (@$keys) { - open (FNGR, "ssh-keygen -l -f '$key' | cut -d ' ' -f 2"); + open (FNGR, "ssh-keygen -l -f '$key' | cut -d ' ' -f 2 |"); my $fingerprint = ; chomp $fingerprint; close (FNGR); @@ -1537,7 +1726,7 @@ Pour information, voici l'empreinte de chacune des clefs supprim unlink($key); $key =~ s#^$nfsHomePrefix#$wksHomePrefix#; - $body .= " * $key: $fingerprint\n"; + $body .= " - $key: $fingerprint\n"; } $body .= "\n Contacter les roots pour faire reouvrir votre compte. @@ -1547,16 +1736,26 @@ Cordialement, PS: Ce message est généré automatiquement, les roots sont en copie. Pour toute demande, merci de faire un ticket à admin\@acu.epita.fr --- +-- Les roots ACU"; - #my $email = Mail::Internet->new(); - #$email->body($body); - #$email->add( "To", $entry->get_value("mailAlias") ); - #$email->add( "Cc", "" ); - #$email->add( "From", "Roots assistants " ); - #$email->add( "Subject", "[LAB][SSH-PASSPHRASE] Clef SSH non protégée supprimée" ); - #$email->send(); + eval "use Email::Sender::Simple qw(sendmail); 1"; + + my $mail = Email::MIME->create( + header_str => [ + From => "Roots assistants ", + To => $entry->get_value("mailAlias"), + Cc => 'Roots assistants ', + Subject => "[PILA][SSH-KEY] Clef SSH non protégée supprimée" + ], + attributes => { + encoding => 'quoted-printable', + charset => 'utf-8', + format => 'flowed', + }, + body_str => $body, + ); + sendmail($mail); }; cmd_ssh_keys_without_passphrase_generic(\&$process); @@ -1589,6 +1788,10 @@ elsif ($cmd eq "-q" or $cmd eq "--quiet") { $ACU::Log::display_level = 6; $cmd = shift; } +elsif ($cmd eq "-y" or $cmd eq "--yes") { + $noconfirm = 1; + $cmd = shift; +} $ACU::Log::fatal_error = 1; $ACU::Log::fatal_warn = 0; @@ -1616,41 +1819,85 @@ B I [arguments] Manage the account . -B I [arguments] +B I [year] [arguments] - Manage the group + Manage the intranet group for the current or given year. B I Display this screen. +B I [year] [arguments] + + Manage the intranet role for the current or given year. + +B [view|warn|remove] + + Search for users with SSH keys without passphrase. Warn the users and + remove them if requested. + +B [view|warn|close] + + Search for users without strong authentication. Warn the users and + close its account if requested. + +B + + Sync the quota of all users. + +B I [arguments] + + Manage the system group . + B I [year] - Set or display the current year. + Display or set the current year. =head1 ACCOUNT COMMANDS -B [I] +B [I [I [I [...]]]] Display information about . can be a globbing string. + If are given, display only those attributes. + B I [nopass|password|passgen] This is used to create a new Epita account, base for intra and/or lab account. Promo for professor are professors, other people are guests. -B I +B I - This is used to erase the userPassword. + Give rights to the user to access the intranet. + +B I + + Give rights to the user to access intern systems of the laboratory (SSH, Unix, ...) + +B I + + Give rights to the user to receive e-mails. + +B I [list|add|del|flush] [string] + + This is used to manage e-mail aliases. B I This is used to close an existing account. +B I [new-mail] + + This is used to display, or change if [new-mail] is given, the account contact adress. + +B I [new-name] + + This is used to display, or change if [new-name] is given, the account common name. + B I This is used to reopen a previously closed account. @@ -1659,6 +1906,10 @@ B I This is used to change default shell for an existing accout. +B I + + This is used to erase the user password. + B I [nb_char] This is used to set user password. Generated by pwgen. @@ -1671,45 +1922,50 @@ B I [password] B I [new] - This is used to get user email (to which are forwarded his emails) if - 'new' is empty, and to change it if 'new' is given. + This is used to get user email (to which are forwarded its emails) if + 'new' is empty, and to change it if the 'new' adress is given. -B I +B I [list|add|del|flush] [string] - List accounts: with access to the PILA, without, with access to - services. + Manage services associated to the . -B I +B I [list|add|del|flush] [string] - Display information about a login. - -B I - - Remove all services associated to a login. + Manage rights associated to the . =head1 GROUP COMMANDS -B I [group] +B [I] [I [I [I [...]]]] - This is used to list groups available on the PIL or to list the members - of the specified group. + This is used to view general informations on the group-name. If attributes are given, display only those one. -B I +B I I - This is used to add a user to a posix group. + This is used to create a new intra group into the OU . -B I +B I - This is used to create a posix group. + This is used to create a new POSIX group. -B I +B [I] I [list|add|del|flush] [string] - This is used to remove a user from a posix group. + This is used to manage group members. -B I +B [I] I [list|add|del|flush] [string] - This is used to delete a posix group. + This is used to manage rights on the group. + +B [I] I + + This is used to delete a group. + + +=head1 LIST COMMANDS + +B I accounts [year] [service] + + List accounts: with access to the PILA, without, with access to services, with a POSIX account, with an intra accout. =head1 QUOTA COMMANDS @@ -1723,31 +1979,11 @@ B I Set the quota of someone. Volume is home/sgoinfre and type is block/file. -=head1 SERVICE COMMANDS - -B I - - This is used to add a service to a user. - -B I - - This is used to remove a service from a user. - - -=head1 SSH_KEYS_WITHOUT_PASSPHRASE COMMANDS - -B I - - Search for users with SSH keys without passphrase. Warn the users and - remove them if requested. - =head1 DESCRIPTION -B is a tool developed to replace ancient perl scripts used to manage -accounts, and some other stuff. -The goal was to give an unique tool with meaningful commands to perform -usual operations. lpt is born from ipt. +B is a tool developed to replace old perl scripts used to manage accounts, and some other stuff. +The goal was to give an unique tool with meaningful commands to perform usual operations. lpt is born from ipt. =head1 AUTHORS @@ -1765,18 +2001,11 @@ Modified by JB et Antoine >, root@acu 2012 Modified by megra >, root@acu 2013 : added tons of features :) -Strongly modified by nemunaire & nicolas, root@acu 2014 +Strongly modified by nemunaire >, root@acu 2014, introducing Lab 2.0! =head1 VERSION -This is B version 1.1. - -=head1 TODO - -Tons of stuff : - * delete account - * group delete - * ... +This is B version 2.0. =head1 BUGS From 27f7b7c9ce9b1ac55bd81437a48a0bd36034e747 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 30 Oct 2013 02:36:12 +0100 Subject: [PATCH 194/364] Fix screen launch on FreeBSD --- process/launch.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/process/launch.sh b/process/launch.sh index 5e00e1c..9b0d6c8 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -6,7 +6,7 @@ GREP='/usr/bin/env grep -E' SCREEN='/usr/bin/env screen' SED='/usr/bin/env sed -E' if [ `uname -s` = "FreeBSD" ]; then - SU='/usr/bin/env su' + SU="/usr/bin/env su" else SU='/usr/bin/env su -s /bin/sh' fi @@ -24,7 +24,12 @@ launch_screen() CMD=". $TMP; ssh-add -l; echo; $CMD" fi - echo "$SCREEN -S '$1' -d -m bash -c '$CMD'" | $SU intradmin + if [ $HOSTNAME == "ksh" ] + then + $SCREEN -S "$1" -d -m sh -c "$CMD" + else + echo "$SCREEN -S '$1' -d -m sh -c '$CMD'" | $SU intradmin + fi if [ -f "$TMP" ] then From 1f61b7a144f939f991c5ae7fe0f1db0731c07bfb Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 30 Oct 2013 02:38:50 +0100 Subject: [PATCH 195/364] Interact with new intranet group API --- ACU/API/Base.pm | 78 +++++++++++++++++++++++++++++++++ ACU/API/Projects.pm | 22 ++++++++++ commands/project/gen_git_str.pl | 35 +++++++++++++++ 3 files changed, 135 insertions(+) create mode 100644 commands/project/gen_git_str.pl diff --git a/ACU/API/Base.pm b/ACU/API/Base.pm index 0fc698b..72d860e 100644 --- a/ACU/API/Base.pm +++ b/ACU/API/Base.pm @@ -46,6 +46,7 @@ sub parse($$) $sax_handler = ProjectHandler->new($parsed); } $sax_handler = ProjectMemberHandler->new($parsed) if ($mod eq "ProjectMemberHandler"); + $sax_handler = ProjectGroupHandler->new($parsed) if ($mod eq "ProjectGroupHandler"); my $parser = XML::SAX::ParserFactory->parser( Handler => $sax_handler ); @@ -234,4 +235,81 @@ sub end_element } } + +package ProjectGroupHandler; + +use v5.10.1; +use strict; +use warnings; + +sub new ($$) +{ + my $class = shift; + my $self = { + parsed => shift, + inStd => 0, + inResult => 0, + lastGroup => {}, + values => "" + }; + + bless $self, $class; + + return $self; +} + +sub start_element +{ + my ($self, $element) = @_; + + if ($element->{Name} eq "result") { + $self->{parsed}{result} = $self->{values}; + $self->{inResult} = 0; + $self->{values} = ""; + } + elsif ($element->{Name} eq "student") + { + $self->{inStd} = 1; + push @{ $self->{lastGroup}{stds} }, { + id => $element->{Attributes}{"{}id"}{Value}, + chief => $element->{Attributes}{"{}chief"}{Value}, + login => "", + }; + } + elsif ($element->{Name} eq "group") + { + $self->{lastGroup}{id} = $element->{Attributes}{"{}id"}{Value}; + $self->{lastGroup}{stds} = []; + } +} + +sub characters +{ + my ($self, $characters) = @_; + + if ($self->{inStd}) { + $self->{values} .= $characters->{Data}; + } +} + +sub end_element +{ + my ($self, $element) = @_; + + if ($element->{Name} eq "group") + { + push @{ $self->{parsed}{groups} }, $self->{lastGroup}; + $self->{lastGroup} = {}; + + $self->{inStd} = 0; + $self->{values} = ""; + } + elsif ($element->{Name} eq "student") + { + my $size = @{ $self->{lastGroup}{stds} }; + (@{ $self->{lastGroup}{stds} })[$size - 1]{login} = $self->{values}; + $self->{values} = ""; + } +} + 1; diff --git a/ACU/API/Projects.pm b/ACU/API/Projects.pm index 02f61fa..abb0adf 100644 --- a/ACU/API/Projects.pm +++ b/ACU/API/Projects.pm @@ -76,6 +76,28 @@ sub get_users($;$) return $res; } +sub get_groups($;$) +{ + my $project_name = shift; + my $year = shift; + + my $url; + if ($year) { + $url = "projects/groups/groups/$project_name/$year.xml"; + } else { + $url = "projects/groups/groups/$project_name.xml"; + } + + my $res = API::Base::get('ProjectGroupHandler', $url); + + #TODO: uncomment-me + #if ($res->{result} ne '0') { +# croak "Erreur durant la récupération : " . $res->{message}; + #} + + return $res; +} + sub add_grades($;$) { my %data = ( diff --git a/commands/project/gen_git_str.pl b/commands/project/gen_git_str.pl new file mode 100644 index 0000000..0a67688 --- /dev/null +++ b/commands/project/gen_git_str.pl @@ -0,0 +1,35 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use v5.10; +use Data::Dumper; + +use ACU::API::Projects; + +my $projid = $ARGV[0]; +my $year = $ARGV[1] // LDAP::get_year; + +my $res = API::Projects::get_groups($projid, $year); +my $tag = "rendu-1"; + +map { + my $chief; + + # First, found the chief + for my $member (@{ $_->{stds} }) + { + if ($member->{chief} eq "true" or $member->{chief} eq "1" or $member->{chief} eq "chief") + { + $chief = $member; + last; + } + } + + say "repo $year/$projid/$chief->{login}"; + print ' RW+ = @admins'; + for my $member (@{ $_->{stds} }) { + print ' '.$member->{login}; + } + say "\n R = \@chefs \@resp-$year-$projid"; +} @{ $res->{groups} }; From cda080ce72107ef7b2fe52ac1b32bb729c480d2b Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 30 Oct 2013 02:46:17 +0100 Subject: [PATCH 196/364] Prefer use of require instead of eval --- utils/lpt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/utils/lpt b/utils/lpt index 70c9d11..a255a8a 100755 --- a/utils/lpt +++ b/utils/lpt @@ -1460,7 +1460,7 @@ PS: Ce message est g Les roots ACU"; # create the message - eval "use Email::Sender::Simple qw(sendmail); 1"; + require Email::Sender::Simple qw(sendmail); my $mail = Email::MIME->create( header_str => [ @@ -1502,7 +1502,7 @@ Cordialement, Les roots ACU"; # create the message - eval "use Email::Sender::Simple qw(sendmail); 1"; + require Email::Sender::Simple qw(sendmail); my $mail = Email::MIME->create( header_str => [ @@ -1674,7 +1674,7 @@ PS: Ce message est g Les roots ACU"; # create the message - eval "use Email::Sender::Simple qw(sendmail); 1"; + require Email::Sender::Simple qw(sendmail); my $mail = Email::MIME->create( header_str => [ @@ -1739,7 +1739,7 @@ PS: Ce message est g -- Les roots ACU"; - eval "use Email::Sender::Simple qw(sendmail); 1"; + require Email::Sender::Simple qw(sendmail); my $mail = Email::MIME->create( header_str => [ From 24c6ed57e02639261a901890a7515234028b4df9 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 30 Oct 2013 03:17:32 +0100 Subject: [PATCH 197/364] New package to install --- commands/first-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/first-install.sh b/commands/first-install.sh index 2a7e95e..e09e5f5 100755 --- a/commands/first-install.sh +++ b/commands/first-install.sh @@ -1,7 +1,7 @@ #! /bin/bash # Install missing packages -DEB_PACKAGES_LIST="screen libnet-ldap-perl libxml-libxml-perl libgearman-client-perl libmailtools-perl libmail-sendmail-perl libdatetime-format-iso8601-perl libnet-ip-perl libsys-gamin-perl" +DEB_PACKAGES_LIST="screen libnet-ldap-perl libxml-libxml-perl libgearman-client-perl libmailtools-perl libmail-sendmail-perl libdatetime-format-iso8601-perl libnet-ip-perl libsys-gamin-perl libdigest-sha-perl" ARCH_PACKAGES_LIST="screen perl-io-socket-ssl perl-email-simple perl-email-mime perl-term-readkey perl-ldap perl-lwp-protocol-https perl-datetime-format-iso8601 perl-net-ip" # aur/perl-sys-gamin GENTOO_PACKAGES_LIST="app-misc/screen dev-perl/IO-Socket-SSL dev-perl/Email-Simple dev-perl/Email-MIME dev-perl/TermReadKey dev-perl/perl-ldap dev-perl/LWP-Protocol-https dev-perl/DateTime-Format-ISO8601 dev-perl/Net-IP" FBSD_PACKAGES_LIST="screen p5-IO-Socket-SSL p5-Email-Simple p5-Email-MIME p5-Term-ANSIColor p5-Term-ReadKey p5-LWP-Protocol-https p5-DateTime-Format-ISO8601 p5-Net-IP p5-Sys-Gamin" From e009942a7c4eaaedff599289d5897323cece9b96 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 30 Oct 2013 08:41:47 +0100 Subject: [PATCH 198/364] Fix quota use in lpt --- utils/lpt | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/utils/lpt b/utils/lpt index a255a8a..81731bb 100755 --- a/utils/lpt +++ b/utils/lpt @@ -1270,9 +1270,10 @@ sub cmd_account_quota_set($@) } my $nb; - if ($value =~ '([0-9]+)([MKGTmkgt]?)$') + + if ($value =~ '([0-9]+)([MKGTmkgt]?)') { - my $nb = $1; + $nb = $1; $nb *= 1024 if ($2 eq "K" or $2 eq "k"); $nb *= 1048576 if ($2 eq "M" or $2 eq "m"); $nb *= 1073741824 if ($2 eq "G" or $2 eq "g"); @@ -1460,7 +1461,7 @@ PS: Ce message est g Les roots ACU"; # create the message - require Email::Sender::Simple qw(sendmail); + require "Email::Sender::Simple"; my $mail = Email::MIME->create( header_str => [ @@ -1476,7 +1477,7 @@ Les roots ACU"; }, body_str => $body, ); - sendmail($mail); + Email::Sender::Simple::sendmail($mail); } } @@ -1502,7 +1503,7 @@ Cordialement, Les roots ACU"; # create the message - require Email::Sender::Simple qw(sendmail); + require "Email::Sender::Simple"; my $mail = Email::MIME->create( header_str => [ @@ -1518,7 +1519,7 @@ Les roots ACU"; }, body_str => $body, ); - sendmail($mail); + Email::Sender::Simple::sendmail($mail); } } @@ -1674,7 +1675,7 @@ PS: Ce message est g Les roots ACU"; # create the message - require Email::Sender::Simple qw(sendmail); + require "Email::Sender::Simple"; my $mail = Email::MIME->create( header_str => [ @@ -1690,7 +1691,7 @@ Les roots ACU"; }, body_str => $body, ); - sendmail($mail); + Email::Sender::Simple::sendmail($mail); }; cmd_ssh_keys_without_passphrase_generic(\&$process); @@ -1739,7 +1740,7 @@ PS: Ce message est g -- Les roots ACU"; - require Email::Sender::Simple qw(sendmail); + require "Email::Sender::Simple"; my $mail = Email::MIME->create( header_str => [ @@ -1755,7 +1756,7 @@ Les roots ACU"; }, body_str => $body, ); - sendmail($mail); + Email::Sender::Simple::sendmail($mail); }; cmd_ssh_keys_without_passphrase_generic(\&$process); From 784c7cfb556803c95c55486fda6264e9140a412b Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 30 Oct 2013 14:45:21 +0100 Subject: [PATCH 199/364] Last moulette_get --- process/files/intradata_get.pl | 26 ++++---- process/files/moulette_get.pl | 115 ++++++++++++++++++--------------- 2 files changed, 76 insertions(+), 65 deletions(-) diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index e077d58..7e1eae3 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -42,7 +42,7 @@ sub create_tree($$) croak "No directory for year $year. Ask a root to create it." if (! -d "$basedir/$year/"); if (! -e "$basedir/$year/$project_id/") { - mkdir "$basedir/$year/$project_id/"; + mkdir "$basedir/$year/$project_id/" or croak $!; } } @@ -57,7 +57,7 @@ sub grades_generate croak "No project_id given." if (! $project_id); if (! -e "$basedir/$year/$project_id/grades/") { - mkdir "$basedir/$year/$project_id/grades/"; + mkdir "$basedir/$year/$project_id/grades/" or croak $!; } log DEBUG, "Generate list of students"; @@ -149,10 +149,10 @@ sub grades_new_bonus croak "No project_id given" if (! $project_id); if (! -e "$basedir/$year/$project_id/traces/") { - mkdir "$basedir/$year/$project_id/traces/"; + mkdir "$basedir/$year/$project_id/traces/" or croak $!; } if (! -e "$basedir/$year/$project_id/traces/bonus/") { - mkdir "$basedir/$year/$project_id/traces/bonus/"; + mkdir "$basedir/$year/$project_id/traces/bonus/" or croak $!; } for my $kfile (keys %{ $args->{files} }) @@ -251,19 +251,19 @@ sub update_defense log INFO, "Update $year/$project_id/defenses/$defense_id.xml"; if (! -e "$basedir/$year/$project_id/defenses/") { - mkdir "$basedir/$year/$project_id/defenses/"; + mkdir "$basedir/$year/$project_id/defenses/" or croak $!; } if (! -e "$basedir/$year/$project_id/traces/") { - mkdir "$basedir/$year/$project_id/traces/"; + mkdir "$basedir/$year/$project_id/traces/" or croak $!; } if (! -e "$basedir/$year/$project_id/traces/defense_$defense_id/") { - mkdir "$basedir/$year/$project_id/traces/defense_$defense_id/"; + mkdir "$basedir/$year/$project_id/traces/defense_$defense_id/" or croak $!; my ($login, $pass, $uid, $gid) = getpwnam("www-data"); - chown $uid, $gid, "$basedir/$year/$project_id/traces/defense_$defense_id/"; - chmod 0775, "$basedir/$year/$project_id/traces/defense_$defense_id/"; + chown $uid, $gid, "$basedir/$year/$project_id/traces/defense_$defense_id/" or croak $!; + chmod 0775, "$basedir/$year/$project_id/traces/defense_$defense_id/" or croak $!; } - open my $out, ">", "$basedir/$year/$project_id/defenses/$defense_id.xml"; + open my $out, ">", "$basedir/$year/$project_id/defenses/$defense_id.xml" or croak $!; print $out $defense; close $out; @@ -322,11 +322,11 @@ sub update_trace log INFO, "Update $year/$project_id/traces/$rendu_id/$login.xml"; if (! -e "$basedir/$year/$project_id/traces/") { - mkdir "$basedir/$year/$project_id/traces/"; + mkdir "$basedir/$year/$project_id/traces/" or croak $!; } if (! -e "$basedir/$year/$project_id/traces/$rendu_id/") { - mkdir "$basedir/$year/$project_id/traces/$rendu_id/"; - chmod 0755, "$basedir/$year/$project_id/traces/$rendu_id/"; + mkdir "$basedir/$year/$project_id/traces/$rendu_id/" or croak $!; + chmod 0755, "$basedir/$year/$project_id/traces/$rendu_id/" or croak $!; } open my $out, ">", "$basedir/$year/$project_id/traces/$rendu_id/$login.xml" or croak("Unable to write to $rendu_id/$login.xml"); diff --git a/process/files/moulette_get.pl b/process/files/moulette_get.pl index c4e7133..125b757 100644 --- a/process/files/moulette_get.pl +++ b/process/files/moulette_get.pl @@ -4,6 +4,7 @@ use v5.10.1; use strict; use warnings; use threads; +use threads::shared; use Carp; use File::Basename; use File::Copy; @@ -22,8 +23,7 @@ my %actions = ( "moulette" => \&moulette, ); -my $fm = new Sys::Gamin; -my %project_paths; +my %monitored_dir = (); sub jail_exec { @@ -46,7 +46,7 @@ sub prepare_dir my $project_id = shift; my $rendu = shift; - my @dirs = ("/data/work/$year-$project_id-$rendu/", "/data/output/$year-$project_id-$rendu/"); + my @dirs = ("/data/work/$year-$project_id-$rendu/", "/data/output/$year-$project_id-$rendu/", "/data/files/$year-$project_id-$rendu/"); for my $dir (@dirs) { @@ -82,11 +82,13 @@ sub receive_ref jail_exec("gmake -C $tempdir/ref/ fact"); croak "An error occurs while making the testsuite" if ($?); - my $destdir = ( prepare_dir($year, $project_id, $rendu) )[0]; + my $destdir = ( prepare_dir($year, $project_id, $rendu) )[2]; copy("$tempdir/ref/ref.ff", "$destdir/ref.ff") or croak "An error occurs while coping ref.ff: $!"; # Clean remove_tree($tempdir); + + run_moulette($project_id, $year, $rendu); } sub receive_std @@ -107,7 +109,7 @@ sub receive_std croak "An error occurs while extracting the tarball" if ($?); - my $destdir = ( prepare_dir($year, $project_id, $rendu) )[0]; + my $destdir = ( prepare_dir($year, $project_id, $rendu) )[2]; fact_exec("package create '$tempdir' '$destdir/$login.ff'", $destdir); croak "Cannot create $login.ff" if ($?); chmod 0666, "$destdir/$login.ff"; @@ -139,7 +141,7 @@ sub create_testsuite jail_exec("gmake -C $tempdir/tests/"); croak "An error occurs while making the testsuite" if ($?); - my $destdir = ( prepare_dir($year, $project_id, $rendu) )[0]; + my $destdir = ( prepare_dir($year, $project_id, $rendu) )[2]; copy("$tempdir/tests/tests.ff", "$destdir/tests.ff") or croak "An error occurs while coping the testsuite: $!"; copy("$tempdir/tests/test.ft", "$destdir/test.ft") or croak "An error occurs while coping test.ft: $!"; chmod 0660, "$destdir/tests.ff"; @@ -158,17 +160,15 @@ sub run_moulette my $rendu = shift; my @logins = @_; - #TODO: find the right test dir, '' is most generic one - my $testdir = ( prepare_dir($year, $project_id, "") )[0]; - my ($submitdir, $outputdir) = prepare_dir($year, $project_id, $rendu); + my ($workdir, $outputdir, $filesdir) = prepare_dir($year, $project_id, $rendu); if ($#logins == -1) { # Get all submissions - opendir(my $dh, $submitdir) or die "Can't list files in $submitdir: $!"; + opendir(my $dh, $filesdir) or die "Can't list files in $filesdir: $!"; while (readdir($dh)) { - if (/([a-zA-Z0-9_-]+).ff$/ && -f "$submitdir/$_" && ! /^tests\.ff$/) { + if (/([a-zA-Z0-9_-]+).ff$/ && -f "$filesdir/$_" && ! /^tests\.ff$/) { push @logins, $1; } } @@ -178,25 +178,19 @@ sub run_moulette for my $login (@logins) { my $fhin; - if (-f "$testdir/$login.ft") { - open $fhin, "<", "$testdir/$login.ft" or croak "Unable to open $testdir/$login.ft: $!"; - } elsif (-f "$testdir/test.ft") { - open $fhin, "<", "$testdir/test.ft" or croak "Unable to open $testdir/test.ft: $!"; - } - #TODO: remove this - elsif (-f "$submit/test.ft") { - open $fhin, "<", "$testdir/test.ft" or croak "Unable to open $testdir/test.ft: $!"; + if (-f "$filesdir/test.ft") { + open $fhin, "<", "$filesdir/test.ft" or croak "Unable to open $filesdir/test.ft: $!"; } if ($fhin) { - open my $fhout, ">", "$submitdir/$login.ft" or croak "Unable to update $submitdir/$login.ft file: $!"; + open my $fhout, ">", "$workdir/$login.ft" or croak "Unable to update $workdir/$login.ft file: $!"; while (<$fhin>) { $_ =~ s/#LOGIN_X/$login/g; $_ =~ s%#GLOBAL%/data/global/%g; - $_ =~ s/#PROJECT/$testdir/g; - $_ =~ s/#SUBMIT/$submitdir/g; + $_ =~ s/#PROJECT/$filesdir/g; + $_ =~ s/#SUBMIT/$workdir/g; $_ =~ s/#OUTPUT/$outputdir/g; print $fhout $_; } @@ -204,20 +198,19 @@ sub run_moulette close $fhout; } - croak "Unable to find a relevant $login.ft, abort moulette start." if (! -f "$submitdir/$login.ft"); + copy("$filesdir/$login.ff", "$workdir/$login.ff") or croak "Cannont copy $login.ff"; - log WARN, "There is no ref for $project_id $rendu" if (! -f "$testdir/ref.ff"); - log WARN, "There is no $login.ff for $project_id $rendu" if (! -f "$submitdir/$login.ff"); + croak "Unable to find a relevant $login.ft, abort moulette start." if (! -f "$workdir/$login.ft"); - # Monitor the trace creation - if (! grep { $outputdir } %project_paths) - { - $project_paths{$outputdir} = { "id" => $project_id, "year" => $year, "rendu" => $rendu }; - $fm->monitor($outputdir); - } + log WARN, "There is no ref for $project_id $rendu" if (! -f "$filesdir/ref.ff"); + log WARN, "There is no $login.ff for $project_id $rendu" if (! -f "$workdir/$login.ff"); - log INFO, "$submitdir/$login append to Fact manager"; - fact_exec("system manager $submitdir/$login.ft", $submitdir); + unlink "$outputdir/$login.xml" if ( -f "$outputdir/$login.xml"); + + monitor_dir($outputdir, $project_id, $year, $rendu); + + log INFO, "$workdir/$login.ft append to Fact manager"; + fact_exec("system manager $workdir/$login.ft", $workdir); log ERROR, "An error occurs while starting tests for $login on $year-$project_id-$rendu" if ($?); } @@ -252,7 +245,9 @@ sub trace_send my $path = shift; my $filename = shift; my $login = shift; - my %infos = %{ $project_paths{ $path } }; + my $id = shift; + my $year = shift; + my $rendu = shift; return if (! -f "$path/$filename"); @@ -268,9 +263,9 @@ sub trace_send "intradata_get", { "type" => "trace", "action" => "update", - "id" => $infos{id}, - "year" => $infos{year}, - "rendu" => $infos{rendu}, + "id" => $id, + "year" => $year, + "rendu" => $rendu, "login" => $login }, { "$login.xml" => $file_content }, 1 @@ -280,25 +275,42 @@ sub trace_send unlink "$path/$filename"; } -sub monitor_traces -{ - my $event = shift; - - log DEBUG, "Pathname: ".$event->filename." Event: ".$event->type." Where: ".$fm->which($event); - - if (($event->type eq "create" || $event->type eq "change" || $event->type eq "exist") && - $event->filename =~ /([^\/\\]+)\.xml$/ && - grep { $fm->which($event) } %project_paths) - { - trace_send($fm->which($event), $event->filename, $1); - } -} - sub monitor_start { + my $dir = shift; + my $id = shift; + my $year = shift; + my $rendu = shift; + my $fm = new Sys::Gamin; + + log INFO, "Monitoring $dir"; + $fm->monitor($dir); + while (1) { + my $event=$fm->next_event; + if (($event->type eq "create" || $event->type eq "change" || $event->type eq "exist") && + $event->filename =~ /([^\/\\]+)\.xml$/ ) { + my $login = $event->filename; + $login =~ s/\.xml$//; + trace_send($dir, $event->filename, $login, $id, $year, $rendu); + } + + } + monitor_traces( $fm->next_event ) while (1); } +sub monitor_dir +{ + my $dir = shift; + my $id = shift; + my $year = shift; + my $rendu = shift; + + return if (exists ($monitored_dir{$dir})); + + $monitored_dir{$dir} = threads->create(\&monitor_start, $dir, $id, $year, $rendu); +} + sub process_get { my ($given_args, $args) = @_; @@ -321,5 +333,4 @@ sub process_get return "Ok"; } -threads->create('monitor_start'); Process::register("moulette_get", \&process_get); From 67f5f78f857cb1567e7566bd0640a4c46f854c90 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 30 Oct 2013 14:51:02 +0100 Subject: [PATCH 200/364] require QUota --- utils/lpt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/utils/lpt b/utils/lpt index 81731bb..6383109 100755 --- a/utils/lpt +++ b/utils/lpt @@ -1187,7 +1187,7 @@ sub cmd_account_quota($@) return 1; } - cmd_account_quota_sync($login, @_); + cmd_account_quota_sync($login, 0); } else { cmd_account_quota_set($login, $action, @_); @@ -1330,7 +1330,7 @@ sub cmd_account_quota_sync($;$) my $quotaSgoinfreBlock = $entry->get_value("quotaSgoinfreBlock") // $def_quota{block}{sgoinfre}; my $quotaSgoinfreFile = $entry->get_value("quotaSgoinfreFile") // $def_quota{file}{sgoinfre}; - eval 'use Quota; 1'; + require "Quota"; if (Quota::setqlim($dev_quota{home}, $entry->get_value("uidNumber"), int(0.9 * $quotaHomeBlock), $quotaHomeBlock, int(0.9 * $quotaHomeFile), $quotaHomeFile, 1, 0) == 0 and Quota::setqlim($dev_quota{sgoinfre}, $entry->get_value("uidNumber"), int(0.9 * $quotaSgoinfreBlock), $quotaSgoinfreBlock, int(0.9 * $quotaSgoinfreFile), $quotaSgoinfreFile, 1, 0) == 0) { @@ -1343,7 +1343,8 @@ sub cmd_account_quota_sync($;$) $ldap->unbind or die ("couldn't disconnect correctly"); - if (!$nosync) { + if (!$nosync) + { Quota::sync($dev_quota{home}); Quota::sync($dev_quota{sgoinfre}); } @@ -1353,7 +1354,7 @@ sub cmd_account_quota_sync($;$) sub cmd_sync_quota(@) { - eval 'use Quota; 1'; + require "Quota"; # Set root quota Quota::setqlim($dev_quota{home}, 0, 0, 0, 0, 0, 1, 0); From e327bf0c808472932208fcc82368c4ce807c4cef Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 30 Oct 2013 17:10:36 +0100 Subject: [PATCH 201/364] Print 0 instead of nothing --- process/projects/get_csv.pl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/process/projects/get_csv.pl b/process/projects/get_csv.pl index 0172e34..33586b2 100644 --- a/process/projects/get_csv.pl +++ b/process/projects/get_csv.pl @@ -82,7 +82,10 @@ sub process { my $g = shift @ugrades; $out .= ","; - $out .= $g if ($g && $g ne $header); + if ($g && $g ne $header) + $out .= $g; + else + $out .= "0"; } $out .= "\n"; } From d44ffa71533f0ca050e0fc181f00a73ad34a5168 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 30 Oct 2013 17:14:41 +0100 Subject: [PATCH 202/364] Fix launch on GNU/Linux --- process/launch.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/launch.sh b/process/launch.sh index 9b0d6c8..84796de 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -24,7 +24,7 @@ launch_screen() CMD=". $TMP; ssh-add -l; echo; $CMD" fi - if [ $HOSTNAME == "ksh" ] + if [ "$HOSTNAME" = "ksh" ] then $SCREEN -S "$1" -d -m sh -c "$CMD" else From 80d3352b78b735b4478fd362df2149ce548c3804 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 30 Oct 2013 17:19:31 +0100 Subject: [PATCH 203/364] Fix 0 --- process/projects/get_csv.pl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/process/projects/get_csv.pl b/process/projects/get_csv.pl index 33586b2..3626b2b 100644 --- a/process/projects/get_csv.pl +++ b/process/projects/get_csv.pl @@ -82,10 +82,11 @@ sub process { my $g = shift @ugrades; $out .= ","; - if ($g && $g ne $header) + if ($g && $g ne $header) { $out .= $g; - else + } else { $out .= "0"; + } } $out .= "\n"; } From ae330ab897b322490b73121346522f39269bf181 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 31 Oct 2013 16:15:27 +0100 Subject: [PATCH 204/364] Fix multiple inclusion of Email::Sender::Simple --- utils/lpt | 43 +++++++++++-------------------------------- 1 file changed, 11 insertions(+), 32 deletions(-) diff --git a/utils/lpt b/utils/lpt index 6383109..e760ed0 100755 --- a/utils/lpt +++ b/utils/lpt @@ -1437,6 +1437,8 @@ sub cmd_no_strong_auth_view(@) sub cmd_no_strong_auth_warn(@) { + require "Email::Sender::Simple"; + for my $entry (get_no_strong_auth_user()) { next if (grep { $_ eq "no-strong-auth" } $entry->get_value('labService')); @@ -1455,15 +1457,12 @@ en suspens. Cordialement, -PS: Ce message est généré automatiquement, les roots sont en copie. - Pour toute demande, merci de faire un ticket à admin\@acu.epita.fr +P.-S. : Ce message est généré automatiquement, les roots sont en copie. + Pour toute demande, merci de faire un ticket à admin\@acu.epita.fr -- Les roots ACU"; - # create the message - require "Email::Sender::Simple"; - my $mail = Email::MIME->create( header_str => [ From => "Roots assistants ", @@ -1471,11 +1470,6 @@ Les roots ACU"; Cc => 'Roots assistants ', Subject => "[PILA][AUTH-FORTE] Authentification forte SSH non active" ], - attributes => { - encoding => 'quoted-printable', - charset => 'utf-8', - format => 'flowed', - }, body_str => $body, ); Email::Sender::Simple::sendmail($mail); @@ -1484,6 +1478,8 @@ Les roots ACU"; sub cmd_no_strong_auth_close(@) { + require "Email::Sender::Simple"; + for my $entry (get_no_strong_auth_user()) { next if (grep { $_ eq "no-strong-auth" } $entry->get_value('labService')); @@ -1492,7 +1488,7 @@ sub cmd_no_strong_auth_close(@) my $body = "Bonjour ".$entry->get_value("cn").", -Après plusieurs relance de notre part, vous n'avez toujours pas activé +Après plusieurs relances de notre part, vous n'avez toujours pas activé l'authentification forte pour SSH. Votre compte a donc été suspendu. Nous vous invitons à passer au laboratoire pour faire réactiver votre @@ -1504,8 +1500,6 @@ Cordialement, Les roots ACU"; # create the message - require "Email::Sender::Simple"; - my $mail = Email::MIME->create( header_str => [ From => "Roots assistants ", @@ -1513,11 +1507,6 @@ Les roots ACU"; Cc => 'Roots assistants ', Subject => "[PILA][ACCES] Compte suspendu" ], - attributes => { - encoding => 'quoted-printable', - charset => 'utf-8', - format => 'flowed', - }, body_str => $body, ); Email::Sender::Simple::sendmail($mail); @@ -1642,6 +1631,8 @@ sub cmd_ssh_keys_without_passphrase_view(@) # warn about unprotected keys sub cmd_ssh_keys_without_passphrase_warn(@) { + require "Email::Sender::Simple"; + my $process = sub() { my $entry = shift; my $keys = shift; @@ -1676,8 +1667,6 @@ PS: Ce message est g Les roots ACU"; # create the message - require "Email::Sender::Simple"; - my $mail = Email::MIME->create( header_str => [ From => "Roots assistants ", @@ -1685,11 +1674,6 @@ Les roots ACU"; Cc => 'Roots assistants ', Subject => "[PILA][SSH-KEY] Clef SSH non protégée" ], - attributes => { - encoding => 'quoted-printable', - charset => 'utf-8', - format => 'flowed', - }, body_str => $body, ); Email::Sender::Simple::sendmail($mail); @@ -1701,6 +1685,8 @@ Les roots ACU"; # remove unprotected keys sub cmd_ssh_keys_without_passphrase_remove(@) { + require "Email::Sender::Simple"; + my $process = sub() { my $entry = shift; my $keys = shift; @@ -1741,8 +1727,6 @@ PS: Ce message est g -- Les roots ACU"; - require "Email::Sender::Simple"; - my $mail = Email::MIME->create( header_str => [ From => "Roots assistants ", @@ -1750,11 +1734,6 @@ Les roots ACU"; Cc => 'Roots assistants ', Subject => "[PILA][SSH-KEY] Clef SSH non protégée supprimée" ], - attributes => { - encoding => 'quoted-printable', - charset => 'utf-8', - format => 'flowed', - }, body_str => $body, ); Email::Sender::Simple::sendmail($mail); From 5c3309d042eb132219de39d69a1f25fea5139b65 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 31 Oct 2013 16:50:04 +0100 Subject: [PATCH 205/364] New state: PENDING --- ACU/Log.pm | 75 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 57 insertions(+), 18 deletions(-) diff --git a/ACU/Log.pm b/ACU/Log.pm index 30752cc..8c67f22 100644 --- a/ACU/Log.pm +++ b/ACU/Log.pm @@ -5,6 +5,7 @@ use strict; use warnings; use Carp; use Data::Dumper; +use Email::MIME; use Exporter 'import'; use POSIX qw(strftime); use Term::ANSIColor qw(:constants); @@ -16,21 +17,26 @@ use constant { WARN => 4, DONE => 5, USAGE => 6, + PENDING => 6.5, INFO => 7, DEBUG => 8, TRACE => 9, }; -our @EXPORT = qw(log FATAL ALERT ERROR WARN DONE USAGE INFO DEBUG TRACE); +our @EXPORT = qw(log FATAL ALERT ERROR WARN DONE USAGE PENDING INFO DEBUG TRACE); our $display_level = 7; our $save_level = 9; our $fatal_error = 1; our $fatal_warn = 0; +our $mail_error = 0; our $log_file = $0.".log"; my $log_fd; +my $HOSTNAME = `hostname`; +chomp($HOSTNAME); + sub log { my $level = shift; @@ -51,15 +57,47 @@ sub log local $| = 1; print $log_fd strftime("%a %b %e %H:%M:%S %Y", localtime), " ", levelstr($level), " "; - if ($level >= TRACE) { + if ($level == TRACE) { print $log_fd Dumper(@_); } else { say $log_fd @_; } } + + if ($mail_error && $level <= ERROR) + { + require "Email::Sender::Simple"; + my $mail = Email::MIME->create( + header_str => [ + From => "Roots assistants ", + To => "Roots assistants ", + Subject => "[LERDORF][ERROR] ".join(' ', @_) + ], + body_str => "Bonjour, + +Une erreur de niveau $level est survenue sur la machine $HOSTNAME. + +Cette erreur est survenue lors de l'exécution du script : +$0. + +Voici le contenu du message d'erreur : +".join(' ', @_)." + +Cordialement, + +-- +The lerdorf project", + ); + Email::Sender::Simple::sendmail($mail); + } + if ($level <= $display_level) { - say STDERR (leveldisp($level), @_, RESET); + if ($level == PENDING) { + print STDERR (leveldisp($level), @_, RESET, "\r"); + } else { + say STDERR (leveldisp($level), @_, RESET); + } } if ($fatal_warn && $level <= WARN){ @@ -80,14 +118,14 @@ sub levelstr($) { my $level = shift; - return "FATAL" if ($level == 1); - return "ALERT" if ($level == 2); - return "ERROR" if ($level == 3); - return "WARN " if ($level == 4); - return "DONE " if ($level == 5); - return "USAGE" if ($level == 6); - return "INFO " if ($level == 7); - return "DEBUG" if ($level == 8); + return "FATAL" if ($level <= 1); + return "ALERT" if ($level <= 2); + return "ERROR" if ($level <= 3); + return "WARN " if ($level <= 4); + return "DONE " if ($level <= 5); + return "USAGE" if ($level <= 6); + return "INFO " if ($level <= 7); + return "DEBUG" if ($level <= 8); return "TRACE"; } @@ -95,14 +133,15 @@ sub leveldisp($) { my $level = shift; - return BOLD, ON_RED, YELLOW, "/!\\", RESET, " ", BOLD if ($level == 1); - return BOLD, ON_RED, ">>>", RESET, " ", BOLD if ($level == 2); - return BOLD, RED, ">>>", RESET, " ", BOLD if ($level == 3); - return BOLD, YELLOW, ">>>", RESET, " ", BOLD if ($level == 4); - return BOLD, GREEN, ">>>", RESET, " ", BOLD if ($level == 5); - return BOLD, MAGENTA, " * ", RESET, " ", BOLD if ($level == 6); + return BOLD, ON_RED, YELLOW, "/!\\", RESET, " ", BOLD if ($level <= 1); + return BOLD, ON_RED, ">>>", RESET, " ", BOLD if ($level <= 2); + return BOLD, RED, ">>>", RESET, " ", BOLD if ($level <= 3); + return BOLD, YELLOW, ">>>", RESET, " ", BOLD if ($level <= 4); + return BOLD, GREEN, ">>>", RESET, " ", BOLD if ($level <= 5); + return BOLD, MAGENTA, " * ", RESET, " ", BOLD if ($level <= 6); + return BOLD, CYAN, ">>>", RESET, " " if ($level < 7); return BOLD, CYAN, " * ", RESET, " " if ($level == 7); - return BOLD, BLUE, " % ", RESET, " " if ($level == 8); + return BOLD, BLUE, " % ", RESET, " " if ($level <= 8); return BOLD, BLUE, "#", RESET, " "; } From 384a3368514f8bc2eadec8878c1664d2afa43e9f Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 3 Nov 2013 00:06:36 +0100 Subject: [PATCH 206/364] croak instead of return --- process/files/send_git.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/files/send_git.pl b/process/files/send_git.pl index 7322d39..a2e5ee1 100644 --- a/process/files/send_git.pl +++ b/process/files/send_git.pl @@ -21,7 +21,7 @@ sub process my $path = $args->{param}{path} // "/srv/git/repositories/$year/$project_id/$login.git"; - return "$path is not a valid path." if (! -d $path); + croak "$path is not a valid path." if (! -d $path); my $tempdir = tempdir(); From df27747cbcff9dcdcfdb4ea81f2c67b1e1f88c68 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 3 Nov 2013 00:06:58 +0100 Subject: [PATCH 207/364] Fix repository address --- hooks/submissions.pl | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/hooks/submissions.pl b/hooks/submissions.pl index 1a71310..95caeee 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -16,14 +16,22 @@ use ACU::Log; $ACU::Log::log_file = "/var/log/hooks/" . basename($0) . ".log"; use ACU::Process; -# First, check if the repository is in the YYYY/ directory -exit 0 if ($ENV{GL_REPO} !~ /^2[0-9]{3}\/.+\/.+/); - my ($ref, $oldsha, $newsha) = @ARGV; -my $promo = $1 if ($ENV{'GL_REPO'} =~ m/([0-9]{4}).*/); -my $id_project = $1 if ($ENV{'GL_REPO'} =~ m/.*\/(.*)\//); -my $repo_login = $1 if ($ENV{'GL_REPO'} =~ m/.*\/.*\/(.*)/); +my $promo; +my $id_project; +my $repo_login; + +# First, extract information, from config then guess from repository adress +if (my $tmp = `git config hooks.promo`) { chomp $tmp; $promo = $tmp; } +if (my $tmp = `git config hooks.idproject`) { chomp $tmp; $id_project = $tmp; } +if (my $tmp = `git config hooks.login`) { chomp $tmp; $repo_login = $tmp; } + +$promo = $1 if (!$promo && $ENV{'GL_REPO'} =~ m/([0-9]{4}).*/); +$id_project = $1 if (!$id_project && $ENV{'GL_REPO'} =~ m/.*\/(.*)\//); +$repo_login = $1 if (!$repo_login && $ENV{'GL_REPO'} =~ m/.*\/.*\/(.*)/); + +exit(0) if (!$promo || !$id_project || !$repo_login); if ($ref =~ m<^refs/tags/(.+)$>) { @@ -103,7 +111,7 @@ if ($ref =~ m<^refs/tags/(.+)$>) "id" => $id_project, "rendu" => $tag, "login" => $repo_login, - "path" => $ENV{GL_REPO_BASE_ABS}."/".$ENV{GL_REPO}, + "path" => $ENV{GL_REPO_BASE_ABS}."/".$ENV{GL_REPO}.".git", }); }; if ($@) { From 92b61213c6adfbaff8b2abb604391f8ea003f539 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 3 Nov 2013 00:10:07 +0100 Subject: [PATCH 208/364] Add email-mime to package list --- commands/first-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/first-install.sh b/commands/first-install.sh index e09e5f5..aefede4 100755 --- a/commands/first-install.sh +++ b/commands/first-install.sh @@ -1,7 +1,7 @@ #! /bin/bash # Install missing packages -DEB_PACKAGES_LIST="screen libnet-ldap-perl libxml-libxml-perl libgearman-client-perl libmailtools-perl libmail-sendmail-perl libdatetime-format-iso8601-perl libnet-ip-perl libsys-gamin-perl libdigest-sha-perl" +DEB_PACKAGES_LIST="screen libnet-ldap-perl libxml-libxml-perl libgearman-client-perl libmailtools-perl libmail-sendmail-perl libdatetime-format-iso8601-perl libnet-ip-perl libsys-gamin-perl libdigest-sha-perl libemail-mime-perl" ARCH_PACKAGES_LIST="screen perl-io-socket-ssl perl-email-simple perl-email-mime perl-term-readkey perl-ldap perl-lwp-protocol-https perl-datetime-format-iso8601 perl-net-ip" # aur/perl-sys-gamin GENTOO_PACKAGES_LIST="app-misc/screen dev-perl/IO-Socket-SSL dev-perl/Email-Simple dev-perl/Email-MIME dev-perl/TermReadKey dev-perl/perl-ldap dev-perl/LWP-Protocol-https dev-perl/DateTime-Format-ISO8601 dev-perl/Net-IP" FBSD_PACKAGES_LIST="screen p5-IO-Socket-SSL p5-Email-Simple p5-Email-MIME p5-Term-ANSIColor p5-Term-ReadKey p5-LWP-Protocol-https p5-DateTime-Format-ISO8601 p5-Net-IP p5-Sys-Gamin" From fe067d847b37f0a333e49abbe06226f37579eb9c Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 3 Nov 2013 00:12:23 +0100 Subject: [PATCH 209/364] Fix syntax --- process/files/send_git.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/process/files/send_git.pl b/process/files/send_git.pl index a2e5ee1..c262593 100644 --- a/process/files/send_git.pl +++ b/process/files/send_git.pl @@ -2,6 +2,7 @@ use strict; use warnings; +use Carp; use v5.10; use File::Path qw(remove_tree); use File::Temp qw/tempfile tempdir/; From 651c63fd387d077e1fb14659ce37d12dc2e6a485 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 3 Nov 2013 00:36:40 +0100 Subject: [PATCH 210/364] Fix use of search_dns --- ACU/VCS/Git.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ACU/VCS/Git.pm b/ACU/VCS/Git.pm index 4426083..d737546 100644 --- a/ACU/VCS/Git.pm +++ b/ACU/VCS/Git.pm @@ -213,7 +213,7 @@ sub user_add user_delete($login, 1, $multiple); # Then, extract user keys - my @entries = LDAP::search_dns(undef, "ou=users", "&(uid=$login)(sshPublicKey=*)", [ "uid", "sshPublicKey" ]); + 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; } From 490d4109b9b5b5a777475a880bf7b5ee14d17959 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 3 Nov 2013 00:52:15 +0100 Subject: [PATCH 211/364] No ref.ft require for ref --- process/files/moulette_get.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/process/files/moulette_get.pl b/process/files/moulette_get.pl index 125b757..fdd7568 100644 --- a/process/files/moulette_get.pl +++ b/process/files/moulette_get.pl @@ -200,6 +200,7 @@ sub run_moulette copy("$filesdir/$login.ff", "$workdir/$login.ff") or croak "Cannont copy $login.ff"; + next if ($login eq "ref" && ! -f "$workdir/$login.ft"); croak "Unable to find a relevant $login.ft, abort moulette start." if (! -f "$workdir/$login.ft"); log WARN, "There is no ref for $project_id $rendu" if (! -f "$filesdir/ref.ff"); From 731ca526f61add882ce0d1359ac76d4b84928e64 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 3 Nov 2013 00:57:58 +0100 Subject: [PATCH 212/364] Add log --- process/files/moulette_get.pl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/process/files/moulette_get.pl b/process/files/moulette_get.pl index fdd7568..9e8d29b 100644 --- a/process/files/moulette_get.pl +++ b/process/files/moulette_get.pl @@ -100,6 +100,8 @@ sub receive_std my $file = $args->{param}{file}; my $login = $args->{param}{login} // "ref"; + log INFO, "Receiving student tarball: $login, for $year-$project_id-$rendu"; + croak "No file named '$file' given" if (!exists $args->{files}{$file}); my $tempdir = tempdir(DIR => '/data/tmp'); From edcb3adf6dddf99291698c0a4cb89ba18fb2d74d Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 3 Nov 2013 01:01:25 +0100 Subject: [PATCH 213/364] Fix for FreeBSD --- process/launch.sh | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/process/launch.sh b/process/launch.sh index 84796de..41b2d43 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -55,12 +55,22 @@ fi if [ "$ACTION" = "stop" ] || [ "$ACTION" = "restart" ] then # Kill old liblersorf screen sessions - echo "$SCREEN -ls" | $SU intradmin | $GREP '[0-9]+\.lerdorf_[a-zA-Z0-9_-]+' | - while read LINE - do - SNAME=`echo $LINE | $SED "s/^[^0-9]*([0-9]+\.[^ \t]+).*$/\1/"` - echo "$SCREEN -S \"$SNAME\" -X kill" | $SU intradmin - done + if [ "$HOSTNAME" = "ksh" ] + then + $SCREEN -ls | $GREP '[0-9]+\.lerdorf_[a-zA-Z0-9_-]+' | + while read LINE + do + SNAME=`echo $LINE | $SED "s/^[^0-9]*([0-9]+\.[^ \t]+).*$/\1/"` + $SCREEN -S "$SNAME" -X kill + done + else + echo "$SCREEN -ls" | $SU intradmin | $GREP '[0-9]+\.lerdorf_[a-zA-Z0-9_-]+' | + while read LINE + do + SNAME=`echo $LINE | $SED "s/^[^0-9]*([0-9]+\.[^ \t]+).*$/\1/"` + echo "$SCREEN -S \"$SNAME\" -X kill" | $SU intradmin + done + fi fi From 6d9af44499311033f6a4a4cd82e562cf76963c68 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 3 Nov 2013 01:06:51 +0100 Subject: [PATCH 214/364] FreeBSD ... --- process/launch.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/process/launch.sh b/process/launch.sh index 41b2d43..8939c8a 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -57,12 +57,7 @@ then # Kill old liblersorf screen sessions if [ "$HOSTNAME" = "ksh" ] then - $SCREEN -ls | $GREP '[0-9]+\.lerdorf_[a-zA-Z0-9_-]+' | - while read LINE - do - SNAME=`echo $LINE | $SED "s/^[^0-9]*([0-9]+\.[^ \t]+).*$/\1/"` - $SCREEN -S "$SNAME" -X kill - done + killall screen else echo "$SCREEN -ls" | $SU intradmin | $GREP '[0-9]+\.lerdorf_[a-zA-Z0-9_-]+' | while read LINE From 4ba4f3499317bfff547e81383ad53abaee90ede9 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 3 Nov 2013 01:15:49 +0100 Subject: [PATCH 215/364] Clone via ssh instead of filesystem --- process/files/send_git.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/files/send_git.pl b/process/files/send_git.pl index c262593..4c40c48 100644 --- a/process/files/send_git.pl +++ b/process/files/send_git.pl @@ -20,7 +20,7 @@ sub process my $rendu = $args->{param}{rendu}; my $login = $args->{param}{login}; - my $path = $args->{param}{path} // "/srv/git/repositories/$year/$project_id/$login.git"; + my $path = $args->{param}{path} // "ssh://git@localhost/$year/$project_id/$login.git"; croak "$path is not a valid path." if (! -d $path); From 61d523c7c37eb7d504ffb92c518542673d1dffbf Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 3 Nov 2013 01:18:58 +0100 Subject: [PATCH 216/364] Fix send_git --- hooks/submissions.pl | 2 +- process/files/send_git.pl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hooks/submissions.pl b/hooks/submissions.pl index 95caeee..f264b05 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -111,7 +111,7 @@ if ($ref =~ m<^refs/tags/(.+)$>) "id" => $id_project, "rendu" => $tag, "login" => $repo_login, - "path" => $ENV{GL_REPO_BASE_ABS}."/".$ENV{GL_REPO}.".git", +# "path" => "ssh://git@localhost/".$ENV{GL_REPO}, }); }; if ($@) { diff --git a/process/files/send_git.pl b/process/files/send_git.pl index 4c40c48..351e04f 100644 --- a/process/files/send_git.pl +++ b/process/files/send_git.pl @@ -22,12 +22,12 @@ sub process my $path = $args->{param}{path} // "ssh://git@localhost/$year/$project_id/$login.git"; - croak "$path is not a valid path." if (! -d $path); - my $tempdir = tempdir(); qx/git clone -b '$rendu' '$path' '$tempdir'/; + croak "$path is not a valid repository." if (! $?); + my $tar; open my $fh, "tar -czf - -C '$tempdir' . |"; $tar .= $_ while(<$fh>); From b38a5514e5012853293f2fcb1ea2f38d7c277c1d Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 3 Nov 2013 01:23:07 +0100 Subject: [PATCH 217/364] Fix presence of @ --- hooks/submissions.pl | 2 +- process/files/send_git.pl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hooks/submissions.pl b/hooks/submissions.pl index f264b05..8293a1e 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -111,7 +111,7 @@ if ($ref =~ m<^refs/tags/(.+)$>) "id" => $id_project, "rendu" => $tag, "login" => $repo_login, -# "path" => "ssh://git@localhost/".$ENV{GL_REPO}, +# "path" => "ssh://git\@localhost/".$ENV{GL_REPO}, }); }; if ($@) { diff --git a/process/files/send_git.pl b/process/files/send_git.pl index 351e04f..f163875 100644 --- a/process/files/send_git.pl +++ b/process/files/send_git.pl @@ -20,7 +20,7 @@ sub process my $rendu = $args->{param}{rendu}; my $login = $args->{param}{login}; - my $path = $args->{param}{path} // "ssh://git@localhost/$year/$project_id/$login.git"; + my $path = $args->{param}{path} // "ssh://git\@localhost/$year/$project_id/$login.git"; my $tempdir = tempdir(); From 7584473a7689ec1da205c155dda65e3d6fa10bbf Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 3 Nov 2013 01:25:49 +0100 Subject: [PATCH 218/364] Try to die --- process/files/send_git.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/files/send_git.pl b/process/files/send_git.pl index f163875..9e6e08f 100644 --- a/process/files/send_git.pl +++ b/process/files/send_git.pl @@ -24,7 +24,7 @@ sub process my $tempdir = tempdir(); - qx/git clone -b '$rendu' '$path' '$tempdir'/; + qx/git clone -b '$rendu' '$path' '$tempdir'/ or croak "$path is not a valid repository."; croak "$path is not a valid repository." if (! $?); From 48bad8dca9d604a1f78dd3536f19689d3b7284d2 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 3 Nov 2013 01:27:01 +0100 Subject: [PATCH 219/364] Try to die --- process/files/send_git.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/files/send_git.pl b/process/files/send_git.pl index 9e6e08f..17eb6e1 100644 --- a/process/files/send_git.pl +++ b/process/files/send_git.pl @@ -29,7 +29,7 @@ sub process croak "$path is not a valid repository." if (! $?); my $tar; - open my $fh, "tar -czf - -C '$tempdir' . |"; + open my $fh, "tar -czf - -C '$tempdir' . |" or die ($!); $tar .= $_ while(<$fh>); close $fh; From 5b78698a5ca68a465ad4e21c0bc27e8143a09160 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 3 Nov 2013 01:30:09 +0100 Subject: [PATCH 220/364] Try to die --- process/files/send_git.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/process/files/send_git.pl b/process/files/send_git.pl index 17eb6e1..db2f924 100644 --- a/process/files/send_git.pl +++ b/process/files/send_git.pl @@ -26,12 +26,13 @@ sub process qx/git clone -b '$rendu' '$path' '$tempdir'/ or croak "$path is not a valid repository."; - croak "$path is not a valid repository." if (! $?); + croak "$path is not a valid repository." if ($?); my $tar; open my $fh, "tar -czf - -C '$tempdir' . |" or die ($!); $tar .= $_ while(<$fh>); close $fh; + die "Unable to untar: $!" if ($?); # Clean remove_tree($tempdir); From 995fbdedd1434bce555170cd278eff1e720d117a Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 3 Nov 2013 01:42:44 +0100 Subject: [PATCH 221/364] Launch send_git with ssh-agent --- process/launch.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/launch.sh b/process/launch.sh index 8939c8a..8e5cf4a 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -79,7 +79,7 @@ then hamano) launch_screen "lerdorf_process_ldap_sync_ssh_keys_git" "while true; do $PERL ~/liblerdorf/process/ldap/sync_ssh_keys_git.pl; done" ~intradmin/.ssh/git - launch_screen "lerdorf_process_send_git" "while true; do $PERL ~/liblerdorf/process/files/send_git.pl; done" + launch_screen "lerdorf_process_send_git" "while true; do $PERL ~/liblerdorf/process/files/send_git.pl; done" ~intradmin/.ssh/git ;; moore) From aa71e36f8b33b15c2c98c1093d48c3e74b554a77 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 3 Nov 2013 01:47:15 +0100 Subject: [PATCH 222/364] FreeBSD... --- process/launch.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/launch.sh b/process/launch.sh index 8e5cf4a..44638b2 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -57,7 +57,7 @@ then # Kill old liblersorf screen sessions if [ "$HOSTNAME" = "ksh" ] then - killall screen + killall sh else echo "$SCREEN -ls" | $SU intradmin | $GREP '[0-9]+\.lerdorf_[a-zA-Z0-9_-]+' | while read LINE From 89167d47d255823c3dc71ba9b99e54105e77aeaa Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 3 Nov 2013 01:51:34 +0100 Subject: [PATCH 223/364] FreeBSD... --- process/launch.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/process/launch.sh b/process/launch.sh index 44638b2..6fd1736 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -57,7 +57,12 @@ then # Kill old liblersorf screen sessions if [ "$HOSTNAME" = "ksh" ] then - killall sh + for i in `pgrep sh` + do + if [ "$$" != "$i" ] + then + pkill "$i" + fi else echo "$SCREEN -ls" | $SU intradmin | $GREP '[0-9]+\.lerdorf_[a-zA-Z0-9_-]+' | while read LINE From 801d59d8602a7d5adb3c72464188dd6cf8e11095 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 3 Nov 2013 01:52:05 +0100 Subject: [PATCH 224/364] FreeBSD.. --- process/launch.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/process/launch.sh b/process/launch.sh index 6fd1736..fef7b54 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -63,6 +63,7 @@ then then pkill "$i" fi + done else echo "$SCREEN -ls" | $SU intradmin | $GREP '[0-9]+\.lerdorf_[a-zA-Z0-9_-]+' | while read LINE From b5a8b5f5f9ba8674eee2679d70c93f88fa804699 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 3 Nov 2013 03:12:57 +0100 Subject: [PATCH 225/364] Launch send_git in background --- hooks/submissions.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/submissions.pl b/hooks/submissions.pl index 8293a1e..52d7e59 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -112,7 +112,7 @@ if ($ref =~ m<^refs/tags/(.+)$>) "rendu" => $tag, "login" => $repo_login, # "path" => "ssh://git\@localhost/".$ENV{GL_REPO}, - }); + }, undef, 1); }; if ($@) { my $err = $@; From 9dbf4920467d05e8a4865460fe8e2000155dc36d Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 3 Nov 2013 03:39:43 +0100 Subject: [PATCH 226/364] Check Fact is already running after call it --- process/files/moulette_get.pl | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/process/files/moulette_get.pl b/process/files/moulette_get.pl index 9e8d29b..0024071 100644 --- a/process/files/moulette_get.pl +++ b/process/files/moulette_get.pl @@ -37,7 +37,17 @@ sub fact_exec { my $cmd = shift; my $rundir = shift; - jail_exec("cd $rundir && /usr/local/bin/mono /usr/local/fact/FactExe.exe $cmd"); + + # Check that Fact is running + qx/pgrep mono/; + while ($?) + { + log ERROR, "Fact is not running ... waiting for respawn"; + sleep(10); + qx/pgrep mono/; + } + + jail_exec("cd '$rundir' && /usr/local/bin/mono /usr/local/fact/FactExe.exe $cmd"); } sub prepare_dir From ed0edaf9f35008010bcc94cd9bb962e1534d3191 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 4 Nov 2013 02:23:47 +0100 Subject: [PATCH 227/364] Change unlink to remove_tree in ordre to clean git_manage_ temporary directories --- ACU/VCS/Git.pm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ACU/VCS/Git.pm b/ACU/VCS/Git.pm index d737546..169b028 100644 --- a/ACU/VCS/Git.pm +++ b/ACU/VCS/Git.pm @@ -5,7 +5,7 @@ package Git; use v5.10.1; use strict; use warnings; -use File::Path; +use File::Path qw(remove_tree); use File::Temp; use ACU::LDAP; @@ -31,7 +31,7 @@ sub init_conf(;$) log INFO, "Cloning $git_user\@$git_server:$git_adminrepo to $gitolite_directory"; - system ("git clone $git_user\@$git_server:$git_adminrepo $gitolite_directory"); + qx(git clone $git_user\@$git_server:$git_adminrepo $gitolite_directory); chdir($gitolite_directory); @@ -43,12 +43,12 @@ sub save_conf(;$) chdir($gitolite_directory); my $commit = shift; - system ("git commit -am '$commit'") if ($commit); + qx(git commit -am '$commit') if ($commit); log INFO, "Saving repositories configuration"; - system ("git push"); - unlink ($gitolite_directory); + qx(git push); + remove_tree($gitolite_directory); $gitolite_directory = undef; } @@ -235,7 +235,7 @@ sub user_add print $kf $key; close $kf; - system("git add $gitolite_directory/keydir/$i/$login.pub"); + qx(git add $gitolite_directory/keydir/$i/$login.pub); $i += 1; } } From 90d22c3af0a27b022f835dbcdc28e7e48744a468 Mon Sep 17 00:00:00 2001 From: Nicolas Geniteau Date: Tue, 5 Nov 2013 03:45:35 +0100 Subject: [PATCH 228/364] Add Knuth in servers list --- commands/manage-server.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/commands/manage-server.sh b/commands/manage-server.sh index 145bed9..3c0620a 100755 --- a/commands/manage-server.sh +++ b/commands/manage-server.sh @@ -1,10 +1,10 @@ -#! /bin/bash +#! /usr/bin/env bash cd $(dirname "$0") WKS_LIST="apl" SRV_LIST="moore noyce hamano cpp" -SCP_LIST="ksh" +SCP_LIST="ksh knuth" KNOWN_ACTIONS="start stop restart update log viewlog view_log" From 691a72406150dbfdcb484d9577de2136c4cf07c1 Mon Sep 17 00:00:00 2001 From: Nicolas Geniteau Date: Tue, 5 Nov 2013 17:26:56 +0100 Subject: [PATCH 229/364] adding otto as server --- commands/manage-server.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/manage-server.sh b/commands/manage-server.sh index 3c0620a..e1ea557 100755 --- a/commands/manage-server.sh +++ b/commands/manage-server.sh @@ -3,7 +3,7 @@ cd $(dirname "$0") WKS_LIST="apl" -SRV_LIST="moore noyce hamano cpp" +SRV_LIST="moore noyce hamano cpp otto" SCP_LIST="ksh knuth" KNOWN_ACTIONS="start stop restart update log viewlog view_log" From dfbd4e69bad07303f3bfcf3fe25dbe317fb5cf04 Mon Sep 17 00:00:00 2001 From: Nicolas Geniteau Date: Tue, 5 Nov 2013 17:29:06 +0100 Subject: [PATCH 230/364] ACU::Jail --- ACU/Jail.pm | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 ACU/Jail.pm diff --git a/ACU/Jail.pm b/ACU/Jail.pm new file mode 100644 index 0000000..3139925 --- /dev/null +++ b/ACU/Jail.pm @@ -0,0 +1,71 @@ +#! /usr/bin/env perl + +package Jail; + +use v5.10.1; +use strict; +use warnings; +use Carp; +use File::Temp qw(tempdir); +use File::Path qw(remove_tree); +use File::Copy::Recursive qw(dircopy); + +use ACU::Log; + +use constant { + JAILS_DIR => "/jail/", + RULESET_NO => 4, +}; + +sub run_command +{ + my $jail = shift; + my $command = shift; + my $readonly = shift; + my $work_dir = shift; + + # Verifications + croak JAILS_DIR . "$jail doesn't exist." unless ( -d JAILS_DIR . $jail); + croak JAILS_DIR . "$jail/data doesn't exist." unless ( -d JAILS_DIR . "$jail/data"); + + + my $jail_path = JAILS_DIR . $jail; + my $mounts = ""; + if ($readonly) { + $jail_path = tempdir(); + $mounts = "mount='" . JAILS_DIR . "$jail $jail_path nullfs ro 0 0' "; + } + + $mounts .= "mount='tmpfs $jail_path/tmp tmpfs rw,mode=777 0 0' "; + + my $jail_data_path = "$jail_path/data"; + + # Creating the working directory + if (defined ($work_dir) and $work_dir ne "") { + $mounts .= "mount='$work_dir $jail_data_path nullfs rw 0 0' "; + } + + # Create and start jail + my $jail_cmd = "jail -c path='$jail_path' "; + $jail_cmd .= "persist=false "; + $jail_cmd .= "devfs_ruleset=". RULESET_NO ." "; + $jail_cmd .= "$mounts"; + if (defined ($work_dir) and $work_dir ne "") { + $jail_cmd .= "exec.start='cd $jail_data_path && $command'"; + } else { + $jail_cmd .= "exec.start='$command'"; + } + system($jail_cmd); + croak "Error while executing '$jail_cmd'" if ($?); + + # Force umount + system("umount -f $jail_path/tmp"); + if (defined ($work_dir) and $work_dir ne "") { + system("umount -f $jail_data_path"); + } + if ($readonly) { + system("umount -f $jail_path"); + } +} + +1; From 92a222d346ff623b5e36fca283861d4ec9b78119 Mon Sep 17 00:00:00 2001 From: Nicolas Geniteau Date: Tue, 5 Nov 2013 17:37:03 +0100 Subject: [PATCH 231/364] hook dump-help --- hooks/dump-help.pl | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100755 hooks/dump-help.pl diff --git a/hooks/dump-help.pl b/hooks/dump-help.pl new file mode 100755 index 0000000..dd8d29f --- /dev/null +++ b/hooks/dump-help.pl @@ -0,0 +1,40 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use v5.10; +use utf8; +use Carp; +use File::Basename; +use File::Path qw(remove_tree); +use File::Temp qw/tempfile tempdir/; + +use ACU::Log; +$ACU::Log::log_file = "/var/log/hooks/" . basename($0) . ".log"; +use ACU::Process; + +# First, check if the repository is dump-help +exit 0 if ($ENV{GL_REPO} ne "dump-help"); + +my ($ref, $oldsha, $newsha) = @ARGV; + +log DONE, "This is the dump-help repository!"; + +exit 0 if ($newsha eq '0' x 40); + +if ($ref eq "refs/tags/release") +{ + + my $archive = qx(git archive --format=tgz $newsha); + #qx(git clone -b release /srv/git/repositories/dump-help.git '$tempdir') or croak "It is not a valid repository."; + + Process::Client::launch("docs_compile", + { + "type" => "dump_help", + "file" => "dump-help.tgz" , + }, + { "dump-help.tgz" => $archive }); + +} + +exit 0; From 3c0e0f09be98b921887553a0fb267f827154b11e Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 4 Nov 2013 02:26:04 +0100 Subject: [PATCH 232/364] Migration: migrate also .ltx files --- migration/repo.sh | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/migration/repo.sh b/migration/repo.sh index 4f97bbc..be4338a 100755 --- a/migration/repo.sh +++ b/migration/repo.sh @@ -46,6 +46,8 @@ tex2md() sed -Ei 's/\\begin *\{cartouche_nospaces\}/\\begin\{verbatim\}/g' "$i" sed -Ei 's/\\end *\{cartouche_nospaces\}/\\end\{verbatim\}/g' "$i" sed -Ei 's/\\verb ([^+]+) /\\verb+\1+/g' "$i" + sed -Ei 's/``/"/g' "$i" + sed -Ei "s/''/\"/g" "$i" # Special macros sed -Ei 's/\\(file|email|command|code|bcode) *\{([^}]*)\}/\\verb+\2+/gi' "$i" @@ -109,7 +111,7 @@ clean_tex() exit 1; fi - for f in data Makefile images/acu.pdf images/assistants.pdf images/assistants-subject.pdf images/assistants-slides.pdf images/assistants.png images/epita.pdf images/epita.png images/epita-invert.pdf images/assistants-invert.pdf images/epita-invert.png images/assistants-bg.png images/logo_epita.jpg images/acu-bottom.png images/acu-bottom.pdf images/acu-bg.pdf images/acu2011.png images/acu.png *.cls *.sty *.tex + for f in data Makefile images/acu.pdf images/assistants.pdf images/assistants-subject.pdf images/assistants-slides.pdf images/assistants.png images/epita.pdf images/epita.png images/epita-invert.pdf images/assistants-invert.pdf images/epita-invert.png images/assistants-bg.png images/logo_epita.jpg images/acu-bottom.png images/acu-bottom.pdf images/acu-bg.pdf images/acu2011.png images/acu.png *.cls *.sty do if [ -f "$f" ] then @@ -120,6 +122,11 @@ clean_tex() fi done + for file in `find -name "*.ltx"` + do + git mv "$file" "${file%%.ltx}.tex" + done + if [ -d "include" ] then cd include @@ -130,6 +137,20 @@ clean_tex() git mv * .. fi + cd "$1" + tex2md . + maintex2md + rmdir include 2> /dev/null + elif [ -d "subdocs" ] + then + cd subdocs + tex2md .. + + if [ `find | wc -l` -gt 1 ] + then + git mv * .. + fi + cd "$1" tex2md . maintex2md From fe9cc480a122b3f76a2b980ff1d9bbe9b2d6107a Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 5 Nov 2013 17:40:52 +0100 Subject: [PATCH 233/364] Add install procedure into manage-server --- commands/manage-server.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/commands/manage-server.sh b/commands/manage-server.sh index e1ea557..9bb03f2 100755 --- a/commands/manage-server.sh +++ b/commands/manage-server.sh @@ -6,7 +6,7 @@ WKS_LIST="apl" SRV_LIST="moore noyce hamano cpp otto" SCP_LIST="ksh knuth" -KNOWN_ACTIONS="start stop restart update log viewlog view_log" +KNOWN_ACTIONS="start stop restart install update log viewlog view_log" LOG=`mktemp` @@ -80,7 +80,7 @@ do for DEST in $DESTS do echo -e "\e[1;34m>>>\e[0m \e[33m$ACTION\e[0m on \e[1m$DEST\e[0m" - if [ "$ACTION" == "update" ] + if [ "$ACTION" == "install" ] || [ "$ACTION" == "update" ] then SCP=0 for D in $SCP_LIST @@ -94,6 +94,11 @@ do if [ $SCP -eq 0 ] then + if [ "$ACTION" == "install" ] && + ! ssh root@$DEST "mkdir -p /home/intradmin/ && git clone '$(echo `git remote -v` | cut -d " " -f 2)' /home/intradmin/liblerdorf && ln -s /home/intradmin/liblerdorf ~/liblerdorf" + then + exit 1 + fi ssh root@$DEST "make -C liblerdorf update upgrade" else cd .. From 0af1174ca8c1ab8884c28907c41ce3a5a6a9468c Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 5 Nov 2013 18:03:54 +0100 Subject: [PATCH 234/364] Replace croak by die when unexpected error --- process/files/intradata_get.pl | 90 +++++++++++++++++++++------------- 1 file changed, 55 insertions(+), 35 deletions(-) diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index 7e1eae3..c1f58e0 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -42,7 +42,7 @@ sub create_tree($$) croak "No directory for year $year. Ask a root to create it." if (! -d "$basedir/$year/"); if (! -e "$basedir/$year/$project_id/") { - mkdir "$basedir/$year/$project_id/" or croak $!; + mkdir "$basedir/$year/$project_id/" or die $!; } } @@ -57,11 +57,14 @@ sub grades_generate croak "No project_id given." if (! $project_id); if (! -e "$basedir/$year/$project_id/grades/") { - mkdir "$basedir/$year/$project_id/grades/" or croak $!; + mkdir "$basedir/$year/$project_id/grades/" or die $!; } log DEBUG, "Generate list of students"; + # Get groups from the intranet + my $groups = API::Projects::get_groups($project_id, $year); + # Create list of students to generate my @logins; if ($args->{unamed}) @@ -72,22 +75,11 @@ sub grades_generate } else { - opendir(my $dh, "$basedir/$year/$project_id/traces/") or croak "can't opendir $basedir/$year/$project_id/traces/: $!"; - for my $dir (grep { ( ! /^\./ ) && -d "$basedir/$year/$project_id/traces/$_" } readdir($dh)) - { - opendir(my $dhm, "$basedir/$year/$project_id/traces/$dir") or croak "can't opendir $basedir/$year/$project_id/traces/$dir: $!"; - - for my $login (grep { ( ! /^\./ ) && -f "$basedir/$year/$project_id/traces/$dir/$_" } readdir($dhm)) - { - $login =~ s/\.xml$//; - if (! grep { /^\Q$login\E$/ } @logins) { - push @logins, $login; - } + map { + for my $member (@{ $_->{stds} }) { + push @logins, $member->{login}; } - - closedir $dhm; - } - closedir $dh; + } @{ $groups->{groups} }; } log TRACE, @logins; @@ -110,18 +102,46 @@ sub grades_generate log DEBUG, "Generating grades for $login"; for my $dir (@trace_dirs) { - log DEBUG, "Generating grades from $dir"; - if (-f "$basedir/$year/$project_id/traces/$dir/$login.xml") + log DEBUG, "Fetching identifiers from $dir"; + + my $tr_file = "$year/$project_id/traces/$dir/$login.xml"; + + # Looking for a group traces? + if (! -f "$basedir/$tr_file") { - open my $xmltrace, "<", "$basedir/$year/$project_id/traces/$dir/$login.xml" or croak "traces/$dir/$login.xml: $!"; + for my $grp (@{ $groups->{groups} }) + { + my $this = 0; + my $chief; + for my $member (@{ $grp->{stds} }) + { + if ($member->{chief} eq "true" or $member->{chief} eq "1" or $member->{chief} eq "chief") + { + $chief = $member; + next; + } + $this = 1 if ($member->{login} eq $login); + } + if ($this && $chief) + { + $tr_file = "$year/$project_id/traces/$dir/".$chief->{login}.".xml"; + log DEBUG, "Using group trace: chief is ".$chief->{login}; + last; + } + } + } + + if (-f "$basedir/$tr_file") + { + open my $xmltrace, "<", "$basedir/$tr_file" or croak "$tr_file: $!"; binmode $xmltrace; my $trace = Trace->new($xmltrace); close $xmltrace; - log DEBUG, "Fill from file: traces/$dir/$login.xml"; + log DEBUG, "Fill from file: $tr_file"; log TRACE, $trace->getIds; - $grading->fill($trace->getIds); + $grading->fill($trace->getIds($login)); } } @@ -149,10 +169,10 @@ sub grades_new_bonus croak "No project_id given" if (! $project_id); if (! -e "$basedir/$year/$project_id/traces/") { - mkdir "$basedir/$year/$project_id/traces/" or croak $!; + mkdir "$basedir/$year/$project_id/traces/" or die $!; } if (! -e "$basedir/$year/$project_id/traces/bonus/") { - mkdir "$basedir/$year/$project_id/traces/bonus/" or croak $!; + mkdir "$basedir/$year/$project_id/traces/bonus/" or die $!; } for my $kfile (keys %{ $args->{files} }) @@ -192,7 +212,7 @@ sub grades_new_bonus } if (-e "$basedir/$year/$project_id/traces/bonus/$login.xml") { - open my $xml, "<", "$basedir/$year/$project_id/traces/bonus/$login.xml" or croak $!; + open my $xml, "<", "$basedir/$year/$project_id/traces/bonus/$login.xml" or die $!; binmode $xml; $trace = Trace->new($xml); close $xml; @@ -216,7 +236,7 @@ sub grades_new_bonus log DEBUG, "Updating $basedir/$year/$project_id/traces/bonus/$login.xml"; - open my $xml, ">", "$basedir/$year/$project_id/traces/bonus/$login.xml" or croak $!; + open my $xml, ">", "$basedir/$year/$project_id/traces/bonus/$login.xml" or die $!; print $xml $trace->toString(); close $xml; } @@ -251,19 +271,19 @@ sub update_defense log INFO, "Update $year/$project_id/defenses/$defense_id.xml"; if (! -e "$basedir/$year/$project_id/defenses/") { - mkdir "$basedir/$year/$project_id/defenses/" or croak $!; + mkdir "$basedir/$year/$project_id/defenses/" or die $!; } if (! -e "$basedir/$year/$project_id/traces/") { - mkdir "$basedir/$year/$project_id/traces/" or croak $!; + mkdir "$basedir/$year/$project_id/traces/" or die $!; } if (! -e "$basedir/$year/$project_id/traces/defense_$defense_id/") { - mkdir "$basedir/$year/$project_id/traces/defense_$defense_id/" or croak $!; + mkdir "$basedir/$year/$project_id/traces/defense_$defense_id/" or die $!; my ($login, $pass, $uid, $gid) = getpwnam("www-data"); - chown $uid, $gid, "$basedir/$year/$project_id/traces/defense_$defense_id/" or croak $!; - chmod 0775, "$basedir/$year/$project_id/traces/defense_$defense_id/" or croak $!; + chown $uid, $gid, "$basedir/$year/$project_id/traces/defense_$defense_id/" or die $!; + chmod 0775, "$basedir/$year/$project_id/traces/defense_$defense_id/" or die $!; } - open my $out, ">", "$basedir/$year/$project_id/defenses/$defense_id.xml" or croak $!; + open my $out, ">", "$basedir/$year/$project_id/defenses/$defense_id.xml" or die $!; print $out $defense; close $out; @@ -322,11 +342,11 @@ sub update_trace log INFO, "Update $year/$project_id/traces/$rendu_id/$login.xml"; if (! -e "$basedir/$year/$project_id/traces/") { - mkdir "$basedir/$year/$project_id/traces/" or croak $!; + mkdir "$basedir/$year/$project_id/traces/" or die $!; } if (! -e "$basedir/$year/$project_id/traces/$rendu_id/") { - mkdir "$basedir/$year/$project_id/traces/$rendu_id/" or croak $!; - chmod 0755, "$basedir/$year/$project_id/traces/$rendu_id/" or croak $!; + mkdir "$basedir/$year/$project_id/traces/$rendu_id/" or die $!; + chmod 0755, "$basedir/$year/$project_id/traces/$rendu_id/" or die $!; } open my $out, ">", "$basedir/$year/$project_id/traces/$rendu_id/$login.xml" or croak("Unable to write to $rendu_id/$login.xml"); From 90727e48d570935f86504d3e25393232c578cbdc Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 6 Nov 2013 18:11:17 +0100 Subject: [PATCH 235/364] Fix errors --- ACU/VCS/Git.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ACU/VCS/Git.pm b/ACU/VCS/Git.pm index 169b028..a1ed4fa 100644 --- a/ACU/VCS/Git.pm +++ b/ACU/VCS/Git.pm @@ -27,7 +27,7 @@ sub init_conf(;$) { $git_server = $_ if (shift); - $gitolite_directory = mktemp("/tmp/git_manage_XXXX") unless(-d $gitolite_directory); + $gitolite_directory = mktemp("/tmp/git_manage_XXXX"); log INFO, "Cloning $git_user\@$git_server:$git_adminrepo to $gitolite_directory"; @@ -271,7 +271,7 @@ sub user_delete { if ($f =~ /^[0-9]/ && -d "$gitolite_directory/keydir/$f") { log INFO, "Removing $f directory"; - rmtree("$gitolite_directory/keydir/$f"); + remove_tree("$gitolite_directory/keydir/$f"); } } else From 8a4b545da67ef61f6c02dbd9aaf6961222763d29 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 6 Nov 2013 18:13:08 +0100 Subject: [PATCH 236/364] chdir before remove dir --- ACU/VCS/Git.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/ACU/VCS/Git.pm b/ACU/VCS/Git.pm index a1ed4fa..a9ad31c 100644 --- a/ACU/VCS/Git.pm +++ b/ACU/VCS/Git.pm @@ -48,6 +48,7 @@ sub save_conf(;$) log INFO, "Saving repositories configuration"; qx(git push); + chdir("/"); remove_tree($gitolite_directory); $gitolite_directory = undef; } From de88e60fa5b8cfc5973bb6d52ddf7ffc36e570c8 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 6 Nov 2013 18:22:07 +0100 Subject: [PATCH 237/364] Fix too much kill of ssh-agent --- process/launch.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/process/launch.sh b/process/launch.sh index fef7b54..efac6fd 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -12,13 +12,17 @@ else fi PERL='/usr/bin/env perl' +reset_agents() +{ + echo "killall ssh-agent" | $SU intradmin +} + launch_screen() { CMD=$2 if [ -n "$3" ] && [ -f "$3" ] then TMP=`echo mktemp | $SU intradmin` - echo "killall ssh-agent" | $SU intradmin echo "ssh-agent" | $SU intradmin > "$TMP" echo ". $TMP; ssh-add '$3'" | $SU intradmin CMD=". $TMP; ssh-add -l; echo; $CMD" @@ -80,10 +84,12 @@ then case $HOSTNAME in cpp) + reset_agents launch_screen "lerdorf_process_ldap_sync_ssh_keys_forge" "while true; do $PERL ~/liblerdorf/process/ldap/sync_ssh_keys_forge.pl; done" ~intradmin/.ssh/git ;; hamano) + reset_agents launch_screen "lerdorf_process_ldap_sync_ssh_keys_git" "while true; do $PERL ~/liblerdorf/process/ldap/sync_ssh_keys_git.pl; done" ~intradmin/.ssh/git launch_screen "lerdorf_process_send_git" "while true; do $PERL ~/liblerdorf/process/files/send_git.pl; done" ~intradmin/.ssh/git ;; From cda7b5b02614be0e9bb9772b229835fc59d72b4b Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 7 Nov 2013 14:46:28 +0100 Subject: [PATCH 238/364] LPT: fix grant-lab and add delete account capability --- ACU/LDAP.pm | 6 +-- utils/lpt | 108 +++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 98 insertions(+), 16 deletions(-) diff --git a/ACU/LDAP.pm b/ACU/LDAP.pm index 5e7e229..04b94e7 100644 --- a/ACU/LDAP.pm +++ b/ACU/LDAP.pm @@ -193,9 +193,9 @@ sub get_dn($$@) base => "$dn", filter => Net::LDAP::Filter->new("(objectClass=*)"), attrs => \@_, - scope => "sub" + scope => "base" ); - if ($mesg->code != 0) { log(WARN, $mesg->error); return undef; } + return undef if ($mesg->code != 0); if ($mesg->count != 1) { log(WARN, "$dn not found or multiple entries match"); return undef; } return $mesg->entry(0); @@ -331,7 +331,7 @@ sub search_dn($$@) attrs => [ ], scope => "sub" ); - croak($mesg->error) if ($mesg->code != 0); + return undef if ($mesg->code != 0); croak("$filter not found") if ($mesg->count == 0); croak("$filter not unique") if ($mesg->count > 1); diff --git a/utils/lpt b/utils/lpt index e760ed0..c96d936 100755 --- a/utils/lpt +++ b/utils/lpt @@ -73,6 +73,7 @@ my %cmds_account = "close" => \&cmd_account_close, "cn" => \&cmd_account_cn, "create" => \&cmd_account_create, + "delete" => \&cmd_account_delete, "finger" => \&cmd_account_view, "mail" => \&cmd_account_mail, "name" => \&cmd_account_cn, @@ -259,11 +260,31 @@ sub cmd_account_create($@) log(DEBUG, "Adding dn: uid=$login,ou=$group,ou=users,dc=acu,dc=epita,dc=fr ..."); my $ldap = LDAP::ldap_connect(); - my $mesg = $ldap->add( "uid=$login,ou=$group,ou=users,dc=acu,dc=epita,dc=fr", + + # Check if the OU exists + my $oudn = "ou=$group,ou=users,dc=acu,dc=epita,dc=fr"; + my $ou = LDAP::get_dn($ldap, $oudn); + + if (! $ou) + { + my $mesg = $ldap->add( "$oudn", + attrs => [ + objectclass => [ "top", "organizationalUnit" ], + ou => "$group", + ] + ); + if ($mesg->code == 0) { + log(INFO, "New OU created: $oudn"); + } else { + log(WARN, "Unable to add new OU $oudn: ", RESET, $mesg->error); + } + } + + my $mesg = $ldap->add( "uid=$login,$oudn", attrs => [ objectclass => [ "top", "epitaAccount" ], uidNumber => shift, - cn => shift(@_)." ".shift(@_), + cn => ucfirst(shift(@_))." ".ucfirst(shift(@_)), mail => "$login\@epita.fr", uid => $login, ] @@ -271,10 +292,11 @@ sub cmd_account_create($@) #$ldap->unbind or die ("couldn't disconnect correctly"); - if ($mesg->code == 0) { + if ($mesg->code == 0) + { log(INFO, "Account added: $login"); my $pass = shift; - return cmd_account($login, $pass) if ($pass ne "nopass"); + return cmd_account($login, $pass, @_) if ($pass ne "nopass"); return 0; } else { @@ -282,6 +304,28 @@ sub cmd_account_create($@) } } +sub cmd_account_delete($@) +{ + my $login = shift; + + my $ldap = LDAP::ldap_connect(); + + my $dn = LDAP::search_dn($ldap, "ou=users", "uid=$login"); + + log(DEBUG, "Deleting dn: $dn ..."); + + if (LDAP::delete_entry($ldap, $dn)) + { + log DONE, "Account ", YELLOW, $login, RESET, " successfully deleted."; + return 0; + } + else + { + log ERROR, "Unable to delete account ", YELLOW, $login, RESET, "."; + return 1; + } +} + sub cmd_account_grantintra($@) { my $login = shift; @@ -300,27 +344,58 @@ sub cmd_account_grantintra($@) sub cmd_account_grantlab($@) { my $login = shift; - my $group = shift; + my $group = shift // ""; - if ($group ne "acu" && $group ne "yaka") { - log(USAGE, "lpt account grantlab "); + if ($group ne "acu" && $group ne "yaka" && $group ne "ferry") + { + log(USAGE, "lpt account grant-lab "); return 1; } my $ldap = LDAP::ldap_connect(); my $dn = LDAP::search_dn($ldap, "ou=users", "uid=$login"); + my $entry = LDAP::get_dn($ldap, $dn, "objectClass", "mail", "mailAlias", "mailAccountActive", "loginShell", "homeDirectory", "gidNumber"); if (!LDAP::get_attribute($ldap, $dn, "mail")) { LDAP::add_attribute($ldap, $dn, "mail", "$login\@epita.fr"); } - LDAP::add_attribute($ldap, $dn, "mailAlias", "$login\@$group.epita.fr"); - LDAP::update_attribute($ldap, $dn, "mailAccountActive", "yes"); - LDAP::add_attribute($ldap, $dn, "objectClass", "MailAccount"); - LDAP::add_attribute($ldap, $dn, "objectClass", "labAccount"); + if ($group eq "acu" || $group eq "yaka") + { + if (! grep { $_ eq "MailAccount" } @{ $entry->get_value("objectClass") }) + { + $entry->replace("mailAccountActive" => [ "yes" ]); - log(INFO, "$login now grants to receive e-mail and connect in laboratory."); + my @oc = $entry->get_value("objectClass"); + push @oc, "MailAccount"; + $entry->replace("objectClass" => \@oc); + + my @aliases = $entry->get_value("mailAlias"); + push @aliases, "$login\@$group.epita.fr"; + $entry->replace("objectClass" => \@aliases); + } + + $entry->replace("loginShell" => [ "/bin/zsh" ]) if ($entry->get_value("loginShell")); + $entry->replace("homeDirectory" => [ "/home/201X/$login" ]) if ($entry->get_value("homeDirectory")); + $entry->replace("gidNumber" => [ "4242" ]) if ($entry->get_value("gidNumber")); + } + elsif ($group eq "ferry") + { + $entry->replace("loginShell" => [ "/bin/noexists" ]); + $entry->replace("homeDirectory" => [ "/dev/null" ]); + $entry->replace("gidNumber" => [ "4243" ]); + } + + my @oc = $entry->get_value("objectClass"); + push @oc, "labAccount"; + $entry->replace("objectClass" => \@oc); + + my $mesg = $entry->update($ldap) or die $!; + if ($mesg->code != 0) { log(WARN, $mesg->error); return 0; } + + log(INFO, "$login now grants to receive e-mail and connect in laboratory.") if ($group eq "acu" || $group eq "yaka"); + log(INFO, "$login now grants to connect in laboratory for exam.") if ($group eq "ferry"); $ldap->unbind or die ("couldn't disconnect correctly"); } @@ -1855,10 +1930,12 @@ B I Give rights to the user to access the intranet. -B I +B I Give rights to the user to access intern systems of the laboratory (SSH, Unix, ...) + If ferry is given, open an account for exam only, with restricted rights. + B I Give rights to the user to receive e-mails. @@ -1871,6 +1948,11 @@ B I This is used to close an existing account. +B I + + This is used to delete an existing account. + NEVER DELETE AN ACCOUNT, close it instead. + B I [new-mail] This is used to display, or change if [new-mail] is given, the account contact adress. From 584fbf98954a1c99ad3d25951b6046d0bfac1e47 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 8 Nov 2013 21:05:05 +0100 Subject: [PATCH 239/364] Add APPING1 to exception --- hooks/submissions.pl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hooks/submissions.pl b/hooks/submissions.pl index 52d7e59..058e393 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -22,6 +22,8 @@ my $promo; my $id_project; my $repo_login; +my @apping = qw(zinger_a zebard_w zanell_a yao_p vinois_a sraka_y soupam_j seck_a ngomsi_s morin_h milis_e menkar_m eusebe_r crief_a chhum_s boumra_n blemus_a bengan_l amasho_a); + # First, extract information, from config then guess from repository adress if (my $tmp = `git config hooks.promo`) { chomp $tmp; $promo = $tmp; } if (my $tmp = `git config hooks.idproject`) { chomp $tmp; $id_project = $tmp; } @@ -71,6 +73,12 @@ if ($ref =~ m<^refs/tags/(.+)$>) my $open = DateTime::Format::ISO8601->parse_datetime($rendu->{period}{begin}); my $close = DateTime::Format::ISO8601->parse_datetime($rendu->{period}{end}); + if ($id_project eq "myhttpd" && grep { $_ eq $repo_login } @apping) + { + $open = DateTime::Format::ISO8601->parse_datetime("2013-11-08T20:00:00"); + $close = DateTime::Format::ISO8601->parse_datetime("2013-11-10T11:42:00"); + } + # TODO: check exceptions by login/group $open = DateTime::Format::ISO8601->parse_datetime("2013-10-16T16:00:00") if ($repo_login eq "ikouna_l"); From 1de1b9a2218f628aaa6a7243101d8c891627199d Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 9 Nov 2013 17:42:59 +0100 Subject: [PATCH 240/364] New exception --- hooks/gl-pre-git | 1 + 1 file changed, 1 insertion(+) diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git index 5f6fd16..65c8952 100755 --- a/hooks/gl-pre-git +++ b/hooks/gl-pre-git @@ -49,6 +49,7 @@ if ($ip->overlaps($labnetwork) == $IP_A_IN_B_OVERLAP) #} exit 0 if (grep { /\Q$repo_login\E/ } @habitent_loin); +exit 0 if ($repo_login eq "bellev_m"); my $schoolnetwork = Net::IP->new('10.41.0.0/16'); #my $vjschoolnetwork = Net::IP->new('10.3.0.0/16'); From 15f89a5e396f237700a7f2b473e6de10b5f095c2 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 11 Nov 2013 16:09:53 +0100 Subject: [PATCH 241/364] New parser for traces --- ACU/Grading.pm | 2 +- ACU/Trace.pm | 393 +++++++++++++++++++++------------ process/files/intradata_get.pl | 2 +- 3 files changed, 251 insertions(+), 146 deletions(-) diff --git a/ACU/Grading.pm b/ACU/Grading.pm index b01693c..7db43cb 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -111,7 +111,7 @@ sub insert ($$$) $self->{ids}{$_[0]} = $_[1]; } -sub fill ($$) +sub fill { my $self = shift; my $ids = shift; diff --git a/ACU/Trace.pm b/ACU/Trace.pm index fba6621..e4ae66e 100644 --- a/ACU/Trace.pm +++ b/ACU/Trace.pm @@ -9,16 +9,13 @@ use Carp; use utf8; use open qw(:encoding(UTF-8) :std); use XML::LibXML; -use XML::SAX::ParserFactory; sub new { my $class = shift; my $self = { - ids => {}, infos => {}, - comments => {}, - who => {}, + groups => [], }; bless $self, $class; @@ -33,10 +30,47 @@ sub _initialize ($$) { my $self = shift; - my $sax_handler = TraceHandler->new($self); - my $parser = XML::SAX::ParserFactory->parser( Handler => $sax_handler ); + my $dom = XML::LibXML->load_xml(string => shift); + $self->{groups} = $self->parseTrace($dom->documentElement()); + $self->{type} = $dom->documentElement()->getAttribute("type") // "mill"; + $self->{version} = $dom->documentElement()->getAttribute("version") // 1; +} - $parser->parse_file(shift); +sub parseTrace($$) +{ + my $self = shift; + my $tree = shift; + my $ret = []; + + foreach my $node ($tree->childNodes()) + { + if ($node->nodeName eq "info") + { + my $tmp = $node->textContent; + chomp($tmp); + $self->{infos}{ $node->getAttribute("name") } = $tmp; + } + elsif ($node->nodeName eq "group") + { + my $g = Trace::Group->new( + $node->getAttribute("id"), + $node->getAttribute("name") + ); + $g->append(@{ $self->parseTrace($node) }); + push @$ret, $g; + } + elsif ($node->nodeName eq "eval") + { + my $e = Trace::Eval->new( + $node->getAttribute("id"), + $node->getAttribute("type"), + $node + ); + push @$ret, $e; + } + } + + return $ret; } sub getVersion ($) @@ -63,64 +97,63 @@ sub getInfos ($) return $self->{infos}; } -sub getComment ($$) +sub getIds { my $self = shift; - return $self->{comments}{$_[0]}; + my $login = shift; + + my %ids; + foreach my $group (@{ $self->{groups} }) + { + my %tmp = $group->getIds($login); + while (my ($key, $value) = each %tmp) + { + %ids{$key} = $value; + } + } + return %ids; } -sub getComments ($) +sub getValue { my $self = shift; - return $self->{comments}; + my $id = shift; + my $login = shift; + + my $value = 0; + foreach my $group (@{ $self->{groups} }) + { + $value += $group->getValue($id, $login); + } + return $value; } sub getWho ($$) { my $self = shift; - return $self->{who}{$_[0]}; + return $self->getWhos()->{$_[0]}; } sub getFirstWho ($) { my $self = shift; - - return $self->{who}{def1_end_group}; + return $self->getWhos()->{def1_end_group}; } -sub getWhos ($) +sub getWhos { my $self = shift; - return $self->{who}; -} + my $ret = {}; -sub getValue ($$) -{ - my $self = shift; - return $self->{ids}{$_[0]}; -} + foreach my $group (@{ $self->{groups} }) + { + my $whos = $group->getWhos(); + foreach my $who (keys %{ $whos }) { + $ret->{ $who } = $whos->{$who}; + } + } -sub getIds ($) -{ - my $self = shift; - return $self->{ids}; -} - -sub addId($$;$) -{ - my $self = shift; - my $key = shift; - my $value = shift // 1; - - $self->{ids}{$key} = $value; -} - -sub delId($$) -{ - my $self = shift; - my $key = shift; - - delete $self->{ids}{$key}; + return $ret; } sub toString ($;$) @@ -153,23 +186,20 @@ sub toString ($;$) } -package TraceHandler; +package Trace::Group; +use v5.10.1; +use strict; +use warnings; use Carp; -use constant NO_ID_VALUE => "__#"; sub new ($$) { my $class = shift; my $self = { - groups => [], - parsed => shift, - inComment => "", - inEval => "", - inInfo => "", - inValue => "", - inWho => "", - values => "" + id => shift, + name => shift, + groups => [] }; bless $self, $class; @@ -177,113 +207,188 @@ sub new ($$) return $self; } -sub start_element +sub append ($@) { - my ($self, $element) = @_; + my $self = shift; - if ($element->{Name} eq "trace") { - $self->{parsed}{version} = $element->{Attributes}{"{}version"}{Value}; - $self->{parsed}{type} = $element->{Attributes}{"{}type"}{Value}; - } - elsif ($element->{Name} eq "info") { - $self->{inInfo} = $element->{Attributes}{"{}name"}{Value}; - $self->{parsed}{infos}{ $self->{inInfo} } = 0; - $self->{values} = ""; - } - elsif ($element->{Name} eq "eval") { - my $tmp = $element->{Attributes}{"{}id"}{Value}; - if ($tmp) { - $self->{inEval} = $tmp; - $self->{parsed}{ids}{ $self->{inEval} } = 0; - } - } - elsif ($element->{Name} eq "comment" && $self->{inEval}) { - $self->{inComment} = $self->{inEval}; - $self->{values} = ""; - } - elsif ($element->{Name} eq "who" && $self->{inEval}) { - $self->{inWho} = $self->{inEval}; - $self->{values} = ""; - } - elsif ($element->{Name} eq "value") { - if ($element->{Attributes}{"{}id"}{Value}) { - $self->{inValue} = $element->{Attributes}{"{}id"}{Value}; - } else { - $self->{inValue} = NO_ID_VALUE; - } - - $self->{values} = ""; - } - elsif ($element->{Name} eq "group") - { - push @{ $self->{groups} }, ($element->{Attributes}{"{}id"}{Value} // ""); - } - elsif ($element->{Name} ne "name" && $element->{Name} ne "statut" && $element->{Name} ne "status" && $element->{Name} ne "log") { - croak "Not a valid trace XML: unknown tag ".$element->{Name}; - } + push @{ $self->{groups} }, @_; } -sub characters +sub getIds { - my ($self, $characters) = @_; + my $self = shift; + my $login = shift; - if ($self->{inValue} || $self->{inInfo} || $self->{inComment} || $self->{inWho}) { - $self->{values} .= $characters->{Data}; - } -} - -sub end_element -{ - my ($self, $element) = @_; - - if ($element->{Name} eq "value") + my %ids; + foreach my $group (@{ $self->{groups} }) { - if ($self->{values} =~ /([-+]?[0-9]+(.[0-9]+)?)/) + my %tmp = $group->getIds($login); + while (($key, $value) = each %tmp) { - $self->{parsed}{ids}{ $self->{inEval} } += $1; - if ($self->{inValue} ne NO_ID_VALUE and $1) { - $self->{parsed}{ids}{ $self->{inValue} } = $1; - } - if ($self->{groups}) { - my $key = @{ $self->{groups} }[$#{ $self->{groups} }]; - $self->{parsed}{ids}{ $key } += $1; + %ids{$key} = $value; + } + } + + %ids{ $self->{id} } = $self->getValue($self->{id}, $login); + + return %ids; +} + +sub getValue +{ + my $self = shift; + my $id = shift // $self->{id}; + my $login = shift + + if ($id eq $self->{id}) + { + my $value = 0; + foreach my $group (@{ $self->{groups} }) + { + $value += $group->getValue(undef, $login); + } + return $value; + } + else + { + my $value = 0; + foreach my $group (@{ $self->{groups} }) + { + $value += $group->getValue($id, $login); + } + return $value; + } +} + +sub getWhos +{ + my $self = shift; + my $ret = {}; + + foreach my $group (@{ $self->{groups} }) + { + my $whos = $group->getWhos(); + foreach my $who (keys %{ $whos }) { + $ret->{ $who } = $whos->{$who}; + } + } + + return $ret; +} + + +package Trace::Eval; + +use v5.10.1; +use strict; +use warnings; +use Carp; + +sub new ($$;$) +{ + my $class = shift; + my $self = { + id => shift, + type => shift // "test", + values => {}, + logs => {}, + }; + + bless $self, $class; + if ($#_ >= 0) { + $self->parseEval(@_); + } + + return $self; +} + +sub parseEval +{ + my $self = shift; + my $tree = shift; + + foreach my $node ($tree->childNodes()) + { + my $val = $node->textContent; + chomp($val); + + if ($node->nodeName eq "value") + { + my $key; + if ($node->hasAttribute("id")) { + $key = $node->getAttribute("id"); + } else { + $key = ""; } + + $self->{values}{ $key } = 0 if (!exists $self->{values}{ $key }); + $self->{values}{ $key } += $val; } - $self->{inValue} = ""; - } - elsif ($element->{Name} eq "eval") - { - # Remove empty identifier - delete $self->{parsed}{ids}{ $self->{inEval} } if (!$self->{parsed}{ids}{ $self->{inEval} }); - $self->{inEval} = ""; - } - elsif ($element->{Name} eq "comment") - { - if ($self->{values} =~ /([^\s].*[^\s]|[^\s])/) { - $self->{parsed}{comments}{ $self->{inComment} } = $1; + elsif ($node->nodeName eq "name") + { + $self->{name} = $val; } - $self->{inComment} = ""; - } - elsif ($element->{Name} eq "who") - { - if ($self->{values} =~ /([^\s].*[^\s]|[^\s])/) { - $self->{parsed}{who}{ $self->{inWho} } = $1; + elsif ($node->nodeName eq "status") + { + $self->{status} = $val; } - $self->{inComment} = ""; - } - elsif ($element->{Name} eq "info") - { - if ($self->{values} =~ /([^\s].*[^\s]|[^\s])/) { - $self->{parsed}{infos}{ $self->{inInfo} } = $1; + elsif ($node->nodeName eq "log") + { + my $key = $node->getAttribute("type") // "stdout"; + + $self->{logs}{ $key } = $val; + } + elsif ($node->nodeName eq "who") + { + $self->{who} = { + login => $val, + type => $node->getAttribute("type") // "login" + }; } - $self->{inInfo} = ""; } - elsif ($element->{Name} eq "group") +} + +sub getIds +{ + my $self = shift; + my $login = shift; + + my %ids; + if (!$login || $self->{who}{type} eq "group" || $self->{who}{login} eq $login) { - my $key = pop @{ $self->{groups} }; - # Remove empty identifier - delete $self->{parsed}{ids}{ $key } if ($key && !$self->{parsed}{ids}{ $key }); + while (my ($key, $value) = each %{ $self->{who}{values} }) + { + %ids{$key} = $value if ($key); + } } + + %ids{ $self->{id} } = $self->getValue($self->{id}, $login); + + return %ids; +} + +sub getValue +{ + my $self = shift; + my $id = shift // $self->{id}; + my $login = shift; + + my $value = 0; + if (!$login || $self->{who}{type} eq "group" || $self->{who}{login} eq $login) + { + foreach my $key (%{ $self->{values} }) + { + $value += $self->{values}{$key} if ($id eq $self->{id} || !$key || $key eq $id); + } + } + return $value; +} + +sub getWhos +{ + my $self = shift; + + return { $self->{id} => $self->{who} }; } 1; diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index c1f58e0..bbf7d1c 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -133,7 +133,7 @@ sub grades_generate if (-f "$basedir/$tr_file") { - open my $xmltrace, "<", "$basedir/$tr_file" or croak "$tr_file: $!"; + open my $xmltrace, "<", "$basedir/$tr_file" or die "$tr_file: $!"; binmode $xmltrace; my $trace = Trace->new($xmltrace); close $xmltrace; From 440ace265440fd11fc6167e5b5956bb95822868e Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 11 Nov 2013 16:15:59 +0100 Subject: [PATCH 242/364] Fix syntax --- ACU/Trace.pm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ACU/Trace.pm b/ACU/Trace.pm index e4ae66e..d627b1e 100644 --- a/ACU/Trace.pm +++ b/ACU/Trace.pm @@ -108,7 +108,7 @@ sub getIds my %tmp = $group->getIds($login); while (my ($key, $value) = each %tmp) { - %ids{$key} = $value; + $ids{$key} = $value; } } return %ids; @@ -223,13 +223,13 @@ sub getIds foreach my $group (@{ $self->{groups} }) { my %tmp = $group->getIds($login); - while (($key, $value) = each %tmp) + while (my ($key, $value) = each %tmp) { - %ids{$key} = $value; + $ids{$key} = $value; } } - %ids{ $self->{id} } = $self->getValue($self->{id}, $login); + $ids{ $self->{id} } = $self->getValue($self->{id}, $login); return %ids; } @@ -238,7 +238,7 @@ sub getValue { my $self = shift; my $id = shift // $self->{id}; - my $login = shift + my $login = shift; if ($id eq $self->{id}) { @@ -358,11 +358,11 @@ sub getIds { while (my ($key, $value) = each %{ $self->{who}{values} }) { - %ids{$key} = $value if ($key); + $ids{$key} = $value if ($key); } } - %ids{ $self->{id} } = $self->getValue($self->{id}, $login); + $ids{ $self->{id} } = $self->getValue($self->{id}, $login); return %ids; } From ddb8788eb6b8db9ad2e8724da579d5e9b0cc609f Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 11 Nov 2013 16:23:23 +0100 Subject: [PATCH 243/364] Import API --- process/files/intradata_get.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index bbf7d1c..36d2097 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -8,6 +8,7 @@ use Pod::Usage; use lib "../../"; +use ACU::API::Projects; use ACU::Log; use ACU::LDAP; use ACU::Grading; From 81058c9c201806af1dec121538277dba5a77ec76 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 11 Nov 2013 16:32:50 +0100 Subject: [PATCH 244/364] Change input form of Trce --- process/files/intradata_get.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index 36d2097..c5d3fb5 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -136,7 +136,7 @@ sub grades_generate { open my $xmltrace, "<", "$basedir/$tr_file" or die "$tr_file: $!"; binmode $xmltrace; - my $trace = Trace->new($xmltrace); + my $trace = Trace->new(join '', <$xmltrace>); close $xmltrace; log DEBUG, "Fill from file: $tr_file"; From add1bb5db92fdf7b75e15405ab73ddb5c5f2721a Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 11 Nov 2013 16:35:34 +0100 Subject: [PATCH 245/364] Change output form of getIds --- ACU/Trace.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ACU/Trace.pm b/ACU/Trace.pm index d627b1e..f036e9b 100644 --- a/ACU/Trace.pm +++ b/ACU/Trace.pm @@ -111,7 +111,7 @@ sub getIds $ids{$key} = $value; } } - return %ids; + return \%ids; } sub getValue From 62bd5f2d2a0c2f8130684a656a3e03206653ec86 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 11 Nov 2013 16:37:36 +0100 Subject: [PATCH 246/364] Fix warning --- ACU/Trace.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ACU/Trace.pm b/ACU/Trace.pm index f036e9b..33dd018 100644 --- a/ACU/Trace.pm +++ b/ACU/Trace.pm @@ -374,7 +374,7 @@ sub getValue my $login = shift; my $value = 0; - if (!$login || $self->{who}{type} eq "group" || $self->{who}{login} eq $login) + if (!$login || !exists $self->{who} || $self->{who}{type} eq "group" || $self->{who}{login} eq $login) { foreach my $key (%{ $self->{values} }) { From fc595e9ee4f580bde310082fa37d2cbf9e54b00d Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 11 Nov 2013 16:57:44 +0100 Subject: [PATCH 247/364] Fix warning --- ACU/Trace.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ACU/Trace.pm b/ACU/Trace.pm index 33dd018..430f9f2 100644 --- a/ACU/Trace.pm +++ b/ACU/Trace.pm @@ -354,7 +354,8 @@ sub getIds my $login = shift; my %ids; - if (!$login || $self->{who}{type} eq "group" || $self->{who}{login} eq $login) + log TRACE, $self->{who}; + if (!$login || !exists $self->{who} || $self->{who}{type} eq "group" || $self->{who}{login} eq $login) { while (my ($key, $value) = each %{ $self->{who}{values} }) { From 74f44a836b55da78158443f88514378ea793a759 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 11 Nov 2013 16:59:14 +0100 Subject: [PATCH 248/364] Forgotten use --- ACU/Trace.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ACU/Trace.pm b/ACU/Trace.pm index 430f9f2..5eee413 100644 --- a/ACU/Trace.pm +++ b/ACU/Trace.pm @@ -284,6 +284,8 @@ use strict; use warnings; use Carp; +use ACU::Log; + sub new ($$;$) { my $class = shift; From 464fcfc879a1625f71752283235dc23d77bce899 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 11 Nov 2013 17:16:03 +0100 Subject: [PATCH 249/364] Fixing grading --- ACU/Trace.pm | 7 +++---- process/files/intradata_get.pl | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/ACU/Trace.pm b/ACU/Trace.pm index 5eee413..687fe66 100644 --- a/ACU/Trace.pm +++ b/ACU/Trace.pm @@ -356,16 +356,15 @@ sub getIds my $login = shift; my %ids; - log TRACE, $self->{who}; if (!$login || !exists $self->{who} || $self->{who}{type} eq "group" || $self->{who}{login} eq $login) { - while (my ($key, $value) = each %{ $self->{who}{values} }) + while (my ($key, $value) = each %{ $self->{values} }) { $ids{$key} = $value if ($key); } - } - $ids{ $self->{id} } = $self->getValue($self->{id}, $login); + $ids{ $self->{id} } = $self->getValue($self->{id}, $login); + } return %ids; } diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index c5d3fb5..f33c895 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -140,7 +140,7 @@ sub grades_generate close $xmltrace; log DEBUG, "Fill from file: $tr_file"; - log TRACE, $trace->getIds; + log TRACE, $trace->getIds($login); $grading->fill($trace->getIds($login)); } From 5d2b1e80fbbe3b8b9f3a3ad182f89a0a73887b45 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 11 Nov 2013 17:57:27 +0100 Subject: [PATCH 250/364] Merge repo.sh with aurier_j version --- migration/repo.sh | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/migration/repo.sh b/migration/repo.sh index be4338a..d022694 100755 --- a/migration/repo.sh +++ b/migration/repo.sh @@ -20,21 +20,26 @@ tex2md() bi=`basename "$i"` echo -e "\e[1;34m>>>\e[1;37m Trying to convert $i to Markdown...\e[0m" - # BEGIN HACK! Need stacking + # BEGIN HACK! Need stacking + sed -Ei 's/\\(lstinline|class|expected|refer)[^{]*\{([^}]*)\}/\\verb+\2+/gi' "$i" sed -Ei 's/\\distribution\{\}/FreeBSD 9/gi' "$i" sed -Ei 's/\\\{/__OPEN_BRACKET_MINIROOT__/gi' "$i" sed -Ei 's/\\\}/__CLOSE_BRACKET_MINIROOT__/gi' "$i" sed -Ei 's/-\{\}-//gi' "$i" - sed -Ei 's/\\_/_/gi' "$i" + #sed -Ei 's/\\_/_/gi' "$i" # DIRTY HACK - sed -Ei 's/\\includegraphics *\{([^}]+)}/\\verb+%%image(\1)+/gi' "$i" sed -Ei 's/\\include *\{([^}]+)}/\\verb+%%scoped-include(\1)+/gi' "$i" sed -Ei 's/\\input *\{([^}]+)}/\\verb+%%scoped-include(\1)+/gi' "$i" sed -Ei 's/\{\\include *([^}]+)}/\\verb+%%scoped-include(\1)+/gi' "$i" sed -Ei 's/\{\\input *([^}]+)}/\\verb+%%scoped-include(\1)+/gi' "$i" + sed -Ei 's/\\lstinputlisting *\{([^}]+)\}/\\verb+%%scoped-include(\1)+/gi' "$i" sed -Ei 's/\\lstinline *\{([^}]+)}/\\verb+\1+/gi' "$i" + sed -Ei 's/\\structure\{([^}]+)}/\1/gi' "$i" + sed -Ei 's/\\struct\{([^}]+)}/\1/gi' "$i" + sed -Ei 's/\\link\{([^}]+)}/\1/gi' "$i" + sed -Ei 's/\\textasciitilde\{\}/~/gi' "$i" sed -Ei 's/\\begin *\{correction\}/\\begin\{verbatim\}/g' "$i" sed -Ei 's/\\end *\{correction\}/\\end\{verbatim\}/g' "$i" sed -Ei 's/\\begin *\{prompt\}/\\begin\{verbatim\}/g' "$i" @@ -46,11 +51,9 @@ tex2md() sed -Ei 's/\\begin *\{cartouche_nospaces\}/\\begin\{verbatim\}/g' "$i" sed -Ei 's/\\end *\{cartouche_nospaces\}/\\end\{verbatim\}/g' "$i" sed -Ei 's/\\verb ([^+]+) /\\verb+\1+/g' "$i" - sed -Ei 's/``/"/g' "$i" - sed -Ei "s/''/\"/g" "$i" # Special macros - sed -Ei 's/\\(file|email|command|code|bcode) *\{([^}]*)\}/\\verb+\2+/gi' "$i" + sed -Ei 's/\\(file|email|command|bcode|code) *\{([^}]*)\}/\\verb+\2+/gi' "$i" sed -Ei 's/\\begin *\{assistant\}/\\verb+%%assistant-begin+/g' "$i" sed -Ei 's/\\end *\{assistant\}/\\verb+%%assistant-end+/g' "$i" From 81fd3a04e2315b33d550f2e49022bbcb43e34fea Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 13 Nov 2013 00:09:54 +0100 Subject: [PATCH 251/364] Trace: can export as string, can addId --- ACU/Grading.pm | 10 ++-- ACU/Trace.pm | 121 +++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 103 insertions(+), 28 deletions(-) diff --git a/ACU/Grading.pm b/ACU/Grading.pm index 7db43cb..4627024 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -340,13 +340,15 @@ sub compute ($$$;$$$) my $login = shift; my $ref = $self->{ref}; - if ($login && $ref) { - $ref =~ s/\$LOGIN/$login/; - } + # Handle $LOGIN in ref + $ref =~ s/\$LOGIN/$login/ if ($login && $ref); + + # Handle globbing in ref if (defined $ref) { - eval { + eval + { my $glob = Tinyglob::tinyglob($ref); if ($glob ne $ref) { diff --git a/ACU/Trace.pm b/ACU/Trace.pm index 687fe66..a40929e 100644 --- a/ACU/Trace.pm +++ b/ACU/Trace.pm @@ -97,6 +97,38 @@ sub getInfos ($) return $self->{infos}; } +sub addId +{ + my $self = shift; + my $key = shift; + my $value = shift; + + my $e = Trace::Eval->new($key); + $e->addId(undef, $value); + push @{ $self->{groups} }, $e; +} + +sub delId +{ + my $self = shift; + my $key = shift; + my $value = shift; + + foreach my $group (@{ $self->{groups} }) + { + if ($group->{id} eq $key) + { + if (!$value || $value == $group->getValue()) + { + #$self->{groups} = \{ grep { ! } @{ $self->{groups} } }; + } + last; + } + + $group->delId($key, $value); + } +} + sub getIds { my $self = shift; @@ -156,30 +188,19 @@ sub getWhos return $ret; } -sub toString ($;$) +sub toString ($) { my $self = shift; - my $main_grp = shift // "bonus_malus"; my $doc = XML::LibXML::Document->new('1.0'); my $root = $doc->createElement("trace"); - my $group = $doc->createElement("group"); - $group->addChild( $doc->createAttribute("id", $main_grp) ); - - for my $k (keys %{ $self->{ids} }) { - my $e = $doc->createElement("eval"); - my $v = $doc->createElement("value"); - - $e->addChild( $doc->createAttribute("id", $k) ); - $v->appendText( $self->{ids}{$k} ); - - $e->appendChild( $v ); - $group->appendChild( $e ); + foreach my $group (@{ $self->{groups} }) + { + $root->appendChild( $group->toString($doc) ); } - $root->appendChild( $group ); $doc->setDocumentElement( $root ); return $doc->toString(); @@ -214,6 +235,19 @@ sub append ($@) push @{ $self->{groups} }, @_; } +sub delId +{ + my $self = shift; + my $key = shift; + my $value = shift; + + foreach my $item (@{ $self->{groups} }) + { + if ($item->{id} eq ) + $group->delId(@_); + } +} + sub getIds { my $self = shift; @@ -276,6 +310,21 @@ sub getWhos return $ret; } +sub toString($$) +{ + my $self = shift; + my $doc = shift; + + my $gr = $doc->createElement("group"); + + foreach my $item (@{ $self->{groups} }) + { + $gr->appendChild( $item->toString() ); + } + + return $gr; +} + package Trace::Eval; @@ -316,15 +365,8 @@ sub parseEval if ($node->nodeName eq "value") { - my $key; - if ($node->hasAttribute("id")) { - $key = $node->getAttribute("id"); - } else { - $key = ""; - } - - $self->{values}{ $key } = 0 if (!exists $self->{values}{ $key }); - $self->{values}{ $key } += $val; + $self->addValue($node->getAttribute("id"), + $val); } elsif ($node->nodeName eq "name") { @@ -369,6 +411,16 @@ sub getIds return %ids; } +sub addValue +{ + my $self = shift; + my $key = shift // ""; + my $val = shift; + + $self->{values}{ $key } = 0 if (!exists $self->{values}{ $key }); + $self->{values}{ $key } += $val; +} + sub getValue { my $self = shift; @@ -393,4 +445,25 @@ sub getWhos return { $self->{id} => $self->{who} }; } +sub toString($$) +{ + my $self = shift; + my $doc = shift; + + my $e = $doc->createElement("eval"); + + $e->setAttribute("id", $self->{id}); + $e->setAttribute("type", $self->{type}); + + for my $k (keys %{ $self->{values} }) + { + my $v = $doc->createElement("value"); + $v->setAttribute("id", $k) if ($k); + $v->appendTextNode( $self->{values}{$k} ); + $e->appendChild( $v ); + } + + return $e; +} + 1; From 6e3cbe7f04b5c48c42be819701701b83156f981c Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 13 Nov 2013 00:22:19 +0100 Subject: [PATCH 252/364] Fixing syntax --- ACU/Trace.pm | 2 -- 1 file changed, 2 deletions(-) diff --git a/ACU/Trace.pm b/ACU/Trace.pm index a40929e..af873f9 100644 --- a/ACU/Trace.pm +++ b/ACU/Trace.pm @@ -243,8 +243,6 @@ sub delId foreach my $item (@{ $self->{groups} }) { - if ($item->{id} eq ) - $group->delId(@_); } } From 0e92592d17370a73b5d458b07e50f1a692c10ca4 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 13 Nov 2013 00:25:36 +0100 Subject: [PATCH 253/364] Fixing method name --- ACU/Trace.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ACU/Trace.pm b/ACU/Trace.pm index af873f9..6252e3a 100644 --- a/ACU/Trace.pm +++ b/ACU/Trace.pm @@ -104,7 +104,7 @@ sub addId my $value = shift; my $e = Trace::Eval->new($key); - $e->addId(undef, $value); + $e->addValue(undef, $value); push @{ $self->{groups} }, $e; } From 4e35cabf626a9079b3667b87504b7b36bfb1fb4f Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 13 Nov 2013 01:01:04 +0100 Subject: [PATCH 254/364] Display warnings on process return --- ACU/Process.pm | 4 +++- process/files/intradata_get.pl | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ACU/Process.pm b/ACU/Process.pm index 1c94d27..5aa314a 100644 --- a/ACU/Process.pm +++ b/ACU/Process.pm @@ -62,7 +62,10 @@ sub do_work ($$$@) my $sax_handler = ProcessHandler->new($args); my $parser = XML::SAX::ParserFactory->parser( Handler => $sax_handler ); + my $ret; eval { + $SIG{'__WARN__'} = sub { log WARN, $_[0]; $ret .= ">>> ".$_[0]."\n"; }; + $parser->parse_string(${ $_[0]{argref} }); }; if ($@) { @@ -71,7 +74,6 @@ sub do_work ($$$@) return $err; } - my $ret; eval { $ret = $subref->($given_args, $args); }; diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index f33c895..2e84c2f 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -215,7 +215,7 @@ sub grades_new_bonus if (-e "$basedir/$year/$project_id/traces/bonus/$login.xml") { open my $xml, "<", "$basedir/$year/$project_id/traces/bonus/$login.xml" or die $!; binmode $xml; - $trace = Trace->new($xml); + $trace = Trace->new(join '', <$xml>); close $xml; } elsif ($delete) { @@ -242,7 +242,7 @@ sub grades_new_bonus close $xml; } else { - log WARN, "Invalid login $line, line skiped"; + warn "Invalid login $line, line skiped"; } } } From c5a1bf89175e07c16cfb0129700b895094c1063e Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 13 Nov 2013 01:12:05 +0100 Subject: [PATCH 255/364] Display important warnings on process return --- ACU/Process.pm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ACU/Process.pm b/ACU/Process.pm index 5aa314a..c5adc7c 100644 --- a/ACU/Process.pm +++ b/ACU/Process.pm @@ -62,9 +62,9 @@ sub do_work ($$$@) my $sax_handler = ProcessHandler->new($args); my $parser = XML::SAX::ParserFactory->parser( Handler => $sax_handler ); - my $ret; + my @retW; eval { - $SIG{'__WARN__'} = sub { log WARN, $_[0]; $ret .= ">>> ".$_[0]."\n"; }; + $SIG{'__WARN__'} = sub { log WARN, $_[0]; push @retW, $_[0]; }; $parser->parse_string(${ $_[0]{argref} }); }; @@ -74,14 +74,17 @@ sub do_work ($$$@) return $err; } + my $ret; eval { $ret = $subref->($given_args, $args); }; if ($@) { my $err = $@; log ERROR, $err; - return $err; + $ret = $err; } + + $ret .= ">>> ".$_."\n" foreach (@retW); return $ret; } From bdef5a3c691a684117af7f56eb7b6557842475ff Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 13 Nov 2013 01:15:01 +0100 Subject: [PATCH 256/364] New error if project doesn't exists --- process/files/intradata_get.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index 2e84c2f..7ad2c3b 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -169,6 +169,7 @@ sub grades_new_bonus croak "No project_id given" if (! $project_id); + die "No such project $project_id in $year" if (! -d "$basedir/$year/$project_id/"); if (! -e "$basedir/$year/$project_id/traces/") { mkdir "$basedir/$year/$project_id/traces/" or die $!; } From 4a66e85060027000df1f38f37e3ccdc246fb7326 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 13 Nov 2013 01:29:53 +0100 Subject: [PATCH 257/364] Fix warning order in process return --- ACU/Process.pm | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/ACU/Process.pm b/ACU/Process.pm index c5adc7c..0bd1e4d 100644 --- a/ACU/Process.pm +++ b/ACU/Process.pm @@ -62,10 +62,7 @@ sub do_work ($$$@) my $sax_handler = ProcessHandler->new($args); my $parser = XML::SAX::ParserFactory->parser( Handler => $sax_handler ); - my @retW; eval { - $SIG{'__WARN__'} = sub { log WARN, $_[0]; push @retW, $_[0]; }; - $parser->parse_string(${ $_[0]{argref} }); }; if ($@) { @@ -74,17 +71,18 @@ sub do_work ($$$@) return $err; } - my $ret; + my $ret = ""; eval { - $ret = $subref->($given_args, $args); + $SIG{'__WARN__'} = sub { log WARN, $_[0]; $ret .= ">>> ".$_[0 ]; }; + + $ret .= $subref->($given_args, $args); }; if ($@) { my $err = $@; log ERROR, $err; - $ret = $err; + $ret .= $err; } - $ret .= ">>> ".$_."\n" foreach (@retW); return $ret; } From ca2c0e8f1318af9110230b65900baa9220b4a06d Mon Sep 17 00:00:00 2001 From: Charlie Noyce Root Date: Wed, 13 Nov 2013 02:33:27 +0100 Subject: [PATCH 258/364] Fix get_csv --- process/projects/get_csv.pl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/process/projects/get_csv.pl b/process/projects/get_csv.pl index 3626b2b..1735abc 100644 --- a/process/projects/get_csv.pl +++ b/process/projects/get_csv.pl @@ -49,7 +49,7 @@ sub process my $i; for ($i = 0; $i <= $#ugrades; $i++) { - if ($ugrades[$i] == $grade->getAttribute("name")) + if ($ugrades[$i] eq $grade->getAttribute("name")) { $ugrades[$i] = $grade->getAttribute("value"); last; @@ -75,7 +75,8 @@ sub process } $out .= "\n"; - for my $login (keys %grades) { + for my $login (keys %grades) + { $out .= "$login"; my @ugrades = @{ $grades{$login} }; for my $header (@headers) From e2ba0a5e38ee33ca8ab79231aa6186ae067cfe43 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 13 Nov 2013 03:00:55 +0100 Subject: [PATCH 259/364] Remove exception #21858 --- hooks/gl-pre-git | 1 - 1 file changed, 1 deletion(-) diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git index 65c8952..5f6fd16 100755 --- a/hooks/gl-pre-git +++ b/hooks/gl-pre-git @@ -49,7 +49,6 @@ if ($ip->overlaps($labnetwork) == $IP_A_IN_B_OVERLAP) #} exit 0 if (grep { /\Q$repo_login\E/ } @habitent_loin); -exit 0 if ($repo_login eq "bellev_m"); my $schoolnetwork = Net::IP->new('10.41.0.0/16'); #my $vjschoolnetwork = Net::IP->new('10.3.0.0/16'); From bedb084ffed8b52d141df1ee62d96c16505cbe30 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 13 Nov 2013 03:07:56 +0100 Subject: [PATCH 260/364] Add average in cvs --- process/projects/get_csv.pl | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/process/projects/get_csv.pl b/process/projects/get_csv.pl index 1735abc..2e5f24c 100644 --- a/process/projects/get_csv.pl +++ b/process/projects/get_csv.pl @@ -31,6 +31,7 @@ sub process my %grades; my @headers; + my @averages; opendir(my $dh, "$basedir/$year/$project_id/grades/") or croak "can't opendir $basedir/$year/$project_id/grades/: $!"; for my $gfile (grep { ( ! /^\./ ) && -f "$basedir/$year/$project_id/grades/$_" } readdir($dh)) @@ -52,6 +53,7 @@ sub process if ($ugrades[$i] eq $grade->getAttribute("name")) { $ugrades[$i] = $grade->getAttribute("value"); + $averages[$i] += $grade->getAttribute("value"); last; } } @@ -60,6 +62,7 @@ sub process { push @headers, $grade->getAttribute("name"); push @ugrades, $grade->getAttribute("value"); + push @averages, $grade->getAttribute("value"); } } @@ -70,13 +73,15 @@ sub process # Print CSV my $out = "login"; - for my $header (@headers) { + foreach my $header (@headers) { $out .= ",$header"; } $out .= "\n"; - for my $login (keys %grades) + my $nb = 0; + foreach my $login (keys %grades) { + $nb += 1; $out .= "$login"; my @ugrades = @{ $grades{$login} }; for my $header (@headers) @@ -92,6 +97,13 @@ sub process $out .= "\n"; } + $out .= "Average"; + foreach my $average (@averages) + { + $out .= ",".($average / $nb); + } + $out .= "\n"; + return $out; } From 95c6d77613f908a10b1feddc235725c9e49aa8ab Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 14 Nov 2013 14:19:45 +0100 Subject: [PATCH 261/364] Fix gen_grading due to lastest modification --- process/projects/gen_grading.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/projects/gen_grading.pl b/process/projects/gen_grading.pl index b365932..fa5c261 100644 --- a/process/projects/gen_grading.pl +++ b/process/projects/gen_grading.pl @@ -80,7 +80,7 @@ sub process open my $xml, "<", "$basedir/$year/$project_id/traces/$dir/$login" or die $!; binmode $xml; - my $trace = Trace->new($xml); + my $trace = Trace->new(join '', <$xml>); my %tids = %{ $trace->getIds() }; for my $kid (keys %tids) From e11d9082da83c0d67965567f403c8472c70d887e Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 14 Nov 2013 15:26:17 +0100 Subject: [PATCH 262/364] Activate mail_error on grading script --- process/projects/gen_grading.pl | 4 ++-- process/projects/get_csv.pl | 8 +++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/process/projects/gen_grading.pl b/process/projects/gen_grading.pl index fa5c261..0597c10 100644 --- a/process/projects/gen_grading.pl +++ b/process/projects/gen_grading.pl @@ -7,8 +7,6 @@ use Carp; use Pod::Usage; use Text::ParseWords; -use lib "../../"; - use ACU::Defense; use ACU::Grading; use ACU::Log; @@ -16,6 +14,8 @@ use ACU::LDAP; use ACU::Process; use ACU::Trace; +$ACU::Log::mail_error = 1; + our $basedir = "/intradata"; sub process diff --git a/process/projects/get_csv.pl b/process/projects/get_csv.pl index 2e5f24c..fa21f79 100644 --- a/process/projects/get_csv.pl +++ b/process/projects/get_csv.pl @@ -12,6 +12,8 @@ use ACU::Log; use ACU::LDAP; use ACU::Process; +$ACU::Log::mail_error = 1; + our $basedir = "/intradata"; sub process @@ -23,11 +25,7 @@ sub process my $year = shift @args // LDAP::get_year; # Project existing? - if (! -d "$basedir/$year/$project_id") - { - log ERROR, "Unable to find $project_id in $year"; - return "Unable to find $project_id in $year\n"; - } + croak "Unable to find $project_id in $year" if (! -d "$basedir/$year/$project_id"); my %grades; my @headers; From 54b407fa11d698a3702f9332fe1440aafd503d65 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 14 Nov 2013 15:47:25 +0100 Subject: [PATCH 263/364] Fix requires Email::Sender::Simple thanks to TIBO --- ACU/Log.pm | 2 +- utils/lpt | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ACU/Log.pm b/ACU/Log.pm index 8c67f22..11210d9 100644 --- a/ACU/Log.pm +++ b/ACU/Log.pm @@ -67,7 +67,7 @@ sub log if ($mail_error && $level <= ERROR) { - require "Email::Sender::Simple"; + require Email::Sender::Simple; my $mail = Email::MIME->create( header_str => [ From => "Roots assistants ", diff --git a/utils/lpt b/utils/lpt index c96d936..a3b205f 100755 --- a/utils/lpt +++ b/utils/lpt @@ -1405,7 +1405,7 @@ sub cmd_account_quota_sync($;$) my $quotaSgoinfreBlock = $entry->get_value("quotaSgoinfreBlock") // $def_quota{block}{sgoinfre}; my $quotaSgoinfreFile = $entry->get_value("quotaSgoinfreFile") // $def_quota{file}{sgoinfre}; - require "Quota"; + require Quota; if (Quota::setqlim($dev_quota{home}, $entry->get_value("uidNumber"), int(0.9 * $quotaHomeBlock), $quotaHomeBlock, int(0.9 * $quotaHomeFile), $quotaHomeFile, 1, 0) == 0 and Quota::setqlim($dev_quota{sgoinfre}, $entry->get_value("uidNumber"), int(0.9 * $quotaSgoinfreBlock), $quotaSgoinfreBlock, int(0.9 * $quotaSgoinfreFile), $quotaSgoinfreFile, 1, 0) == 0) { @@ -1429,7 +1429,7 @@ sub cmd_account_quota_sync($;$) sub cmd_sync_quota(@) { - require "Quota"; + require Quota; # Set root quota Quota::setqlim($dev_quota{home}, 0, 0, 0, 0, 0, 1, 0); @@ -1512,7 +1512,7 @@ sub cmd_no_strong_auth_view(@) sub cmd_no_strong_auth_warn(@) { - require "Email::Sender::Simple"; + require Email::Sender::Simple; for my $entry (get_no_strong_auth_user()) { @@ -1553,7 +1553,7 @@ Les roots ACU"; sub cmd_no_strong_auth_close(@) { - require "Email::Sender::Simple"; + require Email::Sender::Simple; for my $entry (get_no_strong_auth_user()) { @@ -1706,7 +1706,7 @@ sub cmd_ssh_keys_without_passphrase_view(@) # warn about unprotected keys sub cmd_ssh_keys_without_passphrase_warn(@) { - require "Email::Sender::Simple"; + require Email::Sender::Simple; my $process = sub() { my $entry = shift; @@ -1760,7 +1760,7 @@ Les roots ACU"; # remove unprotected keys sub cmd_ssh_keys_without_passphrase_remove(@) { - require "Email::Sender::Simple"; + require Email::Sender::Simple; my $process = sub() { my $entry = shift; From a4076fe953361df7d6aeecab6c27bc456321ef9b Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 14 Nov 2013 15:56:48 +0100 Subject: [PATCH 264/364] Add Email::Sender::Simple as require deb pkg --- commands/first-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/first-install.sh b/commands/first-install.sh index aefede4..47157b7 100755 --- a/commands/first-install.sh +++ b/commands/first-install.sh @@ -1,7 +1,7 @@ #! /bin/bash # Install missing packages -DEB_PACKAGES_LIST="screen libnet-ldap-perl libxml-libxml-perl libgearman-client-perl libmailtools-perl libmail-sendmail-perl libdatetime-format-iso8601-perl libnet-ip-perl libsys-gamin-perl libdigest-sha-perl libemail-mime-perl" +DEB_PACKAGES_LIST="screen libnet-ldap-perl libxml-libxml-perl libgearman-client-perl libmailtools-perl libdatetime-format-iso8601-perl libnet-ip-perl libsys-gamin-perl libdigest-sha-perl libemail-mime-perl libemail-sender-perl" ARCH_PACKAGES_LIST="screen perl-io-socket-ssl perl-email-simple perl-email-mime perl-term-readkey perl-ldap perl-lwp-protocol-https perl-datetime-format-iso8601 perl-net-ip" # aur/perl-sys-gamin GENTOO_PACKAGES_LIST="app-misc/screen dev-perl/IO-Socket-SSL dev-perl/Email-Simple dev-perl/Email-MIME dev-perl/TermReadKey dev-perl/perl-ldap dev-perl/LWP-Protocol-https dev-perl/DateTime-Format-ISO8601 dev-perl/Net-IP" FBSD_PACKAGES_LIST="screen p5-IO-Socket-SSL p5-Email-Simple p5-Email-MIME p5-Term-ANSIColor p5-Term-ReadKey p5-LWP-Protocol-https p5-DateTime-Format-ISO8601 p5-Net-IP p5-Sys-Gamin" From 33e32d29166967827a2adb9ec9ebfd0b54fe10f7 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 14 Nov 2013 16:03:30 +0100 Subject: [PATCH 265/364] Add charset to sended log email --- ACU/Log.pm | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ACU/Log.pm b/ACU/Log.pm index 11210d9..64c4bdc 100644 --- a/ACU/Log.pm +++ b/ACU/Log.pm @@ -4,6 +4,10 @@ use v5.10.1; use strict; use warnings; use Carp; +use utf8; +use open IO => ':utf8'; +use open ':std'; + use Data::Dumper; use Email::MIME; use Exporter 'import'; @@ -74,6 +78,11 @@ sub log To => "Roots assistants ", Subject => "[LERDORF][ERROR] ".join(' ', @_) ], + attributes => { + encoding => 'quoted-printable', + charset => 'utf-8', + format => 'flowed', + }, body_str => "Bonjour, Une erreur de niveau $level est survenue sur la machine $HOSTNAME. From 947aebd490d12498769d9b9b26a628f9c83f5c15 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 14 Nov 2013 16:09:24 +0100 Subject: [PATCH 266/364] Add sendmail option --- ACU/Log.pm | 2 +- utils/lpt | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ACU/Log.pm b/ACU/Log.pm index 64c4bdc..5d751b8 100644 --- a/ACU/Log.pm +++ b/ACU/Log.pm @@ -71,7 +71,7 @@ sub log if ($mail_error && $level <= ERROR) { - require Email::Sender::Simple; + require Email::Sender::Simple qw(sendmail); my $mail = Email::MIME->create( header_str => [ From => "Roots assistants ", diff --git a/utils/lpt b/utils/lpt index a3b205f..78e3763 100755 --- a/utils/lpt +++ b/utils/lpt @@ -1512,7 +1512,7 @@ sub cmd_no_strong_auth_view(@) sub cmd_no_strong_auth_warn(@) { - require Email::Sender::Simple; + require Email::Sender::Simple qw(sendmail); for my $entry (get_no_strong_auth_user()) { @@ -1553,7 +1553,7 @@ Les roots ACU"; sub cmd_no_strong_auth_close(@) { - require Email::Sender::Simple; + require Email::Sender::Simple qw(sendmail); for my $entry (get_no_strong_auth_user()) { @@ -1706,7 +1706,7 @@ sub cmd_ssh_keys_without_passphrase_view(@) # warn about unprotected keys sub cmd_ssh_keys_without_passphrase_warn(@) { - require Email::Sender::Simple; + require Email::Sender::Simple qw(sendmail); my $process = sub() { my $entry = shift; @@ -1760,7 +1760,7 @@ Les roots ACU"; # remove unprotected keys sub cmd_ssh_keys_without_passphrase_remove(@) { - require Email::Sender::Simple; + require Email::Sender::Simple qw(sendmail); my $process = sub() { my $entry = shift; From 5247d4db535bef903efa8ab3faf0c873c99ab6c8 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 14 Nov 2013 16:20:13 +0100 Subject: [PATCH 267/364] Add sendmail option --- ACU/Log.pm | 3 ++- utils/lpt | 12 ++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ACU/Log.pm b/ACU/Log.pm index 5d751b8..491df18 100644 --- a/ACU/Log.pm +++ b/ACU/Log.pm @@ -71,7 +71,8 @@ sub log if ($mail_error && $level <= ERROR) { - require Email::Sender::Simple qw(sendmail); + require Email::Sender::Simple; + Email::Sender::Simple->import(qw(sendmail)); my $mail = Email::MIME->create( header_str => [ From => "Roots assistants ", diff --git a/utils/lpt b/utils/lpt index 78e3763..ea342b0 100755 --- a/utils/lpt +++ b/utils/lpt @@ -1512,7 +1512,8 @@ sub cmd_no_strong_auth_view(@) sub cmd_no_strong_auth_warn(@) { - require Email::Sender::Simple qw(sendmail); + require Email::Sender::Simple; + Email::Sender::Simple->import(qw(sendmail)); for my $entry (get_no_strong_auth_user()) { @@ -1553,7 +1554,8 @@ Les roots ACU"; sub cmd_no_strong_auth_close(@) { - require Email::Sender::Simple qw(sendmail); + require Email::Sender::Simple; + Email::Sender::Simple->import(qw(sendmail)); for my $entry (get_no_strong_auth_user()) { @@ -1706,7 +1708,8 @@ sub cmd_ssh_keys_without_passphrase_view(@) # warn about unprotected keys sub cmd_ssh_keys_without_passphrase_warn(@) { - require Email::Sender::Simple qw(sendmail); + require Email::Sender::Simple; + Email::Sender::Simple->import(qw(sendmail)); my $process = sub() { my $entry = shift; @@ -1760,7 +1763,8 @@ Les roots ACU"; # remove unprotected keys sub cmd_ssh_keys_without_passphrase_remove(@) { - require Email::Sender::Simple qw(sendmail); + require Email::Sender::Simple; + Email::Sender::Simple->import(qw(sendmail)); my $process = sub() { my $entry = shift; From b95918771861f61d199a36d18b8d78f6ab33839a Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 14 Nov 2013 17:35:14 +0100 Subject: [PATCH 268/364] Fix sendmail --- ACU/Log.pm | 2 +- utils/lpt | 28 ++++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/ACU/Log.pm b/ACU/Log.pm index 491df18..c9685fe 100644 --- a/ACU/Log.pm +++ b/ACU/Log.pm @@ -99,7 +99,7 @@ Cordialement, -- The lerdorf project", ); - Email::Sender::Simple::sendmail($mail); + sendmail($mail); } if ($level <= $display_level) { diff --git a/utils/lpt b/utils/lpt index ea342b0..bae4179 100755 --- a/utils/lpt +++ b/utils/lpt @@ -1546,9 +1546,14 @@ Les roots ACU"; Cc => 'Roots assistants ', Subject => "[PILA][AUTH-FORTE] Authentification forte SSH non active" ], + attributes => { + encoding => 'quoted-printable', + charset => 'utf-8', + format => 'flowed', + }, body_str => $body, ); - Email::Sender::Simple::sendmail($mail); + sendmail($mail); } } @@ -1584,9 +1589,14 @@ Les roots ACU"; Cc => 'Roots assistants ', Subject => "[PILA][ACCES] Compte suspendu" ], + attributes => { + encoding => 'quoted-printable', + charset => 'utf-8', + format => 'flowed', + }, body_str => $body, ); - Email::Sender::Simple::sendmail($mail); + sendmail($mail); } } @@ -1752,9 +1762,14 @@ Les roots ACU"; Cc => 'Roots assistants ', Subject => "[PILA][SSH-KEY] Clef SSH non protégée" ], + attributes => { + encoding => 'quoted-printable', + charset => 'utf-8', + format => 'flowed', + }, body_str => $body, ); - Email::Sender::Simple::sendmail($mail); + sendmail($mail); }; cmd_ssh_keys_without_passphrase_generic(\&$process); @@ -1813,9 +1828,14 @@ Les roots ACU"; Cc => 'Roots assistants ', Subject => "[PILA][SSH-KEY] Clef SSH non protégée supprimée" ], + attributes => { + encoding => 'quoted-printable', + charset => 'utf-8', + format => 'flowed', + }, body_str => $body, ); - Email::Sender::Simple::sendmail($mail); + sendmail($mail); }; cmd_ssh_keys_without_passphrase_generic(\&$process); From 9bcf8c7c2db50255f43ac705285928b0d15d6cce Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 14 Nov 2013 20:34:12 +0100 Subject: [PATCH 269/364] Update gl-pre-git exceptions --- hooks/gl-pre-git | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git index 5f6fd16..c7d0dca 100755 --- a/hooks/gl-pre-git +++ b/hooks/gl-pre-git @@ -19,7 +19,7 @@ my $promo = qx(git config hooks.promo); my $id_project = qx(git config hooks.idproject); my $repo_login = qx(git config hooks.repologin); -my @habitent_loin = ("abdeln_a", "amed_m", "bellev_m", "faure_n", "freima_m", "ikouna_l", "simon_j"); +my @habitent_loin = qw(amed_m bellev_m freima_m ikouna_l simon_j faure_n abdelm_a habri_z trang_d henrie_p verbec_y); # First, check if the repository is in the YYYY/ directory exit 0 if (($promo && $id_project && $repo_login) || $ENV{GL_REPO} !~ /^2[0-9]{3}\/.+\/.+/); From 1d5562b073a8725458ae5ecef14fb1af25d3187c Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 15 Nov 2013 08:39:52 +0100 Subject: [PATCH 270/364] New repo.sh migration --- migration/repo.sh | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/migration/repo.sh b/migration/repo.sh index d022694..23af34c 100755 --- a/migration/repo.sh +++ b/migration/repo.sh @@ -84,7 +84,7 @@ tex2md() git rm -f "$i" > /dev/null fi - sed -Ei 's/`%%([a-z-])\(([^)]+)\)`/%%\1(\2)/gi' "$DEST/${bi%%.tex}.md" + sed -Ei 's/`%%([a-z-]+)\(([^)]+)\)`/%%\1(\2)/gi' "$DEST/${bi%%.tex}.md" sed -Ei 's/\\$/\n/' "$DEST/${bi%%.tex}.md" done } @@ -114,7 +114,7 @@ clean_tex() exit 1; fi - for f in data Makefile images/acu.pdf images/assistants.pdf images/assistants-subject.pdf images/assistants-slides.pdf images/assistants.png images/epita.pdf images/epita.png images/epita-invert.pdf images/assistants-invert.pdf images/epita-invert.png images/assistants-bg.png images/logo_epita.jpg images/acu-bottom.png images/acu-bottom.pdf images/acu-bg.pdf images/acu2011.png images/acu.png *.cls *.sty + for f in data Makefile images/acu.pdf images/assistants.pdf images/assistants-subject.pdf images/assistants-slides.pdf images/assistants.png images/epita.pdf images/epita.png images/epita-invert.pdf images/assistants-invert.pdf images/epita-invert.png images/assistants-bg.png images/logo_epita.jpg images/acu-bottom.png images/acu-bottom.pdf images/acu-bg.pdf images/acu2011.png images/acu.png images/acu_2012_logo_hd.png *.cls *.sty *.toc do if [ -f "$f" ] then @@ -161,7 +161,7 @@ clean_tex() elif [ `find -mindepth 1 -maxdepth 1 -name '*.tex' | wc -l` -gt 0 ] then tex2md . - + else for i in * do @@ -231,7 +231,7 @@ if ls | grep "moulette" then echo -e "\e[1;34m>>>\e[1;37m Creating moulette branch...\e[0m" git checkout -b moulette - + find -mindepth 1 -maxdepth 1 ! -name moulette ! -name tests ! -name .git -exec git rm -rf {} \; git rm -f moulette/DESC 2> /dev/null @@ -321,6 +321,7 @@ do then echo -e "\e[1;32m##\e[1;37m Find directory $DIR with some .tex files \e[1;32m##\e[0m" cd "$DIR" + git rm *.tex clean_tex `pwd` `readlink -f "$(pwd)/.."` echo -e "\e[1;32m## ## ## ## ##\e[0m" echo @@ -348,6 +349,18 @@ do git rm -rf "$f" > /dev/null fi done + + # Append Fact lines + if [ -f "Makefile" ] + then + cat <> Makefile +fact: + rm -rf ref.ff + \${FACT} package create ../ref ref.ff + \${FACT} make make ref.ff ref.ff +EOF + fi + cd - > /dev/null fi done From a809c4ff8dc9cfad57f17fdce80f1b57ace630fc Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 15 Nov 2013 08:49:59 +0100 Subject: [PATCH 271/364] COnvert to UTF8 lpt --- utils/lpt | 49 ++++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 23 deletions(-) mode change 100755 => 100644 utils/lpt diff --git a/utils/lpt b/utils/lpt old mode 100755 new mode 100644 index bae4179..3537346 --- a/utils/lpt +++ b/utils/lpt @@ -3,6 +3,9 @@ use v5.10.1; use strict; use warnings; +use utf8; +use open IO => ':utf8'; +use open ':std'; use Digest::SHA; use Email::MIME; @@ -251,7 +254,7 @@ sub cmd_account_create($@) my $login = shift; if ($#_ < 3) { - log(USAGE, "lpt account create [nopass|passgen|password]"); + log(USAGE, "lpt account create [nopass|passgen|password]"); return 1; } @@ -1523,9 +1526,9 @@ sub cmd_no_strong_auth_warn(@) my $body = "Bonjour ".$entry->get_value("cn").", -Vous n'avez pas activé l'authentification forte pour SSH. +Vous n'avez pas activé l'authentification forte pour SSH. -Pour connaître la marche à suivre pour l'activer, consultez : +Pour connaître la marche à suivre pour l'activer, consultez : https://www.acu.epita.fr/wiki/index.php?title=Ssh_double_factor_auth Merci de rectifier la situation au plus vite ou votre compte sera mis @@ -1533,8 +1536,8 @@ en suspens. Cordialement, -P.-S. : Ce message est généré automatiquement, les roots sont en copie. - Pour toute demande, merci de faire un ticket à admin\@acu.epita.fr +P.-S. : Ce message est généré automatiquement, les roots sont en copie. + Pour toute demande, merci de faire un ticket à admin\@acu.epita.fr -- Les roots ACU"; @@ -1570,10 +1573,10 @@ sub cmd_no_strong_auth_close(@) my $body = "Bonjour ".$entry->get_value("cn").", -Après plusieurs relances de notre part, vous n'avez toujours pas activé -l'authentification forte pour SSH. Votre compte a donc été suspendu. +Après plusieurs relances de notre part, vous n'avez toujours pas activé +l'authentification forte pour SSH. Votre compte a donc été suspendu. -Nous vous invitons à passer au laboratoire pour faire réactiver votre +Nous vous invitons à passer au laboratoire pour faire réactiver votre compte. Cordialement, @@ -1730,11 +1733,11 @@ sub cmd_ssh_keys_without_passphrase_warn(@) my $body = "Bonjour ".$entry->get_value("cn").", -Un outil automatique a découvert une clef sans passphrase sur votre compte -du laboratoire. Il est impératif de mettre une passphrase chiffrant votre -clef pour des raisons de sécurité. +Un outil automatique a découvert une clef sans passphrase sur votre compte +du laboratoire. Il est impératif de mettre une passphrase chiffrant votre +clef pour des raisons de sécurité. -Les clefs non protégées sont les suivantes :\n"; +Les clefs non protégées sont les suivantes :\n"; foreach my $key (@$keys) { $key =~ s#^$nfsHomePrefix#$wksHomePrefix#; @@ -1743,13 +1746,13 @@ Les clefs non prot $body .= "\nPour mettre une passphrase : \$ ssh-keygen -p -f CHEMIN_VERS_LA_CLE_PRIVEE -Merci de rectifier la situation au plus vite ou votre clé sera supprimée et +Merci de rectifier la situation au plus vite ou votre clé sera supprimée et votre compte sera mis en suspens. Cordialement, -PS: Ce message est généré automatiquement, les roots sont en copie. - Pour toute demande, merci de faire un ticket à admin\@acu.epita.fr +PS: Ce message est généré automatiquement, les roots sont en copie. + Pour toute demande, merci de faire un ticket à admin\@acu.epita.fr -- Les roots ACU"; @@ -1760,7 +1763,7 @@ Les roots ACU"; From => "Roots assistants ", To => $entry->get_value("mailAlias"), Cc => 'Roots assistants ', - Subject => "[PILA][SSH-KEY] Clef SSH non protégée" + Subject => "[PILA][SSH-KEY] Clef SSH non protégée" ], attributes => { encoding => 'quoted-printable', @@ -1791,13 +1794,13 @@ sub cmd_ssh_keys_without_passphrase_remove(@) # create the message my $body = "Bonjour ".$entry->get_value("cn").", -Un outil automatique a découvert une clef sans passphrase sur votre +Un outil automatique a découvert une clef sans passphrase sur votre compte du laboratoire. -N'ayant pas corrigé votre situation après plusieurs relances, nous avons -désactivé votre compte et supprimé le(s) clef(s) incriminées. +N'ayant pas corrigé votre situation après plusieurs relances, nous avons +désactivé votre compte et supprimé le(s) clef(s) incriminées. -Pour information, voici l'empreinte de chacune des clefs supprimée :\n"; +Pour information, voici l'empreinte de chacune des clefs supprimée :\n"; foreach my $key (@$keys) { open (FNGR, "ssh-keygen -l -f '$key' | cut -d ' ' -f 2 |"); @@ -1815,8 +1818,8 @@ Contacter les roots pour faire reouvrir votre compte. Cordialement, -PS: Ce message est généré automatiquement, les roots sont en copie. - Pour toute demande, merci de faire un ticket à admin\@acu.epita.fr +PS: Ce message est généré automatiquement, les roots sont en copie. + Pour toute demande, merci de faire un ticket à admin\@acu.epita.fr -- Les roots ACU"; @@ -1826,7 +1829,7 @@ Les roots ACU"; From => "Roots assistants ", To => $entry->get_value("mailAlias"), Cc => 'Roots assistants ', - Subject => "[PILA][SSH-KEY] Clef SSH non protégée supprimée" + Subject => "[PILA][SSH-KEY] Clef SSH non protégée supprimée" ], attributes => { encoding => 'quoted-printable', From 77bee709ed615af1af8c12fec66bb1b303474cd2 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 15 Nov 2013 09:04:45 +0100 Subject: [PATCH 272/364] LDAP name convert to IPv6 --- utils/lpt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/utils/lpt b/utils/lpt index 3537346..354ee81 100644 --- a/utils/lpt +++ b/utils/lpt @@ -7,6 +7,7 @@ use utf8; use open IO => ':utf8'; use open ':std'; +use Encode qw(decode); use Digest::SHA; use Email::MIME; use File::Find; @@ -1524,7 +1525,7 @@ sub cmd_no_strong_auth_warn(@) say $entry->get_value("uid"); - my $body = "Bonjour ".$entry->get_value("cn").", + my $body = "Bonjour ".decode('UTF-8', $entry->get_value("cn"), Encode::FB_CROAK).", Vous n'avez pas activé l'authentification forte pour SSH. @@ -1571,7 +1572,7 @@ sub cmd_no_strong_auth_close(@) say $entry->get_value("uid"); - my $body = "Bonjour ".$entry->get_value("cn").", + my $body = "Bonjour ".decode('UTF-8', $entry->get_value("cn"), Encode::FB_CROAK).", Après plusieurs relances de notre part, vous n'avez toujours pas activé l'authentification forte pour SSH. Votre compte a donc été suspendu. @@ -1731,7 +1732,7 @@ sub cmd_ssh_keys_without_passphrase_warn(@) # Display say $entry->get_value("uid"); - my $body = "Bonjour ".$entry->get_value("cn").", + my $body = "Bonjour ".decode('UTF-8', $entry->get_value("cn"), Encode::FB_CROAK).", Un outil automatique a découvert une clef sans passphrase sur votre compte du laboratoire. Il est impératif de mettre une passphrase chiffrant votre @@ -1792,7 +1793,7 @@ sub cmd_ssh_keys_without_passphrase_remove(@) say $entry->get_value("uid"); # create the message - my $body = "Bonjour ".$entry->get_value("cn").", + my $body = "Bonjour ".decode('UTF-8', $entry->get_value("cn"), Encode::FB_CROAK).", Un outil automatique a découvert une clef sans passphrase sur votre compte du laboratoire. From 984cb050fab15d6f2b580b06e076309cb48a0d03 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 15 Nov 2013 09:21:33 +0100 Subject: [PATCH 273/364] Allow .google-authenticator under 100b --- utils/lpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/lpt b/utils/lpt index 354ee81..584096f 100644 --- a/utils/lpt +++ b/utils/lpt @@ -1496,7 +1496,7 @@ sub get_no_strong_auth_user() my $token = $home . "/.google_authenticator"; my $login = $entry->get_value("uid"); - push @faulty_users, $entry if (! -f $token || -s $token < 100); + push @faulty_users, $entry if (! -f $token || -s $token < 90); } $ldap->unbind or die ("couldn't disconnect correctly"); From 2f6b3a9812daca51b844a63b8faa56ab4af537aa Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 15 Nov 2013 12:40:29 +0100 Subject: [PATCH 274/364] Fix LDAP search --- ACU/LDAP.pm | 3 +++ utils/lpt | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/ACU/LDAP.pm b/ACU/LDAP.pm index 04b94e7..ac90bbf 100644 --- a/ACU/LDAP.pm +++ b/ACU/LDAP.pm @@ -189,6 +189,9 @@ sub get_dn($$@) my $ldap = shift // ldap_connect(); my $dn = shift; + my $base = BASE_DN; + $dn = "$dn," . BASE_DN if ($dn !~ /$base$/); + my $mesg = $ldap->search( # search base => "$dn", filter => Net::LDAP::Filter->new("(objectClass=*)"), diff --git a/utils/lpt b/utils/lpt index 584096f..acc9162 100644 --- a/utils/lpt +++ b/utils/lpt @@ -266,7 +266,7 @@ sub cmd_account_create($@) my $ldap = LDAP::ldap_connect(); # Check if the OU exists - my $oudn = "ou=$group,ou=users,dc=acu,dc=epita,dc=fr"; + my $oudn = "ou=$group,ou=users"; my $ou = LDAP::get_dn($ldap, $oudn); if (! $ou) @@ -841,7 +841,7 @@ sub cmd_groups($@) if ($gname && $gname =~ /^(2[0-9]{3})$/) { - $ou = "year=$1,$ou"; + $ou = "ou=$1,$ou"; $gname = shift; } @@ -1048,7 +1048,7 @@ sub cmd_group_create log(DEBUG, "Adding dn: cn=$gname,ou=intra,ou=groups,dc=acu,dc=epita,dc=fr ..."); - my $dn = "cn=$gname,$ou,dc=acu,dc=epita,dc=fr"; + my $dn = "cn=$gname,$ou"; my $class; $class = "intraGroup" if ($ou ne $group_types{system}); @@ -1060,7 +1060,7 @@ sub cmd_group_create }; log(ERROR, $@) if ($@); - my $mesg = $ldap->add( $dn, + my $mesg = $ldap->add( $dn . ",dc=acu,dc=epita,dc=fr", attrs => [ objectclass => [ "top", $class ], cn => $gname, @@ -1084,7 +1084,7 @@ sub cmd_group_delete(@) my $ou = shift; my $gname = shift; - my $dn = "cn=$gname,$ou,dc=acu,dc=epita,dc=fr"; + my $dn = "cn=$gname,$ou"; log(DEBUG, "Deleting dn: $dn ..."); From db62048be24010cd3c642f724861949099469870 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 16 Nov 2013 13:32:39 +0100 Subject: [PATCH 275/364] Hook: Use GL_USER instead of repo_login --- hooks/gl-pre-git | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git index c7d0dca..2491039 100755 --- a/hooks/gl-pre-git +++ b/hooks/gl-pre-git @@ -48,7 +48,7 @@ if ($ip->overlaps($labnetwork) == $IP_A_IN_B_OVERLAP) # exit 1; #} -exit 0 if (grep { /\Q$repo_login\E/ } @habitent_loin); +exit 0 if (grep { /\Q$ENV{GL_USER}\E/ } @habitent_loin); my $schoolnetwork = Net::IP->new('10.41.0.0/16'); #my $vjschoolnetwork = Net::IP->new('10.3.0.0/16'); From dcb6033caa5dbdb9c264b4be42849aca3ea3e483 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 16 Nov 2013 21:45:25 +0100 Subject: [PATCH 276/364] Add new scripts for moulettes --- commands/moulette/launch.sh | 43 ++++++++++++++++++++++++++++++++++++ commands/moulette/sendgit.sh | 40 +++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100755 commands/moulette/launch.sh create mode 100755 commands/moulette/sendgit.sh diff --git a/commands/moulette/launch.sh b/commands/moulette/launch.sh new file mode 100755 index 0000000..c591920 --- /dev/null +++ b/commands/moulette/launch.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +if [ -z "$2" ] +then + echo "Usage: $0 [year] [login ...]" + exit 1 +fi + +if ! which gearman > /dev/null 2> /dev/null +then + echo "gearman isn't installed on this machine. Please try another one." + exit 1 +fi + +if [ "x${1:0:2}" = "x20" ] +then + YEAR=" $1" + shift +else + YEAR= +fi +PROJECT_ID=$1 +RENDU=$2 + +shift 2 + +LOGINS= +while [ $# -gt 0 ] +do + LOGINS=" $1 +" + shift +done + +cat < + + moulette +$YEAR + $PROJECT_ID + $RENDU +$LOGINS +EOF diff --git a/commands/moulette/sendgit.sh b/commands/moulette/sendgit.sh new file mode 100755 index 0000000..07b92ad --- /dev/null +++ b/commands/moulette/sendgit.sh @@ -0,0 +1,40 @@ +#!/bin/sh + +if [ -z "$2" ] +then + echo "Usage: $0 [year] [login ...]" + exit 1 +fi + +if ! which gearman > /dev/null 2> /dev/null +then + echo "gearman isn't installed on this machine. Please try another one." + exit 1 +fi + +if [ "x${1:0:2}" = "x20" ] +then + YEAR=" $1" + shift +else + YEAR= +fi +PROJECT_ID=$1 +RENDU=$2 + +shift 2 + +while [ $# -gt 0 ] +do + LOGIN=$1 + cat < + +$YEAR + $PROJECT_ID + $RENDU + $LOGIN + +EOF + shift +done From 555c922786631f30f6e3d455802c9a2cd73dc5e9 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 18 Nov 2013 18:57:30 +0100 Subject: [PATCH 277/364] send_git: Year can be omitted --- process/files/send_git.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/process/files/send_git.pl b/process/files/send_git.pl index db2f924..8f29176 100644 --- a/process/files/send_git.pl +++ b/process/files/send_git.pl @@ -7,6 +7,7 @@ use v5.10; use File::Path qw(remove_tree); use File::Temp qw/tempfile tempdir/; +use ACU::LDAP; use ACU::Log; use ACU::Process; @@ -15,7 +16,7 @@ sub process { my ($given_args, $args) = @_; - my $year = $args->{param}{year}; + my $year = $args->{param}{year} // LDAP::get_year(); my $project_id = $args->{param}{id}; my $rendu = $args->{param}{rendu}; my $login = $args->{param}{login}; From f02f484cb8f5840c7a51a79faca0259472382c98 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 18 Nov 2013 22:28:10 +0100 Subject: [PATCH 278/364] gen_grades: better resolution of names --- process/files/intradata_get.pl | 62 ++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index 7ad2c3b..afb953f 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -100,52 +100,54 @@ sub grades_generate for my $login (@logins) { + my @files; + log DEBUG, "Generating grades for $login"; for my $dir (@trace_dirs) { log DEBUG, "Fetching identifiers from $dir"; - my $tr_file = "$year/$project_id/traces/$dir/$login.xml"; - - # Looking for a group traces? - if (! -f "$basedir/$tr_file") + # Looking for a group traces first + for my $grp (@{ $groups->{groups} }) { - for my $grp (@{ $groups->{groups} }) + my $this = 0; + my $chief; + for my $member (@{ $grp->{stds} }) { - my $this = 0; - my $chief; - for my $member (@{ $grp->{stds} }) + if ($member->{chief} eq "true" or $member->{chief} eq "1" or $member->{chief} eq "chief") { - if ($member->{chief} eq "true" or $member->{chief} eq "1" or $member->{chief} eq "chief") - { - $chief = $member; - next; - } - $this = 1 if ($member->{login} eq $login); + $chief = $member; + next; } - if ($this && $chief) - { - $tr_file = "$year/$project_id/traces/$dir/".$chief->{login}.".xml"; - log DEBUG, "Using group trace: chief is ".$chief->{login}; - last; + $this = 1 if ($member->{login} eq $login); + } + if ($this && $chief) + { + if (-f "$basedir/$year/$project_id/traces/$dir/".$chief->{login}.".xml") { + push @files, "$basedir/$year/$project_id/traces/$dir/".$chief->{login}.".xml"; } + last; } } - if (-f "$basedir/$tr_file") - { - open my $xmltrace, "<", "$basedir/$tr_file" or die "$tr_file: $!"; - binmode $xmltrace; - my $trace = Trace->new(join '', <$xmltrace>); - close $xmltrace; - - log DEBUG, "Fill from file: $tr_file"; - log TRACE, $trace->getIds($login); - - $grading->fill($trace->getIds($login)); + if (-f "$basedir/$year/$project_id/traces/$dir/$login.xml") { + push @files, "$basedir/$year/$project_id/traces/$dir/$login.xml"; } } + for my $path (@files) + { + open my $xmltrace, "<", "$path" or die "$path: $!"; + binmode $xmltrace; + my $trace = Trace->new(join '', <$xmltrace>); + close $xmltrace; + + log DEBUG, "Fill from file: $path"; + log TRACE, $trace->getIds($login); + + $grading->fill($trace->getIds($login)); + } + log DEBUG, "Computed grades: ".$grading->compute($login); open my $xmlgrade, ">", "$basedir/$year/$project_id/grades/$login.xml" or croak "grades/$login.xml"; From 49e5dcddf41d9a720d5b35c46a7cc3c31f66e344 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 20 Nov 2013 00:54:01 +0100 Subject: [PATCH 279/364] Remove old .ft --- process/files/moulette_get.pl | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/process/files/moulette_get.pl b/process/files/moulette_get.pl index 0024071..c0312df 100644 --- a/process/files/moulette_get.pl +++ b/process/files/moulette_get.pl @@ -7,6 +7,7 @@ use threads; use threads::shared; use Carp; use File::Basename; +use File::Compare; use File::Copy; use File::Path qw(remove_tree mkpath); use File::Temp qw/tempfile tempdir/; @@ -153,11 +154,35 @@ sub create_testsuite jail_exec("gmake -C $tempdir/tests/"); croak "An error occurs while making the testsuite" if ($?); - my $destdir = ( prepare_dir($year, $project_id, $rendu) )[2]; + my ($workdir, $outputdir, $destdir) = prepare_dir($year, $project_id, $rendu); copy("$tempdir/tests/tests.ff", "$destdir/tests.ff") or croak "An error occurs while coping the testsuite: $!"; - copy("$tempdir/tests/test.ft", "$destdir/test.ft") or croak "An error occurs while coping test.ft: $!"; chmod 0660, "$destdir/tests.ff"; - chmod 0660, "$destdir/test.ft"; + + # Check if test.ft has changed + if (-f "$tempdir/tests/test.ft") + { + if (! -f "$destdir/test.ft" || ! compare("$tempdir/tests/test.ft", "$destdir/test.ft")) + { + log DEBUG, "test.ft has changed, update students ones."; + copy("$tempdir/tests/test.ft", "$destdir/test.ft") or croak "An error occurs while coping test.ft: $!"; + chmod 0660, "$destdir/test.ft"; + + opendir(my $dh, $workdir) or die "Can't list files in $workdir: $!"; + while (readdir($dh)) + { + if (/([a-zA-Z0-9_-]+).ft$/) + { + log DEBUG, "Remove $1.ft"; + unlink "$workdir/$1.ft"; + } + } + closedir $dh; + } + } + else { + remove_tree($tempdir); + croak "tests/test.ft not found."; + } # Clean remove_tree($tempdir); @@ -210,7 +235,7 @@ sub run_moulette close $fhout; } - copy("$filesdir/$login.ff", "$workdir/$login.ff") or croak "Cannont copy $login.ff"; + copy("$filesdir/$login.ff", "$workdir/$login.ff") or croak "Cannot copy $login.ff"; next if ($login eq "ref" && ! -f "$workdir/$login.ft"); croak "Unable to find a relevant $login.ft, abort moulette start." if (! -f "$workdir/$login.ft"); From 26f58dcaa6137e4534ec665f9e815b214980c03b Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 20 Nov 2013 01:04:30 +0100 Subject: [PATCH 280/364] Add log --- ACU/t/tinyglob.t | 7 ++++++- commands/first-install.sh | 6 +++--- commands/moulette/launch.sh | 6 +++--- commands/moulette/sendgit.sh | 25 ++++++++++++++++++++++--- commands/project/gen_git_str.pl | 2 +- migration/repo.sh | 1 - process/files/moulette_get.pl | 6 +++++- 7 files changed, 40 insertions(+), 13 deletions(-) diff --git a/ACU/t/tinyglob.t b/ACU/t/tinyglob.t index 35f6f7b..4c9fe8f 100644 --- a/ACU/t/tinyglob.t +++ b/ACU/t/tinyglob.t @@ -21,6 +21,7 @@ is(Tinyglob::tinyglob("\\\\?"), "\\\\."); is(Tinyglob::tinyglob("\\."), "\\."); is(Tinyglob::tinyglob("\\\\."), "\\\\\\."); is(Tinyglob::tinyglob("a*b?"), "a.*b."); +is(Tinyglob::tinyglob("a-b"), "a\\-b"); ok(! Tinyglob::match("?", "")); ok(! Tinyglob::match("b", "a")); @@ -28,6 +29,8 @@ ok(! Tinyglob::match("b*", "a")); ok(! Tinyglob::match("b?", "a")); ok(Tinyglob::match("*", "")); +ok(Tinyglob::match("a-b", "a-b")); +ok(Tinyglob::match("gfa-bgf", "gfa-bgf")); ok(Tinyglob::match("a", "a")); ok(Tinyglob::match("?", "a")); ok(Tinyglob::match("*", "a")); @@ -49,7 +52,9 @@ ok(Tinyglob::match("a*b*", "acdefblkjgd")); ok(! Tinyglob::match("a?b*", "acdefblkjgd")); ok(Tinyglob::match("a?b*", "acblkjgd")); ok(Tinyglob::match("a?b*", "abblkjgd")); -ok(! Tinyglob::match("a*b?", "abblkjgd")); +#ok(! Tinyglob::match("a*b?", "abblkjgd")); ok(Tinyglob::match("a*b?", "aasdasbd")); +print "youpi " if ("de-bro_m" =~ /^de\-bro_m$/); + done_testing(); diff --git a/commands/first-install.sh b/commands/first-install.sh index 47157b7..ea1d507 100755 --- a/commands/first-install.sh +++ b/commands/first-install.sh @@ -2,9 +2,9 @@ # Install missing packages DEB_PACKAGES_LIST="screen libnet-ldap-perl libxml-libxml-perl libgearman-client-perl libmailtools-perl libdatetime-format-iso8601-perl libnet-ip-perl libsys-gamin-perl libdigest-sha-perl libemail-mime-perl libemail-sender-perl" -ARCH_PACKAGES_LIST="screen perl-io-socket-ssl perl-email-simple perl-email-mime perl-term-readkey perl-ldap perl-lwp-protocol-https perl-datetime-format-iso8601 perl-net-ip" # aur/perl-sys-gamin -GENTOO_PACKAGES_LIST="app-misc/screen dev-perl/IO-Socket-SSL dev-perl/Email-Simple dev-perl/Email-MIME dev-perl/TermReadKey dev-perl/perl-ldap dev-perl/LWP-Protocol-https dev-perl/DateTime-Format-ISO8601 dev-perl/Net-IP" -FBSD_PACKAGES_LIST="screen p5-IO-Socket-SSL p5-Email-Simple p5-Email-MIME p5-Term-ANSIColor p5-Term-ReadKey p5-LWP-Protocol-https p5-DateTime-Format-ISO8601 p5-Net-IP p5-Sys-Gamin" +ARCH_PACKAGES_LIST="screen perl-io-socket-ssl perl-email-mime perl-term-readkey perl-ldap perl-lwp-protocol-https perl-datetime-format-iso8601 perl-net-ip" # aur/perl-sys-gamin +GENTOO_PACKAGES_LIST="app-misc/screen dev-perl/IO-Socket-SSL dev-perl/Email-MIME dev-perl/TermReadKey dev-perl/perl-ldap dev-perl/LWP-Protocol-https dev-perl/DateTime-Format-ISO8601 dev-perl/Net-IP dev-perl/Email-Sender" +FBSD_PACKAGES_LIST="screen p5-IO-Socket-SSL p5-Email-MIME p5-Term-ANSIColor p5-Term-ReadKey p5-LWP-Protocol-https p5-DateTime-Format-ISO8601 p5-Net-IP p5-Sys-Gamin" KERNEL=`uname -s` diff --git a/commands/moulette/launch.sh b/commands/moulette/launch.sh index c591920..e15ad14 100755 --- a/commands/moulette/launch.sh +++ b/commands/moulette/launch.sh @@ -14,10 +14,10 @@ fi if [ "x${1:0:2}" = "x20" ] then - YEAR=" $1" + YEAR="$1" shift else - YEAR= + YEAR=`ldapsearch -x -b "cn=year,dc=acu,dc=epita,dc=fr" | grep "^year" | cut -d " " -f 2` fi PROJECT_ID=$1 RENDU=$2 @@ -36,7 +36,7 @@ cat < moulette -$YEAR + $YEAR $PROJECT_ID $RENDU $LOGINS diff --git a/commands/moulette/sendgit.sh b/commands/moulette/sendgit.sh index 07b92ad..ec68a4c 100755 --- a/commands/moulette/sendgit.sh +++ b/commands/moulette/sendgit.sh @@ -1,8 +1,13 @@ #!/bin/sh -if [ -z "$2" ] +usage() +{ + echo "Usage: $0 [-d] [year] [login ...]" +} + +if [ -z "$3" ] then - echo "Usage: $0 [year] [login ...]" + usage exit 1 fi @@ -12,6 +17,14 @@ then exit 1 fi +if [ "x$1" = "x-d" ] +then + BACKGROUD= + shift +else + BACKGROUD="-b" +fi + if [ "x${1:0:2}" = "x20" ] then YEAR=" $1" @@ -24,10 +37,16 @@ RENDU=$2 shift 2 +if [ $# -le 0 ] +then + usage + exit 1 +fi + while [ $# -gt 0 ] do LOGIN=$1 - cat < $YEAR diff --git a/commands/project/gen_git_str.pl b/commands/project/gen_git_str.pl index 0a67688..f49e193 100644 --- a/commands/project/gen_git_str.pl +++ b/commands/project/gen_git_str.pl @@ -31,5 +31,5 @@ map { for my $member (@{ $_->{stds} }) { print ' '.$member->{login}; } - say "\n R = \@chefs \@resp-$year-$projid"; + say "\n R = \@chefs \@resp-$year-$projid \@soutenance-$year-$projid"; } @{ $res->{groups} }; diff --git a/migration/repo.sh b/migration/repo.sh index 23af34c..c8fffa1 100755 --- a/migration/repo.sh +++ b/migration/repo.sh @@ -321,7 +321,6 @@ do then echo -e "\e[1;32m##\e[1;37m Find directory $DIR with some .tex files \e[1;32m##\e[0m" cd "$DIR" - git rm *.tex clean_tex `pwd` `readlink -f "$(pwd)/.."` echo -e "\e[1;32m## ## ## ## ##\e[0m" echo diff --git a/process/files/moulette_get.pl b/process/files/moulette_get.pl index c0312df..1b4bc3c 100644 --- a/process/files/moulette_get.pl +++ b/process/files/moulette_get.pl @@ -163,7 +163,7 @@ sub create_testsuite { if (! -f "$destdir/test.ft" || ! compare("$tempdir/tests/test.ft", "$destdir/test.ft")) { - log DEBUG, "test.ft has changed, update students ones."; + log DEBUG, "test.ft has changed, UPDATE students ones."; copy("$tempdir/tests/test.ft", "$destdir/test.ft") or croak "An error occurs while coping test.ft: $!"; chmod 0660, "$destdir/test.ft"; @@ -178,6 +178,10 @@ sub create_testsuite } closedir $dh; } + else + { + log DEBUG, "test.ft hasn't changed, KEEP students ones."; + } } else { remove_tree($tempdir); From 1d0d92b040453fb28608afa9bed703d5092d1b97 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 20 Nov 2013 01:13:54 +0100 Subject: [PATCH 281/364] Add traces for debug --- process/files/moulette_get.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/process/files/moulette_get.pl b/process/files/moulette_get.pl index 1b4bc3c..843d538 100644 --- a/process/files/moulette_get.pl +++ b/process/files/moulette_get.pl @@ -161,6 +161,7 @@ sub create_testsuite # Check if test.ft has changed if (-f "$tempdir/tests/test.ft") { + log TRACE, -f "$destdir/test.ft", compare("$tempdir/tests/test.ft", "$destdir/test.ft"); if (! -f "$destdir/test.ft" || ! compare("$tempdir/tests/test.ft", "$destdir/test.ft")) { log DEBUG, "test.ft has changed, UPDATE students ones."; From b25a862650ac1a65bbce7f5536cd78f11111ae7a Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 20 Nov 2013 01:45:30 +0100 Subject: [PATCH 282/364] Fix condition --- process/files/moulette_get.pl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/process/files/moulette_get.pl b/process/files/moulette_get.pl index 843d538..6134d34 100644 --- a/process/files/moulette_get.pl +++ b/process/files/moulette_get.pl @@ -161,8 +161,7 @@ sub create_testsuite # Check if test.ft has changed if (-f "$tempdir/tests/test.ft") { - log TRACE, -f "$destdir/test.ft", compare("$tempdir/tests/test.ft", "$destdir/test.ft"); - if (! -f "$destdir/test.ft" || ! compare("$tempdir/tests/test.ft", "$destdir/test.ft")) + if (! -f "$destdir/test.ft" || compare("$tempdir/tests/test.ft", "$destdir/test.ft")) { log DEBUG, "test.ft has changed, UPDATE students ones."; copy("$tempdir/tests/test.ft", "$destdir/test.ft") or croak "An error occurs while coping test.ft: $!"; From 44722fdd93472fde6dc631eb7b4e61cea29c5398 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 21 Nov 2013 14:47:36 +0100 Subject: [PATCH 283/364] Fix denfense publication --- ACU/Defense.pm | 3 +++ process/files/intradata_get.pl | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ACU/Defense.pm b/ACU/Defense.pm index 6150716..ae14f44 100644 --- a/ACU/Defense.pm +++ b/ACU/Defense.pm @@ -144,6 +144,7 @@ sub genIds ($;$) } else { $grp_i += 1; + $cur_gid = $group->{id}; } my $qst_i = 0; @@ -160,6 +161,7 @@ sub genIds ($;$) } else { $qst_i += 1; + $cur_qid = $question->{id}; } my $ans_i = 0; @@ -176,6 +178,7 @@ sub genIds ($;$) } else { $ans_i += 1; + $cur_aid = $answer->{id}; } } } diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index afb953f..3efbce9 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -283,7 +283,7 @@ sub update_defense if (! -e "$basedir/$year/$project_id/traces/defense_$defense_id/") { mkdir "$basedir/$year/$project_id/traces/defense_$defense_id/" or die $!; my ($login, $pass, $uid, $gid) = getpwnam("www-data"); - chown $uid, $gid, "$basedir/$year/$project_id/traces/defense_$defense_id/" or die $!; + chown $uid, $gid, "$basedir/$year/$project_id/traces/defense_$defense_id/";# or die $!; #FIXME chmod 0775, "$basedir/$year/$project_id/traces/defense_$defense_id/" or die $!; } From 7f418a06fe08d16a33ce7a54908f554ad2ae5907 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 21 Nov 2013 21:01:14 +0100 Subject: [PATCH 284/364] Fix API call --- ACU/API/Base.pm | 4 +++- ACU/API/Projects.pm | 10 ++++++++-- ACU/Defense.pm | 1 - 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ACU/API/Base.pm b/ACU/API/Base.pm index 72d860e..2d9c632 100644 --- a/ACU/API/Base.pm +++ b/ACU/API/Base.pm @@ -105,8 +105,10 @@ sub send($$$) log(DEBUG, 'POST Request to ', API_URL, $url); my $req = POST API_URL . $url, shift; - my $cnt = $ua->request($req)->content; + my $res = $ua->request($req); + log TRACE, $res; + my $cnt = $res->content(); log TRACE, $cnt; return parse($next, $cnt); diff --git a/ACU/API/Projects.pm b/ACU/API/Projects.pm index abb0adf..5f1a2c5 100644 --- a/ACU/API/Projects.pm +++ b/ACU/API/Projects.pm @@ -103,7 +103,10 @@ sub add_grades($;$) my %data = ( project_name => shift ); - $data{year} = $_ if (shift); + my $y = shift; + if ($y) { + $data{year} = $y; + } my $res = API::Base::send('ResultHandler', "projects/notes/add.xml", \%data); @@ -120,7 +123,10 @@ sub add_traces($$;$) project_name => shift, trace_name => shift, ); - $data{year} = $_ if (shift); + my $y = shift; + if ($y) { + $data{year} = $y; + } my $res = API::Base::send('ResultHandler', "projects/traces/add.xml", \%data); diff --git a/ACU/Defense.pm b/ACU/Defense.pm index ae14f44..d286567 100644 --- a/ACU/Defense.pm +++ b/ACU/Defense.pm @@ -178,7 +178,6 @@ sub genIds ($;$) } else { $ans_i += 1; - $cur_aid = $answer->{id}; } } } From a02ed70d5d566353d187409777cf693a4bd3db71 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 21 Nov 2013 21:28:45 +0100 Subject: [PATCH 285/364] Trace: fix warnings --- ACU/Trace.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ACU/Trace.pm b/ACU/Trace.pm index 6252e3a..6981eea 100644 --- a/ACU/Trace.pm +++ b/ACU/Trace.pm @@ -428,7 +428,7 @@ sub getValue my $value = 0; if (!$login || !exists $self->{who} || $self->{who}{type} eq "group" || $self->{who}{login} eq $login) { - foreach my $key (%{ $self->{values} }) + foreach my $key (keys %{ $self->{values} }) { $value += $self->{values}{$key} if ($id eq $self->{id} || !$key || $key eq $id); } From ce15c69841b6a3833eb8f49f4f4f4975845d4c0b Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 22 Nov 2013 21:11:36 +0100 Subject: [PATCH 286/364] Habitent loin : molini_v --- hooks/gl-pre-git | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git index 2491039..261160d 100755 --- a/hooks/gl-pre-git +++ b/hooks/gl-pre-git @@ -19,7 +19,7 @@ my $promo = qx(git config hooks.promo); my $id_project = qx(git config hooks.idproject); my $repo_login = qx(git config hooks.repologin); -my @habitent_loin = qw(amed_m bellev_m freima_m ikouna_l simon_j faure_n abdelm_a habri_z trang_d henrie_p verbec_y); +my @habitent_loin = qw(amed_m bellev_m freima_m ikouna_l simon_j faure_n abdelm_a habri_z trang_d henrie_p verbec_y molini_v); # First, check if the repository is in the YYYY/ directory exit 0 if (($promo && $id_project && $repo_login) || $ENV{GL_REPO} !~ /^2[0-9]{3}\/.+\/.+/); From 37dde8ce57723801c4903b98ee3d69db5e1a6cca Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 23 Nov 2013 03:09:53 +0100 Subject: [PATCH 287/364] Fix API::Projects::get_groups --- ACU/API/Base.pm | 31 +++++++++++++++++-------------- ACU/API/Projects.pm | 7 +++---- commands/project/gen_git_str.pl | 1 - 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/ACU/API/Base.pm b/ACU/API/Base.pm index 2d9c632..c00643c 100644 --- a/ACU/API/Base.pm +++ b/ACU/API/Base.pm @@ -249,8 +249,7 @@ sub new ($$) my $class = shift; my $self = { parsed => shift, - inStd => 0, - inResult => 0, + savValue => 0, lastGroup => {}, values => "" }; @@ -264,14 +263,10 @@ sub start_element { my ($self, $element) = @_; - if ($element->{Name} eq "result") { - $self->{parsed}{result} = $self->{values}; - $self->{inResult} = 0; - $self->{values} = ""; - } - elsif ($element->{Name} eq "student") + if ($element->{Name} eq "student") { - $self->{inStd} = 1; + $self->{values} = ""; + $self->{savValue} = 1; push @{ $self->{lastGroup}{stds} }, { id => $element->{Attributes}{"{}id"}{Value}, chief => $element->{Attributes}{"{}chief"}{Value}, @@ -283,13 +278,18 @@ sub start_element $self->{lastGroup}{id} = $element->{Attributes}{"{}id"}{Value}; $self->{lastGroup}{stds} = []; } + elsif ($element->{Name} eq "result") + { + $self->{values} = ""; + $self->{savValue} = 1; + } } sub characters { my ($self, $characters) = @_; - if ($self->{inStd}) { + if ($self->{savValue}) { $self->{values} .= $characters->{Data}; } } @@ -298,13 +298,16 @@ sub end_element { my ($self, $element) = @_; - if ($element->{Name} eq "group") + if ($element->{Name} eq "result") + { + $self->{parsed}{result} = $self->{values}; + $self->{savValue} = 0; + } + elsif ($element->{Name} eq "group") { push @{ $self->{parsed}{groups} }, $self->{lastGroup}; $self->{lastGroup} = {}; - - $self->{inStd} = 0; - $self->{values} = ""; + $self->{savValue} = 0; } elsif ($element->{Name} eq "student") { diff --git a/ACU/API/Projects.pm b/ACU/API/Projects.pm index 5f1a2c5..eb39572 100644 --- a/ACU/API/Projects.pm +++ b/ACU/API/Projects.pm @@ -90,10 +90,9 @@ sub get_groups($;$) my $res = API::Base::get('ProjectGroupHandler', $url); - #TODO: uncomment-me - #if ($res->{result} ne '0') { -# croak "Erreur durant la récupération : " . $res->{message}; - #} + if ($res->{result} ne '0') { + croak "Erreur durant la récupération : " . $res->{message}; + } return $res; } diff --git a/commands/project/gen_git_str.pl b/commands/project/gen_git_str.pl index f49e193..14cffec 100644 --- a/commands/project/gen_git_str.pl +++ b/commands/project/gen_git_str.pl @@ -11,7 +11,6 @@ my $projid = $ARGV[0]; my $year = $ARGV[1] // LDAP::get_year; my $res = API::Projects::get_groups($projid, $year); -my $tag = "rendu-1"; map { my $chief; From f8e5d1b5c056b6eff01e558ca97cd084e4b4e733 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 23 Nov 2013 04:18:32 +0100 Subject: [PATCH 288/364] Fix grades generation --- ACU/Trace.pm | 17 +++++++++++++++++ process/files/intradata_get.pl | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/ACU/Trace.pm b/ACU/Trace.pm index 6981eea..9e08935 100644 --- a/ACU/Trace.pm +++ b/ACU/Trace.pm @@ -146,6 +146,23 @@ sub getIds return \%ids; } +sub getNonZeroIds +{ + my $self = shift; + my $login = shift; + + my %ids; + foreach my $group (@{ $self->{groups} }) + { + my %tmp = $group->getIds($login); + while (my ($key, $value) = each %tmp) + { + $ids{$key} = $value if $value; + } + } + return \%ids; +} + sub getValue { my $self = shift; diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index 3efbce9..294fbcd 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -145,7 +145,7 @@ sub grades_generate log DEBUG, "Fill from file: $path"; log TRACE, $trace->getIds($login); - $grading->fill($trace->getIds($login)); + $grading->fill($trace->getNonZeroIds($login)); } log DEBUG, "Computed grades: ".$grading->compute($login); From f271f36203c70d8936639fd58860924c445586b0 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 23 Nov 2013 17:21:46 +0100 Subject: [PATCH 289/364] Use Text::Glob instead of ACU::Tinyglob --- ACU/Grading.pm | 5 ++- ACU/Tinyglob.pm | 67 --------------------------------------- ACU/t/tinyglob.t | 60 ----------------------------------- commands/first-install.sh | 8 ++--- 4 files changed, 6 insertions(+), 134 deletions(-) delete mode 100644 ACU/Tinyglob.pm delete mode 100644 ACU/t/tinyglob.t diff --git a/ACU/Grading.pm b/ACU/Grading.pm index 4627024..823ddee 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -7,8 +7,6 @@ use strict; use warnings; use XML::LibXML; -use ACU::Tinyglob; - sub new { my $class = shift; @@ -185,6 +183,7 @@ use warnings; use Carp; use Safe; use List::Util "reduce"; +use Text::Glob qw( glob_to_regex ); use XML::LibXML; sub new ($$$;$$) @@ -349,7 +348,7 @@ sub compute ($$$;$$$) { eval { - my $glob = Tinyglob::tinyglob($ref); + my $glob = glob_to_regex($ref); if ($glob ne $ref) { my $value = 0; diff --git a/ACU/Tinyglob.pm b/ACU/Tinyglob.pm deleted file mode 100644 index 8db5379..0000000 --- a/ACU/Tinyglob.pm +++ /dev/null @@ -1,67 +0,0 @@ -#! /usr/bin/env perl - -package Tinyglob; - -use v5.10.1; -use strict; -use warnings; -use Carp; -use Exporter 'import'; - -our @EXPORT = qw(tinyglob); - -sub tinyglob -{ - my $orig = shift; - my @str = split("", quotemeta($orig)); - my $res = ""; - - my $metaescape = 0; - - for (my $i = 0; $i <= $#str; $i++) - { - if ($str[$i] eq '\\') - { - $i += 1; - if ($str[$i] eq '\\') - { - $metaescape = ! $metaescape; - $res .= $str[$i]; - } - elsif ($metaescape && ($str[$i] eq '*' || $str[$i] eq '?')) { - $res .= $str[$i]; - $metaescape = 0; - } - elsif ($str[$i] eq '?') { - $res .= '.'; - } - elsif ($str[$i] eq '*') { - $res .= '.*'; - } - elsif ($metaescape) { - $res .= $str[$i]; - $metaescape = 0; - } - else { - $res .= "\\".$str[$i]; - } - } - else { - $res .= $str[$i]; - } - } - - return $res; -} - -sub match -{ - my $glob = tinyglob(shift); - my $str = shift; - - say $glob; - - return $str =~ /$glob/; -} - -1; diff --git a/ACU/t/tinyglob.t b/ACU/t/tinyglob.t deleted file mode 100644 index 4c9fe8f..0000000 --- a/ACU/t/tinyglob.t +++ /dev/null @@ -1,60 +0,0 @@ -use v5.10.1; -use strict; -use warnings; - -use Test::More; - -use lib "../"; - -BEGIN { - diag("Testing Tinyglob on perl $]"); - use_ok('ACU::Tinyglob'); -} - -use ACU::Tinyglob; - -is(Tinyglob::tinyglob("test"), "test"); -is(Tinyglob::tinyglob("\\*"), "\\*"); -is(Tinyglob::tinyglob("\\\\*"), "\\\\.*"); -is(Tinyglob::tinyglob("\\?"), "\\?"); -is(Tinyglob::tinyglob("\\\\?"), "\\\\."); -is(Tinyglob::tinyglob("\\."), "\\."); -is(Tinyglob::tinyglob("\\\\."), "\\\\\\."); -is(Tinyglob::tinyglob("a*b?"), "a.*b."); -is(Tinyglob::tinyglob("a-b"), "a\\-b"); - -ok(! Tinyglob::match("?", "")); -ok(! Tinyglob::match("b", "a")); -ok(! Tinyglob::match("b*", "a")); -ok(! Tinyglob::match("b?", "a")); -ok(Tinyglob::match("*", "")); - -ok(Tinyglob::match("a-b", "a-b")); -ok(Tinyglob::match("gfa-bgf", "gfa-bgf")); -ok(Tinyglob::match("a", "a")); -ok(Tinyglob::match("?", "a")); -ok(Tinyglob::match("*", "a")); - -ok(Tinyglob::match("ab", "ab")); -ok(Tinyglob::match("?b", "ab")); -ok(Tinyglob::match("*b", "ab")); -ok(Tinyglob::match("*", "ab")); - -ok(Tinyglob::match("b?", "ba")); -ok(Tinyglob::match("b*", "ba")); -ok(Tinyglob::match("*", "abcdef")); - -ok(Tinyglob::match("a?b", "acb")); -ok(Tinyglob::match("a*b", "acb")); -ok(Tinyglob::match("a*b", "acdefb")); - -ok(Tinyglob::match("a*b*", "acdefblkjgd")); -ok(! Tinyglob::match("a?b*", "acdefblkjgd")); -ok(Tinyglob::match("a?b*", "acblkjgd")); -ok(Tinyglob::match("a?b*", "abblkjgd")); -#ok(! Tinyglob::match("a*b?", "abblkjgd")); -ok(Tinyglob::match("a*b?", "aasdasbd")); - -print "youpi " if ("de-bro_m" =~ /^de\-bro_m$/); - -done_testing(); diff --git a/commands/first-install.sh b/commands/first-install.sh index ea1d507..afd3e4e 100755 --- a/commands/first-install.sh +++ b/commands/first-install.sh @@ -1,10 +1,10 @@ #! /bin/bash # Install missing packages -DEB_PACKAGES_LIST="screen libnet-ldap-perl libxml-libxml-perl libgearman-client-perl libmailtools-perl libdatetime-format-iso8601-perl libnet-ip-perl libsys-gamin-perl libdigest-sha-perl libemail-mime-perl libemail-sender-perl" -ARCH_PACKAGES_LIST="screen perl-io-socket-ssl perl-email-mime perl-term-readkey perl-ldap perl-lwp-protocol-https perl-datetime-format-iso8601 perl-net-ip" # aur/perl-sys-gamin -GENTOO_PACKAGES_LIST="app-misc/screen dev-perl/IO-Socket-SSL dev-perl/Email-MIME dev-perl/TermReadKey dev-perl/perl-ldap dev-perl/LWP-Protocol-https dev-perl/DateTime-Format-ISO8601 dev-perl/Net-IP dev-perl/Email-Sender" -FBSD_PACKAGES_LIST="screen p5-IO-Socket-SSL p5-Email-MIME p5-Term-ANSIColor p5-Term-ReadKey p5-LWP-Protocol-https p5-DateTime-Format-ISO8601 p5-Net-IP p5-Sys-Gamin" +DEB_PACKAGES_LIST="screen libnet-ldap-perl libxml-libxml-perl libgearman-client-perl libmailtools-perl libdatetime-format-iso8601-perl libnet-ip-perl libsys-gamin-perl libdigest-sha-perl libemail-mime-perl libemail-sender-perl libtext-glob-perl" +ARCH_PACKAGES_LIST="screen perl-io-socket-ssl perl-email-mime perl-term-readkey perl-ldap perl-lwp-protocol-https perl-datetime-format-iso8601 perl-net-ip" # aur/perl-sys-gamin aur/perl-text-glob +GENTOO_PACKAGES_LIST="app-misc/screen dev-perl/IO-Socket-SSL dev-perl/Email-MIME dev-perl/TermReadKey dev-perl/perl-ldap dev-perl/LWP-Protocol-https dev-perl/DateTime-Format-ISO8601 dev-perl/Net-IP dev-perl/Email-Sender dev-perl/Text-Glob" +FBSD_PACKAGES_LIST="screen p5-IO-Socket-SSL p5-Email-MIME p5-Term-ANSIColor p5-Term-ReadKey p5-LWP-Protocol-https p5-DateTime-Format-ISO8601 p5-Net-IP p5-Sys-Gamin p5-Text-Glob" KERNEL=`uname -s` From b4fc037a068571bee39c4574961170f743bc1926 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 23 Nov 2013 17:31:16 +0100 Subject: [PATCH 290/364] glob_to_regex --- ACU/Grading.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ACU/Grading.pm b/ACU/Grading.pm index 823ddee..311c684 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -183,7 +183,6 @@ use warnings; use Carp; use Safe; use List::Util "reduce"; -use Text::Glob qw( glob_to_regex ); use XML::LibXML; sub new ($$$;$$) @@ -287,6 +286,7 @@ package Point; use v5.10.1; use strict; use warnings; +use Text::Glob qw( glob_to_regex ); use Term::ANSIColor qw(:constants); use ACU::Log; From be336da8d6ff0f7bb940060588012289683eb5d2 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 23 Nov 2013 20:08:03 +0100 Subject: [PATCH 291/364] Try to fix grades --- ACU/Grading.pm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ACU/Grading.pm b/ACU/Grading.pm index 311c684..c20ae27 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -286,7 +286,7 @@ package Point; use v5.10.1; use strict; use warnings; -use Text::Glob qw( glob_to_regex ); +use Text::Glob qw( glob_to_regex match_glob ); use Term::ANSIColor qw(:constants); use ACU::Log; @@ -352,9 +352,12 @@ sub compute ($$$;$$$) if ($glob ne $ref) { my $value = 0; - for my $r (grep { /^$glob$/ } keys %$ids) { + for my $r (grep { match_glob($ref, $_); } keys %$ids) + { + log DEBUG, "$glob match $r (expanded from $ref)"; $value += $ids->{ $r }; } + log DEBUG, "New $ref is now $value"; $ids->{ $ref } = $value; } }; From 6e655751d43d8c80cde7deab47e6504b27169e79 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 23 Nov 2013 20:11:53 +0100 Subject: [PATCH 292/364] Ok :) --- ACU/Grading.pm | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/ACU/Grading.pm b/ACU/Grading.pm index c20ae27..032ed81 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -352,13 +352,10 @@ sub compute ($$$;$$$) if ($glob ne $ref) { my $value = 0; - for my $r (grep { match_glob($ref, $_); } keys %$ids) - { - log DEBUG, "$glob match $r (expanded from $ref)"; + for my $r (grep { match_glob($ref, $_); } keys %$ids) { $value += $ids->{ $r }; } - log DEBUG, "New $ref is now $value"; - $ids->{ $ref } = $value; + $ids->{ $ref } = $value if ($value); } }; if ($@) { From 3a00d6344ad2418dd6c52403c3ec198d357a358d Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 23 Nov 2013 20:30:20 +0100 Subject: [PATCH 293/364] Faster grading --- ACU/Grading.pm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ACU/Grading.pm b/ACU/Grading.pm index 032ed81..f473289 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -348,8 +348,7 @@ sub compute ($$$;$$$) { eval { - my $glob = glob_to_regex($ref); - if ($glob ne $ref) + if ($ref =~ /\?|\*/) { my $value = 0; for my $r (grep { match_glob($ref, $_); } keys %$ids) { From cddafdf0ad8683eb4fdb99b36568b432ecd7c05f Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 23 Nov 2013 21:13:11 +0100 Subject: [PATCH 294/364] Exceptions --- hooks/submissions.pl | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/hooks/submissions.pl b/hooks/submissions.pl index 058e393..8e422c7 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -23,6 +23,8 @@ my $id_project; my $repo_login; my @apping = qw(zinger_a zebard_w zanell_a yao_p vinois_a sraka_y soupam_j seck_a ngomsi_s morin_h milis_e menkar_m eusebe_r crief_a chhum_s boumra_n blemus_a bengan_l amasho_a); +my @salonD = qw(aniss_i bogalh_j boulea_b cloare_l elhach_h gabrie_j kaplan_p manuel_c palson_c pizzin_a wajntr_a); +my @salonS = qw(allio_a cadet_l digius_p drouin_n dubois_d dupuis_a langre_m lim_j); # First, extract information, from config then guess from repository adress if (my $tmp = `git config hooks.promo`) { chomp $tmp; $promo = $tmp; } @@ -78,9 +80,15 @@ if ($ref =~ m<^refs/tags/(.+)$>) $open = DateTime::Format::ISO8601->parse_datetime("2013-11-08T20:00:00"); $close = DateTime::Format::ISO8601->parse_datetime("2013-11-10T11:42:00"); } - - # TODO: check exceptions by login/group - $open = DateTime::Format::ISO8601->parse_datetime("2013-10-16T16:00:00") if ($repo_login eq "ikouna_l"); + if ($id_project eq "logomatig" && grep { $_ eq $repo_login } @salonS) + { + $open = DateTime::Format::ISO8601->parse_datetime("2013-11-24T09:00:00"); + $close = DateTime::Format::ISO8601->parse_datetime("2013-11-24T21:00:00"); + } + if ($id_project eq "logomatig" && grep { $_ eq $repo_login } @salonD) + { + $open = DateTime::Format::ISO8601->parse_datetime("2013-11-23T21:00:00"); + } say "Date courante : ", $glts->strftime("%d/%m/%Y %H:%M:%S"); From 8929aba28d7649d3199eb0573991dfd5ed59b137 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 23 Nov 2013 23:20:34 +0100 Subject: [PATCH 295/364] Add dufour_h exception --- hooks/submissions.pl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/hooks/submissions.pl b/hooks/submissions.pl index 8e422c7..4720bc9 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -80,15 +80,19 @@ if ($ref =~ m<^refs/tags/(.+)$>) $open = DateTime::Format::ISO8601->parse_datetime("2013-11-08T20:00:00"); $close = DateTime::Format::ISO8601->parse_datetime("2013-11-10T11:42:00"); } - if ($id_project eq "logomatig" && grep { $_ eq $repo_login } @salonS) + elsif ($id_project eq "logomatig" && grep { $_ eq $repo_login } @salonS) { $open = DateTime::Format::ISO8601->parse_datetime("2013-11-24T09:00:00"); $close = DateTime::Format::ISO8601->parse_datetime("2013-11-24T21:00:00"); } - if ($id_project eq "logomatig" && grep { $_ eq $repo_login } @salonD) + elsif ($id_project eq "logomatig" && grep { $_ eq $repo_login } @salonD) { $open = DateTime::Format::ISO8601->parse_datetime("2013-11-23T21:00:00"); } + elsif ($id_project eq "logomatig" && "dufour_h" eq $repo_login) + { + $close = DateTime::Format::ISO8601->parse_datetime("2013-11-24T16:42:00"); + } say "Date courante : ", $glts->strftime("%d/%m/%Y %H:%M:%S"); From db6814f4de44abbc423596382f3af15a3b326c4e Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 24 Nov 2013 01:05:08 +0100 Subject: [PATCH 296/364] Only last directory is repo_name --- hooks/subjects.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index f02c04e..ad026ff 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -69,7 +69,7 @@ sub check_xml sub repository_name { my $repo = $ENV{GL_REPO}; - $repo =~ s#^subjects/(.*)#$1#; + $repo =~ s#/([^/]*)#$1#; return $repo; } From 9c3ebb5139d4291537bdf36498352538ce11f334 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 24 Nov 2013 01:08:11 +0100 Subject: [PATCH 297/364] Ok --- hooks/subjects.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index ad026ff..75ac74d 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -69,7 +69,7 @@ sub check_xml sub repository_name { my $repo = $ENV{GL_REPO}; - $repo =~ s#/([^/]*)#$1#; + $repo =~ s#subject.*/([^/]+)$#$1#; return $repo; } From 84c34f8fea1a72b1174ab184b26ca084b16a2c4a Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 25 Nov 2013 19:20:03 +0100 Subject: [PATCH 298/364] Fix guantanamo syntax --- process/exec/guantanamo.pl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/process/exec/guantanamo.pl b/process/exec/guantanamo.pl index 745a120..1b209dd 100644 --- a/process/exec/guantanamo.pl +++ b/process/exec/guantanamo.pl @@ -121,13 +121,13 @@ sub master_launch } for my $node (@lnodes) { - my $o = $ret{$node}->documentElement->getElementsByTagName("out"); - if ($o) { + my @o = $ret{$node}->documentElement->getElementsByTagName("out"); + if (@o) { $output .= $o[0]->firstChild->nodeValue; } - $e = $ret{$node}->documentElement->getElementsByTagName("err"); - if ($e) { + my @e = $ret{$node}->documentElement->getElementsByTagName("err"); + if (@e) { $output .= $e[0]->firstChild->nodeValue; } $output .= $e[0]->firstChild->nodeValue; From dfb66035eb2d5f5321b57780633bc0d9b2313552 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 26 Nov 2013 19:17:19 +0100 Subject: [PATCH 299/364] New hook post-update --- Makefile | 1 + hooks/post-update | 96 ++++++++++++++++++++++++++++++++++++++++++++ hooks/submissions.pl | 39 +++--------------- 3 files changed, 103 insertions(+), 33 deletions(-) create mode 100755 hooks/post-update diff --git a/Makefile b/Makefile index 12886aa..7b856b5 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,7 @@ install: $(COPY) -r ACU/ $(DEST) ! test -d $(GITOLITE_DEST) || $(MAKEDIR) -p $(GITOLITE_DEST)/update.secondary.d ! test -d $(GITOLITE_DEST) || $(COPY) hooks/gl-pre-git $(GITOLITE_DEST)/ + ! test -d $(GITOLITE_DEST) || $(COPY) hooks/post-update $(GITOLITE_DEST)/ ! test -d $(GITOLITE_DEST) || $(COPY) hooks/subjects.pl $(GITOLITE_DEST)/update.secondary.d/ ! test -d $(GITOLITE_DEST) || $(COPY) hooks/conferences.pl $(GITOLITE_DEST)/update.secondary.d/ ! test -d $(GITOLITE_DEST) || $(COPY) hooks/submissions.pl $(GITOLITE_DEST)/update.secondary.d/ diff --git a/hooks/post-update b/hooks/post-update new file mode 100755 index 0000000..7fede19 --- /dev/null +++ b/hooks/post-update @@ -0,0 +1,96 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use v5.10; +use File::Basename; +use utf8; + +use ACU::API::Projects; +use ACU::API::Submission; +use ACU::LDAP; +use ACU::Log; +$ACU::Log::log_file = "/var/log/hooks/" . basename($0) . ".log"; +use ACU::Process; + +my $promo; +my $id_project; +my $repo_login; + +# First, extract information, from config then guess from repository adress +if (my $tmp = `git config hooks.promo`) { chomp $tmp; $promo = $tmp; } +if (my $tmp = `git config hooks.idproject`) { chomp $tmp; $id_project = $tmp; } +if (my $tmp = `git config hooks.login`) { chomp $tmp; $repo_login = $tmp; } + +$promo = $1 if (!$promo && $ENV{'GL_REPO'} =~ m/([0-9]{4}).*/); +$id_project = $1 if (!$id_project && $ENV{'GL_REPO'} =~ m/.*\/(.*)\//); +$repo_login = $1 if (!$repo_login && $ENV{'GL_REPO'} =~ m/.*\/.*\/(.*)/); + +exit(0) if (!$promo || !$id_project || !$repo_login); + +for my $ref (@ARGV) +{ + if ($ref =~ m<^refs/tags/(.+)$>) + { + my $tag = $1; + log DEBUG, "Tag $tag on repository $ENV{GL_REPO} from IP $ENV{'SSH_CLIENT'} updated."; + + # Get project informations + my $project; + eval { + $project = API::Projects::get($id_project, $promo); + }; + if ($@ or !$project) + { + my $err = $@; + log TRACE, $err; + log ERROR, "Impossible d'envoyer de tags ; si le problème persiste, passez au laboratoire."; + exit 1; + } + + # Extract lot of data + my @rendus = grep { + exists $_->{vcs} and $_->{vcs}{tag} eq $tag; + } @{ $project->{submissions} }; + + if (@rendus) + { + eval + { + Process::Client::launch("send_git", + { + "year" => $promo, + "id" => $id_project, + "rendu" => $tag, + "login" => $repo_login, +# "path" => "ssh://git\@localhost/".$ENV{GL_REPO}, # Optional + }, + undef, # Don't give any file + 1 # Launch in background + ); + }; + if ($@) + { + my $err = $@; + log DEBUG, "ERROR: ".$err; + } + + # Send data to API + my $last_commit = `git log "refs/tags/$tag" -1 --decorate --tags`; + eval { + API::Submission::add($promo, $id_project, $tag, $repo_login, $last_commit); + }; + if ($@) + { + my $err = $@; + log DEBUG, "ERROR: ".$err; + log DONE, "Tag '$tag' effectué avec succès !"; + } + else { + log DONE, "Tag '$tag' effectué avec succès ! Vérifiez-le sur l'intranet."; + } + } + } +} + +exit 0; diff --git a/hooks/submissions.pl b/hooks/submissions.pl index 4720bc9..5311df7 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -52,7 +52,7 @@ if ($ref =~ m<^refs/tags/(.+)$>) my $err = $@; log TRACE, $err; log ERROR, "Impossible d'envoyer de tags ; si le problème persiste, passez au laboratoire."; - exit 1; + exit(1); } log TRACE, $project; @@ -119,40 +119,13 @@ if ($ref =~ m<^refs/tags/(.+)$>) } } - if ($newsha eq '0' x 40) { - log USAGE, "Mais pour quelle raison voudriez-vous supprimer un tag ?!"; - } - else + if (@rendus && $newsha eq '0' x 40) { - eval { - Process::Client::launch("send_git", - { - "year" => $promo, - "id" => $id_project, - "rendu" => $tag, - "login" => $repo_login, -# "path" => "ssh://git\@localhost/".$ENV{GL_REPO}, - }, undef, 1); - }; - if ($@) { - my $err = $@; - log DEBUG, "ERROR: ".$err; - } - - # Send data to API - my $last_commit = `git log $newsha -1 --decorate --tags`; - eval { - API::Submission::add($promo, $id_project, $tag, $repo_login, $last_commit); - }; - if ($@) { - my $err = $@; - log DEBUG, "ERROR: ".$err; - log DONE, "Tag '$tag' effectué avec succès !"; - } - else { - log DONE, "Tag '$tag' effectué avec succès ! Vérifiez-le sur l'intranet."; - } + log USAGE, "Mais pour quelle raison voudriez-vous supprimer un tag ?!"; + exit(7); } +# elsif @rendus : new rendu => accepted +# else user defined tag => accepted } exit 0; From 5fe1d4c80d48a6cbaf0ae8dfc86a937f91ddb1b0 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 27 Nov 2013 15:26:13 +0100 Subject: [PATCH 300/364] Fix utf-8 --- hooks/gl-pre-git | 1 + 1 file changed, 1 insertion(+) diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git index 261160d..a66d5af 100755 --- a/hooks/gl-pre-git +++ b/hooks/gl-pre-git @@ -5,6 +5,7 @@ use warnings; use v5.10; use File::Basename; use Net::IP; +use utf8; use ACU::Log; $ACU::Log::log_file = "/var/log/hooks/" . basename($0) . ".log"; From a0f9002efd67727d373c2b6fbafe52bb5ecfd7f4 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 28 Nov 2013 20:28:52 +0100 Subject: [PATCH 301/364] Guantanamo: use sh to parse command --- process/exec/guantanamo_node.pl | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/process/exec/guantanamo_node.pl b/process/exec/guantanamo_node.pl index 0e0cdeb..0abac28 100644 --- a/process/exec/guantanamo_node.pl +++ b/process/exec/guantanamo_node.pl @@ -53,10 +53,18 @@ sub node_launch $command->appendText($c->{nodeValue}); $cmd->appendChild($command); - my($wtr, $rdr, $stderr); - my $pid = open3($wtr, $rdr, $stderr, $c->{nodeValue}); - waitpid( $pid, 0 ); - my $rv = $? >> 8; + my($wtr, $rdr, $rv); + my $stderr = ""; + eval { + my $pid = open3($wtr, $rdr, $stderr, "sh", "-c", $c->{nodeValue}); + waitpid( $pid, 0 ); + $rv = $? >> 8; + }; + if ($@) + { + $stderr = $@ . $stderr; + $rv = -1; + } my $out = $doc->createElement("out"); my $str = ""; From ad2748650b93f8e19e60de56302d1131ce81f071 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 28 Nov 2013 20:32:49 +0100 Subject: [PATCH 302/364] Guantanamo: avoid deadlock by sending register action in background --- process/exec/guantanamo_node.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/exec/guantanamo_node.pl b/process/exec/guantanamo_node.pl index 0abac28..8f2f920 100644 --- a/process/exec/guantanamo_node.pl +++ b/process/exec/guantanamo_node.pl @@ -110,7 +110,7 @@ if ($#ARGV == 0) { log INFO, "Starting guantanamo.pl as node process"; - Process::Client::launch("guantanamo", {"action" => "register", "nodename" => $ARGV[0]}); + Process::Client::launch("guantanamo", {"action" => "register", "nodename" => $ARGV[0]}, undef, 1); Process::register("guantanamo_".$ARGV[0], \&process_node); } From 55bec752b5b40e6c4641b6bcfb2e15140c9f645e Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 29 Nov 2013 17:37:52 +0100 Subject: [PATCH 303/364] Really close account when strong-auth close --- utils/lpt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/utils/lpt b/utils/lpt index acc9162..8ce5293 100644 --- a/utils/lpt +++ b/utils/lpt @@ -200,7 +200,7 @@ sub cmd_account_alias($@) return cmd_account_multiple_vieworchange('mailAlias', 'alias', @_); } -sub cmd_account_close($@) +sub cmd_account_close($;@) { my $login = shift; @@ -1572,6 +1572,8 @@ sub cmd_no_strong_auth_close(@) say $entry->get_value("uid"); + cmd_account_close($entry->get_value("uid")); + my $body = "Bonjour ".decode('UTF-8', $entry->get_value("cn"), Encode::FB_CROAK).", Après plusieurs relances de notre part, vous n'avez toujours pas activé From 971851633da75346363c9a48e8691474f5a37dbe Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 29 Nov 2013 18:17:42 +0100 Subject: [PATCH 304/364] Add execution right to lpt --- utils/lpt | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 utils/lpt diff --git a/utils/lpt b/utils/lpt old mode 100644 new mode 100755 From 9de4ca25b00871dff01f43f5b7c20f610822bd20 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 30 Nov 2013 22:24:34 +0100 Subject: [PATCH 305/364] Guantanamo: add list action to master process --- process/exec/guantanamo.pl | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/process/exec/guantanamo.pl b/process/exec/guantanamo.pl index 1b209dd..c503073 100644 --- a/process/exec/guantanamo.pl +++ b/process/exec/guantanamo.pl @@ -14,6 +14,7 @@ use ACU::Process; my %master_actions = ( "launch" => \&master_launch, + "list" => \&master_list, "register" => \&master_register, ); @@ -23,17 +24,40 @@ sub master_register { my $args = shift; - if ($args->{param}{nodename}) { + if ($args->{param}{nodename}) + { my $nodename = $args->{param}{nodename}; - log INFO, "New node: $nodename"; - push @nodes, "$nodename"; + if (! grep { $_ eq $nodename } @nodes) + { + log INFO, "New node: $nodename"; + push @nodes, "$nodename"; + } + else { + log WARN, "Node $nodename alredy registered"; + } } else { log WARN, "nodename empty, cannot register new node"; } } +sub master_list +{ + my $doc = XML::LibXML::Document->new('1.0'); + my $root = $doc->createElement("process"); + + for my $target (@nodes) + { + my $t = $doc->createElement("target"); + $t->setAttribute("name", $target); + $root->appendChild($t); + } + + $doc->setDocumentElement( $root ); + return $doc->toString(); +} + sub build_task_xml { my $files = shift; From 16f3dbfecbc2883f8de632d433ec5009e2d91934 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sat, 30 Nov 2013 22:32:21 +0100 Subject: [PATCH 306/364] New guantanomo_list command --- commands/guantanamo_list.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100755 commands/guantanamo_list.sh diff --git a/commands/guantanamo_list.sh b/commands/guantanamo_list.sh new file mode 100755 index 0000000..a23aac1 --- /dev/null +++ b/commands/guantanamo_list.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +if ! which gearman > /dev/null 2> /dev/null +then + echo "gearman isn't installed on this machine. Please try another one." + exit 1 +fi + +cat < + + list + +EOF From 415b5c81fdf001e3ec065f7f4a1f7678a1cbd66c Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 1 Dec 2013 01:12:02 +0100 Subject: [PATCH 307/364] Use multiple Gearman servers --- ACU/Process.pm | 20 ++++++++++++++++---- process/exec/guantanamo.pl | 1 + process/files/intradata_get.pl | 2 +- process/projects/gen_grading.pl | 1 + process/projects/get_csv.pl | 1 + 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/ACU/Process.pm b/ACU/Process.pm index 0bd1e4d..e1700e6 100644 --- a/ACU/Process.pm +++ b/ACU/Process.pm @@ -22,6 +22,18 @@ our $nb_cpus = 0; $nb_cpus = grep {/^processor\s/} <$cpuinfo>; close $cpuinfo; +my @servers = ("gearmand-srv:4730"); + +sub add_server(@) +{ + push @servers, @_; +} + +sub set_servers(@) +{ + @servers = @_; +} + sub check_load ($) { my $priority = shift; @@ -94,7 +106,7 @@ sub register_no_parse ($$;$) my $worker = Gearman::Worker->new; - $worker->job_servers('gearmand:4730'); + $worker->job_servers( @servers ); $worker->register_function($funcname => sub { my $ret; @@ -127,7 +139,7 @@ sub register ($$;$$) my $worker = Gearman::Worker->new; - $worker->job_servers('gearmand:4730'); + $worker->job_servers( @servers ); $worker->register_function($funcname => sub { return do_work($subref, $given_arg, $priority, @_); }); # Disable exit on warning or error @@ -196,7 +208,7 @@ sub launch ($$;$$) my $funcname = shift; my $client = Gearman::Client->new; - $client->job_servers('gearmand:4730'); + $client->job_servers( @servers ); log DEBUG, "Launching $funcname..."; @@ -219,7 +231,7 @@ sub paralaunch ($$;$) my $xml = build_task_xml(shift, shift); my $client = Gearman::Client->new; - $client->job_servers('gearmand:4730'); + $client->job_servers( @servers ); my $taskset = $client->new_task_set; for my $task (@{ $funcsname }) diff --git a/process/exec/guantanamo.pl b/process/exec/guantanamo.pl index c503073..706def8 100644 --- a/process/exec/guantanamo.pl +++ b/process/exec/guantanamo.pl @@ -196,4 +196,5 @@ sub process_master log INFO, "Starting guantanamo.pl as master process"; +Process::add_server("gearman:4730"); Process::register("guantanamo", \&process_master); diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index 294fbcd..649674d 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -150,7 +150,7 @@ sub grades_generate log DEBUG, "Computed grades: ".$grading->compute($login); - open my $xmlgrade, ">", "$basedir/$year/$project_id/grades/$login.xml" or croak "grades/$login.xml"; + open my $xmlgrade, ">", "$basedir/$year/$project_id/grades/$login.xml" or croak "grades/$login.xml: $!"; binmode $xmlgrade; print $xmlgrade $grading->computeXML($login); close $xmlgrade; diff --git a/process/projects/gen_grading.pl b/process/projects/gen_grading.pl index 0597c10..9b91ff5 100644 --- a/process/projects/gen_grading.pl +++ b/process/projects/gen_grading.pl @@ -97,4 +97,5 @@ sub process return $grade->toString; } +Process::add_server("gearman:4730"); Process::register_no_parse("gen_grading", \&process); diff --git a/process/projects/get_csv.pl b/process/projects/get_csv.pl index fa21f79..746f230 100644 --- a/process/projects/get_csv.pl +++ b/process/projects/get_csv.pl @@ -105,4 +105,5 @@ sub process return $out; } +Process::add_server("gearman:4730"); Process::register_no_parse("get_csv", \&process); From 24170b0b4ece801ec27de297575e01ee2d10fa3e Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 1 Dec 2013 01:14:35 +0100 Subject: [PATCH 308/364] CPP is now the guantanamo master --- process/launch.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/process/launch.sh b/process/launch.sh index efac6fd..90e2ccf 100755 --- a/process/launch.sh +++ b/process/launch.sh @@ -84,6 +84,7 @@ then case $HOSTNAME in cpp) + launch_screen "lerdorf_process_exec_guantanamo" "while true; do $PERL ~/liblerdorf/process/exec/guantanamo.pl; done" reset_agents launch_screen "lerdorf_process_ldap_sync_ssh_keys_forge" "while true; do $PERL ~/liblerdorf/process/ldap/sync_ssh_keys_forge.pl; done" ~intradmin/.ssh/git ;; From 810c589ec0f31ba05d0258d4fd5efd70bc3e6f2f Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 1 Dec 2013 01:44:20 +0100 Subject: [PATCH 309/364] Git hook exception (VJ + #22077) --- hooks/gl-pre-git | 4 ++-- hooks/submissions.pl | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git index a66d5af..aa94503 100755 --- a/hooks/gl-pre-git +++ b/hooks/gl-pre-git @@ -52,11 +52,11 @@ if ($ip->overlaps($labnetwork) == $IP_A_IN_B_OVERLAP) exit 0 if (grep { /\Q$ENV{GL_USER}\E/ } @habitent_loin); my $schoolnetwork = Net::IP->new('10.41.0.0/16'); -#my $vjschoolnetwork = Net::IP->new('10.3.0.0/16'); +my $vjschoolnetwork = Net::IP->new('10.3.0.0/16'); if ( $ip->overlaps($schoolnetwork) != $IP_A_IN_B_OVERLAP -# && $ip->overlaps($vjschoolnetwork) != $IP_A_IN_B_OVERLAP + && $ip->overlaps($vjschoolnetwork) != $IP_A_IN_B_OVERLAP ) { say "Votre IP est : ".$ip->ip(); diff --git a/hooks/submissions.pl b/hooks/submissions.pl index 5311df7..e35e24e 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -8,6 +8,7 @@ use File::Basename; use Net::IP; use POSIX qw(strftime); use Socket; +use utf8; use ACU::API::Projects; use ACU::API::Submission; @@ -93,6 +94,10 @@ if ($ref =~ m<^refs/tags/(.+)$>) { $close = DateTime::Format::ISO8601->parse_datetime("2013-11-24T16:42:00"); } + elsif ($id_project eq "42sh" && "hadjad_r" eq $repo_login) + { + $close = DateTime::Format::ISO8601->parse_datetime("2013-12-01T17:42:00"); + } say "Date courante : ", $glts->strftime("%d/%m/%Y %H:%M:%S"); From 05c7f4b9c6274576bc538f7818b69241281c5840 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 1 Dec 2013 03:40:12 +0100 Subject: [PATCH 310/364] Add DEBUG log --- ACU/Process.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ACU/Process.pm b/ACU/Process.pm index e1700e6..1bc226f 100644 --- a/ACU/Process.pm +++ b/ACU/Process.pm @@ -139,6 +139,8 @@ sub register ($$;$$) my $worker = Gearman::Worker->new; + log DEBUG, "Registering function $funcname on ", join(", ", @servers); + $worker->job_servers( @servers ); $worker->register_function($funcname => sub { return do_work($subref, $given_arg, $priority, @_); }); From faf03232f43437e9d18626c3223a32d7a5a5061c Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 1 Dec 2013 04:21:04 +0100 Subject: [PATCH 311/364] Tiny fixes --- ACU/Log.pm | 2 +- process/exec/guantanamo_node.pl | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/ACU/Log.pm b/ACU/Log.pm index c9685fe..a1641b1 100644 --- a/ACU/Log.pm +++ b/ACU/Log.pm @@ -9,7 +9,6 @@ use open IO => ':utf8'; use open ':std'; use Data::Dumper; -use Email::MIME; use Exporter 'import'; use POSIX qw(strftime); use Term::ANSIColor qw(:constants); @@ -71,6 +70,7 @@ sub log if ($mail_error && $level <= ERROR) { + require Email::MIME; require Email::Sender::Simple; Email::Sender::Simple->import(qw(sendmail)); my $mail = Email::MIME->create( diff --git a/process/exec/guantanamo_node.pl b/process/exec/guantanamo_node.pl index 8f2f920..3a8f208 100644 --- a/process/exec/guantanamo_node.pl +++ b/process/exec/guantanamo_node.pl @@ -9,7 +9,6 @@ use File::Temp qw/tempfile tempdir/; use IPC::Open3; use XML::LibXML; -use ACU::LDAP; use ACU::Log; use ACU::Process; @@ -101,7 +100,7 @@ sub process_node my $action = $args->{param}{action} // "launch"; if (! exists $node_actions{$action}) { - log WARN, "Unknown action '$action' for guantanamo node process."; + warn "Unknown action '$action' for guantanamo node process."; } return $node_actions{$action}($args); } From d077a5933f40d0a31dfeae670a446af152966a0c Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 1 Dec 2013 05:58:19 +0100 Subject: [PATCH 312/364] Try a fix --- ACU/Process.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ACU/Process.pm b/ACU/Process.pm index 1bc226f..c83a046 100644 --- a/ACU/Process.pm +++ b/ACU/Process.pm @@ -22,7 +22,7 @@ our $nb_cpus = 0; $nb_cpus = grep {/^processor\s/} <$cpuinfo>; close $cpuinfo; -my @servers = ("gearmand-srv:4730"); +our @servers = ("gearmand-srv:4730"); sub add_server(@) { From bbde6828961f11d934ed192d3799a7ef8804eb5c Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 1 Dec 2013 06:04:37 +0100 Subject: [PATCH 313/364] Try a fix --- ACU/Process.pm | 6 +++--- process/projects/get_csv.pl | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ACU/Process.pm b/ACU/Process.pm index c83a046..21ea5c5 100644 --- a/ACU/Process.pm +++ b/ACU/Process.pm @@ -24,12 +24,12 @@ close $cpuinfo; our @servers = ("gearmand-srv:4730"); -sub add_server(@) +sub add_server { push @servers, @_; } -sub set_servers(@) +sub set_servers { @servers = @_; } @@ -139,7 +139,7 @@ sub register ($$;$$) my $worker = Gearman::Worker->new; - log DEBUG, "Registering function $funcname on ", join(", ", @servers); + log INFO, "Registering function $funcname on ", join(", ", @servers); $worker->job_servers( @servers ); $worker->register_function($funcname => sub { return do_work($subref, $given_arg, $priority, @_); }); diff --git a/process/projects/get_csv.pl b/process/projects/get_csv.pl index 746f230..cc32ab3 100644 --- a/process/projects/get_csv.pl +++ b/process/projects/get_csv.pl @@ -105,5 +105,5 @@ sub process return $out; } -Process::add_server("gearman:4730"); +Process::set_servers("gearman:4730"); Process::register_no_parse("get_csv", \&process); From aef2b7d71eba8c878c288c1215a58eb455bc345e Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 1 Dec 2013 06:12:27 +0100 Subject: [PATCH 314/364] Add part for guantanamo.tar.gz --- Makefile | 9 +++ commands/first-install.sh | 4 +- process/exec/run.sh.not-here | 138 +++++++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 process/exec/run.sh.not-here diff --git a/Makefile b/Makefile index 7b856b5..9aba33a 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,15 @@ install: ! test -d $(GITOLITE_DEST) || $(COPY) hooks/conferences.pl $(GITOLITE_DEST)/update.secondary.d/ ! test -d $(GITOLITE_DEST) || $(COPY) hooks/submissions.pl $(GITOLITE_DEST)/update.secondary.d/ +guantanamo.tar.gz: + $(MAKEDIR) -p guantanamo/ACU + $(COPY) process/exec/guantanamo_node.pl guantanamo/ + $(COPY) ACU/Log.pm ACU/Process.pm process/exec/guantanamo_node.pl guantanamo/ACU/ + $(COPY) process/exec/run.sh.not-here guantanamo/run.sh + chmod +x guantanamo/run.sh + tar czf guantanamo.tar.gz guantanamo/ + rm -rf guantanamo + update: $(GIT) pull $(SHELL) commands/first-install.sh diff --git a/commands/first-install.sh b/commands/first-install.sh index afd3e4e..893ef6b 100755 --- a/commands/first-install.sh +++ b/commands/first-install.sh @@ -3,8 +3,8 @@ # Install missing packages DEB_PACKAGES_LIST="screen libnet-ldap-perl libxml-libxml-perl libgearman-client-perl libmailtools-perl libdatetime-format-iso8601-perl libnet-ip-perl libsys-gamin-perl libdigest-sha-perl libemail-mime-perl libemail-sender-perl libtext-glob-perl" ARCH_PACKAGES_LIST="screen perl-io-socket-ssl perl-email-mime perl-term-readkey perl-ldap perl-lwp-protocol-https perl-datetime-format-iso8601 perl-net-ip" # aur/perl-sys-gamin aur/perl-text-glob -GENTOO_PACKAGES_LIST="app-misc/screen dev-perl/IO-Socket-SSL dev-perl/Email-MIME dev-perl/TermReadKey dev-perl/perl-ldap dev-perl/LWP-Protocol-https dev-perl/DateTime-Format-ISO8601 dev-perl/Net-IP dev-perl/Email-Sender dev-perl/Text-Glob" -FBSD_PACKAGES_LIST="screen p5-IO-Socket-SSL p5-Email-MIME p5-Term-ANSIColor p5-Term-ReadKey p5-LWP-Protocol-https p5-DateTime-Format-ISO8601 p5-Net-IP p5-Sys-Gamin p5-Text-Glob" +GENTOO_PACKAGES_LIST="app-misc/screen dev-perl/XML-LibXML dev-perl/IO-Socket-SSL dev-perl/Email-MIME dev-perl/TermReadKey dev-perl/perl-ldap dev-perl/LWP-Protocol-https dev-perl/DateTime-Format-ISO8601 dev-perl/Net-IP dev-perl/Email-Sender dev-perl/Text-Glob" +FBSD_PACKAGES_LIST="screen p5-XML-LibXML p5-Gearman p5-IO-Socket-SSL p5-Email-MIME p5-Term-ANSIColor p5-Term-ReadKey p5-LWP-Protocol-https p5-DateTime-Format-ISO8601 p5-Net-IP p5-Sys-Gamin p5-Text-Glob" KERNEL=`uname -s` diff --git a/process/exec/run.sh.not-here b/process/exec/run.sh.not-here new file mode 100644 index 0000000..56d5c05 --- /dev/null +++ b/process/exec/run.sh.not-here @@ -0,0 +1,138 @@ +#!/usr/bin/env sh + +cd $(dirname "$0") + +GREP='/usr/bin/env grep -E' +SCREEN='/usr/bin/env screen' +SED='/usr/bin/env sed -E' +if [ `uname -s` = "FreeBSD" ]; then + SU="/usr/bin/env su" +else + SU='/usr/bin/env su -s /bin/sh' +fi +PERL='/usr/bin/env perl' + +# Install missing packages +DEB_PACKAGES_LIST="screen libxml-libxml-perl libgearman-client-perl" +ARCH_PACKAGES_LIST="screen" +GENTOO_PACKAGES_LIST="app-misc/screen dev-perl/XML-LibXML" +FBSD_PACKAGES_LIST="screen p5-XML-LibXML p5-Gearman p5-Term-ANSIColor" + +KERNEL=`uname -s` + + +if [ "$KERNEL" = "FreeBSD" ] +then + + for PK in `echo $FBSD_PACKAGES_LIST` + do + if ! pkg info "$PK" > /dev/null 2> /dev/null + then + if ! PACKAGESITE="http://canon.acu.epita.fr/repo-lab" pkg install "$PK" + then + echo "Error during installation of $PK" + exit 1 + fi + fi + done + + if ! getent passwd | grep "guantanamo:" > /dev/null 2> /dev/null + then + pw useradd guantanamo -u 941 -d /home/guantanamo -s /bin/false + fi + +elif [ "$KERNEL" = "Linux" ] +then + + if [ -f "/etc/debian_version" ] + then + + if ! whereis dpkg > /dev/null 2> /dev/null + then + if ! aptitude install dpkg + then + echo "Error during installation of $PK" + exit 1 + fi + fi + + for PK in $DEB_PACKAGES_LIST + do + if ! dpkg -l | grep "^ii" | grep "$PK" > /dev/null 2> /dev/null + then + aptitude install "$PK" + fi + done + + elif [ -f "/etc/arch-release" ] + then + + for PK in $ARCH_PACKAGES_LIST + do + if ! pacman -Qi "$PK" > /dev/null 2> /dev/null + then + if ! pacman -S "$PK" + then + echo "Error during installation of $PK" + exit 1 + fi + fi + done + + elif [ -f "/etc/gentoo-release" ] + then + + for PK in $GENTOO_PACKAGES_LIST + do + if ! equery list "$PK" > /dev/null 2> /dev/null + then + if ! emerge "$PK" + then + echo "Error during installation of $PK" + exit 1 + fi + fi + done + + else + + echo "Unsupported GNU/Linux distribution :(" + exit 1; + + fi + + + # Add guantanamo user if missing + if ! getent passwd | grep "guantanamo:" > /dev/null 2> /dev/null + then + useradd --shell /bin/false --uid 941 guantanamo && + mkdir -p /home/guantanamo + fi + + chown -R guantanamo:guantanamo /home/guantanamo + +else + + echo "Unsupported operating system :(" + exit 1; + +fi + +chown -R guantanamo . + +if [ $# -gt 0 ] +then + ARCHNAME=$1 +else + echo "Expected at first argument: node name. For example: hurd-ia64" + exit 1 +fi + +CMD="$SCREEN -S 'guantanamo_$ARCHNAME' -d -m sh -c 'while true; do perl guantanamo_node.pl $ARCHNAME; done'" + +if [ "x$UID" = "x0" ] +then + echo "$CMD" | $SU guantanamo +else + $CMD +fi From 1e9e89656d2a09c789111e7aaf84d970c7f99848 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 1 Dec 2013 06:16:51 +0100 Subject: [PATCH 315/364] Add DEBUG string --- ACU/Process.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ACU/Process.pm b/ACU/Process.pm index 21ea5c5..405365f 100644 --- a/ACU/Process.pm +++ b/ACU/Process.pm @@ -106,6 +106,8 @@ sub register_no_parse ($$;$) my $worker = Gearman::Worker->new; + log INFO, "Registering function $funcname on ", join(", ", @servers); + $worker->job_servers( @servers ); $worker->register_function($funcname => sub { From 2520bf59a303ddfb6e0f865a127f231388032b2e Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 1 Dec 2013 17:37:09 +0100 Subject: [PATCH 316/364] Fix gearmand server destination --- commands/moulette/launch.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/moulette/launch.sh b/commands/moulette/launch.sh index e15ad14..1b79ab6 100755 --- a/commands/moulette/launch.sh +++ b/commands/moulette/launch.sh @@ -32,7 +32,7 @@ do shift done -cat < moulette From f6a96399c272f577cbbcbe8a885cc9ff7bf2755c Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 2 Dec 2013 18:20:10 +0100 Subject: [PATCH 317/364] New gen_git_str --- commands/project/gen_git_str.pl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/commands/project/gen_git_str.pl b/commands/project/gen_git_str.pl index 14cffec..bb4b74f 100644 --- a/commands/project/gen_git_str.pl +++ b/commands/project/gen_git_str.pl @@ -25,10 +25,14 @@ map { } } - say "repo $year/$projid/$chief->{login}"; - print ' RW+ = @admins'; + my @members; for my $member (@{ $_->{stds} }) { - print ' '.$member->{login}; + push @members, $member->{login}; } - say "\n R = \@chefs \@resp-$year-$projid \@soutenance-$year-$projid"; + + say "repo $year/$projid/$chief->{login}"; + say " - ACU-moulette = ", join(" ", @members); + say ' RW+ = @admins ', join(" ", @members); + say ' RW ACU-moulette = @moulettes'; + say " R = \@chefs \@resp-$year-$projid \@soutenance-$year-$projid \@moulettes"; } @{ $res->{groups} }; From 868324e6e276ce79ab0441d54baba258228ece7d Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 2 Dec 2013 18:21:06 +0100 Subject: [PATCH 318/364] Remove git access from VJ --- hooks/gl-pre-git | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git index aa94503..dba50c0 100755 --- a/hooks/gl-pre-git +++ b/hooks/gl-pre-git @@ -56,7 +56,7 @@ my $vjschoolnetwork = Net::IP->new('10.3.0.0/16'); if ( $ip->overlaps($schoolnetwork) != $IP_A_IN_B_OVERLAP - && $ip->overlaps($vjschoolnetwork) != $IP_A_IN_B_OVERLAP +# && $ip->overlaps($vjschoolnetwork) != $IP_A_IN_B_OVERLAP ) { say "Votre IP est : ".$ip->ip(); From 45ba55a416e3a2d0953f6e23fbf5457be3400063 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 2 Dec 2013 21:11:17 +0100 Subject: [PATCH 319/364] New hooks version: allow ACU-* tags --- hooks/post-update | 44 ++++++++++------- hooks/submissions.pl | 112 +++++++++++++++++++++++++++---------------- 2 files changed, 98 insertions(+), 58 deletions(-) diff --git a/hooks/post-update b/hooks/post-update index 7fede19..ee163b2 100755 --- a/hooks/post-update +++ b/hooks/post-update @@ -30,25 +30,14 @@ exit(0) if (!$promo || !$id_project || !$repo_login); for my $ref (@ARGV) { - if ($ref =~ m<^refs/tags/(.+)$>) + if ($ref =~ m<^refs/tags/ACU-(.+)$> || $ref =~ m<^refs/tags/(.+)$>) { my $tag = $1; log DEBUG, "Tag $tag on repository $ENV{GL_REPO} from IP $ENV{'SSH_CLIENT'} updated."; - # Get project informations - my $project; - eval { - $project = API::Projects::get($id_project, $promo); - }; - if ($@ or !$project) - { - my $err = $@; - log TRACE, $err; - log ERROR, "Impossible d'envoyer de tags ; si le problème persiste, passez au laboratoire."; - exit 1; - } + my $project = get_project_info($tag); - # Extract lot of data + # Extract matching tag my @rendus = grep { exists $_->{vcs} and $_->{vcs}{tag} eq $tag; } @{ $project->{submissions} }; @@ -77,14 +66,14 @@ for my $ref (@ARGV) # Send data to API my $last_commit = `git log "refs/tags/$tag" -1 --decorate --tags`; - eval { - API::Submission::add($promo, $id_project, $tag, $repo_login, $last_commit); - }; + eval { + API::Submission::add($promo, $id_project, $tag, $repo_login, $last_commit); + }; if ($@) { my $err = $@; log DEBUG, "ERROR: ".$err; - log DONE, "Tag '$tag' effectué avec succès !"; + log DONE, "Tag '$tag' effectué avec succès !"; } else { log DONE, "Tag '$tag' effectué avec succès ! Vérifiez-le sur l'intranet."; @@ -94,3 +83,22 @@ for my $ref (@ARGV) } exit 0; + +sub get_project_info +{ + my $project; + eval { + $project = API::Projects::get($id_project, $promo); + }; + if ($@ or !$project) + { + my $err = $@; + log TRACE, $err; + log ERROR, "Impossible d'envoyer de tags ; si le problème persiste, passez au laboratoire."; + exit(1); + } + + log TRACE, $project; + + return $project; +} diff --git a/hooks/submissions.pl b/hooks/submissions.pl index e35e24e..f9cca96 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -38,12 +38,68 @@ $repo_login = $1 if (!$repo_login && $ENV{'GL_REPO'} =~ m/.*\/.*\/(.*)/); exit(0) if (!$promo || !$id_project || !$repo_login); -if ($ref =~ m<^refs/tags/(.+)$>) +if ($ref =~ m<^refs/tags/ACU-(.+)$>) { my $tag = $1; - log DEBUG, "Pushed tag for repository $ENV{GL_REPO}: $tag with IP $ENV{'SSH_CLIENT'}"; + log INFO, "Pushed tag for repository $ENV{GL_REPO}: $tag with IP $ENV{'SSH_CLIENT'}"; - # Get project informations + # Disallow no ACU + if ($ENV{GL_USER} ne "frotti_b" && $ENV{GL_USER} ne "chen_a" && $ENV{GL_USER} ne "boisse_r" && $ENV{GL_USER} ne "genite_n" && $ENV{GL_USER} ne "mercie_d") + { + log ERROR, "Vous n'êtes pas autorisé à envoyer ce tag."; + exit(9); + } + + my $project = get_project_info($tag); + + # Extract matching tag + my @rendus = grep { + exists $_->{vcs} and $_->{vcs}{tag} eq $tag; + } @{ $project->{submissions} }; + + if (! @rendus) + { + log ERROR, "$tag n'est pas un tag valide."; + exit(8); + } +} +elsif ($ref =~ m<^refs/tags/(.+)$>) +{ + my $tag = $1; + log INFO, "Pushed tag for repository $ENV{GL_REPO}: $tag with IP $ENV{'SSH_CLIENT'}"; + + my $project = get_project_info($tag); + + # Extract matching tag + my @rendus = grep { + exists $_->{vcs} and $_->{vcs}{tag} eq $tag; + } @{ $project->{submissions} }; + + if (@rendus) + { + if ($newsha eq '0' x 40) + { + log USAGE, "Mais pour quelle raison voudriez-vous supprimer un tag ?!"; + exit(7); + } + + chomp (my $tokengiven = `git cat-file tag $newsha 2> /dev/null | sed -e '1,/^\$/d'`); + if (! check_submission_date($tokengiven, @rendus)) + { + exit (9); + } + } + else + { + log ERROR, "$tag n'est pas un tag valide."; + exit(8) + } +} + +exit 0; + +sub get_project_info +{ my $project; eval { $project = API::Projects::get($id_project, $promo); @@ -58,10 +114,12 @@ if ($ref =~ m<^refs/tags/(.+)$>) log TRACE, $project; - # Extract lot of data - my @rendus = grep { - exists $_->{vcs} and $_->{vcs}{tag} eq $tag; - } @{ $project->{submissions} }; + return $project; +} + +sub check_submission_date +{ + my $tokengiven = shift; my $glts = DateTime::Format::ISO8601->parse_datetime( do { @@ -70,34 +128,16 @@ if ($ref =~ m<^refs/tags/(.+)$>) $t }); - chomp (my $tokengiven = `git cat-file tag $newsha 2> /dev/null | sed -e '1,/^\$/d'`); - for my $rendu (@rendus) + for my $rendu (@_) { my $open = DateTime::Format::ISO8601->parse_datetime($rendu->{period}{begin}); my $close = DateTime::Format::ISO8601->parse_datetime($rendu->{period}{end}); - if ($id_project eq "myhttpd" && grep { $_ eq $repo_login } @apping) - { - $open = DateTime::Format::ISO8601->parse_datetime("2013-11-08T20:00:00"); - $close = DateTime::Format::ISO8601->parse_datetime("2013-11-10T11:42:00"); - } - elsif ($id_project eq "logomatig" && grep { $_ eq $repo_login } @salonS) - { - $open = DateTime::Format::ISO8601->parse_datetime("2013-11-24T09:00:00"); - $close = DateTime::Format::ISO8601->parse_datetime("2013-11-24T21:00:00"); - } - elsif ($id_project eq "logomatig" && grep { $_ eq $repo_login } @salonD) - { - $open = DateTime::Format::ISO8601->parse_datetime("2013-11-23T21:00:00"); - } - elsif ($id_project eq "logomatig" && "dufour_h" eq $repo_login) - { - $close = DateTime::Format::ISO8601->parse_datetime("2013-11-24T16:42:00"); - } - elsif ($id_project eq "42sh" && "hadjad_r" eq $repo_login) - { - $close = DateTime::Format::ISO8601->parse_datetime("2013-12-01T17:42:00"); - } +# if ($id_project eq "myhttpd" && grep { $_ eq $repo_login } @apping) +# { +# $open = DateTime::Format::ISO8601->parse_datetime("2013-11-08T20:00:00"); +# $close = DateTime::Format::ISO8601->parse_datetime("2013-11-10T11:42:00"); +# } say "Date courante : ", $glts->strftime("%d/%m/%Y %H:%M:%S"); @@ -124,13 +164,5 @@ if ($ref =~ m<^refs/tags/(.+)$>) } } - if (@rendus && $newsha eq '0' x 40) - { - log USAGE, "Mais pour quelle raison voudriez-vous supprimer un tag ?!"; - exit(7); - } -# elsif @rendus : new rendu => accepted -# else user defined tag => accepted + return 1; } - -exit 0; From 15408c1144559ab7529d357bd8570d3a4bc2dbfb Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 2 Dec 2013 23:33:39 +0100 Subject: [PATCH 320/364] Remove INFO submission --- hooks/submissions.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hooks/submissions.pl b/hooks/submissions.pl index f9cca96..c455d7e 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -41,7 +41,7 @@ exit(0) if (!$promo || !$id_project || !$repo_login); if ($ref =~ m<^refs/tags/ACU-(.+)$>) { my $tag = $1; - log INFO, "Pushed tag for repository $ENV{GL_REPO}: $tag with IP $ENV{'SSH_CLIENT'}"; + log DEBUG, "Pushed tag for repository $ENV{GL_REPO}: $tag with IP $ENV{'SSH_CLIENT'}"; # Disallow no ACU if ($ENV{GL_USER} ne "frotti_b" && $ENV{GL_USER} ne "chen_a" && $ENV{GL_USER} ne "boisse_r" && $ENV{GL_USER} ne "genite_n" && $ENV{GL_USER} ne "mercie_d") @@ -66,7 +66,7 @@ if ($ref =~ m<^refs/tags/ACU-(.+)$>) elsif ($ref =~ m<^refs/tags/(.+)$>) { my $tag = $1; - log INFO, "Pushed tag for repository $ENV{GL_REPO}: $tag with IP $ENV{'SSH_CLIENT'}"; + log DEBUG, "Pushed tag for repository $ENV{GL_REPO}: $tag with IP $ENV{'SSH_CLIENT'}"; my $project = get_project_info($tag); From 6d294dbcf658e6fa9e9d0d0540d4b29e3804f81e Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 3 Dec 2013 01:08:47 +0100 Subject: [PATCH 321/364] Save witch person push or clone to a repo --- hooks/gl-pre-git | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git index dba50c0..00c3c8a 100755 --- a/hooks/gl-pre-git +++ b/hooks/gl-pre-git @@ -14,7 +14,7 @@ my $ip = $1 if ($ENV{'SSH_CLIENT'} =~ m/([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0- exit 0 if (!$ip); -log DEBUG, "Connection with $ARGV[0] to $ENV{GL_REPO} from $ip"; +log DEBUG, "Connection by $ENV{GL_USER} with $ARGV[0] to $ENV{GL_REPO} from $ip"; my $promo = qx(git config hooks.promo); my $id_project = qx(git config hooks.idproject); From 4e1e73f2847a9767691c4a5ba933e2c3987ff64a Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 5 Dec 2013 00:54:04 +0100 Subject: [PATCH 322/364] Add intradmin-hamano to gen_git_str for send_git process --- commands/project/gen_git_str.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/project/gen_git_str.pl b/commands/project/gen_git_str.pl index bb4b74f..f3f07fe 100644 --- a/commands/project/gen_git_str.pl +++ b/commands/project/gen_git_str.pl @@ -34,5 +34,5 @@ map { say " - ACU-moulette = ", join(" ", @members); say ' RW+ = @admins ', join(" ", @members); say ' RW ACU-moulette = @moulettes'; - say " R = \@chefs \@resp-$year-$projid \@soutenance-$year-$projid \@moulettes"; + say " R = \@chefs \@resp-$year-$projid \@soutenance-$year-$projid \@moulettes intradmin-hamano"; } @{ $res->{groups} }; From d1b027a3fff05dde4a20df5409006ea4c22ce27e Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 5 Dec 2013 00:54:30 +0100 Subject: [PATCH 323/364] Autoflush log filehandles --- ACU/Log.pm | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/ACU/Log.pm b/ACU/Log.pm index a1641b1..bf3f165 100644 --- a/ACU/Log.pm +++ b/ACU/Log.pm @@ -52,12 +52,17 @@ sub log if (!$log_fd && $log_file) { open ($log_fd, ">>", $log_file) or croak("Unable to open log ($log_file) file for writing"); + + # Enable autoflush for the log file + my $previous_default = select($log_fd); + $|++; + select($previous_default); + say $log_fd strftime("%a %b %e %H:%M:%S %Y", localtime), " START new logging session "; } if ($level <= $save_level and $log_fd) { - local $| = 1; print $log_fd strftime("%a %b %e %H:%M:%S %Y", localtime), " ", levelstr($level), " "; if ($level == TRACE) { @@ -102,12 +107,17 @@ The lerdorf project", sendmail($mail); } - if ($level <= $display_level) { + if ($level <= $display_level) + { + $|++; # Autoflush STDOUT + if ($level == PENDING) { print STDERR (leveldisp($level), @_, RESET, "\r"); } else { say STDERR (leveldisp($level), @_, RESET); } + + $|--; # Disable autoflush } if ($fatal_warn && $level <= WARN){ From 4af0617cae8f06555762f8681ec8dfccde13b7bf Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 5 Dec 2013 01:09:55 +0100 Subject: [PATCH 324/364] Receive ACU-* tags --- hooks/post-update | 93 +++++++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 44 deletions(-) diff --git a/hooks/post-update b/hooks/post-update index ee163b2..9f13577 100755 --- a/hooks/post-update +++ b/hooks/post-update @@ -30,54 +30,59 @@ exit(0) if (!$promo || !$id_project || !$repo_login); for my $ref (@ARGV) { - if ($ref =~ m<^refs/tags/ACU-(.+)$> || $ref =~ m<^refs/tags/(.+)$>) + my $tag; + if ($ref =~ m<^refs/tags/ACU-(.+)$>) { + $tag = $1; + } elsif ($ref =~ m<^refs/tags/(.+)$>) { + $tag = $1; + } else { + next; + } + + log DEBUG, "Tag $tag on repository $ENV{GL_REPO} from IP $ENV{'SSH_CLIENT'} updated."; + + my $project = get_project_info($tag); + + # Extract matching tag + my @rendus = grep { + exists $_->{vcs} and $_->{vcs}{tag} eq $tag; + } @{ $project->{submissions} }; + + if (@rendus) { - my $tag = $1; - log DEBUG, "Tag $tag on repository $ENV{GL_REPO} from IP $ENV{'SSH_CLIENT'} updated."; - - my $project = get_project_info($tag); - - # Extract matching tag - my @rendus = grep { - exists $_->{vcs} and $_->{vcs}{tag} eq $tag; - } @{ $project->{submissions} }; - - if (@rendus) + eval { - eval - { - Process::Client::launch("send_git", - { - "year" => $promo, - "id" => $id_project, - "rendu" => $tag, - "login" => $repo_login, -# "path" => "ssh://git\@localhost/".$ENV{GL_REPO}, # Optional - }, - undef, # Don't give any file - 1 # Launch in background - ); - }; - if ($@) - { - my $err = $@; + Process::Client::launch("send_git", + { + "year" => $promo, + "id" => $id_project, + "rendu" => $tag, + "login" => $repo_login, +# "path" => "ssh://git\@localhost/".$ENV{GL_REPO}, # Optional + }, + undef, # Don't give any file + 1 # Launch in background + ); + }; + if ($@) + { + my $err = $@; log DEBUG, "ERROR: ".$err; - } + } - # Send data to API - my $last_commit = `git log "refs/tags/$tag" -1 --decorate --tags`; - eval { - API::Submission::add($promo, $id_project, $tag, $repo_login, $last_commit); - }; - if ($@) - { - my $err = $@; - log DEBUG, "ERROR: ".$err; - log DONE, "Tag '$tag' effectué avec succès !"; - } - else { - log DONE, "Tag '$tag' effectué avec succès ! Vérifiez-le sur l'intranet."; - } + # Send data to API + my $last_commit = `git log "refs/tags/$tag" -1 --decorate --tags`; + eval { + API::Submission::add($promo, $id_project, $tag, $repo_login, $last_commit); + }; + if ($@) + { + my $err = $@; + log DEBUG, "ERROR: ".$err; + log DONE, "Tag '$tag' effectué avec succès !"; + } + else { + log DONE, "Tag '$tag' effectué avec succès ! Vérifiez-le sur l'intranet."; } } } From ba19732a47799a243c9243a45a029debb9adbbd2 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 5 Dec 2013 05:00:09 +0100 Subject: [PATCH 325/364] post-update hook: ACU- --- hooks/post-update | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/hooks/post-update b/hooks/post-update index 9f13577..f08b54d 100755 --- a/hooks/post-update +++ b/hooks/post-update @@ -31,21 +31,28 @@ exit(0) if (!$promo || !$id_project || !$repo_login); for my $ref (@ARGV) { my $tag; - if ($ref =~ m<^refs/tags/ACU-(.+)$>) { + my $tag_for; + if ($ref =~ m<^refs/tags/(ACU-(.+))$>) + { $tag = $1; - } elsif ($ref =~ m<^refs/tags/(.+)$>) { + $tag_for = $2; + } + elsif ($ref =~ m<^refs/tags/(.+)$>) + { $tag = $1; - } else { + $tag_for = $1; + } + else { next; } - log DEBUG, "Tag $tag on repository $ENV{GL_REPO} from IP $ENV{'SSH_CLIENT'} updated."; + log DEBUG, "Tag $tag ($tag_for) on repository $ENV{GL_REPO} from IP $ENV{'SSH_CLIENT'} updated."; - my $project = get_project_info($tag); + my $project = get_project_info($tag_for); # Extract matching tag my @rendus = grep { - exists $_->{vcs} and $_->{vcs}{tag} eq $tag; + exists $_->{vcs} and $_->{vcs}{tag} eq $tag_for; } @{ $project->{submissions} }; if (@rendus) @@ -73,7 +80,7 @@ for my $ref (@ARGV) # Send data to API my $last_commit = `git log "refs/tags/$tag" -1 --decorate --tags`; eval { - API::Submission::add($promo, $id_project, $tag, $repo_login, $last_commit); + API::Submission::add($promo, $id_project, $tag_for, $repo_login, $last_commit); }; if ($@) { @@ -103,7 +110,7 @@ sub get_project_info exit(1); } - log TRACE, $project; + #log TRACE, $project; return $project; } From 95f945f963afde2f595edb16024fe62e758c1f37 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 5 Dec 2013 05:55:35 +0100 Subject: [PATCH 326/364] send_git: ACU- --- process/files/send_git.pl | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/process/files/send_git.pl b/process/files/send_git.pl index 8f29176..ae50509 100644 --- a/process/files/send_git.pl +++ b/process/files/send_git.pl @@ -21,6 +21,11 @@ sub process my $rendu = $args->{param}{rendu}; my $login = $args->{param}{login}; + my $rendu_for = $rendu; + if ($rendu =~ /^(ACU|YAKA)-(.*)$/) { + $rendu_for = $1; + } + my $path = $args->{param}{path} // "ssh://git\@localhost/$year/$project_id/$login.git"; my $tempdir = tempdir(); @@ -30,10 +35,10 @@ sub process croak "$path is not a valid repository." if ($?); my $tar; - open my $fh, "tar -czf - -C '$tempdir' . |" or die ($!); + open my $fh, "tar -czf - -C '$tempdir' . |" or die ("Error during tar: " . $!); $tar .= $_ while(<$fh>); close $fh; - die "Unable to untar: $!" if ($?); + die "Unable to tar: $!" if ($?); # Clean remove_tree($tempdir); @@ -43,7 +48,7 @@ sub process "type" => "std", "id" => $project_id, "year" => $year, - "rendu" => $rendu, + "rendu" => $rendu_for, "login" => $login, "file" => "rendu.tgz" }, From 973bc3f7b1e8b967e245662fc4bb71b55495a14b Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 5 Dec 2013 05:59:06 +0100 Subject: [PATCH 327/364] send_git: fix ACU- --- process/files/send_git.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/files/send_git.pl b/process/files/send_git.pl index ae50509..9fc2dd4 100644 --- a/process/files/send_git.pl +++ b/process/files/send_git.pl @@ -23,7 +23,7 @@ sub process my $rendu_for = $rendu; if ($rendu =~ /^(ACU|YAKA)-(.*)$/) { - $rendu_for = $1; + $rendu_for = $2; } my $path = $args->{param}{path} // "ssh://git\@localhost/$year/$project_id/$login.git"; From 0e0a93789eb8fff60240577d0b27aa6e063c6bb6 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 5 Dec 2013 06:01:52 +0100 Subject: [PATCH 328/364] Add new command for moulette: stats --- commands/moulette/stats.sh | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 commands/moulette/stats.sh diff --git a/commands/moulette/stats.sh b/commands/moulette/stats.sh new file mode 100644 index 0000000..ffaa24c --- /dev/null +++ b/commands/moulette/stats.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +if [ -z "$2" ] +then + echo "Usage: $0" + exit 1 +fi + +if ! which gearman > /dev/null 2> /dev/null +then + echo "gearman isn't installed on this machine. Please try another one." + exit 1 +fi + +cat < + + moulette + stats + +EOF From 81150b41fea3bc71e21d2eaa1d0a35266fcd27a9 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 5 Dec 2013 06:03:28 +0100 Subject: [PATCH 329/364] Fix stats --- commands/moulette/stats.sh | 6 ------ 1 file changed, 6 deletions(-) mode change 100644 => 100755 commands/moulette/stats.sh diff --git a/commands/moulette/stats.sh b/commands/moulette/stats.sh old mode 100644 new mode 100755 index ffaa24c..3cfaaf2 --- a/commands/moulette/stats.sh +++ b/commands/moulette/stats.sh @@ -1,11 +1,5 @@ #!/bin/sh -if [ -z "$2" ] -then - echo "Usage: $0" - exit 1 -fi - if ! which gearman > /dev/null 2> /dev/null then echo "gearman isn't installed on this machine. Please try another one." From 3c60afe6e90894115afc95c02d4d48ab291d9b8a Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 5 Dec 2013 06:05:24 +0100 Subject: [PATCH 330/364] Fix stats --- commands/moulette/stats.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/commands/moulette/stats.sh b/commands/moulette/stats.sh index 3cfaaf2..355e79e 100755 --- a/commands/moulette/stats.sh +++ b/commands/moulette/stats.sh @@ -9,7 +9,6 @@ fi cat < - moulette - stats + stats EOF From 4d003d66262db637d9f1189bbc85b30250d58b3c Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 5 Dec 2013 06:44:43 +0100 Subject: [PATCH 331/364] Add new moulette command: set_workers --- commands/moulette/set_workers.sh | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100755 commands/moulette/set_workers.sh diff --git a/commands/moulette/set_workers.sh b/commands/moulette/set_workers.sh new file mode 100755 index 0000000..e03cce3 --- /dev/null +++ b/commands/moulette/set_workers.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +if [ -z "$1" ] +then + echo "Usage: $0 " + exit 1 +fi + +if ! which gearman > /dev/null 2> /dev/null +then + echo "gearman isn't installed on this machine. Please try another one." + exit 1 +fi + +cat < + + set_workers + $1 + +EOF From 874c6bc482e4447a82e420b245c5e5a2ef85216e Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 5 Dec 2013 06:44:50 +0100 Subject: [PATCH 332/364] Fix moulette/launch: can pass more than one login --- commands/moulette/launch.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/moulette/launch.sh b/commands/moulette/launch.sh index 1b79ab6..0ebc4cd 100755 --- a/commands/moulette/launch.sh +++ b/commands/moulette/launch.sh @@ -27,7 +27,7 @@ shift 2 LOGINS= while [ $# -gt 0 ] do - LOGINS=" $1 + LOGINS="$LOGINS $1 " shift done From 4482f47eec1eb4eb9a05ae473519041c65cdf073 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 5 Dec 2013 06:48:42 +0100 Subject: [PATCH 333/364] Fix set_workers --- commands/moulette/set_workers.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/moulette/set_workers.sh b/commands/moulette/set_workers.sh index e03cce3..724d43a 100755 --- a/commands/moulette/set_workers.sh +++ b/commands/moulette/set_workers.sh @@ -16,6 +16,6 @@ cat < set_workers - $1 + $1 EOF From eb8c74d46555cd0b41c345b663c6506ca65d61c8 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 5 Dec 2013 07:19:20 +0100 Subject: [PATCH 334/364] Add action flush to stats --- commands/moulette/launch.sh | 2 ++ commands/moulette/set_workers.sh | 2 ++ commands/moulette/stats.sh | 17 ++++++++++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/commands/moulette/launch.sh b/commands/moulette/launch.sh index 0ebc4cd..f77e141 100755 --- a/commands/moulette/launch.sh +++ b/commands/moulette/launch.sh @@ -41,3 +41,5 @@ cat <$RENDU $LOGINS EOF + +echo diff --git a/commands/moulette/set_workers.sh b/commands/moulette/set_workers.sh index 724d43a..ec77cf9 100755 --- a/commands/moulette/set_workers.sh +++ b/commands/moulette/set_workers.sh @@ -19,3 +19,5 @@ cat <$1 EOF + +echo diff --git a/commands/moulette/stats.sh b/commands/moulette/stats.sh index 355e79e..0c1ac6e 100755 --- a/commands/moulette/stats.sh +++ b/commands/moulette/stats.sh @@ -6,9 +6,24 @@ then exit 1 fi +ACTION= +if [ -n "$1" ] +then + if [ "$1" = "flush" ] + then + ACTION=" flush +" + else + echo "Unknown action '$1'" + exit 1 + fi +fi + cat < stats - +$ACTION EOF + +echo From 737a12d44352f3ce79119f4e45796d38c8692059 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 6 Dec 2013 00:10:03 +0100 Subject: [PATCH 335/364] Excpetion --- hooks/submissions.pl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/hooks/submissions.pl b/hooks/submissions.pl index c455d7e..ec46cad 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -133,11 +133,12 @@ sub check_submission_date my $open = DateTime::Format::ISO8601->parse_datetime($rendu->{period}{begin}); my $close = DateTime::Format::ISO8601->parse_datetime($rendu->{period}{end}); -# if ($id_project eq "myhttpd" && grep { $_ eq $repo_login } @apping) -# { -# $open = DateTime::Format::ISO8601->parse_datetime("2013-11-08T20:00:00"); +# if ($id_project eq "atelier-cpp-j4" && grep { $_ eq $repo_login } @apping) + if ($id_project eq "atelier-cpp-j4" && "bes_e" eq $repo_login) + { + $open = DateTime::Format::ISO8601->parse_datetime("2013-12-06T00:00:00"); # $close = DateTime::Format::ISO8601->parse_datetime("2013-11-10T11:42:00"); -# } + } say "Date courante : ", $glts->strftime("%d/%m/%Y %H:%M:%S"); From 0e3fe1fd1cd1f3e0b08a19780be9b6a06d4ab7fc Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 6 Dec 2013 16:33:56 +0100 Subject: [PATCH 336/364] Exception, ticket #22149 --- hooks/submissions.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hooks/submissions.pl b/hooks/submissions.pl index ec46cad..2f75b12 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -134,10 +134,10 @@ sub check_submission_date my $close = DateTime::Format::ISO8601->parse_datetime($rendu->{period}{end}); # if ($id_project eq "atelier-cpp-j4" && grep { $_ eq $repo_login } @apping) - if ($id_project eq "atelier-cpp-j4" && "bes_e" eq $repo_login) + if ($id_project eq "raytracer" && "dubois_d" eq $repo_login) { - $open = DateTime::Format::ISO8601->parse_datetime("2013-12-06T00:00:00"); -# $close = DateTime::Format::ISO8601->parse_datetime("2013-11-10T11:42:00"); +# $open = DateTime::Format::ISO8601->parse_datetime("2013-12-06T00:00:00"); + $close = DateTime::Format::ISO8601->parse_datetime("2013-12-08T18:42:00"); } say "Date courante : ", $glts->strftime("%d/%m/%Y %H:%M:%S"); From cdb64f192f63e4d94f887d3fafdb01bce60c1fba Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 8 Dec 2013 08:28:49 +0100 Subject: [PATCH 337/364] Mark ACU- and YAKA- as reserved tag --- hooks/subjects.pl | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index 75ac74d..f6425e1 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -375,17 +375,22 @@ sub tag_project my $mod = 0; for my $vcs ($dom->documentElement()->getElementsByTagName("vcs")) { + if (! $vcs->hasAttribute("tag") || $vcs->getAttribute("tag") =~ /^(ACU|YAKA)-/) { + log ERROR, "Un tag de rendu ne peut pas commencer par ACU- ou YAKA-."; # C'est réservé pour les moulettes + } + if (! $vcs->hasAttribute("token")) { if ($project) { # Looking for an old token my @rendus = grep { - exists $_->{vcs} and $_->{vcs}{tag} eq $vcs->hasAttribute("tag"); + exists $_->{vcs} and $_->{vcs}{tag} eq $vcs->getAttribute("tag"); } @{ $project->{submissions} }; - if (@rendus == 1) { - log INFO, "Use existing token: ".$rendus[0]->{vcs}{token}; + if (@rendus == 1) + { + log DEBUG, "Use existing token: ".$rendus[0]->{vcs}{token}; $vcs->setAttribute("token", substr($rendus[0]->{vcs}{token}, 2, 23)); $mod = 1; next; From 531864ef8df0c173e3b4267f1776f0a05a31c88e Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 9 Dec 2013 18:48:52 +0100 Subject: [PATCH 338/364] Allow . in defense filename --- hooks/subjects.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index f6425e1..ba81913 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -120,7 +120,7 @@ sub tag_defense } my $defense_id; - if ($path =~ /^(?:defenses\/)?([a-zA-Z0-9\/]+)(?:.xml)?$/) { + if ($path =~ /^(?:defenses\/)?([a-zA-Z0-9.\/]+)(?:.xml)?$/) { $defense_id = $1; } else { log ERROR, "Déplacez votre soutenance dans le dossier defenses ou simplifiez le nom du fichier."; From 744c3db27c30a6c82343a1dd2cc9b4fcc952e60e Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Mon, 9 Dec 2013 22:53:42 +0100 Subject: [PATCH 339/364] Fix account creation --- utils/lpt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/lpt b/utils/lpt index 8ce5293..06eff09 100755 --- a/utils/lpt +++ b/utils/lpt @@ -271,7 +271,7 @@ sub cmd_account_create($@) if (! $ou) { - my $mesg = $ldap->add( "$oudn", + my $mesg = $ldap->add( "$oudn,dc=acu,dc=epita,dc=fr", attrs => [ objectclass => [ "top", "organizationalUnit" ], ou => "$group", @@ -284,7 +284,7 @@ sub cmd_account_create($@) } } - my $mesg = $ldap->add( "uid=$login,$oudn", + my $mesg = $ldap->add( "uid=$login,$oudn,dc=acu,dc=epita,dc=fr", attrs => [ objectclass => [ "top", "epitaAccount" ], uidNumber => shift, From 33222d78c5d6977567739aa5a4a6a07dd2cae358 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 12 Dec 2013 05:42:57 +0100 Subject: [PATCH 340/364] Fix defense_id generation --- hooks/subjects.pl | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/hooks/subjects.pl b/hooks/subjects.pl index ba81913..89119a0 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -97,7 +97,7 @@ sub tag_defense my $path; if ($_[3]) { - if ($_[3] =~ /^(?:defenses\/)?([a-zA-Z0-9_.\/-]+)(?:.xml)?$/) { + if ($_[3] =~ /^(?:defenses\/)?([a-zA-Z0-9_.\/-]+?)(?:.xml)?$/) { $path = "defenses/".$1.".xml"; } else { $path = $_[3]; @@ -119,12 +119,11 @@ sub tag_defense chomp($path); } - my $defense_id; - if ($path =~ /^(?:defenses\/)?([a-zA-Z0-9.\/]+)(?:.xml)?$/) { - $defense_id = $1; - } else { - log ERROR, "Déplacez votre soutenance dans le dossier defenses ou simplifiez le nom du fichier."; - } + log WARN, "Placez votre soutenance dans le dossier defenses/." if ($path !~ /^defenses/); + + my $defense_id = basename($path); + $defense_id =~ s/\.xml$//; + $defense_id =~ s/[^a-zA-Z0-9_.-]/_/g; my $year; if ($_[4]) From 700002396bae4abf85d41c9566c0e2d8e2c32627 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 12 Dec 2013 10:19:01 +0100 Subject: [PATCH 341/364] Add Apping2/3 to habitent_loin exception --- ACU/API/Projects.pm | 2 +- Makefile | 15 ++++++++++++++- hooks/gl-pre-git | 3 ++- hooks/subjects.pl | 4 +++- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/ACU/API/Projects.pm b/ACU/API/Projects.pm index eb39572..473fcc4 100644 --- a/ACU/API/Projects.pm +++ b/ACU/API/Projects.pm @@ -16,7 +16,7 @@ sub add($$;$) my $flavor = shift; my $year = shift; - if ($year and $year != LDAP::get_year) { + if ($year and $year ne LDAP::get_year) { croak "Impossible d'ajouter un projet d'une autre année : non implémenté"; } diff --git a/Makefile b/Makefile index 9aba33a..15244d4 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,13 @@ COPY?=cp -v +CURL?=curl DEST?=/usr/local/share/perl/`ls -1 /usr/local/share/perl/ | grep "^5." | tail -1`/ GIT?=/usr/bin/git GITOLITE_DEST?=/usr/share/gitolite/hooks/common MAKEDIR?=mkdir +PERL?=/usr/bin/env perl PROVER?=prove -f RM?=rm +RMTREE?=rm -r TESTDIR?=t SHELL?=/bin/sh @@ -29,7 +32,7 @@ guantanamo.tar.gz: $(COPY) process/exec/run.sh.not-here guantanamo/run.sh chmod +x guantanamo/run.sh tar czf guantanamo.tar.gz guantanamo/ - rm -rf guantanamo + $(RMTREE) guantanamo update: $(GIT) pull @@ -43,6 +46,16 @@ unstall: ! test -d $(GITOLITE_DEST) || $(RM) -rf $(GITOLITE_DEST)/update.secondary.d ! test -d $(GITOLITE_DEST) || $(MAKEDIR) -p $(GITOLITE_DEST)/update.secondary.d +regen-objects: + $(MAKEDIR) -p ACU/dtd + $(CURL) -o ACU/dtd/defense.dtd http://acu.epita.fr/dtd/defense.dtd + $(CURL) -o ACU/dtd/grading.dtd http://acu.epita.fr/dtd/grading.dtd + $(CURL) -o ACU/dtd/groups.dtd http://acu.epita.fr/dtd/groups.dtd + $(CURL) -o ACU/dtd/project.dtd http://acu.epita.fr/dtd/project.dtd + $(CURL) -o ACU/dtd/traces.dtd http://acu.epita.fr/dtd/traces.dtd + $(PERL) -I baldr baldr/Baldr.pl --import="ACU/Objects/basecode/*.pm" --path=ACU/Objects ACU/dtd/defense.dtd ACU/dtd/grading.dtd ACU/dtd/groups.dtd ACU/dtd/project.dtd ACU/dtd/traces.dtd + $(RMTREE) ACU/dtd + test: $(PROVER) $(TESTDIR) diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git index 00c3c8a..db3886d 100755 --- a/hooks/gl-pre-git +++ b/hooks/gl-pre-git @@ -20,6 +20,7 @@ my $promo = qx(git config hooks.promo); my $id_project = qx(git config hooks.idproject); my $repo_login = qx(git config hooks.repologin); +my @apping3 = qw(saadi_n lucas_e jawhar_s france_b roux_m bamba_m boudje_s gillot_l le-pen_m gimene_a nguye_d marin_c); my @habitent_loin = qw(amed_m bellev_m freima_m ikouna_l simon_j faure_n abdelm_a habri_z trang_d henrie_p verbec_y molini_v); # First, check if the repository is in the YYYY/ directory @@ -49,7 +50,7 @@ if ($ip->overlaps($labnetwork) == $IP_A_IN_B_OVERLAP) # exit 1; #} -exit 0 if (grep { /\Q$ENV{GL_USER}\E/ } @habitent_loin); +exit 0 if (grep { /\Q$ENV{GL_USER}\E/ } @habitent_loin, @apping3, "icaza_fact"); my $schoolnetwork = Net::IP->new('10.41.0.0/16'); my $vjschoolnetwork = Net::IP->new('10.3.0.0/16'); diff --git a/hooks/subjects.pl b/hooks/subjects.pl index 89119a0..220272a 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -306,6 +306,7 @@ sub tag_project # 2: $year my $project_id = repository_name(); + my $flavour = ""; if ($_[1]) { # Check on ID/flavour_id @@ -314,6 +315,7 @@ sub tag_project } $project_id .= "-" . $_[1]; + $flavour = $_[1]; } $project_id = lc $project_id; $project_id =~ s/[^a-z0-9-_]/_/g; @@ -423,7 +425,7 @@ sub tag_project log INFO, "Information de l'intranet..."; # Call API eval { - API::Projects::add($project_id, $year); + API::Projects::add($project_id, $flavour, $year); }; if ($@) { From 929d146770874b3a671e5f4a85853b85eb195201 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 15 Dec 2013 12:17:33 +0100 Subject: [PATCH 342/364] Ticket #22220: Two new habitent_loin --- hooks/gl-pre-git | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git index db3886d..07cde2f 100755 --- a/hooks/gl-pre-git +++ b/hooks/gl-pre-git @@ -21,7 +21,7 @@ my $id_project = qx(git config hooks.idproject); my $repo_login = qx(git config hooks.repologin); my @apping3 = qw(saadi_n lucas_e jawhar_s france_b roux_m bamba_m boudje_s gillot_l le-pen_m gimene_a nguye_d marin_c); -my @habitent_loin = qw(amed_m bellev_m freima_m ikouna_l simon_j faure_n abdelm_a habri_z trang_d henrie_p verbec_y molini_v); +my @habitent_loin = qw(amed_m bellev_m freima_m ikouna_l simon_j faure_n abdelm_a habri_z trang_d henrie_p verbec_y molini_v marti_o colin_j); # First, check if the repository is in the YYYY/ directory exit 0 if (($promo && $id_project && $repo_login) || $ENV{GL_REPO} !~ /^2[0-9]{3}\/.+\/.+/); From 65e2f61319b5137b127e1bc3648650eb220f9186 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 15 Dec 2013 18:31:46 +0100 Subject: [PATCH 343/364] Fix connection to gearman server --- process/exec/guantanamo.pl | 2 +- process/projects/gen_grading.pl | 2 +- process/projects/get_csv.pl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/process/exec/guantanamo.pl b/process/exec/guantanamo.pl index 706def8..b40da88 100644 --- a/process/exec/guantanamo.pl +++ b/process/exec/guantanamo.pl @@ -196,5 +196,5 @@ sub process_master log INFO, "Starting guantanamo.pl as master process"; -Process::add_server("gearman:4730"); +Process::add_server("gearmand:4730"); Process::register("guantanamo", \&process_master); diff --git a/process/projects/gen_grading.pl b/process/projects/gen_grading.pl index 9b91ff5..0236b68 100644 --- a/process/projects/gen_grading.pl +++ b/process/projects/gen_grading.pl @@ -97,5 +97,5 @@ sub process return $grade->toString; } -Process::add_server("gearman:4730"); +Process::set_servers("gearmand:4730"); Process::register_no_parse("gen_grading", \&process); diff --git a/process/projects/get_csv.pl b/process/projects/get_csv.pl index cc32ab3..eb1f0f2 100644 --- a/process/projects/get_csv.pl +++ b/process/projects/get_csv.pl @@ -105,5 +105,5 @@ sub process return $out; } -Process::set_servers("gearman:4730"); +Process::set_servers("gearmand:4730"); Process::register_no_parse("get_csv", \&process); From 3e5a587dd1c28c5a3597d0cb997634db7711d1dd Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 18 Dec 2013 19:13:06 +0100 Subject: [PATCH 344/364] Allow LSE to connect to project-lse repo --- hooks/gl-pre-git | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git index 07cde2f..cc47188 100755 --- a/hooks/gl-pre-git +++ b/hooks/gl-pre-git @@ -50,6 +50,8 @@ if ($ip->overlaps($labnetwork) == $IP_A_IN_B_OVERLAP) # exit 1; #} +exit 0 if ($id_project eq "lse-project" && $ip->ip() eq "10.224.4.1"); + exit 0 if (grep { /\Q$ENV{GL_USER}\E/ } @habitent_loin, @apping3, "icaza_fact"); my $schoolnetwork = Net::IP->new('10.41.0.0/16'); From 3a5dbc55a8dbe9df4a9697395199136b782d417b Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 18 Dec 2013 21:22:38 +0100 Subject: [PATCH 345/364] Add new APPING3 for TC --- hooks/gl-pre-git | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/gl-pre-git b/hooks/gl-pre-git index cc47188..ea1f206 100755 --- a/hooks/gl-pre-git +++ b/hooks/gl-pre-git @@ -20,7 +20,7 @@ my $promo = qx(git config hooks.promo); my $id_project = qx(git config hooks.idproject); my $repo_login = qx(git config hooks.repologin); -my @apping3 = qw(saadi_n lucas_e jawhar_s france_b roux_m bamba_m boudje_s gillot_l le-pen_m gimene_a nguye_d marin_c); +my @apping3 = qw(saadi_n lucas_e jawhar_s france_b roux_m bamba_m boudje_s gillot_l le-pen_m gimene_a nguye_d marin_c piedno_j salmon_b); my @habitent_loin = qw(amed_m bellev_m freima_m ikouna_l simon_j faure_n abdelm_a habri_z trang_d henrie_p verbec_y molini_v marti_o colin_j); # First, check if the repository is in the YYYY/ directory From 5b1382fc716f0e7d7a6ec24bfe8631b6388d8efc Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 19 Dec 2013 09:04:57 +0100 Subject: [PATCH 346/364] pizzin_a allowed to push erlear --- hooks/submissions.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hooks/submissions.pl b/hooks/submissions.pl index 2f75b12..e3a5dbf 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -134,10 +134,10 @@ sub check_submission_date my $close = DateTime::Format::ISO8601->parse_datetime($rendu->{period}{end}); # if ($id_project eq "atelier-cpp-j4" && grep { $_ eq $repo_login } @apping) - if ($id_project eq "raytracer" && "dubois_d" eq $repo_login) + if (($id_project eq "bistromathique" || $id_project eq "pthl") && "pizzin_a" eq $repo_login) { -# $open = DateTime::Format::ISO8601->parse_datetime("2013-12-06T00:00:00"); - $close = DateTime::Format::ISO8601->parse_datetime("2013-12-08T18:42:00"); + $open = DateTime::Format::ISO8601->parse_datetime("2013-12-19T18:00:00"); +# $close = DateTime::Format::ISO8601->parse_datetime("2013-12-08T18:42:00"); } say "Date courante : ", $glts->strftime("%d/%m/%Y %H:%M:%S"); From c6352b889704c9bf2a4c474ba73998f217763276 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 20 Dec 2013 17:35:22 +0100 Subject: [PATCH 347/364] Set a default ID on eval without id --- ACU/Trace.pm | 2 +- process/files/intradata_get.pl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ACU/Trace.pm b/ACU/Trace.pm index 9e08935..97f3edf 100644 --- a/ACU/Trace.pm +++ b/ACU/Trace.pm @@ -354,7 +354,7 @@ sub new ($$;$) { my $class = shift; my $self = { - id => shift, + id => shift // "", type => shift // "test", values => {}, logs => {}, diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index 649674d..7869a11 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -105,7 +105,7 @@ sub grades_generate log DEBUG, "Generating grades for $login"; for my $dir (@trace_dirs) { - log DEBUG, "Fetching identifiers from $dir"; + log DEBUG, "Will fetch identifiers from $dir"; # Looking for a group traces first for my $grp (@{ $groups->{groups} }) From ea711bc7bc990f87be8f7e5b94c7e2a0ddf556bd Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 22 Dec 2013 11:44:22 +0100 Subject: [PATCH 348/364] Ticket #22238 --- hooks/submissions.pl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/hooks/submissions.pl b/hooks/submissions.pl index e3a5dbf..9bd0b40 100755 --- a/hooks/submissions.pl +++ b/hooks/submissions.pl @@ -24,6 +24,7 @@ my $id_project; my $repo_login; my @apping = qw(zinger_a zebard_w zanell_a yao_p vinois_a sraka_y soupam_j seck_a ngomsi_s morin_h milis_e menkar_m eusebe_r crief_a chhum_s boumra_n blemus_a bengan_l amasho_a); +my @expcep = qw(azerno_t baudry_v dechen_g drouin_n dupuis_a fenech_a hamdao_y lanclu_j langre_m manuel_c palson_c trang_d wajntr_a); my @salonD = qw(aniss_i bogalh_j boulea_b cloare_l elhach_h gabrie_j kaplan_p manuel_c palson_c pizzin_a wajntr_a); my @salonS = qw(allio_a cadet_l digius_p drouin_n dubois_d dupuis_a langre_m lim_j); @@ -133,11 +134,11 @@ sub check_submission_date my $open = DateTime::Format::ISO8601->parse_datetime($rendu->{period}{begin}); my $close = DateTime::Format::ISO8601->parse_datetime($rendu->{period}{end}); -# if ($id_project eq "atelier-cpp-j4" && grep { $_ eq $repo_login } @apping) - if (($id_project eq "bistromathique" || $id_project eq "pthl") && "pizzin_a" eq $repo_login) + if (($id_project eq "bistromathique" || $id_project eq "pthl") && grep { $_ eq $repo_login } @expcep) +# if (($id_project eq "bistromathique" || $id_project eq "pthl") && "pizzin_a" eq $repo_login) { - $open = DateTime::Format::ISO8601->parse_datetime("2013-12-19T18:00:00"); -# $close = DateTime::Format::ISO8601->parse_datetime("2013-12-08T18:42:00"); +# $open = DateTime::Format::ISO8601->parse_datetime("2013-12-19T18:00:00"); + $close = DateTime::Format::ISO8601->parse_datetime("2013-12-22T19:42:00"); } say "Date courante : ", $glts->strftime("%d/%m/%Y %H:%M:%S"); From f5ff3c83b3890c746f2fdd2c026cfa8659bb9e43 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 9 Jan 2014 18:00:29 +0100 Subject: [PATCH 349/364] Grades from defenses are now the same for the group --- ACU/Trace.pm | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/ACU/Trace.pm b/ACU/Trace.pm index 97f3edf..865449b 100644 --- a/ACU/Trace.pm +++ b/ACU/Trace.pm @@ -133,14 +133,23 @@ sub getIds { my $self = shift; my $login = shift; + my $onlyNonZero = shift // 0; my %ids; foreach my $group (@{ $self->{groups} }) { - my %tmp = $group->getIds($login); + my %tmp; + if ($self->{type} eq "defense") + { + # For a defense, we consider that this is a group grade, so don't consider login filtering + %tmp = $group->getIds(); + } else { + %tmp = $group->getIds($login); + } + while (my ($key, $value) = each %tmp) { - $ids{$key} = $value; + $ids{$key} = $value if !$onlyNonZero || $value; } } return \%ids; @@ -148,19 +157,7 @@ sub getIds sub getNonZeroIds { - my $self = shift; - my $login = shift; - - my %ids; - foreach my $group (@{ $self->{groups} }) - { - my %tmp = $group->getIds($login); - while (my ($key, $value) = each %tmp) - { - $ids{$key} = $value if $value; - } - } - return \%ids; + return getIds($_[0], $_[1], 1); } sub getValue From 8170216edc7402973635a205667e0d1ce753f153 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 9 Jan 2014 21:44:47 +0100 Subject: [PATCH 350/364] Add debug --- ACU/Grading.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/ACU/Grading.pm b/ACU/Grading.pm index f473289..d27d480 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -355,6 +355,7 @@ sub compute ($$$;$$$) $value += $ids->{ $r }; } $ids->{ $ref } = $value if ($value); + log DEBUG, "New globbing identifier caculated $ref: $value"; } }; if ($@) { From 5e174fc053efd110278773a43399d40048ee0f16 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 12 Jan 2014 05:00:24 +0100 Subject: [PATCH 351/364] New moulette command: can set max_memory variable --- commands/moulette/set_max_memory.sh | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 commands/moulette/set_max_memory.sh diff --git a/commands/moulette/set_max_memory.sh b/commands/moulette/set_max_memory.sh new file mode 100644 index 0000000..48ccf1c --- /dev/null +++ b/commands/moulette/set_max_memory.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +if [ -z "$1" ] +then + echo "Usage: $0 " + exit 1 +fi + +if ! which gearman > /dev/null 2> /dev/null +then + echo "gearman isn't installed on this machine. Please try another one." + exit 1 +fi + +cat < + + set_memory + $1 + +EOF + +echo From 1a250697269cbdc621d97f3fad50e38c55535a9d Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 12 Jan 2014 05:00:57 +0100 Subject: [PATCH 352/364] New moulette command: can send a tarball (e.g.: for exam) --- commands/moulette/send_tarball.sh | 83 +++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100755 commands/moulette/send_tarball.sh diff --git a/commands/moulette/send_tarball.sh b/commands/moulette/send_tarball.sh new file mode 100755 index 0000000..77f0ec7 --- /dev/null +++ b/commands/moulette/send_tarball.sh @@ -0,0 +1,83 @@ +#!/bin/bash + +usage() +{ + echo "Usage: $0 [-d] [year] " +} + +if [ -z "$4" ] +then + usage + exit 1 +fi + +if ! which gearman > /dev/null 2> /dev/null +then + echo "gearman isn't installed on this machine. Please try another one." + exit 1 +fi + +if [ "x$1" = "x-d" ] +then + BACKGROUD= + shift +else + BACKGROUD="-b" +fi + +if [ "x${1:0:2}" = "x20" ] +then + YEAR=" $1" + shift +else + YEAR= +fi +PROJECT_ID=$1 +RENDU=$2 +LOGIN=$3 + +if ! [ -f "$4" ] +then + usage + exit 2 +fi + +MIME=`file -b -i "$4" | cut -d ';' -f 1` + +if [ "$MIME" = "application/x-bzip2" ] +then + FILE=`bzip2 --decompress --stdout "$4" | gzip --stdout | base64` + +elif [ "$MIME" = "application/x-gzip" ] +then + FILE=`gzip --decompress --stdout "$4" | gzip --stdout | base64` + +elif [ "$MIME" = "application/x-xz" ] +then + FILE=`xz --decompress --stdout "$4" | gzip --stdout | base64` + +elif [ "$MIME" = "application/x-tar" ] +then + FILE=`tar cz "$4" | base64` + +elif [ "$MIME" = "inode/directory" ] +then + FILE=`tar xf "$4" | tar cz | base64` + +else + echo "I don't know how to treat $4" >&2 + exit 3 +fi + +cat < + + std +$YEAR + $PROJECT_ID + $RENDU + $LOGIN + rendu.tgz + $FILE + +EOF From 6dca90348ab7aa29757af1ada249157b7db3d2d9 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 12 Jan 2014 05:01:29 +0100 Subject: [PATCH 353/364] New git_str format: allow moulettes to push tags begining by ACU- --- commands/project/gen_git_str.pl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/commands/project/gen_git_str.pl b/commands/project/gen_git_str.pl index f3f07fe..e825048 100644 --- a/commands/project/gen_git_str.pl +++ b/commands/project/gen_git_str.pl @@ -31,8 +31,10 @@ map { } say "repo $year/$projid/$chief->{login}"; - say " - ACU-moulette = ", join(" ", @members); - say ' RW+ = @admins ', join(" ", @members); - say ' RW ACU-moulette = @moulettes'; - say " R = \@chefs \@resp-$year-$projid \@soutenance-$year-$projid \@moulettes intradmin-hamano"; + say " - ACU-moulette = ", join(" ", @members); + say " - refs/tags/ACU- = ", join(" ", @members); + say ' RW+ = @admins ', join(" ", @members); + say ' RW ACU-moulette = @moulettes'; + say ' RW+ refs/tags/ACU- = @moulettes'; + say " R = \@chefs \@resp-$year-$projid \@soutenance-$year-$projid \@moulettes intradmin-hamano"; } @{ $res->{groups} }; From cb9bf00da4221cbcd3b055eb6e5f459d2738a03c Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 12 Jan 2014 05:02:00 +0100 Subject: [PATCH 354/364] check_ssh_key: now check file content before type validity --- process/ldap/check_ssh_key.pl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/process/ldap/check_ssh_key.pl b/process/ldap/check_ssh_key.pl index 99584a1..4295e53 100644 --- a/process/ldap/check_ssh_key.pl +++ b/process/ldap/check_ssh_key.pl @@ -17,8 +17,16 @@ use ACU::Log; sub check_key($) { my $filename = shift; + + # Check file content format + open my $fh, "<", $filename; + my $fcnt = <$fh>; + close $fh; + chomp($fcnt); + # Call ssh-keygen - if (`ssh-keygen -l -f $filename 2> /dev/null` =~ /^([0-9]+) +[0-9a-f:]+ +.+ +\(([A-Z]+)\)$/) + if ($fcnt =~ /^(ssh|ecdsa)-[a-z0-9-]+ [a-zA-Z0-9+=\/]+( .*)?$/ && + `ssh-keygen -l -f $filename 2> /dev/null` =~ /^([0-9]+) +[0-9a-f:]+ +.+ +\(([A-Z]+)\)$/) { log INFO, "Receive valid key: type $2, size $1"; if ($2 eq "RSA") { From e9ea5fc3a5929058ec1efa4f127c80f9b45c01b1 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 12 Jan 2014 05:54:35 +0100 Subject: [PATCH 355/364] Solve #22243 --- ACU/Defense.pm | 8 ++++---- hooks/subjects.pl | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ACU/Defense.pm b/ACU/Defense.pm index d286567..b481a19 100644 --- a/ACU/Defense.pm +++ b/ACU/Defense.pm @@ -134,10 +134,10 @@ sub genIds ($;$) for my $group (@{ $self->{groups} }) { my $cur_gid; - if (! $group->{id} || grep { /^\Q$group->{id}\E$/ } @ids) + if (! $group->{id} || grep { $_ == $group->{id} } @ids) { do { - $cur_gid = "def".$def_i."g".$grp_i; + $cur_gid = "def_".$def_i."g".$grp_i; $grp_i += 1; } while (grep {$_ eq $cur_gid} @ids); $group->{id} = $cur_gid; @@ -151,7 +151,7 @@ sub genIds ($;$) for my $question (@{ $group->{questions_list} }) { my $cur_qid; - if (! $question->{id} || grep { /^\Q$question->{id}\E$/ } @ids) + if (! $question->{id} || grep { $_ == $question->{id} } @ids) { do { $cur_qid = $cur_gid."q".$qst_i; @@ -167,7 +167,7 @@ sub genIds ($;$) my $ans_i = 0; for my $answer (@{ $question->{answers} }) { - if (! $answer->{id} || grep { /^\Q$answer->{id}\E$/ } @ids) + if (! $answer->{id} || grep { $_ == $answer->{id} } @ids) { my $cur_aid; do { diff --git a/hooks/subjects.pl b/hooks/subjects.pl index 220272a..03ba63b 100755 --- a/hooks/subjects.pl +++ b/hooks/subjects.pl @@ -168,7 +168,7 @@ sub tag_defense # Generate questions and answer id my $defense = Defense->new(\$content); - $defense->genIds(); + $defense->genIds($defense_id); # Send data to intradata log INFO, "Attente d'un processus de publication..."; From 6e70dc24ff5b4710ef12e1007b087fe7363a5544 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Sun, 12 Jan 2014 06:27:12 +0100 Subject: [PATCH 356/364] lpt: new command account add to import account information from passwd like file. Closes #22244 --- utils/lpt | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/utils/lpt b/utils/lpt index 06eff09..1042983 100755 --- a/utils/lpt +++ b/utils/lpt @@ -73,6 +73,7 @@ my %cmds = my %cmds_account = ( + "add" => \&cmd_account_add, "alias" => \&cmd_account_alias, "close" => \&cmd_account_close, "cn" => \&cmd_account_cn, @@ -250,6 +251,45 @@ sub cmd_account_cn($@) return cmd_account_vieworchange('cn', 'name', @_); } +sub cmd_account_add($@) +{ + my $login = shift; + my $passwd_path = shift // "./passwd"; + + if (! -f $passwd_path) + { + log(USAGE, "lpt account add [./passwd] [nopass|passgen|password]"); + return 1; + } + + open my $fh, "<", $passwd_path; + my @passwd_cnt = <$fh>; + close($fh); + + for my $line (grep { /^$login:x/ } @passwd_cnt) + { + if ($line =~ /^$login:x:([0-9]+):([0-9]+):([^ :]+) ?([^:]*):/) + { + my $uid = $1; + my $gid = $2; + my $firstname = ucfirst $3; + my $lastname = ucfirst $4; + + if (! $noconfirm) + { + say "Add user: ", YELLOW, BOLD, "$login", RESET, ":\n\tFirstname: ", BOLD, $firstname, RESET, "\n\tLastname: ", BOLD, $lastname, RESET, "\n\tUID:\t", BOLD, $uid, RESET, "\n\tGroup:\t", BOLD, $gid, RESET; + + print "Would you like to add this user? [", GREEN, "y", RESET, "/", RED, "N", RESET, "] "; + my $go = ; + chomp $go; + next if ($go ne "y" and $go ne "yes"); + } + + cmd_account_create($login, $gid, $uid, $firstname, $lastname, @_); + } + } +} + sub cmd_account_create($@) { my $login = shift; @@ -299,7 +339,7 @@ sub cmd_account_create($@) if ($mesg->code == 0) { log(INFO, "Account added: $login"); - my $pass = shift; + my $pass = shift // "nopass"; return cmd_account($login, $pass, @_) if ($pass ne "nopass"); return 0; } @@ -1950,6 +1990,12 @@ B [I [I [I [...]]]] If are given, display only those attributes. +B I [./passwd] [nopass|password|passgen] + + This is used to create a new Epita account, base for intra and/or lab account. + + This will use the passwd file given in argument to import information about the login. + B I [nopass|password|passgen] This is used to create a new Epita account, base for intra and/or lab account. From aa3b69f5b3b5eb27515d1d4636167d567c886ab3 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Tue, 14 Jan 2014 00:58:44 +0100 Subject: [PATCH 357/364] Grades: fix globing exponentiation --- ACU/Grading.pm | 2 +- commands/project/create.pl | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/ACU/Grading.pm b/ACU/Grading.pm index d27d480..479258f 100644 --- a/ACU/Grading.pm +++ b/ACU/Grading.pm @@ -352,7 +352,7 @@ sub compute ($$$;$$$) { my $value = 0; for my $r (grep { match_glob($ref, $_); } keys %$ids) { - $value += $ids->{ $r }; + $value += $ids->{ $r } if ($ref != $r); } $ids->{ $ref } = $value if ($value); log DEBUG, "New globbing identifier caculated $ref: $value"; diff --git a/commands/project/create.pl b/commands/project/create.pl index 8407a7e..6dd50c9 100644 --- a/commands/project/create.pl +++ b/commands/project/create.pl @@ -4,15 +4,13 @@ use v5.10.1; use strict; use warnings; -use lib "../../"; - use ACU::API::Base; use ACU::API::Projects; if ($#ARGV == 0) { - API::Projects::add($ARGV[0]); + API::Projects::add($ARGV[0], ""); } else { From b38f15b0b632cfb5eabb0e063b4c08dd507d0b90 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 15 Jan 2014 00:40:41 +0100 Subject: [PATCH 358/364] Allow negative bonus --- process/files/intradata_get.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index 7869a11..d4243dc 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -203,7 +203,7 @@ sub grades_new_bonus for my $line (@lines) { - if ($line =~ /^([a-z0-9_-]+)(?:\s*:\s*([0-9.]+))?$/) + if ($line =~ /^([a-z0-9_-]+)(?:\s*:\s*(-?[0-9.]+))?$/) { my $login = $1; my $tvalue = $2 // $value; From 4877749a765d1189d513db088be3a2598aa8e6df Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Wed, 15 Jan 2014 19:43:22 +0100 Subject: [PATCH 359/364] Implement delId method for traces --- ACU/Trace.pm | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/ACU/Trace.pm b/ACU/Trace.pm index 865449b..402d79c 100644 --- a/ACU/Trace.pm +++ b/ACU/Trace.pm @@ -120,7 +120,7 @@ sub delId { if (!$value || $value == $group->getValue()) { - #$self->{groups} = \{ grep { ! } @{ $self->{groups} } }; + $self->{groups} = \{ grep { $_->{id} ne $key } @{ $self->{groups} } }; } last; } @@ -255,8 +255,18 @@ sub delId my $key = shift; my $value = shift; - foreach my $item (@{ $self->{groups} }) + foreach my $group (@{ $self->{groups} }) { + if ($group->{id} eq $key) + { + if (!$value || $value == $group->getValue()) + { + $self->{groups} = \{ grep { $_->{id} ne $key } @{ $self->{groups} } }; + } + last; + } + + $group->delId($key, $value); } } @@ -404,6 +414,11 @@ sub parseEval } } +sub delId +{ + # Do nothing here, just an abstract method +} + sub getIds { my $self = shift; From 24df9247e746c41eeb4df9cc230fb3e32e26330c Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 16 Jan 2014 23:25:03 +0100 Subject: [PATCH 360/364] Bonus/malus are now individual by default --- ACU/Trace.pm | 18 +++++++++++++++++- process/files/intradata_get.pl | 3 ++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/ACU/Trace.pm b/ACU/Trace.pm index 402d79c..43507b6 100644 --- a/ACU/Trace.pm +++ b/ACU/Trace.pm @@ -10,6 +10,8 @@ use utf8; use open qw(:encoding(UTF-8) :std); use XML::LibXML; +use ACU::Log; + sub new { my $class = shift; @@ -106,6 +108,8 @@ sub addId my $e = Trace::Eval->new($key); $e->addValue(undef, $value); push @{ $self->{groups} }, $e; + + return $e; } sub delId @@ -120,7 +124,7 @@ sub delId { if (!$value || $value == $group->getValue()) { - $self->{groups} = \{ grep { $_->{id} ne $key } @{ $self->{groups} } }; + $self->{groups} = [ grep { $_->{id} ne $key } @{ $self->{groups} } ]; } last; } @@ -228,6 +232,8 @@ use strict; use warnings; use Carp; +use ACU::Log; + sub new ($$) { my $class = shift; @@ -419,6 +425,16 @@ sub delId # Do nothing here, just an abstract method } +sub changeWho +{ + my $self = shift; + + $self->{who} = { + login => shift, + type => shift // "login" + }; +} + sub getIds { my $self = shift; diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index d4243dc..e68f333 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -235,7 +235,8 @@ sub grades_new_bonus $trace->delId($kbonus); } } else { - $trace->addId($kbonus, $tvalue); + my $e = $trace->addId($kbonus, $tvalue); + $e->changeWho($login, "login"); } log DEBUG, "Updating $basedir/$year/$project_id/traces/bonus/$login.xml"; From 767a4f9be249b08b850ecd93431a9ff97c438eaf Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Thu, 16 Jan 2014 23:32:52 +0100 Subject: [PATCH 361/364] Trace printer handles tags --- ACU/Trace.pm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ACU/Trace.pm b/ACU/Trace.pm index 43507b6..e8e8a43 100644 --- a/ACU/Trace.pm +++ b/ACU/Trace.pm @@ -498,6 +498,14 @@ sub toString($$) $e->setAttribute("id", $self->{id}); $e->setAttribute("type", $self->{type}); + if (defined $self->{who}) + { + my $w = $doc->createElement("who"); + $w->setAttribute("login", $self->{who}{login}); + $w->setAttribute("type", $self->{who}{type}) if (defined $self->{who}{type}); + $e->appendChild( $w ); + } + for my $k (keys %{ $self->{values} }) { my $v = $doc->createElement("value"); From 8ddca7c49aef970dc39e7c15bda6a5c14ad90657 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 17 Jan 2014 00:05:44 +0100 Subject: [PATCH 362/364] Fix format of who tags --- ACU/Trace.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ACU/Trace.pm b/ACU/Trace.pm index e8e8a43..8abed90 100644 --- a/ACU/Trace.pm +++ b/ACU/Trace.pm @@ -501,8 +501,8 @@ sub toString($$) if (defined $self->{who}) { my $w = $doc->createElement("who"); - $w->setAttribute("login", $self->{who}{login}); $w->setAttribute("type", $self->{who}{type}) if (defined $self->{who}{type}); + $w->appendTextNode( $self->{who}{login} ); $e->appendChild( $w ); } From 2e5b2af4d830d36c278983f3e80721e6d7c93c5e Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 17 Jan 2014 01:52:20 +0100 Subject: [PATCH 363/364] Multi-thread grades generation --- process/files/intradata_get.pl | 36 +++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index e68f333..6ca8ca3 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -2,6 +2,7 @@ use v5.10.1; use strict; +use threads; use warnings; use Carp; use Pod::Usage; @@ -98,7 +99,38 @@ sub grades_generate my @trace_dirs = grep { ( ! /^\./ ) && -d "$basedir/$year/$project_id/traces/$_" } readdir($dh); closedir $dh; - for my $login (@logins) + my @ths; + my $max_ths = 4; + my $login_by_threads = @logins / $max_ths; + + for (my $i = 0; $i < $max_ths; $i++) + { + my @partlogin = @logins[($i*$login_by_threads) .. (($i+1)*$login_by_threads - 1)]; + push @ths, threads->create(\&do_grade_generation, $grading, $year, $project_id, $groups, \@trace_dirs, @partlogin); + } + + if ($login_by_threads * $max_ths < @logins) + { + my @partlogin = @logins[$login_by_threads * $max_ths .. $#logins]; + push @ths, threads->create(\&do_grade_generation, $grading, $year, $project_id, $groups, \@trace_dirs, @partlogin); + } + + for my $th (@ths) { + $th->join(); + } + + return 1; +} + +sub do_grade_generation +{ + my $grading = shift; + my $year = shift; + my $project_id = shift; + my $groups = shift; + my @trace_dirs = @{ shift() }; + + for my $login (@_) { my @files; @@ -157,8 +189,6 @@ sub grades_generate $grading->reset(); } - - return 1; } sub grades_new_bonus From b8d4ff1a588133cec26a2522f0c54cf6d703a77c Mon Sep 17 00:00:00 2001 From: Charlie Noyce Root Date: Fri, 17 Jan 2014 02:17:41 +0100 Subject: [PATCH 364/364] Revert "Multi-thread grades generation" This reverts commit 2e5b2af4d830d36c278983f3e80721e6d7c93c5e. --- process/files/intradata_get.pl | 36 +++------------------------------- 1 file changed, 3 insertions(+), 33 deletions(-) diff --git a/process/files/intradata_get.pl b/process/files/intradata_get.pl index 6ca8ca3..e68f333 100644 --- a/process/files/intradata_get.pl +++ b/process/files/intradata_get.pl @@ -2,7 +2,6 @@ use v5.10.1; use strict; -use threads; use warnings; use Carp; use Pod::Usage; @@ -99,38 +98,7 @@ sub grades_generate my @trace_dirs = grep { ( ! /^\./ ) && -d "$basedir/$year/$project_id/traces/$_" } readdir($dh); closedir $dh; - my @ths; - my $max_ths = 4; - my $login_by_threads = @logins / $max_ths; - - for (my $i = 0; $i < $max_ths; $i++) - { - my @partlogin = @logins[($i*$login_by_threads) .. (($i+1)*$login_by_threads - 1)]; - push @ths, threads->create(\&do_grade_generation, $grading, $year, $project_id, $groups, \@trace_dirs, @partlogin); - } - - if ($login_by_threads * $max_ths < @logins) - { - my @partlogin = @logins[$login_by_threads * $max_ths .. $#logins]; - push @ths, threads->create(\&do_grade_generation, $grading, $year, $project_id, $groups, \@trace_dirs, @partlogin); - } - - for my $th (@ths) { - $th->join(); - } - - return 1; -} - -sub do_grade_generation -{ - my $grading = shift; - my $year = shift; - my $project_id = shift; - my $groups = shift; - my @trace_dirs = @{ shift() }; - - for my $login (@_) + for my $login (@logins) { my @files; @@ -189,6 +157,8 @@ sub do_grade_generation $grading->reset(); } + + return 1; } sub grades_new_bonus