Re-work somethings in codebase

* Move code to seperate _main procedure to allow better use of core:mem
* functionality whilst testing and developing.
* Use builtin ini parser
* Fix memory leaks
* Currently some code is commented out whilst working way through
  current memory leaks
master
Ronald 1 year ago
parent 5a977d1dcd
commit aadf045f41

@ -1,12 +1,14 @@
package main package main
import "core:encoding/ini"
import "core:encoding/json"
import "core:fmt" import "core:fmt"
import "core:log" import "core:log"
import "core:mem"
import "core:os" import "core:os"
import "core:strings"
import "core:strconv" import "core:strconv"
import "core:strings"
import "libs/ini"
import "libs/http" import "libs/http"
import "libs/http/client" import "libs/http/client"
import "libs/sysinfo" import "libs/sysinfo"
@ -15,37 +17,62 @@ CONFIG_FILE_PATH :: "./config.ini"
PC: Program_Config = {} PC: Program_Config = {}
get_config :: proc(config_file_path: string) -> Maybe(ini.INI) { // get_config :: proc(config_file_path: string) -> Maybe(ini.INI) {
bytes, ok := os.read_entire_file_from_filename(config_file_path) // bytes, ok := os.read_entire_file_from_filename(config_file_path)
if !ok { // if !ok {
return nil // return nil
} // }
defer delete(bytes) // defer delete(bytes)
config, res := ini.parse(bytes) // config, res := ini.parse(bytes)
if res.err == ini.ParseErr.EOF { // if res.err == ini.ParseErr.EOF {
return config // return config
} // }
return nil // return nil
} // }
// Returns the host ID, of if the host doesn't exist in api_request_get :: proc(endpoint: string) -> (body: client.Body_Type, allocation: bool, ok: bool) {
// LSM then it will return -1
get_host_id :: proc(hostname: string) -> (int, bool) {
request: client.Request request: client.Request
client.request_init(&request, .Get) client.request_init(&request, .Get)
defer client.request_destroy(&request) defer client.request_destroy(&request)
response, err := client.request(&request, fmt.tprintf("%s/get_host_id_for_hostname/%s", PC.api_address, hostname)) response, err := client.request(&request, endpoint)
if err != nil { if err != nil {
return 0, false return nil, false, false
} }
defer client.response_destroy(&response) defer client.response_destroy(&response)
body, allocation, body_err := client.response_body(&response) body_err: client.Body_Error
body, allocation, body_err = client.response_body(&response)
if body_err != nil { if body_err != nil {
return 0, false return nil, false, false
}
return body, allocation, true
}
// api_request_post :: proc(endpoint: string, post_body: any) -> (body: client.Body_Type, allocation: bool, ok: bool) {
// request: client.Request
// client.requset_init(&request, .Post)
// defer client.request_destroy(&request)
// if err := client.with_json(&request, post_body); err != nil do return nil, false, false
// response, err := client.request(&request, endpoint)
// if err != nil do return nil, false, false
// defer client.response_destroy(&response)
// }
// Returns the host ID, or if the host doesn't exist in
// LSM then it will return -1
get_host_id :: proc(hostname: string) -> (int, bool) {
endpoint := fmt.tprintf("%s/get_host_id_for_hostname/%s", PC.api_address, hostname)
body, allocation, ok := api_request_get(endpoint)
if !ok {
return 0, ok
} }
defer client.body_destroy(body, allocation) defer client.body_destroy(body, allocation)
@ -54,13 +81,88 @@ get_host_id :: proc(hostname: string) -> (int, bool) {
return host_id, true return host_id, true
} }
main :: proc() { get_cpus_for_host_from_id :: proc(host_id: int) -> (cpus: [dynamic]CPU, ok: bool) {
endpoint := fmt.tprintf("%s/get_cpus_by_host_id/%d", PC.api_address, host_id)
body, allocation, request_ok := api_request_get(endpoint)
if !request_ok {
return nil, false
}
defer client.body_destroy(body, allocation)
if body.(client.Body_Plain) == "[]" {
return cpus, true
}
body_data := transmute([]u8)body.(client.Body_Plain)
json_data, err := json.parse(body_data)
if err != .None {
return nil, false
}
defer json.destroy_value(json_data)
root := json_data.(json.Array)
for cpu, i in root {
resize(&cpus, len(cpus)+1)
cpu_object := cpu.(json.Object)
cpus[i].id = int(cpu_object["id"].(json.Float))
cpus[i].socket = int(cpu_object["socket"].(json.Float))
cpus[i].name = strings.clone(cpu_object["name"].(json.String))
}
return cpus, true
}
destroy_cpus :: proc(cpus: [dynamic]CPU) {
for cpu in cpus {
delete(cpu.name)
}
delete(cpus)
}
add_cpu_to_lsm :: proc(cpu_name: string, socket: int, host_id: int) -> bool {
request: client.Request
client.request_init(&request, .Post)
defer client.request_destroy(&request)
post_body := Base_CPU{cpu_name, socket, host_id}
if err := client.with_json(&request, post_body); err != nil {
return false
}
response, err := client.request(&request, fmt.tprintf("%s/add_cpu/", PC.api_address))
if err != nil do log.fatal("Failed to add host to API with the error: %s", err)
defer client.response_destroy(&response)
if response.status != .Created {
return false
}
return true
}
_main :: proc() {
context.logger = log.create_console_logger(.Info) context.logger = log.create_console_logger(.Info)
defer log.destroy_console_logger(context.logger)
ini_config, ok := get_config(CONFIG_FILE_PATH).? data, ok := os.read_entire_file_from_filename("config.ini")
if !ok { if !ok {
log.fatal("Failed to read config file, please ensure it's in the correct format") fmt.eprintln("Failed to open config file")
return
} }
defer delete(data)
data_str := strings.to_lower(transmute(string)data, allocator=context.temp_allocator)
ini_config, err := ini.load_map_from_string(data_str, allocator=context.allocator)
if err != nil {
log.fatal("Failed to read config file")
return
}
defer ini.delete_map(ini_config)
fmt.println("ini_config[\"api\"][\"address\"]:", ini_config["api"]["address"])
if _, ok := ini_config["log"]; ok { if _, ok := ini_config["log"]; ok {
if level, ok := ini_config["log"]["level"]; ok && level in Log_Level_Map { if level, ok := ini_config["log"]["level"]; ok && level in Log_Level_Map {
@ -77,21 +179,28 @@ main :: proc() {
context.logger.lowest_level = PC.log_level context.logger.lowest_level = PC.log_level
if _, ok := ini_config["api"]; ok { if _, ok := ini_config["api"]; ok {
if api_address, ok := ini_config["api"]["address"]; ok do PC.api_address = strings.clone(api_address) if api_address, ok := ini_config["api"]["address"]; ok {
else do log.fatal("API address not specified in config file") PC.api_address = api_address
} else {
log.fatal("API address not specified in config file")
return
}
} }
log.debug("Program config:", PC) log.debug("Program config:", PC)
hostname, hostname_ok := sysinfo.get_hostname().? PC.hostname, ok = sysinfo.get_hostname().?
if !hostname_ok { if !ok {
log.fatal("Failed to get hostname")
return return
} }
defer delete(PC.hostname)
log.info("Successfully got hostname") log.info("Successfully got hostname")
PC.host_id, ok = get_host_id(hostname) PC.host_id, ok = get_host_id(PC.hostname)
if !ok { if !ok {
log.fatal("Failed to contact API and determine if host already exists in LSM") log.fatal("Failed to contact API and determine if host already exists in LSM")
return
} }
if PC.host_id < 0 { if PC.host_id < 0 {
@ -102,9 +211,10 @@ main :: proc() {
client.request_init(&request, .Post) client.request_init(&request, .Post)
defer client.request_destroy(&request) defer client.request_destroy(&request)
post_body := Base_Host{hostname} post_body := Base_Host{PC.hostname}
if err := client.with_json(&request, post_body); err != nil { if err := client.with_json(&request, post_body); err != nil {
log.fatal("JSON error: %s", err) log.fatal("JSON error:", err)
// TODO: Handle this
} }
response, err := client.request(&request, fmt.tprintf("%s/add_host/", PC.api_address)) response, err := client.request(&request, fmt.tprintf("%s/add_host/", PC.api_address))
@ -113,7 +223,7 @@ main :: proc() {
if response.status == .Created { if response.status == .Created {
log.info("Successfully added host to LSM") log.info("Successfully added host to LSM")
PC.host_id, ok = get_host_id(hostname) PC.host_id, ok = get_host_id(PC.hostname)
if !ok do log.fatal("Failed to get host ID, exiting") if !ok do log.fatal("Failed to get host ID, exiting")
} }
} else { } else {
@ -121,4 +231,36 @@ main :: proc() {
} }
log.debug("Host ID", PC.host_id) log.debug("Host ID", PC.host_id)
// cpus, cpu_ok := get_cpus_for_host_from_id(PC.host_id)
// if len(cpus) == 0 {
// delete(cpus)
// log.info("Need to add CPUs to LSM")
// cpu_name, socket, ok := sysinfo.get_cpu_name_and_socket_number()
// log.info("Attempting to add CPU", cpu_name, "to LSM")
// if ok := add_cpu_to_lsm(cpu_name, socket, PC.host_id); !ok {
// log.fatal("Failed to add CPU, exiting")
// os.exit(1)
// }
// log.info("Successfully added CPU to LSM")
// cpus, cpu_ok := get_cpus_for_host_from_id(PC.host_id)
// }
// defer delete(cpus)
// log.debug("cpus for host: ", cpus)
}
main :: proc() {
track: mem.Tracking_Allocator
mem.tracking_allocator_init(&track, context.allocator)
context.allocator = mem.tracking_allocator(&track)
_main()
for _, leak in track.allocation_map {
fmt.println(leak.location, "leaked", leak.size, "bytes")
}
for bad_free in track.bad_free_array {
fmt.println(bad_free.location, "allocation", bad_free.memory, "was freed badly")
}
} }

@ -16,9 +16,11 @@ Program_Config :: struct {
api_address: string, api_address: string,
host_id: int, host_id: int,
hostname: string,
} }
CPU :: struct { CPU :: struct {
id: int,
name: string, name: string,
socket: int, socket: int,
usage: f16, usage: f16,
@ -43,3 +45,8 @@ Base_Host :: struct {
hostname: string hostname: string
} }
Base_CPU :: struct {
name: string,
socket: int,
host_id: int
}

Loading…
Cancel
Save