Skip to content

feat(linux/vfs): integrate openvfs linux virtual files plugin - #10635

Open
mgallien wants to merge 12 commits into
masterfrom
feature/integrateOpenVfsPlugin
Open

mgallien wants to merge 12 commits into
masterfrom
feature/integrateOpenVfsPlugin

Conversation

@mgallien

Copy link
Copy Markdown
Collaborator

Resolves

#

Summary

TODO

  • ...

Checklist

AI (if applicable)

@mgallien

Copy link
Copy Markdown
Collaborator Author

currently able to complete the initial synchronization
missing is proper communication between the openvfs fuse daemon and the desktop files client
will need investigation

@mgallien
mgallien force-pushed the feature/integrateOpenVfsPlugin branch from 5cc28ff to aab773f Compare August 27, 2026 08:35
@mgallien

Copy link
Copy Markdown
Collaborator Author

Current UI on linux to decide what type of synchronization the user wants to enable
image

@kra-mo We would want to offer an easy way to test the linux virtual files plug-in while recommending people to not use for production use (until it is ready for that)
any idea how to tune the UI to achieve that ?
I understand that this may not be easy to do 😄
I would still like to have an easy way of discovering the new feature (currently I modified the code as if the plug-in should be the default as seen in the screenshot)
previous experimental plug-in needed to modify the configuration file manually

@kra-mo

kra-mo commented Aug 27, 2026

Copy link
Copy Markdown
Member

@mgallien I think being straightforward with the text is probably the best idea. For example:

Virtual files (beta)
Download files on-demand. This feature is in an early preview. Recommended only with proper backups.

And don't have it be the default selection.

@mgallien
mgallien marked this pull request as ready for review August 28, 2026 09:54
@mgallien
mgallien force-pushed the feature/integrateOpenVfsPlugin branch from bbb62b9 to af01969 Compare August 28, 2026 09:55
@mgallien

Copy link
Copy Markdown
Collaborator Author

I need to implement the suggestion for the selection of the synchronization types
I have now working hydration
so this is ready for testing
the disclaimer is that there is no guarantee, so feedback is very much welcome but be careful with your data

@mgallien

Copy link
Copy Markdown
Collaborator Author

there is a build and runtime dependency on https://github.com/opencloud-eu/openvfs

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Clang-Tidy found issue(s) with the introduced code (57/63)

Comment thread src/common/vfs.h Outdated
*/
bool multipleAccountsRegistered = false;

const FileSystem::Path &root() const;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ modernize-use-nodiscard ⚠️
function root should be marked [[nodiscard]]

Suggested change
const FileSystem::Path &root() const;
[[nodiscard]] const FileSystem::Path &root() const;

Comment thread src/libsync/syncfileitem.h Outdated
};
FolderQuota _folderQuota;

QString localName() const

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ modernize-use-nodiscard ⚠️
function localName should be marked [[nodiscard]]

Suggested change
QString localName() const
[[nodiscard]] QString localName() const

Comment thread src/common/path.h Outdated
*/
static Path relative(QAnyStringView path);

const std::filesystem::path &get() const { return _path; }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ modernize-use-nodiscard ⚠️
function get should be marked [[nodiscard]]

Suggested change
const std::filesystem::path &get() const { return _path; }
[[nodiscard]] const std::filesystem::path &get() const { return _path; }

Comment thread src/common/vfs.h Outdated
*/
bool multipleAccountsRegistered = false;

const FileSystem::Path &root() const;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ modernize-use-nodiscard ⚠️
function root should be marked [[nodiscard]]

Suggested change
const FileSystem::Path &root() const;
[[nodiscard]] const FileSystem::Path &root() const;

Comment thread src/libsync/syncfileitem.h Outdated
};
FolderQuota _folderQuota;

QString localName() const

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ modernize-use-nodiscard ⚠️
function localName should be marked [[nodiscard]]

Suggested change
QString localName() const
[[nodiscard]] QString localName() const

Comment thread src/common/path.h Outdated
*/
static Path relative(QAnyStringView path);

const std::filesystem::path &get() const { return _path; }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ modernize-use-nodiscard ⚠️
function get should be marked [[nodiscard]]

Suggested change
const std::filesystem::path &get() const { return _path; }
[[nodiscard]] const std::filesystem::path &get() const { return _path; }

Comment thread src/common/vfs.h Outdated
*/
bool multipleAccountsRegistered = false;

const FileSystem::Path &root() const;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ modernize-use-nodiscard ⚠️
function root should be marked [[nodiscard]]

Suggested change
const FileSystem::Path &root() const;
[[nodiscard]] const FileSystem::Path &root() const;

Comment thread src/libsync/syncfileitem.h Outdated
};
FolderQuota _folderQuota;

QString localName() const

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ modernize-use-nodiscard ⚠️
function localName should be marked [[nodiscard]]

Suggested change
QString localName() const
[[nodiscard]] QString localName() const

Comment thread src/common/path.h Outdated
*/
static Path relative(QAnyStringView path);

const std::filesystem::path &get() const { return _path; }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ modernize-use-nodiscard ⚠️
function get should be marked [[nodiscard]]

Suggested change
const std::filesystem::path &get() const { return _path; }
[[nodiscard]] const std::filesystem::path &get() const { return _path; }

Comment thread src/common/vfs.h Outdated
*/
bool multipleAccountsRegistered = false;

const FileSystem::Path &root() const;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ modernize-use-nodiscard ⚠️
function root should be marked [[nodiscard]]

Suggested change
const FileSystem::Path &root() const;
[[nodiscard]] const FileSystem::Path &root() const;

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Clang-Tidy found issue(s) with the introduced code (58/63)

Comment thread src/libsync/syncfileitem.h Outdated
Comment thread src/libsync/syncfileitem.h Outdated
Comment thread src/common/path.h Outdated
Comment thread src/common/vfs.h Outdated
Comment thread src/libsync/syncfileitem.h Outdated
Comment thread src/common/path.h Outdated
Comment thread src/common/vfs.h Outdated
Comment thread src/libsync/syncfileitem.h Outdated
Comment thread src/common/path.h Outdated
Comment thread src/common/vfs.h Outdated

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Clang-Tidy found issue(s) with the introduced code (59/63)

Comment thread src/libsync/syncfileitem.h Outdated
Comment thread src/common/path.h Outdated
Comment thread src/common/vfs.h Outdated
Comment thread src/libsync/syncfileitem.h Outdated
Comment thread src/common/path.h Outdated
Comment thread src/common/vfs.h Outdated
Comment thread src/libsync/syncfileitem.h Outdated
Comment thread src/common/path.h Outdated
Comment thread src/common/vfs.h Outdated
Comment thread src/libsync/syncfileitem.h Outdated

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Clang-Tidy found issue(s) with the introduced code (60/63)

Comment thread src/common/path.h Outdated
Comment thread src/common/vfs.h Outdated
Comment thread src/libsync/syncfileitem.h Outdated
Comment thread src/common/path.h Outdated
Comment thread src/common/vfs.h Outdated
Comment thread src/libsync/syncfileitem.h Outdated
Comment thread src/libsync/syncfileitem.h Outdated
Comment thread src/common/path.h Outdated
Comment thread src/common/vfs.h Outdated
Comment thread src/libsync/syncfileitem.h Outdated

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Clang-Tidy found issue(s) with the introduced code (61/63)

Comment thread src/common/path.h Outdated
Comment thread src/common/vfs.h Outdated
Comment thread src/libsync/syncfileitem.h Outdated
Comment thread src/common/path.h Outdated
Comment thread src/common/vfs.h Outdated
Comment thread src/libsync/syncfileitem.h Outdated
Comment thread src/common/path.h Outdated
Comment thread src/common/vfs.h Outdated
Comment thread src/libsync/syncfileitem.h Outdated
Comment thread src/common/path.h Outdated

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Clang-Tidy found issue(s) with the introduced code (62/63)

Comment thread src/common/vfs.h Outdated
Comment thread src/libsync/syncfileitem.h Outdated
Comment thread src/common/path.h Outdated
Comment thread src/common/vfs.h Outdated
Comment thread src/common/path.h Outdated
Comment thread src/common/vfs.h Outdated
Comment thread src/libsync/syncfileitem.h Outdated
Comment thread src/libsync/syncfileitem.h Outdated
Comment thread src/common/path.h Outdated
Comment thread src/common/vfs.h Outdated

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Clang-Tidy found issue(s) with the introduced code (63/63)

Comment thread src/libsync/syncfileitem.h Outdated
Comment thread src/common/path.h Outdated
Comment thread src/common/vfs.h Outdated
Comment thread src/libsync/syncfileitem.h Outdated
@mgallien
mgallien dismissed github-actions[bot]’s stale review September 9, 2026 20:26

not sure why it does that

@mgallien
mgallien force-pushed the feature/integrateOpenVfsPlugin branch from bda0c3a to c180e70 Compare September 9, 2026 20:39
@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Artifact containing the Flatpak bundle: com.nextcloud.desktopclient.nextcloud.flatpak.zip

Digest: sha256:22411da8d96a8230790ef49a866e986ddc31bfc70789d4769f0d9ace618ee5a1

To test this change/fix you can download the above artifact file, unzip it, and install the bundle with:
flatpak install --user com.nextcloud.desktopclient.nextcloud.flatpak

Please make sure to quit your existing Nextcloud app and backup your data.

mgallien and others added 12 commits September 14, 2026 09:37
Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
we need to store and restore the account UUID that is used to identify
the synchronization folder

that will enable connection again to the folder when restarting the
client

Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
we want to offer an easy way to test the linux on-demand (virtula files)
feature

we want to still select the classical sync by default and warn users of
virtual files to be cautious with it

Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
Assisted-by: ClaudeCode:claude-sonnet-5
Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
should enable to build flatpak packages directly from desktop repository

modify the build manifest to enable the new openvfs virtual files
feature

Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
@mgallien
mgallien force-pushed the feature/integrateOpenVfsPlugin branch from c180e70 to 60e2513 Compare September 14, 2026 07:38
@github-actions

Copy link
Copy Markdown
Contributor

Artifact containing the AppImage: nextcloud-appimage-pr-10635.zip

Digest: sha256:836105d05c3356c2c536a7de96d234521223768db1f01c8509f8049dcc4eabd4

To test this change/fix you can download the above artifact file, unzip it, and run it.

Please make sure to quit your existing Nextcloud app and backup your data.

Comment thread src/libsync/CMakeLists.txt
Comment thread src/libsync/logger.cpp
Comment thread src/libsync/hydrationjob.cpp
Comment on lines +608 to +626
// LocalInfo OpenVFS::statTypeVirtualFile(const std::filesystem::directory_entry &path, ItemType type)
// {
// if (type == ItemTypeFile) {
// const auto attribs = placeHolderAttributes(path.path());
// if (attribs.state == ::OpenVFS::Constants::States::DeHydrated) {
// type = ItemTypeVirtualFile;
// if (attribs.pinState == convertPinState(PinState::AlwaysLocal)) {
// type = ItemTypeVirtualFileDownload;
// }
// } else {
// if (attribs.pinState == convertPinState(PinState::OnlineOnly)) {
// type = ItemTypeVirtualFileDehydration;
// }
// }
// }
// qCDebug(lcOpenVFS) << path.path().native() << Utility::enumToString(type);
// return LocalInfo(path, type);
// }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// LocalInfo OpenVFS::statTypeVirtualFile(const std::filesystem::directory_entry &path, ItemType type)
// {
// if (type == ItemTypeFile) {
// const auto attribs = placeHolderAttributes(path.path());
// if (attribs.state == ::OpenVFS::Constants::States::DeHydrated) {
// type = ItemTypeVirtualFile;
// if (attribs.pinState == convertPinState(PinState::AlwaysLocal)) {
// type = ItemTypeVirtualFileDownload;
// }
// } else {
// if (attribs.pinState == convertPinState(PinState::OnlineOnly)) {
// type = ItemTypeVirtualFileDehydration;
// }
// }
// }
// qCDebug(lcOpenVFS) << path.path().native() << Utility::enumToString(type);
// return LocalInfo(path, type);
// }

Comment on lines +576 to +578
if (stat->type == ItemTypeDirectory) {
return false;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this catch virtual directories early as well?

Suggested change
if (stat->type == ItemTypeDirectory) {
return false;
}
if (stat->type == ItemTypeDirectory || stat->type == ItemTypeVirtualDirectory) {
return false;
}

that would be covered by the if (stat->type == ItemTypeFile) below

const auto owner = xattrOwnerString(params.account->uuid()).toStdString();
if (const auto info = ::OpenVFS::Registration::registerFilesystem(std::filesystem::path{params.filesystemPath.toStdWString()}, owner); !info) {
if (info.owner() != owner) {
Q_EMIT error(tr("Unable to claim the sync root for files on demand, the folder is already claimed by %1").arg(info.owner()));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Q_EMIT error(tr("Unable to claim the sync root for files on demand, the folder is already claimed by %1").arg(info.owner()));
//: %1: system user name who is the owner of the sync root directory
Q_EMIT error(tr("Unable to claim the sync root for files on demand, the folder is already claimed by %1").arg(info.owner()));

Comment on lines +58 to +63
// if (OCC::Utility::runningInAppImage()) {
// auto appimagePath = OCC::FileSystem::Path(qApp->applicationDirPath()) / "../etc/xdg/openvfs/config.json";
// if (appimagePath.exists()) {
// return appimagePath;
// }
// }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this not necessary?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will double check

PUBLIC
OpenVFS::LibOpenVFS
)
endif()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does libsync really need to link to OpenVFS? The appimage build script now includes the --library=/root/linux-gcc-x86_64/lib64/libopenvfs.so option, maybe this change here can be omitted

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no
without that, the plugin loader is not finding the libopenvfs.so needed dependency
do not ask me why the loader behave that way inside the AppImage, I did not understand it

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
9.6% Coverage on New Code (required ≥ 80%)
53 New Code Smells (required ≤ 0)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

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

Projects

Status: NC35

Development

Successfully merging this pull request may close these issues.

5 participants