Skip to content

feat(mount-provider): implement IPartialMountProvider#2378

Open
cristianscheid wants to merge 3 commits intomasterfrom
feat/2308/partial-mount-provider
Open

feat(mount-provider): implement IPartialMountProvider#2378
cristianscheid wants to merge 3 commits intomasterfrom
feat/2308/partial-mount-provider

Conversation

@cristianscheid
Copy link
Copy Markdown
Contributor

@cristianscheid cristianscheid commented Feb 27, 2026

Summary

Implemented IPartialMountProvider in CircleMountProvider by adding getMountsForPath() and added limitToMountpoint() to CoreQueryBuilder to support filtering.

Testing

To test this implementation, I did the following:

  • Temporarily commented out the if (!$this->configService->isLocalInstance($event->getOrigin())) condition in lib/FederatedItems/Files/FileShare::manage() to allow mount entries to be created locally
  • Created teams mock_team_1, mock_team_2 and mock_team_3
  • Created folders mock_folder_1, mock_folder_2 and mock_folder_3 and shared with their respective folders (mock_team_1, mock_team_2 and mock_team_3)
  • Temporarily commented out the early return in lib/AppInfo/Application::registerMountProvider() to force registration of CircleMountProvider regardless of GlobalScale availability
  • Using Xdebug with a breakpoint on circles/lib/MountManager/CircleMountProvider::getMountsForUser(), accessed nextcloud.local/index.php/apps/dashboard/, triggering the getMountsForUser() method
  • Instead of running the regular method flow, I created some mock params and called getMountsForPath() directly:
$makeMountArg = function(string $path) use ($user): \OCP\Files\Config\MountProviderArgs {
	$mountInfo = new class($user, $path) implements \OCP\Files\Config\ICachedMountInfo {
		public function __construct(private \OCP\IUser $user, private string $path) {}
		public function getUser(): \OCP\IUser { return $this->user; }
		public function getMountPoint(): string { return '/' . $this->user->getUID() . '/files/' . $this->path; }
		public function getStorageId(): int { return 0; }
		public function getRootId(): int { return 0; }
		public function getMountPointNode(): ?\OCP\Files\Node { return null; }
		public function getMountId(): ?int { return null; }
		public function getRootInternalPath(): string { return ''; }
		public function getMountProvider(): string { return ''; }
		public function getKey(): string { return ''; }
	};
	return new \OCP\Files\Config\MountProviderArgs(
		$mountInfo,
		new \OC\Files\Cache\CacheEntry([])
	);
};

$this->getMountsForPath(
	'/' . $user->getUID() . '/files/mock_folder',
	false,
	[
		$makeMountArg('mock_folder_1'),
		$makeMountArg('mock_folder_2'),
		$makeMountArg('another_folder'),
	],
	$loader
);

Results

  • Path filtering worked correctly when forChildren was set to false. With multiple folders on my setup (mock_team_1, mock_team_2 and mock_team_3), in the test above only the requested mounts that exist in the DB were returned for the given paths when calling getForUser() inside getMountsForPath(), confirming that limitToMountpoints() is filtering correctly at the database level.
  • forChildren did not work as expected when set to true. During testing, circles always stored mountpoints relatively. For example, sharing a folder created inside mock_folder generated a circles_mount entry with mountpoint /mock_subfolder instead of /mock_folder/mock_subfolder. As a result, the LIKE '/mock_folder/%' filter used when forChildren is true will not match these entries.
  • During testing, generateCircleMount() threw an exception in both the original getMountsForUser() and on new method getMountsForPath(). I believe this happened because the mount entries were artificially created by bypassing the remote instance check in FileShare::manage(), resulting in incomplete data compared to what would be present in a real GlobalScale environment.

Checklist

AI (if applicable)

  • The content of this PR was partly or fully generated using AI

Comment thread lib/MountManager/CircleMountProvider.php Outdated
Comment thread lib/MountManager/CircleMountProvider.php Outdated
@cristianscheid
Copy link
Copy Markdown
Contributor Author

@provokateurin I've addressed your review comments and updated the PR description with new testing instructions. Thanks!

Comment thread lib/Db/CoreQueryBuilder.php Outdated
Comment thread lib/Db/CoreQueryBuilder.php
Comment thread lib/Db/CoreQueryBuilder.php Outdated
Comment thread lib/Db/MountRequest.php Outdated
Comment thread lib/MountManager/CircleMountProvider.php Outdated
Comment thread lib/MountManager/CircleMountProvider.php
Comment thread lib/MountManager/CircleMountProvider.php Outdated
Signed-off-by: Cristian Scheid <cristianscheid@gmail.com>
…single query

Signed-off-by: Cristian Scheid <cristianscheid@gmail.com>
…s function

Signed-off-by: Cristian Scheid <cristianscheid@gmail.com>
@cristianscheid cristianscheid force-pushed the feat/2308/partial-mount-provider branch from a1632ed to ce45026 Compare April 2, 2026 18:53
@cristianscheid
Copy link
Copy Markdown
Contributor Author

@provokateurin @salmart-dev I've adjusted the PR after your suggestions. Would appreciate another review when you have a chance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Implement the new partial mount provider API

3 participants