Merge pull request #14416 from owncloud/setup-command

Setup command
remotes/origin/log-external-deletes
Thomas Müller 2015-02-23 22:41:10 +07:00
commit e87ada86d1
11 changed files with 223 additions and 76 deletions

@ -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) {

@ -0,0 +1,129 @@
<?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) {
if (is_array($error)) {
$output->writeln('<error>' . (string)$error['error'] . '</error>');
$output->writeln('<info> -> ' . (string)$error['hint'] . '</info>');
} else {
$output->writeln('<error>' . (string)$error . '</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;
}
}

@ -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()));
}

@ -75,7 +75,7 @@ class Controller {
if(isset($post['install']) AND $post['install']=='true') {
// We have to launch the installation process :
$e = \OC_Setup::install($post);
$e = \OC\Setup::install($post);
$errors = array('errors' => $e);
if(count($e) > 0) {
@ -145,7 +145,7 @@ class Controller {
* in case of errors/warnings
*/
public function getSystemInfo() {
$setup = new \OC_Setup($this->config);
$setup = new \OC\Setup($this->config);
$databases = $setup->getSupportedDatabases();
$dataDir = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT.'/data');
@ -159,7 +159,7 @@ class Controller {
$htAccessWorking = true;
if (is_dir($dataDir) && is_writable($dataDir)) {
// Protect data directory here, so we can test if the protection is working
\OC_Setup::protectDataDirectory();
\OC\Setup::protectDataDirectory();
try {
$htAccessWorking = \OC_Util::isHtaccessWorking();

@ -152,18 +152,22 @@ class OC {
}
}
if (substr($scriptName, 0 - strlen(OC::$SUBURI)) === OC::$SUBURI) {
OC::$WEBROOT = substr($scriptName, 0, 0 - strlen(OC::$SUBURI));
if (OC::$CLI) {
OC::$WEBROOT = OC_Config::getValue('overwritewebroot', '');
} else {
if (substr($scriptName, 0 - strlen(OC::$SUBURI)) === OC::$SUBURI) {
OC::$WEBROOT = substr($scriptName, 0, 0 - strlen(OC::$SUBURI));
if (OC::$WEBROOT != '' && OC::$WEBROOT[0] !== '/') {
OC::$WEBROOT = '/' . OC::$WEBROOT;
if (OC::$WEBROOT != '' && OC::$WEBROOT[0] !== '/') {
OC::$WEBROOT = '/' . OC::$WEBROOT;
}
} else {
// The scriptName is not ending with OC::$SUBURI
// This most likely means that we are calling from CLI.
// However some cron jobs still need to generate
// a web URL, so we use overwritewebroot as a fallback.
OC::$WEBROOT = OC_Config::getValue('overwritewebroot', '');
}
} else {
// The scriptName is not ending with OC::$SUBURI
// This most likely means that we are calling from CLI.
// However some cron jobs still need to generate
// a web URL, so we use overwritewebroot as a fallback.
OC::$WEBROOT = OC_Config::getValue('overwritewebroot', '');
}
// search the 3rdparty folder
@ -257,6 +261,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) {
@ -513,6 +520,8 @@ class OC {
spl_autoload_register(array(self::$loader, 'load'));
$loaderEnd = microtime(true);
self::$CLI = (php_sapi_name() == 'cli');
self::initPaths();
// setup 3rdparty autoloader
@ -538,7 +547,6 @@ class OC {
if (defined('DEBUG') && DEBUG) {
ini_set('display_errors', 1);
}
self::$CLI = (php_sapi_name() == 'cli');
date_default_timezone_set('UTC');
ini_set('arg_separator.output', '&amp;');

@ -625,7 +625,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* @return string Server host
*/
public function getInsecureServerHost() {
$host = null;
$host = 'localhost';
if (isset($this->server['HTTP_X_FORWARDED_HOST'])) {
if (strpos($this->server['HTTP_X_FORWARDED_HOST'], ',') !== false) {
$parts = explode(',', $this->server['HTTP_X_FORWARDED_HOST']);

@ -33,9 +33,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OC;
use Exception;
use OC_L10N;
use OCP\IConfig;
class OC_Setup {
class Setup {
/** @var IConfig */
protected $config;
@ -156,7 +161,7 @@ class OC_Setup {
$error[] = $l->t('Set an admin password.');
}
if(empty($options['directory'])) {
$options['directory'] = OC::$SERVERROOT."/data";
$options['directory'] = \OC::$SERVERROOT."/data";
}
if (!isset(self::$dbSetupClasses[$dbType])) {
@ -194,7 +199,7 @@ class OC_Setup {
$trustedDomains = [$request->getInsecureServerHost()];
}
if (OC_Util::runningOnWindows()) {
if (\OC_Util::runningOnWindows()) {
$dataDir = rtrim(realpath($dataDir), '\\');
}
@ -214,9 +219,9 @@ class OC_Setup {
'secret' => $secret,
'trusted_domains' => $trustedDomains,
'datadirectory' => $dataDir,
'overwrite.cli.url' => $request->getServerProtocol() . '://' . $request->getInsecureServerHost() . OC::$WEBROOT,
'overwrite.cli.url' => $request->getServerProtocol() . '://' . $request->getInsecureServerHost() . \OC::$WEBROOT,
'dbtype' => $dbType,
'version' => implode('.', OC_Util::getVersion()),
'version' => implode('.', \OC_Util::getVersion()),
]);
try {
@ -237,27 +242,31 @@ class OC_Setup {
}
//create the user and group
$user = null;
try {
OC_User::createUser($username, $password);
$user = \OC::$server->getUserManager()->createUser($username, $password);
if (!$user) {
$error[] = "User <$username> could not be created.";
}
} catch(Exception $exception) {
$error[] = $exception->getMessage();
}
if(count($error) == 0) {
$appConfig = \OC::$server->getAppConfig();
$appConfig->setValue('core', 'installedat', microtime(true));
$appConfig->setValue('core', 'lastupdatedat', microtime(true));
$config = \OC::$server->getConfig();
$config->setAppValue('core', 'installedat', microtime(true));
$config->setAppValue('core', 'lastupdatedat', microtime(true));
OC_Group::createGroup('admin');
OC_Group::addToGroup($username, 'admin');
OC_User::login($username, $password);
$group =\OC::$server->getGroupManager()->createGroup('admin');
$group->addUser($user);
\OC_User::login($username, $password);
//guess what this does
OC_Installer::installShippedApps();
\OC_Installer::installShippedApps();
// create empty file in data dir, so we can later find
// out that this is indeed an ownCloud data directory
file_put_contents(OC_Config::getValue('datadirectory', OC::$SERVERROOT.'/data').'/.ocdata', '');
file_put_contents($config->getSystemValue('datadirectory', \OC::$SERVERROOT.'/data').'/.ocdata', '');
// Update htaccess files for apache hosts
if (isset($_SERVER['SERVER_SOFTWARE']) && strstr($_SERVER['SERVER_SOFTWARE'], 'Apache')) {
@ -266,7 +275,7 @@ class OC_Setup {
}
//and we are done
OC_Config::setValue('installed', true);
$config->setSystemValue('installed', true);
}
return $error;
@ -276,7 +285,7 @@ class OC_Setup {
* @return string Absolute path to htaccess
*/
private function pathToHtaccess() {
return OC::$SERVERROOT.'/.htaccess';
return \OC::$SERVERROOT.'/.htaccess';
}
/**
@ -300,14 +309,14 @@ class OC_Setup {
* @throws \OC\HintException If .htaccess does not include the current version
*/
public static function updateHtaccess() {
$setupHelper = new OC_Setup(\OC::$server->getConfig());
$setupHelper = new \OC\Setup(\OC::$server->getConfig());
if(!$setupHelper->isCurrentHtaccess()) {
throw new \OC\HintException('.htaccess file has the wrong version. Please upload the correct version. Maybe you forgot to replace it after updating?');
}
$content = "\n";
$content.= "ErrorDocument 403 ".OC::$WEBROOT."/core/templates/403.php\n";//custom 403 error page
$content.= "ErrorDocument 404 ".OC::$WEBROOT."/core/templates/404.php";//custom 404 error page
$content.= "ErrorDocument 403 ".\OC::$WEBROOT."/core/templates/403.php\n";//custom 403 error page
$content.= "ErrorDocument 404 ".\OC::$WEBROOT."/core/templates/404.php";//custom 404 error page
@file_put_contents($setupHelper->pathToHtaccess(), $content, FILE_APPEND); //suppress errors in case we don't have permissions for it
}
@ -326,7 +335,7 @@ class OC_Setup {
$content.= "</ifModule>\n\n";
$content.= "# section for Apache 2.2 and 2.4\n";
$content.= "IndexIgnore *\n";
file_put_contents(OC_Config::getValue('datadirectory', OC::$SERVERROOT.'/data').'/.htaccess', $content);
file_put_contents(OC_Config::getValue('datadirectory', OC::$SERVERROOT.'/data').'/index.html', '');
file_put_contents(\OC_Config::getValue('datadirectory', \OC::$SERVERROOT.'/data').'/.htaccess', $content);
file_put_contents(\OC_Config::getValue('datadirectory', \OC::$SERVERROOT.'/data').'/index.html', '');
}
}

@ -211,7 +211,7 @@ class Updater extends BasicEmitter {
// Update htaccess files for apache hosts
if (isset($_SERVER['SERVER_SOFTWARE']) && strstr($_SERVER['SERVER_SOFTWARE'], 'Apache')) {
try {
\OC_Setup::updateHtaccess();
\OC\Setup::updateHtaccess();
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}

@ -187,7 +187,7 @@ class OC_User {
* itself, not in its subclasses.
*
* Allowed characters in the username are: "a-z", "A-Z", "0-9" and "_.@-"
* @deprecated Use \OC::$server->getUserManager->createUser($uid, $password)
* @deprecated Use \OC::$server->getUserManager()->createUser($uid, $password)
*/
public static function createUser($uid, $password) {
return self::getManager()->createUser($uid, $password);

@ -550,7 +550,7 @@ class OC_Util {
}
$webServerRestart = false;
$setup = new OC_Setup($config);
$setup = new OC\Setup($config);
$availableDatabases = $setup->getSupportedDatabases();
if (empty($availableDatabases)) {
$errors[] = array(

@ -12,14 +12,14 @@ class Test_OC_Setup extends \Test\TestCase {
/** @var IConfig */
protected $config;
/** @var \OC_Setup */
/** @var \OC\Setup */
protected $setupClass;
protected function setUp() {
parent::setUp();
$this->config = $this->getMock('\OCP\IConfig');
$this->setupClass = $this->getMock('\OC_Setup', ['class_exists', 'is_callable'], [$this->config]);
$this->setupClass = $this->getMock('\OC\Setup', ['class_exists', 'is_callable'], [$this->config]);
}
public function testGetSupportedDatabasesWithOneWorking() {
@ -115,4 +115,4 @@ class Test_OC_Setup extends \Test\TestCase {
);
$this->assertTrue($result);
}
}
}