From e545b70d5330ebdfd4e9737f8951017d796092b4 Mon Sep 17 00:00:00 2001 From: GnomeZworc Date: Wed, 29 Apr 2026 00:21:55 +0200 Subject: [PATCH 1/6] f-25: add propre log for init db Signed-off-by: GnomeZworc --- pkg/db/kv/init.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/db/kv/init.go b/pkg/db/kv/init.go index 677c656..0ee2374 100644 --- a/pkg/db/kv/init.go +++ b/pkg/db/kv/init.go @@ -1,6 +1,8 @@ package kv import ( + "log" + "github.com/dgraph-io/badger/v4" ) @@ -15,7 +17,7 @@ func InitDB(conf Config, readonly bool) *badger.DB { opts.NumLevelZeroTablesStall = 2 db, err := badger.Open(opts) if err != nil { - panic(err) + log.Fatalf("kv.InitDB (readonly=%v, path=%s): %v", readonly, conf.Path, err) } return db } From 4bef0f9d5f90c39f16114f01d601277564155f01 Mon Sep 17 00:00:00 2001 From: GnomeZworc Date: Wed, 29 Apr 2026 00:33:22 +0200 Subject: [PATCH 2/6] f-25: config: add metadata dir Signed-off-by: GnomeZworc --- conf/agent/config.exemple.yml | 4 ++++ internal/config/agent/struct.go | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/conf/agent/config.exemple.yml b/conf/agent/config.exemple.yml index fb8e604..89eb90f 100644 --- a/conf/agent/config.exemple.yml +++ b/conf/agent/config.exemple.yml @@ -35,6 +35,10 @@ interfaces: internet: br-000000 admin: br-000000 +# Metadata server runtime directory (cloud-init files per VM) +metadata: + run_dir: "/run/two/metadata" + # Logging configuration logger: # Log level: debug, info, warn, error (default: info) diff --git a/internal/config/agent/struct.go b/internal/config/agent/struct.go index d8e4ee5..69a4492 100644 --- a/internal/config/agent/struct.go +++ b/internal/config/agent/struct.go @@ -28,6 +28,9 @@ type Config struct { Level string `mapstructure:"level"` Debug bool `mapstructure:"debug"` } `mapstructure:"logger"` + Metadata struct { + RunDir string `mapstructure:"run_dir"` + } `mapstructure:"metadata"` DefaultInterface string `mapstructure:"default_interface"` Interfaces map[string]string `mapstructure:"interfaces"` } @@ -46,6 +49,7 @@ func LoadConfig(path string) (*Config, error) { v.SetDefault("worker.buffer_size", 100) v.SetDefault("dispatcher.timeout_seconds", 300) v.SetDefault("dispatcher.poll_seconds", 2) + v.SetDefault("metadata.run_dir", "/run/two/metadata") v.SetDefault("default_interface", "br-000000") v.SetDefault("logger.level", "info") v.SetDefault("logger.debug", false) From 915581904c9e38dc7bf7332bbcb8a54838b51481 Mon Sep 17 00:00:00 2001 From: GnomeZworc Date: Wed, 29 Apr 2026 00:36:01 +0200 Subject: [PATCH 3/6] f-25: code: add cfg to start vm Signed-off-by: GnomeZworc --- internal/dispatcher/agent/vm_commands.go | 2 +- internal/vm/create.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/dispatcher/agent/vm_commands.go b/internal/dispatcher/agent/vm_commands.go index c0245ca..aade998 100644 --- a/internal/dispatcher/agent/vm_commands.go +++ b/internal/dispatcher/agent/vm_commands.go @@ -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): } } - return vm.StartVM(db, c.Name) + return vm.StartVM(db, c.Name, cfg) } type StopVMCommand struct { diff --git a/internal/vm/create.go b/internal/vm/create.go index 4737e62..b24fa80 100644 --- a/internal/vm/create.go +++ b/internal/vm/create.go @@ -3,6 +3,7 @@ package vm import ( "fmt" + configuration "git.g3e.fr/syonad/two/internal/config/agent" "git.g3e.fr/syonad/two/internal/iptables" "git.g3e.fr/syonad/two/internal/metadata" "git.g3e.fr/syonad/two/internal/netif" @@ -13,7 +14,7 @@ import ( "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") if err != nil { return err From f5707c343c4251c3e162200675d4982205ae11c7 Mon Sep 17 00:00:00 2001 From: GnomeZworc Date: Wed, 29 Apr 2026 00:41:43 +0200 Subject: [PATCH 4/6] f-25: add load files Signed-off-by: GnomeZworc --- internal/metadata/handle.go | 14 +++++++------- internal/metadata/render.go | 29 ++++++++++++++++------------- internal/vm/create.go | 2 +- internal/vm/delete.go | 2 +- 4 files changed, 25 insertions(+), 22 deletions(-) diff --git a/internal/metadata/handle.go b/internal/metadata/handle.go index 9ec5486..d34dd20 100644 --- a/internal/metadata/handle.go +++ b/internal/metadata/handle.go @@ -3,18 +3,18 @@ package metadata import ( "fmt" + configuration "git.g3e.fr/syonad/two/internal/config/agent" "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() if err != nil { return fmt.Errorf("failed to connect to systemd: %w", err) } defer service.Close() - LoadNcCloudInDB(config, db) + LoadNcCloudInDB(config, cfg.Metadata.RunDir) if !dryrun { if err := service.Start("metadata@" + config.Name + ".service"); err != nil { 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 } -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() if err != nil { return fmt.Errorf("failed to connect to systemd: %w", err) } defer service.Close() - UnLoadNoCloudInDB(vm_name, db) + UnLoadNoCloudInDB(vmName, cfg.Metadata.RunDir) if !dryrun { - if err := service.Stop("metadata@" + vm_name + ".service"); err != nil { - return fmt.Errorf("failed to stop metadata@%s: %w", vm_name, err) + if err := service.Stop("metadata@" + vmName + ".service"); err != nil { + return fmt.Errorf("failed to stop metadata@%s: %w", vmName, err) } } return nil diff --git a/internal/metadata/render.go b/internal/metadata/render.go index f6c3cae..0d4fd59 100644 --- a/internal/metadata/render.go +++ b/internal/metadata/render.go @@ -3,10 +3,9 @@ package metadata import ( "bytes" "embed" + "os" + "path/filepath" "text/template" - - "git.g3e.fr/syonad/two/pkg/db/kv" - "github.com/dgraph-io/badger/v4" ) //go:embed templates/*.tmpl @@ -26,21 +25,25 @@ func RenderConfig(path string, cfg NoCloudConfig) (string, error) { 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) user_data, _ := RenderConfig("templates/user-data.tmpl", config) network_config, _ := RenderConfig("templates/network-config.tmpl", config) vendor_data, _ := RenderConfig("templates/vendor-data.tmpl", config) - kv.AddInDB(db, "metadata/"+config.Name+"/meta-data", meta_data) - kv.AddInDB(db, "metadata/"+config.Name+"/user-data", user_data) - kv.AddInDB(db, "metadata/"+config.Name+"/network-config", network_config) - kv.AddInDB(db, "metadata/"+config.Name+"/vendor-data", vendor_data) - kv.AddInDB(db, "metadata/"+config.Name+"/vpc", config.VpcName) - kv.AddInDB(db, "metadata/"+config.Name+"/bind_ip", config.BindIP) - kv.AddInDB(db, "metadata/"+config.Name+"/bind_port", config.BindPort) + dir := filepath.Join(runDir, config.Name) + if err := os.MkdirAll(dir, 0755); err != nil { + return + } + os.WriteFile(filepath.Join(dir, "meta-data"), []byte(meta_data), 0644) + os.WriteFile(filepath.Join(dir, "user-data"), []byte(user_data), 0644) + 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) { - kv.DeleteInDB(db, "metadata/"+vm_name) +func UnLoadNoCloudInDB(vmName string, runDir string) { + os.RemoveAll(filepath.Join(runDir, vmName)) } diff --git a/internal/vm/create.go b/internal/vm/create.go index b24fa80..53e2e96 100644 --- a/internal/vm/create.go +++ b/internal/vm/create.go @@ -45,7 +45,7 @@ func StartVM(db *badger.DB, name string, cfg *configuration.Config) error { BindPort: d.metadataPort, Password: d.password, SSHKEY: d.sshkey, - }, db, false); err != nil { + }, cfg, false); err != nil { return fmt.Errorf("start metadata: %w", err) } diff --git a/internal/vm/delete.go b/internal/vm/delete.go index faadb4b..5030339 100644 --- a/internal/vm/delete.go +++ b/internal/vm/delete.go @@ -57,7 +57,7 @@ func StopVM(db *badger.DB, name string, cfg *configuration.Config) error { 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) } From 862406f0419fd39b872b56e16d304e298e96408c Mon Sep 17 00:00:00 2001 From: GnomeZworc Date: Wed, 29 Apr 2026 00:48:55 +0200 Subject: [PATCH 5/6] f-25: use file for metadata Signed-off-by: GnomeZworc --- cmd/metadata/main.go | 23 ++--- internal/metadata/metadata_test.go | 129 +++++++++++------------------ internal/metadata/server.go | 57 ++++--------- internal/metadata/struct.go | 8 +- 4 files changed, 80 insertions(+), 137 deletions(-) diff --git a/cmd/metadata/main.go b/cmd/metadata/main.go index 96e3f75..82abaed 100644 --- a/cmd/metadata/main.go +++ b/cmd/metadata/main.go @@ -2,26 +2,29 @@ package main import ( "flag" + "fmt" + "os" + configuration "git.g3e.fr/syonad/two/internal/config/agent" "git.g3e.fr/syonad/two/internal/metadata" ) var ( - iface = flag.String("interface", "0.0.0.0", "Interface IP à écouter") - 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") + confFile = flag.String("conf", "/etc/two/agent.yml", "configuration file") + vm_name = flag.String("vm", "", "Name of the vm") ) func main() { 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{ - Netns: *netns_name, - Iface: *iface, - Port: *port, - ConfFile: *conf_file, - VmName: *vm_name, + VmName: *vm_name, + RunDir: cfg.Metadata.RunDir, }) } diff --git a/internal/metadata/metadata_test.go b/internal/metadata/metadata_test.go index 5884151..cc54530 100644 --- a/internal/metadata/metadata_test.go +++ b/internal/metadata/metadata_test.go @@ -3,10 +3,10 @@ package metadata import ( "net/http" "net/http/httptest" + "os" + "path/filepath" "strings" "testing" - - "git.g3e.fr/syonad/two/pkg/db/kv" ) 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() - db := kv.InitDB(kv.Config{Path: t.TempDir()}, false) - t.Cleanup(func() { db.Close() }) - return db + return t.TempDir() } // --- RenderConfig --- @@ -108,78 +106,67 @@ func TestRenderConfig_SpecialCharsInName(t *testing.T) { // --- LoadNcCloudInDB / UnLoadNoCloudInDB --- -func TestLoadNcCloudInDB_StoresAllKeys(t *testing.T) { - db := kv.InitDB(kv.Config{Path: t.TempDir()}, false) - t.Cleanup(func() { db.Close() }) - - 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", +func readTestFile(t *testing.T, dir, vmName, name string) string { + t.Helper() + b, err := os.ReadFile(filepath.Join(dir, vmName, name)) + if err != nil { + t.Errorf("fichier %q absent après LoadNcCloudInDB : %v", name, err) + return "" } - for _, key := range keys { - val, err := kv.GetFromDB(db, key) - if err != nil { - t.Errorf("clé %q absente après LoadNcCloudInDB : %v", key, err) - } - if val == "" && key != "metadata/vm1/user-data" { - t.Errorf("clé %q vide après LoadNcCloudInDB", key) + return string(b) +} + +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) { - db := kv.InitDB(kv.Config{Path: t.TempDir()}, false) - t.Cleanup(func() { db.Close() }) + dir := useTestDir(t) + LoadNcCloudInDB(newCfg(), dir) - cfg := newCfg() - LoadNcCloudInDB(cfg, db) - - vpc, _ := kv.GetFromDB(db, "metadata/vm1/vpc") - if vpc != "vpc-test" { + if vpc := readTestFile(t, dir, "vm1", "vpc"); vpc != "vpc-test" { t.Errorf("vpc attendu %q, obtenu %q", "vpc-test", vpc) } - - ip, _ := kv.GetFromDB(db, "metadata/vm1/bind_ip") - if ip != "169.254.169.254" { + if ip := readTestFile(t, dir, "vm1", "bind_ip"); ip != "169.254.169.254" { t.Errorf("bind_ip attendu %q, obtenu %q", "169.254.169.254", ip) } - - port, _ := kv.GetFromDB(db, "metadata/vm1/bind_port") - if port != "80" { + if port := readTestFile(t, dir, "vm1", "bind_port"); port != "80" { t.Errorf("bind_port attendu %q, obtenu %q", "80", port) } } -func TestUnLoadNoCloudInDB_RemovesAllKeys(t *testing.T) { - db := kv.InitDB(kv.Config{Path: t.TempDir()}, false) - t.Cleanup(func() { db.Close() }) +func TestUnLoadNoCloudInDB_RemovesAllFiles(t *testing.T) { + dir := useTestDir(t) + LoadNcCloudInDB(newCfg(), dir) + UnLoadNoCloudInDB("vm1", dir) - cfg := newCfg() - LoadNcCloudInDB(cfg, db) - 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", + if _, err := os.Stat(filepath.Join(dir, "vm1")); !os.IsNotExist(err) { + t.Error("répertoire vm1 devrait être supprimé après UnLoadNoCloudInDB") } - for _, key := range keys { - _, err := kv.GetFromDB(db, key) - if err == nil { - t.Errorf("clé %q devrait être supprimée après UnLoadNoCloudInDB", key) - } +} + +func TestUnLoadNoCloudInDB_DoesNotAffectOtherVMs(t *testing.T) { + 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) } } - -// --- 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) - } -} diff --git a/internal/metadata/server.go b/internal/metadata/server.go index 3b4e12f..b1f8943 100644 --- a/internal/metadata/server.go +++ b/internal/metadata/server.go @@ -5,12 +5,13 @@ import ( "log" "net" "net/http" + "os" + "path/filepath" "strconv" + "strings" "time" - configuration "git.g3e.fr/syonad/two/internal/config/agent" "git.g3e.fr/syonad/two/internal/netns" - "git.g3e.fr/syonad/two/pkg/db/kv" ) var data NoCloudData @@ -23,47 +24,23 @@ func getIP(r *http.Request) string { return ip } -func getFromDB(config ServerConfig) NoCloudData { - var netns_name string - var port int - var iface string +func readFile(dir, name string) string { + b, _ := os.ReadFile(filepath.Join(dir, name)) + return strings.TrimRight(string(b), "\n") +} - 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) - 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 - } + port, _ := strconv.Atoi(readFile(dir, "bind_port")) return NoCloudData{ - MetaData: metadata, - UserData: userdata, - NetworkConfig: networkconfig, - VendorData: vendordata, - NetNs: netns_name, - Iface: iface, + MetaData: readFile(dir, "meta-data"), + UserData: readFile(dir, "user-data"), + NetworkConfig: readFile(dir, "network-config"), + VendorData: readFile(dir, "vendor-data"), + NetNs: readFile(dir, "vpc"), + Iface: readFile(dir, "bind_ip"), Port: port, } } @@ -93,7 +70,7 @@ func rootHandler(w http.ResponseWriter, r *http.Request) { } func StartServer(config ServerConfig) { - data = getFromDB(config) + data = getFromFiles(config) if data.NetNs != "" { if err := netns.Enter(data.NetNs); err != nil { diff --git a/internal/metadata/struct.go b/internal/metadata/struct.go index 5810ff4..e706087 100644 --- a/internal/metadata/struct.go +++ b/internal/metadata/struct.go @@ -11,12 +11,8 @@ type NoCloudData struct { } type ServerConfig struct { - Netns string - File string - Iface string - Port int - ConfFile string - VmName string + VmName string + RunDir string } type NoCloudConfig struct { From 87808312f46dfd32a8d9b3bde0c56af55f817f19 Mon Sep 17 00:00:00 2001 From: GnomeZworc Date: Wed, 29 Apr 2026 00:50:04 +0200 Subject: [PATCH 6/6] f-25: bin: remove old binaries Signed-off-by: GnomeZworc --- .forgejo/workflows/prerelease.yml | 2 -- cmd/metacli/main.go | 53 ------------------------------- 2 files changed, 55 deletions(-) delete mode 100644 cmd/metacli/main.go diff --git a/.forgejo/workflows/prerelease.yml b/.forgejo/workflows/prerelease.yml index 2440fbd..1869374 100644 --- a/.forgejo/workflows/prerelease.yml +++ b/.forgejo/workflows/prerelease.yml @@ -33,9 +33,7 @@ jobs: goos: [linux] goarch: [amd64] binaries: - - db - metadata - - metacli - agent uses: ./.forgejo/workflows/build.yml with: diff --git a/cmd/metacli/main.go b/cmd/metacli/main.go deleted file mode 100644 index 140bde6..0000000 --- a/cmd/metacli/main.go +++ /dev/null @@ -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) - } - } -}