@@ -4,33 +4,12 @@ A subvolume
4
4
5
5
import { type Filesystem , DEFAULT_SUBVOLUME_SIZE } from "./filesystem" ;
6
6
import refCache from "@cocalc/util/refcache" ;
7
- import {
8
- appendFile ,
9
- chmod ,
10
- cp ,
11
- copyFile ,
12
- link ,
13
- readFile ,
14
- realpath ,
15
- rename ,
16
- rm ,
17
- rmdir ,
18
- mkdir ,
19
- stat ,
20
- symlink ,
21
- truncate ,
22
- writeFile ,
23
- unlink ,
24
- utimes ,
25
- watch ,
26
- } from "node:fs/promises" ;
27
- import { exists , isdir , listdir , mkdirp , sudo } from "./util" ;
7
+ import { exists , listdir , mkdirp , sudo } from "./util" ;
28
8
import { join , normalize } from "path" ;
29
9
import { updateRollingSnapshots , type SnapshotCounts } from "./snapshots" ;
30
- import { DirectoryListingEntry } from "@cocalc/util/types" ;
31
- import getListing from "@cocalc/backend/get-listing" ;
10
+ import { type DirectoryListingEntry } from "@cocalc/util/types" ;
32
11
import getLogger from "@cocalc/backend/logger" ;
33
- import { exists as pathExists } from "@cocalc/backend/misc/async-utils-node " ;
12
+ import { SubvolumeFilesystem } from "./subvolume-fs " ;
34
13
35
14
export const SNAPSHOTS = ".snapshots" ;
36
15
const SEND_SNAPSHOT_PREFIX = "send-" ;
@@ -48,14 +27,16 @@ export class Subvolume {
48
27
public readonly name : string ;
49
28
50
29
private filesystem : Filesystem ;
51
- private readonly path : string ;
52
- private readonly snapshotsDir : string ;
30
+ public readonly path : string ;
31
+ public readonly snapshotsDir : string ;
32
+ public readonly fs : SubvolumeFilesystem ;
53
33
54
34
constructor ( { filesystem, name } : Options ) {
55
35
this . filesystem = filesystem ;
56
36
this . name = name ;
57
37
this . path = join ( filesystem . opts . mount , name ) ;
58
38
this . snapshotsDir = join ( this . path , SNAPSHOTS ) ;
39
+ this . fs = new SubvolumeFilesystem ( this ) ;
59
40
}
60
41
61
42
init = async ( ) => {
@@ -96,135 +77,13 @@ export class Subvolume {
96
77
// this should provide a path that is guaranteed to be
97
78
// inside this.path on the filesystem or throw error
98
79
// [ ] TODO: not sure if the code here is sufficient!!
99
- private normalize = ( path : string ) => {
80
+ normalize = ( path : string ) => {
100
81
return join ( this . path , normalize ( path ) ) ;
101
82
} ;
102
83
103
84
/////////////
104
85
// Files
105
86
/////////////
106
- ls = async (
107
- path : string ,
108
- { hidden, limit } : { hidden ?: boolean ; limit ?: number } = { } ,
109
- ) : Promise < DirectoryListingEntry [ ] > => {
110
- path = normalize ( path ) ;
111
- return await getListing ( this . normalize ( path ) , hidden , {
112
- limit,
113
- home : "/" ,
114
- } ) ;
115
- } ;
116
-
117
- readFile = async ( path : string , encoding ?: any ) : Promise < string | Buffer > => {
118
- path = normalize ( path ) ;
119
- return await readFile ( this . normalize ( path ) , encoding ) ;
120
- } ;
121
-
122
- writeFile = async ( path : string , data : string | Buffer ) => {
123
- path = normalize ( path ) ;
124
- return await writeFile ( this . normalize ( path ) , data ) ;
125
- } ;
126
-
127
- appendFile = async ( path : string , data : string | Buffer , encoding ?) => {
128
- path = normalize ( path ) ;
129
- return await appendFile ( this . normalize ( path ) , data , encoding ) ;
130
- } ;
131
-
132
- unlink = async ( path : string ) => {
133
- await unlink ( this . normalize ( path ) ) ;
134
- } ;
135
-
136
- stat = async ( path : string ) => {
137
- return await stat ( this . normalize ( path ) ) ;
138
- } ;
139
-
140
- exists = async ( path : string ) => {
141
- return await pathExists ( this . normalize ( path ) ) ;
142
- } ;
143
-
144
- // hard link
145
- link = async ( existingPath : string , newPath : string ) => {
146
- return await link ( this . normalize ( existingPath ) , this . normalize ( newPath ) ) ;
147
- } ;
148
-
149
- symlink = async ( target : string , path : string ) => {
150
- return await symlink ( this . normalize ( target ) , this . normalize ( path ) ) ;
151
- } ;
152
-
153
- realpath = async ( path : string ) => {
154
- const x = await realpath ( this . normalize ( path ) ) ;
155
- return x . slice ( this . path . length + 1 ) ;
156
- } ;
157
-
158
- rename = async ( oldPath : string , newPath : string ) => {
159
- await rename ( this . normalize ( oldPath ) , this . normalize ( newPath ) ) ;
160
- } ;
161
-
162
- utimes = async (
163
- path : string ,
164
- atime : number | string | Date ,
165
- mtime : number | string | Date ,
166
- ) => {
167
- await utimes ( this . normalize ( path ) , atime , mtime ) ;
168
- } ;
169
-
170
- watch = ( filename : string , options ?) => {
171
- return watch ( this . normalize ( filename ) , options ) ;
172
- } ;
173
-
174
- truncate = async ( path : string , len ?: number ) => {
175
- await truncate ( this . normalize ( path ) , len ) ;
176
- } ;
177
-
178
- copyFile = async ( src : string , dest : string ) => {
179
- await copyFile ( this . normalize ( src ) , this . normalize ( dest ) ) ;
180
- } ;
181
-
182
- cp = async ( src : string , dest : string , options ?) => {
183
- await cp ( this . normalize ( src ) , this . normalize ( dest ) , options ) ;
184
- } ;
185
-
186
- chmod = async ( path : string , mode : string | number ) => {
187
- await chmod ( this . normalize ( path ) , mode ) ;
188
- } ;
189
-
190
- mkdir = async ( path : string , options ?) => {
191
- await mkdir ( this . normalize ( path ) , options ) ;
192
- } ;
193
-
194
- rsync = async ( {
195
- src,
196
- target,
197
- args = [ "-axH" ] ,
198
- timeout = 5 * 60 * 1000 ,
199
- } : {
200
- src : string ;
201
- target : string ;
202
- args ?: string [ ] ;
203
- timeout ?: number ;
204
- } ) : Promise < { stdout : string ; stderr : string ; exit_code : number } > => {
205
- let srcPath = this . normalize ( src ) ;
206
- let targetPath = this . normalize ( target ) ;
207
- if ( ! srcPath . endsWith ( "/" ) && ( await isdir ( srcPath ) ) ) {
208
- srcPath += "/" ;
209
- if ( ! targetPath . endsWith ( "/" ) ) {
210
- targetPath += "/" ;
211
- }
212
- }
213
- return await sudo ( {
214
- command : "rsync" ,
215
- args : [ ...args , srcPath , targetPath ] ,
216
- err_on_exit : false ,
217
- timeout : timeout / 1000 ,
218
- } ) ;
219
- } ;
220
-
221
- rmdir = async ( path : string , options ?) => {
222
- await rmdir ( this . normalize ( path ) , options ) ;
223
- } ;
224
-
225
- rm = async ( path : string , options ?) => {
226
- await rm ( this . normalize ( path ) , options ) ;
227
- } ;
228
87
229
88
/////////////
230
89
// QUOTA
0 commit comments