use mount providers to setup home storages (#24567)

This commit is contained in:
Robin Appelman 2016-05-17 21:40:55 +02:00 committed by Thomas Müller
parent 7dbdf2f7e0
commit de5b7609f9
7 changed files with 230 additions and 36 deletions

View File

@ -24,6 +24,7 @@ namespace OC\Files\Config;
use OC\Hooks\Emitter;
use OC\Hooks\EmitterTrait;
use OCP\Files\Config\IHomeMountProvider;
use OCP\Files\Config\IMountProviderCollection;
use OCP\Files\Config\IMountProvider;
use OCP\Files\Config\IUserMountCache;
@ -34,6 +35,11 @@ use OCP\IUser;
class MountProviderCollection implements IMountProviderCollection, Emitter {
use EmitterTrait;
/**
* @var \OCP\Files\Config\IHomeMountProvider[]
*/
private $homeProviders = [];
/**
* @var \OCP\Files\Config\IMountProvider[]
*/
@ -77,6 +83,25 @@ class MountProviderCollection implements IMountProviderCollection, Emitter {
}, array());
}
/**
* Get the configured home mount for this user
*
* @param \OCP\IUser $user
* @return \OCP\Files\Mount\IMountPoint
* @since 9.1.0
*/
public function getHomeMountForUser(IUser $user) {
/** @var \OCP\Files\Config\IHomeMountProvider[] $providers */
$providers = array_reverse($this->homeProviders); // call the latest registered provider first to give apps an opportunity to overwrite builtin
foreach ($providers as $homeProvider) {
if ($mount = $homeProvider->getHomeMountForUser($user, $this->loader)) {
$mount->setMountPoint('/' . $user->getUID()); //make sure the mountpoint is what we expect
return $mount;
}
}
throw new \Exception('No home storage configured for user ' . $user);
}
/**
* Add a provider for mount points
*
@ -87,6 +112,17 @@ class MountProviderCollection implements IMountProviderCollection, Emitter {
$this->emit('\OC\Files\Config', 'registerMountProvider', [$provider]);
}
/**
* Add a provider for home mount points
*
* @param \OCP\Files\Config\IHomeMountProvider $provider
* @since 9.1.0
*/
public function registerHomeProvider(IHomeMountProvider $provider) {
$this->homeProviders[] = $provider;
$this->emit('\OC\Files\Config', 'registerHomeMountProvider', [$provider]);
}
/**
* Cache mounts for user
*

View File

@ -397,7 +397,6 @@ class Filesystem {
if (isset(self::$usersSetup[$user])) {
return;
}
$root = \OC_User::getHome($user);
$userManager = \OC::$server->getUserManager();
$userObject = $userManager->get($user);
@ -409,50 +408,26 @@ class Filesystem {
self::$usersSetup[$user] = true;
$homeStorage = \OC::$server->getConfig()->getSystemValue('objectstore');
if (!empty($homeStorage)) {
// sanity checks
if (empty($homeStorage['class'])) {
\OCP\Util::writeLog('files', 'No class given for objectstore', \OCP\Util::ERROR);
}
if (!isset($homeStorage['arguments'])) {
$homeStorage['arguments'] = array();
}
// instantiate object store implementation
$homeStorage['arguments']['objectstore'] = new $homeStorage['class']($homeStorage['arguments']);
// mount with home object store implementation
$homeStorage['class'] = '\OC\Files\ObjectStore\HomeObjectStoreStorage';
} else {
$homeStorage = array(
//default home storage configuration:
'class' => '\OC\Files\Storage\Home',
'arguments' => array()
);
}
$homeStorage['arguments']['user'] = $userObject;
// check for legacy home id (<= 5.0.12)
if (\OC\Files\Cache\Storage::exists('local::' . $root . '/')) {
$homeStorage['arguments']['legacy'] = true;
}
$mount = new MountPoint($homeStorage['class'], '/' . $user, $homeStorage['arguments'], self::getLoader());
self::getMountManager()->addMount($mount);
$home = \OC\Files\Filesystem::getStorage($user);
// Chance to mount for other storages
/** @var \OC\Files\Config\MountProviderCollection $mountConfigManager */
$mountConfigManager = \OC::$server->getMountProviderCollection();
// home mounts are handled seperate since we need to ensure this is mounted before we call the other mount providers
$homeMount = $mountConfigManager->getHomeMountForUser($userObject);
self::getMountManager()->addMount($homeMount);
\OC\Files\Filesystem::getStorage($user);
// Chance to mount for other storages
if ($userObject) {
$mounts = $mountConfigManager->getMountsForUser($userObject);
array_walk($mounts, array(self::$mounts, 'addMount'));
$mounts[] = $mount;
$mounts[] = $homeMount;
$mountConfigManager->registerMounts($userObject, $mounts);
}
self::listenForNewMountProviders($mountConfigManager, $userManager);
\OC_Hook::emit('OC_Filesystem', 'post_initMountPoints', array('user' => $user, 'user_dir' => $root));
\OC_Hook::emit('OC_Filesystem', 'post_initMountPoints', array('user' => $user));
}
/**

View File

@ -0,0 +1,46 @@
<?php
/**
* @author Robin Appelman <icewind@owncloud.com>
*
* @copyright Copyright (c) 2016, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OC\Files\Mount;
use OCP\Files\Config\IHomeMountProvider;
use OCP\Files\Storage\IStorageFactory;
use OCP\IUser;
/**
* Mount provider for regular posix home folders
*/
class LocalHomeMountProvider implements IHomeMountProvider {
/**
* Get the cache mount for a user
*
* @param IUser $user
* @param IStorageFactory $loader
* @return \OCP\Files\Mount\IMountPoint[]
*/
public function getHomeMountForUser(IUser $user, IStorageFactory $loader) {
$arguments = ['user' => $user];
if (\OC\Files\Cache\Storage::exists('local::' . $user->getHome() . '/')) {
$arguments['legacy'] = true;
}
return new MountPoint('\OC\Files\Storage\Home', '/' . $user->getUID(), $arguments, $loader);
}
}

View File

@ -0,0 +1,73 @@
<?php
/**
* @author Robin Appelman <icewind@owncloud.com>
*
* @copyright Copyright (c) 2016, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OC\Files\Mount;
use OCP\Files\Config\IHomeMountProvider;
use OCP\Files\Storage\IStorageFactory;
use OCP\IConfig;
use OCP\IUser;
/**
* Mount provider for object store home storages
*/
class ObjectHomeMountProvider implements IHomeMountProvider {
/**
* @var IConfig
*/
private $config;
/**
* ObjectStoreHomeMountProvider constructor.
*
* @param IConfig $config
*/
public function __construct(IConfig $config) {
$this->config = $config;
}
/**
* Get the cache mount for a user
*
* @param IUser $user
* @param IStorageFactory $loader
* @return \OCP\Files\Mount\IMountPoint[]
*/
public function getHomeMountForUser(IUser $user, IStorageFactory $loader) {
$config = $this->config->getSystemValue('objectstore');
if (!is_array($config)) {
return null; //fall back to local home provider
}
// sanity checks
if (empty($config['class'])) {
\OCP\Util::writeLog('files', 'No class given for objectstore', \OCP\Util::ERROR);
}
if (!isset($config['arguments'])) {
$config['arguments'] = [];
}
$config['arguments']['user'] = $user;
// instantiate object store implementation
$config['arguments']['objectstore'] = new $config['class']($config['arguments']);
return new MountPoint('\OC\Files\ObjectStore\HomeObjectStoreStorage', '/' . $user->getUID(), $config['arguments'], $loader);
}
}

View File

@ -49,6 +49,8 @@ use OC\Diagnostics\QueryLogger;
use OC\Files\Config\UserMountCache;
use OC\Files\Config\UserMountCacheListener;
use OC\Files\Mount\CacheMountProvider;
use OC\Files\Mount\LocalHomeMountProvider;
use OC\Files\Mount\ObjectHomeMountProvider;
use OC\Files\Node\HookConnector;
use OC\Files\Node\LazyRoot;
use OC\Files\Node\Root;
@ -479,6 +481,8 @@ class Server extends ServerContainer implements IServerContainer {
$config = $c->getConfig();
$manager->registerProvider(new CacheMountProvider($config));
$manager->registerHomeProvider(new LocalHomeMountProvider());
$manager->registerHomeProvider(new ObjectHomeMountProvider($config));
return $manager;
});

View File

@ -0,0 +1,43 @@
<?php
/**
* @author Morris Jobke <hey@morrisjobke.de>
* @author Robin Appelman <icewind@owncloud.com>
*
* @copyright Copyright (c) 2016, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OCP\Files\Config;
use OCP\Files\Storage\IStorageFactory;
use OCP\IUser;
/**
* Provides
*
* @since 9.1.0
*/
interface IHomeMountProvider {
/**
* Get all mountpoints applicable for the user
*
* @param \OCP\IUser $user
* @param \OCP\Files\Storage\IStorageFactory $loader
* @return \OCP\Files\Mount\IMountPoint|null
* @since 9.1.0
*/
public function getHomeMountForUser(IUser $user, IStorageFactory $loader);
}

View File

@ -39,6 +39,15 @@ interface IMountProviderCollection {
*/
public function getMountsForUser(IUser $user);
/**
* Get the configured home mount for this user
*
* @param \OCP\IUser $user
* @return \OCP\Files\Mount\IMountPoint
* @since 9.1.0
*/
public function getHomeMountForUser(IUser $user);
/**
* Add a provider for mount points
*
@ -47,6 +56,14 @@ interface IMountProviderCollection {
*/
public function registerProvider(IMountProvider $provider);
/**
* Add a provider for home mount points
*
* @param \OCP\Files\Config\IHomeMountProvider $provider
* @since 9.1.0
*/
public function registerHomeProvider(IHomeMountProvider $provider);
/**
* Get the mount cache which can be used to search for mounts without setting up the filesystem
*