mirror of
https://git.numenor-labs.us/dsfx.git
synced 2025-04-29 08:10:34 +00:00
refactor(cmd/dsfx,internal/peer): use single file
This commit is contained in:
parent
aa13896cb1
commit
defca2fa74
@ -5,13 +5,13 @@ import (
|
|||||||
|
|
||||||
"koti.casa/numenor-labs/dsfx/internal/lib/disk"
|
"koti.casa/numenor-labs/dsfx/internal/lib/disk"
|
||||||
"koti.casa/numenor-labs/dsfx/internal/lib/system"
|
"koti.casa/numenor-labs/dsfx/internal/lib/system"
|
||||||
"koti.casa/numenor-labs/dsfx/internal/peer/node"
|
"koti.casa/numenor-labs/dsfx/internal/peer"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
n := node.New(disk.Default(), system.Default())
|
p := peer.New(disk.Default(), system.Default())
|
||||||
|
|
||||||
err := n.Run(context.Background())
|
err := p.Run(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -1,50 +0,0 @@
|
|||||||
package conf
|
|
||||||
|
|
||||||
import "koti.casa/numenor-labs/dsfx/internal/lib/system"
|
|
||||||
|
|
||||||
const (
|
|
||||||
// DefaultConfigDir is the default directory for the dsfx configuration.
|
|
||||||
DefaultConfigDir = "/etc/dsfx/config"
|
|
||||||
// DefaultStorageDir is the default directory for the dsfx storage.
|
|
||||||
DefaultStorageDir = "/etc/dsfx/data"
|
|
||||||
// DefaultHost is the default host for the dsfxctl application.
|
|
||||||
DefaultHost = "0.0.0.0"
|
|
||||||
// DefaultPort is the default port for the dsfxctl application.
|
|
||||||
DefaultPort = "8000"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Conf holds the configuration for the dsfxctl application.
|
|
||||||
type Conf struct {
|
|
||||||
// Directories
|
|
||||||
ConfigDir string
|
|
||||||
StorageDir string
|
|
||||||
// Networking
|
|
||||||
Host string
|
|
||||||
Port string
|
|
||||||
}
|
|
||||||
|
|
||||||
func FromSystem(sys system.System) Conf {
|
|
||||||
var c Conf
|
|
||||||
|
|
||||||
c.ConfigDir = sys.GetEnv("DSFX_CONFIG_DIR")
|
|
||||||
if c.ConfigDir == "" {
|
|
||||||
c.ConfigDir = DefaultConfigDir
|
|
||||||
}
|
|
||||||
|
|
||||||
c.StorageDir = sys.GetEnv("DSFX_STORAGE_DIR")
|
|
||||||
if c.StorageDir == "" {
|
|
||||||
c.StorageDir = DefaultStorageDir
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Host = sys.GetEnv("DSFX_HOST")
|
|
||||||
if c.Host == "" {
|
|
||||||
c.Host = DefaultHost
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Port = sys.GetEnv("DSFX_PORT")
|
|
||||||
if c.Port == "" {
|
|
||||||
c.Port = DefaultPort
|
|
||||||
}
|
|
||||||
|
|
||||||
return c
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
package node
|
package peer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@ -16,56 +16,101 @@ import (
|
|||||||
"koti.casa/numenor-labs/dsfx/internal/lib/network"
|
"koti.casa/numenor-labs/dsfx/internal/lib/network"
|
||||||
"koti.casa/numenor-labs/dsfx/internal/lib/storage/scoped"
|
"koti.casa/numenor-labs/dsfx/internal/lib/storage/scoped"
|
||||||
"koti.casa/numenor-labs/dsfx/internal/lib/system"
|
"koti.casa/numenor-labs/dsfx/internal/lib/system"
|
||||||
|
|
||||||
"koti.casa/numenor-labs/dsfx/internal/peer/conf"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Node struct {
|
const (
|
||||||
|
// DefaultConfigDir is the default directory for the dsfx configuration.
|
||||||
|
DefaultConfigDir = "/etc/dsfx/config"
|
||||||
|
// DefaultStorageDir is the default directory for the dsfx storage.
|
||||||
|
DefaultStorageDir = "/etc/dsfx/data"
|
||||||
|
// DefaultHost is the default host for the dsfxctl application.
|
||||||
|
DefaultHost = "0.0.0.0"
|
||||||
|
// DefaultPort is the default port for the dsfxctl application.
|
||||||
|
DefaultPort = "8000"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Conf holds the configuration for the dsfxctl application.
|
||||||
|
type Conf struct {
|
||||||
|
// Directories
|
||||||
|
ConfigDir string
|
||||||
|
StorageDir string
|
||||||
|
// Networking
|
||||||
|
Host string
|
||||||
|
Port string
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadConfigFromSystem(sys system.System) Conf {
|
||||||
|
var c Conf
|
||||||
|
|
||||||
|
c.ConfigDir = sys.GetEnv("DSFX_CONFIG_DIR")
|
||||||
|
if c.ConfigDir == "" {
|
||||||
|
c.ConfigDir = DefaultConfigDir
|
||||||
|
}
|
||||||
|
|
||||||
|
c.StorageDir = sys.GetEnv("DSFX_STORAGE_DIR")
|
||||||
|
if c.StorageDir == "" {
|
||||||
|
c.StorageDir = DefaultStorageDir
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Host = sys.GetEnv("DSFX_HOST")
|
||||||
|
if c.Host == "" {
|
||||||
|
c.Host = DefaultHost
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Port = sys.GetEnv("DSFX_PORT")
|
||||||
|
if c.Port == "" {
|
||||||
|
c.Port = DefaultPort
|
||||||
|
}
|
||||||
|
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
type Peer struct {
|
||||||
disk disk.Disk
|
disk disk.Disk
|
||||||
system system.System
|
system system.System
|
||||||
config scoped.StorageScope
|
config scoped.StorageScope
|
||||||
storage scoped.StorageScope
|
storage scoped.StorageScope
|
||||||
conf conf.Conf
|
conf Conf
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(disk disk.Disk, system system.System) *Node {
|
func New(disk disk.Disk, system system.System) *Peer {
|
||||||
conf := conf.FromSystem(system)
|
conf := loadConfigFromSystem(system)
|
||||||
|
|
||||||
config := scoped.New(disk, conf.ConfigDir)
|
config := scoped.New(disk, conf.ConfigDir)
|
||||||
storage := scoped.New(disk, conf.StorageDir)
|
storage := scoped.New(disk, conf.StorageDir)
|
||||||
|
|
||||||
return &Node{disk, system, config, storage, conf}
|
return &Peer{disk, system, config, storage, conf}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Node) Run(ctx context.Context) error {
|
func (p *Peer) Run(ctx context.Context) error {
|
||||||
opts := &slog.HandlerOptions{
|
opts := &slog.HandlerOptions{
|
||||||
AddSource: false,
|
AddSource: false,
|
||||||
Level: slog.LevelDebug,
|
Level: slog.LevelDebug,
|
||||||
}
|
}
|
||||||
logger := slog.New(slog.NewTextHandler(a.system.Stdout(), opts))
|
logger := slog.New(slog.NewTextHandler(p.system.Stdout(), opts))
|
||||||
|
|
||||||
slog.SetDefault(logger)
|
slog.SetDefault(logger)
|
||||||
ctx = logging.WithContext(ctx, logger)
|
ctx = logging.WithContext(ctx, logger)
|
||||||
|
|
||||||
err := a.disk.MkdirAll(a.conf.ConfigDir, 0755)
|
err := p.disk.MkdirAll(p.conf.ConfigDir, 0755)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.ErrorContext(ctx, "failed to create config dir", slog.Any("error", err))
|
logger.ErrorContext(ctx, "failed to create config dir", slog.Any("error", err))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = a.disk.MkdirAll(a.conf.StorageDir, 0755)
|
err = p.disk.MkdirAll(p.conf.StorageDir, 0755)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.ErrorContext(ctx, "failed to create storage dir", slog.Any("error", err))
|
logger.ErrorContext(ctx, "failed to create storage dir", slog.Any("error", err))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
id, err := a.loadIdentity()
|
id, err := p.loadIdentity()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.ErrorContext(ctx, "failed to read key file", slog.Any("error", err))
|
logger.ErrorContext(ctx, "failed to read key file", slog.Any("error", err))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
admins, err := a.loadAdmins()
|
admins, err := p.loadAdmins()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.ErrorContext(ctx, "failed to read admins file", slog.Any("error", err))
|
logger.ErrorContext(ctx, "failed to read admins file", slog.Any("error", err))
|
||||||
return err
|
return err
|
||||||
@ -75,7 +120,7 @@ func (a *Node) Run(ctx context.Context) error {
|
|||||||
logger.WarnContext(ctx, "no admins found", slog.String("admins", "none"))
|
logger.WarnContext(ctx, "no admins found", slog.String("admins", "none"))
|
||||||
}
|
}
|
||||||
|
|
||||||
tcpAddrRaw := net.JoinHostPort(a.conf.Host, a.conf.Port)
|
tcpAddrRaw := net.JoinHostPort(p.conf.Host, p.conf.Port)
|
||||||
tcpAddr, err := net.ResolveTCPAddr("tcp", tcpAddrRaw)
|
tcpAddr, err := net.ResolveTCPAddr("tcp", tcpAddrRaw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -100,29 +145,29 @@ func (a *Node) Run(ctx context.Context) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
go handleConnection(ctx, conn)
|
go p.handleConnection(ctx, conn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadAdmins ...
|
// loadAdmins ...
|
||||||
func (c *Node) loadAdmins() ([]string, error) {
|
func (p *Peer) loadAdmins() ([]string, error) {
|
||||||
hasKeyFile, err := c.hasAdminsFile()
|
hasKeyFile, err := p.hasAdminsFile()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to check for admins file: %w", err)
|
return nil, fmt.Errorf("failed to check for admins file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !hasKeyFile {
|
if !hasKeyFile {
|
||||||
if err := c.createAdminsFile(); err != nil {
|
if err := p.createAdminsFile(); err != nil {
|
||||||
return nil, fmt.Errorf("failed to create admins file: %w", err)
|
return nil, fmt.Errorf("failed to create admins file: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.readAdminsFile()
|
return p.readAdminsFile()
|
||||||
}
|
}
|
||||||
|
|
||||||
// hasAdminsFile ...
|
// hasAdminsFile ...
|
||||||
func (c *Node) hasAdminsFile() (bool, error) {
|
func (p *Peer) hasAdminsFile() (bool, error) {
|
||||||
f, err := c.config.Open("admins")
|
f, err := p.config.Open("admins")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return false, nil
|
return false, nil
|
||||||
@ -135,8 +180,8 @@ func (c *Node) hasAdminsFile() (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// createAdminsFile ...
|
// createAdminsFile ...
|
||||||
func (c *Node) createAdminsFile() error {
|
func (p *Peer) createAdminsFile() error {
|
||||||
f, err := c.config.Create("admins")
|
f, err := p.config.Create("admins")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -146,8 +191,8 @@ func (c *Node) createAdminsFile() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// readAdminsFile ...
|
// readAdminsFile ...
|
||||||
func (c *Node) readAdminsFile() ([]string, error) {
|
func (p *Peer) readAdminsFile() ([]string, error) {
|
||||||
f, err := c.config.Open("admins")
|
f, err := p.config.Open("admins")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -173,26 +218,26 @@ func (c *Node) readAdminsFile() ([]string, error) {
|
|||||||
|
|
||||||
// loadIdentity loads the private key from the key file. If the key file does not
|
// loadIdentity loads the private key from the key file. If the key file does not
|
||||||
// exist, it creates a new key file with a generated private key and returns it.
|
// exist, it creates a new key file with a generated private key and returns it.
|
||||||
func (c *Node) loadIdentity() (ed25519.PrivateKey, error) {
|
func (p *Peer) loadIdentity() (ed25519.PrivateKey, error) {
|
||||||
hasKeyFile, err := c.hasKeyFile()
|
hasKeyFile, err := p.hasKeyFile()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if hasKeyFile {
|
if hasKeyFile {
|
||||||
return c.readKeyFile()
|
return p.readKeyFile()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.createKeyFile(); err != nil {
|
if err := p.createKeyFile(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.readKeyFile()
|
return p.readKeyFile()
|
||||||
}
|
}
|
||||||
|
|
||||||
// hasKeyFile checks if the key file exists in the disk storage.
|
// hasKeyFile checks if the key file exists in the disk storage.
|
||||||
func (c *Node) hasKeyFile() (bool, error) {
|
func (p *Peer) hasKeyFile() (bool, error) {
|
||||||
f, err := c.config.Open("key")
|
f, err := p.config.Open("key")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return false, nil
|
return false, nil
|
||||||
@ -205,8 +250,8 @@ func (c *Node) hasKeyFile() (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// createKeyFile creates a new key file with a generated private key.
|
// createKeyFile creates a new key file with a generated private key.
|
||||||
func (c *Node) createKeyFile() error {
|
func (p *Peer) createKeyFile() error {
|
||||||
f, err := c.config.Create("key")
|
f, err := p.config.Create("key")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -226,8 +271,8 @@ func (c *Node) createKeyFile() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// readKeyFile reads the private key from the key file and returns it as an ed25519.PrivateKey.
|
// readKeyFile reads the private key from the key file and returns it as an ed25519.PrivateKey.
|
||||||
func (c *Node) readKeyFile() (ed25519.PrivateKey, error) {
|
func (p *Peer) readKeyFile() (ed25519.PrivateKey, error) {
|
||||||
f, err := c.config.Open("key")
|
f, err := p.config.Open("key")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -245,7 +290,7 @@ func (c *Node) readKeyFile() (ed25519.PrivateKey, error) {
|
|||||||
return ed25519.PrivateKey(keyRaw), nil
|
return ed25519.PrivateKey(keyRaw), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleConnection(ctx context.Context, conn net.Conn) error {
|
func (p *Peer) handleConnection(ctx context.Context, conn net.Conn) error {
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
logger := logging.FromContext(ctx)
|
logger := logging.FromContext(ctx)
|
Loading…
x
Reference in New Issue
Block a user