Rework runtime init a little bit.

It was hardcoded that if KORE_USE_PYTHON was defined we would
look at the passed argument on the command-line as the python
script or module to be run.

This won't work when adding more runtimes.

So instead call a kore_runtime_resolve() function that in
turn calls each available runtime its resolve function.

That resolve function will check if its a script / module
that it can load, and if so will load it.

This way we can remove all those KORE_USE_PYTHON blocks in the
Kore startup path and we pave the way for lua.
This commit is contained in:
Joris Vink 2023-01-16 21:00:01 +01:00
parent d21c0aab5f
commit 2f5d274059
7 changed files with 136 additions and 53 deletions

View File

@ -25,6 +25,7 @@
#include <sys/types.h>
#include <sys/time.h>
#include <sys/queue.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <netinet/in.h>
@ -276,6 +277,7 @@ extern struct connection_list disconnected;
struct kore_runtime {
int type;
int (*resolve)(const char *, const struct stat *);
#if !defined(KORE_NO_HTTP)
int (*http_request)(void *, struct http_request *);
void (*http_request_free)(void *, struct http_request *);
@ -749,6 +751,7 @@ void kore_server_closeall(void);
void kore_server_cleanup(void);
void kore_server_free(struct kore_server *);
void kore_server_finalize(struct kore_server *);
void kore_hooks_set(const char *, const char *, const char *);
struct kore_server *kore_server_create(const char *);
struct kore_server *kore_server_lookup(const char *);
@ -819,6 +822,7 @@ void kore_tls_dh_check(void);
int kore_tls_supported(void);
void kore_tls_version_set(int);
void kore_tls_keymgr_init(void);
void kore_tls_log_version(void);
int kore_tls_dh_load(const char *);
void kore_tls_seed(const void *, size_t);
int kore_tls_ciphersuite_set(const char *);
@ -1024,6 +1028,7 @@ int kore_route_lookup(struct http_request *,
#endif
/* runtime.c */
const size_t kore_runtime_count(void);
struct kore_runtime_call *kore_runtime_getcall(const char *);
struct kore_module *kore_module_load(const char *,
const char *, int);
@ -1031,6 +1036,7 @@ struct kore_module *kore_module_load(const char *,
void kore_runtime_execute(struct kore_runtime_call *);
int kore_runtime_onload(struct kore_runtime_call *, int);
void kore_runtime_signal(struct kore_runtime_call *, int);
void kore_runtime_resolve(const char *, const struct stat *);
void kore_runtime_configure(struct kore_runtime_call *, int, char **);
void kore_runtime_connect(struct kore_runtime_call *, struct connection *);
#if !defined(KORE_NO_HTTP)

View File

@ -44,10 +44,6 @@ void kore_python_seccomp_cleanup(void);
void kore_python_seccomp_hook(const char *);
#endif
#if !defined(KORE_SINGLE_BINARY)
extern const char *kore_pymodule;
#endif
extern struct kore_module_functions kore_python_module;
extern struct kore_runtime kore_python_runtime;

View File

@ -62,7 +62,7 @@ int skip_chroot = 0;
u_int8_t worker_count = 0;
char **kore_argv = NULL;
int kore_mem_guard = 0;
int kore_foreground = 0;
int kore_foreground = 1;
char *kore_progname = NULL;
u_int32_t kore_socket_backlog = 5000;
int kore_quit = KORE_QUIT_NONE;
@ -83,16 +83,16 @@ static void kore_server_shutdown(void);
static void kore_server_start(int, char *[]);
static void kore_call_parent_configure(int, char **);
#if !defined(KORE_SINGLE_BINARY) && defined(KORE_USE_PYTHON)
static const char *parent_config_hook = KORE_PYTHON_CONFIG_HOOK;
static const char *parent_teardown_hook = KORE_PYTHON_TEARDOWN_HOOK;
#else
#if !defined(KORE_SINGLE_BINARY)
static const char *rarg0 = NULL;
#endif
static const char *parent_config_hook = KORE_CONFIG_HOOK;
static const char *parent_teardown_hook = KORE_TEARDOWN_HOOK;
#if defined(KORE_SINGLE_BINARY)
static const char *parent_daemonized_hook = KORE_DAEMONIZED_HOOK;
#endif
#endif
static void
usage(void)
@ -167,10 +167,10 @@ version(void)
int
main(int argc, char *argv[])
{
struct kore_runtime_call *rcall;
#if !defined(KORE_SINGLE_BINARY) && defined(KORE_USE_PYTHON)
#if !defined(KORE_SINGLE_BINARY)
struct stat st;
#endif
struct kore_runtime_call *rcall;
kore_argc = argc;
kore_argv = argv;
@ -192,23 +192,22 @@ main(int argc, char *argv[])
argv += optind;
#endif
#if !defined(KORE_SINGLE_BINARY) && defined(KORE_USE_PYTHON)
if (argc > 0) {
kore_pymodule = argv[0];
argc--;
argv++;
} else {
kore_pymodule = NULL;
}
if (kore_pymodule) {
if (lstat(kore_pymodule, &st) == -1) {
fatal("failed to stat '%s': %s",
kore_pymodule, errno_s);
#if !defined(KORE_SINGLE_BINARY)
if (kore_runtime_count() > 0) {
if (argc > 0) {
rarg0 = argv[0];
argc--;
argv++;
}
if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
fatal("%s: not a directory or file", kore_pymodule);
if (rarg0) {
if (lstat(rarg0, &st) == -1) {
if (errno == ENOENT)
rarg0 = NULL;
else
fatal("stat(%s): %s", rarg0, errno_s);
}
}
}
#endif
@ -243,25 +242,17 @@ main(int argc, char *argv[])
#if defined(KORE_USE_PYTHON)
kore_python_init();
#if !defined(KORE_SINGLE_BINARY)
if (kore_pymodule) {
kore_module_load(kore_pymodule, NULL, KORE_MODULE_PYTHON);
if (S_ISDIR(st.st_mode) && chdir(kore_pymodule) == -1)
fatal("chdir(%s): %s", kore_pymodule, errno_s);
} else {
/* swap back to non-python hooks. */
parent_config_hook = KORE_CONFIG_HOOK;
parent_teardown_hook = KORE_TEARDOWN_HOOK;
}
#endif
#if !defined(KORE_SINGLE_BINARY)
if (kore_runtime_count() > 0 && rarg0 != NULL)
kore_runtime_resolve(rarg0, &st);
#endif
#if defined(KORE_SINGLE_BINARY)
kore_call_parent_configure(argc, argv);
#endif
#if defined(KORE_USE_PYTHON) && !defined(KORE_SINGLE_BINARY)
if (kore_pymodule)
#else
if (kore_runtime_count() > 0 && rarg0 != NULL)
kore_call_parent_configure(argc, argv);
#endif
@ -314,9 +305,9 @@ kore_default_getopt(int argc, char **argv)
int ch;
#if !defined(KORE_SINGLE_BINARY)
while ((ch = getopt(argc, argv, "c:fhnqrv")) != -1) {
while ((ch = getopt(argc, argv, "c:dfhnqrv")) != -1) {
#else
while ((ch = getopt(argc, argv, "fhnqrv")) != -1) {
while ((ch = getopt(argc, argv, "dfhnqrv")) != -1) {
#endif
switch (ch) {
#if !defined(KORE_SINGLE_BINARY)
@ -326,8 +317,12 @@ kore_default_getopt(int argc, char **argv)
fatal("strdup");
break;
#endif
case 'd':
kore_foreground = 0;
break;
case 'f':
kore_foreground = 1;
printf("note: -f is the default now, "
"use -d to daemonize\n");
break;
case 'h':
usage();
@ -763,6 +758,17 @@ kore_proctitle(const char *title)
memset(kore_argv[0] + len, 0, proctitle_maxlen - len);
}
void
kore_hooks_set(const char *config, const char *teardown, const char *daemonized)
{
parent_config_hook = config;
parent_teardown_hook = teardown;
#if defined(KORE_SINGLE_BINARY)
parent_daemonized_hook = daemonized;
#endif
}
static void
kore_proctitle_setup(void)
{
@ -827,6 +833,8 @@ kore_server_start(int argc, char *argv[])
);
}
kore_tls_log_version();
if (kore_foreground == 0) {
if (daemon(1, 0) == -1)
fatal("cannot daemon(): %s", errno_s);
@ -842,12 +850,8 @@ kore_server_start(int argc, char *argv[])
kore_pid = getpid();
kore_write_kore_pid();
#if !defined(KORE_SINGLE_BINARY) && !defined(KORE_USE_PYTHON)
kore_call_parent_configure(argc, argv);
#endif
#if defined(KORE_USE_PYTHON) && !defined(KORE_SINGLE_BINARY)
if (kore_pymodule == NULL)
#if !defined(KORE_SINGLE_BINARY)
if (kore_runtime_count() == 0 || rarg0 == NULL)
kore_call_parent_configure(argc, argv);
#endif

View File

@ -167,6 +167,7 @@ static void python_push_integer(PyObject *, const char *, long);
static void python_push_type(const char *, PyObject *, PyTypeObject *);
static int python_validator_check(PyObject *);
static int python_runtime_resolve(const char *, const struct stat *);
static int python_runtime_http_request(void *, struct http_request *);
static void python_runtime_http_request_free(void *, struct http_request *);
static void python_runtime_http_body_chunk(void *, struct http_request *,
@ -200,6 +201,7 @@ struct kore_module_functions kore_python_module = {
struct kore_runtime kore_python_runtime = {
KORE_RUNTIME_PYTHON,
.resolve = python_runtime_resolve,
.http_request = python_runtime_http_request,
.http_body_chunk = python_runtime_http_body_chunk,
.http_request_free = python_runtime_http_request_free,
@ -330,7 +332,7 @@ static PyObject *python_tracer = NULL;
static struct python_coro *coro_running = NULL;
#if !defined(KORE_SINGLE_BINARY)
const char *kore_pymodule = NULL;
static const char *kore_pymodule = NULL;
#endif
void
@ -1278,6 +1280,36 @@ pyhttp_file_dealloc(struct pyhttp_file *pyfile)
PyObject_Del((PyObject *)pyfile);
}
static int
python_runtime_resolve(const char *module, const struct stat *st)
{
const char *ext;
if (!S_ISDIR(st->st_mode) && !S_ISREG(st->st_mode))
return (KORE_RESULT_ERROR);
if (S_ISDIR(st->st_mode)) {
kore_module_load(module, NULL, KORE_MODULE_PYTHON);
if (chdir(module) == -1)
fatal("chdir(%s): %s", module, errno_s);
} else {
if ((ext = strrchr(module, '.')) == NULL)
return (KORE_RESULT_ERROR);
if (strcasecmp(ext, ".py"))
return (KORE_RESULT_ERROR);
kore_module_load(module, NULL, KORE_MODULE_PYTHON);
}
kore_pymodule = module;
kore_hooks_set(KORE_PYTHON_CONFIG_HOOK,
KORE_PYTHON_TEARDOWN_HOOK, KORE_PYTHON_DAEMONIZED_HOOK);
return (KORE_RESULT_OK);
}
static int
python_runtime_http_request(void *addr, struct http_request *req)
{

View File

@ -62,6 +62,38 @@ struct kore_runtime kore_native_runtime = {
.configure = native_runtime_configure
};
static struct kore_runtime *runtimes[] = {
#if defined(KORE_USE_PYTHON)
&kore_python_runtime,
#endif
NULL
};
const size_t
kore_runtime_count(void)
{
return ((sizeof(runtimes) / sizeof(runtimes[0])) - 1);
}
void
kore_runtime_resolve(const char *module, const struct stat *st)
{
int i;
if (runtimes[0] == NULL)
return;
for (i = 0; runtimes[i] != NULL; i++) {
if (runtimes[i]->resolve == NULL)
continue;
if (runtimes[i]->resolve(module, st))
break;
}
if (runtimes[i] == NULL)
fatal("No runtime available to run '%s'", module);
}
struct kore_runtime_call *
kore_runtime_getcall(const char *symbol)
{

View File

@ -40,6 +40,11 @@ kore_keymgr_cleanup(int final)
void
kore_tls_init(void)
{
}
void
kore_tls_log_version(void)
{
kore_log(LOG_NOTICE, "No compiled in TLS backend");
}

View File

@ -111,15 +111,23 @@ kore_tls_init(void)
#if !defined(LIBRESSL_VERSION_NUMBER)
if (!CRYPTO_set_mem_functions(tls_malloc, tls_realloc, tls_free))
fatalx("CRYPTO_set_mem_functions failed");
#else
kore_log(LOG_NOTICE, "libressl does not support malloc-wrappers");
#endif
SSL_library_init();
SSL_load_error_strings();
ERR_load_crypto_strings();
}
void
kore_tls_log_version(void)
{
kore_log(LOG_NOTICE, "TLS backend %s", OPENSSL_VERSION_TEXT);
#if defined(LIBRESSL_VERSION_NUMBER)
kore_log(LOG_NOTICE, "libressl does not support malloc-wrappers");
#endif
#if !defined(TLS1_3_VERSION)
if (!kore_quiet) {
kore_log(LOG_NOTICE,