-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
336 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,3 +30,5 @@ package.json | |
coverage.out | ||
|
||
.idea | ||
network.json | ||
networks_db.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"log/slog" | ||
"os" | ||
"os/signal" | ||
"path/filepath" | ||
"syscall" | ||
|
||
"github.com/vechain/networkhub/environments/local" | ||
"github.com/vechain/networkhub/hub" | ||
"github.com/vechain/networkhub/preset" | ||
|
||
"github.com/spf13/cobra" | ||
|
||
cmdentrypoint "github.com/vechain/networkhub/entrypoint/cmd" | ||
) | ||
|
||
func setup() *cmdentrypoint.Cmd { | ||
envManager := hub.NewNetworkHub() | ||
envManager.RegisterEnvironment("local", local.NewLocalEnv) | ||
|
||
presets := preset.NewPresetNetworks() | ||
presets.Register("threeMasterNodesNetwork", preset.LocalThreeMasterNodesNetwork) | ||
presets.Register("sixNodesNetwork", preset.LocalSixNodesNetwork) | ||
|
||
execDir, err := os.Getwd() // TODO might want to make this configurable in the future ? | ||
if err != nil { | ||
panic(fmt.Errorf("unable to use current directory: %w", err)) | ||
} | ||
|
||
cmdEntrypoint := cmdentrypoint.New(envManager, presets, filepath.Join(execDir, "networks_db.json")) | ||
if err = cmdEntrypoint.LoadExistingNetworks(); err != nil { | ||
panic(fmt.Errorf("unable to load existing networks: %w", err)) | ||
} | ||
|
||
return cmdEntrypoint | ||
} | ||
|
||
var cmdCmd = &cobra.Command{ | ||
Use: "cmd", | ||
Short: "Directly uses NetworkHub", | ||
} | ||
|
||
var startCmd = &cobra.Command{ | ||
Use: "start [network-id]", | ||
Short: "Start a specific network", | ||
Args: cobra.MinimumNArgs(1), | ||
Run: func(cmd *cobra.Command, args []string) { | ||
cmdManager := setup() | ||
networkID := args[0] | ||
slog.Info("Starting network...", "ID", networkID) | ||
|
||
// Channel to listen for interrupt signals | ||
sigChan := make(chan os.Signal, 1) | ||
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM) | ||
|
||
go func() { | ||
err := cmdManager.Start(networkID) | ||
if err != nil { | ||
slog.Error("unable to start network", "err", err) | ||
return | ||
} | ||
slog.Info("network started successfully...") | ||
}() | ||
|
||
// Wait for interrupt signal | ||
<-sigChan | ||
slog.Info("Interrupt signal received. Stopping the network...") | ||
|
||
err := cmdManager.Stop(networkID) | ||
if err != nil { | ||
slog.Error("unable to stop network", "err", err) | ||
} else { | ||
slog.Info("network stopped successfully.") | ||
} | ||
}, | ||
} | ||
|
||
var configureCmd = &cobra.Command{ | ||
Use: "config [network-json-config]", | ||
Short: "Configures a specific network", | ||
Args: cobra.MinimumNArgs(1), | ||
Run: func(cmd *cobra.Command, args []string) { | ||
cmdManager := setup() | ||
|
||
// Read from the specified file | ||
data, err := ioutil.ReadFile(args[0]) | ||
if err != nil { | ||
fmt.Printf("Error reading config file: %v\n", err) | ||
os.Exit(1) | ||
} | ||
|
||
slog.Info("Configuring network...") | ||
|
||
networkID, err := cmdManager.Config(string(data)) | ||
if err != nil { | ||
slog.Error("unable to config network", "err", err) | ||
return | ||
} | ||
slog.Info("network config was successful...", "networkId", networkID) | ||
}, | ||
} | ||
|
||
var presetCmd = &cobra.Command{ | ||
Use: "preset [preset-name] [preset-thor-path]", | ||
Short: "Configures a preset network", | ||
Args: cobra.MinimumNArgs(2), | ||
Run: func(cmd *cobra.Command, args []string) { | ||
cmdManager := setup() | ||
|
||
presetNetwork := args[0] | ||
presetArtifactPath := args[1] | ||
|
||
slog.Info("Configuring network...") | ||
|
||
networkID, err := cmdManager.Preset(presetNetwork, presetArtifactPath) | ||
if err != nil { | ||
slog.Error("unable to config preset network", "err", err) | ||
return | ||
} | ||
slog.Info("preset network config was successful...", "networkId", networkID) | ||
}, | ||
} | ||
|
||
func init() { | ||
|
||
cmdCmd.AddCommand(startCmd, configureCmd, presetCmd) | ||
rootCmd.AddCommand(cmdCmd) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package cmd | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"github.com/vechain/networkhub/hub" | ||
"github.com/vechain/networkhub/network" | ||
"github.com/vechain/networkhub/preset" | ||
) | ||
|
||
type Cmd struct { | ||
networkHub *hub.NetworkHub | ||
presets *preset.Networks | ||
storage *Storage | ||
} | ||
|
||
func (c *Cmd) Stop(id string) error { | ||
return c.networkHub.StopNetwork(id) | ||
} | ||
|
||
func (c *Cmd) Start(id string) error { | ||
return c.networkHub.StartNetwork(id) | ||
} | ||
|
||
func (c *Cmd) Config(config string) (string, error) { | ||
var netCfg network.Network | ||
|
||
if err := json.Unmarshal([]byte(config), &netCfg); err != nil { | ||
return "", err | ||
} | ||
return c.config(&netCfg) | ||
} | ||
|
||
func (c *Cmd) LoadExistingNetworks() error { | ||
nets, err := c.storage.LoadExistingNetworks() | ||
if err != nil { | ||
return fmt.Errorf("unable to load existing networks: %w", err) | ||
} | ||
|
||
for networkID, net := range nets { | ||
loadedID, err := c.networkHub.LoadNetworkConfig(net) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if networkID != loadedID { | ||
return fmt.Errorf("unexpected networkID loaded: storedID:%s configuredID:%s", networkID, loadedID) | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (c *Cmd) Preset(presetNetwork string, presetConfig string) (string, error) { | ||
netCfg, err := c.presets.Load(presetNetwork, &preset.APIConfigPayload{ArtifactPath: presetConfig}) | ||
if err != nil { | ||
return "", fmt.Errorf("unable to load network preset: %w", err) | ||
} | ||
return c.config(netCfg) | ||
} | ||
|
||
func New(networkHub *hub.NetworkHub, presets *preset.Networks, storagePath string) *Cmd { | ||
return &Cmd{ | ||
networkHub: networkHub, | ||
presets: presets, | ||
storage: NewStorage(storagePath), | ||
} | ||
} | ||
|
||
func (c *Cmd) config(netCfg *network.Network) (string, error) { | ||
networkID, err := c.networkHub.LoadNetworkConfig(netCfg) | ||
if err != nil { | ||
return "", fmt.Errorf("unable to load config: %w", err) | ||
} | ||
|
||
networkInst, err := c.networkHub.GetNetwork(networkID) | ||
if err != nil { | ||
return "", fmt.Errorf("unable to retrieve network: %w", err) | ||
} | ||
|
||
err = c.storage.Store(networkID, networkInst) | ||
if err != nil { | ||
return "", fmt.Errorf("unable to store network: %w", err) | ||
} | ||
|
||
return networkID, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package cmd | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"github.com/vechain/networkhub/network" | ||
"io/ioutil" | ||
"log/slog" | ||
"os" | ||
) | ||
|
||
type StorageJson struct { | ||
Network map[string]*network.Network `json:"network"` | ||
} | ||
|
||
type Storage struct { | ||
path string | ||
} | ||
|
||
func (s *Storage) Store(networkID string, net *network.Network) error { | ||
storageJson, err := s.LoadExistingNetworks() | ||
if err != nil { | ||
return fmt.Errorf("unable to load existing networks: %w", err) | ||
} | ||
|
||
// Add/Update the network entry | ||
storageJson[networkID] = net | ||
|
||
// Marshal the updated data | ||
data, err := json.MarshalIndent(storageJson, "", " ") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Write the updated data back to file | ||
err = ioutil.WriteFile(s.path, data, 0644) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
slog.Info("Network saved to file", "filepath", s.path) | ||
return nil | ||
} | ||
|
||
func (s *Storage) LoadExistingNetworks() (map[string]*network.Network, error) { | ||
// Initialize an empty StorageJson | ||
storageJson := make(map[string]*network.Network) | ||
|
||
// Check if file exists | ||
if _, err := os.Stat(s.path); err == nil { | ||
// File exists, load the current data | ||
fileData, err := ioutil.ReadFile(s.path) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
err = json.Unmarshal(fileData, &storageJson) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
return storageJson, nil | ||
} | ||
|
||
func NewStorage(path string) *Storage { | ||
return &Storage{ | ||
path: path, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.