Compare commits
6 commits
7078691db6
...
87808312f4
| Author | SHA1 | Date | |
|---|---|---|---|
|
87808312f4 |
|||
|
862406f041 |
|||
|
f5707c343c |
|||
|
915581904c |
|||
|
4bef0f9d5f |
|||
|
e545b70d53 |
14 changed files with 119 additions and 217 deletions
|
|
@ -33,9 +33,7 @@ jobs:
|
||||||
goos: [linux]
|
goos: [linux]
|
||||||
goarch: [amd64]
|
goarch: [amd64]
|
||||||
binaries:
|
binaries:
|
||||||
- db
|
|
||||||
- metadata
|
- metadata
|
||||||
- metacli
|
|
||||||
- agent
|
- agent
|
||||||
uses: ./.forgejo/workflows/build.yml
|
uses: ./.forgejo/workflows/build.yml
|
||||||
with:
|
with:
|
||||||
|
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
configuration "git.g3e.fr/syonad/two/internal/config/agent"
|
|
||||||
"git.g3e.fr/syonad/two/internal/metadata"
|
|
||||||
"git.g3e.fr/syonad/two/pkg/db/kv"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
conf_file := flag.String("conf", "/etc/two/agent.yml", "configuration file")
|
|
||||||
vm_name := flag.String("vm_name", "", "Nom de la vm")
|
|
||||||
vpc := flag.String("vpc_name", "", "vpc name")
|
|
||||||
bind_ip := flag.String("ip", "", "bind ip")
|
|
||||||
bind_port := flag.String("port", "", "bind port")
|
|
||||||
ssh_key := flag.String("key", "", "Clef ssh")
|
|
||||||
password := flag.String("pass", "", "password user")
|
|
||||||
start := flag.Bool("start", false, "start metadata server")
|
|
||||||
stop := flag.Bool("stop", false, "stop metadata server")
|
|
||||||
dryrun := flag.Bool("dryrun", false, "launch in dry node")
|
|
||||||
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
conf, err := configuration.LoadConfig(*conf_file)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
db := kv.InitDB(kv.Config{
|
|
||||||
Path: conf.Database.Path,
|
|
||||||
}, false)
|
|
||||||
defer db.Close()
|
|
||||||
|
|
||||||
if *start {
|
|
||||||
if err := metadata.StartMetadata(metadata.NoCloudConfig{
|
|
||||||
VpcName: *vpc,
|
|
||||||
Name: *vm_name,
|
|
||||||
BindIP: *bind_ip,
|
|
||||||
BindPort: *bind_port,
|
|
||||||
Password: *password,
|
|
||||||
SSHKEY: *ssh_key,
|
|
||||||
}, db, *dryrun); err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
} else if *stop {
|
|
||||||
if err := metadata.StopMetadata(*vm_name, db, *dryrun); err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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")
|
|
||||||
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")
|
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,
|
|
||||||
Iface: *iface,
|
|
||||||
Port: *port,
|
|
||||||
ConfFile: *conf_file,
|
|
||||||
VmName: *vm_name,
|
VmName: *vm_name,
|
||||||
|
RunDir: cfg.Metadata.RunDir,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,10 @@ interfaces:
|
||||||
internet: br-000000
|
internet: br-000000
|
||||||
admin: br-000000
|
admin: br-000000
|
||||||
|
|
||||||
|
# Metadata server runtime directory (cloud-init files per VM)
|
||||||
|
metadata:
|
||||||
|
run_dir: "/run/two/metadata"
|
||||||
|
|
||||||
# Logging configuration
|
# Logging configuration
|
||||||
logger:
|
logger:
|
||||||
# Log level: debug, info, warn, error (default: info)
|
# Log level: debug, info, warn, error (default: info)
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,9 @@ type Config struct {
|
||||||
Level string `mapstructure:"level"`
|
Level string `mapstructure:"level"`
|
||||||
Debug bool `mapstructure:"debug"`
|
Debug bool `mapstructure:"debug"`
|
||||||
} `mapstructure:"logger"`
|
} `mapstructure:"logger"`
|
||||||
|
Metadata struct {
|
||||||
|
RunDir string `mapstructure:"run_dir"`
|
||||||
|
} `mapstructure:"metadata"`
|
||||||
DefaultInterface string `mapstructure:"default_interface"`
|
DefaultInterface string `mapstructure:"default_interface"`
|
||||||
Interfaces map[string]string `mapstructure:"interfaces"`
|
Interfaces map[string]string `mapstructure:"interfaces"`
|
||||||
}
|
}
|
||||||
|
|
@ -46,6 +49,7 @@ func LoadConfig(path string) (*Config, error) {
|
||||||
v.SetDefault("worker.buffer_size", 100)
|
v.SetDefault("worker.buffer_size", 100)
|
||||||
v.SetDefault("dispatcher.timeout_seconds", 300)
|
v.SetDefault("dispatcher.timeout_seconds", 300)
|
||||||
v.SetDefault("dispatcher.poll_seconds", 2)
|
v.SetDefault("dispatcher.poll_seconds", 2)
|
||||||
|
v.SetDefault("metadata.run_dir", "/run/two/metadata")
|
||||||
v.SetDefault("default_interface", "br-000000")
|
v.SetDefault("default_interface", "br-000000")
|
||||||
v.SetDefault("logger.level", "info")
|
v.SetDefault("logger.level", "info")
|
||||||
v.SetDefault("logger.debug", false)
|
v.SetDefault("logger.debug", false)
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ func (c StartVMCommand) Execute(db *badger.DB, cfg *configuration.Config) error
|
||||||
case <-time.After(time.Duration(cfg.Dispatcher.PollSeconds) * time.Second):
|
case <-time.After(time.Duration(cfg.Dispatcher.PollSeconds) * time.Second):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return vm.StartVM(db, c.Name)
|
return vm.StartVM(db, c.Name, cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
type StopVMCommand struct {
|
type StopVMCommand struct {
|
||||||
|
|
|
||||||
|
|
@ -3,18 +3,18 @@ package metadata
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
configuration "git.g3e.fr/syonad/two/internal/config/agent"
|
||||||
"git.g3e.fr/syonad/two/pkg/systemd"
|
"git.g3e.fr/syonad/two/pkg/systemd"
|
||||||
"github.com/dgraph-io/badger/v4"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func StartMetadata(config NoCloudConfig, db *badger.DB, dryrun bool) error {
|
func StartMetadata(config NoCloudConfig, cfg *configuration.Config, dryrun bool) error {
|
||||||
service, err := systemd.New()
|
service, err := systemd.New()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to connect to systemd: %w", err)
|
return fmt.Errorf("failed to connect to systemd: %w", err)
|
||||||
}
|
}
|
||||||
defer service.Close()
|
defer service.Close()
|
||||||
|
|
||||||
LoadNcCloudInDB(config, db)
|
LoadNcCloudInDB(config, cfg.Metadata.RunDir)
|
||||||
if !dryrun {
|
if !dryrun {
|
||||||
if err := service.Start("metadata@" + config.Name + ".service"); err != nil {
|
if err := service.Start("metadata@" + config.Name + ".service"); err != nil {
|
||||||
return fmt.Errorf("failed to start metadata@%s: %w", config.Name, err)
|
return fmt.Errorf("failed to start metadata@%s: %w", config.Name, err)
|
||||||
|
|
@ -23,17 +23,17 @@ func StartMetadata(config NoCloudConfig, db *badger.DB, dryrun bool) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func StopMetadata(vm_name string, db *badger.DB, dryrun bool) error {
|
func StopMetadata(vmName string, cfg *configuration.Config, dryrun bool) error {
|
||||||
service, err := systemd.New()
|
service, err := systemd.New()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to connect to systemd: %w", err)
|
return fmt.Errorf("failed to connect to systemd: %w", err)
|
||||||
}
|
}
|
||||||
defer service.Close()
|
defer service.Close()
|
||||||
|
|
||||||
UnLoadNoCloudInDB(vm_name, db)
|
UnLoadNoCloudInDB(vmName, cfg.Metadata.RunDir)
|
||||||
if !dryrun {
|
if !dryrun {
|
||||||
if err := service.Stop("metadata@" + vm_name + ".service"); err != nil {
|
if err := service.Stop("metadata@" + vmName + ".service"); err != nil {
|
||||||
return fmt.Errorf("failed to stop metadata@%s: %w", vm_name, err)
|
return fmt.Errorf("failed to stop metadata@%s: %w", vmName, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
||||||
cfg := newCfg()
|
|
||||||
LoadNcCloudInDB(cfg, 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 {
|
|
||||||
val, err := kv.GetFromDB(db, key)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("clé %q absente après LoadNcCloudInDB : %v", key, err)
|
t.Errorf("fichier %q absent après LoadNcCloudInDB : %v", name, err)
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
if val == "" && key != "metadata/vm1/user-data" {
|
return string(b)
|
||||||
t.Errorf("clé %q vide après LoadNcCloudInDB", key)
|
}
|
||||||
|
|
||||||
|
func TestLoadNcCloudInDB_StoresAllFiles(t *testing.T) {
|
||||||
|
dir := useTestDir(t)
|
||||||
|
LoadNcCloudInDB(newCfg(), dir)
|
||||||
|
|
||||||
|
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{
|
func TestUnLoadNoCloudInDB_DoesNotAffectOtherVMs(t *testing.T) {
|
||||||
"metadata/vm1/meta-data",
|
dir := useTestDir(t)
|
||||||
"metadata/vm1/user-data",
|
|
||||||
"metadata/vm1/network-config",
|
cfg1 := newCfg()
|
||||||
"metadata/vm1/vendor-data",
|
cfg2 := newCfg()
|
||||||
"metadata/vm1/vpc",
|
cfg2.Name = "vm2"
|
||||||
"metadata/vm1/bind_ip",
|
LoadNcCloudInDB(cfg1, dir)
|
||||||
"metadata/vm1/bind_port",
|
LoadNcCloudInDB(cfg2, dir)
|
||||||
}
|
|
||||||
for _, key := range keys {
|
UnLoadNoCloudInDB("vm1", dir)
|
||||||
_, err := kv.GetFromDB(db, key)
|
|
||||||
if err == nil {
|
if _, err := os.Stat(filepath.Join(dir, "vm2", "vpc")); err != nil {
|
||||||
t.Errorf("clé %q devrait être supprimée après UnLoadNoCloudInDB", key)
|
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,9 @@ package metadata
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"embed"
|
"embed"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"git.g3e.fr/syonad/two/pkg/db/kv"
|
|
||||||
"github.com/dgraph-io/badger/v4"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed templates/*.tmpl
|
//go:embed templates/*.tmpl
|
||||||
|
|
@ -26,21 +25,25 @@ func RenderConfig(path string, cfg NoCloudConfig) (string, error) {
|
||||||
return buf.String(), nil
|
return buf.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadNcCloudInDB(config NoCloudConfig, db *badger.DB) {
|
func LoadNcCloudInDB(config NoCloudConfig, runDir string) {
|
||||||
meta_data, _ := RenderConfig("templates/meta-data.tmpl", config)
|
meta_data, _ := RenderConfig("templates/meta-data.tmpl", config)
|
||||||
user_data, _ := RenderConfig("templates/user-data.tmpl", config)
|
user_data, _ := RenderConfig("templates/user-data.tmpl", config)
|
||||||
network_config, _ := RenderConfig("templates/network-config.tmpl", config)
|
network_config, _ := RenderConfig("templates/network-config.tmpl", config)
|
||||||
vendor_data, _ := RenderConfig("templates/vendor-data.tmpl", config)
|
vendor_data, _ := RenderConfig("templates/vendor-data.tmpl", config)
|
||||||
|
|
||||||
kv.AddInDB(db, "metadata/"+config.Name+"/meta-data", meta_data)
|
dir := filepath.Join(runDir, config.Name)
|
||||||
kv.AddInDB(db, "metadata/"+config.Name+"/user-data", user_data)
|
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||||
kv.AddInDB(db, "metadata/"+config.Name+"/network-config", network_config)
|
return
|
||||||
kv.AddInDB(db, "metadata/"+config.Name+"/vendor-data", vendor_data)
|
}
|
||||||
kv.AddInDB(db, "metadata/"+config.Name+"/vpc", config.VpcName)
|
os.WriteFile(filepath.Join(dir, "meta-data"), []byte(meta_data), 0644)
|
||||||
kv.AddInDB(db, "metadata/"+config.Name+"/bind_ip", config.BindIP)
|
os.WriteFile(filepath.Join(dir, "user-data"), []byte(user_data), 0644)
|
||||||
kv.AddInDB(db, "metadata/"+config.Name+"/bind_port", config.BindPort)
|
os.WriteFile(filepath.Join(dir, "network-config"), []byte(network_config), 0644)
|
||||||
|
os.WriteFile(filepath.Join(dir, "vendor-data"), []byte(vendor_data), 0644)
|
||||||
|
os.WriteFile(filepath.Join(dir, "vpc"), []byte(config.VpcName), 0644)
|
||||||
|
os.WriteFile(filepath.Join(dir, "bind_ip"), []byte(config.BindIP), 0644)
|
||||||
|
os.WriteFile(filepath.Join(dir, "bind_port"), []byte(config.BindPort), 0644)
|
||||||
}
|
}
|
||||||
|
|
||||||
func UnLoadNoCloudInDB(vm_name string, db *badger.DB) {
|
func UnLoadNoCloudInDB(vmName string, runDir string) {
|
||||||
kv.DeleteInDB(db, "metadata/"+vm_name)
|
os.RemoveAll(filepath.Join(runDir, vmName))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,8 @@ type NoCloudData struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServerConfig struct {
|
type ServerConfig struct {
|
||||||
Netns string
|
|
||||||
File string
|
|
||||||
Iface string
|
|
||||||
Port int
|
|
||||||
ConfFile string
|
|
||||||
VmName string
|
VmName string
|
||||||
|
RunDir string
|
||||||
}
|
}
|
||||||
|
|
||||||
type NoCloudConfig struct {
|
type NoCloudConfig struct {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package vm
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
configuration "git.g3e.fr/syonad/two/internal/config/agent"
|
||||||
"git.g3e.fr/syonad/two/internal/iptables"
|
"git.g3e.fr/syonad/two/internal/iptables"
|
||||||
"git.g3e.fr/syonad/two/internal/metadata"
|
"git.g3e.fr/syonad/two/internal/metadata"
|
||||||
"git.g3e.fr/syonad/two/internal/netif"
|
"git.g3e.fr/syonad/two/internal/netif"
|
||||||
|
|
@ -13,7 +14,7 @@ import (
|
||||||
"github.com/dgraph-io/badger/v4"
|
"github.com/dgraph-io/badger/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
func StartVM(db *badger.DB, name string) error {
|
func StartVM(db *badger.DB, name string, cfg *configuration.Config) error {
|
||||||
state, err := kv.GetFromDB(db, "vm/"+name+"/state")
|
state, err := kv.GetFromDB(db, "vm/"+name+"/state")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -44,7 +45,7 @@ func StartVM(db *badger.DB, name string) error {
|
||||||
BindPort: d.metadataPort,
|
BindPort: d.metadataPort,
|
||||||
Password: d.password,
|
Password: d.password,
|
||||||
SSHKEY: d.sshkey,
|
SSHKEY: d.sshkey,
|
||||||
}, db, false); err != nil {
|
}, cfg, false); err != nil {
|
||||||
return fmt.Errorf("start metadata: %w", err)
|
return fmt.Errorf("start metadata: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ func StopVM(db *badger.DB, name string, cfg *configuration.Config) error {
|
||||||
return fmt.Errorf("delete metadata redirect: %w", err)
|
return fmt.Errorf("delete metadata redirect: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := metadata.StopMetadata(name, db, false); err != nil {
|
if err := metadata.StopMetadata(name, cfg, false); err != nil {
|
||||||
return fmt.Errorf("stop metadata: %w", err)
|
return fmt.Errorf("stop metadata: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package kv
|
package kv
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
"github.com/dgraph-io/badger/v4"
|
"github.com/dgraph-io/badger/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -15,7 +17,7 @@ func InitDB(conf Config, readonly bool) *badger.DB {
|
||||||
opts.NumLevelZeroTablesStall = 2
|
opts.NumLevelZeroTablesStall = 2
|
||||||
db, err := badger.Open(opts)
|
db, err := badger.Open(opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
log.Fatalf("kv.InitDB (readonly=%v, path=%s): %v", readonly, conf.Path, err)
|
||||||
}
|
}
|
||||||
return db
|
return db
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue