@@ -2,6 +2,7 @@ package aperture
22
33import (
44 "crypto/tls"
5+ "errors"
56 "fmt"
67 "io"
78 "io/ioutil"
@@ -11,9 +12,11 @@ import (
1112 "sync"
1213 "time"
1314
15+ flags "github.com/jessevdk/go-flags"
1416 "github.com/lightninglabs/aperture/auth"
1517 "github.com/lightninglabs/aperture/mint"
1618 "github.com/lightninglabs/aperture/proxy"
19+ "github.com/lightningnetwork/lnd"
1720 "github.com/lightningnetwork/lnd/build"
1821 "github.com/lightningnetwork/lnd/cert"
1922 "github.com/lightningnetwork/lnd/lnrpc"
@@ -71,10 +74,21 @@ var (
7174func Main () {
7275 // TODO: Prevent from running twice.
7376 err := run ()
74- if err != nil {
75- _ , _ = fmt .Fprintln (os .Stderr , err )
76- os .Exit (1 )
77+
78+ // Unwrap our error and check whether help was requested from our flag
79+ // library. If the error is not wrapped, Unwrap returns nil. It is
80+ // still safe to check the type of this nil error.
81+ flagErr , isFlagErr := errors .Unwrap (err ).(* flags.Error )
82+ isHelpErr := isFlagErr && flagErr .Type == flags .ErrHelp
83+
84+ // If we got a nil error, or help was requested, just exit.
85+ if err == nil || isHelpErr {
86+ os .Exit (0 )
7787 }
88+
89+ // Print any other non-help related errors.
90+ _ , _ = fmt .Fprintln (os .Stderr , err )
91+ os .Exit (1 )
7892}
7993
8094// run sets up the proxy server and runs it. This function blocks until a
@@ -88,10 +102,9 @@ func run() error {
88102 }
89103
90104 // Next, parse configuration file and set up logging.
91- configFile := filepath .Join (apertureDataDir , defaultConfigFilename )
92- cfg , err := getConfig (configFile )
105+ cfg , err := getConfig ()
93106 if err != nil {
94- return fmt .Errorf ("unable to parse config file: %v " , err )
107+ return fmt .Errorf ("unable to parse config file: %w " , err )
95108 }
96109 err = setupLogging (cfg , interceptor )
97110 if err != nil {
@@ -305,22 +318,66 @@ func fileExists(name string) bool {
305318
306319// getConfig loads and parses the configuration file then checks it for valid
307320// content.
308- func getConfig (configFile string ) (* Config , error ) {
321+ func getConfig () (* Config , error ) {
322+ // Pre-parse command line flags to determine whether we've been pointed
323+ // to a custom config file.
309324 cfg := & Config {}
325+ if _ , err := flags .Parse (cfg ); err != nil {
326+ return nil , err
327+ }
328+
329+ // If a custom config file is provided, we require that it exists.
330+ var mustExist bool
331+
332+ configFile := filepath .Join (apertureDataDir , defaultConfigFilename )
333+ if cfg .ConfigFile != "" {
334+ configFile = lnd .CleanAndExpandPath (cfg .ConfigFile )
335+ mustExist = true
336+ }
337+
338+ // Read our config file, either from the custom path provided or our
339+ // default location.
310340 b , err := ioutil .ReadFile (configFile )
311- if err != nil {
341+ switch {
342+ // If the file was found, unmarshal it.
343+ case err == nil :
344+ err = yaml .Unmarshal (b , cfg )
345+ if err != nil {
346+ return nil , err
347+ }
348+
349+ // If the error is unrelated to the existence of the file, we must
350+ // always return it.
351+ case ! os .IsNotExist (err ):
312352 return nil , err
353+
354+ // If we require that the config file exists and we got an error
355+ // related to file existence, we must fail.
356+ case mustExist && os .IsNotExist (err ):
357+ return nil , fmt .Errorf ("config file: %v must exist: %w" ,
358+ configFile , err )
313359 }
314- err = yaml .Unmarshal (b , cfg )
315- if err != nil {
360+
361+ // Finally, parse the remaining command line options again to ensure
362+ // they take precedence.
363+ if _ , err := flags .Parse (cfg ); err != nil {
316364 return nil , err
317365 }
318366
367+ // Clean and expand our cert and macaroon paths.
368+ cfg .Authenticator .TLSPath = lnd .CleanAndExpandPath (
369+ cfg .Authenticator .TLSPath ,
370+ )
371+ cfg .Authenticator .MacDir = lnd .CleanAndExpandPath (
372+ cfg .Authenticator .MacDir ,
373+ )
374+
319375 // Then check the configuration that we got from the config file, all
320376 // required values need to be set at this point.
321- if cfg .ListenAddr == "" {
322- return nil , fmt . Errorf ( "missing listen address for server" )
377+ if err := cfg .validate (); err != nil {
378+ return nil , err
323379 }
380+
324381 return cfg , nil
325382}
326383
0 commit comments