Commit fb5626f4 authored by Laurent Lécluse's avatar Laurent Lécluse
Browse files

Pull from Master

parent 3c348dc8
config/*.local.php
config.local.php
config/autoload/*.local.php
vendor/*
data/cache/*
.idea
deploy.log
\ No newline at end of file
deploy.log
VERSION
\ No newline at end of file
---
title: "Changement intervenus sur OSE"
author: Laurent Lécluse - DSI - Unicaen
...
#OSE 6.3
## Corrections de bugs
* Suppression de la vue `V_TYPE_INTERVENTION_REGLE_EP` qui ne compilait pas.
* Ajout de la dépendance à BCMath (extension PHP à installer).
* Correction de bug portant sur la validation du numéro INSEE dans les données personnelles.
* Correction de bug portant sur la recherche d'intervenants (se produisant uniquement avec PHP 7.1).
* Connecteurs : les disciplines remontent aussi pour les intervenants ayant une fin d'affectation en cours d'année.
* Correction de bug empêchant l'affichage de l'interface d'administration des années.
* Correction de bug à l'installation : toutes les tables étaent considérées par défaut comme
synchronisées, ce qui n'était pas le cas.
## Nouveautés
* Personnalisation : vous pouvez maintenant adapter entièrement l'interface de OSE
à votre établissement (finies les références explicites à l'Université de Caen dans l'interface)
L'apparence de l'application peut également être personnalisée en fournissant une URL qui
pointe vers une feuille de style CSS propre à votre établissement.
* Nouvelle procédure d'installation (https://ose.unicaen.fr/deploiement)
Le déploiement de OSE se fait désormais directement à partir de sa plateforme GitLab.
* Nouvelle procédure de mise à jour à partir de GitLab.
* Suppression des anciens Jobs Oracle et remplacement par des tâches CRON
## Procédure de mise à jour
* Sauvegardez votre fichier de configuration local (`config/application.local.php`)
dans un autre répertoire que celui de OSE.
* Du fait de la mise en place d'une nouvelle procédure de mise à jour, l'application doit être
réinstallée (uniquement les fichiers, pas la base de données).
Supprimez complètement le répertoire OSE.
* Procédez à une nouvelle installation (procédure ici : https://ose.unicaen.fr/deploiement/install).
Si vous déployez au même endroit qu'avant, la configuration d'Apache ne devra pas être modifiée.
La base de données n'a pas non plus besoin d'être réinstallée.
* Réintégrez votre fichier de configuration locale.
Attention : **ce dernier a changé d'emplacement**. De `config/application.local.php` il est devenu `config.local.php`.
Le fichier n'est donc plus placé dans le répertoire `config`, mais à la **racine** du répertoire OSE!!
* Le fichier de configuration locale (`config.local.php`) doit être modifié.
La rubrique `'liens'` (Liens divers) n'a plus d'utilité et doit être supprimée.
A sa place, copiez-collez dans votre fichier la rubrique `'etablissement'` en provenance
du fichier `config/application.local.dist`, puis personnalisez-là.
* Modifiez la structure de votre base de données en exécutant dans SQL developer le script de mise à jour suivant :
`data/Mises à jour/06.3.sql`
* Créez les tâches CRON suivantes si elles n'existent pas déjà :
* notifier-indicateurs
* synchronisation
* chargens-calcul-effectifs
* calcul-tableaux-bord
* formule-calcul
Pour cela, se référer à la procédure d'installation de OSE.
\ No newline at end of file
#!/usr/bin/env php
<?php
$c = new Console();
$oa = new OseAdmin($c);
$c->printMainTitle("OSE", 15);
$action = $c->getArg(1);
switch ($action) {
case 'update':
update($c, $oa);
break;
case 'notifier-indicateurs':
$oa->exec('notifier indicateurs');
break;
case 'migration':
$oldVersion = $c->getArg(2);
$version = $c->getArg(3);
/* Action à effectuer */
break;
case 'synchronisation':
$job = $c->getArg(2);
$oa->exec('UnicaenImport SyncJob '.$job);
break;
case 'chargens-calcul-effectifs':
$oa->exec('chargens-calcul-effectifs');
break;
case 'calcul-tableaux-bord':
$oa->exec('calcul-tableaux-bord');
break;
case 'formule-calcul':
$oa->exec('formule-calcul');
break;
default:
help($c, $oa);
break;
}
function update(Console $c, OseAdmin $oa)
{
$osedir = dirname(__DIR__);
// Choix de la version
$c->println("Mise à jour de OSE");
$c->println("Assurez-vous bien d'avoir mis OSE en mode maintenance avant de démarrer\n(pressez Entrée pour continuer)...");
$c->getInput();
$c->exec([
"cd $osedir",
"git fetch --all --tags --prune",
], false);
$oldVersion = $oa->currentVersion($osedir);
$c->println("Sélection de la version à déployer", $c::COLOR_LIGHT_CYAN);
$c->println("La version actuellement installée est la ".$oldVersion);
$c->println("Voici la liste des versions de OSE disponibles:");
$tags = $oa->getTags();
foreach ($tags as $tag) {
$c->println($tag);
}
$ok = false;
while (!$ok) {
$c->print("Veuillez choisir une version à déployer: ");
$version = $c->getInput();
if ($oa->tagIsValid($version)) {
$ok = true;
} else {
$c->println("$version n'est pas dans la liste des versions disponibles.");
}
}
// Récupération des sources
$c->println("\nMise à jour des fichiers à partir de GIT", $c::COLOR_LIGHT_CYAN);
$c->passthru([
"cd $osedir",
"git checkout tags/$version",
]);
$oa->writeVersion($osedir, $version);
// Récupération des dépendances
$c->println("\nMise à jour des dépendances à l'aide de Composer", $c::COLOR_LIGHT_CYAN);
$c->passthru([
"cd $osedir",
"php composer.phar self-update",
"php composer.phar install",
]);
// Néttoyage des caches et mise à jour des proxies, lancement du script de migration éventuel
$c->exec([
"cd $osedir",
"rm -Rf data/cache/*",
"php vendor/bin/doctrine-module orm:generate-proxies",
"chmod -R 777 data/cache/DoctrineProxy",
"php bin/ose migration $oldVersion $version"
]);
// Conclusion
$c->println("\nFin de la mise à jour des fichiers", $c::COLOR_LIGHT_GREEN);
$c->println("Il reste encore votre base de données à mettre à jour.");
$c->println("N'oubliez pas de sortir du mode maintenance!");
$c->println('');
}
function help(Console $c, OseAdmin $oa)
{
$c->println('Actions possibles :');
$c->println(" - update : Mise à jour de l'application");
$c->println(" - notifier-indicateurs : Envoi des mails relatifs aux indicateurs");
$c->println(" - synchronisation <job> : Effectue la synchronisation des données pour le <job> transmis");
$c->println(" - chargens-calcul-effectifs : Calcul des effectifs du module Charges");
$c->println(" - calcul-tableaux-bord : Recalcule tous les tableaux de bord de calculs itermédiaires");
$c->println(" - formule-calcul : Calcul de toutes les heures complémentaires à l'aide de la formule");
}
/************************************************************
* Classes utiles *
************************************************************/
class OseAdmin
{
const OSE_ORIGIN = 'git@git.unicaen.fr:dsi/OSE.git';
/**
* @var Console
*/
protected $console;
/**
* @var array
*/
private $tags = false;
/**
* OseAdmin constructor.
*
* @param Console $console
*/
public function __construct(Console $console)
{
$this->console = $console;
}
public function gitlabIsReachable(): bool
{
$gitCheck = $this->console->exec("git ls-remote --heads " . self::OSE_ORIGIN, false);
return (false !== strpos(implode(' ', $gitCheck), 'heads/master'));
}
public function getTags(): array
{
if (false === $this->tags) {
$this->tags = [];
$ts = $this->console->exec("git ls-remote --tags --refs " . self::OSE_ORIGIN, false);
foreach ($ts as $tag) {
$this->tags[] = substr($tag, strpos($tag, 'refs/tags/') + 10);
}
}
return $this->tags;
}
/**
* @param string $tag
*
* @return bool
*/
public function tagIsValid(string $tag): bool
{
return in_array($tag, $this->getTags());
}
public function currentVersion(string $osedir): string
{
$vf = $this->getVersionFile($osedir);
if (!file_exists($vf)) {
return 'inconnue';
}
return file_get_contents($vf);
}
public function writeVersion(string $osedir, string $version)
{
$vf = $this->getVersionFile($osedir);
file_put_contents($vf, $version);
}
private function getVersionFile(string $osedir): string
{
if ('/' == substr($osedir, -1)) {
return $osedir . 'VERSION';
} else {
return $osedir . '/VERSION';
}
}
public function exec($args)
{
$this->console->exec("php ".dirname(__DIR__)."/public/index.php " . $args);
}
}
class Console
{
const COLOR_BLACK = '0;30';
const COLOR_DARK_GRAY = '1;30';
const COLOR_BLUE = '0;34';
const COLOR_LIGHT_BLUE = '1;34';
const COLOR_GREEN = '0;32';
const COLOR_LIGHT_GREEN = '1;32';
const COLOR_CYAN = '0;36';
const COLOR_LIGHT_CYAN = '1;36';
const COLOR_RED = '0;31';
const COLOR_LIGHT_RED = '1;31';
const COLOR_PURPLE = '0;35';
const COLOR_LIGHT_PURPLE = '1;35';
const COLOR_BROWN = '0;33';
const COLOR_YELLOW = '1;33';
const COLOR_LIGHT_GRAY = '0;37';
const COLOR_WHITE = '1;37';
const BG_BLACK = '40';
const BG_RED = '41';
const BG_GREEN = '42';
const BG_YELLOW = '43';
const BG_BLUE = '44';
const BG_MAGENTA = '45';
const BG_CYAN = '46';
const BG_LIGHT_GRAY = '47';
public function printMainTitle($title, $spaces = 1)
{
$pstr = str_repeat(' ', $spaces);
$t = $pstr . $title . $pstr;
$len = mb_strlen($t);
echo '╔' . str_repeat('═', $len) . "╗\n";
echo '║' . str_repeat(' ', $len) . "║\n";
echo "║" . $t . "║\n";
echo '║' . str_repeat(' ', $len) . "║\n";
echo '╚' . str_repeat('═', $len) . "╝\n\n";
}
public function print($text, $color = null, $bgColor = null)
{
if ($bgColor) $bgColor = ';' . $bgColor;
if (!$color && !$bgColor) {
echo $text;
} else {
echo "\e[$color$bgColor" . "m$text\e[0m";
}
}
public function println($text, $color = null, $bgColor = null)
{
$this->print($text, $color, $bgColor);
echo "\n";
}
public function gestExitCode($code)
{
if (0 == $code) return;
$this->printDie("Une erreur ($code) est survenue. Le script est stoppé");
}
public function printDie($text)
{
$this->println($text, self::COLOR_LIGHT_RED);
$this->println(' -- FIN Prématurée de l\'exécution du script -- ', null, self::BG_RED);
die("\n");
}
public function getArg($index=null)
{
$args = isset($_SERVER['argv']) ? $_SERVER['argv'] : [];
if (null === $index) return $args;
if (isset($args[$index])){
return $args[$index];
}else{
return null;
}
}
public function getInput()
{
return trim(fgets(STDIN));
}
public function exec($command, $autoDisplay = true)
{
if (is_array($command)) {
$command = implode(';', $command);
}
exec($command, $output, $return);
if ($autoDisplay) {
echo implode("\n", $output) . "\n";
}
$this->gestExitCode($return);
return $output;
}
public function passthru($command)
{
if (is_array($command)) {
$command = implode(';', $command);
}
passthru($command, $returnVar);
$this->gestExitCode($returnVar);
return $returnVar;
}
public function strPad($input, $padLength = null, $padString = ' ')
{
return utf8_encode(str_pad(utf8_decode($input), $padLength, $padString));
}
}
\ No newline at end of file
#!/usr/bin/env php
<?php
$c = new Console();
$od = new OseDeploy($c);
$c->printMainTitle("Déploiement de OSE", 13);
// Mise en place de la clé SSH
$c->println("\nMise en place de la clé SSH vers le GitLab hébergeant OSE", $c::COLOR_LIGHT_CYAN);
$c->println("L'accès au serveur Gitlab doit se faire par SSH.");
$c->print("Voulez-vous créer une clé SSH pour accéder au serveur Gitlab hébergeant OSE ? (o/n, n par défaut) ");
$needKey = $c->getInput();
if (in_array($needKey, ["o", "O"])) {
$c->println("Génération de la clé SSH...");
$c->print("Veuillez préciser l'adresse mail du compte utilisé pour accéder au Gitlab de OSE: ");
$gitlabMail = $c->getInput();
$c->passthru("ssh-keygen -t rsa -C $gitlabMail -b 4096");
$c->println("Intégrez ensuite votre clé SSH dans Gitlab.");
$c->println("Le serveur GitLab est accessible à l'adresse suivante : https://git.unicaen.fr/dsi/OSE");
$c->println("Ensuite, appuyez sur \"Entrée\" pour continuer...");
$c->getInput();
if ($od->gitlabIsReachable()) {
$c->println("Votre clé SSH a bien été déployée et est fonctionnelle.", $c::COLOR_LIGHT_GREEN);
} else {
$c->printDie("L'accès par SSH au serveur GitLab de OSE ne fonctionne pas. Merci de déployer par vous-même une clé, car vous en aurez besoin pour la suite de la procédure.");
}
} else {
if (!$od->gitlabIsReachable()) {
$c->printDie("L'accès par SSH au serveur GitLab de OSE ne fonctionne pas. Merci de déployer par vous-même une clé, car vous en aurez besoin pour la suite de la procédure.");
}
}
// Création du dossier
$c->println("\nCréation du dossier et initialisation de GIT", $c::COLOR_LIGHT_CYAN);
$c->print("Veuillez indiquer un nouveau répertoire où implanter OSE: ");
$osedir = $c->getInput();
if (file_exists($osedir)){
$c->printDie("Le répertoire $osedir existe déjà. Merci d'en spécifier un nouveau.");
}
$c->exec([
"mkdir $osedir",
"cd $osedir",
"git init",
"git remote add origin " . $od::OSE_ORIGIN,
"git fetch --all --tags --prune",
]);
// Choix de la version
$c->println("\nSélection de la version à déployer", $c::COLOR_LIGHT_CYAN);
$c->println("Voici la liste des versions de OSE disponibles:");
$tags = $od->getTags();
foreach ($tags as $tag) {
$c->println($tag);
}
$ok = false;
while (!$ok) {
$c->print("Veuillez choisir une version à déployer: ");
$version = $c->getInput();
if ($od->tagIsValid($version)) {
$ok = true;
} else {
$c->println("$version n'est pas dans la liste des versions disponibles.");
}
}
// Récupération des sources
$c->println("\nDéploiement à partir des sources GIT", $c::COLOR_LIGHT_CYAN);
$c->exec([
"cd $osedir",
"git checkout tags/$version",
"mkdir data/cache",
"chmod 777 data/cache",
"chmod +7 bin/ose",
]);
$od->writeVersion($osedir, $version);
// Récupération de Composer
$c->println("\nRécupération de l'outil de gestion des dépendances Composer", $c::COLOR_LIGHT_CYAN);
$c->passthru("cd $osedir;wget https://getcomposer.org/composer.phar");
// Récupération des dépendances
$c->println("\nChargement des dépendances à l'aide de Composer", $c::COLOR_LIGHT_CYAN);
$c->passthru("cd $osedir;php composer.phar install");
// Génération des proxies pour l'ORM Doctrine
$c->println("\nGénération des proxies pour l'ORM Doctrine", $c::COLOR_LIGHT_CYAN);
$c->exec([
"cd $osedir",
"php vendor/bin/doctrine-module orm:generate-proxies",
"chmod -R 777 data/cache/DoctrineProxy",
"cp config/application.local.php.dist config.local.php",
]);
// Mise en place des tâches CRON ??
// Conclusion
$c->println("\nFin du script d'installation des fichiers", $c::COLOR_LIGHT_GREEN);
$c->println("Il reste encore six étapes à réaliser pour que OSE soit pleinement fonctionnel :");
$c->println(" 1 - Configurez votre serveur Apache");
$c->println(" 2 - Initialisez la base de données de OSE avec le script prévu à cet effet");
$c->println(" 3 - Mettez en place la configuration locale de l'application");
$c->println(" 4 - Une fois bien connecté, configurez vos connecteurs en vous appuyant\n le cas échéant sur ceux qui vous sont fournis");
$c->println(" 5 - Mettez en place les tâches CRON et les JOBS Oracle nécessaires (envoi de mails pour les infdicateurs, Synchronisatio automatique, etc.");
$c->println(" 6 - Paramétrez l'application pour l'adapter à vos besoins");
$c->println('');
$c->println("Pour la suite, merci de vous reporter sur la procédure d'installation de OSE (https://ose.unicaen.fr/deploiement/install)");
$c->println("OSE possède également un guide de l'administrateur pour vous aider à configurer l'application");
$c->println('');
/************************************************************
* Classes utiles *
************************************************************/
class OseDeploy
{
const OSE_ORIGIN = 'git@git.unicaen.fr:dsi/OSE.git';
/**
* @var Console
*/
protected $console;
/**
* @var array
*/
private $tags = false;
/**
* OseDeploy constructor.
*
* @param Console $console
*/
public function __construct(Console $console)
{
$this->console = $console;
}
public function gitlabIsReachable(): bool
{
$gitCheck = $this->console->exec("git ls-remote --heads " . self::OSE_ORIGIN, false);
return (false !== strpos(implode(' ', $gitCheck), 'heads/master'));
}
public function getTags(): array
{
if (false === $this->tags) {
$this->tags = [];
$ts = $this->console->exec("git ls-remote --tags --refs " . self::OSE_ORIGIN, false);
foreach ($ts as $tag) {
$this->tags[] = substr($tag, strpos($tag, 'refs/tags/') + 10);
}
}