103 lines
2.6 KiB
Go
103 lines
2.6 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/xml"
|
|
"flag"
|
|
"fmt"
|
|
"lux/crypto"
|
|
"lux/proto"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
var isNode bool
|
|
var isHost bool
|
|
var isRpc bool
|
|
var configPath string
|
|
var rpcPath string
|
|
var bootstrap bool
|
|
var justNodeId bool
|
|
|
|
type NodeConfig struct {
|
|
XMLName xml.Name `xml:"node"`
|
|
KeyStore string `xml:"keystore"`
|
|
ID string `xml:"id"`
|
|
Interior []string `xml:"interior"`
|
|
Exterior []string `xml:"exterior"`
|
|
Neighbors []struct {
|
|
XMLName xml.Name `xml:"neighbor"`
|
|
ID string `xml:"id"`
|
|
Address string `xml:"address"`
|
|
} `xml:"neighbor"`
|
|
}
|
|
|
|
func bootstrapNode() {
|
|
xmlBytes, err := os.ReadFile(configPath)
|
|
if err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
var config NodeConfig
|
|
if err := xml.Unmarshal(xmlBytes, &config); err != nil {
|
|
fmt.Fprintf(os.Stderr, "failed to parse xml: %v", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
// create keystore, generate node key
|
|
ks := crypto.NewLuxKeyStore(config.KeyStore)
|
|
nodeKey, err := crypto.NewLuxKey(proto.LuxTypeNode)
|
|
if err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
if err := ks.Put(nodeKey); err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
if justNodeId {
|
|
fmt.Println(nodeKey.Id.String())
|
|
} else {
|
|
fmt.Printf("Your node key ID is: %s\nAdd <id>%s</id> to your node config!\n",
|
|
nodeKey.Id.String(), nodeKey.Id.String())
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
// first, we need to determine who we are: node, host or rpc.
|
|
// determine by executable name (lux binary will be symlinked to lux-node, lux-host, luc-rpc),
|
|
// or by explicit cli flag (--node, --host, --rpc)
|
|
flag.BoolVar(&isNode, "node", false, "LUX node")
|
|
flag.BoolVar(&isHost, "host", false, "LUX host")
|
|
flag.BoolVar(&isRpc, "rpc", false, "RPC tool")
|
|
flag.StringVar(&configPath, "config", "", "node or host config")
|
|
flag.StringVar(&rpcPath, "rpc-path", "", "path to RPC UNIX socket or TCP socket, must be in unix:// or tcp:// form")
|
|
flag.BoolVar(&bootstrap, "bootstrap", false, "bootstrap node keystore. config must be specified")
|
|
flag.BoolVar(&justNodeId, "just-node-id", false, "when bootstrapping only output node id to stdout")
|
|
flag.Parse()
|
|
|
|
if !isNode && !isHost && !isRpc {
|
|
// determine by argv[0]
|
|
if strings.Contains(os.Args[0], "node") {
|
|
isNode = true
|
|
} else if strings.Contains(os.Args[0], "host") {
|
|
isHost = true
|
|
} else if strings.Contains(os.Args[0], "rpc") {
|
|
isRpc = true
|
|
}
|
|
}
|
|
|
|
if (isNode || isHost) && configPath == "" {
|
|
fmt.Fprintln(os.Stderr, "must provide config path")
|
|
os.Exit(1)
|
|
} else if isRpc && rpcPath == "" {
|
|
fmt.Fprintln(os.Stderr, "must provide RPC socket path")
|
|
os.Exit(1)
|
|
}
|
|
|
|
if isNode && bootstrap {
|
|
bootstrapNode()
|
|
return
|
|
}
|
|
}
|