github.com/dmmcquay/sia@v1.3.1-0.20180712220038-9f8d535311b9/cmd/siac/main.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"reflect"
     7  
     8  	"github.com/spf13/cobra"
     9  
    10  	"github.com/NebulousLabs/Sia/build"
    11  	"github.com/NebulousLabs/Sia/node/api/client"
    12  )
    13  
    14  var (
    15  	// Flags.
    16  	hostContractOutputType string // output type for host contracts
    17  	hostVerbose            bool   // display additional host info
    18  	initForce              bool   // destroy and re-encrypt the wallet on init if it already exists
    19  	initPassword           bool   // supply a custom password when creating a wallet
    20  	renterAllContracts     bool   // Show all active and expired contracts
    21  	renterDownloadAsync    bool   // Downloads files asynchronously
    22  	renterListVerbose      bool   // Show additional info about uploaded files.
    23  	renterShowHistory      bool   // Show download history in addition to download queue.
    24  )
    25  
    26  var (
    27  	// Globals.
    28  	rootCmd    *cobra.Command // Root command cobra object, used by bash completion cmd.
    29  	httpClient client.Client
    30  )
    31  
    32  // Exit codes.
    33  // inspired by sysexits.h
    34  const (
    35  	exitCodeGeneral = 1  // Not in sysexits.h, but is standard practice.
    36  	exitCodeUsage   = 64 // EX_USAGE in sysexits.h
    37  )
    38  
    39  // post makes an API call and discards the response. An error is returned if
    40  // the response status is not 2xx.
    41  // wrap wraps a generic command with a check that the command has been
    42  // passed the correct number of arguments. The command must take only strings
    43  // as arguments.
    44  func wrap(fn interface{}) func(*cobra.Command, []string) {
    45  	fnVal, fnType := reflect.ValueOf(fn), reflect.TypeOf(fn)
    46  	if fnType.Kind() != reflect.Func {
    47  		panic("wrapped function has wrong type signature")
    48  	}
    49  	for i := 0; i < fnType.NumIn(); i++ {
    50  		if fnType.In(i).Kind() != reflect.String {
    51  			panic("wrapped function has wrong type signature")
    52  		}
    53  	}
    54  
    55  	return func(cmd *cobra.Command, args []string) {
    56  		if len(args) != fnType.NumIn() {
    57  			cmd.UsageFunc()(cmd)
    58  			os.Exit(exitCodeUsage)
    59  		}
    60  		argVals := make([]reflect.Value, fnType.NumIn())
    61  		for i := range args {
    62  			argVals[i] = reflect.ValueOf(args[i])
    63  		}
    64  		fnVal.Call(argVals)
    65  	}
    66  }
    67  
    68  // die prints its arguments to stderr, then exits the program with the default
    69  // error code.
    70  func die(args ...interface{}) {
    71  	fmt.Fprintln(os.Stderr, args...)
    72  	os.Exit(exitCodeGeneral)
    73  }
    74  
    75  func main() {
    76  	root := &cobra.Command{
    77  		Use:   os.Args[0],
    78  		Short: "Sia Client v" + build.Version,
    79  		Long:  "Sia Client v" + build.Version,
    80  		Run:   wrap(consensuscmd),
    81  	}
    82  
    83  	rootCmd = root
    84  
    85  	// create command tree
    86  	root.AddCommand(versionCmd)
    87  	root.AddCommand(stopCmd)
    88  
    89  	root.AddCommand(updateCmd)
    90  	updateCmd.AddCommand(updateCheckCmd)
    91  
    92  	root.AddCommand(hostCmd)
    93  	hostCmd.AddCommand(hostConfigCmd, hostAnnounceCmd, hostFolderCmd, hostContractCmd, hostSectorCmd)
    94  	hostFolderCmd.AddCommand(hostFolderAddCmd, hostFolderRemoveCmd, hostFolderResizeCmd)
    95  	hostSectorCmd.AddCommand(hostSectorDeleteCmd)
    96  	hostCmd.Flags().BoolVarP(&hostVerbose, "verbose", "v", false, "Display detailed host info")
    97  	hostContractCmd.Flags().StringVarP(&hostContractOutputType, "type", "t", "value", "Select output type")
    98  
    99  	root.AddCommand(hostdbCmd)
   100  	hostdbCmd.AddCommand(hostdbViewCmd)
   101  	hostdbCmd.Flags().IntVarP(&hostdbNumHosts, "numhosts", "n", 0, "Number of hosts to display from the hostdb")
   102  	hostdbCmd.Flags().BoolVarP(&hostdbVerbose, "verbose", "v", false, "Display full hostdb information")
   103  
   104  	root.AddCommand(minerCmd)
   105  	minerCmd.AddCommand(minerStartCmd, minerStopCmd)
   106  
   107  	root.AddCommand(walletCmd)
   108  	walletCmd.AddCommand(walletAddressCmd, walletAddressesCmd, walletChangepasswordCmd, walletInitCmd, walletInitSeedCmd,
   109  		walletLoadCmd, walletLockCmd, walletSeedsCmd, walletSendCmd, walletSweepCmd,
   110  		walletBalanceCmd, walletTransactionsCmd, walletUnlockCmd)
   111  	walletInitCmd.Flags().BoolVarP(&initPassword, "password", "p", false, "Prompt for a custom password")
   112  	walletInitCmd.Flags().BoolVarP(&initForce, "force", "", false, "destroy the existing wallet and re-encrypt")
   113  	walletInitSeedCmd.Flags().BoolVarP(&initForce, "force", "", false, "destroy the existing wallet")
   114  	walletLoadCmd.AddCommand(walletLoad033xCmd, walletLoadSeedCmd, walletLoadSiagCmd)
   115  	walletSendCmd.AddCommand(walletSendSiacoinsCmd, walletSendSiafundsCmd)
   116  	walletUnlockCmd.Flags().BoolVarP(&initPassword, "password", "p", false, "Display interactive password prompt even if SIA_WALLET_PASSWORD is set")
   117  
   118  	root.AddCommand(renterCmd)
   119  	renterCmd.AddCommand(renterFilesDeleteCmd, renterFilesDownloadCmd,
   120  		renterDownloadsCmd, renterAllowanceCmd, renterSetAllowanceCmd,
   121  		renterContractsCmd, renterFilesListCmd, renterFilesRenameCmd,
   122  		renterFilesUploadCmd, renterUploadsCmd, renterExportCmd,
   123  		renterPricesCmd)
   124  
   125  	renterContractsCmd.AddCommand(renterContractsViewCmd)
   126  	renterAllowanceCmd.AddCommand(renterAllowanceCancelCmd)
   127  
   128  	renterCmd.Flags().BoolVarP(&renterListVerbose, "verbose", "v", false, "Show additional file info such as redundancy")
   129  	renterContractsCmd.Flags().BoolVarP(&renterAllContracts, "all", "A", false, "Show all expired contracts in addition to active contracts")
   130  	renterDownloadsCmd.Flags().BoolVarP(&renterShowHistory, "history", "H", false, "Show download history in addition to the download queue")
   131  	renterFilesDownloadCmd.Flags().BoolVarP(&renterDownloadAsync, "async", "A", false, "Download file asynchronously")
   132  	renterFilesListCmd.Flags().BoolVarP(&renterListVerbose, "verbose", "v", false, "Show additional file info such as redundancy")
   133  	renterExportCmd.AddCommand(renterExportContractTxnsCmd)
   134  
   135  	root.AddCommand(gatewayCmd)
   136  	gatewayCmd.AddCommand(gatewayConnectCmd, gatewayDisconnectCmd, gatewayAddressCmd, gatewayListCmd)
   137  
   138  	root.AddCommand(consensusCmd)
   139  
   140  	root.AddCommand(bashcomplCmd)
   141  	root.AddCommand(mangenCmd)
   142  
   143  	// initialize client
   144  	root.PersistentFlags().StringVarP(&httpClient.Address, "addr", "a", "localhost:9980", "which host/port to communicate with (i.e. the host/port siad is listening on)")
   145  	root.PersistentFlags().StringVarP(&httpClient.Password, "apipassword", "", "", "the password for the API's http authentication")
   146  	root.PersistentFlags().StringVarP(&httpClient.UserAgent, "useragent", "", "Sia-Agent", "the useragent used by siac to connect to the daemon's API")
   147  
   148  	// Check if the api password environment variable is set.
   149  	apiPassword := os.Getenv("SIA_API_PASSWORD")
   150  	if apiPassword != "" {
   151  		httpClient.Password = apiPassword
   152  		fmt.Println("Using SIA_API_PASSWORD environment variable")
   153  	}
   154  
   155  	// run
   156  	if err := root.Execute(); err != nil {
   157  		// Since no commands return errors (all commands set Command.Run instead of
   158  		// Command.RunE), Command.Execute() should only return an error on an
   159  		// invalid command or flag. Therefore Command.Usage() was called (assuming
   160  		// Command.SilenceUsage is false) and we should exit with exitCodeUsage.
   161  		os.Exit(exitCodeUsage)
   162  	}
   163  }