public function execute(PhutilArgumentParser $args) { $iterator = $this->buildIterator($args); if (!$iterator) { throw new PhutilArgumentUsageException(pht('Either specify a list of files to encode, or use --all to ' . 'encode all files.')); } $force = (bool) $args->getArg('force'); $format_list = PhabricatorFileStorageFormat::getAllFormats(); $format_list = array_keys($format_list); $format_list = implode(', ', $format_list); $format_key = $args->getArg('as'); if (!strlen($format_key)) { throw new PhutilArgumentUsageException(pht('Use --as <format> to select a target encoding format. Available ' . 'formats are: %s.', $format_list)); } $format = PhabricatorFileStorageFormat::getFormat($format_key); if (!$format) { throw new PhutilArgumentUsageException(pht('Storage format "%s" is not valid. Available formats are: %s.', $format_key, $format_list)); } $key_name = $args->getArg('key'); if (strlen($key_name)) { $format->selectMasterKey($key_name); } $engines = PhabricatorFileStorageEngine::loadAllEngines(); $failed = array(); foreach ($iterator as $file) { $monogram = $file->getMonogram(); $engine_key = $file->getStorageEngine(); $engine = idx($engines, $engine_key); if (!$engine) { echo tsprintf("%s\n", pht('%s: Uses unknown storage engine "%s".', $monogram, $engine_key)); $failed[] = $file; continue; } if ($engine->isChunkEngine()) { echo tsprintf("%s\n", pht('%s: Stored as chunks, no data to encode directly.', $monogram)); continue; } if ($file->getStorageFormat() == $format_key && !$force) { echo tsprintf("%s\n", pht('%s: Already encoded in target format.', $monogram)); continue; } echo tsprintf("%s\n", pht('%s: Changing encoding from "%s" to "%s".', $monogram, $file->getStorageFormat(), $format_key)); try { $file->migrateToStorageFormat($format); echo tsprintf("%s\n", pht('Done.')); } catch (Exception $ex) { echo tsprintf("%B\n", pht('Failed! %s', (string) $ex)); $failed[] = $file; } } if ($failed) { $monograms = mpull($failed, 'getMonogram'); echo tsprintf("%s\n", pht('Failures: %s.', implode(', ', $monograms))); return 1; } return 0; }
public function execute(PhutilArgumentParser $args) { $iterator = $this->buildIterator($args); if (!$iterator) { throw new PhutilArgumentUsageException(pht('Either specify a list of files to cycle, or use --all to cycle ' . 'all files.')); } $format_map = PhabricatorFileStorageFormat::getAllFormats(); $engines = PhabricatorFileStorageEngine::loadAllEngines(); $key_name = $args->getArg('key'); $failed = array(); foreach ($iterator as $file) { $monogram = $file->getMonogram(); $engine_key = $file->getStorageEngine(); $engine = idx($engines, $engine_key); if (!$engine) { echo tsprintf("%s\n", pht('%s: Uses unknown storage engine "%s".', $monogram, $engine_key)); $failed[] = $file; continue; } if ($engine->isChunkEngine()) { echo tsprintf("%s\n", pht('%s: Stored as chunks, declining to cycle directly.', $monogram)); continue; } $format_key = $file->getStorageFormat(); if (empty($format_map[$format_key])) { echo tsprintf("%s\n", pht('%s: Uses unknown storage format "%s".', $monogram, $format_key)); $failed[] = $file; continue; } $format = clone $format_map[$format_key]; $format->setFile($file); if (!$format->canCycleMasterKey()) { echo tsprintf("%s\n", pht('%s: Storage format ("%s") does not support key cycling.', $monogram, $format->getStorageFormatName())); continue; } echo tsprintf("%s\n", pht('%s: Cycling master key.', $monogram)); try { if ($key_name) { $format->selectMasterKey($key_name); } $file->cycleMasterStorageKey($format); echo tsprintf("%s\n", pht('Done.')); } catch (Exception $ex) { echo tsprintf("%B\n", pht('Failed! %s', (string) $ex)); $failed[] = $file; } } if ($failed) { $monograms = mpull($failed, 'getMonogram'); echo tsprintf("%s\n", pht('Failures: %s.', implode(', ', $monograms))); return 1; } return 0; }
public function buildConfigurationPagePanel() { $viewer = $this->getViewer(); $application = $this->getApplication(); $engines = PhabricatorFileStorageEngine::loadAllEngines(); $writable_engines = PhabricatorFileStorageEngine::loadWritableEngines(); $chunk_engines = PhabricatorFileStorageEngine::loadWritableChunkEngines(); $yes = pht('Yes'); $no = pht('No'); $rows = array(); $rowc = array(); foreach ($engines as $key => $engine) { $limited = $no; $limit = null; if ($engine->hasFilesizeLimit()) { $limited = $yes; $limit = phutil_format_bytes($engine->getFilesizeLimit()); } if ($engine->canWriteFiles()) { $writable = $yes; } else { $writable = $no; } if ($engine->isTestEngine()) { $test = $yes; } else { $test = $no; } if (isset($writable_engines[$key]) || isset($chunk_engines[$key])) { $rowc[] = 'highlighted'; } else { $rowc[] = null; } $rows[] = array($key, get_class($engine), $test, $writable, $limited, $limit); } $table = id(new AphrontTableView($rows))->setNoDataString(pht('No storage engines available.'))->setHeaders(array(pht('Key'), pht('Class'), pht('Unit Test'), pht('Writable'), pht('Has Limit'), pht('Limit')))->setRowClasses($rowc)->setColumnClasses(array('', 'wide', '', '', '', 'n')); $box = id(new PHUIObjectBoxView())->setHeaderText(pht('Storage Engines'))->setTable($table); return $box; }
public function execute(PhutilArgumentParser $args) { $target_key = $args->getArg('engine'); if (!$target_key) { throw new PhutilArgumentUsageException(pht('Specify an engine to migrate to with `%s`. ' . 'Use `%s` to get a list of engines.', '--engine', 'files engines')); } $target_engine = PhabricatorFile::buildEngine($target_key); $iterator = $this->buildIterator($args); if (!$iterator) { throw new PhutilArgumentUsageException(pht('Either specify a list of files to migrate, or use `%s` ' . 'to migrate all files.', '--all')); } $is_dry_run = $args->getArg('dry-run'); $min_size = (int) $args->getArg('min-size'); $max_size = (int) $args->getArg('max-size'); $is_copy = $args->getArg('copy'); $failed = array(); $engines = PhabricatorFileStorageEngine::loadAllEngines(); $total_bytes = 0; $total_files = 0; foreach ($iterator as $file) { $monogram = $file->getMonogram(); $engine_key = $file->getStorageEngine(); $engine = idx($engines, $engine_key); if (!$engine) { echo tsprintf("%s\n", pht('%s: Uses unknown storage engine "%s".', $monogram, $engine_key)); $failed[] = $file; continue; } if ($engine->isChunkEngine()) { echo tsprintf("%s\n", pht('%s: Stored as chunks, no data to migrate directly.', $monogram)); continue; } if ($engine_key === $target_key) { echo tsprintf("%s\n", pht('%s: Already stored in engine "%s".', $monogram, $target_key)); continue; } $byte_size = $file->getByteSize(); if ($min_size && $byte_size < $min_size) { echo tsprintf("%s\n", pht('%s: File size (%s) is smaller than minimum size (%s).', $monogram, phutil_format_bytes($byte_size), phutil_format_bytes($min_size))); continue; } if ($max_size && $byte_size > $max_size) { echo tsprintf("%s\n", pht('%s: File size (%s) is larger than maximum size (%s).', $monogram, phutil_format_bytes($byte_size), phutil_format_bytes($max_size))); continue; } if ($is_dry_run) { echo tsprintf("%s\n", pht('%s: (%s) Would migrate from "%s" to "%s" (dry run)...', $monogram, phutil_format_bytes($byte_size), $engine_key, $target_key)); } else { echo tsprintf("%s\n", pht('%s: (%s) Migrating from "%s" to "%s"...', $monogram, phutil_format_bytes($byte_size), $engine_key, $target_key)); } try { if ($is_dry_run) { // Do nothing, this is a dry run. } else { $file->migrateToEngine($target_engine, $is_copy); } $total_files += 1; $total_bytes += $byte_size; echo tsprintf("%s\n", pht('Done.')); } catch (Exception $ex) { echo tsprintf("%s\n", pht('Failed! %s', (string) $ex)); $failed[] = $file; throw $ex; } } echo tsprintf("%s\n", pht('Total Migrated Files: %s', new PhutilNumber($total_files))); echo tsprintf("%s\n", pht('Total Migrated Bytes: %s', phutil_format_bytes($total_bytes))); if ($is_dry_run) { echo tsprintf("%s\n", pht('This was a dry run, so no real migrations were performed.')); } if ($failed) { $monograms = mpull($failed, 'getMonogram'); echo tsprintf("%s\n", pht('Failures: %s.', implode(', ', $monograms))); return 1; } return 0; }
/** * Find a storage engine which is suitable for storing chunks. * * This engine must be a writable engine, have a filesize limit larger than * the chunk limit, and must not be a chunk engine itself. */ private function getWritableEngine() { // NOTE: We can't just load writable engines or we'll loop forever. $engines = parent::loadAllEngines(); foreach ($engines as $engine) { if ($engine->isChunkEngine()) { continue; } if ($engine->isTestEngine()) { continue; } if (!$engine->canWriteFiles()) { continue; } if ($engine->hasFilesizeLimit()) { if ($engine->getFilesizeLimit() < $this->getChunkSize()) { continue; } } return true; } return false; }
public function testLoadAllEngines() { PhabricatorFileStorageEngine::loadAllEngines(); $this->assertTrue(true); }