123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- /*
- * Copyright (C) 2024 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 <https://www.gnu.org/licenses/>.
- */
- const { AdvancedBase } = require("puter-js-common");
- const { Context } = require('./util/context');
- class Kernel extends AdvancedBase {
- constructor () {
- super();
- this.modules = [];
- }
- add_module (module) {
- this.modules.push(module);
- }
- _runtime_init () {
- const kvjs = require('@heyputer/kv.js');
- const kv = new kvjs();
- global.kv = kv;
- global.cl = console.log;
- const { RuntimeEnvironment } = require('./boot/RuntimeEnvironment');
- const { BootLogger } = require('./boot/BootLogger');
- // Temporary logger for boot process;
- // LoggerService will be initialized in app.js
- const bootLogger = new BootLogger();
- // Determine config and runtime locations
- const runtimeEnv = new RuntimeEnvironment({
- logger: bootLogger,
- });
- runtimeEnv.init();
- // polyfills
- require('./polyfill/to-string-higher-radix');
- }
- boot () {
- this._runtime_init();
- // const express = require('express')
- // const app = express();
- const config = require('./config');
- globalThis.xtra_log = () => {};
- if ( config.env === 'dev' ) {
- globalThis.xtra_log = (...args) => {
- // append to file in temp
- const fs = require('fs');
- const path = require('path');
- const log_path = path.join('/tmp/xtra_log.txt');
- fs.appendFileSync(log_path, args.join(' ') + '\n');
- }
- }
- const { consoleLogManager } = require('./util/consolelog');
- consoleLogManager.initialize_proxy_methods();
- // TODO: temporary dependency inversion; requires moving:
- // - rm, so we can move mv
- // - mv, so we can move mkdir
- // - generate_default_fsentries, so we can move mkdir
- // - mkdir, which needs an fs provider
- // === START: Initialize Service Registry ===
- const { Container } = require('./services/Container');
- const services = new Container();
- this.services = services;
- // app.set('services', services);
- const root_context = Context.create({
- services,
- config,
- }, 'app');
- globalThis.root_context = root_context;
- root_context.arun(async () => {
- await this._install_modules();
- await this._boot_services();
- });
- // Error.stackTraceLimit = Infinity;
- Error.stackTraceLimit = 200;
- }
- async _install_modules () {
- const { services } = this;
- for ( const module of this.modules ) {
- await module.install(Context.get());
- }
- try {
- await services.init();
- } catch (e) {
- // First we'll try to mark the system as invalid via
- // SystemValidationService. This might fail because this service
- // may not be initialized yet.
- const svc_systemValidation = (() => {
- try {
- return services.get('system-validation');
- } catch (e) {
- return null;
- }
- })();
- if ( ! svc_systemValidation ) {
- // If we can't mark the system as invalid, we'll just have to
- // throw the error and let the server crash.
- throw e;
- }
- await svc_systemValidation.mark_invalid(
- 'failed to initialize services',
- e,
- );
- }
- for ( const module of this.modules ) {
- await module.install_legacy?.(Context.get());
- }
- services.ready.resolve();
- // provide services to helpers
- const { tmp_provide_services } = require('./helpers');
- tmp_provide_services(services);
- }
- async _boot_services () {
- const { services } = this;
- await services.ready;
- {
- const app = services.get('web-server').app;
- app.use(async (req, res, next) => {
- req.services = services;
- next();
- });
- await services.emit('boot.services-initialized');
- await services.emit('install.middlewares.context-aware', { app });
- await services.emit('install.routes', { app });
- await services.emit('install.routes-gui', { app });
- }
- // === END: Initialize Service Registry ===
- // self check
- (async () => {
- await services.ready;
- globalThis.services = services;
- const log = services.get('log-service').create('init');
- log.info('services ready');
- log.system('server ready', {
- deployment_type: globalThis.deployment_type,
- });
- })();
- await services.emit('start.webserver');
- await services.emit('ready.webserver');
- }
- }
- module.exports = { Kernel };
|