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 }