dev: implement unlink in puterfs extension

This commit is contained in:
KernelDeimos
2025-11-04 21:32:41 -05:00
committed by Eric Dubé
parent 24b1570007
commit a0ff03b13d
4 changed files with 85 additions and 11 deletions
+76 -2
View File
@@ -16,15 +16,89 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const svc_metering = extension.import('service:meteringService');
const svc_trace = extension.import('service:traceService');
// TODO: these services ought to be part of this extension
const svc_size = extension.import('service:sizeService');
const svc_fsEntry = extension.import('service:fsEntryService');
const {
APIError,
Actor,
Context,
UserActorType,
} = extension.import('core');
const {
get_user,
} = extension.import('core').util.helpers;
const {
ParallelTasks,
} = extension.import('core').util.otelutil;
const {
TYPE_DIRECTORY,
} = extension.import('core').fs;
class PuterFSProvider {
//
async unlink ({ context, node, options = {} }) {
if ( await node.get('type') === TYPE_DIRECTORY ) {
throw new APIError(409, 'Cannot unlink a directory.');
}
await this.#rmnode({ context, node, options });
}
async #rmnode ({ node, options }) {
console.log('USING THE NEW IMPLEMENTATION');
// Services
if ( ! options.override_immutable && await node.get('immutable') ) {
throw new APIError(403, 'File is immutable.');
}
const userId = await node.get('user_id');
const fileSize = await node.get('size');
svc_size.change_usage(userId,
-1 * fileSize);
const ownerActor = new Actor({
type: new UserActorType({
user: await get_user({ id: userId }),
}),
});
svc_metering.incrementUsage(ownerActor, 'filesystem:delete:bytes', fileSize);
const tracer = svc_trace.tracer;
const tasks = new ParallelTasks({ tracer, max: 4 });
tasks.add('remove-fsentry', async () => {
await svc_fsEntry.delete(await node.get('uid'));
});
if ( await node.get('has-s3') ) {
tasks.add('remove-from-s3', async () => {
// const storage = new PuterS3StorageStrategy({ services: svc });
const storage = Context.get('storage');
const state_delete = storage.create_delete();
await state_delete.run({
node: node,
});
});
}
await tasks.awaitAll();
}
}
const { TmpProxyFSProvider } = extension.import('fs');
extension.on('create.filesystem-types', event => {
event.createFilesystemType('puterfs', {
mount({ path }) {
mount ({ path }) {
return new TmpProxyFSProvider(path, new PuterFSProvider(path));
},
});
+6 -3
View File
@@ -25,6 +25,7 @@ const { Context } = require('./util/context');
const { LLOWrite } = require('./filesystem/ll_operations/ll_write');
const { LLRead } = require('./filesystem/ll_operations/ll_read');
const { RuntimeModule } = require('./extension/RuntimeModule.js');
const { TYPE_DIRECTORY, TYPE_FILE } = require('./filesystem/FSNodeContext.js');
/**
* Core module for the Puter platform that includes essential services including
@@ -36,10 +37,10 @@ const { RuntimeModule } = require('./extension/RuntimeModule.js');
* and Core2Module will take on its name.
*/
class CoreModule extends AdvancedBase {
dirname() {
dirname () {
return __dirname;
}
async install(context) {
async install (context) {
const services = context.get('services');
const app = context.get('app');
const useapi = context.get('useapi');
@@ -57,7 +58,7 @@ class CoreModule extends AdvancedBase {
* @param {Object} context.services - Service registry for registering legacy services
* @returns {Promise<void>} Resolves when legacy services are installed
*/
async install_legacy(context) {
async install_legacy (context) {
const services = context.get('services');
await install_legacy({ services });
}
@@ -98,6 +99,8 @@ const install = async ({ context, services, app, useapi, modapi }) => {
def('core.fs', {
LLOWrite,
LLRead,
TYPE_DIRECTORY,
TYPE_FILE,
});
def('core.fs.selectors', require('./filesystem/node/selectors'));
def('core.util.stream', require('./util/streamutil'));
@@ -410,12 +410,8 @@ class PuterFSProvider extends putility.AdvancedBase {
}
async unlink({ context, node, options = {} }) {
if ( await node.get('type') === TYPE_DIRECTORY ) {
console.log(`\x1B[31;1m===N=====${await node.get('path')}=========\x1B[0m`);
throw new APIError(409, 'Cannot unlink a directory.');
}
await this.#rmnode({ context, node, options });
console.error('This .unlink should not be called!');
process.exit(1);
}
async rmdir({ context, node, options = {} }) {
@@ -255,6 +255,7 @@ class DriverService extends BaseService {
return await this._call(o);
} catch ( e ) {
this.log.error('Driver error response: ' + e.toString());
console.error(e);
if ( ! (e instanceof APIError) ) {
this.errors.report('driver', {
source: e,