setName('files_external:verify') ->setDescription('Verify mount configuration') ->addArgument( 'mount_id', InputArgument::REQUIRED, 'The id of the mount to check' )->addOption( 'config', 'c', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Additional config option to set before checking in key=value pairs, required for certain auth backends such as login credentails' ); parent::configure(); } protected function execute(InputInterface $input, OutputInterface $output): int { $mountId = $input->getArgument('mount_id'); $configInput = $input->getOption('config'); try { $mount = $this->globalService->getStorage($mountId); } catch (NotFoundException $e) { $output->writeln('Mount with id "' . $mountId . ' not found, check "occ files_external:list" to get available mounts"'); return Http::STATUS_NOT_FOUND; } $this->updateStorageStatus($mount, $configInput, $output); $this->writeArrayInOutputFormat($input, $output, [ 'status' => StorageNotAvailableException::getStateCodeName($mount->getStatus()), 'code' => $mount->getStatus(), 'message' => $mount->getStatusMessage() ]); return self::SUCCESS; } private function manipulateStorageConfig(StorageConfig $storage): void { $authMechanism = $storage->getAuthMechanism(); $authMechanism->manipulateStorageConfig($storage); $backend = $storage->getBackend(); $backend->manipulateStorageConfig($storage); } private function updateStorageStatus(StorageConfig &$storage, $configInput, OutputInterface $output): void { try { try { $this->manipulateStorageConfig($storage); } catch (InsufficientDataForMeaningfulAnswerException $e) { if (count($configInput) === 0) { // extra config options might solve the error throw $e; } } foreach ($configInput as $configOption) { if (!strpos($configOption, '=')) { $output->writeln('Invalid mount configuration option "' . $configOption . '"'); return; } [$key, $value] = explode('=', $configOption, 2); $storage->setBackendOption($key, $value); } $backend = $storage->getBackend(); // update status (can be time-consuming) $storage->setStatus( MountConfig::getBackendStatus( $backend->getStorageClass(), $storage->getBackendOptions(), false ) ); } catch (InsufficientDataForMeaningfulAnswerException $e) { $status = $e->getCode() ?: StorageNotAvailableException::STATUS_INDETERMINATE; $storage->setStatus( $status, $e->getMessage() ); } catch (StorageNotAvailableException $e) { $storage->setStatus( $e->getCode(), $e->getMessage() ); } catch (\Exception $e) { // FIXME: convert storage exceptions to StorageNotAvailableException $storage->setStatus( StorageNotAvailableException::STATUS_ERROR, get_class($e) . ': ' . $e->getMessage() ); } } }