diff --git a/tor-miner/cmd/tor-miner/main.go b/tor-miner/cmd/tor-miner/main.go index f68223b..abf6125 100644 --- a/tor-miner/cmd/tor-miner/main.go +++ b/tor-miner/cmd/tor-miner/main.go @@ -2,6 +2,7 @@ package main import ( "context" + "errors" "fmt" "os" @@ -9,13 +10,13 @@ import ( ) func main() { - if len(os.Args) < 2 { - fmt.Println("usage: tor-miner CONFIG_PASSPHRASE [XMRIG_ARGS...]") - os.Exit(2) - } - app := miner.Runner{} if err := app.Run(context.Background()); err != nil { + if errors.Is(err, miner.UsageError) { + fmt.Println(err) + os.Exit(2) + } + fmt.Println("tor-miner:", err) os.Exit(1) } diff --git a/tor-miner/runner.go b/tor-miner/runner.go index df1c7d5..71e7947 100644 --- a/tor-miner/runner.go +++ b/tor-miner/runner.go @@ -3,7 +3,9 @@ package miner import ( "context" "encoding/base32" + "errors" "fmt" + "io/fs" "net" net_url "net/url" "os" @@ -15,12 +17,15 @@ import ( ) const ( - DefaultMinerPath = "xmrig" - TorProxyAddr = "127.0.0.1:9050" - TorStartupTimeout = time.Minute - DefaultAPIAddr = "127.0.0.1:3638" + DefaultMinerPath = "xmrig" + TorProxyAddr = "127.0.0.1:9050" + TorStartupTimeout = time.Minute + DefaultAPIAddr = "127.0.0.1:3638" ) +var UsageError = errors.New( + "usage: tor-miner [CONFIG_PASSPHRASE] [XMRIG_ARGS...]") + var httpAPI = regexp.MustCompile(`HTTP API\s+(\S+:\d+)\n`) type Runner struct { @@ -36,24 +41,26 @@ type Runner struct { } func (r *Runner) Run(ctx context.Context) error { - if len(os.Args) < 2 { - return panique("invocation error") + password, err := configPassword() + if err != nil { + return err } if r.isStarted { return panique("already started") } r.isStarted = true - config, err := DefaultConfig(os.Args[1]) + config, err := DefaultConfig(password) if err != nil { return err } + password = "" if r.MinerPath == "" { r.MinerPath = DefaultMinerPath } if r.MinerArgs == nil { - r.MinerArgs = os.Args[2:] + r.MinerArgs = os.Args[1:] } if r.LocalAPI.URL == "" { r.LocalAPI.URL = "http://" + DefaultAPIAddr @@ -179,6 +186,29 @@ func (r *Runner) Run(ctx context.Context) error { return monitor(cmds, &r.LocalAPI, r.onionAPI, &config.Monitor) } +func configPassword() (string, error) { + if len(os.Args) < 2 || strings.HasPrefix(os.Args[1], "-") { + for _, filename := range []string{ + "/run/secrets/tor_miner_config_passphrase", + "/etc/tor-miner/config_passphrase", + } { + bytes, err := os.ReadFile(filename) + if err == nil { + return strings.TrimSpace(string(bytes)), nil + } else if !errors.Is(err, fs.ErrNotExist) { + return "", err + } + msg, _ := strings.CutPrefix(err.Error(), "open ") + fmt.Println("tor-miner:", msg) + } + + return "", UsageError + } + password := os.Args[1] + os.Args = append(os.Args[:1], os.Args[2:]...) + return password, nil +} + func (r *Runner) dryRun(ctx context.Context) (string, error) { cmd := r.newMinerCommand(ctx, "--dry-run") out, err := cmd.CombinedOutput()