From 1954c00b39304a6024d202b79637df4d2d230f7f Mon Sep 17 00:00:00 2001 From: Arnaud Fornerot Date: Wed, 2 Jun 2021 14:59:41 +0200 Subject: [PATCH] =?UTF-8?q?mise=20en=20place=20du=20cron=20+=20syst=C3=A8m?= =?UTF-8?q?e=20de=20moulinette=20+=20init=20du=20domaine=20sur=20les=20pro?= =?UTF-8?q?jets=20existant?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dicos/25_schedule.xml | 1 + src/schedule-2.0/.env | 2 +- src/schedule-2.0/config/routes.yaml | 19 ++-- src/schedule-2.0/config/services.yaml | 6 +- src/schedule-2.0/scripts/reconfigure.sh | 1 + .../src/Command/AppInitCommand.php | 22 +++++ .../src/Command/CronInitCommand.php | 90 +++--------------- .../src/Command/DumpBddCommand.php | 92 +++++++++++++++++++ .../src/Command/ScriptCommand.php | 88 ++++++++++++++++++ .../src/Controller/CronController.php | 66 +++++-------- src/schedule-2.0/src/Entity/Domaine.php | 25 +++++ src/schedule-2.0/src/Entity/Script.php | 50 ++++++++++ .../src/Repository/ScriptRepository.php | 15 +++ .../templates/Cron/list.html.twig | 8 +- .../templates/Cron/logs.html.twig | 27 +++--- src/schedule-2.0/templates/base.html.twig | 15 +++ tmpl/schedule.cron | 1 + 17 files changed, 377 insertions(+), 151 deletions(-) create mode 100644 src/schedule-2.0/src/Command/DumpBddCommand.php create mode 100644 src/schedule-2.0/src/Command/ScriptCommand.php create mode 100644 src/schedule-2.0/src/Entity/Script.php create mode 100644 src/schedule-2.0/src/Repository/ScriptRepository.php create mode 100644 tmpl/schedule.cron diff --git a/dicos/25_schedule.xml b/dicos/25_schedule.xml index 6aabfb9..f395c83 100644 --- a/dicos/25_schedule.xml +++ b/dicos/25_schedule.xml @@ -17,6 +17,7 @@ + diff --git a/src/schedule-2.0/.env b/src/schedule-2.0/.env index 6872ba8..331f47b 100644 --- a/src/schedule-2.0/.env +++ b/src/schedule-2.0/.env @@ -30,7 +30,7 @@ APP_ALIAS=schedule APP_AUTH=MYSQL APP_NAME=Schedule APP_ENV=PROD -APP_CRON=false +APP_CRON=true # Office hours OFFICE_HOUR_START=09:00 diff --git a/src/schedule-2.0/config/routes.yaml b/src/schedule-2.0/config/routes.yaml index 84a237a..405aca0 100644 --- a/src/schedule-2.0/config/routes.yaml +++ b/src/schedule-2.0/config/routes.yaml @@ -58,10 +58,11 @@ oneup_uploader: resource: . type: uploader -#== Cron ======================================================================================================== + +#== Cron ================================================================================================================= app_cron: path: /admin/cron - defaults: { _controller: App\Controller\CronController:list } + defaults: { _controller: App\Controller\CronController:list } app_cron_ajax_list: path: /admin/cron/ajax/list @@ -69,16 +70,20 @@ app_cron_ajax_list: app_cron_update: path: /admin/cron/update/{id} - defaults: { _controller: App\Controller\CronController:update } + defaults: { _controller: App\Controller\CronController:update } app_cron_exec: path: /admin/cron/exec/{id} - defaults: { _controller: App\Controller\CronController:exec } + defaults: { _controller: App\Controller\CronController:exec } app_cron_log: - path: /admin/cron/log/{id} - controller: App\Controller\Cron:log - defaults: { id: "cron" } + path: /admin/cron/log + defaults: { _controller: App\Controller\CronController:log } + +app_cron_getlog: + path: /admin/cron/getlog/{id} + defaults: { _controller: App\Controller\CronController:getlog } + #== User ======================================================================================================== app_user: diff --git a/src/schedule-2.0/config/services.yaml b/src/schedule-2.0/config/services.yaml index cb5a388..fca556d 100644 --- a/src/schedule-2.0/config/services.yaml +++ b/src/schedule-2.0/config/services.yaml @@ -24,7 +24,11 @@ parameters: doliActive: '%env(resolve:DOLIBARR_ACTIVE)%' doliApiKey: '%env(resolve:DOLIBARR_API_KEY)%' doliUri: '%env(resolve:DOLIBARR_URI)%' - + databaseName: '%env(resolve:DATABASE_NAME)%' + databaseUser: '%env(resolve:DATABASE_USER)%' + databasePassword: '%env(resolve:DATABASE_PASSWORD)%' + databaseHost: '%env(resolve:DATABASE_HOST)%' + services: # default configuration for services in *this* file _defaults: diff --git a/src/schedule-2.0/scripts/reconfigure.sh b/src/schedule-2.0/scripts/reconfigure.sh index a9c3dbc..8a07499 100755 --- a/src/schedule-2.0/scripts/reconfigure.sh +++ b/src/schedule-2.0/scripts/reconfigure.sh @@ -15,6 +15,7 @@ composer install php bin/console app:AppInit --env=prod php bin/console app:CronInit --env=prod +php bin/console app:Script --env=prod # Permissions ./scripts/perm.sh www-data diff --git a/src/schedule-2.0/src/Command/AppInitCommand.php b/src/schedule-2.0/src/Command/AppInitCommand.php index ee5194d..0922824 100644 --- a/src/schedule-2.0/src/Command/AppInitCommand.php +++ b/src/schedule-2.0/src/Command/AppInitCommand.php @@ -15,6 +15,8 @@ use Doctrine\ORM\Id\AssignedGenerator; use App\Entity\User; use App\Entity\Nature; +use App\Entity\Domaine; + class AppInitCommand extends Command @@ -58,6 +60,9 @@ class AppInitCommand extends Command $this->insertNature(-90,"Non Facturable",false); $this->insertNature(-80,"Prestation",false); + // Création domaine par défaut + $this->insertDomaine(-100,"Administratif","Administratif"); + // Création du compte admin si non existant $this->insertUser("admin","admin"); @@ -82,6 +87,23 @@ class AppInitCommand extends Command } } + + protected function insertDomaine($id,$category,$name) { + $metadata = $this->em->getClassMetaData('App:Domaine'); + $metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_NONE); + $metadata->setIdGenerator(new AssignedGenerator()); + + $entity = $this->em->getRepository('App:Domaine')->find($id); + if(!$entity) { + $entity = new Domaine; + $entity->setId($id); + $entity->setName($name); + $entity->setCategory($category); + $this->em->persist($entity); + $this->em->flush(); + } + } + protected function insertUser() { $metadata = $this->em->getClassMetaData('App:User'); $metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_NONE); diff --git a/src/schedule-2.0/src/Command/CronInitCommand.php b/src/schedule-2.0/src/Command/CronInitCommand.php index 14cbad2..165b66b 100644 --- a/src/schedule-2.0/src/Command/CronInitCommand.php +++ b/src/schedule-2.0/src/Command/CronInitCommand.php @@ -57,94 +57,33 @@ class CronInitCommand extends Command } protected function insertCron() { - /* $metadata = $this->em->getClassMetaData('App:Cron'); - $metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_NONE); - $metadata->setIdGenerator(new AssignedGenerator()); - - - // Job Récupératoin la table de référence des articles - // Toute les 1mn - $entity = $this->em->getRepository('App:Cron')->find(10); + // Job Mail + // Toute les minutes + $entity = $this->em->getRepository('App:Cron')->findOneBy(["command"=>"app:sendMail"]); if(!$entity) { $entity = new Cron; - $entity->setId(10); - $entity->setCommand("app:CrousGo"); - $entity->setDescription("Récupératoin des commandes CROUS & GO"); + $entity->setCommand("app:sendMail"); + $entity->setDescription("Execution du spool de mail en attente"); $entity->setStatut(2); $entity->setRepeatcall(0); $entity->setRepeatexec(0); $entity->setRepeatinterval(60); $entity->setNextexecdate($entity->getSubmitdate()); - $this->em->persist($entity); - } - - // Job Fermeture automatique des guichets - // Toute les 1mn - $entity = $this->em->getRepository('App:Cron')->find(20); - if(!$entity) { - $entity = new Cron; - $entity->setId(20); - $entity->setCommand("app:FermetureGuichet"); - $entity->setDescription("Fermeture automatique des guichets"); - $entity->setStatut(2); - $entity->setRepeatcall(0); - $entity->setRepeatexec(0); - $entity->setRepeatinterval(60); - $entity->setNextexecdate($entity->getSubmitdate()); - $this->em->persist($entity); - } - - // Job Récupératoin la table de référence des articles - // Toute les 24h à 3h00 - $entity = $this->em->getRepository('App:Cron')->find(1000); - if(!$entity) { - $entity = new Cron; - $nextdate=$entity->getSubmitdate(); - $nextdate->setTime(3,0); - - $entity->setId(1000); - $entity->setCommand("app:CodeArticle"); - $entity->setDescription("Récupératoin la table de référence des articles"); - $entity->setStatut(2); - $entity->setRepeatcall(0); - $entity->setRepeatexec(0); - $entity->setRepeatinterval(86400); - $entity->setNextexecdate($nextdate); + $entity->setJsonargument('{"message-limit":"100","env":"prod"}'); $this->em->persist($entity); } - // Job reinit des piles à 0 - // Toute les 24h à 3h00 - $entity = $this->em->getRepository('App:Cron')->find(1010); + // Job Dump + // Toute les 24h à 2h00 + $entity = $this->em->getRepository('App:Cron')->findOneBy(["command"=>"app:dumpBdd"]); if(!$entity) { $entity = new Cron; $nextdate=$entity->getSubmitdate(); - $nextdate->setTime(3,0); - - $entity->setId(1010); - $entity->setCommand("app:RazPile"); - $entity->setDescription("Remet les piles des services à 0"); - $entity->setStatut(2); - $entity->setRepeatcall(0); - $entity->setRepeatexec(0); - $entity->setRepeatinterval(86400); - $entity->setNextexecdate($nextdate); - $this->em->persist($entity); - } - - // Job reinit des piles à 0 - // Toute les 24h à 3h00 - $entity = $this->em->getRepository('App:Cron')->find(1020); - if(!$entity) { - $entity = new Cron; - $nextdate=$entity->getSubmitdate(); - $nextdate->setTime(3,0); - - $entity->setId(1020); - $entity->setCommand("app:RazCommande"); - $entity->setDescription("Cloture et Purge des Commandes"); + $nextdate->setTime(2,0); + $entity->setCommand("app:dumpBdd"); + $entity->setDescription("Sauvegarde de la BDD"); $entity->setStatut(2); $entity->setRepeatcall(0); $entity->setRepeatexec(0); @@ -152,9 +91,8 @@ class CronInitCommand extends Command $entity->setNextexecdate($nextdate); $this->em->persist($entity); } - + // On flush - $this->em->flush(); - */ + $this->em->flush(); } } diff --git a/src/schedule-2.0/src/Command/DumpBddCommand.php b/src/schedule-2.0/src/Command/DumpBddCommand.php new file mode 100644 index 0000000..f172d3c --- /dev/null +++ b/src/schedule-2.0/src/Command/DumpBddCommand.php @@ -0,0 +1,92 @@ +container = $container; + $this->em = $em; + } + + protected function configure() + { + $this + ->setName('app:dumpBdd') + ->setDescription('Sauvegarde de la BDD') + ->setHelp('Sauvegarde de la BDD') + ->addArgument('cronid', InputArgument::OPTIONAL, 'ID Cron Job') + ->addArgument('lastchance', InputArgument::OPTIONAL, 'Lastchance to run the cron') + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->output = $output; + $this->filesystem = new Filesystem(); + $this->rootlog = $this->container->get('kernel')->getLogDir()."/"; + $alias = $this->container->getParameter('appAlias'); + + $this->writelnred(''); + $this->writelnred('== app:dumpBdd'); + $this->writelnred('=========================================================================================================='); + + $this->datahost = $this->container->getParameter('databaseHost'); + $this->database = $this->container->getParameter('databaseName') ; + $this->username = $this->container->getParameter('databaseUser') ; + $this->password = $this->container->getParameter('databasePassword') ; + + $cmd = sprintf('mysqldump -h %s -B %s -u %s --password=%s' + , $this->datahost + , $this->database + , $this->username + , $this->password + ); + + $result = $this->runCommand($cmd); + if($result['exit_status'] == 0) { + $this->filesystem->dumpFile($this->rootlog.$alias.".sql", implode('', $result['output'])); + } + + $this->writeln(''); + return 1; + } + + protected function runCommand($command) + { + $command .=" >&1"; + exec($command, $output, $exit_status); + return array( + "output" => $output + , "exit_status" => $exit_status + ); + } + + private function writelnred($string) { + $this->output->writeln(''.$string.''); + $this->filesystem->appendToFile($this->rootlog.'cron.log', $string."\n"); + } + private function writeln($string) { + $this->output->writeln($string); + $this->filesystem->appendToFile($this->rootlog.'cron.log', $string."\n"); + } +} diff --git a/src/schedule-2.0/src/Command/ScriptCommand.php b/src/schedule-2.0/src/Command/ScriptCommand.php new file mode 100644 index 0000000..c339241 --- /dev/null +++ b/src/schedule-2.0/src/Command/ScriptCommand.php @@ -0,0 +1,88 @@ +container = $container; + $this->em = $em; + } + + + protected function configure() + { + $this + ->setName('app:Script') + ->setDescription('Script to call') + ->setHelp('Script to call') + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->output = $output; + $this->filesystem = new Filesystem(); + $this->rootlog = $this->container->get('kernel')->getLogDir()."/"; + + $output->writeln('APP = Scripts'); + + $this->callscript("initdomaine"); + + $output->writeln(''); + + return 1; + } + + + private function callscript($name) { + $script=$this->em->getRepository("App:Script")->findOneBy(["name"=>$name]); + if(!$script) { + //$this->writelnred("== SCRIPT = ".$name); + $this->$name(); + + $script=new Script(); + $script->setName($name); + $this->em->persist($script); + $this->em->flush(); + $this->writeln(""); + } + } + + private function initdomaine() { + $domaine=$this->em->getRepository("App:Domaine")->find(-100); + $projects=$this->em->getRepository("App:Project")->findBy(["domaine"=>null]); + foreach($projects as $project) { + $project->setDomaine($domaine); + $this->em->persist($project); + $this->em->flush(); + } + } + + private function writelnred($string) { + $this->output->writeln(''.$string.''); + $this->filesystem->appendToFile($this->rootlog.'cron.log', $string."\n"); + } + private function writeln($string) { + $this->output->writeln($string); + $this->filesystem->appendToFile($this->rootlog.'cron.log', $string."\n"); + } +} diff --git a/src/schedule-2.0/src/Controller/CronController.php b/src/schedule-2.0/src/Controller/CronController.php index 4ade2f0..7f67661 100644 --- a/src/schedule-2.0/src/Controller/CronController.php +++ b/src/schedule-2.0/src/Controller/CronController.php @@ -11,6 +11,8 @@ use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Output\BufferedOutput; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\HttpFoundation\BinaryFileResponse; +use Symfony\Component\HttpFoundation\ResponseHeaderBag; use App\Entity\Cron as Entity; use App\Form\CronType as Form; @@ -70,53 +72,27 @@ class CronController extends AbstractController ]); } - public function execAction(Request $request, $id) + public function log() + { + return $this->render($this->render.'logs.html.twig', [ + 'useheader' => true, + 'usesidebar' => true, + ]); + } + + public function getlog(Request $request, $id) { - set_time_limit(0); - $em = $this->getDoctrine()->getManager(); - $entity = $em->getRepository($this->labelentity)->find($id); - - if (!$entity) { - throw $this->createNotFoundException('Unable to find entity.'); - } - - $kernel = $this->get('kernel'); - $application = new Application($kernel); - $application->setAutoExit(false); - $command = $application->find($entity->getCommand()); - $jsonparameter=json_decode($entity->getJsonargument(),true); - $parameter = ($jsonparameter?new ArrayInput($jsonparameter):new ArrayInput([])); - - - $output = new BufferedOutput(OutputInterface::VERBOSITY_NORMAL,false); - $command->run($parameter, $output); - $content = $output->fetch(); - - return $this->render('CadolesCoreBundle:Core:command.html.twig', [ - 'useheader' => true, - 'usemenu' => false, - 'usesidebar' => true, - "title" => $entity->getDescription(), - "return_path" =>"cadoles_cron_config", - "content" =>$content - ]); - } - - public function logAction(Request $request, $id) - { - $kernel = $this->get('kernel'); - $path = $this->get('kernel')->getRootDir() . '/../var/logs/'.$id.'.log'; - $content = file_get_contents($path); - - return $this->render('CadolesCronBundle:Cron:logs.html.twig', [ - 'useheader' => true, - 'usemenu' => false, - 'usesidebar' => true, - "title" => "LOG = ".$id, - "content" => $content - ]); - } + $path = $this->getParameter('kernel.project_dir'); + if($id=="dump") + $file = $path . '/var/log/' . $this->getParameter("appAlias") . '.sql'; + else + $file = $path . '/var/log/'.$id.'.log'; + + $response = new BinaryFileResponse($file); + $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT); + return $response; + } protected function getErrorForm($id,$form,$request,$data,$mode) { diff --git a/src/schedule-2.0/src/Entity/Domaine.php b/src/schedule-2.0/src/Entity/Domaine.php index fd3f73e..71a4c0c 100644 --- a/src/schedule-2.0/src/Entity/Domaine.php +++ b/src/schedule-2.0/src/Entity/Domaine.php @@ -28,6 +28,12 @@ class Domaine */ private $name; + /** + * @ORM\Column(name="category", type="string") + * + */ + private $category; + /** * @ORM\Column(type="text", nullable=true) */ @@ -55,6 +61,13 @@ class Domaine return $this->id; } + public function setId(int $id): self + { + $this->id = $id; + + return $this; + } + public function getName(): ?string { return $this->name; @@ -138,6 +151,18 @@ class Domaine } } + return $this; + } + + public function getCategory(): ?string + { + return $this->category; + } + + public function setCategory(string $category): self + { + $this->category = $category; + return $this; } diff --git a/src/schedule-2.0/src/Entity/Script.php b/src/schedule-2.0/src/Entity/Script.php new file mode 100644 index 0000000..ac9885c --- /dev/null +++ b/src/schedule-2.0/src/Entity/Script.php @@ -0,0 +1,50 @@ +id; + } + + public function getName(): ?string + { + return $this->name; + } + + public function setName(string $name): self + { + $this->name = $name; + + return $this; + } +} diff --git a/src/schedule-2.0/src/Repository/ScriptRepository.php b/src/schedule-2.0/src/Repository/ScriptRepository.php new file mode 100644 index 0000000..977a640 --- /dev/null +++ b/src/schedule-2.0/src/Repository/ScriptRepository.php @@ -0,0 +1,15 @@ + -

Ajouter

-
Liste des Jobs @@ -18,11 +16,10 @@ JOBS Action - Order + Prochaine exécution Command Description Statut - Prochaine exécution @@ -31,11 +28,10 @@ JOBS - {{cron.id}} + {{cron.nextexecdate|date("d/m/Y H:i")}} {{cron.command}} {{cron.description}} {{cron.statutlabel}} - {{cron.nextexecdate|date("m/d/Y H:i")}} {% endfor %} diff --git a/src/schedule-2.0/templates/Cron/logs.html.twig b/src/schedule-2.0/templates/Cron/logs.html.twig index 0988633..eba2793 100644 --- a/src/schedule-2.0/templates/Cron/logs.html.twig +++ b/src/schedule-2.0/templates/Cron/logs.html.twig @@ -1,19 +1,16 @@ -{% extends "CRWhizBundle::base.html.twig" %} +{% extends 'base.html.twig' %} {% block body %} -

{{ title }}

+

+ Télécharger les logs +

- Log CRON - Log PROD - Log DEV -

-
-
- Logs -
- -
- {{ content | nl2br }} -
-
+ {% if appCron %} + Log CRON + {% endif %} + Log PROD + Log DEV + {% if appCron %} + Dump de la Base + {% endif %} {% endblock %} \ No newline at end of file diff --git a/src/schedule-2.0/templates/base.html.twig b/src/schedule-2.0/templates/base.html.twig index 7b125dd..8ee0a32 100644 --- a/src/schedule-2.0/templates/base.html.twig +++ b/src/schedule-2.0/templates/base.html.twig @@ -486,6 +486,21 @@ + {% if appCron %} +
  • Outils
  • +
  • + + Jobs + +
  • + +
  • + + Logs / Dump + +
  • + {% endif %} + {% endif %}
    diff --git a/tmpl/schedule.cron b/tmpl/schedule.cron new file mode 100644 index 0000000..d414f4b --- /dev/null +++ b/tmpl/schedule.cron @@ -0,0 +1 @@ +* * * * * root /var/www/html/schedule/scripts/cron.sh &>/dev/null