Changeset View
Changeset View
Standalone View
Standalone View
swh/fuse/fs/mountpoint.py
# Copyright (C) 2020 The Software Heritage developers | # Copyright (C) 2020 The Software Heritage developers | ||||
# See the AUTHORS file at the top-level directory of this distribution | # See the AUTHORS file at the top-level directory of this distribution | ||||
# License: GNU General Public License version 3, or any later version | # License: GNU General Public License version 3, or any later version | ||||
# See top-level LICENSE file for more information | # See top-level LICENSE file for more information | ||||
from dataclasses import dataclass, field | from dataclasses import dataclass, field | ||||
import json | import json | ||||
from typing import AsyncIterator | from typing import AsyncIterator | ||||
from swh.fuse.fs.artifact import OBJTYPE_GETTERS | from swh.fuse.fs.artifact import OBJTYPE_GETTERS | ||||
from swh.fuse.fs.entry import EntryMode, FuseEntry | from swh.fuse.fs.entry import EntryMode, FuseEntry | ||||
from swh.model.identifiers import CONTENT, SWHID | from swh.model.exceptions import ValidationError | ||||
from swh.model.identifiers import CONTENT, SWHID, parse_swhid | |||||
@dataclass | @dataclass | ||||
class Root(FuseEntry): | class Root(FuseEntry): | ||||
""" The FUSE mountpoint, consisting of the archive/ and meta/ directories """ | """ The FUSE mountpoint, consisting of the archive/ and meta/ directories """ | ||||
name: str = field(init=False, default=None) | name: str = field(init=False, default=None) | ||||
mode: int = field(init=False, default=int(EntryMode.RDONLY_DIR)) | mode: int = field(init=False, default=int(EntryMode.RDONLY_DIR)) | ||||
depth: int = field(init=False, default=1) | depth: int = field(init=False, default=1) | ||||
async def __aiter__(self) -> AsyncIterator[FuseEntry]: | async def __aiter__(self) -> AsyncIterator[FuseEntry]: | ||||
yield self.create_child(ArchiveDir) | yield self.create_child(ArchiveDir) | ||||
yield self.create_child(MetaDir) | yield self.create_child(MetaDir) | ||||
@dataclass | @dataclass | ||||
class ArchiveDir(FuseEntry): | class ArchiveDir(FuseEntry): | ||||
""" The archive/ directory is lazily populated with one entry per accessed | """ The archive/ directory is lazily populated with one entry per accessed | ||||
SWHID, having actual SWHIDs as names """ | SWHID, having actual SWHIDs as names """ | ||||
name: str = field(init=False, default="archive") | name: str = field(init=False, default="archive") | ||||
mode: int = field(init=False, default=int(EntryMode.RDONLY_DIR)) | mode: int = field(init=False, default=int(EntryMode.RDONLY_DIR)) | ||||
async def __aiter__(self) -> AsyncIterator[FuseEntry]: | def create_child(self, swhid: SWHID) -> FuseEntry: | ||||
async for swhid in self.fuse.cache.get_cached_swhids(): | |||||
if swhid.object_type == CONTENT: | if swhid.object_type == CONTENT: | ||||
mode = EntryMode.RDONLY_FILE | mode = EntryMode.RDONLY_FILE | ||||
else: | else: | ||||
mode = EntryMode.RDONLY_DIR | mode = EntryMode.RDONLY_DIR | ||||
yield self.create_child( | return super().create_child( | ||||
OBJTYPE_GETTERS[swhid.object_type], | OBJTYPE_GETTERS[swhid.object_type], | ||||
name=str(swhid), | name=str(swhid), | ||||
mode=int(mode), | mode=int(mode), | ||||
swhid=swhid, | swhid=swhid, | ||||
) | ) | ||||
async def __aiter__(self) -> AsyncIterator[FuseEntry]: | |||||
async for swhid in self.fuse.cache.get_cached_swhids(): | |||||
yield self.create_child(swhid) | |||||
async def lookup(self, name: str) -> FuseEntry: | |||||
entry = await super().lookup(name) | |||||
if entry: | |||||
return entry | |||||
# On the fly mounting of a new artifact | |||||
try: | |||||
swhid = parse_swhid(name) | |||||
await self.fuse.get_metadata(swhid) | |||||
return self.create_child(swhid) | |||||
except ValidationError: | |||||
return None | |||||
@dataclass | @dataclass | ||||
class MetaDir(FuseEntry): | class MetaDir(FuseEntry): | ||||
""" The meta/ directory contains one SWHID.json file for each SWHID entry | """ The meta/ directory contains one SWHID.json file for each SWHID entry | ||||
under archive/. The JSON file contain all available meta information about | under archive/. The JSON file contain all available meta information about | ||||
the given SWHID, as returned by the Software Heritage Web API for that | the given SWHID, as returned by the Software Heritage Web API for that | ||||
object. Note that, in case of pagination (e.g., snapshot objects with many | object. Note that, in case of pagination (e.g., snapshot objects with many | ||||
branches) the JSON file will contain a complete version with all pages | branches) the JSON file will contain a complete version with all pages | ||||
Show All 30 Lines |