mirror of https://git.48k.eu/ogserver
rest: allow repository to have more than one IP address
Repository can have more than one single IP address. * Add alias field to database to represent the extra IPs that are attached to the repository, update schema and add version 9. * Use og_dbi_get_repository_ip() to infer the repository IP address. * Add helper functions (src/repo.c) to build a list of repositories and update rest API to use it.master
parent
4e0f9aac9e
commit
5eba9f4e1b
|
@ -10,6 +10,7 @@ ogserver_SOURCES= src/ogAdmServer.c \
|
|||
src/schedule.c \
|
||||
src/schema.c \
|
||||
src/utils.c \
|
||||
src/repo.c \
|
||||
src/rest.c \
|
||||
src/client.c \
|
||||
src/json.c \
|
||||
|
|
13
src/client.c
13
src/client.c
|
@ -621,15 +621,15 @@ static bool og_dbi_update_image(struct og_dbi *dbi,
|
|||
const struct og_image_legacy *img_info,
|
||||
const char *computer_id)
|
||||
{
|
||||
int repo_id, sw_id, repo_alias;
|
||||
const char *msglog;
|
||||
dbi_result result;
|
||||
int repo_id, sw_id;
|
||||
uint32_t revision;
|
||||
|
||||
/* find repository identifier by repository ip and computer ID. */
|
||||
result = dbi_conn_queryf(dbi->conn,
|
||||
"SELECT repositorios.idrepositorio"
|
||||
" FROM repositorios"
|
||||
"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);
|
||||
|
@ -646,7 +646,12 @@ static bool og_dbi_update_image(struct og_dbi *dbi,
|
|||
dbi_result_free(result);
|
||||
return false;
|
||||
}
|
||||
repo_id = dbi_result_get_uint(result, "idrepositorio");
|
||||
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. */
|
||||
|
|
76
src/dbi.c
76
src/dbi.c
|
@ -270,14 +270,50 @@ bool og_dbi_get_image(struct og_dbi *dbi, struct og_image *image)
|
|||
}
|
||||
|
||||
int og_dbi_get_repository_ip(const struct og_dbi *dbi, const uint32_t repo_id,
|
||||
char *repository_ip)
|
||||
const char *client_ip, char *repository_ip)
|
||||
{
|
||||
const char *msglog, *dbi_repository_ip;
|
||||
const char *msglog, *netmask_ip, *repo_ip;
|
||||
struct in_addr client, netmask, repo;
|
||||
bool found = false;
|
||||
dbi_result result;
|
||||
|
||||
if (inet_aton(client_ip, &client) < 0) {
|
||||
syslog(LOG_ERR, "failed to parse client IP (%s:%d)\n",
|
||||
__func__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = dbi_conn_queryf(dbi->conn,
|
||||
"SELECT ip FROM repositorios WHERE idrepositorio = %u",
|
||||
repo_id);
|
||||
"SELECT aulas.netmask FROM aulas "
|
||||
"INNER JOIN ordenadores ON ordenadores.idaula = aulas.idaula "
|
||||
"WHERE ordenadores.ip = '%s'", client_ip);
|
||||
if (!result) {
|
||||
dbi_conn_error(dbi->conn, &msglog);
|
||||
syslog(LOG_ERR, "failed to get netmask (%s:%d) %s\n",
|
||||
__func__, __LINE__, msglog);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!dbi_result_next_row(result)) {
|
||||
syslog(LOG_ERR, "netmask does not exist in database (%s:%d)\n",
|
||||
__func__, __LINE__);
|
||||
dbi_result_free(result);
|
||||
return -1;
|
||||
}
|
||||
|
||||
netmask_ip = dbi_result_get_string(result, "netmask");
|
||||
if (inet_aton(netmask_ip, &netmask) < 0) {
|
||||
syslog(LOG_ERR, "failed to parse netmask (%s:%d)\n",
|
||||
__func__, __LINE__);
|
||||
dbi_result_free(result);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dbi_result_free(result);
|
||||
|
||||
result = dbi_conn_queryf(dbi->conn,
|
||||
"SELECT ip FROM repositorios WHERE idrepositorio = %u OR alias = %u",
|
||||
repo_id, repo_id);
|
||||
if (!result) {
|
||||
dbi_conn_error(dbi->conn, &msglog);
|
||||
syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
|
||||
|
@ -285,19 +321,37 @@ int og_dbi_get_repository_ip(const struct og_dbi *dbi, const uint32_t repo_id,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (!dbi_result_next_row(result)) {
|
||||
dbi_conn_error(dbi->conn, &msglog);
|
||||
while (dbi_result_next_row(result) > 0) {
|
||||
repo_ip = dbi_result_get_string(result, "ip");
|
||||
|
||||
if (inet_aton(repo_ip, &repo) < 0) {
|
||||
syslog(LOG_ERR, "failed to get repository IP (%s:%d)\n",
|
||||
__func__, __LINE__);
|
||||
dbi_result_free(result);
|
||||
return -1;
|
||||
}
|
||||
client.s_addr &= netmask.s_addr;
|
||||
|
||||
if (client.s_addr != (repo.s_addr & netmask.s_addr))
|
||||
continue;
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
syslog(LOG_ERR,
|
||||
"repository with id %u does not exist (%s:%d) %s\n",
|
||||
repo_id, __func__, __LINE__, msglog);
|
||||
"cannot find repository IP with repository ID %u for client %s (%s:%d)\n",
|
||||
repo_id, client_ip, __func__, __LINE__);
|
||||
dbi_result_free(result);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dbi_repository_ip = dbi_result_get_string(result, "ip");
|
||||
snprintf(repository_ip, OG_DB_IP_MAXLEN + 1, "%s", dbi_repository_ip);
|
||||
|
||||
snprintf(repository_ip, OG_DB_IP_MAXLEN + 1, "%s", repo_ip);
|
||||
dbi_result_free(result);
|
||||
|
||||
syslog(LOG_INFO, "using repository with ID %u and IP %s for computer %s\n",
|
||||
repo_id, repository_ip, client_ip);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -127,12 +127,6 @@ struct og_folder {
|
|||
char name[OG_DB_FOLDER_NAME_MAXLEN + 1];
|
||||
};
|
||||
|
||||
struct og_repository {
|
||||
unsigned int center;
|
||||
char name[OG_DB_REPO_NAME_MAXLEN];
|
||||
char ip[OG_DB_IP_MAXLEN];
|
||||
};
|
||||
|
||||
struct in_addr;
|
||||
int og_dbi_get_computer_info(struct og_dbi *dbi, struct og_computer *computer,
|
||||
struct in_addr addr);
|
||||
|
@ -145,6 +139,6 @@ int og_dbi_add_image(struct og_dbi *dbi, struct og_image *image);
|
|||
int og_dbi_schema_update(void);
|
||||
|
||||
int og_dbi_get_repository_ip(const struct og_dbi *dbi, const uint32_t repo_id,
|
||||
char *repository_ip);
|
||||
const char *client_ip, char *repository_ip);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Copyright (C) 2020-2021 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 <stdint.h>
|
||||
#include <syslog.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "cfg.h"
|
||||
#include "list.h"
|
||||
#include "repo.h"
|
||||
#include "dbi.h"
|
||||
|
||||
static struct og_repo *og_repo_alloc(uint32_t id, const char *name,
|
||||
struct in_addr *addr)
|
||||
{
|
||||
struct og_repo *repo;
|
||||
|
||||
repo = calloc(1, sizeof(struct og_repo));
|
||||
if (!repo)
|
||||
return NULL;
|
||||
|
||||
repo->name = strdup(name);
|
||||
repo->id = id;
|
||||
repo->addr[0] = *addr;
|
||||
repo->num_ips++;
|
||||
|
||||
return repo;
|
||||
}
|
||||
|
||||
static int og_repo_add_ip(struct og_repo *repo, struct in_addr *addr)
|
||||
{
|
||||
if (repo->num_ips > OG_ADDR_REPO_MAX)
|
||||
return -1;
|
||||
|
||||
repo->addr[repo->num_ips++] = *addr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct og_repo *og_repo_find(uint32_t id, struct list_head *repo_list)
|
||||
{
|
||||
struct og_repo *repo;
|
||||
|
||||
list_for_each_entry(repo, repo_list, list) {
|
||||
if (repo->id == id)
|
||||
return repo;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int og_repo_list(struct list_head *repo_list)
|
||||
{
|
||||
const char *name, *ip;
|
||||
struct og_repo *repo;
|
||||
struct in_addr addr;
|
||||
const char *msglog;
|
||||
struct og_dbi *dbi;
|
||||
uint32_t id, alias;
|
||||
dbi_result result;
|
||||
|
||||
dbi = og_dbi_open(&ogconfig.db);
|
||||
if (!dbi) {
|
||||
syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
|
||||
__func__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = dbi_conn_queryf(dbi->conn,
|
||||
"SELECT idrepositorio, ip, nombrerepositorio, alias "
|
||||
"FROM repositorios");
|
||||
if (!result) {
|
||||
dbi_conn_error(dbi->conn, &msglog);
|
||||
syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
|
||||
__func__, __LINE__, msglog);
|
||||
og_dbi_close(dbi);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (dbi_result_next_row(result)) {
|
||||
id = dbi_result_get_ulonglong(result, "idrepositorio");
|
||||
ip = dbi_result_get_string(result, "ip");
|
||||
name = dbi_result_get_string(result, "nombrerepositorio");
|
||||
alias = dbi_result_get_ulonglong(result, "alias");
|
||||
|
||||
if (inet_aton(ip, &addr) < 0) {
|
||||
syslog(LOG_ERR, "malformed IP in repo %s\n", name);
|
||||
goto err_repo_list;
|
||||
}
|
||||
|
||||
if (alias)
|
||||
id = alias;
|
||||
|
||||
repo = og_repo_find(id, repo_list);
|
||||
if (repo) {
|
||||
if (og_repo_add_ip(repo, &addr) < 0) {
|
||||
syslog(LOG_ERR, "too many IPs in repo %s\n",
|
||||
repo->name);
|
||||
goto err_repo_list;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
repo = og_repo_alloc(id, name, &addr);
|
||||
if (!repo)
|
||||
goto err_repo_list;
|
||||
|
||||
list_add_tail(&repo->list, repo_list);
|
||||
}
|
||||
|
||||
dbi_result_free(result);
|
||||
og_dbi_close(dbi);
|
||||
|
||||
return 0;
|
||||
|
||||
err_repo_list:
|
||||
og_repo_free_list(repo_list);
|
||||
dbi_result_free(result);
|
||||
og_dbi_close(dbi);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void og_repo_free_list(struct list_head *repo_list)
|
||||
{
|
||||
struct og_repo *repo, *next;
|
||||
|
||||
list_for_each_entry_safe(repo, next, repo_list, list) {
|
||||
list_del(&repo->list);
|
||||
free((void *)repo->name);
|
||||
free(repo);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef _OG_REPO_H_
|
||||
#define _OG_REPO_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "list.h"
|
||||
|
||||
#define OG_ADDR_REPO_MAX 16
|
||||
|
||||
struct og_repo {
|
||||
struct list_head list;
|
||||
const char *name;
|
||||
uint32_t id;
|
||||
struct in_addr addr[OG_ADDR_REPO_MAX];
|
||||
int num_ips;
|
||||
};
|
||||
|
||||
int og_repo_list(struct list_head *repo_list);
|
||||
void og_repo_free_list(struct list_head *repo_list);
|
||||
|
||||
#endif
|
339
src/rest.c
339
src/rest.c
|
@ -15,6 +15,7 @@
|
|||
#include "core.h"
|
||||
#include "wol.h"
|
||||
#include "cfg.h"
|
||||
#include "repo.h"
|
||||
#include "schedule.h"
|
||||
#include "legacy.h"
|
||||
#include <ev.h>
|
||||
|
@ -1509,7 +1510,6 @@ struct og_boot_mode_params {
|
|||
const char *ip;
|
||||
const char *ipserveradm;
|
||||
const char *nombreaula;
|
||||
const char *repoip;
|
||||
const char *oglivedir;
|
||||
const char *hardprofile;
|
||||
const char *router;
|
||||
|
@ -1518,18 +1518,21 @@ struct og_boot_mode_params {
|
|||
const char *netiface;
|
||||
const char *directorio;
|
||||
const char *resolucion;
|
||||
uint32_t repoid;
|
||||
int is_prof;
|
||||
int has_unit;
|
||||
};
|
||||
|
||||
static int og_get_client_mode_params(struct og_dbi *dbi, const char *mac, char *params, size_t params_size)
|
||||
{
|
||||
char repository_ip[OG_DB_IP_MAXLEN + 1] = {};
|
||||
struct og_boot_mode_params boot_params = {};
|
||||
const char *res_prefix = " vga=";
|
||||
const char *res_value = "788";
|
||||
char *lang = getenv("LANG");
|
||||
const char *msglog;
|
||||
dbi_result result;
|
||||
int err = 0;
|
||||
|
||||
result = dbi_conn_queryf(dbi->conn,
|
||||
"SELECT "
|
||||
|
@ -1540,7 +1543,7 @@ static int og_get_client_mode_params(struct og_dbi *dbi, const char *mac, char *
|
|||
"ordenadores.nombreordenador AS nombreordenador, "
|
||||
"ordenadores.netiface AS netiface, "
|
||||
"REPLACE(TRIM(aulas.nombreaula), ' ', '_') AS nombreaula, "
|
||||
"IFNULL(repositorios.ip, '') AS repoip, "
|
||||
"repositorios.idrepositorio AS repoid, "
|
||||
"ordenadores.oglivedir AS oglivedir, "
|
||||
"IF(ordenadores.idordenador = aulas.idordprofesor, 1, 0) AS is_prof, "
|
||||
"REPLACE(TRIM(IFNULL(perfileshard.descripcion, '')), ' ', '_') AS hardprofile, "
|
||||
|
@ -1584,7 +1587,6 @@ static int og_get_client_mode_params(struct og_dbi *dbi, const char *mac, char *
|
|||
boot_params.nombreordenador = dbi_result_get_string_copy(result, "nombreordenador");
|
||||
boot_params.netiface = dbi_result_get_string_copy(result, "netiface");
|
||||
boot_params.nombreaula = dbi_result_get_string_copy(result, "nombreaula");
|
||||
boot_params.repoip = dbi_result_get_string_copy(result, "repoip");
|
||||
boot_params.oglivedir = dbi_result_get_string_copy(result, "oglivedir");
|
||||
boot_params.hardprofile = dbi_result_get_string_copy(result, "hardprofile");
|
||||
boot_params.ntp = dbi_result_get_string_copy(result, "ntp");
|
||||
|
@ -1592,6 +1594,7 @@ static int og_get_client_mode_params(struct og_dbi *dbi, const char *mac, char *
|
|||
boot_params.proxy = dbi_result_get_string_copy(result, "proxy");
|
||||
boot_params.directorio = dbi_result_get_string_copy(result, "directorio");
|
||||
boot_params.resolucion = dbi_result_get_string_copy(result, "resolucion");
|
||||
boot_params.repoid = dbi_result_get_uint(result, "repoid");
|
||||
boot_params.has_unit = dbi_result_get_uint(result, "has_unit");
|
||||
boot_params.is_prof = dbi_result_get_uint(result, "is_prof");
|
||||
|
||||
|
@ -1601,13 +1604,21 @@ static int og_get_client_mode_params(struct og_dbi *dbi, const char *mac, char *
|
|||
res_prefix = " video=";
|
||||
}
|
||||
|
||||
dbi_result_free(result);
|
||||
|
||||
if (og_dbi_get_repository_ip(dbi, boot_params.repoid, boot_params.ip,
|
||||
repository_ip) < 0) {
|
||||
err = -1;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
snprintf(params, params_size,
|
||||
" LANG=%s ip=%s:%s:%s:%s:%s:%s:none group=%s ogrepo=%s oglive=%s oglog=%s ogshare=%s oglivedir=%s ogprof=%s server=%s"
|
||||
"%s%s%s%s%s%s%s%s%s%s%s%s",
|
||||
lang,
|
||||
boot_params.ip, boot_params.ipserveradm, boot_params.router, boot_params.netmask, boot_params.nombreordenador, boot_params.netiface,
|
||||
boot_params.nombreaula,
|
||||
boot_params.repoip,
|
||||
repository_ip,
|
||||
boot_params.ipserveradm, boot_params.ipserveradm, boot_params.ipserveradm,
|
||||
boot_params.oglivedir,
|
||||
boot_params.is_prof ? "true" : "false",
|
||||
|
@ -1618,9 +1629,7 @@ static int og_get_client_mode_params(struct og_dbi *dbi, const char *mac, char *
|
|||
boot_params.proxy[0] ? " ogproxy=" : "", boot_params.proxy[0] ? boot_params.proxy : "",
|
||||
boot_params.has_unit ? " ogunit=" : "", boot_params.has_unit ? boot_params.directorio : "",
|
||||
res_prefix, res_value);
|
||||
|
||||
dbi_result_free(result);
|
||||
|
||||
err_out:
|
||||
free((void *)boot_params.ip);
|
||||
free((void *)boot_params.ipserveradm);
|
||||
free((void *)boot_params.router);
|
||||
|
@ -1628,7 +1637,6 @@ static int og_get_client_mode_params(struct og_dbi *dbi, const char *mac, char *
|
|||
free((void *)boot_params.nombreordenador);
|
||||
free((void *)boot_params.netiface);
|
||||
free((void *)boot_params.nombreaula);
|
||||
free((void *)boot_params.repoip);
|
||||
free((void *)boot_params.oglivedir);
|
||||
free((void *)boot_params.hardprofile);
|
||||
free((void *)boot_params.ntp);
|
||||
|
@ -1637,11 +1645,11 @@ static int og_get_client_mode_params(struct og_dbi *dbi, const char *mac, char *
|
|||
free((void *)boot_params.directorio);
|
||||
free((void *)boot_params.resolucion);
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int og_set_client_mode(struct og_dbi *dbi, const char *mac,
|
||||
const char *mode)
|
||||
static int og_set_client_mode(struct og_dbi *dbi, const char *client_ip,
|
||||
const char *mac, const char *mode)
|
||||
{
|
||||
char params[4096];
|
||||
|
||||
|
@ -1651,7 +1659,10 @@ static int og_set_client_mode(struct og_dbi *dbi, const char *mac,
|
|||
return -1;
|
||||
}
|
||||
|
||||
og_get_client_mode_params(dbi, mac, params, sizeof(params));
|
||||
if (og_get_client_mode_params(dbi, mac, params, sizeof(params)) < 0) {
|
||||
syslog(LOG_ERR, "failed to get boot parameters (%s:%d)\n", __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (og_create_boot_file(OG_TFTP_BOOT_BIOS, mac, mode, params) < 0) {
|
||||
syslog(LOG_ERR, "failed to create BIOS boot file (%s:%d)\n", __FILE__, __LINE__);
|
||||
|
@ -1675,9 +1686,8 @@ static int og_set_client_mode(struct og_dbi *dbi, const char *mac,
|
|||
|
||||
static int og_cmd_post_modes(json_t *element, struct og_msg_params *params)
|
||||
{
|
||||
char ips_str[(OG_DB_IP_MAXLEN + 1) * OG_CLIENTS_MAX + 1] = {};
|
||||
const char *mode_str, *mac;
|
||||
int ips_str_len = 0;
|
||||
const char *msglog;
|
||||
struct og_dbi *dbi;
|
||||
uint64_t flags = 0;
|
||||
dbi_result result;
|
||||
|
@ -1704,12 +1714,6 @@ static int og_cmd_post_modes(json_t *element, struct og_msg_params *params)
|
|||
!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < params->ips_array_len; ++i) {
|
||||
ips_str_len += snprintf(ips_str + ips_str_len,
|
||||
sizeof(ips_str) - ips_str_len,
|
||||
"'%s',", params->ips_array[i]);
|
||||
}
|
||||
ips_str[ips_str_len - 1] = '\0';
|
||||
|
||||
dbi = og_dbi_open(&ogconfig.db);
|
||||
if (!dbi) {
|
||||
|
@ -1718,21 +1722,38 @@ static int og_cmd_post_modes(json_t *element, struct og_msg_params *params)
|
|||
return -1;
|
||||
}
|
||||
|
||||
result = dbi_conn_queryf(dbi->conn,
|
||||
"SELECT mac FROM ordenadores "
|
||||
"WHERE ip IN (%s)", ips_str);
|
||||
|
||||
while (dbi_result_next_row(result)) {
|
||||
mac = dbi_result_get_string(result, "mac");
|
||||
err = og_set_client_mode(dbi, mac, mode_str);
|
||||
if (err != 0) {
|
||||
for (i = 0; i < params->ips_array_len; i++) {
|
||||
result = dbi_conn_queryf(dbi->conn,
|
||||
"SELECT mac FROM ordenadores "
|
||||
"WHERE ip = '%s'", params->ips_array[i]);
|
||||
if (!result) {
|
||||
dbi_conn_error(dbi->conn, &msglog);
|
||||
syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
|
||||
__func__, __LINE__, msglog);
|
||||
og_dbi_close(dbi);
|
||||
return -1;
|
||||
}
|
||||
if (!dbi_result_next_row(result)) {
|
||||
syslog(LOG_ERR, "could not find client IP: %s (%s:%d)\n",
|
||||
params->ips_array[i], __func__, __LINE__);
|
||||
dbi_result_free(result);
|
||||
og_dbi_close(dbi);
|
||||
return -1;
|
||||
}
|
||||
mac = dbi_result_get_string(result, "mac");
|
||||
|
||||
err = og_set_client_mode(dbi, params->ips_array[i], mac, mode_str);
|
||||
if (err < 0) {
|
||||
syslog(LOG_ERR, "cannot set boot mode for client IP: %s (%s:%d)\n",
|
||||
params->ips_array[i], __func__, __LINE__);
|
||||
dbi_result_free(result);
|
||||
og_dbi_close(dbi);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dbi_result_free(result);
|
||||
}
|
||||
|
||||
dbi_result_free(result);
|
||||
og_dbi_close(dbi);
|
||||
|
||||
return 0;
|
||||
|
@ -2435,7 +2456,7 @@ static int og_cmd_post_client_update(json_t *element,
|
|||
|
||||
dbi_result_free(result);
|
||||
|
||||
if (og_set_client_mode(dbi, computer.mac, computer.boot)) {
|
||||
if (og_set_client_mode(dbi, computer.ip, computer.mac, computer.boot)) {
|
||||
syslog(LOG_ERR, "failed to set client boot mode (%s:%d)\n",
|
||||
__func__, __LINE__);
|
||||
og_dbi_close(dbi);
|
||||
|
@ -3029,7 +3050,7 @@ static int og_cmd_post_client_add(json_t *element,
|
|||
|
||||
dbi_result_free(result);
|
||||
|
||||
if (og_set_client_mode(dbi, computer.mac, computer.boot)) {
|
||||
if (og_set_client_mode(dbi, computer.ip, computer.mac, computer.boot)) {
|
||||
syslog(LOG_ERR, "failed to set client boot mode (%s:%d)\n",
|
||||
__func__, __LINE__);
|
||||
og_dbi_close(dbi);
|
||||
|
@ -3497,53 +3518,62 @@ static int og_cmd_get_software(json_t *element, struct og_msg_params *params,
|
|||
|
||||
static const int og_cmd_get_repositories(char *buffer_reply)
|
||||
{
|
||||
json_t *root, *repositories, *repository, *id, *ip, *name;
|
||||
json_t *root, *repository, *repositories, *ips;
|
||||
struct og_buffer og_buffer = {
|
||||
.data = buffer_reply,
|
||||
};
|
||||
struct og_dbi *dbi;
|
||||
dbi_result result;
|
||||
LIST_HEAD(repo_list);
|
||||
struct og_repo *repo;
|
||||
uint32_t i;
|
||||
|
||||
dbi = og_dbi_open(&ogconfig.db);
|
||||
if (!dbi) {
|
||||
syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
|
||||
__func__, __LINE__);
|
||||
if (og_repo_list(&repo_list) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = dbi_conn_queryf(dbi->conn,
|
||||
"SELECT idrepositorio, ip, nombrerepositorio "
|
||||
"FROM repositorios");
|
||||
|
||||
repositories = json_array();
|
||||
|
||||
while (dbi_result_next_row(result)) {
|
||||
repository = json_object();
|
||||
id = json_integer(dbi_result_get_ulonglong(result,
|
||||
"idrepositorio"));
|
||||
ip = json_string(dbi_result_get_string(result, "ip"));
|
||||
name = json_string(dbi_result_get_string(result,
|
||||
"nombrerepositorio"));
|
||||
json_object_set_new(repository, "id", id);
|
||||
json_object_set_new(repository, "ip", ip);
|
||||
json_object_set_new(repository, "name", name);
|
||||
json_array_append_new(repositories, repository);
|
||||
}
|
||||
|
||||
dbi_result_free(result);
|
||||
og_dbi_close(dbi);
|
||||
|
||||
root = json_object();
|
||||
json_object_set_new(root, "repositories", repositories);
|
||||
if (!root)
|
||||
return -1;
|
||||
|
||||
if (json_dump_callback(root, og_json_dump_clients, &og_buffer, JSON_ENSURE_ASCII)) {
|
||||
repositories = json_array();
|
||||
if (!repositories) {
|
||||
json_decref(root);
|
||||
return -1;
|
||||
}
|
||||
|
||||
json_object_set_new(root, "repositories", repositories);
|
||||
|
||||
list_for_each_entry(repo, &repo_list, list) {
|
||||
repository = json_object();
|
||||
if (!repository)
|
||||
goto err_out;
|
||||
|
||||
ips = json_array();
|
||||
if (!ips) {
|
||||
json_decref(repository);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
for (i = 0; i < repo->num_ips; i++)
|
||||
json_array_append_new(ips, json_string(inet_ntoa(repo->addr[i])));
|
||||
|
||||
json_object_set_new(repository, "id", json_integer(repo->id));
|
||||
json_object_set_new(repository, "addr", ips);
|
||||
json_object_set_new(repository, "name", json_string(repo->name));
|
||||
json_array_append_new(repositories, repository);
|
||||
}
|
||||
|
||||
if (json_dump_callback(root, og_json_dump_clients, &og_buffer, JSON_ENSURE_ASCII))
|
||||
goto err_out;
|
||||
|
||||
og_repo_free_list(&repo_list);
|
||||
json_decref(root);
|
||||
|
||||
return 0;
|
||||
|
||||
err_out:
|
||||
og_repo_free_list(&repo_list);
|
||||
json_decref(root);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define OG_IMAGE_TYPE_MAXLEN 4
|
||||
|
@ -3830,7 +3860,8 @@ static int og_cmd_add_image(json_t *element, struct og_msg_params *params,
|
|||
clients = json_copy(element);
|
||||
json_object_del(clients, "clients");
|
||||
|
||||
err = og_dbi_get_repository_ip(dbi, params->image.repo_id, repository_ip);
|
||||
err = og_dbi_get_repository_ip(dbi, params->image.repo_id,
|
||||
params->ips_array[0], repository_ip);
|
||||
og_dbi_close(dbi);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
@ -7104,34 +7135,30 @@ static int og_cmd_post_repository_update(json_t *element,
|
|||
struct og_msg_params *params,
|
||||
char *buffer_reply)
|
||||
{
|
||||
struct og_repository repo = {};
|
||||
char name[OG_DB_REPO_NAME_MAXLEN];
|
||||
const char *key, *msglog;
|
||||
unsigned int repo_id;
|
||||
struct og_dbi *dbi;
|
||||
dbi_result result;
|
||||
int err = 0, i;
|
||||
json_t *value;
|
||||
int err = 0;
|
||||
|
||||
json_object_foreach(element, key, value) {
|
||||
if (!strcmp(key, "id")) {
|
||||
err = og_json_parse_uint(value, &repo_id);
|
||||
params->flags |= OG_REST_PARAM_ID;
|
||||
} else if (!strcmp(key, "name")) {
|
||||
err = og_json_parse_string_copy(value, name,
|
||||
sizeof(name));
|
||||
} else if (!strcmp(key, "addr")) {
|
||||
err = og_json_parse_clients(value, params);
|
||||
}
|
||||
if (!strcmp(key, "name")) {
|
||||
err = og_json_parse_string_copy(value,
|
||||
repo.name,
|
||||
sizeof(repo.name));
|
||||
} else if (!strcmp(key, "ip")) {
|
||||
err = og_json_parse_string_copy(value,
|
||||
repo.ip,
|
||||
sizeof(repo.ip));
|
||||
} else if (!strcmp(key, "center")) {
|
||||
err = og_json_parse_uint(value, &repo.center);
|
||||
}
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
if (!og_msg_params_validate(params, OG_REST_PARAM_ID))
|
||||
if (!og_msg_params_validate(params, OG_REST_PARAM_ID |
|
||||
OG_REST_PARAM_ADDR))
|
||||
return -1;
|
||||
|
||||
dbi = og_dbi_open(&ogconfig.db);
|
||||
|
@ -7142,12 +7169,8 @@ static int og_cmd_post_repository_update(json_t *element,
|
|||
}
|
||||
|
||||
result = dbi_conn_queryf(dbi->conn,
|
||||
"UPDATE repositorios"
|
||||
" SET nombrerepositorio='%s',"
|
||||
" ip='%s',"
|
||||
" idcentro=%u"
|
||||
" WHERE idrepositorio=%u;",
|
||||
repo.name, repo.ip, repo.center, repo_id);
|
||||
"DELETE FROM repositorios WHERE alias=%u;",
|
||||
repo_id);
|
||||
if (!result) {
|
||||
dbi_conn_error(dbi->conn, &msglog);
|
||||
syslog(LOG_ERR, "failed to update repository in database (%s:%d) %s\n",
|
||||
|
@ -7155,75 +7178,83 @@ static int og_cmd_post_repository_update(json_t *element,
|
|||
og_dbi_close(dbi);
|
||||
return -1;
|
||||
}
|
||||
if (!dbi_result_get_numrows_affected(result)) {
|
||||
syslog(LOG_ERR, "repository with id %u does not exist (%s:%d)\n",
|
||||
repo_id, __func__, __LINE__);
|
||||
dbi_result_free(result);
|
||||
dbi_result_free(result);
|
||||
|
||||
result = dbi_conn_queryf(dbi->conn,
|
||||
"UPDATE repositorios "
|
||||
"SET ip='%s' WHERE idrepositorio=%u;",
|
||||
params->ips_array[0], repo_id);
|
||||
if (!result) {
|
||||
dbi_conn_error(dbi->conn, &msglog);
|
||||
syslog(LOG_ERR,
|
||||
"failed to add repository to database (%s:%d) %s\n",
|
||||
__func__, __LINE__, msglog);
|
||||
og_dbi_close(dbi);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dbi_result_free(result);
|
||||
|
||||
for (i = 1; i < params->ips_array_len; i++) {
|
||||
result = dbi_conn_queryf(dbi->conn,
|
||||
"INSERT INTO repositorios("
|
||||
"nombrerepositorio, ip, idcentro, grupoid, alias) VALUES "
|
||||
"('%s', '%s', 1, 0, %u);",
|
||||
name, params->ips_array[i], repo_id);
|
||||
if (!result) {
|
||||
dbi_conn_error(dbi->conn, &msglog);
|
||||
syslog(LOG_ERR,
|
||||
"failed to add repository to database (%s:%d) %s\n",
|
||||
__func__, __LINE__, msglog);
|
||||
og_dbi_close(dbi);
|
||||
return -1;
|
||||
}
|
||||
dbi_result_free(result);
|
||||
}
|
||||
|
||||
og_dbi_close(dbi);
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int og_cmd_post_repository_add(json_t *element,
|
||||
struct og_msg_params *params,
|
||||
char *buffer_reply)
|
||||
{
|
||||
struct og_repository repo = {
|
||||
.center = 1, /* never used, set it to 1. */
|
||||
};
|
||||
char name[OG_DB_REPO_NAME_MAXLEN];
|
||||
const char *key, *msglog;
|
||||
struct in_addr addr;
|
||||
struct og_dbi *dbi;
|
||||
dbi_result result;
|
||||
int err = 0, i;
|
||||
json_t *value;
|
||||
int err = 0;
|
||||
uint32_t id;
|
||||
|
||||
json_object_foreach(element, key, value) {
|
||||
if (!strcmp(key, "name")) {
|
||||
err = og_json_parse_string_copy(value,
|
||||
repo.name,
|
||||
sizeof(repo.name));
|
||||
params->flags |= OG_REST_PARAM_NAME;
|
||||
} else if (!strcmp(key, "ip")) {
|
||||
err = og_json_parse_string_copy(value,
|
||||
repo.ip,
|
||||
sizeof(repo.ip));
|
||||
params->flags |= OG_REST_PARAM_ADDR;
|
||||
} else if (!strcmp(key, "center")) {
|
||||
err = og_json_parse_uint(value, &repo.center);
|
||||
err = og_json_parse_string_copy(value, name,
|
||||
sizeof(name));
|
||||
} else if (!strcmp(key, "addr")) {
|
||||
err = og_json_parse_clients(value, params);
|
||||
}
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!og_msg_params_validate(params, OG_REST_PARAM_NAME |
|
||||
OG_REST_PARAM_ADDR))
|
||||
if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
|
||||
return -1;
|
||||
|
||||
if (inet_pton(AF_INET, repo.ip, &addr) <= 0) {
|
||||
syslog(LOG_ERR, "invalid server ip address (%s:%d)\n",
|
||||
__func__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dbi = og_dbi_open(&ogconfig.db);
|
||||
if (!dbi) {
|
||||
syslog(LOG_ERR, "cannot open conection database (%s:%d)\n",
|
||||
syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
|
||||
__func__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = dbi_conn_queryf(dbi->conn,
|
||||
"INSERT INTO repositorios("
|
||||
"nombrerepositorio, ip, idcentro, grupoid) VALUES "
|
||||
"('%s', '%s', %u, 0)",
|
||||
repo.name, repo.ip, repo.center);
|
||||
|
||||
"nombrerepositorio, ip, idcentro, grupoid, alias) VALUES "
|
||||
"('%s', '%s', 1, 0, NULL);",
|
||||
name, params->ips_array[0]);
|
||||
if (!result) {
|
||||
dbi_conn_error(dbi->conn, &msglog);
|
||||
syslog(LOG_ERR,
|
||||
|
@ -7234,9 +7265,29 @@ static int og_cmd_post_repository_add(json_t *element,
|
|||
}
|
||||
|
||||
dbi_result_free(result);
|
||||
|
||||
id = dbi_conn_sequence_last(dbi->conn, NULL);
|
||||
|
||||
for (i = 1; i < params->ips_array_len; i++) {
|
||||
result = dbi_conn_queryf(dbi->conn,
|
||||
"INSERT INTO repositorios("
|
||||
"nombrerepositorio, ip, idcentro, grupoid, alias) VALUES "
|
||||
"('%s', '%s', 1, 0, %u);",
|
||||
name, params->ips_array[i], id);
|
||||
if (!result) {
|
||||
dbi_conn_error(dbi->conn, &msglog);
|
||||
syslog(LOG_ERR,
|
||||
"failed to add repository to database (%s:%d) %s\n",
|
||||
__func__, __LINE__, msglog);
|
||||
og_dbi_close(dbi);
|
||||
return -1;
|
||||
}
|
||||
dbi_result_free(result);
|
||||
}
|
||||
|
||||
og_dbi_close(dbi);
|
||||
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int og_cmd_post_repository_delete(json_t *element,
|
||||
|
@ -7270,7 +7321,7 @@ static int og_cmd_post_repository_delete(json_t *element,
|
|||
|
||||
result = dbi_conn_queryf(dbi->conn,
|
||||
"DELETE FROM repositorios "
|
||||
"WHERE idrepositorio=%u",
|
||||
"WHERE idrepositorio=%u OR alias=%u",
|
||||
repo_id, repo_id);
|
||||
|
||||
if (!result) {
|
||||
|
@ -8060,10 +8111,9 @@ static int og_dbi_update_oglive(struct og_dbi *dbi, const char *mac,
|
|||
|
||||
static int og_cmd_oglive_set(json_t *element, struct og_msg_params *params)
|
||||
{
|
||||
char ips_str[(OG_DB_IP_MAXLEN + 1) * OG_CLIENTS_MAX + 1] = {};
|
||||
const char legacy_default_oglive_str[] = "ogLive";
|
||||
const char *oglive_str, *mac, *mode_str;
|
||||
int ips_str_len = 0;
|
||||
const char *msglog;
|
||||
struct og_dbi *dbi;
|
||||
uint64_t flags = 0;
|
||||
dbi_result result;
|
||||
|
@ -8093,13 +8143,6 @@ static int og_cmd_oglive_set(json_t *element, struct og_msg_params *params)
|
|||
if (!strcmp(oglive_str, "default"))
|
||||
oglive_str = legacy_default_oglive_str;
|
||||
|
||||
for (i = 0; i < params->ips_array_len; ++i) {
|
||||
ips_str_len += snprintf(ips_str + ips_str_len,
|
||||
sizeof(ips_str) - ips_str_len,
|
||||
"'%s',", params->ips_array[i]);
|
||||
}
|
||||
ips_str[ips_str_len - 1] = '\0';
|
||||
|
||||
dbi = og_dbi_open(&ogconfig.db);
|
||||
if (!dbi) {
|
||||
syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
|
||||
|
@ -8107,30 +8150,46 @@ static int og_cmd_oglive_set(json_t *element, struct og_msg_params *params)
|
|||
return -1;
|
||||
}
|
||||
|
||||
result = dbi_conn_queryf(dbi->conn,
|
||||
"SELECT mac, arranque FROM ordenadores "
|
||||
"WHERE ip IN (%s)", ips_str);
|
||||
|
||||
while (dbi_result_next_row(result)) {
|
||||
mac = dbi_result_get_string(result, "mac");
|
||||
for (i = 0; i < params->ips_array_len; i++) {
|
||||
result = dbi_conn_queryf(dbi->conn,
|
||||
"SELECT mac, arranque FROM ordenadores "
|
||||
"WHERE ip = '%s'", params->ips_array[i]);
|
||||
if (!result) {
|
||||
dbi_conn_error(dbi->conn, &msglog);
|
||||
syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
|
||||
__func__, __LINE__, msglog);
|
||||
og_dbi_close(dbi);
|
||||
return -1;
|
||||
}
|
||||
if (!dbi_result_next_row(result)) {
|
||||
syslog(LOG_ERR, "could not find client IP: %s (%s:%d)\n",
|
||||
params->ips_array[i], __func__, __LINE__);
|
||||
dbi_result_free(result);
|
||||
og_dbi_close(dbi);
|
||||
return -1;
|
||||
}
|
||||
mode_str = dbi_result_get_string(result, "arranque");
|
||||
mac = dbi_result_get_string(result, "mac");
|
||||
|
||||
err = og_dbi_update_oglive(dbi, mac, oglive_str);
|
||||
if (err != 0) {
|
||||
if (err < 0) {
|
||||
syslog(LOG_ERR, "failed to change db oglive (%s:%d)\n",
|
||||
__func__, __LINE__);
|
||||
dbi_result_free(result);
|
||||
og_dbi_close(dbi);
|
||||
return -1;
|
||||
}
|
||||
err = og_set_client_mode(dbi, mac, mode_str);
|
||||
if (err != 0) {
|
||||
|
||||
err = og_set_client_mode(dbi, params->ips_array[i], mac, mode_str);
|
||||
if (err < 0) {
|
||||
dbi_result_free(result);
|
||||
og_dbi_close(dbi);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dbi_result_free(result);
|
||||
}
|
||||
|
||||
dbi_result_free(result);
|
||||
og_dbi_close(dbi);
|
||||
|
||||
return 0;
|
||||
|
|
30
src/schema.c
30
src/schema.c
|
@ -369,6 +369,35 @@ static int og_dbi_schema_v8(struct og_dbi *dbi)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int og_dbi_schema_v9(struct og_dbi *dbi)
|
||||
{
|
||||
const char *msglog;
|
||||
dbi_result result;
|
||||
|
||||
syslog(LOG_DEBUG, "Adding alias to repositorios\n");
|
||||
result = dbi_conn_query(dbi->conn,
|
||||
"ALTER TABLE `repositorios` "
|
||||
"ADD `alias` int(11) NULL;");
|
||||
if (!result) {
|
||||
dbi_conn_error(dbi->conn, &msglog);
|
||||
syslog(LOG_INFO, "Error when adding alias (%s:%d) %s\n",
|
||||
__func__, __LINE__, msglog);
|
||||
return -1;
|
||||
}
|
||||
dbi_result_free(result);
|
||||
|
||||
result = dbi_conn_query(dbi->conn, "UPDATE version SET version = 9");
|
||||
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 {
|
||||
int version;
|
||||
int (*update)(struct og_dbi *dbi);
|
||||
|
@ -381,6 +410,7 @@ static struct og_schema_version {
|
|||
{ .version = 6, .update = og_dbi_schema_v6 },
|
||||
{ .version = 7, .update = og_dbi_schema_v7, },
|
||||
{ .version = 8, .update = og_dbi_schema_v8, },
|
||||
{ .version = 9, .update = og_dbi_schema_v9, },
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue