diff --git a/doc/contributors/extensions/README.md b/doc/contributors/extensions/README.md index 661d943ce..0af053c18 100644 --- a/doc/contributors/extensions/README.md +++ b/doc/contributors/extensions/README.md @@ -87,7 +87,3 @@ See [events.md](./events.md) ## Definitions See [definitions.md](./definitions.md) - -## Bundled extensions - -- [dev-console](./dev-console.md) – Dev socket for running backend commands locally (opt-in via `DEVCONSOLE=1`). diff --git a/doc/contributors/extensions/dev-console.md b/doc/contributors/extensions/dev-console.md deleted file mode 100644 index 1a9d73687..000000000 --- a/doc/contributors/extensions/dev-console.md +++ /dev/null @@ -1,21 +0,0 @@ -# dev-console extension - -The **dev-console** extension provides a **dev socket** so you can run backend commands on a local Puter instance (e.g. commands registered in [CommandService](../../../src/backend/src/services/CommandService.js)). - -## Enabling - -The extension is **opt-in**. Set the environment variable `DEVCONSOLE=1` when starting Puter. The `npm run dev` script already does this: - -```bash -npm run dev -``` - -With `DEVCONSOLE=1`, the extension registers a `dev-socket` service that creates a UNIX socket and runs command lines through CommandService. - -## Usage - -See [Backend – dev socket](../../../src/backend/doc/dev_socket.md) for how to connect (e.g. `rlwrap nc -U ./dev.sock`) and run commands like `help`, `logs:indent`, etc. - -## Location - -The extension lives in `extensions/dev-console/`. It only registers the dev-socket service when `DEVCONSOLE=1`; otherwise the extension loads but does nothing, so it does not affect default runs. diff --git a/extensions/README.md b/extensions/README.md index d8c0f876f..6186a41dd 100644 --- a/extensions/README.md +++ b/extensions/README.md @@ -5,10 +5,6 @@ ### Here Documentation for extensions is [here](src/backend/doc/extensions/README.md). -### Bundled extensions - -- **dev-console** (`extensions/dev-console/`) – Dev socket for running backend commands locally. Opt-in via `DEVCONSOLE=1` (e.g. `npm run dev`). See [Backend – dev socket](src/backend/doc/dev_socket.md). - ### Not Here Outdated documentation for extensions is [here](../doc/contributors/extensions/README.md). diff --git a/mods/mods_available/dev-socket/main.js b/mods/mods_available/dev-socket/main.js deleted file mode 100644 index f0082eb0f..000000000 --- a/mods/mods_available/dev-socket/main.js +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import fs from 'node:fs'; -import net from 'node:net'; -import path from 'node:path'; - -const SOCKET_NAME = 'dev.sock'; -const WELCOME = [ - 'Puter dev socket – enter a command (e.g. help) and press Enter.', - 'Close the connection with Ctrl+C or by typing exit.', - '', -].join('\n'); - -function getSocketDir () { - if ( process.env.PUTER_DEV_SOCKET_DIR ) { - return process.env.PUTER_DEV_SOCKET_DIR; - } - const volatileRuntime = path.join(process.cwd(), 'volatile', 'runtime'); - if ( fs.existsSync(volatileRuntime) ) { - return volatileRuntime; - } - return process.cwd(); -} - -extension.on('init', async () => { - if ( process.env.DEVCONSOLE !== '1' ) { - return; - } - - const commands = extension.import('service:commands'); - const socketDir = getSocketDir(); - const socketPath = path.join(socketDir, SOCKET_NAME); - - try { - if ( fs.existsSync(socketPath) ) { - fs.unlinkSync(socketPath); - } - fs.mkdirSync(socketDir, { recursive: true }); - } catch ( err ) { - console.warn('dev-socket: could not prepare socket path', socketPath, err.message); - return; - } - - const server = net.createServer((socket) => { - socket.setEncoding('utf8'); - socket.write(`${WELCOME }\n> `); - let buffer = ''; - socket.on('data', (chunk) => { - buffer += chunk; - const lines = buffer.split(/\r?\n/); - buffer = lines.pop() ?? ''; - for ( const line of lines ) { - const trimmed = line.trim(); - if ( trimmed === '' ) continue; - if ( trimmed.toLowerCase() === 'exit' ) { - socket.end(); - return; - } - const log = { - log: (msg) => { - socket.write(`${String(msg) }\n`); - }, - error: (msg) => { - socket.write(`${String(msg) }\n`); - }, - }; - commands.executeRawCommand(trimmed, log).then(() => { - socket.write('> '); - }).catch((err) => { - log.error(err?.message ?? err); - socket.write('> '); - }); - } - }); - socket.on('end', () => { - }); - socket.on('error', () => { - }); - }); - - server.listen(socketPath, () => { - console.log('dev-socket: socket listening at', socketPath); - }); - server.on('error', (err) => { - console.warn('dev-socket: socket error', err.message); - }); -}); diff --git a/mods/mods_available/dev-socket/package.json b/mods/mods_available/dev-socket/package.json deleted file mode 100644 index 16a796309..000000000 --- a/mods/mods_available/dev-socket/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "@heyputer/extension-dev-console", - "version": "1.0.0", - "description": "Dev socket for running backend commands locally (opt-in via DEVCONSOLE=1)", - "main": "main.js", - "type": "module", - "private": true -} \ No newline at end of file diff --git a/mods/mods_available/kdmod/CustomPuterService.js b/mods/mods_available/kdmod/CustomPuterService.js index ec5b730d8..51f5685f1 100644 --- a/mods/mods_available/kdmod/CustomPuterService.js +++ b/mods/mods_available/kdmod/CustomPuterService.js @@ -26,52 +26,27 @@ class CustomPuterService extends use.Service { const svc_puterHomepage = this.services.get('puter-homepage'); svc_puterHomepage.register_script('/custom-gui/main.js'); } - ['__on_install.routes'] (_, { app }) { + '__on_install.routes' (_, { app }) { const require = this.require; const express = require('express'); const path_ = require('path'); - app.use('/custom-gui', - express.static(path.join(__dirname, 'gui'))); + app.use( + '/custom-gui', + express.static(path.join(__dirname, 'gui')), + ); } - async ['__on_boot.consolidation'] () { - const then = Date.now(); - this.tod_widget = () => { - const s = 5 - Math.floor((Date.now() - then) / 1000); - const lines = [ - '\x1B[36;1mKDMOD ENABLED\x1B[0m' + - ` (👁️ ${s}s)`, - ]; - // It would be super cool to be able to use this here - // surrounding_box('33;1', lines); - return lines; - }; - - const svc_devConsole = this.services.get('dev-console', { optional: true }); - if ( ! svc_devConsole ) return; - svc_devConsole.add_widget(this.tod_widget); - - setTimeout(() => { - svc_devConsole.remove_widget(this.tod_widget); - }, 5000); - } - _register_commands (commands) { commands.registerCommands('o', [ { id: 'k', description: '', handler: async (_, log) => { - const svc_devConsole = this.services.get('dev-console', { optional: true }); - if ( ! svc_devConsole ) return; - svc_devConsole.remove_widget(this.tod_widget); - const lines = this.tod_widget(); - for ( const line of lines ) log.log(line); - this.tod_widget = null; + log.log('kdmod is enabled'); }, }, ]); } } -module.exports = { CustomPuterService }; \ No newline at end of file +module.exports = { CustomPuterService }; diff --git a/package.json b/package.json index 868551dc8..495d0b488 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "start=gui": "nodemon --exec \"node dev-server.js\" ", "start": "node ./tools/run-selfhosted.js", "prestart": "npm run build:ts", - "dev": "npm run build:ts && DEVCONSOLE=1 node ./tools/run-selfhosted.js", + "dev": "npm run build:ts && node ./tools/run-selfhosted.js", "build": "npx eslint --quiet -c eslint/mandatory.eslint.config.js src/backend/src extensions && npm run build:ts && cd src/gui && node ./build.js", "check-translations": "node tools/check-translations.js", "prepare": "husky", diff --git a/src/backend/doc/dev_socket.md b/src/backend/doc/dev_socket.md deleted file mode 100644 index 73df862d2..000000000 --- a/src/backend/doc/dev_socket.md +++ /dev/null @@ -1,32 +0,0 @@ -## Backend - dev socket - -The "dev socket" allows you to interact with Puter's backend by running commands. -It's a UNIX socket that lets you run commands registered with -[CommandService](../../src/services/CommandService.js) (e.g. `help`, `logs:indent`, `params:get`, etc.). - -### Enabling the dev socket - -The dev socket is provided by the **dev-console extension** and is **opt-in**. To enable it: - -1. Set the environment variable `DEVCONSOLE=1` when starting Puter (e.g. `npm run dev` already does this). -2. The extension lives in `extensions/dev-console/` and registers a `dev-socket` service when `DEVCONSOLE=1`. - -### Socket location - -The socket is created in a directory chosen as follows (in order): - -- `PUTER_DEV_SOCKET_DIR` if set -- `./volatile/runtime` if it exists (typical local dev) -- otherwise the process current working directory - -The socket file is named `dev.sock`. - -### Connecting - -When in that directory, connect with your tool of choice. For example, using `nc` and `rlwrap` for readline history: - -``` -rlwrap nc -U ./dev.sock -``` - -If it is successful you will see a message with instructions. Enter a command (e.g. `help`) and press Enter. diff --git a/src/backend/doc/extensions/README.md b/src/backend/doc/extensions/README.md index fe3201bfb..2ac7ca49e 100644 --- a/src/backend/doc/extensions/README.md +++ b/src/backend/doc/extensions/README.md @@ -72,10 +72,6 @@ key-value store, and in-memory cache. ### Adding Features to Puter - [Implementing Drivers](./pages/drivers.md) -### Bundled extensions - -- **dev-console** – When `DEVCONSOLE=1` is set (e.g. `npm run dev`), the dev-console extension registers a UNIX socket (`dev.sock`) so you can run backend commands (see [CommandService](../../src/services/CommandService.js)) from a terminal. See [Backend – dev socket](../dev_socket.md). - ## Extensions - Planned Features Extensions are under refactor currently. This is the checklist: diff --git a/src/backend/src/CoreModule.js b/src/backend/src/CoreModule.js index 82417a553..2b61b3b66 100644 --- a/src/backend/src/CoreModule.js +++ b/src/backend/src/CoreModule.js @@ -33,6 +33,7 @@ const { redisClient } = require('./clients/redis/redisSingleton'); const { kv } = require('./util/kvSingleton'); const { s3ClientProvider } = require('./clients/s3/s3ClientProvider'); const { PuterS3Service } = require('./deprecated/filesystem/PuterS3Service'); +const BaseService = require('./services/BaseService'); /** * @footgun - real install method is defined above @@ -121,7 +122,6 @@ const install = async ({ context, services, app, useapi, modapi }) => { // TODO: move these to top level imports or await imports and esm this file - const { CommandService } = require('./services/CommandService'); const { RateLimitService } = require('./services/sla/RateLimitService'); const { AuthService } = require('./services/auth/AuthService'); const { SLAService } = require('./services/sla/SLAService'); @@ -164,7 +164,6 @@ const install = async ({ context, services, app, useapi, modapi }) => { services.registerService('dynamo', DDBClientWrapper); services.registerService('system-validation', SystemValidationService); - services.registerService('commands', CommandService); services.registerService('__api-filesystem', FilesystemAPIService); services.registerService('__api', PuterAPIService); services.registerService('__gui', ServeGUIService); @@ -395,14 +394,11 @@ const install = async ({ context, services, app, useapi, modapi }) => { const install_legacy = async ({ services }) => { const { OperationTraceService } = require('./services/OperationTraceService'); const { ClientOperationService } = require('./services/ClientOperationService'); - const { EngPortalService } = require('./services/EngPortalService'); // === Services which do not yet extend BaseService === // services.registerService('filesystem', FilesystemService); services.registerService('operationTrace', OperationTraceService); services.registerService('client-operation', ClientOperationService); - services.registerService('engineering-portal', EngPortalService); - }; /** diff --git a/src/backend/src/DatabaseModule.js b/src/backend/src/DatabaseModule.js index a20187462..ee785d935 100644 --- a/src/backend/src/DatabaseModule.js +++ b/src/backend/src/DatabaseModule.js @@ -16,14 +16,17 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -const { AdvancedBase } = require('@heyputer/putility'); + +import { AdvancedBase } from '@heyputer/putility'; +import { StrategizedService } from './services/StrategizedService.js'; +import { SqliteDatabaseAccessService } from './services/database/SqliteDatabaseAccessService.js'; + +// import {BaseService} from './services/BaseService.js'; class DatabaseModule extends AdvancedBase { async install (context) { const services = context.get('services'); - const { StrategizedService } = require('./services/StrategizedService'); - const { SqliteDatabaseAccessService } = require('./services/database/SqliteDatabaseAccessService'); services.registerService('database', StrategizedService, { strategy_key: 'engine', strategies: { @@ -33,4 +36,4 @@ class DatabaseModule extends AdvancedBase { } } -module.exports = DatabaseModule; +export default DatabaseModule; diff --git a/src/backend/src/Kernel.js b/src/backend/src/Kernel.js index be0f45f90..dd712e3b1 100644 --- a/src/backend/src/Kernel.js +++ b/src/backend/src/Kernel.js @@ -213,7 +213,6 @@ class Kernel extends AdvancedBase { deployment_type: globalThis.deployment_type, }); })(); - await services.emit('boot.activation'); await services.emit('boot.ready'); diff --git a/src/backend/src/modules/core/AlarmService.js b/src/backend/src/modules/core/AlarmService.js index 013e41897..dce7f5b31 100644 --- a/src/backend/src/modules/core/AlarmService.js +++ b/src/backend/src/modules/core/AlarmService.js @@ -64,7 +64,6 @@ class AlarmService extends BaseService { * the '_init' method of CommandService may not have been called yet. */ '__on_boot.consolidation' () { - this._register_commands(this.services.get('commands')); } adapt_id_ (id) { @@ -361,137 +360,6 @@ class AlarmService extends BaseService { get_alarm (id) { return this.alarms[id] ?? this.alarm_aliases[id]; } - - _register_commands (commands) { - // Function to handle a specific alarm event. - // This comment can be added above line 320. - // This function is responsible for processing specific events related to alarms. - // It can be used for tasks such as updating alarm status, sending notifications, or triggering actions. - // This function is called internally by the AlarmService class. - - // /* - // * handleAlarmEvent - Handles a specific alarm event. - // * - // * @param {Object} alarm - The alarm object containing relevant information. - // * @param {Function} callback - Optional callback function to be called when the event is handled. - // */ - // function handleAlarmEvent(alarm, callback) { - // // Implementation goes here. - // } - const completeAlarmID = (args) => { - // The alarm ID is the first argument, so return no results if we're on the second or later. - if ( args.length > 1 ) - { - return; - } - const lastArg = args[args.length - 1]; - - const results = []; - for ( const alarm of Object.values(this.alarms) ) { - if ( alarm.id.startsWith(lastArg) ) { - results.push(alarm.id); - } - if ( alarm.short_id?.startsWith(lastArg) ) { - results.push(alarm.short_id); - } - } - return results; - }; - - commands.registerCommands('alarm', [ - { - id: 'list', - description: 'list alarms', - handler: async (args, log) => { - for ( const alarm of Object.values(this.alarms) ) { - log.log(`${alarm.id_string}: ${alarm.message} (${alarm.count})`); - } - }, - }, - { - id: 'info', - description: 'show info about an alarm', - handler: async (args, log) => { - const [id] = args; - const alarm = this.get_alarm(id); - if ( ! alarm ) { - log.log(`no alarm with id ${id}`); - return; - } - log.log(`\x1B[33;1m${alarm.id_string}\x1B[0m :: ${alarm.message} (${alarm.count})`); - log.log(`started: ${new Date(alarm.started).toISOString()}`); - log.log(`short id: ${alarm.short_id}`); - log.log(`original id: ${alarm.id}`); - - // print stack trace of alarm error - if ( alarm.error ) { - log.log(alarm.error.stack); - } - // print other fields - for ( const [key, value] of Object.entries(alarm.fields) ) { - log.log(`- ${key}: ${util.inspect(value)}`); - } - }, - completer: completeAlarmID, - }, - { - id: 'clear', - description: 'clear an alarm', - handler: async (args, log) => { - const [id] = args; - const alarm = this.get_alarm(id); - if ( ! alarm ) { - log.log(`no alarm with id ${id}; ` + - `but calling clear(${JSON.stringify(id)}) anyway.`); - } - this.clear(id); - }, - completer: completeAlarmID, - }, - { - id: 'clear-all', - description: 'clear all alarms', - handler: async (_args, _log) => { - const alarms = Object.values(this.alarms); - this.alarms = {}; - for ( const alarm of alarms ) { - this.handle_alarm_off_(alarm); - } - }, - }, - { - id: 'sound', - description: 'sound an alarm', - handler: async (args, _log) => { - const [id, message] = args; - this.create(id ?? 'test', message, {}); - }, - }, - { - id: 'inspect', - description: 'show logs that happened an alarm', - handler: async (args, log) => { - const [id, occurance_idx] = args; - const alarm = this.get_alarm(id); - if ( ! alarm ) { - log.log(`no alarm with id ${id}`); - return; - } - const occurance = alarm.occurrences[occurance_idx]; - if ( ! occurance ) { - log.log(`no occurance with index ${occurance_idx}`); - return; - } - log.log(`┏━━ Logs before: ${alarm.id_string} ━━━━`); - for ( const lg of occurance.logs ) { - log.log(`┃ ${ this.logutil.stringify_log_entry(lg)}`); - } - log.log(`┗━━ Logs before: ${alarm.id_string} ━━━━`); - }, - completer: completeAlarmID, - }, - ]); - } } module.exports = { diff --git a/src/backend/src/modules/core/LogService.js b/src/backend/src/modules/core/LogService.js index 70462ebf3..e09cfd412 100644 --- a/src/backend/src/modules/core/LogService.js +++ b/src/backend/src/modules/core/LogService.js @@ -410,61 +410,6 @@ class LogService extends BaseService { * Registers logging commands with the command service. */ '__on_boot.consolidation' () { - const commands = this.services.get('commands'); - commands.registerCommands('logs', [ - { - id: 'show', - description: 'toggle log output', - handler: async () => { - this.devlogger && (this.devlogger.off = !this.devlogger.off); - }, - }, - { - id: 'rec', - description: 'start recording to a file via dev logger', - handler: async (args, ctx) => { - const [name] = args; - const { log } = ctx; - if ( ! this.devlogger ) { - log('no dev logger; what are you doing?'); - } - this.devlogger.recto = name; - }, - }, - { - id: 'stop', - description: 'stop recording to a file via dev logger', - handler: async ([_name], log) => { - if ( ! this.devlogger ) { - log('no dev logger; what are you doing?'); - } - this.devlogger.recto = null; - }, - }, - { - id: 'indent', - description: 'toggle log indentation', - handler: async () => { - globalThis.dev_console_indent_on = - !globalThis.dev_console_indent_on; - }, - }, - { - id: 'get-level', - description: 'get the current log level for displayed logs', - handler: async (args, log) => { - log.log(`${display_log_level} (${display_log_level_label[display_log_level] ?? '?'})`); - }, - }, - { - id: 'set-level', - description: 'set the new log level for displayed logs', - handler: async (args, log) => { - display_log_level = Number(args[0]); - log.log(`${display_log_level} (${display_log_level_label[display_log_level] ?? '?'})`); - }, - }, - ]); } /** * Registers logging commands with the command service. diff --git a/src/backend/src/modules/core/PagerService.js b/src/backend/src/modules/core/PagerService.js index 648fba2ca..e40be7308 100644 --- a/src/backend/src/modules/core/PagerService.js +++ b/src/backend/src/modules/core/PagerService.js @@ -45,7 +45,6 @@ class PagerService extends BaseService { * the '_init' method of CommandService may not have been called yet. */ '__on_boot.consolidation' () { - this._register_commands(this.services.get('commands')); } /** @@ -139,24 +138,6 @@ class PagerService extends BaseService { } } - _register_commands (commands) { - commands.registerCommands('pager', [ - { - id: 'test-alert', - description: 'create a test alert', - handler: async (args, log) => { - const [severity] = args; - await this.alert({ - id: 'test-alert', - message: 'test alert', - source: 'test', - severity, - }); - }, - }, - ]); - } - } module.exports = { diff --git a/src/backend/src/modules/core/ParameterService.js b/src/backend/src/modules/core/ParameterService.js index ccd4206d8..d26599dce 100644 --- a/src/backend/src/modules/core/ParameterService.js +++ b/src/backend/src/modules/core/ParameterService.js @@ -98,7 +98,6 @@ class ParameterService extends BaseService { * @private */ '__on_boot.consolidation' () { - this._registerCommands(this.services.get('commands')); } createParameters (serviceName, parameters, opt_instance) { @@ -109,9 +108,11 @@ class ParameterService extends BaseService { id: `${serviceName}:${parameter.id}`, })); if ( opt_instance ) { - this.bindToInstance(`${serviceName}:${parameter.id}`, - opt_instance, - parameter.id); + this.bindToInstance( + `${serviceName}:${parameter.id}`, + opt_instance, + parameter.id, + ); } } } @@ -144,71 +145,6 @@ class ParameterService extends BaseService { } return parameter; } - - /** - * Registers parameter-related commands with the command service - * @param {Object} commands - The command service instance to register with - */ - _registerCommands (commands) { - const completeParameterName = (args) => { - // The parameter name is the first argument, so return no results if we're on the second or later. - if ( args.length > 1 ) - { - return; - } - const lastArg = args[args.length - 1]; - - return this.parameters_ - .map(parameter => parameter.spec_.id) - .filter(parameterName => parameterName.startsWith(lastArg)); - }; - - commands.registerCommands('params', [ - { - id: 'get', - description: 'get a parameter', - handler: async (args, log) => { - const [name] = args; - const value = await this.get(name); - log.log(value); - }, - completer: completeParameterName, - }, - { - id: 'set', - description: 'set a parameter', - handler: async (args, log) => { - const [name, value] = args; - const parameter = this._get_param(name); - parameter.set(value); - log.log(value); - }, - completer: completeParameterName, - }, - { - id: 'list', - description: 'list parameters', - handler: async (args, log) => { - const [prefix] = args; - let parameters = this.parameters_; - if ( prefix ) { - parameters = parameters - .filter(p => p.spec_.id.startsWith(prefix)); - } - log.log(`available parameters${ - prefix ? ` (starting with: ${prefix})` : '' - }:`); - for ( const parameter of parameters ) { - // log.log(`- ${parameter.spec_.id}: ${parameter.spec_.description}`); - // Log parameter description and value - const value = await parameter.get(); - log.log(`- ${parameter.spec_.id} = ${value}`); - log.log(` ${parameter.spec_.description}`); - } - }, - }, - ]); - } } module.exports = { diff --git a/src/backend/src/modules/domain/DomainVerificationService.js b/src/backend/src/modules/domain/DomainVerificationService.js index f8c76ad96..01b032bec 100644 --- a/src/backend/src/modules/domain/DomainVerificationService.js +++ b/src/backend/src/modules/domain/DomainVerificationService.js @@ -23,19 +23,6 @@ class DomainVerificationService extends BaseService { return await get_user({ username: 'admin' }); } - _register_commands (commands) { - const svc_commands = this.services.get('commands'); - svc_commands.registerCommands('domain', [ - { - id: 'user', - description: '', - handler: async (args, log) => { - const res = await this.get_controlling_user({ domain: args[0] }); - log.log(res); - }, - }, - ]); - } } module.exports = { diff --git a/src/backend/src/modules/puterfs/SizeService.js b/src/backend/src/modules/puterfs/SizeService.js index 270b5e1ef..67a5afa59 100644 --- a/src/backend/src/modules/puterfs/SizeService.js +++ b/src/backend/src/modules/puterfs/SizeService.js @@ -42,35 +42,6 @@ class SizeService extends BaseService { } '__on_boot.consolidate' () { - const svc_commands = this.services.get('commands'); - svc_commands.registerCommands('size', [ - { - id: 'get-usage', - description: 'get usage for a user', - handler: async (args, log) => { - const user = await UserParameter.adapt(args[0]); - const usage = await this.get_usage(user.id); - log.log(`usage: ${usage} bytes`); - }, - }, - { - id: 'get-capacity', - description: 'get storage capacity for a user', - handler: async (args, log) => { - const user = await UserParameter.adapt(args[0]); - const capacity = await this.get_storage_capacity(user); - log.log(`capacity: ${capacity} bytes`); - }, - }, - { - id: 'get-cache-size', - description: 'get the number of cached users', - handler: async (args, log) => { - const size = Object.keys(this.usages).length; - log.log(`cache size: ${size}`); - }, - }, - ]); } async get_usage (user_id) { diff --git a/src/backend/src/modules/selfhosted/DefaultUserService.js b/src/backend/src/modules/selfhosted/DefaultUserService.js index 7ed64ac9e..daa79d620 100644 --- a/src/backend/src/modules/selfhosted/DefaultUserService.js +++ b/src/backend/src/modules/selfhosted/DefaultUserService.js @@ -36,7 +36,6 @@ const DEFAULT_FILES = {}; class DefaultUserService extends BaseService { async _init () { - this._register_commands(this.services.get('commands')); } async '__on_ready.webserver' () { // check if a user named `admin` exists @@ -221,19 +220,6 @@ class DefaultUserService extends BaseService { return tmp_password; }); } - _register_commands (commands) { - commands.registerCommands('default-user', [ - { - id: 'reset-password', - handler: async (args, ctx) => { - const [username] = args; - const user = await get_user({ username }); - const tmp_pwd = await this.force_tmp_password_(user); - ctx.log(`New password for ${quot(username)} is: ${tmp_pwd}`); - }, - }, - ]); - } } module.exports = DefaultUserService; diff --git a/src/backend/src/modules/selfhosted/SelfhostedService.js b/src/backend/src/modules/selfhosted/SelfhostedService.js index d0cf95d8f..fbdde8752 100644 --- a/src/backend/src/modules/selfhosted/SelfhostedService.js +++ b/src/backend/src/modules/selfhosted/SelfhostedService.js @@ -25,57 +25,6 @@ class SelfhostedService extends BaseService { `; async _init () { - this._register_commands(this.services.get('commands')); - } - - _register_commands (commands) { - const db = this.services.get('database').get(DB_WRITE, 'selfhosted'); - commands.registerCommands('app', [ - { - id: 'godmode-on', - description: 'Toggle godmode for an app', - handler: async (args, _log) => { - const svc_su = this.services.get('su'); - await await svc_su.sudo(async () => { - const [app_uid] = args; - const es_app = await this.services.get('es:app'); - const app = await es_app.read(app_uid); - if ( ! app ) { - throw new Error(`App ${app_uid} not found`); - } - await db.write('UPDATE apps SET godmode = 1 WHERE uid = ?', [app_uid]); - const svc_event = this.services.get('event'); - await svc_event.emit('app.changed', { - app_uid, - action: 'updated', - }); - }); - }, - }, - ]); - commands.registerCommands('app', [ - { - id: 'godmode-off', - description: 'Toggle godmode for an app', - handler: async (args, _log) => { - const svc_su = this.services.get('su'); - await await svc_su.sudo(async () => { - const [app_uid] = args; - const es_app = await this.services.get('es:app'); - const app = await es_app.read(app_uid); - if ( ! app ) { - throw new Error(`App ${app_uid} not found`); - } - await db.write('UPDATE apps SET godmode = 0 WHERE uid = ?', [app_uid]); - const svc_event = this.services.get('event'); - await svc_event.emit('app.changed', { - app_uid, - action: 'updated', - }); - }); - }, - }, - ]); } } diff --git a/src/backend/src/modules/test-core/TestCoreModule.js b/src/backend/src/modules/test-core/TestCoreModule.js index aa28a81ec..5711fced3 100644 --- a/src/backend/src/modules/test-core/TestCoreModule.js +++ b/src/backend/src/modules/test-core/TestCoreModule.js @@ -33,7 +33,6 @@ export class TestCoreModule { services.registerService('su', SUService); services.registerService('alarm', AlarmService); services.registerService('event', EventService); - services.registerService('commands', CommandService); services.registerService('meteringService', MeteringServiceWrapper); services.registerService('puter-kvstore', DynamoKVStoreWrapper); services.registerService('permission', PermissionService); diff --git a/src/backend/src/modules/web/WebServerService.js b/src/backend/src/modules/web/WebServerService.js index caf3639b8..be74ef6f7 100644 --- a/src/backend/src/modules/web/WebServerService.js +++ b/src/backend/src/modules/web/WebServerService.js @@ -136,6 +136,7 @@ class WebServerService extends BaseService { * @returns {Promise} A promise that resolves once the server is started. */ async '__on_boot.activation' () { + console.log('starting webser'); const services = this.services; await services.emit('start.webserver'); await services.emit('ready.webserver'); diff --git a/src/backend/src/services/CommandService.js b/src/backend/src/services/CommandService.js index ee7155809..e69de29bb 100644 --- a/src/backend/src/services/CommandService.js +++ b/src/backend/src/services/CommandService.js @@ -1,204 +0,0 @@ -/* - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -const { Context } = require('../util/context'); -const BaseService = require('./BaseService'); - -/** -* Represents a Command class that encapsulates command execution functionality. -* Each Command instance contains a specification (spec) that defines its ID, -* name, description, handler function, and optional argument completer. -* The class provides methods for executing commands and handling command -* argument completion. -*/ -class Command { - constructor (spec) { - this.spec_ = spec; - } - - /** - * Gets the unique identifier for this command - * @returns {string} The command's ID as specified in the constructor - */ - get id () { - return this.spec_.id; - } - - /** - * Executes the command with given arguments and logging - * @param {Array} args - Command arguments to pass to the handler - * @param {Object} [log=console] - Logger object for output, defaults to console - * @returns {Promise} - * @throws {Error} Logs any errors that occur during command execution - */ - async execute (args, log) { - log = log ?? console; - const { id, name, description, handler } = this.spec_; - try { - await handler(args, log); - } catch ( err ) { - log.error(`command ${name ?? id} failed: ${err.message}`); - log.error(err.stack); - } - } - - completeArgument (args) { - const completer = this.spec_.completer; - if ( completer ) - { - return completer(args); - } - return []; - } -} - -/** -* CommandService class manages the registration, execution, and handling of commands in the Puter system. -* Extends BaseService to provide command-line interface functionality. Maintains a collection of Command -* objects, supports command registration with namespaces, command execution with arguments, and provides -* command lookup capabilities. Includes built-in help command functionality. -* @extends BaseService -*/ -class CommandService extends BaseService { - /** - * Initializes the command service's internal state - * Called during service construction to set up the empty commands array - */ - async _construct () { - this.commands_ = []; - } - - /** - * Add the help command to the list of commands on init - */ - async _init () { - this.commands_.push(new Command({ - id: 'help', - description: 'show this help', - handler: (args, log) => { - log.log('available commands:'); - for ( const command of this.commands_ ) { - log.log(`- ${command.spec_.id}: ${command.spec_.description}`); - } - }, - })); - } - - async '__on_boot.consolidation' () { - const svc_event = this.services.get('event'); - const svc_command = this; - const event = { - createCommand (name, command) { - const serviceName = Context.get('extension_name') ?? '%missing%'; - const commandSpec = typeof command === 'function' - ? { handler: command } - : command; - if ( typeof commandSpec !== 'object' ) { - throw new Error('command must be either a function or an object'); - } - if ( ! (typeof command.handler === 'function') ) { - throw new Error('command should have a handler function'); - } - svc_command.registerCommands(serviceName, [{ - id: name, - ...commandSpec, - }]); - }, - }; - svc_event.emit('create.commands', event); - } - - registerCommands (serviceName, commands) { - if ( ! this.log ) { - /* eslint-disable */ - console.error( - 'CommandService.registerCommands was called before a logger ' + - 'was initialied. This happens when calling registerCommands ' + - 'in the "construct" phase instead of the "init" phase. If ' + - 'you are migrating a legacy service that does not extend ' + - 'BaseService, maybe the _construct hook is calling init()' - ); - /* eslint-enable */ - process.exit(1); - } - for ( const command of commands ) { - this.log.debug(`registering command ${serviceName}:${command.id}`); - this.commands_.push(new Command({ - ...command, - id: `${serviceName}:${command.id}`, - })); - } - } - - /** - * Executes a command with the given arguments and logging context - * @param {string[]} args - Array of command arguments where first element is command name - * @param {Object} log - Logger object for output (defaults to console if not provided) - * @returns {Promise} - * @throws {Error} If command execution fails - */ - async executeCommand (args, log) { - const [commandName, ...commandArgs] = args; - const command = this.commands_.find(c => c.spec_.id === commandName); - if ( ! command ) { - log.error(`unknown command: ${commandName}`); - return; - } - /** - * Executes a command with the given arguments in a global context - * @param {string[]} args - Array of command arguments where first element is command name - * @param {Object} log - Logger object for output - * @returns {Promise} - * @throws {Error} If command execution fails - */ - await globalThis.root_context.sub({ - injected_logger: log, - }).arun(async () => { - await command.execute(commandArgs, log); - }); - } - - /** - * Executes a raw command string by splitting it into arguments and executing the command - * @param {string} text - Raw command string to execute - * @param {object} log - Logger object for output (defaults to console if not provided) - * @returns {Promise} - * @todo Replace basic whitespace splitting with proper tokenizer (obvious-json) - */ - async executeRawCommand (text, log) { - // TODO: add obvious-json as a tokenizer - const args = text.split(/\s+/); - await this.executeCommand(args, log); - } - - /** - * Gets a list of all registered command names/IDs - * @returns {string[]} Array of command identifier strings - */ - get commandNames () { - return this.commands_.map(command => command.id); - } - - getCommand (id) { - return this.commands_.find(command => command.id === id); - } -} - -module.exports = { - CommandService, -}; diff --git a/src/backend/src/services/CommandService.test.ts b/src/backend/src/services/CommandService.test.ts index 3d4c02a39..e69de29bb 100644 --- a/src/backend/src/services/CommandService.test.ts +++ b/src/backend/src/services/CommandService.test.ts @@ -1,120 +0,0 @@ -import { describe, expect, it, vi } from 'vitest'; -import { createTestKernel } from '../../tools/test.mjs'; -import { CommandService } from './CommandService'; - -describe('CommandService', async () => { - const testKernel = await createTestKernel({ - serviceMap: { - commands: CommandService, - }, - initLevelString: 'init', - }); - - const commandService = testKernel.services!.get('commands') as CommandService; - - it('should be instantiated', () => { - expect(commandService).toBeInstanceOf(CommandService); - }); - - it('should have help command registered by default', () => { - expect(commandService.commandNames).toContain('help'); - }); - - it('should register commands', () => { - commandService.registerCommands('test-service', [ - { - id: 'test-cmd', - description: 'A test command', - handler: async () => {}, - }, - ]); - expect(commandService.commandNames).toContain('test-service:test-cmd'); - }); - - it('should execute registered commands', async () => { - let executed = false; - commandService.registerCommands('exec-test', [ - { - id: 'exec-cmd', - description: 'Execute test', - handler: async () => { executed = true; }, - }, - ]); - - const mockLog = { error: vi.fn(), log: vi.fn() }; - await commandService.executeCommand(['exec-test:exec-cmd'], mockLog); - expect(executed).toBe(true); - }); - - it('should pass arguments to command handler', async () => { - let receivedArgs: string[] = []; - commandService.registerCommands('args-test', [ - { - id: 'args-cmd', - description: 'Args test', - handler: async (args) => { receivedArgs = args; }, - }, - ]); - - const mockLog = { error: vi.fn(), log: vi.fn() }; - await commandService.executeCommand(['args-test:args-cmd', 'arg1', 'arg2'], mockLog); - expect(receivedArgs).toEqual(['arg1', 'arg2']); - }); - - it('should handle unknown commands', async () => { - const mockLog = { error: vi.fn(), log: vi.fn() }; - await commandService.executeCommand(['unknown-command'], mockLog); - expect(mockLog.error).toHaveBeenCalledWith('unknown command: unknown-command'); - }); - - it('should execute raw commands', async () => { - let executed = false; - commandService.registerCommands('raw-test', [ - { - id: 'raw-cmd', - description: 'Raw test', - handler: async () => { executed = true; }, - }, - ]); - - const mockLog = { error: vi.fn(), log: vi.fn() }; - await commandService.executeRawCommand('raw-test:raw-cmd', mockLog); - expect(executed).toBe(true); - }); - - it('should get command by id', () => { - commandService.registerCommands('get-test', [ - { - id: 'get-cmd', - description: 'Get test', - handler: async () => {}, - }, - ]); - - const cmd = commandService.getCommand('get-test:get-cmd'); - expect(cmd).toBeDefined(); - expect(cmd?.id).toBe('get-test:get-cmd'); - }); - - it('should execute help command', async () => { - const mockLog = { error: vi.fn(), log: vi.fn() }; - await commandService.executeCommand(['help'], mockLog); - expect(mockLog.log).toHaveBeenCalledWith('available commands:'); - }); - - it('should support command completers', () => { - commandService.registerCommands('complete-test', [ - { - id: 'complete-cmd', - description: 'Complete test', - handler: async () => {}, - completer: (args) => ['option1', 'option2'], - }, - ]); - - const cmd = commandService.getCommand('complete-test:complete-cmd'); - const completions = cmd?.completeArgument([]); - expect(completions).toEqual(['option1', 'option2']); - }); -}); - diff --git a/src/backend/src/services/Container.js b/src/backend/src/services/Container.js index 07b25821b..117803b20 100644 --- a/src/backend/src/services/Container.js +++ b/src/backend/src/services/Container.js @@ -211,7 +211,17 @@ class Container { for ( const k in this.instances_ ) { try { if ( PARALLEL ) promises.push(this.instances_[k].init()); - else await this.instances_[k].init(); + else { + // Logic to get name of a service, unused but + // if you ever need to log the name + // this will be accurate + let name = this.instances_[k].constructor.name; + if ( name === 'ExtensionService' ) { + name = this.instances_[k].args.state.extension.runtime.name; + } + + await this.instances_[k].init(); + } } catch (e) { init_failures.push({ k, e }); } diff --git a/src/backend/src/services/EngPortalService.js b/src/backend/src/services/EngPortalService.js deleted file mode 100644 index 06e6c9d20..000000000 --- a/src/backend/src/services/EngPortalService.js +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2024-present Puter Technologies Inc. - * - * This file is part of Puter. - * - * Puter is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -const { AdvancedBase } = require('@heyputer/putility'); - -/** -* @class EngPortalService -* @extends {AdvancedBase} -* -* EngPortalService is a class that provides services for managing and accessing various operations, alarms, and statistics -* within a system. It inherits from the AdvancedBase class and utilizes multiple dependencies such as socket.io for communication -* and uuidv4 for generating unique identifiers. The class includes methods for listing operations, serializing frames, listing alarms, -* fetching server statistics, and registering command handlers. This class is integral to maintaining and monitoring system health -* and operations efficiently. -*/ -class EngPortalService extends AdvancedBase { - static MODULES = { - uuidv4: require('uuid').v4, - }; - - constructor ({ services }) { - super(); - this.services = services; - this.commands = services.get('commands'); - this._registerCommands(this.commands); - } - - /** - * Lists all ongoing operations. - * This method retrieves all ongoing operations from the 'operationTrace' service, - * serializes them, and returns the serialized list. - * - * @async - * @returns {Promise} A list of serialized operation frames. - */ - async list_operations () { - const svc_operationTrace = this.services.get('operationTrace'); - const ls = []; - for ( const id in svc_operationTrace.ongoing ) { - const op = svc_operationTrace.ongoing[id]; - ls.push(this._serialize_frame(op)); - } - - return ls; - } - - _serialize_frame (frame) { - const out = { - id: frame.id, - label: frame.label, - status: frame.status, - async: frame.async, - checkpoint: frame.checkpoint, - // tags: frame.tags, - // attributes: frame.attributes, - // messages: frame.messages, - // error: frame.error_ ? frame.error_.message || true : null, - children: [], - attributes: {}, - }; - - for ( const k in frame.attributes ) { - out.attributes[k] = frame.attributes[k]; - } - - for ( const child of frame.children ) { - out.children.push(this._serialize_frame(child)); - } - - return out; - } - - /** - * Retrieves a list of alarms. - * - * This method fetches all active alarms from the 'alarm' service and returns a serialized array of alarm objects. - * - * @returns {Promise} A promise that resolves to an array of serialized alarm objects. - */ - async list_alarms () { - const svc_alarm = this.services.get('alarm'); - const ls = []; - for ( const id in svc_alarm.alarms ) { - const alarm = svc_alarm.alarms[id]; - ls.push(this._serialize_alarm(alarm)); - } - - return ls; - } - - /** - * Gets the system statistics. - * - * This method retrieves the system statistics from the server-health service and returns them. - * - * @async - * @returns {Promise} A promise that resolves to the system statistics. - */ - async get_stats () { - const svc_health = this.services.get('server-health'); - return await svc_health.get_stats(); - } - - _serialize_alarm (alarm) { - const out = { - id: alarm.id, - short_id: alarm.short_id, - started: alarm.started, - occurrances: alarm.occurrences.map(this._serialize_occurance.bind(this)), - ...(alarm.error ? { - error: { - message: alarm.error.message, - stack: alarm.error.stack, - }, - } : {}), - }; - - return out; - } - - _serialize_occurance (occurance) { - const out = { - message: occurance.message, - timestamp: occurance.timestamp, - fields: occurance.fields, - }; - - return out; - } - - _registerCommands (commands) { - this.commands.registerCommands('eng', [ - { - id: 'list-operations', - description: 'testing', - handler: async (args, log) => { - const ops = await this.list_operations(); - log.log(JSON.stringify(ops, null, 2)); - }, - }, - ]); - } -} - -module.exports = { - EngPortalService, -}; diff --git a/src/backend/src/services/LockService.js b/src/backend/src/services/LockService.js index 3a379e0ad..90eb3aab4 100644 --- a/src/backend/src/services/LockService.js +++ b/src/backend/src/services/LockService.js @@ -45,39 +45,6 @@ class LockService extends BaseService { * initialization is complete. */ async _init () { - const svc_commands = this.services.get('commands'); - svc_commands.registerCommands('lock', [ - { - id: 'locks', - description: 'lists locks', - handler: async (args, log) => { - for ( const name in this.locks ) { - let line = `${name }: `; - if ( this.locks[name].effective_mode === RWLock.TYPE_READ ) { - line += `READING (${this.locks[name].readers_})`; - log.log(line); - } - else - if ( this.locks[name].effective_mode === RWLock.TYPE_WRITE ) { - line += 'WRITING'; - log.log(line); - } - else { - line += 'UNKNOWN'; - log.log(line); - - // log the lock's internal state - const lines = JSON.stringify(this.locks[name], - null, - 2).split('\n'); - for ( const line of lines ) { - log.log(` -> ${ line}`); - } - } - } - }, - }, - ]); } /** diff --git a/src/backend/src/services/ScriptService.js b/src/backend/src/services/ScriptService.js index cabb8427c..29b970fe6 100644 --- a/src/backend/src/services/ScriptService.js +++ b/src/backend/src/services/ScriptService.js @@ -70,34 +70,7 @@ class ScriptService extends BaseService { * @returns {Promise} A promise that resolves when the initialization is complete. */ async _init () { - const svc_commands = this.services.get('commands'); - svc_commands.registerCommands('script', [ - { - id: 'run', - description: 'run a script', - handler: async (args, ctx) => { - const script_name = args.shift(); - const script = this.scripts.find(s => s.name === script_name); - if ( ! script ) { - ctx.error(`script not found: ${script_name}`); - return; - } - await script.run(ctx, args); - }, - completer: (args) => { - // The script name is the first argument, so return no results if we're on the second or later. - if ( args.length > 1 ) - { - return; - } - const scriptName = args[args.length - 1]; - return this.scripts - .filter(script => scriptName.startsWith(scriptName)) - .map(script => script.name); - }, - }, - ]); } register (name, fn) { diff --git a/src/backend/src/services/ai/chat/providers/OpenRouterProvider/OpenRouterProvider.ts b/src/backend/src/services/ai/chat/providers/OpenRouterProvider/OpenRouterProvider.ts index 57685c822..668bae356 100644 --- a/src/backend/src/services/ai/chat/providers/OpenRouterProvider/OpenRouterProvider.ts +++ b/src/backend/src/services/ai/chat/providers/OpenRouterProvider/OpenRouterProvider.ts @@ -158,47 +158,48 @@ export class OpenRouterProvider implements IChatProvider { } async models () { - let models = kv.get('openrouterChat:models'); - if ( ! models ) { - try { - const resp = await axios.request({ - method: 'GET', - url: `${this.#apiBaseUrl}/models`, - }); + return [] as IChatModel[]; + // let models = kv.get('openrouterChat:models'); + // if ( ! models ) { + // try { + // const resp = await axios.request({ + // method: 'GET', + // url: `${this.#apiBaseUrl}/models`, + // }); - models = resp.data.data; - kv.set('openrouterChat:models', models); - } catch (e) { - console.log(e); - } - } - const coerced_models: IChatModel[] = []; - for ( const model of models ) { - if ( (model.id as string).includes('openrouter/auto') ) { - continue; - } - const overridenModel = OPEN_ROUTER_MODEL_OVERRIDES.find(m => m.id === `openrouter:${model.id}`); - const microcentCosts = Object.fromEntries(Object.entries(model.pricing).map(([k, v]) => [k, Math.round((v as number < 0 ? 1 : v as number) * 1_000_000 * 100)])) ; - if ( ! microcentCosts.request ) { - microcentCosts.request = 0; - } - coerced_models.push({ - id: `openrouter:${model.id}`, - name: `${model.name} (OpenRouter)`, - aliases: [model.id, model.name, `openrouter/${model.id}`, model.id.split('/').slice(1).join('/')], - context: model.context_length, - max_tokens: model.top_provider.max_completion_tokens, - costs_currency: 'usd-cents', - input_cost_key: 'prompt', - output_cost_key: 'completion', - costs: { - tokens: 1_000_000, - ...microcentCosts, - }, - ...overridenModel, - }); - } - return coerced_models; + // models = resp.data.data; + // kv.set('openrouterChat:models', models); + // } catch (e) { + // console.log(e); + // } + // } + // const coerced_models: IChatModel[] = []; + // for ( const model of models ) { + // if ( (model.id as string).includes('openrouter/auto') ) { + // continue; + // } + // const overridenModel = OPEN_ROUTER_MODEL_OVERRIDES.find(m => m.id === `openrouter:${model.id}`); + // const microcentCosts = Object.fromEntries(Object.entries(model.pricing).map(([k, v]) => [k, Math.round((v as number < 0 ? 1 : v as number) * 1_000_000 * 100)])) ; + // if ( ! microcentCosts.request ) { + // microcentCosts.request = 0; + // } + // coerced_models.push({ + // id: `openrouter:${model.id}`, + // name: `${model.name} (OpenRouter)`, + // aliases: [model.id, model.name, `openrouter/${model.id}`, model.id.split('/').slice(1).join('/')], + // context: model.context_length, + // max_tokens: model.top_provider.max_completion_tokens, + // costs_currency: 'usd-cents', + // input_cost_key: 'prompt', + // output_cost_key: 'completion', + // costs: { + // tokens: 1_000_000, + // ...microcentCosts, + // }, + // ...overridenModel, + // }); + // } + // return coerced_models; } checkModeration (_text: string): ReturnType { throw new Error('Method not implemented.'); diff --git a/src/backend/src/services/auth/PermissionService.js b/src/backend/src/services/auth/PermissionService.js index 4ab0a7f5f..182259e7e 100644 --- a/src/backend/src/services/auth/PermissionService.js +++ b/src/backend/src/services/auth/PermissionService.js @@ -71,7 +71,6 @@ class PermissionService extends BaseService { */ this.kvService = this.services.get('puter-kvstore').as('puter-kvstore'); this.db = this.services.get('database').get(DB_WRITE, 'permissions'); - this._register_commands(this.services.get('commands')); this.kvAvgTimes = { count: 0, avg: 0, max: 0 }; this.dbAvgTimes = { count: 0, avg: 0, max: 0 }; } @@ -1272,62 +1271,6 @@ class PermissionService extends BaseService { this._permission_exploders.push(exploder); } - - _register_commands (commands) { - commands.registerCommands('perms', [ - { - id: 'grant-user-app', - handler: async (args, _log) => { - const [username, app_uid, permission, extra] = args; - - // actor from username - const actor = new Actor({ - type: new UserActorType({ - user: await get_user({ username }), - }), - }); - - await this.grant_user_app_permission(actor, app_uid, permission, extra); - }, - }, - { - id: 'scan', - handler: async (args, ctx) => { - const [username, permission] = args; - - // actor from username - const actor = new Actor({ - type: new UserActorType({ - user: await get_user({ username }), - }), - }); - - let reading = await this.scan(actor, permission); - // reading = PermissionUtil.reading_to_options(reading); - ctx.log(JSON.stringify(reading, undefined, ' ')); - }, - }, - { - id: 'scan-app', - handler: async (args, ctx) => { - const [username, app_name, permission] = args; - const app = await get_app({ name: app_name }); - - // actor from username - const actor = new Actor({ - type: new AppUnderUserActorType({ - app, - user: await get_user({ username }), - }), - }); - - const reading = await this.scan(actor, permission); - // reading = PermissionUtil.reading_to_options(reading); - ctx.log(JSON.stringify(reading, undefined, ' ')); - }, - }, - ]); - } } module.exports = { diff --git a/src/backend/src/services/database/SqliteDatabaseAccessService.js b/src/backend/src/services/database/SqliteDatabaseAccessService.js index 4348c31a1..40d6849be 100644 --- a/src/backend/src/services/database/SqliteDatabaseAccessService.js +++ b/src/backend/src/services/database/SqliteDatabaseAccessService.js @@ -270,7 +270,6 @@ class SqliteDatabaseAccessService extends BaseDatabaseAccessService { } async '__on_boot.consolidation' () { - this._register_commands(this.services.get('commands')); } /** @@ -372,37 +371,6 @@ class SqliteDatabaseAccessService extends BaseDatabaseAccessService { await vm.runInContext(contents, context); } - _register_commands (commands) { - commands.registerCommands('sqlite', [ - { - id: 'execfile', - description: 'execute a file', - handler: async (args, log) => { - try { - const [filename] = args; - const fs = require('fs'); - const contents = fs.readFileSync(filename, 'utf8'); - this.db.exec(contents); - } catch ( err ) { - log.error(err.message); - } - }, - }, - { - id: 'read', - description: 'read a query', - handler: async (args, log) => { - try { - const [query] = args; - const rows = this._read(query, []); - log.log(rows); - } catch ( err ) { - log.error(err.message); - } - }, - }, - ]); - } } module.exports = { diff --git a/src/backend/src/services/fs/FSLockService.js b/src/backend/src/services/fs/FSLockService.js index 692990cb3..9a8c032c5 100644 --- a/src/backend/src/services/fs/FSLockService.js +++ b/src/backend/src/services/fs/FSLockService.js @@ -44,39 +44,6 @@ class FSLockService extends BaseService { * @returns {Promise} A promise that resolves when the initialization is complete. */ async _init () { - const svc_commands = this.services.get('commands'); - svc_commands.registerCommands('fslock', [ - { - id: 'locks', - description: 'lists locks', - handler: async (args, log) => { - for ( const path in this.locks ) { - let line = `${path }: `; - if ( this.locks[path].effective_mode === MODE_READ ) { - line += `READING (${this.locks[path].readers_})`; - log.log(line); - } - else - if ( this.locks[path].effective_mode === MODE_WRITE ) { - line += 'WRITING'; - log.log(line); - } - else { - line += 'UNKNOWN'; - log.log(line); - - // log the lock's internal state - const lines = JSON.stringify(this.locks[path], - null, - 2).split('\n'); - for ( const line of lines ) { - log.log(` -> ${ line}`); - } - } - } - }, - }, - ]); } /** diff --git a/src/backend/src/services/periodic/FSEntryMigrateService.js b/src/backend/src/services/periodic/FSEntryMigrateService.js index fb01737a2..2f636ab51 100644 --- a/src/backend/src/services/periodic/FSEntryMigrateService.js +++ b/src/backend/src/services/periodic/FSEntryMigrateService.js @@ -104,7 +104,8 @@ class Mig_StorePath extends Job { for ( ;; ) { const t_0 = performance.now(); const [fsentries] = await dbrr.promise().execute( - 'SELECT id, uuid FROM fsentries WHERE path IS NULL ORDER BY accessed DESC LIMIT 50'); + 'SELECT id, uuid FROM fsentries WHERE path IS NULL ORDER BY accessed DESC LIMIT 50', + ); if ( fsentries.length === 0 ) { log.info('No more fsentries to migrate'); @@ -127,8 +128,9 @@ class Mig_StorePath extends Job { log.info(`id=${fsentry.id} uuid=${fsentry.uuid} path=${path}`); } await dbrw.promise().execute( - 'UPDATE fsentries SET path=? WHERE id=?', - [path, fsentry.id]); + 'UPDATE fsentries SET path=? WHERE id=?', + [path, fsentry.id], + ); } const t_1 = performance.now(); @@ -173,7 +175,8 @@ class Mig_IndexAccessed extends Job { log.info('Running update statement'); const t_0 = performance.now(); const [results] = await dbrr.promise().execute( - 'UPDATE fsentries SET accessed = COALESCE(accessed, created) WHERE accessed IS NULL LIMIT 10000'); + 'UPDATE fsentries SET accessed = COALESCE(accessed, created) WHERE accessed IS NULL LIMIT 10000', + ); log.info(`Updated ${results.affectedRows} rows`); if ( results.affectedRows === 0 ) { @@ -369,43 +372,19 @@ class Mig_AuditInitialStorage extends Job { * independently. */ class FSEntryMigrateService { - constructor ({ services }) { - const mysql = services.get('mysql'); - const dbrr = mysql.get(DB_MODE_READ, 'fsentry-migrate'); - const dbrw = mysql.get(DB_MODE_WRITE, 'fsentry-migrate'); - const log = services.get('log-service').create('fsentry-migrate'); + constructor (_) { + // const mysql = services.get('mysql'); + // const dbrr = mysql.get(DB_MODE_READ, 'fsentry-migrate'); + // const dbrw = mysql.get(DB_MODE_WRITE, 'fsentry-migrate'); + // const log = services.get('log-service').create('fsentry-migrate'); - const migrations = { - 'store-path': new Mig_StorePath({ dbrr, dbrw, log }), - 'index-accessed': new Mig_IndexAccessed({ dbrr, dbrw, log }), - 'fix-trash': new Mig_FixTrash({ dbrr, dbrw, log }), - 'gen-referral-codes': new Mig_AddReferralCodes({ dbrr, dbrw, log }), - }; + // const migrations = { + // 'store-path': new Mig_StorePath({ dbrr, dbrw, log }), + // 'index-accessed': new Mig_IndexAccessed({ dbrr, dbrw, log }), + // 'fix-trash': new Mig_FixTrash({ dbrr, dbrw, log }), + // 'gen-referral-codes': new Mig_AddReferralCodes({ dbrr, dbrw, log }), + // }; - services.get('commands').registerCommands('fsentry-migrate', [ - { - id: 'start', - description: 'start a migration', - handler: async (args, log) => { - const [migration] = args; - if ( ! migrations[migration] ) { - throw new Error(`unknown migration: ${migration}`); - } - migrations[migration].start(args.slice(1)); - }, - }, - { - id: 'stop', - description: 'stop a migration', - handler: async (args, log) => { - const [migration] = args; - if ( ! migrations[migration] ) { - throw new Error(`unknown migration: ${migration}`); - } - migrations[migration].stop(); - }, - }, - ]); } }