Skip to content

Added vm_start and vm_stop to PyCSH #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ pycsh_sources = [
'src/wrapper/spaceboot_py.c',
'src/wrapper/param_list_py.c',
'src/wrapper/vmem_client_py.c',
'src/wrapper/victoria_metrics_py.c',

# Utilities
'src/utils.c',
Expand Down
13 changes: 13 additions & 0 deletions pycsh.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,19 @@ def sps(from: int, to: int, filename: str, node: int = None, window: int = None,
:raises ProgramDiffError: See class docstring.
"""

def vm_start(logfile: int = 0, username: str = None, password: str = None, pyargs: dict = None):
"""Starts victoria metrics thread

Args:
logfile (int, optional): _description_. Defaults to 0.
username (str, optional): Username for vm. Defaults to None.
password (str, optional): Password for vm. Defaults to None.
pyargs (dict, optional): _description_. Defaults to None.
"""

def vm_stop():
"""Stops victoria metrics thread"""

def csp_init(host: str = None, model: str = None, revision: str = None, version: int = 2, dedup: int = 3) -> None:
"""
Initialize CSP
Expand Down
15 changes: 1 addition & 14 deletions src/csh/victoria_metrics.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,15 @@
#include <param/param_queue.h>
#include <param/param_string.h>
#include "param_sniffer.h"
#include "victoria_metrics.h"

static pthread_t vm_push_thread;
int vm_running = 0;

#define SERVER_PORT 8428
#define SERVER_PORT_AUTH 8427
#define BUFFER_SIZE 10 * 1024 * 1024

static char buffer[BUFFER_SIZE];
static size_t buffer_size = 0;
static pthread_mutex_t buffer_mutex = PTHREAD_MUTEX_INITIALIZER;

typedef struct {
int use_ssl;
int port;
int skip_verify;
int verbose;
char * username;
char * password;
char * server_ip;
} vm_args;

static size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata) {
return size * nmemb;
}
Expand Down
16 changes: 16 additions & 0 deletions src/csh/victoria_metrics.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,19 @@

void vm_add(char * metric_line);
void vm_add_param(param_t * param);

#define SERVER_PORT 8428
#define SERVER_PORT_AUTH 8427
#define BUFFER_SIZE 10 * 1024 * 1024

typedef struct {
int use_ssl;
int port;
int skip_verify;
int verbose;
char * username;
char * password;
char * server_ip;
} vm_args;

void * vm_push(void * arg);
5 changes: 5 additions & 0 deletions src/pycsh.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
#include "wrapper/csp_init_py.h"
#include "wrapper/param_list_py.h"
#include "wrapper/vmem_client_py.h"
#include "wrapper/victoria_metrics_py.h"

extern const char *version_string;

Expand Down Expand Up @@ -249,6 +250,10 @@ static PyMethodDef methods[] = {
{"node", pycsh_slash_node, METH_VARARGS, "Used to get or change the default node."},
{"timeout", pycsh_slash_timeout, METH_VARARGS, "Used to get or change the default timeout."},
{"queue", pycsh_param_cmd, METH_NOARGS, "Print the current command."},

/* Victoria Metrics */
{"vm_start", (PyCFunction)pycsh_vm_start, METH_VARARGS | METH_KEYWORDS, "Starts the victoria metrics thread."},
{"vm_stop", (PyCFunction)pycsh_vm_stop, METH_VARARGS | METH_KEYWORDS, "Stops the victoria metrics thread."},

/* Converted CSH commands from libparam/src/param/list/param_list_slash.c */
{"list", (PyCFunction)pycsh_param_list, METH_VARARGS | METH_KEYWORDS, "List all known parameters."},
Expand Down
1 change: 1 addition & 0 deletions src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "parameter/parameterarray.h"
#include "parameter/pythonparameter.h"
#include "parameter/parameterlist.h"
#include "../src/csh/victoria_metrics.h"


/* __attribute__(()) doesn't like to treat char** and void** interchangeably. */
Expand Down
166 changes: 166 additions & 0 deletions src/wrapper/victoria_metrics_py.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/*
* param_list_py.c
*
* Wrappers for lib/param/src/param/list/param_list_slash.c
*
*/

#define PY_SSIZE_T_CLEAN
#include <Python.h>

#include <param/param_string.h>
#include <curl/curl.h>
#include <csp/csp.h>
#include "../pycsh.h"
#include "../utils.h"
#include "../parameter/parameter.h"
#include "../parameter/pythonparameter.h"
#include "../src/csh/victoria_metrics.h"

#include "victoria_metrics_py.h"

static pthread_t vm_push_thread;
extern int vm_running;

static int pycsh_parse_vm_args(PyObject * args_in, vm_args * args_out) {
assert(args_in != NULL);

// Get all the values from the python dict. Everything is a string when it comes from python.
PyObject * py_use_ssl = PyDict_GetItemString(args_in, "use_ssl");
PyObject * py_port = PyDict_GetItemString(args_in, "port");
PyObject * py_skip_verify = PyDict_GetItemString(args_in, "skip_verify");
PyObject * py_verbose = PyDict_GetItemString(args_in, "verbose");
PyObject * py_server_ip = PyDict_GetItemString(args_in, "server_ip");

// Check if long characters are larger than INT_MAX since we actually want them to be ints and not longs.
// These values are not required, so if the input is NULL we initialize them to 0.
long use_ssl;
if(py_use_ssl == NULL){
use_ssl = 0;
} else if (PyLong_Check(py_use_ssl)){
use_ssl = PyLong_AsLong(py_use_ssl);
if(use_ssl > INT_MAX){
PyErr_SetString(PyExc_TypeError, "use_ssl value greater than INT_MAX");
return -1;
}
} else {
PyErr_SetString(PyExc_TypeError, "TypeError.");
return -1;
}

long port;
if(py_port == NULL){
port = 0;
} else if (PyLong_Check(py_port)){
port = PyLong_AsLong(py_port);
if(port > INT_MAX){
PyErr_SetString(PyExc_TypeError, "port value greater than INT_MAX");
return -1;
}
} else {
PyErr_SetString(PyExc_TypeError, "TypeError.");
return -1;
}

long skip_verify;
if(py_skip_verify == NULL){
skip_verify = 0;
} else if (PyLong_Check(py_skip_verify)){
skip_verify = PyLong_AsLong(py_skip_verify);
if(skip_verify > INT_MAX){
PyErr_SetString(PyExc_TypeError, "skip_verify value greater than INT_MAX");
return -1;
}
} else {
PyErr_SetString(PyExc_TypeError, "TypeError.");
return -1;
}

long verbose;
if(py_verbose == NULL){
verbose = 0;
} else if (PyLong_Check(py_verbose)){
verbose = PyLong_AsLong(py_verbose);
if(verbose > INT_MAX){
PyErr_SetString(PyExc_TypeError, "verbose value greater than INT_MAX");
return -1;
}
} else {
PyErr_SetString(PyExc_TypeError, "TypeError.");
return -1;
}

// Server_ip is required, so we make sure it exists.
if(!py_server_ip){
PyErr_SetString(PyExc_KeyError, "server_ip field missing.");
return -1;
}
if(!PyUnicode_Check(py_server_ip)){
PyErr_SetString(PyExc_TypeError, "TypeError in field server_ip.");
return -1;
}
char * server_ip = strdup(PyUnicode_AsUTF8(py_server_ip));

// Set values in the vm_args struct.
args_out->use_ssl = (int)use_ssl;
args_out->port = (int)port;
args_out->skip_verify = (int)skip_verify;
args_out->verbose = (int)verbose;

args_out->server_ip = server_ip;

return 0;

}

PyObject * pycsh_vm_start(PyObject * self, PyObject * args, PyObject * kwds) {
if(vm_running){
printf("Thread already running.\n");
return Py_None;
}

int logfile = 0;
char * tmp_username = NULL;
char * tmp_password = NULL;
PyObject * pyargs = NULL;

static char *kwlist[] = {"logfile", "username", "password", "args", NULL};

if (!PyArg_ParseTupleAndKeywords(args, kwds, "|issO", kwlist, &logfile, &tmp_username, &tmp_password, &pyargs)) {
return NULL;
}

vm_args * vmargs = calloc(1, sizeof(vm_args));

if(pycsh_parse_vm_args(pyargs, vmargs) < 0){
PyErr_SetString(PyExc_ConnectionError, "Invalid arguments");
return NULL;
}

if (tmp_username) {
if (!tmp_password) {
PyErr_SetString(PyExc_ConnectionError, "Provide password");
return NULL;
}
vmargs->username = strdup(tmp_username);
vmargs->password = strdup(tmp_password);
if (!vmargs->port) {
vmargs->port = SERVER_PORT_AUTH;
}
} else if (!vmargs->port) {
vmargs->port = SERVER_PORT;
}

printf("\n%d\n", vmargs->port);
pthread_create(&vm_push_thread, NULL, &vm_push, vmargs);
vm_running = 1;

return Py_None;

}

PyObject * pycsh_vm_stop(PyObject * self, PyObject * args, PyObject * kwds) {
if(!vm_running) return Py_None;
vm_running = 0;
return Py_None;
}
15 changes: 15 additions & 0 deletions src/wrapper/victoria_metrics_py.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* vm_start_py.c
*
* Wrappers for lib/param/src/param/list/param_list_slash.c
*
*/

#pragma once

#define PY_SSIZE_T_CLEAN
#include <Python.h>

PyObject * pycsh_vm_start(PyObject * self, PyObject * args, PyObject * kwds);

PyObject * pycsh_vm_stop(PyObject * self, PyObject * args, PyObject * kwds);