mirror of
https://github.com/matrix-construct/construct
synced 2024-12-27 07:54:05 +01:00
ircd:Ⓜ️:app: Application management infrastructure w/ cmd suite.
This commit is contained in:
parent
7c931b880e
commit
5d7f56a5ce
6 changed files with 329 additions and 0 deletions
37
include/ircd/m/app.h
Normal file
37
include/ircd/m/app.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
// The Construct
|
||||||
|
//
|
||||||
|
// Copyright (C) The Construct Developers, Authors & Contributors
|
||||||
|
// Copyright (C) 2016-2020 Jason Volk <jason@zemos.net>
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice is present in all copies. The
|
||||||
|
// full license for this software is available in the LICENSE file.
|
||||||
|
|
||||||
|
namespace ircd::m
|
||||||
|
{
|
||||||
|
struct app;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ircd::m::app
|
||||||
|
:instance_list<ircd::m::app>
|
||||||
|
{
|
||||||
|
static log::log log;
|
||||||
|
static conf::item<std::string> path;
|
||||||
|
static std::set<std::string> bin;
|
||||||
|
|
||||||
|
m::event::idx event_idx;
|
||||||
|
std::string feature;
|
||||||
|
json::object config;
|
||||||
|
json::array arg;
|
||||||
|
std::vector<json::string> argv;
|
||||||
|
exec child;
|
||||||
|
context worker_context;
|
||||||
|
|
||||||
|
void worker();
|
||||||
|
|
||||||
|
app(const m::event::idx &);
|
||||||
|
~app() noexcept;
|
||||||
|
|
||||||
|
static void init(), fini();
|
||||||
|
};
|
|
@ -89,6 +89,7 @@ namespace ircd
|
||||||
#include "visible.h"
|
#include "visible.h"
|
||||||
#include "redacted.h"
|
#include "redacted.h"
|
||||||
#include "feds.h"
|
#include "feds.h"
|
||||||
|
#include "app.h"
|
||||||
#include "bridge.h"
|
#include "bridge.h"
|
||||||
#include "sync/sync.h"
|
#include "sync/sync.h"
|
||||||
#include "fetch.h"
|
#include "fetch.h"
|
||||||
|
|
|
@ -136,6 +136,7 @@ libircd_matrix_la_SOURCES += user_room_tags.cc
|
||||||
libircd_matrix_la_SOURCES += user_rooms.cc
|
libircd_matrix_la_SOURCES += user_rooms.cc
|
||||||
libircd_matrix_la_SOURCES += user_tokens.cc
|
libircd_matrix_la_SOURCES += user_tokens.cc
|
||||||
libircd_matrix_la_SOURCES += acquire.cc
|
libircd_matrix_la_SOURCES += acquire.cc
|
||||||
|
libircd_matrix_la_SOURCES += app.cc
|
||||||
libircd_matrix_la_SOURCES += bridge.cc
|
libircd_matrix_la_SOURCES += bridge.cc
|
||||||
libircd_matrix_la_SOURCES += breadcrumbs.cc
|
libircd_matrix_la_SOURCES += breadcrumbs.cc
|
||||||
libircd_matrix_la_SOURCES += burst.cc
|
libircd_matrix_la_SOURCES += burst.cc
|
||||||
|
|
196
matrix/app.cc
Normal file
196
matrix/app.cc
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
// The Construct
|
||||||
|
//
|
||||||
|
// Copyright (C) The Construct Developers, Authors & Contributors
|
||||||
|
// Copyright (C) 2016-2020 Jason Volk <jason@zemos.net>
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice is present in all copies. The
|
||||||
|
// full license for this software is available in the LICENSE file.
|
||||||
|
|
||||||
|
decltype(ircd::m::app::log)
|
||||||
|
ircd::m::app::log
|
||||||
|
{
|
||||||
|
"m.app"
|
||||||
|
};
|
||||||
|
|
||||||
|
decltype(ircd::m::app::path)
|
||||||
|
ircd::m::app::path
|
||||||
|
{
|
||||||
|
{ "name", "ircd.m.app.path" },
|
||||||
|
{ "default", string_view{} },
|
||||||
|
{ "persist", false },
|
||||||
|
};
|
||||||
|
|
||||||
|
decltype(ircd::m::app::bin)
|
||||||
|
ircd::m::app::bin;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
decltype(ircd::util::instance_list<ircd::m::app>::allocator)
|
||||||
|
ircd::util::instance_list<ircd::m::app>::allocator{};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
decltype(ircd::util::instance_list<ircd::m::app>::list)
|
||||||
|
ircd::util::instance_list<ircd::m::app>::list
|
||||||
|
{
|
||||||
|
allocator
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// init
|
||||||
|
//
|
||||||
|
|
||||||
|
void
|
||||||
|
ircd::m::app::init()
|
||||||
|
{
|
||||||
|
static const auto not_executable{[]
|
||||||
|
(const std::string &file)
|
||||||
|
{
|
||||||
|
return !fs::is_exec(file);
|
||||||
|
}};
|
||||||
|
|
||||||
|
std::vector<std::string> files
|
||||||
|
{
|
||||||
|
bool(path)?
|
||||||
|
fs::ls(string_view(path)):
|
||||||
|
std::vector<std::string>{}
|
||||||
|
};
|
||||||
|
|
||||||
|
bin = std::set<std::string>
|
||||||
|
{
|
||||||
|
begin(files), std::remove_if(begin(files), end(files), not_executable)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ircd::m::app::fini()
|
||||||
|
{
|
||||||
|
std::vector<app *> apps
|
||||||
|
{
|
||||||
|
std::begin(list), std::end(list)
|
||||||
|
};
|
||||||
|
|
||||||
|
for(auto *const &app : apps)
|
||||||
|
delete app;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// app::app
|
||||||
|
//
|
||||||
|
|
||||||
|
ircd::m::app::app(const m::event::idx &event_idx)
|
||||||
|
:event_idx
|
||||||
|
{
|
||||||
|
event_idx
|
||||||
|
}
|
||||||
|
,feature
|
||||||
|
{
|
||||||
|
m::get(event_idx, "content")
|
||||||
|
}
|
||||||
|
,config
|
||||||
|
{
|
||||||
|
feature
|
||||||
|
}
|
||||||
|
,arg
|
||||||
|
{
|
||||||
|
config.at("arg")
|
||||||
|
}
|
||||||
|
,argv
|
||||||
|
{
|
||||||
|
std::begin(arg), std::end(arg)
|
||||||
|
}
|
||||||
|
,child
|
||||||
|
{
|
||||||
|
argv
|
||||||
|
}
|
||||||
|
,worker_context
|
||||||
|
{
|
||||||
|
"m.app",
|
||||||
|
512_KiB,
|
||||||
|
std::bind(&app::worker, this)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ircd::m::app::~app()
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
worker_context.interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ircd::m::app::worker()
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const auto event_id
|
||||||
|
{
|
||||||
|
m::event_id(event_idx)
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto room_id
|
||||||
|
{
|
||||||
|
m::room_id(event_idx)
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto user_id
|
||||||
|
{
|
||||||
|
m::get(event_idx, "sender")
|
||||||
|
};
|
||||||
|
|
||||||
|
log::info
|
||||||
|
{
|
||||||
|
log, "app:%lu starting %s in %s for %s @ `%s' id:%lu pid:%ld",
|
||||||
|
event_idx,
|
||||||
|
string_view{event_id},
|
||||||
|
string_view{room_id},
|
||||||
|
string_view{user_id},
|
||||||
|
argv.at(0),
|
||||||
|
child.id,
|
||||||
|
child.pid,
|
||||||
|
};
|
||||||
|
|
||||||
|
char buf alignas(4096) [16_KiB];
|
||||||
|
for(run::barrier<ctx::interrupted>{};; )
|
||||||
|
{
|
||||||
|
const string_view &output
|
||||||
|
{
|
||||||
|
read(child, buf)
|
||||||
|
};
|
||||||
|
|
||||||
|
if(empty(output))
|
||||||
|
{
|
||||||
|
child.join();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto message_id
|
||||||
|
{
|
||||||
|
m::notice(room_id, user_id, output)
|
||||||
|
};
|
||||||
|
|
||||||
|
log::debug
|
||||||
|
{
|
||||||
|
log, "app:%lu output %zu bytes in %s to %s :%s%s",
|
||||||
|
event_idx,
|
||||||
|
size(output),
|
||||||
|
string_view{message_id},
|
||||||
|
string_view{room_id},
|
||||||
|
trunc(output, 64),
|
||||||
|
size(output) > 64? "..."_sv: ""_sv,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(const std::exception &e)
|
||||||
|
{
|
||||||
|
log::error
|
||||||
|
{
|
||||||
|
log, "app:%lu (%p) worker fatal :%s",
|
||||||
|
event_idx,
|
||||||
|
this,
|
||||||
|
e.what(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const ctx::exception_handler eh;
|
||||||
|
child.join();
|
||||||
|
return;
|
||||||
|
}
|
|
@ -279,6 +279,9 @@ try
|
||||||
if(key && !key->verify_keys.empty())
|
if(key && !key->verify_keys.empty())
|
||||||
m::keys::cache::set(key->verify_keys);
|
m::keys::cache::set(key->verify_keys);
|
||||||
|
|
||||||
|
if(!ircd::maintenance)
|
||||||
|
m::app::init();
|
||||||
|
|
||||||
if(!ircd::maintenance)
|
if(!ircd::maintenance)
|
||||||
signon(*this);
|
signon(*this);
|
||||||
|
|
||||||
|
@ -317,6 +320,7 @@ noexcept try
|
||||||
mods::imports.erase("net_dns_cache"s);
|
mods::imports.erase("net_dns_cache"s);
|
||||||
_fetch.reset(nullptr);
|
_fetch.reset(nullptr);
|
||||||
_vm.reset(nullptr);
|
_vm.reset(nullptr);
|
||||||
|
m::app::fini();
|
||||||
}
|
}
|
||||||
catch(const std::exception &e)
|
catch(const std::exception &e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -16270,3 +16270,93 @@ console_cmd__exec(opt &out, const string_view &line)
|
||||||
out << in << std::endl;
|
out << in << std::endl;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// app
|
||||||
|
//
|
||||||
|
|
||||||
|
bool
|
||||||
|
console_cmd__app(opt &out, const string_view &line)
|
||||||
|
{
|
||||||
|
for(const auto *const &app : ircd::m::app::list)
|
||||||
|
out
|
||||||
|
<< " " << std::right << std::setw(5) << app->child.id
|
||||||
|
<< " " << std::right << std::setw(5) << app->child.code
|
||||||
|
<< " " << std::right << std::setw(10) << app->child.pid
|
||||||
|
<< " " << std::left << std::setw(40) << string_view{m::room_id(app->event_idx)}
|
||||||
|
<< " " << std::left << std::setw(40) << string_view{m::event_id(app->event_idx)}
|
||||||
|
<< " :" << app->argv.at(0)
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
console_cmd__app__start(opt &out, const string_view &line)
|
||||||
|
{
|
||||||
|
const params param{line, " ",
|
||||||
|
{
|
||||||
|
"room_id", "name"
|
||||||
|
}};
|
||||||
|
|
||||||
|
const auto room_id
|
||||||
|
{
|
||||||
|
m::room_id(param.at("room_id"))
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto name
|
||||||
|
{
|
||||||
|
param.at("name")
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto event_idx
|
||||||
|
{
|
||||||
|
m::room(room_id).get("ircd.app", name)
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<m::app> app
|
||||||
|
{
|
||||||
|
std::make_unique<m::app>(event_idx)
|
||||||
|
};
|
||||||
|
|
||||||
|
out << "Started PID " << app->child.pid << "..." << std::endl;
|
||||||
|
app.release();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
console_cmd__app__stop(opt &out, const string_view &line)
|
||||||
|
{
|
||||||
|
const params param{line, " ",
|
||||||
|
{
|
||||||
|
"room_id", "name"
|
||||||
|
}};
|
||||||
|
|
||||||
|
const auto room_id
|
||||||
|
{
|
||||||
|
m::room_id(param.at("room_id"))
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto name
|
||||||
|
{
|
||||||
|
param["name"]
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto event_idx
|
||||||
|
{
|
||||||
|
m::valid(m::id::EVENT, param.at("room_id"))?
|
||||||
|
m::index(param.at("room_id")):
|
||||||
|
m::room(room_id).get("ircd.app", name)
|
||||||
|
};
|
||||||
|
|
||||||
|
for(auto *const &app : m::app::list)
|
||||||
|
if(app->event_idx == event_idx)
|
||||||
|
{
|
||||||
|
out << "Stopped PID " << app->child.pid << "..." << std::endl;
|
||||||
|
delete app;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
out << "not found." << std::endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue