public function perform() { set_time_limit(0); $log = new DeploynautLogFile($this->args['logfile']); $projects = DNProject::get()->filter('Name', Convert::raw2sql($this->args['projectName'])); $project = $projects->first(); $path = $project->getLocalCVSPath(); $env = $this->args['env']; $log->write('Starting git fetch for project "' . $project->Name . '"'); // if an alternate user has been configured for clone, run the command as that user // @todo Gitonomy doesn't seem to have any way to prefix the command properly, if you // set 'sudo -u composer git' as the "command" parameter, it tries to run the whole // thing as a single command and fails $user = DNData::inst()->getGitUser(); if (!empty($user)) { $command = sprintf('cd %s && sudo -u %s git fetch -p origin +refs/heads/*:refs/heads/* --tags', $path, $user); $process = new \Symfony\Component\Process\Process($command); $process->setEnv($env); $process->setTimeout(3600); $process->run(); if (!$process->isSuccessful()) { throw new RuntimeException($process->getErrorOutput()); } } else { $repository = new Gitonomy\Git\Repository($path, array('environment_variables' => $env)); $repository->run('fetch', array('-p', 'origin', '+refs/heads/*:refs/heads/*', '--tags')); } $log->write('Git fetch is finished'); }
public function perform() { set_time_limit(0); $path = $this->args['path']; $repo = $this->args['repo']; $env = $this->args['env']; $logfile = DEPLOYNAUT_LOG_PATH . '/clonegitrepo.log'; $fh = fopen($logfile, 'a'); if (!$fh) { throw new RuntimeException(sprintf('Can\'t open file "%s" for logging.', $logfile)); } // if an alternate user has been configured for clone, run the command as that user $user = DNData::inst()->getGitUser(); if (file_exists($path)) { $command = array(); if (!empty($user)) { $command[] = sprintf('sudo -u %s', $user); } $command[] = sprintf('rm -rf %s', $path); fwrite($fh, sprintf('[%s] Cleaning up existing repository %s', date('Y-m-d H:i:s'), $path) . PHP_EOL); fwrite($fh, sprintf('[%s] Running command: %s', date('Y-m-d H:i:s'), implode(' ', $command)) . PHP_EOL); $process = new \Symfony\Component\Process\Process(implode(' ', $command)); $process->setEnv($env); $process->setTimeout(3600); $process->run(); if (!$process->isSuccessful()) { fwrite($fh, sprintf('[%s] Error cleaning up existing repository: %s', date('Y-m-d H:i:s'), $process->getErrorOutput()) . PHP_EOL); throw new RuntimeException($process->getErrorOutput()); } } fwrite($fh, sprintf('[%s] Cloning repository %s to %s', date('Y-m-d H:i:s'), $repo, $path) . PHP_EOL); echo "[-] CloneGitRepo starting" . PHP_EOL; $command = array(); if (!empty($user)) { $command[] = sprintf('sudo -u %s', $user); } $command[] = sprintf('git clone --bare -q %s %s', $repo, $path); fwrite($fh, sprintf('[%s] Running command: %s', date('Y-m-d H:i:s'), implode(' ', $command)) . PHP_EOL); $process = new \Symfony\Component\Process\Process(implode(' ', $command)); $process->setEnv($env); $process->setTimeout(3600); $process->run(); if (!$process->isSuccessful()) { fwrite($fh, sprintf('[%s] Error cloning repository %s to %s: %s', date('Y-m-d H:i:s'), $repo, $path, $process->getErrorOutput()) . PHP_EOL); throw new RuntimeException($process->getErrorOutput()); } fwrite($fh, sprintf('[%s] Successfully cloned repository %s to %s', date('Y-m-d H:i:s'), $repo, $path) . PHP_EOL); }
public function perform() { set_time_limit(0); if (!empty($this->args['logfile'])) { $this->log = new DeploynautLogFile($this->args['logfile']); } $this->project = DNProject::get()->byId($this->args['projectID']); if (!($this->project && $this->project->exists())) { throw new RuntimeException(sprintf('Project ID %s not found', $this->args['projectID'])); } $this->user = DNData::inst()->getGitUser() ?: null; // Disallow concurrent git fetches on the same project. // Only consider fetches started in the last 30 minutes (older jobs probably got stuck) try { if (!empty($this->args['fetchID'])) { $runningFetches = DNGitFetch::get()->filter(array('ProjectID' => $this->project->ID, 'Status' => array('Queued', 'Started'), 'Created:GreaterThan' => strtotime('-30 minutes')))->exclude('ID', $this->args['fetchID']); if ($runningFetches->count()) { $runningFetch = $runningFetches->first(); $message = sprintf('Another fetch is in progress (started at %s by %s)', $runningFetch->dbObject('Created')->Nice(), $runningFetch->Deployer()->Title); if ($this->log) { $this->log->write($message); } throw new RuntimeException($message); } } // Decide whether we need to just update what we already have // or initiate a clone if no local repo exists. if ($this->project->repoExists() && empty($this->args['forceClone'])) { $this->fetchRepo(); } else { $this->cloneRepo(); } } catch (Exception $e) { if ($this->log) { $this->log->write($e->getMessage()); } throw $e; } $this->project->clearGitCache(); $this->updateStatus('Finished'); }
public function perform() { set_time_limit(0); $path = $this->args['path']; $repo = $this->args['repo']; $env = $this->args['env']; $logfile = DEPLOYNAUT_LOG_PATH . '/clonegitrepo.log'; $fh = fopen($logfile, 'a'); if (!$fh) { throw new RuntimeException('Can\'t open file "' . $logfile . '" for logging.'); } // if an alternate user has been configured for clone, run the command as that user $user = DNData::inst()->getGitUser(); if (file_exists($path)) { if ($user) { exec(sprintf('sudo -u %s rm -rf %s', $user, $path)); } else { exec(sprintf('rm -rf %s', $path)); } } fwrite($fh, '[' . date('Y-m-d H:i:s') . '] Cloning ' . $repo . ' to ' . $path . PHP_EOL); echo "[-] CloneGitRepo starting" . PHP_EOL; // using git clone straight via system call since doing it via the // Gitonomy\Git\Admin times out. Silly. if ($user) { $command = sprintf('sudo -u %s git clone --bare -q %s %s', $user, $repo, $path); } else { $command = sprintf('git clone --bare -q %s %s', $repo, $path); } fwrite($fh, '[' . date('Y-m-d H:i:s') . '] Running command: ' . $command . PHP_EOL); $process = new \Symfony\Component\Process\Process($command); $process->setEnv($env); $process->setTimeout(3600); $process->run(); if (!$process->isSuccessful()) { throw new RuntimeException($process->getErrorOutput()); } fwrite($fh, '[' . date('Y-m-d H:i:s') . '] Cloned ' . $repo . ' to ' . $path . PHP_EOL); }
public function run($request = null) { // should syncing remove obsolete records? $remove = true; $dryRun = true; if ($request && $request->requestVar('remove') !== NULL) { $remove = (bool) $request->requestVar('remove'); } if ($request && $request->requestVar('dryrun') !== NULL) { $dryRun = (bool) $request->requestVar('dryrun'); } if ($dryRun) { echo "Running in dry run mode, no changes commited, "; echo "the output shows a prediction on what will happen." . PHP_EOL; echo "To skip dryrun, run the task like this:" . PHP_EOL; echo "./framework/sake dev/tasks/SyncProjectsAndEnvironments dryrun=0" . PHP_EOL . PHP_EOL; sleep(3); } $data = DNData::inst(); $projectPaths = $data->getProjectPaths(); // Sync projects $projects = DNProject::get(); if ($remove) { $this->echoHeader('Removing obsolete projects'); $this->removeObsoleteProjects($projectPaths, $dryRun); } $this->echoHeader('Adding new projects'); $this->syncProjectPaths($projectPaths, $dryRun); $this->echoHeader('Syncing environment files'); foreach ($projects as $project) { $this->echoHeader($project->Name); // Sync environments for each project $environmentPaths = $data->getEnvironmentPaths($project->Name); $this->removeObsoleteEnvironments($environmentPaths, $project, $dryRun); $this->syncEnvironmentPaths($environmentPaths, $project, $dryRun); } }
/** * Get the DNData object. * * @return DNData */ public function DNData() { return DNData::inst(); }
/** * @return DNData */ protected function DNData() { return DNData::inst(); }
/** * Returns a path unique to a specific transfer, including project/environment details. * Does not create the path on the filesystem. Can be used to store files related to this transfer. * * @param DNDataTransfer * @return String Absolute file path */ public function generateFilepath(DNDataTransfer $dataTransfer) { $data = DNData::inst(); $transferDir = $data->getDataTransferDir(); $filter = FileNameFilter::create(); return sprintf('%s/%s/%s/transfer-%s/', $transferDir, $filter->filter(strtolower($this->OriginalEnvironment()->Project()->Name)), $filter->filter(strtolower($this->OriginalEnvironment()->Name)), $dataTransfer->ID); }
/** * @param string $action Capistrano action to be executed * @param string $roles Defining a server role is required to target only the required servers. * @param DNEnvironment $environment * @param array<string>|null $args Additional arguments for process * @param DeploynautLogFile $log * @return \Symfony\Component\Process\Process */ public function getCommand($action, $roles, DNEnvironment $environment, $args = null, DeploynautLogFile $log) { $name = $environment->getFullName(); $env = $environment->Project()->getProcessEnv(); if (!$args) { $args = array(); } $args['history_path'] = realpath(DEPLOYNAUT_LOG_PATH . '/'); // Inject env string directly into the command. // Capistrano doesn't like the $process->setEnv($env) we'd normally do below. $envString = ''; if (!empty($env)) { $envString .= 'env '; foreach ($env as $key => $value) { $envString .= "{$key}=\"{$value}\" "; } } $data = DNData::inst(); // Generate a capfile from a template $capTemplate = file_get_contents(BASE_PATH . '/deploynaut/Capfile.template'); $cap = str_replace(array('<config root>', '<ssh key>', '<base path>'), array($data->getEnvironmentDir(), DEPLOYNAUT_SSH_KEY, BASE_PATH), $capTemplate); if (defined('DEPLOYNAUT_CAPFILE')) { $capFile = DEPLOYNAUT_CAPFILE; } else { $capFile = ASSETS_PATH . '/Capfile'; } file_put_contents($capFile, $cap); $command = "{$envString}cap -f " . escapeshellarg($capFile) . " -vv {$name} {$action} ROLES={$roles}"; foreach ($args as $argName => $argVal) { $command .= ' -s ' . escapeshellarg($argName) . '=' . escapeshellarg($argVal); } $log->write(sprintf('Running command: %s', $command)); $process = new Process($command); $process->setTimeout(3600); return $process; }
public function getSigFile() { $dir = DNData::inst()->getSignalDir(); if (!is_dir($dir)) { `mkdir {$dir}`; } return sprintf('%s/deploynaut-signal-%s-%s', DNData::inst()->getSignalDir(), $this->ClassName, $this->ID); }
/** * Returns a path unique to a specific transfer, including project/environment details. * Does not create the path on the filesystem. Can be used to store files related to this transfer. * * @param DNDataTransfer * @return String Absolute file path */ public function generateFilepath(DNDataTransfer $dataTransfer) { $data = DNData::inst(); $transferDir = $data->getDataTransferDir(); $sanitizeRegex = array('/\\s+/', '/[^a-zA-Z0-9-_\\.]/'); $sanitizeReplace = array('/_/', ''); $projectName = strtolower(preg_replace($sanitizeRegex, $sanitizeReplace, $this->OriginalEnvironment()->Project()->Name)); $envName = strtolower(preg_replace($sanitizeRegex, $sanitizeReplace, $this->OriginalEnvironment()->Name)); return sprintf('%s/%s/%s/transfer-%s/', $transferDir, $projectName, $envName, $dataTransfer->ID); }