From bcd10d3dc52f2a6fa187895526eac05b48ddb7f9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thomas=20M=C3=BCller?= <thomas.mueller@tmit.eu>
Date: Sat, 21 Feb 2015 20:52:32 +0100
Subject: [PATCH] implement command maintenance:install

---
 console.php                          |  32 +++----
 core/command/maintenance/install.php | 124 +++++++++++++++++++++++++++
 core/register_command.php            |  37 ++++----
 lib/base.php                         |   3 +
 4 files changed, 162 insertions(+), 34 deletions(-)
 create mode 100644 core/command/maintenance/install.php

diff --git a/console.php b/console.php
index 9b2475aa038..43f0563dc74 100644
--- a/console.php
+++ b/console.php
@@ -22,18 +22,14 @@
  */
 use Symfony\Component\Console\Application;
 
+define('OC_CONSOLE', 1);
+
 try {
 	require_once 'lib/base.php';
 
 	// set to run indefinitely if needed
 	set_time_limit(0);
 
-	// Don't do anything if ownCloud has not been installed yet
-	if (!\OC::$server->getConfig()->getSystemValue('installed', false)) {
-		echo "Console can only be used once ownCloud has been installed" . PHP_EOL;
-		exit(0);
-	}
-
 	if (!OC::$CLI) {
 		echo "This script can be run from the command line only" . PHP_EOL;
 		exit(0);
@@ -54,23 +50,23 @@ try {
 		}
 	}
 
-	// only load apps if no update is due,
-	// else only core commands will be available
-	if (!\OCP\Util::needUpgrade()) {
-		// load all apps to get all api routes properly setup
-		OC_App::loadApps();
-	}
-
 	$defaults = new OC_Defaults;
 	$application = new Application($defaults->getName(), \OC_Util::getVersionString());
 	require_once 'core/register_command.php';
-	if (!\OCP\Util::needUpgrade()) {
-		foreach(OC_App::getAllApps() as $app) {
-			$file = OC_App::getAppPath($app).'/appinfo/register_command.php';
-			if(file_exists($file)) {
-				require $file;
+	if (\OC::$server->getConfig()->getSystemValue('installed', false)) {
+		if (!\OCP\Util::needUpgrade()) {
+			OC_App::loadApps();
+			foreach (OC_App::getAllApps() as $app) {
+				$file = OC_App::getAppPath($app) . '/appinfo/register_command.php';
+				if (file_exists($file)) {
+					require $file;
+				}
 			}
+		} else {
+			echo "ownCloud or one of the apps require upgrade - only a limited number of commands are available" . PHP_EOL;
 		}
+	} else {
+		echo "ownCloud is not installed - only a limited number of commands are available" . PHP_EOL;
 	}
 	$application->run();
 } catch (Exception $ex) {
diff --git a/core/command/maintenance/install.php b/core/command/maintenance/install.php
new file mode 100644
index 00000000000..38074adf11a
--- /dev/null
+++ b/core/command/maintenance/install.php
@@ -0,0 +1,124 @@
+<?php
+
+namespace OC\Core\Command\Maintenance;
+
+use InvalidArgumentException;
+use OCP\IConfig;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class Install extends Command {
+
+	/**
+	 * @var IConfig
+	 */
+	private $config;
+
+	public function __construct(IConfig $config) {
+		parent::__construct();
+		$this->config = $config;
+	}
+
+	protected function configure() {
+		$this
+			->setName('maintenance:install')
+			->setDescription('install ownCloud')
+			->addOption('database', null, InputOption::VALUE_REQUIRED, 'Supported database type', 'sqlite')
+			->addOption('database-name', null, InputOption::VALUE_REQUIRED, 'Name of the database')
+			->addOption('database-host', null, InputOption::VALUE_REQUIRED, 'Hostname of the database', 'localhost')
+			->addOption('database-user', null, InputOption::VALUE_REQUIRED, 'User name to connect to the database')
+			->addOption('database-pass', null, InputOption::VALUE_REQUIRED, 'Password of the database user')
+			->addOption('database-table-prefix', null, InputOption::VALUE_REQUIRED, 'Prefix for all tables', 'oc_')
+			->addOption('admin-user', null, InputOption::VALUE_REQUIRED, 'User name of the admin account', 'admin')
+			->addOption('admin-pass', null, InputOption::VALUE_REQUIRED, 'Password of the admin account')
+			->addOption('data-dir', null, InputOption::VALUE_REQUIRED, 'Path to data directory', \OC::$SERVERROOT."/data");
+	}
+
+	protected function execute(InputInterface $input, OutputInterface $output) {
+
+		$options = $this->validateInput($input, $output);
+
+		$errors = \OC\Setup::install($options);
+		if (count($errors) === 0) {
+			$output->writeln("ownCloud was successfully installed");
+			return 0;
+		}
+		foreach($errors as $error) {
+			$output->writeln((string)$error);
+		}
+
+		return 1;
+	}
+
+	/**
+	 * @param InputInterface $input
+	 * @param OutputInterface $output
+	 * @return array
+	 */
+	protected function validateInput(InputInterface $input, OutputInterface $output) {
+		$db = strtolower($input->getOption('database'));
+		$supportedDatabases = $this->config->getSystemValue('supportedDatabases', [
+			'sqlite',
+			'mysql',
+			'pgsql',
+			'oci',
+			'mssql'
+		]);
+
+		if (!in_array($db, $supportedDatabases)) {
+			throw new InvalidArgumentException("Database <$db> is not supported.");
+		}
+
+		$dbUser = $input->getOption('database-user');
+		$dbPass = $input->getOption('database-pass');
+		$dbName = $input->getOption('database-name');
+		$dbHost = $input->getOption('database-host');
+		$dbTablePrefix = $input->getOption('database-table-prefix');
+		$adminLogin = $input->getOption('admin-user');
+		$adminPassword = $input->getOption('admin-pass');
+		$dataDir = $input->getOption('data-dir');
+
+		if ($db !== 'sqlite') {
+			if (is_null($dbUser)) {
+				throw new InvalidArgumentException("Database user not provided.");
+			}
+			if (is_null($dbName)) {
+				throw new InvalidArgumentException("Database name not provided.");
+			}
+			if (is_null($dbPass)) {
+				/** @var $dialog \Symfony\Component\Console\Helper\DialogHelper */
+				$dialog = $this->getHelperSet()->get('dialog');
+				$dbPass = $dialog->askHiddenResponse(
+					$output,
+					"<question>What is the password to access the database with user <$dbUser>?</question>",
+					false
+				);
+			}
+		}
+
+		if (is_null($adminPassword)) {
+			/** @var $dialog \Symfony\Component\Console\Helper\DialogHelper */
+			$dialog = $this->getHelperSet()->get('dialog');
+			$adminPassword = $dialog->askHiddenResponse(
+				$output,
+				"<question>What is the password you like to use for the admin account <$adminLogin>?</question>",
+				false
+			);
+		}
+
+		$options = [
+			'dbtype' => $db,
+			'dbuser' => $dbUser,
+			'dbpass' => $dbPass,
+			'dbname' => $dbName,
+			'dbhost' => $dbHost,
+			'dbtableprefix' => $dbTablePrefix,
+			'adminlogin' => $adminLogin,
+			'adminpass' => $adminPassword,
+			'directory' => $dataDir
+		];
+		return $options;
+	}
+}
diff --git a/core/register_command.php b/core/register_command.php
index 4af423054d7..c62282c084c 100644
--- a/core/register_command.php
+++ b/core/register_command.php
@@ -24,23 +24,28 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>
  *
  */
-$repair = new \OC\Repair(\OC\Repair::getRepairSteps());
 
 /** @var $application Symfony\Component\Console\Application */
 $application->add(new OC\Core\Command\Status);
-$application->add(new OC\Core\Command\Db\GenerateChangeScript());
-$application->add(new OC\Core\Command\Db\ConvertType(\OC::$server->getConfig(), new \OC\DB\ConnectionFactory()));
-$application->add(new OC\Core\Command\Upgrade(\OC::$server->getConfig()));
-$application->add(new OC\Core\Command\Maintenance\SingleUser());
-$application->add(new OC\Core\Command\Maintenance\Mode(\OC::$server->getConfig()));
-$application->add(new OC\Core\Command\App\CheckCode());
-$application->add(new OC\Core\Command\App\Disable());
-$application->add(new OC\Core\Command\App\Enable());
-$application->add(new OC\Core\Command\App\ListApps());
-$application->add(new OC\Core\Command\Maintenance\Repair($repair, \OC::$server->getConfig()));
-$application->add(new OC\Core\Command\User\Report());
-$application->add(new OC\Core\Command\User\ResetPassword(\OC::$server->getUserManager()));
-$application->add(new OC\Core\Command\User\LastSeen());
-$application->add(new OC\Core\Command\User\Delete(\OC::$server->getUserManager()));
-$application->add(new OC\Core\Command\L10n\CreateJs());
 
+if (\OC::$server->getConfig()->getSystemValue('installed', false)) {
+	$repair = new \OC\Repair(\OC\Repair::getRepairSteps());
+
+	$application->add(new OC\Core\Command\Db\GenerateChangeScript());
+	$application->add(new OC\Core\Command\Db\ConvertType(\OC::$server->getConfig(), new \OC\DB\ConnectionFactory()));
+	$application->add(new OC\Core\Command\Upgrade(\OC::$server->getConfig()));
+	$application->add(new OC\Core\Command\Maintenance\SingleUser());
+	$application->add(new OC\Core\Command\Maintenance\Mode(\OC::$server->getConfig()));
+	$application->add(new OC\Core\Command\App\CheckCode());
+	$application->add(new OC\Core\Command\App\Disable());
+	$application->add(new OC\Core\Command\App\Enable());
+	$application->add(new OC\Core\Command\App\ListApps());
+	$application->add(new OC\Core\Command\Maintenance\Repair($repair, \OC::$server->getConfig()));
+	$application->add(new OC\Core\Command\User\Report());
+	$application->add(new OC\Core\Command\User\ResetPassword(\OC::$server->getUserManager()));
+	$application->add(new OC\Core\Command\User\LastSeen());
+	$application->add(new OC\Core\Command\User\Delete(\OC::$server->getUserManager()));
+	$application->add(new OC\Core\Command\L10n\CreateJs());
+} else {
+	$application->add(new OC\Core\Command\Maintenance\Install(\OC::$server->getConfig()));
+}
diff --git a/lib/base.php b/lib/base.php
index 3cf0fef2eda..6048df33f43 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -257,6 +257,9 @@ class OC {
 	}
 
 	public static function checkInstalled() {
+		if (defined('OC_CONSOLE')) {
+			return;
+		}
 		// Redirect to installer if not installed
 		if (!\OC::$server->getSystemConfig()->getValue('installed', false) && OC::$SUBURI != '/index.php') {
 			if (OC::$CLI) {
-- 
GitLab