mirror of https://git.48k.eu/ogserver
#1004 Add GET /images
This commit adds GET /images to the ogServer REST API. This call returns information of all the images in ogServer. Example response: { "images": [ { "filename": "ubuntu.img", "datasize": 2150400000, "size": 613476223, "modified": "Wed Sep 23 10:37:36 2020", "permissions": "744" }, { "filename": "test.img", "datasize": 2150400000, "size": 613236475, "modified": "Tue Sep 29 08:57:47 2020", "permissions": "744" } ], "disk": { "total": 52573995008, "free": 39624544256 } }master
parent
f068a79c1a
commit
403e7c323b
27
src/cfg.c
27
src/cfg.c
|
@ -88,9 +88,28 @@ static int parse_json_wol(struct og_server_cfg *cfg, json_t *element)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int parse_json_repo(struct og_server_cfg *cfg, json_t *element)
|
||||||
|
{
|
||||||
|
const char *key;
|
||||||
|
json_t *value;
|
||||||
|
|
||||||
|
json_object_foreach(element, key, value) {
|
||||||
|
if (!strcmp(key, "directory")) {
|
||||||
|
if (og_json_parse_string(value, &cfg->repo.dir) < 0)
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
syslog(LOG_ERR, "unknown key `%s' in repo\n", key);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#define OG_SERVER_CFG_REST (1 << 0)
|
#define OG_SERVER_CFG_REST (1 << 0)
|
||||||
#define OG_SERVER_CFG_DB (1 << 1)
|
#define OG_SERVER_CFG_DB (1 << 1)
|
||||||
#define OG_SERVER_CFG_WOL (1 << 2)
|
#define OG_SERVER_CFG_WOL (1 << 2)
|
||||||
|
#define OG_SERVER_CFG_REPO (1 << 3)
|
||||||
|
|
||||||
int parse_json_config(const char *filename, struct og_server_cfg *cfg)
|
int parse_json_config(const char *filename, struct og_server_cfg *cfg)
|
||||||
{
|
{
|
||||||
|
@ -138,6 +157,11 @@ int parse_json_config(const char *filename, struct og_server_cfg *cfg)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
flags |= OG_SERVER_CFG_DB;
|
flags |= OG_SERVER_CFG_DB;
|
||||||
|
} else if (!strcmp(key, "repository")) {
|
||||||
|
if (parse_json_repo(cfg, value) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
flags |= OG_SERVER_CFG_REPO;
|
||||||
} else {
|
} else {
|
||||||
syslog(LOG_ERR, "unknown key `%s' in %s\n",
|
syslog(LOG_ERR, "unknown key `%s' in %s\n",
|
||||||
key, filename);
|
key, filename);
|
||||||
|
@ -150,7 +174,8 @@ int parse_json_config(const char *filename, struct og_server_cfg *cfg)
|
||||||
|
|
||||||
if ((flags & OG_SERVER_CFG_REST) &&
|
if ((flags & OG_SERVER_CFG_REST) &&
|
||||||
(flags & OG_SERVER_CFG_DB) &&
|
(flags & OG_SERVER_CFG_DB) &&
|
||||||
(flags & OG_SERVER_CFG_WOL)) {
|
(flags & OG_SERVER_CFG_WOL) &&
|
||||||
|
(flags & OG_SERVER_CFG_REPO)) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
} else {
|
} else {
|
||||||
syslog(LOG_ERR, "Missing attributes in json file");
|
syslog(LOG_ERR, "Missing attributes in json file");
|
||||||
|
|
|
@ -17,6 +17,9 @@ struct og_server_cfg {
|
||||||
struct {
|
struct {
|
||||||
const char *interface;
|
const char *interface;
|
||||||
} wol;
|
} wol;
|
||||||
|
struct {
|
||||||
|
const char *dir;
|
||||||
|
} repo;
|
||||||
json_t *json;
|
json_t *json;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
165
src/rest.c
165
src/rest.c
|
@ -26,6 +26,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
#include <sys/statvfs.h>
|
||||||
|
|
||||||
struct ev_loop *og_loop;
|
struct ev_loop *og_loop;
|
||||||
|
|
||||||
|
@ -240,6 +241,7 @@ static const char *og_cmd_to_uri[OG_CMD_MAX] = {
|
||||||
[OG_CMD_IMAGE_RESTORE] = "image/restore",
|
[OG_CMD_IMAGE_RESTORE] = "image/restore",
|
||||||
[OG_CMD_SETUP] = "setup",
|
[OG_CMD_SETUP] = "setup",
|
||||||
[OG_CMD_RUN_SCHEDULE] = "run/schedule",
|
[OG_CMD_RUN_SCHEDULE] = "run/schedule",
|
||||||
|
[OG_CMD_IMAGES] = "images",
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool og_client_is_busy(const struct og_client *cli,
|
static bool og_client_is_busy(const struct og_client *cli,
|
||||||
|
@ -1532,6 +1534,161 @@ static int og_cmd_software(json_t *element, struct og_msg_params *params)
|
||||||
return og_send_request(OG_METHOD_POST, OG_CMD_SOFTWARE, params, clients);
|
return og_send_request(OG_METHOD_POST, OG_CMD_SOFTWARE, params, clients);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define OG_IMAGE_TYPE_MAXLEN 4
|
||||||
|
|
||||||
|
struct og_image {
|
||||||
|
const char *filename;
|
||||||
|
uint64_t datasize;
|
||||||
|
struct stat image_stats;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int og_get_image_stats(const char *name,
|
||||||
|
struct stat *image_stats)
|
||||||
|
{
|
||||||
|
const char *dir = cfg.repo.dir;
|
||||||
|
char filename[PATH_MAX + 1];
|
||||||
|
|
||||||
|
snprintf(filename, sizeof(filename), "%s/%s", dir, name);
|
||||||
|
if (stat(filename, image_stats) < 0) {
|
||||||
|
syslog(LOG_ERR, "%s image does not exists", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static json_t *og_json_disk_alloc()
|
||||||
|
{
|
||||||
|
const char *dir = cfg.repo.dir;
|
||||||
|
struct statvfs buffer;
|
||||||
|
json_t *disk_json;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = statvfs(dir, &buffer);
|
||||||
|
if (ret)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
disk_json = json_object();
|
||||||
|
if (!disk_json)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
json_object_set_new(disk_json, "total",
|
||||||
|
json_integer(buffer.f_blocks * buffer.f_frsize));
|
||||||
|
json_object_set_new(disk_json, "free",
|
||||||
|
json_integer(buffer.f_bfree * buffer.f_frsize));
|
||||||
|
|
||||||
|
return disk_json;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define OG_PERMS_IRWX (S_IRWXU | S_IRWXG | S_IRWXO)
|
||||||
|
#define OG_PERMS_MAXLEN 4
|
||||||
|
|
||||||
|
static json_t *og_json_image_alloc(struct og_image *image)
|
||||||
|
{
|
||||||
|
char perms_string[OG_PERMS_MAXLEN];
|
||||||
|
json_t *image_json;
|
||||||
|
char *modified;
|
||||||
|
uint16_t perms;
|
||||||
|
|
||||||
|
image_json = json_object();
|
||||||
|
if (!image_json)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
perms = image->image_stats.st_mode & OG_PERMS_IRWX;
|
||||||
|
snprintf(perms_string, sizeof(perms_string), "%o", perms);
|
||||||
|
|
||||||
|
modified = ctime(&image->image_stats.st_mtime);
|
||||||
|
modified[strlen(modified) - 1] = '\0';
|
||||||
|
|
||||||
|
json_object_set_new(image_json, "filename",
|
||||||
|
json_string(image->filename));
|
||||||
|
json_object_set_new(image_json, "datasize",
|
||||||
|
json_integer(image->datasize));
|
||||||
|
json_object_set_new(image_json, "size",
|
||||||
|
json_integer(image->image_stats.st_size));
|
||||||
|
json_object_set_new(image_json, "modified",
|
||||||
|
json_string(modified));
|
||||||
|
json_object_set_new(image_json, "permissions",
|
||||||
|
json_string(perms_string));
|
||||||
|
|
||||||
|
return image_json;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int og_cmd_images(char *buffer_reply)
|
||||||
|
{
|
||||||
|
json_t *root, *images, *image_json, *disk_json;
|
||||||
|
struct og_buffer og_buffer = {
|
||||||
|
.data = buffer_reply
|
||||||
|
};
|
||||||
|
struct og_image image;
|
||||||
|
struct og_dbi *dbi;
|
||||||
|
dbi_result result;
|
||||||
|
|
||||||
|
root = json_object();
|
||||||
|
if (!root)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
images = json_array();
|
||||||
|
if (!images) {
|
||||||
|
json_decref(root);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object_set_new(root, "images", images);
|
||||||
|
|
||||||
|
dbi = og_dbi_open(&dbi_config);
|
||||||
|
if (!dbi) {
|
||||||
|
syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
|
||||||
|
__func__, __LINE__);
|
||||||
|
json_decref(root);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = dbi_conn_queryf(dbi->conn,
|
||||||
|
"SELECT i.nombreca, o.nombreordenador, "
|
||||||
|
" i.clonator, i.compressor, "
|
||||||
|
" i.filesystem, i.datasize "
|
||||||
|
"FROM imagenes i "
|
||||||
|
"LEFT JOIN ordenadores o "
|
||||||
|
"ON i.idordenador = o.idordenador");
|
||||||
|
|
||||||
|
while (dbi_result_next_row(result)) {
|
||||||
|
image = (struct og_image){0};
|
||||||
|
image.filename = dbi_result_get_string(result, "nombreca");
|
||||||
|
image.datasize = dbi_result_get_ulonglong(result, "datasize");
|
||||||
|
|
||||||
|
if (og_get_image_stats(image.filename, &image.image_stats)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
image_json = og_json_image_alloc(&image);
|
||||||
|
if (!image_json) {
|
||||||
|
dbi_result_free(result);
|
||||||
|
og_dbi_close(dbi);
|
||||||
|
json_decref(root);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
json_array_append(images, image_json);
|
||||||
|
}
|
||||||
|
|
||||||
|
dbi_result_free(result);
|
||||||
|
og_dbi_close(dbi);
|
||||||
|
|
||||||
|
disk_json = og_json_disk_alloc();
|
||||||
|
if (!disk_json) {
|
||||||
|
syslog(LOG_ERR, "cannot allocate disk json");
|
||||||
|
json_decref(root);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object_set_new(root, "disk", disk_json);
|
||||||
|
|
||||||
|
json_dump_callback(root, og_json_dump_clients, &og_buffer, 0);
|
||||||
|
json_decref(root);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int og_cmd_create_image(json_t *element, struct og_msg_params *params)
|
static int og_cmd_create_image(json_t *element, struct og_msg_params *params)
|
||||||
{
|
{
|
||||||
json_t *value, *clients;
|
json_t *value, *clients;
|
||||||
|
@ -3489,6 +3646,14 @@ int og_client_state_process_payload_rest(struct og_client *cli)
|
||||||
return og_client_bad_request(cli);
|
return og_client_bad_request(cli);
|
||||||
}
|
}
|
||||||
err = og_cmd_software(root, ¶ms);
|
err = og_cmd_software(root, ¶ms);
|
||||||
|
} else if (!strncmp(cmd, "images", strlen("images"))) {
|
||||||
|
if (method != OG_METHOD_GET)
|
||||||
|
return og_client_method_not_found(cli);
|
||||||
|
|
||||||
|
if (!root)
|
||||||
|
err = og_cmd_images(buf_reply);
|
||||||
|
else
|
||||||
|
return og_client_method_not_found(cli);
|
||||||
} else if (!strncmp(cmd, "image/create", strlen("image/create"))) {
|
} else if (!strncmp(cmd, "image/create", strlen("image/create"))) {
|
||||||
if (method != OG_METHOD_POST)
|
if (method != OG_METHOD_POST)
|
||||||
return og_client_method_not_found(cli);
|
return og_client_method_not_found(cli);
|
||||||
|
|
|
@ -33,6 +33,7 @@ enum og_cmd_type {
|
||||||
OG_CMD_IMAGE_RESTORE,
|
OG_CMD_IMAGE_RESTORE,
|
||||||
OG_CMD_SETUP,
|
OG_CMD_SETUP,
|
||||||
OG_CMD_RUN_SCHEDULE,
|
OG_CMD_RUN_SCHEDULE,
|
||||||
|
OG_CMD_IMAGES,
|
||||||
OG_CMD_MAX
|
OG_CMD_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue