/**
  * Runs a client level pre or post script.
  *
  * @param  string   $type       Either "pre" or "post".
  *
  * @param  int      $status     Status of previos command.
  *
  * @param  Client   $client     Client entity
  *
  * @param  Job      $job        Job entity. Null if running at the client level.
  *
  * @param  Script   $script     Script entity
  *
  * @param  string   $stats      Stats for script environment vars (not stored in DB)
  *
  * @return boolean  true on success, false on error.
  *
  */
 protected function runScript($type, $status, $client, $job, $script, $stats)
 {
     if ($script === null) {
         return true;
     }
     if (null == $job) {
         $entity = $client;
         $context = array('link' => $this->generateClientRoute($client->getId()));
         $errScriptError = 'Client "%entityid%" %scripttype% script "%scriptname%" execution failed. Diagnostic information follows: %output%';
         $errScriptMissing = 'Client "%entityid%" %scripttype% script "%scriptname%" present but file "%scriptfile%" missing.';
         $errScriptOk = 'Client "%entityid%" %scripttype% script "%scriptname%" execution succeeded. Output follows: %output%';
         $level = 'CLIENT';
         // Empty vars (only available under JOB level)
         $job_name = '';
         $owner_email = '';
         $recipient_list = '';
         $job_total_size = 0;
         $job_run_size = 0;
         $job_starttime = 0;
         $job_endtime = 0;
         if ($type == 'post') {
             $client_endtime = $stats['ELKARBACKUP_CLIENT_ENDTIME'];
             $client_starttime = $stats['ELKARBACKUP_CLIENT_STARTTIME'];
         } else {
             $client_endtime = 0;
             $client_starttime = 0;
         }
     } else {
         $entity = $job;
         $context = array('link' => $this->generateJobRoute($job->getId(), $client->getId()));
         $errScriptError = 'Job "%entityid%" %scripttype% script "%scriptname%" execution failed. Diagnostic information follows: %output%';
         $errScriptMissing = 'Job "%entityid%" %scripttype% script "%scriptname%" present but file "%scriptfile%" missing.';
         $errScriptOk = 'Job "%entityid%" %scripttype% script "%scriptname%" execution succeeded. Output follows: %output%';
         $level = 'JOB';
         $job_name = $job->getName();
         $owner_email = $job->getClient()->getOwner()->getEmail();
         $recipient_list = $job->getNotificationsEmail();
         $job_total_size = $job->getDiskUsage();
         $client_starttime = 0;
         $client_endtime = 0;
         if ($type == 'post') {
             $job_run_size = $stats['ELKARBACKUP_JOB_RUN_SIZE'];
             $job_starttime = $stats['ELKARBACKUP_JOB_STARTTIME'];
             $job_endtime = $stats['ELKARBACKUP_JOB_ENDTIME'];
         } else {
             $job_run_size = 0;
             $job_starttime = 0;
             $job_endtime = 0;
         }
     }
     $scriptName = $script->getName();
     $scriptFile = $script->getScriptPath();
     if (!file_exists($scriptFile)) {
         $this->err($errScriptMissing, array('%entityid%' => $entity->getId(), '%scriptfile%' => $scriptFile, '%scriptname%' => $scriptName, '%scripttype%' => $type), $context);
         return false;
     }
     $commandOutput = array();
     $command = sprintf('env ELKARBACKUP_LEVEL="%s" ELKARBACKUP_EVENT="%s" ELKARBACKUP_URL="%s" ELKARBACKUP_ID="%s" ELKARBACKUP_PATH="%s" ELKARBACKUP_STATUS="%s" ELKARBACKUP_CLIENT_NAME="%s" ELKARBACKUP_JOB_NAME="%s" ELKARBACKUP_OWNER_EMAIL="%s" ELKARBACKUP_RECIPIENT_LIST="%s" ELKARBACKUP_CLIENT_TOTAL_SIZE="%s" ELKARBACKUP_JOB_TOTAL_SIZE="%s" ELKARBACKUP_JOB_RUN_SIZE="%s" ELKARBACKUP_CLIENT_STARTTIME="%s" ELKARBACKUP_CLIENT_ENDTIME="%s" ELKARBACKUP_JOB_STARTTIME="%s" ELKARBACKUP_JOB_ENDTIME="%s" sudo "%s" 2>&1', $level, 'pre' == $type ? 'PRE' : 'POST', $entity->getUrl(), $entity->getId(), $entity->getSnapshotRoot(), $status, $client->getName(), $job_name, $owner_email, $recipient_list, $client->getDiskUsage(), $job_total_size, $job_run_size, $client_starttime, $client_endtime, $job_starttime, $job_endtime, $scriptFile);
     exec($command, $commandOutput, $status);
     if (0 != $status) {
         $this->err($errScriptError, array('%entityid%' => $entity->getId(), '%output%' => "\n" . implode("\n", $commandOutput), '%scriptname%' => $scriptName, '%scripttype%' => $type), $context);
         return false;
     }
     $this->info($errScriptOk, array('%entityid%' => $entity->getId(), '%output%' => "\n" . implode("\n", $commandOutput), '%scriptname%' => $scriptName, '%scripttype%' => $type), $context);
     return true;
 }
Exemplo n.º 2
0
 protected function runJob(Job $job, $runnableRetains)
 {
     $stats[] = array();
     $warnings = False;
     $container = $this->getContainer();
     $backupDir = $container->getParameter('backup_dir');
     $rsnapshot = $container->getParameter('rsnapshot');
     $tmpDir = $container->getParameter('tmp_dir');
     $engine = $container->get('templating');
     $idClient = $job->getClient()->getId();
     $idJob = $job->getId();
     $url = $job->getUrl();
     $retains = $job->getPolicy()->getRetains();
     $includes = array();
     $include = $job->getInclude();
     if ($include) {
         $includes = explode("\n", $include);
         foreach ($includes as &$theInclude) {
             $theInclude = str_replace('\\ ', '?', trim($theInclude));
         }
     }
     $excludes = array();
     $exclude = $job->getExclude();
     if ($exclude) {
         $excludes = explode("\n", $exclude);
         foreach ($excludes as &$theExclude) {
             $theExclude = str_replace('\\ ', '?', trim($theExclude));
         }
     }
     $syncFirst = (int) $job->getPolicy()->getSyncFirst();
     $context = array('link' => $this->generateJobRoute($idJob, $idClient));
     $content = $engine->render('BinovoElkarBackupBundle:Default:rsnapshotconfig.txt.twig', array('cmdPreExec' => '', 'cmdPostExec' => '', 'excludes' => $excludes, 'idClient' => sprintf('%04d', $idClient), 'idJob' => sprintf('%04d', $idJob), 'includes' => $includes, 'backupDir' => $backupDir, 'retains' => $retains, 'tmp' => $tmpDir, 'snapshotRoot' => $job->getSnapshotRoot(), 'syncFirst' => $syncFirst, 'url' => $url, 'useLocalPermissions' => $job->getUseLocalPermissions(), 'sshArgs' => $job->getSshArgs()));
     $confFileName = sprintf("%s/rsnapshot.%s_%s.cfg", $tmpDir, $idClient, $idJob);
     $fd = fopen($confFileName, 'w');
     if (false === $fd) {
         $this->err('Error opening config file %filename%. Aborting backup.', array('%filename%' => $confFileName), $context);
         return false;
     }
     $bytesWriten = fwrite($fd, $content);
     if (false === $bytesWriten) {
         $this->err('Error writing to config file %filename%. Aborting backup.', array('%filename%' => $confFileName), $context);
         return false;
     }
     $ok = fclose($fd);
     if (false === $ok) {
         $this->warn('Error closing config file %filename%.', array('%filename%' => $confFileName), $context);
     }
     if (!is_dir($job->getSnapshotRoot())) {
         $ok = mkdir($job->getSnapshotRoot(), 0777, true);
         if (false === $ok) {
             $this->err('Error creating snapshot root %filename%. Aborting backup.', array('%filename%' => $job->getSnapshotRoot()), $context);
             return false;
         }
     }
     foreach ($runnableRetains as $retain) {
         $status = 0;
         // pre script execution if needed
         $mustRunScripts = !$job->getPolicy()->isRotation($retain);
         if ($mustRunScripts) {
             foreach ($job->getPreScripts() as $script) {
                 if ($this->runScript('pre', 0, $job->getClient(), $job, $script, $stats)) {
                     $this->info('Job "%jobid%" pre script ok.', array('%jobid%' => $job->getId()), $context);
                 } else {
                     $this->err('Job "%jobid%" pre script error.', array('%jobid%' => $job->getId()), $context);
                     $warnings = True;
                 }
             }
         }
         $job_starttime = time();
         // run rsnapshot. sync first if needed
         $commands = array();
         if ($job->getPolicy()->mustSync($retain)) {
             $commands[] = sprintf('"%s" -c "%s" sync 2>&1', $rsnapshot, $confFileName);
         }
         $commands[] = sprintf('"%s" -c "%s" %s 2>&1', $rsnapshot, $confFileName, $retain);
         foreach ($commands as $command) {
             $commandOutput = array();
             $status = 0;
             $this->info('Running %command%', array('%command%' => $command), $context);
             exec($command, $commandOutput, $status);
             if (0 != $status) {
                 $this->err('Command %command% failed. Diagnostic information follows: %output%', array('%command%' => $command, '%output%' => "\n" . implode("\n", $commandOutput)), $context);
                 $ok = false;
                 break;
             } else {
                 $this->info('Command %command% succeeded with output: %output%', array('%command%' => $command, '%output%' => implode("\n", $commandOutput)), $context);
             }
         }
         $job_endtime = time();
         // get disk usage
         $du_before = $job->getDiskUsage();
         $this->info('Client "%clientid%", Job "%jobid%" du begin.', array('%clientid%' => $job->getClient()->getId(), '%jobid%' => $job->getId()), $context);
         $du = (int) shell_exec(sprintf("du -ks '%s' | sed 's/\t.*//'", $job->getSnapshotRoot()));
         $job->setDiskUsage($du);
         $this->info('Client "%clientid%", Job "%jobid%" du end.', array('%clientid%' => $job->getClient()->getId(), '%jobid%' => $job->getId()), $context);
         $job_run_size = $du - $du_before;
         // post script execution if needed
         if ($mustRunScripts) {
             foreach ($job->getPostScripts() as $script) {
                 $stats['ELKARBACKUP_JOB_RUN_SIZE'] = $job_run_size;
                 $stats['ELKARBACKUP_JOB_STARTTIME'] = $job_starttime;
                 $stats['ELKARBACKUP_JOB_ENDTIME'] = $job_endtime;
                 if ($this->runScript('post', $status, $job->getClient(), $job, $script, $stats)) {
                     $this->info('Job "%jobid%" post script ok.', array('%jobid%' => $job->getId()), $context);
                 } else {
                     $this->err('Job "%jobid%" post script error.', array('%jobid%' => $job->getId()), $context);
                     $warnings = True;
                 }
             }
         }
         //tahoe backup
         $tahoe = $container->get('Tahoe');
         $tahoeInstalled = $tahoe->isInstalled();
         $tahoeOn = $container->getParameter('tahoe_active');
         if ($tahoeInstalled && $tahoeOn) {
             $tahoe->enqueueJob($job, $retain);
         }
     }
     if (false === unlink($confFileName)) {
         $this->warn('Error unlinking config file %filename%.', array('%filename%' => $confFileName), $context);
     }
     if (True === $ok) {
         if (True === $warnings) {
             $ok = 2;
         }
     }
     return $ok;
 }
Exemplo n.º 3
0
 protected function _getJobTahoePath(Job $job)
 {
     $idClient = $job->getClient()->getId();
     $idJob = $job->getId();
     return 'elkarbackup:Backups/' . sprintf('%04d', $idClient) . '/' . sprintf('%04d', $idJob) . '/';
 }