f-25: use file for metadata

Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
This commit is contained in:
GnomeZworc 2026-04-29 00:48:55 +02:00
commit 862406f041
Signed by: nicolas.boufideline
GPG key ID: 4406BBBF8845D632
4 changed files with 80 additions and 137 deletions

View file

@ -2,26 +2,29 @@ package main
import ( import (
"flag" "flag"
"fmt"
"os"
configuration "git.g3e.fr/syonad/two/internal/config/agent"
"git.g3e.fr/syonad/two/internal/metadata" "git.g3e.fr/syonad/two/internal/metadata"
) )
var ( var (
iface = flag.String("interface", "0.0.0.0", "Interface IP à écouter") confFile = flag.String("conf", "/etc/two/agent.yml", "configuration file")
port = flag.Int("port", 0, "Port à utiliser") vm_name = flag.String("vm", "", "Name of the vm")
netns_name = flag.String("netns", "", "Network namespace à utiliser")
conf_file = flag.String("conf", "/etc/two/agent.yml", "configuration file")
vm_name = flag.String("vm", "", "Name of the vm")
) )
func main() { func main() {
flag.Parse() flag.Parse()
cfg, err := configuration.LoadConfig(*confFile)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to load config: %v\n", err)
os.Exit(1)
}
metadata.StartServer(metadata.ServerConfig{ metadata.StartServer(metadata.ServerConfig{
Netns: *netns_name, VmName: *vm_name,
Iface: *iface, RunDir: cfg.Metadata.RunDir,
Port: *port,
ConfFile: *conf_file,
VmName: *vm_name,
}) })
} }

View file

@ -3,10 +3,10 @@ package metadata
import ( import (
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"os"
"path/filepath"
"strings" "strings"
"testing" "testing"
"git.g3e.fr/syonad/two/pkg/db/kv"
) )
func newCfg() NoCloudConfig { func newCfg() NoCloudConfig {
@ -20,11 +20,9 @@ func newCfg() NoCloudConfig {
} }
} }
func newTestDB(t *testing.T) interface{ Close() error } { func useTestDir(t *testing.T) string {
t.Helper() t.Helper()
db := kv.InitDB(kv.Config{Path: t.TempDir()}, false) return t.TempDir()
t.Cleanup(func() { db.Close() })
return db
} }
// --- RenderConfig --- // --- RenderConfig ---
@ -108,78 +106,67 @@ func TestRenderConfig_SpecialCharsInName(t *testing.T) {
// --- LoadNcCloudInDB / UnLoadNoCloudInDB --- // --- LoadNcCloudInDB / UnLoadNoCloudInDB ---
func TestLoadNcCloudInDB_StoresAllKeys(t *testing.T) { func readTestFile(t *testing.T, dir, vmName, name string) string {
db := kv.InitDB(kv.Config{Path: t.TempDir()}, false) t.Helper()
t.Cleanup(func() { db.Close() }) b, err := os.ReadFile(filepath.Join(dir, vmName, name))
if err != nil {
cfg := newCfg() t.Errorf("fichier %q absent après LoadNcCloudInDB : %v", name, err)
LoadNcCloudInDB(cfg, db) return ""
keys := []string{
"metadata/vm1/meta-data",
"metadata/vm1/user-data",
"metadata/vm1/network-config",
"metadata/vm1/vendor-data",
"metadata/vm1/vpc",
"metadata/vm1/bind_ip",
"metadata/vm1/bind_port",
} }
for _, key := range keys { return string(b)
val, err := kv.GetFromDB(db, key) }
if err != nil {
t.Errorf("clé %q absente après LoadNcCloudInDB : %v", key, err) func TestLoadNcCloudInDB_StoresAllFiles(t *testing.T) {
} dir := useTestDir(t)
if val == "" && key != "metadata/vm1/user-data" { LoadNcCloudInDB(newCfg(), dir)
t.Errorf("clé %q vide après LoadNcCloudInDB", key)
files := []string{"meta-data", "user-data", "network-config", "vendor-data", "vpc", "bind_ip", "bind_port"}
for _, f := range files {
path := filepath.Join(dir, "vm1", f)
if _, err := os.Stat(path); err != nil {
t.Errorf("fichier %q absent : %v", f, err)
} }
} }
} }
func TestLoadNcCloudInDB_VpcAndBindValues(t *testing.T) { func TestLoadNcCloudInDB_VpcAndBindValues(t *testing.T) {
db := kv.InitDB(kv.Config{Path: t.TempDir()}, false) dir := useTestDir(t)
t.Cleanup(func() { db.Close() }) LoadNcCloudInDB(newCfg(), dir)
cfg := newCfg() if vpc := readTestFile(t, dir, "vm1", "vpc"); vpc != "vpc-test" {
LoadNcCloudInDB(cfg, db)
vpc, _ := kv.GetFromDB(db, "metadata/vm1/vpc")
if vpc != "vpc-test" {
t.Errorf("vpc attendu %q, obtenu %q", "vpc-test", vpc) t.Errorf("vpc attendu %q, obtenu %q", "vpc-test", vpc)
} }
if ip := readTestFile(t, dir, "vm1", "bind_ip"); ip != "169.254.169.254" {
ip, _ := kv.GetFromDB(db, "metadata/vm1/bind_ip")
if ip != "169.254.169.254" {
t.Errorf("bind_ip attendu %q, obtenu %q", "169.254.169.254", ip) t.Errorf("bind_ip attendu %q, obtenu %q", "169.254.169.254", ip)
} }
if port := readTestFile(t, dir, "vm1", "bind_port"); port != "80" {
port, _ := kv.GetFromDB(db, "metadata/vm1/bind_port")
if port != "80" {
t.Errorf("bind_port attendu %q, obtenu %q", "80", port) t.Errorf("bind_port attendu %q, obtenu %q", "80", port)
} }
} }
func TestUnLoadNoCloudInDB_RemovesAllKeys(t *testing.T) { func TestUnLoadNoCloudInDB_RemovesAllFiles(t *testing.T) {
db := kv.InitDB(kv.Config{Path: t.TempDir()}, false) dir := useTestDir(t)
t.Cleanup(func() { db.Close() }) LoadNcCloudInDB(newCfg(), dir)
UnLoadNoCloudInDB("vm1", dir)
cfg := newCfg() if _, err := os.Stat(filepath.Join(dir, "vm1")); !os.IsNotExist(err) {
LoadNcCloudInDB(cfg, db) t.Error("répertoire vm1 devrait être supprimé après UnLoadNoCloudInDB")
UnLoadNoCloudInDB("vm1", db)
keys := []string{
"metadata/vm1/meta-data",
"metadata/vm1/user-data",
"metadata/vm1/network-config",
"metadata/vm1/vendor-data",
"metadata/vm1/vpc",
"metadata/vm1/bind_ip",
"metadata/vm1/bind_port",
} }
for _, key := range keys { }
_, err := kv.GetFromDB(db, key)
if err == nil { func TestUnLoadNoCloudInDB_DoesNotAffectOtherVMs(t *testing.T) {
t.Errorf("clé %q devrait être supprimée après UnLoadNoCloudInDB", key) dir := useTestDir(t)
}
cfg1 := newCfg()
cfg2 := newCfg()
cfg2.Name = "vm2"
LoadNcCloudInDB(cfg1, dir)
LoadNcCloudInDB(cfg2, dir)
UnLoadNoCloudInDB("vm1", dir)
if _, err := os.Stat(filepath.Join(dir, "vm2", "vpc")); err != nil {
t.Errorf("vm2 ne devrait pas être supprimée : %v", err)
} }
} }
@ -277,23 +264,3 @@ func TestRootHandler_ContentType(t *testing.T) {
t.Errorf("Content-Type attendu text/yaml, obtenu %q", ct) t.Errorf("Content-Type attendu text/yaml, obtenu %q", ct)
} }
} }
// --- UnLoadNoCloudInDB_DoesNotAffectOtherVMs ---
func TestUnLoadNoCloudInDB_DoesNotAffectOtherVMs(t *testing.T) {
db := kv.InitDB(kv.Config{Path: t.TempDir()}, false)
t.Cleanup(func() { db.Close() })
cfg1 := newCfg()
cfg2 := newCfg()
cfg2.Name = "vm2"
LoadNcCloudInDB(cfg1, db)
LoadNcCloudInDB(cfg2, db)
UnLoadNoCloudInDB("vm1", db)
_, err := kv.GetFromDB(db, "metadata/vm2/vpc")
if err != nil {
t.Errorf("vm2 ne devrait pas être supprimée : %v", err)
}
}

View file

@ -5,12 +5,13 @@ import (
"log" "log"
"net" "net"
"net/http" "net/http"
"os"
"path/filepath"
"strconv" "strconv"
"strings"
"time" "time"
configuration "git.g3e.fr/syonad/two/internal/config/agent"
"git.g3e.fr/syonad/two/internal/netns" "git.g3e.fr/syonad/two/internal/netns"
"git.g3e.fr/syonad/two/pkg/db/kv"
) )
var data NoCloudData var data NoCloudData
@ -23,47 +24,23 @@ func getIP(r *http.Request) string {
return ip return ip
} }
func getFromDB(config ServerConfig) NoCloudData { func readFile(dir, name string) string {
var netns_name string b, _ := os.ReadFile(filepath.Join(dir, name))
var port int return strings.TrimRight(string(b), "\n")
var iface string }
conf_db, _ := configuration.LoadConfig(config.ConfFile) func getFromFiles(config ServerConfig) NoCloudData {
dir := filepath.Join(config.RunDir, config.VmName)
db := kv.InitDB(kv.Config{Path: conf_db.Database.Path}, true) port, _ := strconv.Atoi(readFile(dir, "bind_port"))
defer db.Close()
metadata, _ := kv.GetFromDB(db, "metadata/"+config.VmName+"/meta-data")
userdata, _ := kv.GetFromDB(db, "metadata/"+config.VmName+"/user-data")
networkconfig, _ := kv.GetFromDB(db, "metadata/"+config.VmName+"/network-config")
vendordata, _ := kv.GetFromDB(db, "metadata/"+config.VmName+"/vendor-data")
if config.Netns == "" {
netns_name, _ = kv.GetFromDB(db, "metadata/"+config.VmName+"/vpc")
} else {
netns_name = config.Netns
}
if config.Iface == "" {
iface, _ = kv.GetFromDB(db, "metadata/"+config.VmName+"/bind_ip")
} else {
iface = config.Iface
}
if config.Port == 0 {
sport, _ := kv.GetFromDB(db, "metadata/"+config.VmName+"/bind_port")
port, _ = strconv.Atoi(sport)
} else {
port = config.Port
}
return NoCloudData{ return NoCloudData{
MetaData: metadata, MetaData: readFile(dir, "meta-data"),
UserData: userdata, UserData: readFile(dir, "user-data"),
NetworkConfig: networkconfig, NetworkConfig: readFile(dir, "network-config"),
VendorData: vendordata, VendorData: readFile(dir, "vendor-data"),
NetNs: netns_name, NetNs: readFile(dir, "vpc"),
Iface: iface, Iface: readFile(dir, "bind_ip"),
Port: port, Port: port,
} }
} }
@ -93,7 +70,7 @@ func rootHandler(w http.ResponseWriter, r *http.Request) {
} }
func StartServer(config ServerConfig) { func StartServer(config ServerConfig) {
data = getFromDB(config) data = getFromFiles(config)
if data.NetNs != "" { if data.NetNs != "" {
if err := netns.Enter(data.NetNs); err != nil { if err := netns.Enter(data.NetNs); err != nil {

View file

@ -11,12 +11,8 @@ type NoCloudData struct {
} }
type ServerConfig struct { type ServerConfig struct {
Netns string VmName string
File string RunDir string
Iface string
Port int
ConfFile string
VmName string
} }
type NoCloudConfig struct { type NoCloudConfig struct {