rest: add cache/list

Add GET cache/list request to obtain information about the client's
cache.

Resquest payload structure:
{
    'clients': ['10.141.10.21', '10.141.10.22']
}

Response's structure:
{
    'clients': [
        {
            'ip': '10.141.10.21',
            'cache_size': 2894572304857,
            'images': [
                {name:'img1', size: 87283902343, checksum: '5d4dcc677bc19f40a647d0002f4ade90'},
                {name:'img2', size: 894572304857, checksum: '3eb22f888f88a55ad954f55644e1192e'}
            ]
        },
        {
            'ip': '10.141.10.22',
            'cache_size': 49872839023434,
            'images': [
                {name:'img2', size: 894572304857, checksum: '3eb22f888f88a55ad954f55644e1192e'}
            ]
        }
    ]
}

Both 'cache_size' and the values in 'image_sizes' are provided
as bytes.

If a client has no cache partition the payload will include it as:
...
	{
            'ip': '10.141.10.22',
            'cache_size': 0,
            'images': []
        }
...
master
Alejandro Sirgo Rica 2024-05-22 15:47:45 +02:00
parent efb5f27585
commit 6666aba8b7
2 changed files with 162 additions and 0 deletions

View File

@ -3458,6 +3458,153 @@ static int og_cmd_delete_image(json_t *element, struct og_msg_params *params)
return 0;
}
static int og_dbi_client_cache_get(struct og_dbi *dbi, json_t *clients, const char *ip)
{
const char *img_name, *msglog, *img_checksum;
json_t *client_data, *cache_arr, *img_info;
uint64_t img_size, cache_size = 0;
dbi_result result;
result = dbi_conn_queryf(dbi->conn,
"SELECT ordenadores_particiones.tamano "
"FROM ordenadores_particiones JOIN ordenadores "
"ON ordenadores.idordenador = ordenadores_particiones.idordenador "
"WHERE ordenadores.ip = '%s' AND codpar = 202", ip);
if (!result) {
dbi_conn_error(dbi->conn, &msglog);
syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
__func__, __LINE__, msglog);
return -1;
}
if (dbi_result_next_row(result)) {
cache_size = dbi_result_get_longlong(result, "tamano") * 1024;
}
dbi_result_free(result);
result = dbi_conn_queryf(dbi->conn,
"SELECT cache.imagename, cache.size, cache.checksum "
"FROM ordenadores JOIN cache "
"ON ordenadores.idordenador = cache.clientid "
"WHERE ordenadores.ip = '%s'", ip);
if (!result) {
dbi_conn_error(dbi->conn, &msglog);
syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
__func__, __LINE__, msglog);
return -1;
}
client_data = json_object();
if (!client_data) {
dbi_result_free(result);
return -1;
}
cache_arr = json_array();
if (!cache_arr) {
json_decref(client_data);
dbi_result_free(result);
return -1;
}
while (dbi_result_next_row(result)) {
img_name = dbi_result_get_string(result, "imagename");
img_size = dbi_result_get_ulonglong(result, "size");
img_checksum = dbi_result_get_string(result, "checksum");
img_info = json_object();
if (!img_info) {
json_decref(client_data);
json_decref(cache_arr);
dbi_result_free(result);
return -1;
}
json_object_set_new(img_info, "name", json_string(img_name));
json_object_set_new(img_info, "size", json_integer(img_size));
json_object_set_new(img_info, "checksum", json_string(img_checksum));
json_array_append_new(cache_arr, img_info);
}
json_object_set_new(client_data, "ip", json_string(ip));
json_object_set_new(client_data, "cache_size", json_integer(cache_size));
json_object_set_new(client_data, "images", cache_arr);
json_array_append_new(clients, client_data);
dbi_result_free(result);
return 0;
}
static int og_cmd_cache_list(json_t *element, struct og_msg_params *params,
char *buffer_reply)
{
json_t *value, *root, *clients;
struct og_dbi *dbi;
const char *key;
int err = 0, i;
struct og_buffer og_buffer = {
.data = buffer_reply
};
if (json_typeof(element) != JSON_OBJECT)
return -1;
json_object_foreach(element, key, value) {
if (!strcmp(key, "clients"))
err = og_json_parse_clients(value, params);
else
err = -1;
if (err < 0)
return err;
}
if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
return -1;
clients = json_array();
if (!clients)
return -1;
dbi = og_dbi_open(&ogconfig.db);
if (!dbi) {
syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
__func__, __LINE__);
json_decref(clients);
return -1;
}
for (i = 0; i < params->ips_array_len; i++) {
if (og_dbi_client_cache_get(dbi, clients, params->ips_array[i]) < 0) {
json_decref(clients);
og_dbi_close(dbi);
return -1;
}
}
og_dbi_close(dbi);
root = json_object();
if (!root) {
json_decref(clients);
return -1;
}
json_object_set_new(root, "clients", clients);
if (json_dump_callback(root, og_json_dump_clients, &og_buffer, 0)) {
json_decref(root);
return -1;
}
json_decref(root);
return 0;
}
static int og_cmd_setup(json_t *element, struct og_msg_params *params)
{
json_t *value, *clients;
@ -7312,6 +7459,7 @@ struct {
[OG_URI_IMAGE_UPDATE] = { "image/update" },
[OG_URI_IMAGE_RESTORE] = { "image/restore", },
[OG_URI_IMAGE_DELETE] = { "image/delete", },
[OG_URI_CACHE_LIST] = { "cache/list", },
[OG_URI_PART_SETUP] = { "setup", },
[OG_URI_RUN_SCHEDULE] = { "run/schedule", },
[OG_URI_TASK_RUN] = { "task/run", },
@ -7884,6 +8032,19 @@ int og_client_state_process_payload_rest(struct og_client *cli)
goto err_process_rest_payload;
}
err = og_cmd_delete_image(root, &params);
} else if (!strncmp(cmd, "cache/list", strlen("cache/list"))) {
if (method != OG_METHOD_GET) {
err = og_client_method_not_found(cli);
goto err_process_rest_payload;
}
if (!root) {
syslog(LOG_ERR,
"command cache list with no payload\n");
err = og_client_bad_request(cli);
goto err_process_rest_payload;
}
err = og_cmd_cache_list(root, &params, buf_reply);
} else if (!strncmp(cmd, "setup", strlen("setup"))) {
if (method != OG_METHOD_POST) {
err = og_client_method_not_found(cli);

View File

@ -116,6 +116,7 @@ enum og_rest_uri {
OG_URI_IMAGE_UPDATE,
OG_URI_IMAGE_RESTORE,
OG_URI_IMAGE_DELETE,
OG_URI_CACHE_LIST,
OG_URI_PART_SETUP,
OG_URI_RUN_SCHEDULE,
OG_URI_TASK_RUN,