mirror of https://git.48k.eu/ogserver
Compare commits
35 Commits
Author | SHA1 | Date |
---|---|---|
|
5cecb4f294 | |
|
730d42a872 | |
|
91c042ed61 | |
|
acf9c07236 | |
|
4db69ad054 | |
|
d8b271f503 | |
|
2daa9cdb36 | |
|
41c8dec51c | |
|
31d426b018 | |
|
5e21716afb | |
|
6a63218f85 | |
|
e3188191d9 | |
|
8f52b8911e | |
|
ef3bad6e14 | |
|
da31efb4e0 | |
|
00d54325d3 | |
|
113472d5c0 | |
|
232e6eb308 | |
|
c110bd7d8d | |
|
aebf2281bf | |
|
0ea0394709 | |
|
16baa88541 | |
|
4103945785 | |
|
892a8fa2e5 | |
|
55179decb7 | |
|
1fd62a4850 | |
|
e67cdafb71 | |
|
24e70ac3ff | |
|
bff3d1dc9d | |
|
479998d76f | |
|
83b1be6589 | |
|
16cc22df3e | |
|
2febb50a92 | |
|
e679925bd0 | |
|
e960063a13 |
|
@ -3,6 +3,7 @@ sbin_PROGRAMS = ogserver
|
||||||
AM_CFLAGS = ${LIBDBI_CFLAGS} ${LIBJANSSON_CFLAGS} ${LIBEVENT_CFLAGS} -g -Wall
|
AM_CFLAGS = ${LIBDBI_CFLAGS} ${LIBJANSSON_CFLAGS} ${LIBEVENT_CFLAGS} -g -Wall
|
||||||
|
|
||||||
ogserver_SOURCES= src/ogAdmServer.c \
|
ogserver_SOURCES= src/ogAdmServer.c \
|
||||||
|
src/boot.c \
|
||||||
src/cfg.c \
|
src/cfg.c \
|
||||||
src/core.c \
|
src/core.c \
|
||||||
src/dbi.c \
|
src/dbi.c \
|
||||||
|
|
|
@ -11,6 +11,10 @@
|
||||||
"user" : "mysql",
|
"user" : "mysql",
|
||||||
"pass" : "mysql"
|
"pass" : "mysql"
|
||||||
},
|
},
|
||||||
|
"samba" : {
|
||||||
|
"user" : "opengnsys",
|
||||||
|
"pass" : "test"
|
||||||
|
},
|
||||||
"wol" : {
|
"wol" : {
|
||||||
"interface" : "lo"
|
"interface" : "lo"
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020-2024 Soleta Networks <info@soleta.eu>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU Affero General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include "boot.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
#define OGRELIVE_TEMPLATE \
|
||||||
|
"# Autogenerated by ogserver on %s - do not edit this file!\n" \
|
||||||
|
"set oghostname=%s\n" \
|
||||||
|
"set ogserver=%s\n" \
|
||||||
|
"set ogrepo=%s\n" \
|
||||||
|
"set ogreliveversion=%s\n" \
|
||||||
|
"set ogrelivedir=ogrelive/$ogreliveversion\n" \
|
||||||
|
"set username=%s\n" \
|
||||||
|
"set passwd=%s\n" \
|
||||||
|
"\n" \
|
||||||
|
"set timeout=0\n" \
|
||||||
|
"set timeout_style=hidden\n" \
|
||||||
|
"\n" \
|
||||||
|
"echo \"checking for vmlinuz in cache...\"\n" \
|
||||||
|
"set root=''\n" \
|
||||||
|
"search --file --set root /boot/$ogreliveversion/vmlinuz\n" \
|
||||||
|
"if [ \"$root\" == \"\" ]; then\n" \
|
||||||
|
" echo \"no vmlinuz found in cache, booting from network\"\n" \
|
||||||
|
" set default=1;\n" \
|
||||||
|
"else\n" \
|
||||||
|
" echo \"vmlinuz found, booting from cache\"\n" \
|
||||||
|
" set default=0;\n" \
|
||||||
|
"fi\n" \
|
||||||
|
"\n" \
|
||||||
|
"menuentry \"ogReLive HTTP boot\" {\n" \
|
||||||
|
" insmod http\n" \
|
||||||
|
" insmod net\n" \
|
||||||
|
" net_bootp\n" \
|
||||||
|
" linux (http,$ogrepo)/$ogrelivedir/vmlinuz ro boot=live quiet splash oglivedir=$ogrelivedir hostname=$oghostname ip=$ogserver ogrepo=$ogrepo username=$username passwd=$passwd fetch=http://$ogrepo/$ogrelivedir/filesystem.squashfs\n" \
|
||||||
|
" initrd (http,$ogrepo)/$ogrelivedir/initrd.img\n" \
|
||||||
|
" boot\n" \
|
||||||
|
"}\n"
|
||||||
|
|
||||||
|
/* Same as OG_TFTP_BOOT_UEFI. */
|
||||||
|
#define OG_BOOT_GRUB_DIR "/opt/opengnsys/tftpboot/grub"
|
||||||
|
|
||||||
|
static void ogrelive_grub2_file_path(char *grub2_filename,
|
||||||
|
size_t grub2_filename_size,
|
||||||
|
const char *mac)
|
||||||
|
{
|
||||||
|
snprintf(grub2_filename, grub2_filename_size,
|
||||||
|
OG_BOOT_GRUB_DIR"/01-%c%c:%c%c:%c%c:%c%c:%c%c:%c%c",
|
||||||
|
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
|
||||||
|
mac[6], mac[7], mac[8], mac[9], mac[10], mac[11]);
|
||||||
|
str_tolower(grub2_filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ogrelive_generate_grub2_file(const struct og_boot_cfg *cfg, const char *mac)
|
||||||
|
{
|
||||||
|
char grub2_tmp_filename[] = "/tmp/grub_template_XXXXXX";
|
||||||
|
char grub2_filename[FILENAME_MAX] = {};
|
||||||
|
time_t now = time(NULL);
|
||||||
|
char *date;
|
||||||
|
FILE *fp;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
date = asctime(localtime(&now));
|
||||||
|
date[strlen(date) - 1] = '\0';
|
||||||
|
|
||||||
|
fd = mkstemp(grub2_tmp_filename);
|
||||||
|
if (fd < 0) {
|
||||||
|
syslog(LOG_ERR, "Cannot open %s to %s (%s:%u)\n",
|
||||||
|
grub2_tmp_filename, grub2_filename, __FILE__, __LINE__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fp = fdopen(fd, "w+");
|
||||||
|
if (!fp) {
|
||||||
|
close(fd);
|
||||||
|
syslog(LOG_ERR, "Cannot open %s to %s (%s:%u)\n",
|
||||||
|
grub2_tmp_filename, grub2_filename, __FILE__, __LINE__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fp, OGRELIVE_TEMPLATE, date,
|
||||||
|
cfg->hostname, cfg->ogserver, cfg->ogrepo, cfg->ogrelivedir, cfg->username, cfg->passwd);
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
if (unlink(grub2_filename) < 0) {
|
||||||
|
if (errno != ENOENT) {
|
||||||
|
syslog(LOG_ERR, "Failed to delete %s (%s:%u)\n",
|
||||||
|
grub2_filename, __FILE__, __LINE__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ogrelive_grub2_file_path(grub2_filename, sizeof(grub2_filename), mac);
|
||||||
|
|
||||||
|
if (rename(grub2_tmp_filename, grub2_filename) < 0) {
|
||||||
|
unlink(grub2_tmp_filename);
|
||||||
|
syslog(LOG_ERR, "Failed to rename %s to %s (%s:%u)\n",
|
||||||
|
grub2_tmp_filename, grub2_filename, __FILE__, __LINE__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
chmod(grub2_filename, 0644);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef _OG_BOOT_H_
|
||||||
|
#define _OG_BOOT_H_
|
||||||
|
|
||||||
|
struct og_boot_cfg {
|
||||||
|
const char *hostname;
|
||||||
|
const char *ogserver;
|
||||||
|
const char *ogrepo;
|
||||||
|
const char *ogrelivedir;
|
||||||
|
const char *username;
|
||||||
|
const char *passwd;
|
||||||
|
};
|
||||||
|
|
||||||
|
int ogrelive_generate_grub2_file(const struct og_boot_cfg *cfg, const char *mac);
|
||||||
|
|
||||||
|
#endif /* _OG_BOOT_H_ */
|
31
src/cfg.c
31
src/cfg.c
|
@ -70,6 +70,27 @@ static int parse_json_db(struct og_server_cfg *cfg, json_t *element)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int parse_json_samba(struct og_server_cfg *cfg, json_t *element)
|
||||||
|
{
|
||||||
|
const char *key;
|
||||||
|
json_t *value;
|
||||||
|
|
||||||
|
json_object_foreach(element, key, value) {
|
||||||
|
if (!strcmp(key, "user")) {
|
||||||
|
if (og_json_parse_string(value, &cfg->smb.user) < 0)
|
||||||
|
return -1;
|
||||||
|
} else if (!strcmp(key, "pass")) {
|
||||||
|
if (og_json_parse_string(value, &cfg->smb.pass) < 0)
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
syslog(LOG_ERR, "unknown key `%s' in samba\n", key);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int parse_json_wol(struct og_server_cfg *cfg, json_t *element)
|
static int parse_json_wol(struct og_server_cfg *cfg, json_t *element)
|
||||||
{
|
{
|
||||||
const char *key;
|
const char *key;
|
||||||
|
@ -110,6 +131,7 @@ static int parse_json_repo(struct og_server_cfg *cfg, json_t *element)
|
||||||
#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)
|
#define OG_SERVER_CFG_REPO (1 << 3)
|
||||||
|
#define OG_SERVER_CFG_SAMBA (1 << 4)
|
||||||
|
|
||||||
int parse_json_config(const char *filename, struct og_server_cfg *cfg)
|
int parse_json_config(const char *filename, struct og_server_cfg *cfg)
|
||||||
{
|
{
|
||||||
|
@ -157,6 +179,12 @@ 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, "samba")) {
|
||||||
|
if (parse_json_samba(cfg, value) < 0) {
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
flags |= OG_SERVER_CFG_SAMBA;
|
||||||
} else if (!strcmp(key, "repository")) {
|
} else if (!strcmp(key, "repository")) {
|
||||||
if (parse_json_repo(cfg, value) < 0)
|
if (parse_json_repo(cfg, value) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -181,6 +209,9 @@ int parse_json_config(const char *filename, struct og_server_cfg *cfg)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(flags & OG_SERVER_CFG_SAMBA))
|
||||||
|
syslog(LOG_WARNING, "Missing samba configuration in ogserver.json file");
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
json_decref(root);
|
json_decref(root);
|
||||||
else
|
else
|
||||||
|
|
|
@ -11,6 +11,10 @@ struct og_server_cfg {
|
||||||
const char *port;
|
const char *port;
|
||||||
const char *api_token;
|
const char *api_token;
|
||||||
} rest;
|
} rest;
|
||||||
|
struct {
|
||||||
|
const char *user;
|
||||||
|
const char *pass;
|
||||||
|
} smb;
|
||||||
struct {
|
struct {
|
||||||
const char *interface;
|
const char *interface;
|
||||||
} wol;
|
} wol;
|
||||||
|
|
197
src/client.c
197
src/client.c
|
@ -14,6 +14,7 @@
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "rest.h"
|
#include "rest.h"
|
||||||
#include "json.h"
|
#include "json.h"
|
||||||
|
#include <stdint.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <ifaddrs.h>
|
#include <ifaddrs.h>
|
||||||
|
@ -557,6 +558,7 @@ static bool og_update_client_disk_info(struct og_dbi *dbi,
|
||||||
int disk_part_len = 0;
|
int disk_part_len = 0;
|
||||||
char disk_part[1024];
|
char disk_part[1024];
|
||||||
const char *msglog;
|
const char *msglog;
|
||||||
|
uint64_t part_code;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (serial_number && strlen(serial_number) > 0) {
|
if (serial_number && strlen(serial_number) > 0) {
|
||||||
|
@ -617,7 +619,12 @@ static bool og_update_client_disk_info(struct og_dbi *dbi,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
reported_disk.size = strtoull(disks[i].size, NULL, 0);
|
if (safe_strtoull(disks[i].size, &reported_disk.size, 10, UINT64_MAX) < 0) {
|
||||||
|
syslog(LOG_ERR, "failed to parse disk size for disk %d (%s:%d)\n",
|
||||||
|
i + 1, __func__, __LINE__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
cur_disk.size = dbi_result_get_longlong(result, "tamano");
|
cur_disk.size = dbi_result_get_longlong(result, "tamano");
|
||||||
|
|
||||||
dbi_result_free(result);
|
dbi_result_free(result);
|
||||||
|
@ -661,8 +668,17 @@ static bool og_update_client_disk_info(struct og_dbi *dbi,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
reported_part.size = strtoull(partitions[i].size, NULL, 0);
|
if (safe_strtoull(partitions[i].size, &reported_part.size, 10, UINT64_MAX) < 0) {
|
||||||
reported_part.code = strtoul(partitions[i].code, NULL, 16);
|
syslog(LOG_ERR, "failed to parse partition size %s for partition %d (%s:%d)\n",
|
||||||
|
partitions[i].size, i + 1, __func__, __LINE__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (safe_strtoull(partitions[i].code, &part_code, 16, UINT32_MAX) < 0) {
|
||||||
|
syslog(LOG_ERR, "failed to parse partition code %s for partition %d (%s:%d)\n",
|
||||||
|
partitions[i].code, i + 1, __func__, __LINE__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
reported_part.code = part_code;
|
||||||
reported_part.filesystem = get_filesystem_id(partitions[i].filesystem);
|
reported_part.filesystem = get_filesystem_id(partitions[i].filesystem);
|
||||||
reported_part.used_size = partitions[i].used_size;
|
reported_part.used_size = partitions[i].used_size;
|
||||||
reported_part.free_size = partitions[i].free_size;
|
reported_part.free_size = partitions[i].free_size;
|
||||||
|
@ -677,7 +693,7 @@ static bool og_update_client_disk_info(struct og_dbi *dbi,
|
||||||
"idordenador, numdisk, numpar, codpar, tamano, uso, "
|
"idordenador, numdisk, numpar, codpar, tamano, uso, "
|
||||||
"idsistemafichero, idnombreso, idimagen, "
|
"idsistemafichero, idnombreso, idimagen, "
|
||||||
"used_size, free_size)"
|
"used_size, free_size)"
|
||||||
" VALUES(%d,%s,%s,0x%d,%s,0,%d,%d,0,%lu,%lu)",
|
" VALUES(%d,%s,%s,%d,%s,0,%d,%d,0,%lu,%lu)",
|
||||||
computer_id,
|
computer_id,
|
||||||
partitions[i].disk,
|
partitions[i].disk,
|
||||||
partitions[i].number,
|
partitions[i].number,
|
||||||
|
@ -833,8 +849,12 @@ static int og_resp_refresh(json_t *data, struct og_client *cli)
|
||||||
* client using linux/windows mode.
|
* client using linux/windows mode.
|
||||||
*/
|
*/
|
||||||
if (status) {
|
if (status) {
|
||||||
if (!strncmp(status, "LINUX", strlen("LINUX"))) {
|
if (!strncmp(status, "LINUXS", strlen("LINUXS"))) {
|
||||||
|
cli->status = OG_CLIENT_STATUS_LINUX_SESSION;
|
||||||
|
} else if (!strncmp(status, "LINUX", strlen("LINUX"))) {
|
||||||
cli->status = OG_CLIENT_STATUS_LINUX;
|
cli->status = OG_CLIENT_STATUS_LINUX;
|
||||||
|
} else if (!strncmp(status, "WINS", strlen("WINS"))) {
|
||||||
|
cli->status = OG_CLIENT_STATUS_WIN_SESSION;
|
||||||
} else if (!strncmp(status, "WIN", strlen("WIN"))) {
|
} else if (!strncmp(status, "WIN", strlen("WIN"))) {
|
||||||
cli->status = OG_CLIENT_STATUS_WIN;
|
cli->status = OG_CLIENT_STATUS_WIN;
|
||||||
}
|
}
|
||||||
|
@ -890,38 +910,10 @@ static bool og_dbi_update_image(struct og_dbi *dbi,
|
||||||
const struct og_image_legacy *img_info,
|
const struct og_image_legacy *img_info,
|
||||||
const char *computer_id)
|
const char *computer_id)
|
||||||
{
|
{
|
||||||
int repo_id, sw_id, repo_alias;
|
|
||||||
const char *msglog;
|
const char *msglog;
|
||||||
dbi_result result;
|
dbi_result result;
|
||||||
uint32_t revision;
|
uint32_t revision;
|
||||||
|
int sw_id;
|
||||||
/* find repository identifier by repository ip and computer ID. */
|
|
||||||
result = dbi_conn_queryf(dbi->conn,
|
|
||||||
"SELECT repositorios.idrepositorio, repositorios.alias"
|
|
||||||
" FROM repositorios"
|
|
||||||
" LEFT JOIN ordenadores USING (idrepositorio)"
|
|
||||||
" WHERE repositorios.ip='%s' AND ordenadores.idordenador=%s",
|
|
||||||
img_info->repo, computer_id);
|
|
||||||
if (!result) {
|
|
||||||
dbi_conn_error(dbi->conn, &msglog);
|
|
||||||
syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
|
|
||||||
__func__, __LINE__, msglog);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!dbi_result_next_row(result)) {
|
|
||||||
syslog(LOG_ERR,
|
|
||||||
"repository does not exist in database (%s:%d)\n",
|
|
||||||
__func__, __LINE__);
|
|
||||||
dbi_result_free(result);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
repo_alias = dbi_result_get_uint(result, "alias");
|
|
||||||
if (repo_alias)
|
|
||||||
repo_id = repo_alias;
|
|
||||||
else
|
|
||||||
repo_id = dbi_result_get_uint(result, "idrepositorio");
|
|
||||||
|
|
||||||
dbi_result_free(result);
|
|
||||||
|
|
||||||
/* find software id by computer ID, disk number and partition. */
|
/* find software id by computer ID, disk number and partition. */
|
||||||
result = dbi_conn_queryf(dbi->conn,
|
result = dbi_conn_queryf(dbi->conn,
|
||||||
|
@ -949,11 +941,11 @@ static bool og_dbi_update_image(struct og_dbi *dbi,
|
||||||
result = dbi_conn_queryf(dbi->conn,
|
result = dbi_conn_queryf(dbi->conn,
|
||||||
"UPDATE imagenes"
|
"UPDATE imagenes"
|
||||||
" SET idordenador=%s, numdisk=%s, numpar=%s, codpar=%s,"
|
" SET idordenador=%s, numdisk=%s, numpar=%s, codpar=%s,"
|
||||||
" idperfilsoft=%d, idrepositorio=%d,"
|
" idperfilsoft=%d, "
|
||||||
" fechacreacion=NOW(), revision=revision+1"
|
" fechacreacion=NOW(), revision=revision+1"
|
||||||
" WHERE idimagen=%s",
|
" WHERE idimagen=%s",
|
||||||
computer_id, img_info->disk, img_info->part, img_info->code,
|
computer_id, img_info->disk, img_info->part, img_info->code,
|
||||||
sw_id, repo_id, img_info->image_id);
|
sw_id, img_info->image_id);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
dbi_conn_error(dbi->conn, &msglog);
|
dbi_conn_error(dbi->conn, &msglog);
|
||||||
|
@ -1115,8 +1107,8 @@ static int og_resp_image_create(json_t *data, struct og_client *cli)
|
||||||
computer.center);
|
computer.center);
|
||||||
snprintf(soft_legacy.software, sizeof(soft_legacy.software), "%s",
|
snprintf(soft_legacy.software, sizeof(soft_legacy.software), "%s",
|
||||||
software);
|
software);
|
||||||
snprintf(img_legacy.image_id, sizeof(img_legacy.image_id), "%s",
|
snprintf(img_legacy.image_id, sizeof(img_legacy.image_id), "%u",
|
||||||
image_id);
|
cli->last_cmd.ctx.image.id);
|
||||||
snprintf(soft_legacy.id, sizeof(soft_legacy.id), "%d", computer.id);
|
snprintf(soft_legacy.id, sizeof(soft_legacy.id), "%d", computer.id);
|
||||||
snprintf(img_legacy.part, sizeof(img_legacy.part), "%s", partition);
|
snprintf(img_legacy.part, sizeof(img_legacy.part), "%s", partition);
|
||||||
snprintf(img_legacy.disk, sizeof(img_legacy.disk), "%s", disk);
|
snprintf(img_legacy.disk, sizeof(img_legacy.disk), "%s", disk);
|
||||||
|
@ -1132,24 +1124,27 @@ static int og_resp_image_create(json_t *data, struct og_client *cli)
|
||||||
soft_legacy.center);
|
soft_legacy.center);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
og_dbi_close(dbi);
|
og_dbi_close(dbi);
|
||||||
syslog(LOG_ERR, "Problem updating client configuration\n");
|
syslog(LOG_ERR, "Problem updating software inventory (%s:%u)\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = og_dbi_update_image(dbi, &img_legacy, soft_legacy.id);
|
res = og_dbi_update_image(dbi, &img_legacy, soft_legacy.id);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
og_dbi_close(dbi);
|
og_dbi_close(dbi);
|
||||||
syslog(LOG_ERR, "Problem updating client configuration\n");
|
syslog(LOG_ERR, "Problem updating image (%s:%u)\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = update_image_info(dbi, image_id, clonator, compressor,
|
res = update_image_info(dbi, img_legacy.image_id, clonator, compressor,
|
||||||
filesystem, datasize, size, lastupdate, perms,
|
filesystem, datasize, size, lastupdate, perms,
|
||||||
checksum);
|
checksum);
|
||||||
og_dbi_close(dbi);
|
og_dbi_close(dbi);
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
syslog(LOG_ERR, "Problem updating image info\n");
|
syslog(LOG_ERR, "Problem updating image (%s:%u)\n",
|
||||||
|
__FILE__, __LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1159,37 +1154,17 @@ static int og_resp_image_create(json_t *data, struct og_client *cli)
|
||||||
static int og_resp_image_restore(json_t *data, struct og_client *cli)
|
static int og_resp_image_restore(json_t *data, struct og_client *cli)
|
||||||
{
|
{
|
||||||
struct og_software_legacy soft_legacy;
|
struct og_software_legacy soft_legacy;
|
||||||
|
uint32_t disk, partition, image_id;
|
||||||
struct og_image_legacy img_legacy;
|
struct og_image_legacy img_legacy;
|
||||||
struct og_computer computer = {};
|
struct og_computer computer = {};
|
||||||
const char *partition = NULL;
|
|
||||||
const char *image_id = NULL;
|
|
||||||
const char *disk = NULL;
|
|
||||||
const char *msglog;
|
const char *msglog;
|
||||||
struct og_dbi *dbi;
|
struct og_dbi *dbi;
|
||||||
dbi_result result;
|
dbi_result result;
|
||||||
const char *key;
|
|
||||||
json_t *value;
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (json_typeof(data) != JSON_OBJECT)
|
err = og_resp_refresh(data, cli);
|
||||||
return -1;
|
if (err < 0)
|
||||||
|
return err;
|
||||||
json_object_foreach(data, key, value) {
|
|
||||||
if (!strcmp(key, "partition"))
|
|
||||||
err = og_json_parse_string(value, &partition);
|
|
||||||
else if (!strcmp(key, "disk"))
|
|
||||||
err = og_json_parse_string(value, &disk);
|
|
||||||
else if (!strcmp(key, "image_id"))
|
|
||||||
err = og_json_parse_string(value, &image_id);
|
|
||||||
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!partition || !disk || !image_id) {
|
|
||||||
syslog(LOG_ERR, "malformed response json\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbi = og_dbi_open(&ogconfig.db);
|
dbi = og_dbi_open(&ogconfig.db);
|
||||||
if (!dbi) {
|
if (!dbi) {
|
||||||
|
@ -1198,9 +1173,13 @@ static int og_resp_image_restore(json_t *data, struct og_client *cli)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
image_id = cli->last_cmd.ctx.image_restore.id;
|
||||||
|
partition = cli->last_cmd.ctx.image_restore.part;
|
||||||
|
disk = cli->last_cmd.ctx.image_restore.disk;
|
||||||
|
|
||||||
result = dbi_conn_queryf(dbi->conn,
|
result = dbi_conn_queryf(dbi->conn,
|
||||||
"SELECT idperfilsoft FROM imagenes "
|
"SELECT idperfilsoft FROM imagenes "
|
||||||
" WHERE idimagen='%s'", image_id);
|
" WHERE idimagen='%u'", image_id);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
og_dbi_close(dbi);
|
og_dbi_close(dbi);
|
||||||
syslog(LOG_ERR, "failed to query database\n");
|
syslog(LOG_ERR, "failed to query database\n");
|
||||||
|
@ -1209,7 +1188,8 @@ static int og_resp_image_restore(json_t *data, struct og_client *cli)
|
||||||
if (!dbi_result_next_row(result)) {
|
if (!dbi_result_next_row(result)) {
|
||||||
dbi_result_free(result);
|
dbi_result_free(result);
|
||||||
og_dbi_close(dbi);
|
og_dbi_close(dbi);
|
||||||
syslog(LOG_ERR, "software profile does not exist in database\n");
|
syslog(LOG_ERR, "software profile for image id %u does not exist in database\n",
|
||||||
|
image_id);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
snprintf(img_legacy.software_id, sizeof(img_legacy.software_id),
|
snprintf(img_legacy.software_id, sizeof(img_legacy.software_id),
|
||||||
|
@ -1222,20 +1202,19 @@ static int og_resp_image_restore(json_t *data, struct og_client *cli)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(img_legacy.image_id, sizeof(img_legacy.image_id), "%s",
|
snprintf(img_legacy.image_id, sizeof(img_legacy.image_id), "%u",
|
||||||
image_id);
|
image_id);
|
||||||
snprintf(img_legacy.part, sizeof(img_legacy.part), "%s", partition);
|
snprintf(img_legacy.part, sizeof(img_legacy.part), "%u", partition);
|
||||||
snprintf(img_legacy.disk, sizeof(img_legacy.disk), "%s", disk);
|
snprintf(img_legacy.disk, sizeof(img_legacy.disk), "%u", disk);
|
||||||
snprintf(soft_legacy.id, sizeof(soft_legacy.id), "%d", computer.id);
|
snprintf(soft_legacy.id, sizeof(soft_legacy.id), "%u", computer.id);
|
||||||
|
|
||||||
result = dbi_conn_queryf(dbi->conn,
|
result = dbi_conn_queryf(dbi->conn,
|
||||||
"UPDATE ordenadores_particiones"
|
"UPDATE ordenadores_particiones"
|
||||||
" SET idimagen=%s, idperfilsoft=%s, fechadespliegue=NOW(),"
|
" SET idimagen=%s, idperfilsoft=%s, fechadespliegue=NOW(),"
|
||||||
" revision=(SELECT revision FROM imagenes WHERE idimagen=%s),"
|
" revision=(SELECT revision FROM imagenes WHERE idimagen=%s)"
|
||||||
" idnombreso=IFNULL((SELECT idnombreso FROM perfilessoft WHERE idperfilsoft=%s),0)"
|
|
||||||
" WHERE idordenador=%s AND numdisk=%s AND numpar=%s",
|
" WHERE idordenador=%s AND numdisk=%s AND numpar=%s",
|
||||||
img_legacy.image_id, img_legacy.software_id,
|
img_legacy.image_id, img_legacy.software_id,
|
||||||
img_legacy.image_id, img_legacy.software_id,
|
img_legacy.image_id,
|
||||||
soft_legacy.id, img_legacy.disk, img_legacy.part);
|
soft_legacy.id, img_legacy.disk, img_legacy.part);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
dbi_conn_error(dbi->conn, &msglog);
|
dbi_conn_error(dbi->conn, &msglog);
|
||||||
|
@ -1274,11 +1253,9 @@ static int og_agent_http_response_code(const char *buf)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int og_clear_image_placeholder()
|
static int og_resp_image_create_error(struct og_client *cli)
|
||||||
{
|
{
|
||||||
uint32_t image_id = 0;
|
|
||||||
struct og_dbi *dbi;
|
struct og_dbi *dbi;
|
||||||
dbi_result result;
|
|
||||||
|
|
||||||
dbi = og_dbi_open(&ogconfig.db);
|
dbi = og_dbi_open(&ogconfig.db);
|
||||||
if (!dbi) {
|
if (!dbi) {
|
||||||
|
@ -1287,26 +1264,9 @@ static int og_clear_image_placeholder()
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = dbi_conn_queryf(dbi->conn,
|
if (og_dbi_delete_image(dbi, cli->last_cmd.ctx.image.id) < 0) {
|
||||||
"SELECT idimagen FROM imagenes WHERE fechacreacion IS NULL");
|
syslog(LOG_WARNING, "Cannot delete image stub with id %d\n",
|
||||||
if (!result) {
|
cli->last_cmd.ctx.image.id);
|
||||||
syslog(LOG_ERR, "failed to query database\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dbi_result_next_row(result)) {
|
|
||||||
dbi_result_free(result);
|
|
||||||
og_dbi_close(dbi);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
image_id = dbi_result_get_uint(result, "idimagen");
|
|
||||||
dbi_result_free(result);
|
|
||||||
|
|
||||||
syslog(LOG_INFO, "Trying to delete uninitialized image with id %d\n", image_id);
|
|
||||||
|
|
||||||
if (og_dbi_delete_image(dbi, image_id) < 0) {
|
|
||||||
og_dbi_close(dbi);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1314,9 +1274,16 @@ static int og_clear_image_placeholder()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void og_client_reset_cmd(struct og_client *cli)
|
||||||
|
{
|
||||||
|
cli->last_cmd.id = 0;
|
||||||
|
cli->last_cmd.type = OG_CMD_UNSPEC;
|
||||||
|
memset(&cli->last_cmd.ctx, 0, sizeof(cli->last_cmd.ctx));
|
||||||
|
}
|
||||||
|
|
||||||
int og_agent_state_process_response(struct og_client *cli)
|
int og_agent_state_process_response(struct og_client *cli)
|
||||||
{
|
{
|
||||||
enum og_cmd_type cmd_type = cli->last_cmd;
|
enum og_cmd_type cmd_type = cli->last_cmd.type;
|
||||||
int ret, err = -1, code;
|
int ret, err = -1, code;
|
||||||
json_error_t json_err;
|
json_error_t json_err;
|
||||||
bool success;
|
bool success;
|
||||||
|
@ -1343,7 +1310,7 @@ int og_agent_state_process_response(struct og_client *cli)
|
||||||
case 500:
|
case 500:
|
||||||
ret = 0;
|
ret = 0;
|
||||||
success = false;
|
success = false;
|
||||||
cli->last_cmd = OG_CMD_UNSPEC;
|
cli->last_cmd.type = OG_CMD_UNSPEC;
|
||||||
syslog(LOG_ERR, "Client %s:%hu reports failure to process command\n",
|
syslog(LOG_ERR, "Client %s:%hu reports failure to process command\n",
|
||||||
inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
|
inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port));
|
||||||
/* ... cancel pending actions related to this task for this client here */
|
/* ... cancel pending actions related to this task for this client here */
|
||||||
|
@ -1363,21 +1330,25 @@ int og_agent_state_process_response(struct og_client *cli)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
cli->last_cmd_result = OG_SUCCESS;
|
cli->last_cmd.result = OG_SUCCESS;
|
||||||
else
|
else
|
||||||
cli->last_cmd_result = OG_FAILURE;
|
cli->last_cmd.result = OG_FAILURE;
|
||||||
|
|
||||||
if (!success && cmd_type == OG_CMD_IMAGE_CREATE)
|
if (!success && cmd_type == OG_CMD_IMAGE_CREATE) {
|
||||||
og_clear_image_placeholder();
|
syslog(LOG_ERR, "Client %s:%hu reports failure when creating image with id %d\n",
|
||||||
|
inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port),
|
||||||
|
cli->last_cmd.ctx.image.id);
|
||||||
|
og_resp_image_create_error(cli);
|
||||||
|
}
|
||||||
|
|
||||||
if (code != 200 && code != 103) {
|
if (code != 200 && code != 103) {
|
||||||
cli->last_cmd_id = 0;
|
cli->last_cmd.id = 0;
|
||||||
|
memset(&cli->last_cmd.ctx, 0, sizeof(cli->last_cmd.ctx));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cli->content_length) {
|
if (!cli->content_length) {
|
||||||
cli->last_cmd_id = 0;
|
og_client_reset_cmd(cli);
|
||||||
cli->last_cmd = OG_CMD_UNSPEC;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1396,7 +1367,7 @@ int og_agent_state_process_response(struct og_client *cli)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (cli->last_cmd) {
|
switch (cli->last_cmd.type) {
|
||||||
case OG_CMD_SHELL_RUN:
|
case OG_CMD_SHELL_RUN:
|
||||||
err = og_resp_shell_run(cli, root);
|
err = og_resp_shell_run(cli, root);
|
||||||
break;
|
break;
|
||||||
|
@ -1413,6 +1384,11 @@ int og_agent_state_process_response(struct og_client *cli)
|
||||||
err = og_resp_refresh(root, cli);
|
err = og_resp_refresh(root, cli);
|
||||||
break;
|
break;
|
||||||
case OG_CMD_IMAGE_CREATE:
|
case OG_CMD_IMAGE_CREATE:
|
||||||
|
err = og_resp_image_create(root, cli);
|
||||||
|
if (err < 0)
|
||||||
|
og_resp_image_create_error(cli);
|
||||||
|
break;
|
||||||
|
case OG_CMD_IMAGE_UPDATE:
|
||||||
err = og_resp_image_create(root, cli);
|
err = og_resp_image_create(root, cli);
|
||||||
break;
|
break;
|
||||||
case OG_CMD_IMAGE_RESTORE:
|
case OG_CMD_IMAGE_RESTORE:
|
||||||
|
@ -1436,12 +1412,11 @@ int og_agent_state_process_response(struct og_client *cli)
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err = 0;
|
err = 0;
|
||||||
success = false;
|
success = false;
|
||||||
cli->last_cmd_result = OG_FAILURE;
|
cli->last_cmd.result = OG_FAILURE;
|
||||||
/* ... cancel pending actions related to this task for this client here */
|
/* ... cancel pending actions related to this task for this client here */
|
||||||
}
|
}
|
||||||
|
|
||||||
cli->last_cmd_id = 0;
|
og_client_reset_cmd(cli);
|
||||||
cli->last_cmd = OG_CMD_UNSPEC;
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
11
src/core.c
11
src/core.c
|
@ -281,7 +281,7 @@ static void og_agent_send_refresh(struct og_client *cli)
|
||||||
params.ips_array[0] = inet_ntoa(cli->addr.sin_addr);
|
params.ips_array[0] = inet_ntoa(cli->addr.sin_addr);
|
||||||
params.ips_array_len = 1;
|
params.ips_array_len = 1;
|
||||||
|
|
||||||
og_send_request(OG_METHOD_GET, OG_CMD_REFRESH, ¶ms, NULL);
|
og_send_request(OG_METHOD_GET, OG_CMD_REFRESH, ¶ms, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shut down connection if there is no complete message after 10 seconds. */
|
/* Shut down connection if there is no complete message after 10 seconds. */
|
||||||
|
@ -367,6 +367,7 @@ void og_server_accept_cb(struct ev_loop *loop, struct ev_io *io, int events)
|
||||||
int og_socket_server_init(const char *addr, const char *port)
|
int og_socket_server_init(const char *addr, const char *port)
|
||||||
{
|
{
|
||||||
struct sockaddr_in local;
|
struct sockaddr_in local;
|
||||||
|
uint64_t port_num;
|
||||||
uint32_t s_addr;
|
uint32_t s_addr;
|
||||||
int sd, on = 1;
|
int sd, on = 1;
|
||||||
|
|
||||||
|
@ -384,7 +385,13 @@ int og_socket_server_init(const char *addr, const char *port)
|
||||||
|
|
||||||
local.sin_addr.s_addr = s_addr;
|
local.sin_addr.s_addr = s_addr;
|
||||||
local.sin_family = AF_INET;
|
local.sin_family = AF_INET;
|
||||||
local.sin_port = htons(atoi(port));
|
|
||||||
|
if (safe_strtoull(port, &port_num, 10, UINT16_MAX) < 0) {
|
||||||
|
syslog(LOG_ERR, "failed to parse port %s (%s:%d)\n",
|
||||||
|
port, __func__, __LINE__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
local.sin_port = htons(port_num);
|
||||||
|
|
||||||
if (bind(sd, (struct sockaddr *) &local, sizeof(local)) < 0) {
|
if (bind(sd, (struct sockaddr *) &local, sizeof(local)) < 0) {
|
||||||
close(sd);
|
close(sd);
|
||||||
|
|
|
@ -75,7 +75,6 @@ struct og_msg_params {
|
||||||
const char *cache;
|
const char *cache;
|
||||||
const char *cache_size;
|
const char *cache_size;
|
||||||
const char *comment;
|
const char *comment;
|
||||||
bool echo;
|
|
||||||
struct og_partition partition_setup[OG_PARTITION_MAX];
|
struct og_partition partition_setup[OG_PARTITION_MAX];
|
||||||
struct og_image image;
|
struct og_image image;
|
||||||
uint64_t flags;
|
uint64_t flags;
|
||||||
|
@ -83,8 +82,6 @@ struct og_msg_params {
|
||||||
};
|
};
|
||||||
|
|
||||||
int og_json_parse_partition_setup(json_t *element, struct og_msg_params *params);
|
int og_json_parse_partition_setup(json_t *element, struct og_msg_params *params);
|
||||||
int og_json_parse_create_image(json_t *element, struct og_msg_params *params);
|
|
||||||
int og_json_parse_restore_image(json_t *element, struct og_msg_params *params);
|
|
||||||
|
|
||||||
struct og_cmd_json {
|
struct og_cmd_json {
|
||||||
const char *type;
|
const char *type;
|
||||||
|
|
|
@ -575,7 +575,7 @@ bool cuestionPerfilSoftware(struct og_dbi *dbi, char *idc, char *ido,
|
||||||
if (idperfilsoftware != nwidperfilsoft) { // No coinciden los perfiles
|
if (idperfilsoftware != nwidperfilsoft) { // No coinciden los perfiles
|
||||||
// Actualiza el identificador del perfil software del ordenador
|
// Actualiza el identificador del perfil software del ordenador
|
||||||
result = dbi_conn_queryf(dbi->conn,
|
result = dbi_conn_queryf(dbi->conn,
|
||||||
"UPDATE ordenadores_particiones SET idperfilsoft=%d,idimagen=0"
|
"UPDATE ordenadores_particiones SET idperfilsoft=%d"
|
||||||
" WHERE idordenador=%s AND numpar=%s", nwidperfilsoft, ido, par);
|
" WHERE idordenador=%s AND numpar=%s", nwidperfilsoft, ido, par);
|
||||||
if (!result) { // Error al insertar
|
if (!result) { // Error al insertar
|
||||||
dbi_conn_error(dbi->conn, &msglog);
|
dbi_conn_error(dbi->conn, &msglog);
|
||||||
|
|
1853
src/rest.c
1853
src/rest.c
File diff suppressed because it is too large
Load Diff
27
src/rest.h
27
src/rest.h
|
@ -51,6 +51,19 @@ enum og_cmd_result {
|
||||||
OG_SUCCESS = 2,
|
OG_SUCCESS = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct og_cmd_ctx {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint32_t id;
|
||||||
|
} image;
|
||||||
|
struct {
|
||||||
|
uint32_t id;
|
||||||
|
uint32_t disk;
|
||||||
|
uint32_t part;
|
||||||
|
} image_restore;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
#define OG_MSG_REQUEST_MAXLEN 131072
|
#define OG_MSG_REQUEST_MAXLEN 131072
|
||||||
|
|
||||||
struct og_client {
|
struct og_client {
|
||||||
|
@ -66,9 +79,12 @@ struct og_client {
|
||||||
int content_length;
|
int content_length;
|
||||||
char auth_token[64];
|
char auth_token[64];
|
||||||
enum og_client_status status;
|
enum og_client_status status;
|
||||||
enum og_cmd_type last_cmd;
|
struct {
|
||||||
unsigned int last_cmd_id;
|
enum og_cmd_type type;
|
||||||
enum og_cmd_result last_cmd_result;
|
unsigned int id;
|
||||||
|
enum og_cmd_result result;
|
||||||
|
struct og_cmd_ctx ctx;
|
||||||
|
} last_cmd;
|
||||||
uint32_t speed;
|
uint32_t speed;
|
||||||
uint32_t seq;
|
uint32_t seq;
|
||||||
struct {
|
struct {
|
||||||
|
@ -131,7 +147,10 @@ enum og_rest_uri {
|
||||||
OG_URI_CACHE_FETCH,
|
OG_URI_CACHE_FETCH,
|
||||||
OG_URI_PART_SETUP,
|
OG_URI_PART_SETUP,
|
||||||
OG_URI_OGLIVE_LIST,
|
OG_URI_OGLIVE_LIST,
|
||||||
|
OG_URI_OGLIVE_ADD,
|
||||||
|
OG_URI_OGLIVE_DELETE,
|
||||||
OG_URI_OGLIVE_SET,
|
OG_URI_OGLIVE_SET,
|
||||||
|
OG_URI_OGLIVE_DEFAULT,
|
||||||
OG_URI_CENTER_ADD,
|
OG_URI_CENTER_ADD,
|
||||||
OG_URI_CENTER_UPDATE,
|
OG_URI_CENTER_UPDATE,
|
||||||
OG_URI_CENTER_DELETE,
|
OG_URI_CENTER_DELETE,
|
||||||
|
@ -157,7 +176,7 @@ enum og_rest_method {
|
||||||
|
|
||||||
int og_send_request(enum og_rest_method method, enum og_cmd_type type,
|
int og_send_request(enum og_rest_method method, enum og_cmd_type type,
|
||||||
const struct og_msg_params *params,
|
const struct og_msg_params *params,
|
||||||
const json_t *data);
|
const json_t *data, const struct og_cmd_ctx *ctx);
|
||||||
|
|
||||||
int og_dbi_scope_get(struct og_dbi *dbi, json_t *array);
|
int og_dbi_scope_get(struct og_dbi *dbi, json_t *array);
|
||||||
|
|
||||||
|
|
71
src/schema.c
71
src/schema.c
|
@ -464,6 +464,75 @@ static int og_dbi_schema_v11(struct og_dbi *dbi)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int og_dbi_schema_v12(struct og_dbi *dbi)
|
||||||
|
{
|
||||||
|
const char *msglog;
|
||||||
|
dbi_result result;
|
||||||
|
|
||||||
|
syslog(LOG_DEBUG, "Creating table oglive\n");
|
||||||
|
result = dbi_conn_query(dbi->conn, "CREATE TABLE `oglive` ("
|
||||||
|
"`id` BIGINT NOT NULL AUTO_INCREMENT,"
|
||||||
|
"`name` VARCHAR(100),"
|
||||||
|
"`creation_date` DATETIME NOT NULL,"
|
||||||
|
"`is_default` BOOLEAN NOT NULL,"
|
||||||
|
"PRIMARY KEY (`id`)"
|
||||||
|
")");
|
||||||
|
if (!result) {
|
||||||
|
dbi_conn_error(dbi->conn, &msglog);
|
||||||
|
syslog(LOG_INFO, "Error when creating oglive (%s:%d) %s\n",
|
||||||
|
__func__, __LINE__, msglog);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
dbi_result_free(result);
|
||||||
|
|
||||||
|
result = dbi_conn_query(dbi->conn, "UPDATE version SET version = 12");
|
||||||
|
if (!result) {
|
||||||
|
dbi_conn_error(dbi->conn, &msglog);
|
||||||
|
syslog(LOG_INFO, "Could not update version row (%s:%d) %s\n",
|
||||||
|
__func__, __LINE__, msglog);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
dbi_result_free(result);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int og_dbi_schema_v13(struct og_dbi *dbi)
|
||||||
|
{
|
||||||
|
const char *msglog;
|
||||||
|
dbi_result result;
|
||||||
|
|
||||||
|
syslog(LOG_DEBUG, "Updating table oglive\n");
|
||||||
|
result = dbi_conn_query(dbi->conn, "ALTER TABLE `oglive` DROP COLUMN `is_default`");
|
||||||
|
if (!result) {
|
||||||
|
dbi_conn_error(dbi->conn, &msglog);
|
||||||
|
syslog(LOG_INFO, "Error deleting column is_default in oglive table (%s:%d) %s\n",
|
||||||
|
__func__, __LINE__, msglog);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
dbi_result_free(result);
|
||||||
|
|
||||||
|
result = dbi_conn_query(dbi->conn, "ALTER TABLE `oglive` ADD COLUMN `priority` INT NOT NULL DEFAULT 0");
|
||||||
|
if (!result) {
|
||||||
|
dbi_conn_error(dbi->conn, &msglog);
|
||||||
|
syslog(LOG_INFO, "Error adding column priority to oglive table (%s:%d) %s\n",
|
||||||
|
__func__, __LINE__, msglog);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
dbi_result_free(result);
|
||||||
|
|
||||||
|
result = dbi_conn_query(dbi->conn, "UPDATE version SET version = 13");
|
||||||
|
if (!result) {
|
||||||
|
dbi_conn_error(dbi->conn, &msglog);
|
||||||
|
syslog(LOG_INFO, "Could not update version row (%s:%d) %s\n",
|
||||||
|
__func__, __LINE__, msglog);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
dbi_result_free(result);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static struct og_schema_version {
|
static struct og_schema_version {
|
||||||
int version;
|
int version;
|
||||||
int (*update)(struct og_dbi *dbi);
|
int (*update)(struct og_dbi *dbi);
|
||||||
|
@ -479,6 +548,8 @@ static struct og_schema_version {
|
||||||
{ .version = 9, .update = og_dbi_schema_v9, },
|
{ .version = 9, .update = og_dbi_schema_v9, },
|
||||||
{ .version = 10, .update = og_dbi_schema_v10,},
|
{ .version = 10, .update = og_dbi_schema_v10,},
|
||||||
{ .version = 11, .update = og_dbi_schema_v11,},
|
{ .version = 11, .update = og_dbi_schema_v11,},
|
||||||
|
{ .version = 12, .update = og_dbi_schema_v12,},
|
||||||
|
{ .version = 13, .update = og_dbi_schema_v13,},
|
||||||
{ 0, NULL },
|
{ 0, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
28
src/utils.c
28
src/utils.c
|
@ -7,7 +7,12 @@
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
void str_toupper(char *str)
|
void str_toupper(char *str)
|
||||||
|
@ -29,3 +34,26 @@ void str_tolower(char *str)
|
||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int safe_strtoull(const char *str, uint64_t *out_value, int base, uint64_t max)
|
||||||
|
{
|
||||||
|
char *endptr = NULL;
|
||||||
|
uint64_t result;
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
assert(str != NULL && out_value != NULL);
|
||||||
|
|
||||||
|
if (str[0] == '-')
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
result = strtoull(str, &endptr, base);
|
||||||
|
|
||||||
|
if (endptr == str ||
|
||||||
|
*endptr != '\0' ||
|
||||||
|
(errno == ERANGE && result == ULLONG_MAX) ||
|
||||||
|
result > max)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
*out_value = result;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
#ifndef _OG_UTILS_H
|
#ifndef _OG_UTILS_H
|
||||||
#define _OG_UTILS_H
|
#define _OG_UTILS_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
void str_toupper(char *str);
|
void str_toupper(char *str);
|
||||||
void str_tolower(char *str);
|
void str_tolower(char *str);
|
||||||
|
int safe_strtoull(const char *str, uint64_t *out_value, int base, uint64_t max);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue