configure meta-fuse to connect to meta-core

This commit is contained in:
Pierre
2026-01-25 22:02:49 +01:00
parent f62acdfdbf
commit 2c85b409b9
3 changed files with 69 additions and 14 deletions
+4 -4
View File
@@ -242,8 +242,8 @@ WEBDAV_USERNAME=metamesh # WebDAV username
WEBDAV_PASSWORD=metamesh # WebDAV password
WEBDAV_READONLY=true # Read-only mode
# meta-sort WebDAV Access (reading files from meta-sort)
META_SORT_WEBDAV_URL=http://meta-sort-dev/webdav # URL to access files via meta-sort's WebDAV
# meta-core WebDAV Access (reading files from meta-core)
META_CORE_WEBDAV_URL=http://meta-core/webdav # URL to access files via meta-core's WebDAV
# Enables access to SMB/rclone mounts
```
@@ -276,8 +276,8 @@ services:
- FILES_VOLUME=/files
- FUSE_MOUNT_POINT=/mnt/virtual
- REDIS_PREFIX=meta-sort:
# Optional: Read files via meta-sort WebDAV (enables SMB/rclone mount access)
- META_SORT_WEBDAV_URL=http://meta-sort/webdav
# Optional: Read files via meta-core WebDAV (enables SMB/rclone mount access)
- META_CORE_WEBDAV_URL=http://meta-core/webdav
```
## API Endpoints
+5 -5
View File
@@ -57,13 +57,13 @@ async function main(): Promise<void> {
vfsRefreshInterval: parseInt(process.env.VFS_REFRESH_INTERVAL ?? '30000', 10),
baseUrl: process.env.BASE_URL,
serviceVersion: process.env.SERVICE_VERSION ?? '1.0.0',
// WebDAV URL for meta-sort file access (e.g., http://meta-sort-dev/webdav)
metaSortWebdavUrl: process.env.META_SORT_WEBDAV_URL,
// WebDAV URL for meta-core file access (e.g., http://meta-core/webdav)
metaCoreWebdavUrl: process.env.META_CORE_WEBDAV_URL,
};
logger.info(`Config: META_CORE_PATH=${config.metaCorePath}, FILES_VOLUME=${config.filesPath}`);
if (config.metaSortWebdavUrl) {
logger.info(`WebDAV: Using meta-sort WebDAV at ${config.metaSortWebdavUrl}`);
if (config.metaCoreWebdavUrl) {
logger.info(`WebDAV: Using meta-core WebDAV at ${config.metaCoreWebdavUrl}`);
} else {
logger.info(`WebDAV: Not configured, FUSE driver will use local filesystem`);
}
@@ -125,7 +125,7 @@ async function main(): Promise<void> {
gid: parseInt(process.env.PGID ?? '1000', 10),
refreshInterval: config.vfsRefreshInterval,
configDir: process.env.CONFIG_DIR ?? '/meta-fuse/config',
webdavBaseUrl: config.metaSortWebdavUrl,
webdavBaseUrl: config.metaCoreWebdavUrl,
filesPath: config.filesPath,
});
@@ -221,7 +221,7 @@ export class VirtualFileSystem {
// Compute virtual path using rules or fallback
const virtualPath = this.computeVirtualPath(metadata, sourcePath);
if (virtualPath) {
this.addFile(virtualPath, metadata);
await this.addFile(virtualPath, metadata);
this.sourcePathToVirtualPath.set(sourcePath, virtualPath);
}
}
@@ -325,7 +325,7 @@ export class VirtualFileSystem {
}
// Add/update file
this.addFile(virtualPath, metadata);
await this.addFile(virtualPath, metadata);
this.sourcePathToVirtualPath.set(metadata.sourcePath, virtualPath);
logger.debug(`File ${action}ed: ${virtualPath}`);
@@ -334,7 +334,7 @@ export class VirtualFileSystem {
/**
* Add a file to the VFS
*/
private addFile(virtualPath: string, metadata: FileMetadata): void {
private async addFile(virtualPath: string, metadata: FileMetadata): Promise<void> {
virtualPath = this.normalizePath(virtualPath);
// Skip if file already exists at this path
@@ -363,8 +363,20 @@ export class VirtualFileSystem {
mtime = stats.mtime;
ctime = stats.ctime;
} catch {
logger.warn(`Cannot stat source file: ${metadata.sourcePath}`);
return;
// Local stat failed, try WebDAV if configured
if (this.config.webdavBaseUrl) {
const webdavStats = await this.statViaWebDAV(metadata.sourcePath);
if (webdavStats) {
size = webdavStats.size;
mtime = webdavStats.mtime || mtime;
} else {
logger.warn(`Cannot stat source file via WebDAV: ${metadata.sourcePath}`);
return;
}
} else {
logger.warn(`Cannot stat source file: ${metadata.sourcePath}`);
return;
}
}
}
@@ -392,6 +404,49 @@ export class VirtualFileSystem {
this.cachedStats.totalSize += size;
}
/**
* Get file stats via WebDAV HEAD request
*/
private async statViaWebDAV(sourcePath: string): Promise<{ size: number; mtime?: Date } | null> {
if (!this.config.webdavBaseUrl) {
return null;
}
try {
// Convert source path to WebDAV URL
let relativePath = sourcePath;
if (this.config.filesPath && sourcePath.startsWith(this.config.filesPath)) {
relativePath = sourcePath.slice(this.config.filesPath.length);
}
if (!relativePath.startsWith('/')) {
relativePath = '/' + relativePath;
}
// URL-encode path segments (but not slashes)
const encodedPath = relativePath.split('/').map(segment => encodeURIComponent(segment)).join('/');
const webdavUrl = this.config.webdavBaseUrl + encodedPath;
// Make HEAD request
const response = await fetch(webdavUrl, { method: 'HEAD' });
if (response.ok) {
const contentLength = response.headers.get('Content-Length');
const lastModified = response.headers.get('Last-Modified');
return {
size: contentLength ? parseInt(contentLength, 10) : 0,
mtime: lastModified ? new Date(lastModified) : undefined,
};
}
logger.debug(`WebDAV HEAD failed for ${webdavUrl}: ${response.status}`);
return null;
} catch (error: any) {
logger.debug(`WebDAV stat error for ${sourcePath}: ${error.message}`);
return null;
}
}
/**
* Remove a file from the VFS
*/