Path: blob/master/src/packages/file-server/zfs/names.ts
1447 views
import { join } from "path";1import { context } from "./config";2import { primaryKey, type PrimaryKey } from "./types";3import { randomId } from "@cocalc/conat/names";45export function databaseFilename(data: string) {6return join(data, "database.sqlite3");7}89export function namespaceDataset({10pool,11namespace,12}: {13pool: string;14namespace: string;15}) {16return `${pool}/${namespace}`;17}1819// Archives20// There is one single dataset for each namespace/pool pair: All the different21// archives across filesystems are stored in the *same* dataset, since there is no22// point in separating them.23export function archivesDataset({24pool,25namespace,26}: {27pool: string;28namespace: string;29}) {30return `${namespaceDataset({ pool, namespace })}/archives`;31}3233export function archivesMountpoint({34pool,35namespace,36}: {37pool: string;38namespace: string;39}) {40return join(context.ARCHIVES, namespace, pool);41}4243export function filesystemArchivePath({44pool,45...fs46}: PrimaryKey & { pool: string }) {47const pk = primaryKey(fs);48return join(49archivesMountpoint({ pool, namespace: pk.namespace }),50pk.owner_type,51pk.owner_id,52pk.name,53);54}5556export function filesystemArchiveFilename(opts: PrimaryKey & { pool: string }) {57const { owner_type, owner_id, name } = primaryKey(opts);58return join(59filesystemArchivePath(opts),60`full-${owner_type}-${owner_id}-${name}.zfs`,61);62}6364export function filesystemStreamsPath(opts: PrimaryKey & { pool: string }) {65return join(filesystemArchivePath(opts), "streams");66}6768export function filesystemStreamsFilename({69snapshot1,70snapshot2,71...opts72}: PrimaryKey & { snapshot1: string; snapshot2: string; pool: string }) {73return join(filesystemStreamsPath(opts), `${snapshot1}-${snapshot2}.zfs`);74}7576// Bup77export function bupDataset({78pool,79namespace,80}: {81pool: string;82namespace: string;83}) {84return `${namespaceDataset({ pool, namespace })}/bup`;85}8687export function bupMountpoint({88pool,89namespace,90}: {91pool: string;92namespace: string;93}) {94return join(context.BUP, namespace, pool);95}9697export function bupFilesystemMountpoint({98pool,99...fs100}: PrimaryKey & { pool: string }) {101const pk = primaryKey(fs);102return join(103bupMountpoint({ ...pk, pool }),104pk.owner_type,105pk.owner_id,106pk.name,107);108}109110// Filesystems111112export function filesystemsPath({ namespace }) {113return join(context.FILESYSTEMS, namespace);114}115116export function filesystemMountpoint(fs: PrimaryKey) {117const pk = primaryKey(fs);118return join(filesystemsPath(pk), pk.owner_type, pk.owner_id, pk.name);119}120121export function filesystemSnapshotMountpoint(122opts: PrimaryKey & { snapshot: string },123) {124return join(filesystemMountpoint(opts), ".zfs", "snapshot", opts.snapshot);125}126127export function filesystemsDataset({128pool,129namespace,130}: {131pool: string;132namespace: string;133}) {134return `${namespaceDataset({ pool, namespace })}/filesystems`;135}136137// There is one single dataset for each project_id/namespace/pool tripple since it138// is critical to separate each project to properly support snapshots, clones,139// backups, etc.140export function filesystemDataset({141pool,142...fs143}: PrimaryKey & { pool: string }) {144const { namespace, owner_type, owner_id, name } = primaryKey(fs);145// NOTE: we *could* use a heirarchy of datasets like this:146// ${owner_type}/${owner_id}/${name}147// However, that greatly increases the raw number of datasets, and there's a huge performance148// penalty. Since the owner_type is a fixed small list, owner_id is a uuid and the name is149// more general, there's no possible overlaps just concating them as below, and this way there's150// only one dataset, rather than three. (We also don't need to worry about deleting parents151// when there are no children...)152return `${filesystemsDataset({ pool, namespace: namespace })}/${owner_type}-${owner_id}-${name}`;153}154155export function tempDataset({156pool,157namespace,158}: {159pool: string;160namespace: string;161}) {162return `${namespaceDataset({ pool, namespace })}/temp`;163}164165export function filesystemDatasetTemp({166pool,167...fs168}: PrimaryKey & { pool: string }) {169const { namespace, owner_type, owner_id, name } = primaryKey(fs);170return `${tempDataset({ pool, namespace })}/${owner_type}-${owner_id}-${name}-${randomId()}`;171}172173// NOTE: We use "join" for actual file paths and explicit174// strings with / for ZFS filesystem names, since in some whacky175// futuristic world maybe this server is running on MS Windows.176177178