Documentation ¶
Index ¶
- Variables
- func AppendDigits(inValue int, buf []byte) int
- func AppendNDigits(inNumDigits int, inValue int, buf []byte, inPad byte) int
- func AppendTimestamp(buf []byte) int
- func AwaitInterrupt() <-chan struct{}
- func DefaultConfigPath(appName string) (root string, _ error)
- func DefaultConfigRoot(appName string) (root string, _ error)
- func DefaultDataRoot(appName string) (string, error)
- func FindOrCreateConfigAtPath(dst *Config, appName, configPath string) error
- func NewTermUI() *termUI
- type App
- type AuthProtocolConfig
- type BlobProtocolConfig
- type BootstrapPeer
- type BraidHTTPTransportConfig
- type Component
- type Config
- type FmtConstWidth
- type HushProtocolConfig
- type KeyStoreConfig
- type Libp2pTransportConfig
- type Mode
- type NurseConfig
- type REPLCommand
- type REPLCommands
- type REPLConfig
- type REPLHandler
- type TreeProtocolConfig
Constants ¶
This section is empty.
Variables ¶
View Source
var ( CmdMnemonic = REPLCommand{ HelpText: "show your identity's mnemonic", Handler: func(args []string, app *App) error { m, err := app.KeyStore.Mnemonic() if err != nil { return err } app.Debugf("mnemonic: %v", m) return nil }, } CmdAddress = REPLCommand{ HelpText: "show your address", Handler: func(args []string, app *App) error { identity, err := app.KeyStore.DefaultPublicIdentity() if err != nil { return err } app.Debugf("address: %v", identity.Address()) return nil }, } CmdLibp2pPeerID = REPLCommand{ HelpText: "show your libp2p peer ID", Handler: func(args []string, app *App) error { if app.Libp2pTransport == nil { return errors.New("libp2p is disabled") } peerID := app.Libp2pTransport.Libp2pPeerID() app.Debugf("libp2p peer ID: %v", peerID) return nil }, } CmdLibp2pRelayAdd = REPLCommand{ HelpText: "add a libp2p static relay", Handler: func(args []string, app *App) error { if app.Libp2pTransport == nil { return errors.New("libp2p is disabled") } else if len(args) < 1 { return errors.New("requires 1 argument: libp2p relay add <multiaddress>") } return app.Libp2pTransport.AddStaticRelay(args[0]) }, } CmdLibp2pRelayRemove = REPLCommand{ HelpText: "remove a libp2p static relay", Handler: func(args []string, app *App) error { if app.Libp2pTransport == nil { return errors.New("libp2p is disabled") } else if len(args) < 1 { return errors.New("requires 1 argument: libp2p relay rm <multiaddress>") } return app.Libp2pTransport.RemoveStaticRelay(args[0]) }, } CmdLibp2pRelayList = REPLCommand{ HelpText: "list the currently configured libp2p static relays", Handler: func(args []string, app *App) error { if app.Libp2pTransport == nil { return errors.New("libp2p is disabled") } for _, relay := range app.Libp2pTransport.StaticRelays().Slice() { fmt.Println(" -", relay) } return nil }, } CmdLibp2pStoreDebugPrint = REPLCommand{ HelpText: "print the contents of the libp2p store", Handler: func(args []string, app *App) error { app.Libp2pStore.DebugPrint() return nil }, } CmdSubscribe = REPLCommand{ HelpText: "subscribe to a state URI", Handler: func(args []string, app *App) error { if len(args) < 1 { return errors.New("missing argument: state URI") } stateURI := args[0] err := app.TreeProto.Subscribe(context.Background(), stateURI) if err != nil { return err } return nil }, } CmdStateURIs = REPLCommand{ HelpText: "list all known state URIs", Handler: func(args []string, app *App) error { stateURIs, err := app.ControllerHub.StateURIsWithData() if err != nil { return err } if len(stateURIs) == 0 { fmt.Println("no known state URIs") } else { for stateURI := range stateURIs { fmt.Println("- ", stateURI) } } return nil }, } CmdGetState = REPLCommand{ HelpText: "print the current state tree for a state URI", Handler: func(args []string, app *App) error { if len(args) < 1 { return errors.New("missing argument: state URI") } stateURI := args[0] node, err := app.ControllerHub.StateAtVersion(stateURI, nil) if err != nil { return err } var keypath state.Keypath var rng *state.Range if len(args) > 1 { keypath, rng, err = state.ParseKeypathAndRange([]byte(args[1]), byte('.')) if err != nil { return err } } app.Debugf("stateURI: %v / keypath: %v / range: %v", stateURI, keypath, rng) node = node.NodeAt(keypath, rng) node.DebugPrint(app.Debugf, false, 0) fmt.Println(utils.PrettyJSON(node)) return nil }, } CmdSetState = REPLCommand{ HelpText: "set a keypath in a state tree", Handler: func(args []string, app *App) error { if len(args) < 3 { return errors.New("requires 3 arguments: set <state URI> <keypath> <JSON value>") } stateURI := args[0] keypath := state.Keypath(args[1]) jsonVal := strings.Join(args[2:], " ") _, err := app.ControllerHub.StateAtVersion(stateURI, nil) var txID state.Version if errors.Cause(err) == errors.Err404 { txID = tree.GenesisTxID } else { txID = state.RandomVersion() } err = app.TreeProto.SendTx(context.TODO(), tree.Tx{ ID: txID, StateURI: stateURI, Patches: []tree.Patch{{ Keypath: keypath, ValueJSON: []byte(jsonVal), }}, }) return err }, } CmdListTxs = REPLCommand{ HelpText: "list the txs for a given state URI", Handler: func(args []string, app *App) error { if len(args) < 1 { return errors.New("requires 1 arguments: txs <state URI>") } stateURI := args[0] iter, err := app.TxStore.AllTxsForStateURI(stateURI, tree.GenesisTxID) if err != nil { return err } var rows [][]string for iter.Rewind(); iter.Valid(); iter.Next() { tx := iter.Tx() if tx == nil { break } var parents []string for _, parent := range tx.Parents { parents = append(parents, parent.Hex()) } rows = append(rows, []string{tx.ID.Hex(), tx.Status.String(), strings.Join(parents, " ")}) } if iter.Err() != nil { app.Errorf("iterator: %v", iter.Err()) } table := tablewriter.NewWriter(os.Stdout) table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false}) table.SetCenterSeparator("|") table.SetRowLine(true) table.SetAutoMergeCellsByColumnIndex([]int{0, 1}) table.SetHeader([]string{"ID", "Status", "Parents"}) table.AppendBulk(rows) table.Render() return nil }, } CmdTxStoreLeaves = REPLCommand{ HelpText: "print the leaves of the given state URI", Handler: func(args []string, app *App) error { if len(args) < 1 { return errors.New("requires 1 argument: leaves <state URI>") } leaves, err := app.TxStore.Leaves(args[0]) if err != nil { return err } for _, leaf := range leaves { app.Infof(0, "- %v", leaf.Hex()) } return nil }, } CmdTxStoreDebugPrint = REPLCommand{ HelpText: "print the contents of the tx store", Handler: func(args []string, app *App) error { app.TxStore.DebugPrint() return nil }, } CmdBlobs = REPLCommand{ HelpText: "list all blobs", Handler: func(args []string, app *App) error { app.BlobStore.DebugPrint() contents, err := app.BlobStore.Contents() if err != nil { return err } var rows [][]string for blobHash, x := range contents { for chunkHash, have := range x { rows = append(rows, []string{blobHash.Hex(), chunkHash.Hex(), fmt.Sprintf("%v", have)}) } } table := tablewriter.NewWriter(os.Stdout) table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false}) table.SetCenterSeparator("|") table.SetRowLine(true) table.SetAutoMergeCellsByColumnIndex([]int{0, 1}) table.SetHeader([]string{"Blob", "Chunk", "Have"}) table.AppendBulk(rows) table.Render() return nil }, } CmdPeers = REPLCommand{ HelpText: "list all known peers", Handler: func(args []string, app *App) error { var full bool if len(args) > 0 { if args[0] == "full" { full = true } else { return errors.Errorf("unknown argument '%v'", args[0]) } } fmtPeerRow := func(addr, duID, dialAddr string, lastContact, lastFailure time.Time, failures uint64, remainingBackoff time.Duration, stateURIs []string) []string { if !full && len(addr) > 10 { addr = addr[:4] + "..." + addr[len(addr)-4:] } if !full && len(dialAddr) > 30 { dialAddr = dialAddr[:30] + "..." + dialAddr[len(dialAddr)-6:] } lastContactStr := time.Now().Sub(lastContact).Round(1 * time.Second).String() if lastContact.IsZero() { lastContactStr = "" } lastFailureStr := time.Now().Sub(lastFailure).Round(1 * time.Second).String() if lastFailure.IsZero() { lastFailureStr = "" } failuresStr := fmt.Sprintf("%v", failures) remainingBackoffStr := remainingBackoff.Round(1 * time.Second).String() if remainingBackoff == 0 { remainingBackoffStr = "" } if !full && len(duID) > 4 { duID = duID[:4] + "..." } return []string{addr, duID, dialAddr, lastContactStr, lastFailureStr, failuresStr, remainingBackoffStr, fmt.Sprintf("%v", stateURIs)} } var data [][]string for _, peer := range app.PeerStore.Peers() { for _, e := range peer.Endpoints() { for addr := range peer.Addresses() { data = append(data, fmtPeerRow(addr.Hex(), e.DeviceUniqueID(), e.DialInfo().DialAddr, e.LastContact(), e.LastFailure(), e.Failures(), e.RemainingBackoff(), e.StateURIs().Slice())) } if len(e.Addresses()) == 0 { data = append(data, fmtPeerRow("?", e.DeviceUniqueID(), e.DialInfo().DialAddr, e.LastContact(), e.LastFailure(), e.Failures(), e.RemainingBackoff(), e.StateURIs().Slice())) } } } sort.Slice(data, func(i, j int) bool { cmp := strings.Compare(data[i][0], data[j][0]) if cmp == 0 { return strings.Compare(data[i][1], data[j][1]) < 0 } else { return cmp < 0 } }) table := tablewriter.NewWriter(os.Stdout) table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false}) table.SetCenterSeparator("|") table.SetRowLine(true) table.SetHeader([]string{"Address", "DeviceID", "DialAddr", "LastContact", "LastFailure", "Failures", "Backoff", "StateURIs"}) table.SetAutoMergeCellsByColumnIndex([]int{0, 1}) table.SetColumnColor( tablewriter.Colors{tablewriter.Bold, tablewriter.FgCyanColor}, tablewriter.Colors{}, tablewriter.Colors{}, tablewriter.Colors{}, tablewriter.Colors{}, tablewriter.Colors{}, tablewriter.Colors{}, tablewriter.Colors{}, ) table.AppendBulk(data) table.Render() return nil }, } CmdAddPeer = REPLCommand{ HelpText: "add a peer", Handler: func(args []string, app *App) error { if len(args) < 2 { return errors.New("requires 2 arguments: peers add <transport> <dial addr>") } app.PeerStore.AddDialInfo(swarm.PeerDialInfo{args[0], args[1]}, "") return nil }, } CmdRemoveAllPeers = REPLCommand{ HelpText: "remove all peers", Handler: func(args []string, app *App) error { var toDelete []string for _, peer := range app.PeerStore.Peers() { toDelete = append(toDelete, peer.DeviceUniqueID()) } app.PeerStore.RemovePeers(toDelete) return nil }, } CmdRemoveUnverifiedPeers = REPLCommand{ HelpText: "remove peers who haven't been verified", Handler: func(args []string, app *App) error { var toDelete []string for _, peer := range app.PeerStore.Peers() { if len(peer.Addresses()) == 0 { toDelete = append(toDelete, peer.DeviceUniqueID()) } } app.PeerStore.RemovePeers(toDelete) return nil }, } CmdRemoveFailedPeers = REPLCommand{ HelpText: "remove peers with more than a certain number of failures", Handler: func(args []string, app *App) error { if len(args) < 1 { return errors.New("requires 1 argument: rmfailedpeers <number of failures>") } num, err := strconv.Atoi(args[0]) if err != nil { return errors.Wrap(err, "bad argument") } var toDelete []string for _, peer := range app.PeerStore.Peers() { if peer.Failures() > uint64(num) { toDelete = append(toDelete, peer.DeviceUniqueID()) } } app.PeerStore.RemovePeers(toDelete) return nil }, } CmdHushSendIndividualMessage = REPLCommand{ HelpText: "send a 1:1 Hush message", Handler: func(args []string, app *App) error { if len(args) < 2 { return errors.New("requires 2 arguments: hushmsg <recipient address> <message>") } recipient, err := types.AddressFromHex(args[0]) if err != nil { return err } msg := strings.Join(args[1:], " ") return app.HushProto.EncryptIndividualMessage("foo", recipient, []byte(msg)) }, } CmdHushSendGroupMessage = REPLCommand{ HelpText: "send a group Hush message", Handler: func(args []string, app *App) error { if len(args) < 2 { return errors.New("requires 2 arguments: hushmsg <comma-separated recipient addresses> <message>") } addrStrs := strings.Split(args[0], ",") var recipients []types.Address for _, s := range addrStrs { addr, err := types.AddressFromHex(s) if err != nil { return err } recipients = append(recipients, addr) } msg := strings.Join(args[1:], " ") id := types.RandomID() return app.HushProto.EncryptGroupMessage("foo", id.Hex(), recipients, []byte(msg)) }, } CmdHushStoreDebugPrint = REPLCommand{ HelpText: "print the contents of the protohush store", Handler: func(args []string, app *App) error { app.HushProtoStore.DebugPrint() return nil }, } CmdTreeStoreDebugPrint = REPLCommand{ HelpText: "print the contents of the prototree store", Handler: func(args []string, app *App) error { app.TreeProtoStore.DebugPrint() return nil }, } CmdControllerDebugPrint = REPLCommand{ HelpText: "print the contents of a state DB", Handler: func(args []string, app *App) error { if len(args) < 1 { return errors.New("requires 1 argument: tree dumptree <state uri>") } app.ControllerHub.DebugPrint(args[0]) return nil }, } CmdPeerStoreDebugPrint = REPLCommand{ HelpText: "print the contents of the peer store", Handler: func(args []string, app *App) error { app.PeerStore.DebugPrint() return nil }, } CmdProcessTree = REPLCommand{ HelpText: "display the current process tree", Handler: func(args []string, app *App) error { app.Infof(0, "processes:\n%v", utils.PrettyJSON(app.ProcessTree())) return nil }, } CmdSetBlobMaxFetchConns = REPLCommand{ HelpText: "set the maximum number of peers to fetch a blob from simultaneously", Handler: func(args []string, app *App) error { if len(args) < 1 { return errors.New("requires 1 argument: blob set maxfetchconns <n>") } n, err := strconv.ParseUint(args[0], 10, 64) if err != nil { return err } return app.BlobStore.SetMaxFetchConns(n) }, } HelpText: "print the contents of the shared state store", Handler: func(args []string, app *App) error { node := app.SharedStateDB.State(false) defer node.Close() node.DebugPrint(func(msg string, args ...interface{}) { fmt.Printf(msg, args...) }, true, 0) return nil }, } )
View Source
var ErrShowHelp = errors.New("")
Functions ¶
func AppendDigits ¶
AppendDigits appends the base 10 value to the given buffer, returning the number of bytes written.
Pre: inValue > 0
func AppendNDigits ¶
AppendNDigits formats an n-digit integer to the given buffer, padding as needed, returning the number of bytes written.
Pre: len(buf) >= inNumDigits
func AppendTimestamp ¶
AppendTimestamp appends a glog/klog-style timestamp to the given slice, returning how many bytes were written.
Pre: len(buf) >= 20
func AwaitInterrupt ¶
func AwaitInterrupt() <-chan struct{}
func DefaultConfigPath ¶
func DefaultConfigRoot ¶
func DefaultDataRoot ¶
Types ¶
type App ¶
type App struct { process.Process log.Logger Config Config TermUI *termUI ControllerHub tree.ControllerHub TxStore tree.TxStore KeyStore identity.KeyStore PeerStore swarm.PeerStore BlobStore blob.Store AuthProto protoauth.AuthProtocol BlobProto protoblob.BlobProtocol HushProto protohush.HushProtocol HushProtoStore protohush.Store TreeProto prototree.TreeProtocol TreeProtoStore prototree.Store HTTPTransport braidhttp.Transport Libp2pTransport libp2p.Transport Libp2pStore libp2p.Store HTTPRPCServer *http.Server HTTPRPCServerConfig rpc.HTTPConfig PeerDB *state.DBTree HushDB *state.DBTree TreeDB *state.DBTree Nurse *health.Nurse }
func (*App) EnsureDataDirs ¶
func (*App) EnsureInitialState ¶
type AuthProtocolConfig ¶
type AuthProtocolConfig struct {
Enabled bool `yaml:"Enabled"`
}
type BlobProtocolConfig ¶
type BlobProtocolConfig struct {
Enabled bool `yaml:"Enabled"`
}
type BootstrapPeer ¶
type BraidHTTPTransportConfig ¶
type BraidHTTPTransportConfig struct { Enabled bool `yaml:"Enabled"` ListenHost string `yaml:"ListenHost"` ListenHostSSL string `yaml:"ListenHostSSL"` TLSCertFile string `yaml:"TLSCertFile"` TLSKeyFile string `yaml:"TLSKeyFile"` DefaultStateURI string `yaml:"DefaultStateURI"` ReachableAt string `yaml:"ReachableAt"` }
type Config ¶
type Config struct { Mode Mode `yaml:"-"` REPLConfig REPLConfig `yaml:"-"` BootstrapPeers []BootstrapPeer `yaml:"BootstrapPeers"` DataRoot string `yaml:"DataRoot"` DNSOverHTTPSURL string `yaml:"DNSOverHTTPSURL"` JWTSecret string `yaml:"JWTSecret"` DevMode bool `yaml:"-"` Nurse NurseConfig `yaml:"Nurse"` KeyStore KeyStoreConfig `yaml:"-"` PprofPort uint32 `yaml:"PprofPort"` Libp2pTransport Libp2pTransportConfig `yaml:"Libp2pTransport"` BraidHTTPTransport BraidHTTPTransportConfig `yaml:"BraidHTTPTransport"` AuthProtocol AuthProtocolConfig `yaml:"AuthProtocol"` BlobProtocol BlobProtocolConfig `yaml:"BlobProtocol"` HushProtocol HushProtocolConfig `yaml:"HushProtocol"` TreeProtocol TreeProtocolConfig `yaml:"TreeProtocol"` HTTPRPC *rpc.HTTPConfig `yaml:"HTTPRPC"` // contains filtered or unexported fields }
func DefaultConfig ¶
func (*Config) BlobDataRoot ¶
func (*Config) KeyStoreRoot ¶
func (*Config) StateDBRoot ¶
type FmtConstWidth ¶
type FmtConstWidth struct { // FileNameCharWidth is the number of chars to use from the given file name. // Filenames shorter than this are padded with spaces. // If 0, file names are not printed. FileNameCharWidth int // If set, color codes will be inserted UseColor bool }
FmtConstWidth is a basic formatter that makes reasonable attempts to make the header length a constant width, improving readability. It also can insert console color codes so each severity level is a different color.
func (*FmtConstWidth) FormatHeader ¶
func (f *FmtConstWidth) FormatHeader(inSeverity string, inFile string, inLine int, buf *bytes.Buffer)
FormatHeader -- see interface Formatter
type HushProtocolConfig ¶
type HushProtocolConfig struct {
Enabled bool `yaml:"Enabled"`
}
type KeyStoreConfig ¶
type Libp2pTransportConfig ¶
type NurseConfig ¶
type NurseConfig struct { Enabled bool `yaml:"Enabled"` ProfileRoot string `yaml:"ProfileRoot"` PollInterval time.Duration `yaml:"PollInterval"` GatherDuration time.Duration `yaml:"GatherDuration"` MaxProfileSize utils.FileSize `yaml:"MaxProfileSize"` CPUProfileRate int `yaml:"CPUProfileRate"` MemProfileRate int `yaml:"MemProfileRate"` BlockProfileRate int `yaml:"BlockProfileRate"` MutexProfileFraction int `yaml:"MutexProfileFraction"` MemThreshold utils.FileSize `yaml:"MemThreshold"` GoroutineThreshold int `yaml:"GoroutineThreshold"` }
type REPLCommand ¶
type REPLCommand struct { HelpText string Subcommands REPLCommands Handler func(args []string, app *App) error }
func (REPLCommand) Handle ¶
func (c REPLCommand) Handle(cmdParts []string, args []string, app *App) error
func (REPLCommand) Help ¶
func (c REPLCommand) Help() string
type REPLCommands ¶
type REPLCommands map[string]REPLCommand
func (REPLCommands) Handle ¶
func (c REPLCommands) Handle(cmdParts []string, args []string, app *App) error
func (REPLCommands) Help ¶
func (c REPLCommands) Help() string
type REPLConfig ¶
type REPLConfig struct { Prompt string Commands REPLCommands }
type REPLHandler ¶
type TreeProtocolConfig ¶
Click to show internal directories.
Click to hide internal directories.