Documentation ¶
Overview ¶
Package commands implements the IPFS command interface
Using github.com/ipfs/go-ipfs/commands to define the command line and HTTP APIs. This is the interface available to folks consuming IPFS from outside of the Go language.
Index ¶
- Constants
- Variables
- func CommandsCmd(root *cmds.Command) *cmds.Command
- func KeyListTextMarshaler(res cmds.Response) (io.Reader, error)
- func MessageTextMarshaler(res cmds.Response) (io.Reader, error)
- func Mount(node *core.IpfsNode, fsdir, nsdir string) error
- func NewMemoryDagService() dag.DAGService
- func ParsePeerParam(text string) (ma.Multiaddr, peer.ID, error)
- type AddedObject
- type BlockStat
- type BootstrapOutput
- type Command
- type ConfigField
- type DiagnosticConnection
- type DiagnosticOutput
- type DiagnosticPeer
- type IdOutput
- type IpnsEntry
- type KeyList
- type Link
- type LsLink
- type LsObject
- type LsOutput
- type MessageOutput
- type Node
- type Object
- type PinOutput
- type PingResult
- type RefKeyList
- type RefKeyObject
- type RefWrapper
- type RefWriter
- type ResolvedPath
- type TestOutput
- type UpdateOutput
- type VersionOutput
Constants ¶
const (
ApiOption = "api"
)
Variables ¶
var AddCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Add an object to ipfs.", ShortDescription: ` Adds contents of <path> to ipfs. Use -r to add directories. Note that directories are added recursively, to form the ipfs MerkleDAG. A smarter partial add with a staging area (like git) remains to be implemented. `, }, Arguments: []cmds.Argument{ cmds.FileArg("path", true, true, "The path to a file to be added to IPFS").EnableRecursive().EnableStdin(), }, Options: []cmds.Option{ cmds.OptionRecursivePath, cmds.BoolOption(quietOptionName, "q", "Write minimal output"), cmds.BoolOption(progressOptionName, "p", "Stream progress data"), cmds.BoolOption(trickleOptionName, "t", "Use trickle-dag format for dag generation"), cmds.BoolOption(onlyHashOptionName, "n", "Only chunk and hash - do not write to disk"), cmds.BoolOption(wrapOptionName, "w", "Wrap files with a directory object"), cmds.BoolOption(hiddenOptionName, "Include files that are hidden"), cmds.StringOption(chunkerOptionName, "s", "chunking algorithm to use"), }, PreRun: func(req cmds.Request) error { if quiet, _, _ := req.Option(quietOptionName).Bool(); quiet { return nil } req.SetOption(progressOptionName, true) sizeFile, ok := req.Files().(files.SizeFile) if !ok { return nil } size, err := sizeFile.Size() if err != nil { return nil } log.Debugf("Total size of file being added: %v\n", size) req.Values()["size"] = size return nil }, Run: func(req cmds.Request, res cmds.Response) { n, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } progress, _, _ := req.Option(progressOptionName).Bool() trickle, _, _ := req.Option(trickleOptionName).Bool() wrap, _, _ := req.Option(wrapOptionName).Bool() hash, _, _ := req.Option(onlyHashOptionName).Bool() hidden, _, _ := req.Option(hiddenOptionName).Bool() chunker, _, _ := req.Option(chunkerOptionName).String() e := dagutils.NewDagEditor(NewMemoryDagService(), newDirNode()) if hash { nilnode, err := core.NewNode(n.Context(), &core.BuildCfg{ NilRepo: true, }) if err != nil { res.SetError(err, cmds.ErrNormal) return } n = nilnode } outChan := make(chan interface{}, 8) res.SetOutput((<-chan interface{})(outChan)) fileAdder := adder{ ctx: req.Context(), node: n, editor: e, out: outChan, chunker: chunker, progress: progress, hidden: hidden, trickle: trickle, wrap: wrap, } addAllFiles := func(sliceFile files.File) error { for { file, err := sliceFile.NextFile() if err != nil && err != io.EOF { return err } if file == nil { return nil } if _, err := fileAdder.addFile(file); err != nil { return err } } } pinRoot := func(rootnd *dag.Node) error { rnk, err := rootnd.Key() if err != nil { return err } mp := n.Pinning.GetManual() mp.RemovePinWithMode(rnk, pin.Indirect) mp.PinWithMode(rnk, pin.Recursive) return n.Pinning.Flush() } addAllAndPin := func(f files.File) error { if err := addAllFiles(f); err != nil { return err } if !hash { err := e.WriteOutputTo(n.DAG) if err != nil { log.Error("WRITE OUT: ", err) return err } } rootnd, err := fileAdder.RootNode() if err != nil { return err } return pinRoot(rootnd) } go func() { defer close(outChan) if err := addAllAndPin(req.Files()); err != nil { res.SetError(err, cmds.ErrNormal) return } }() }, PostRun: func(req cmds.Request, res cmds.Response) { if res.Error() != nil { return } outChan, ok := res.Output().(<-chan interface{}) if !ok { res.SetError(u.ErrCast(), cmds.ErrNormal) return } res.SetOutput(nil) quiet, _, err := req.Option("quiet").Bool() if err != nil { res.SetError(u.ErrCast(), cmds.ErrNormal) return } size := int64(0) s, found := req.Values()["size"] if found { size = s.(int64) } showProgressBar := !quiet && size >= progressBarMinSize var bar *pb.ProgressBar var terminalWidth int if showProgressBar { bar = pb.New64(size).SetUnits(pb.U_BYTES) bar.ManualUpdate = true bar.Start() terminalWidth = 0 bar.Callback = func(line string) { terminalWidth = len(line) bar.Callback = nil bar.Output = res.Stderr() log.Infof("terminal width: %v\n", terminalWidth) } bar.Update() } lastFile := "" var totalProgress, prevFiles, lastBytes int64 for out := range outChan { output := out.(*AddedObject) if len(output.Hash) > 0 { if showProgressBar { fmt.Fprintf(res.Stderr(), "\033[2K\r") } if quiet { fmt.Fprintf(res.Stdout(), "%s\n", output.Hash) } else { fmt.Fprintf(res.Stdout(), "added %s %s\n", output.Hash, output.Name) } } else { log.Debugf("add progress: %v %v\n", output.Name, output.Bytes) if !showProgressBar { continue } if len(lastFile) == 0 { lastFile = output.Name } if output.Name != lastFile || output.Bytes < lastBytes { prevFiles += lastBytes lastFile = output.Name } lastBytes = output.Bytes delta := prevFiles + lastBytes - totalProgress totalProgress = bar.Add64(delta) } if showProgressBar { bar.Update() } } }, Type: AddedObject{}, }
var BitswapCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "A set of commands to manipulate the bitswap agent", ShortDescription: ``, }, Subcommands: map[string]*cmds.Command{ "wantlist": showWantlistCmd, "stat": bitswapStatCmd, "unwant": unwantCmd, }, }
var BlockCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Manipulate raw IPFS blocks", ShortDescription: ` 'ipfs block' is a plumbing command used to manipulate raw ipfs blocks. Reads from stdin or writes to stdout, and <key> is a base58 encoded multihash. `, }, Subcommands: map[string]*cmds.Command{ "stat": blockStatCmd, "get": blockGetCmd, "put": blockPutCmd, }, }
var BootstrapCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Show or edit the list of bootstrap peers", Synopsis: ` ipfs bootstrap list - Show peers in the bootstrap list ipfs bootstrap add <peer>... - Add peers to the bootstrap list ipfs bootstrap rm <peer>... - Removes peers from the bootstrap list `, ShortDescription: ` Running 'ipfs bootstrap' with no arguments will run 'ipfs bootstrap list'. ` + bootstrapSecurityWarning, }, Run: bootstrapListCmd.Run, Marshalers: bootstrapListCmd.Marshalers, Type: bootstrapListCmd.Type, Subcommands: map[string]*cmds.Command{ "list": bootstrapListCmd, "add": bootstrapAddCmd, "rm": bootstrapRemoveCmd, }, }
var CatCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Show IPFS object data", ShortDescription: ` Retrieves the object named by <ipfs-or-ipns-path> and outputs the data it contains. `, }, Arguments: []cmds.Argument{ cmds.StringArg("ipfs-path", true, true, "The path to the IPFS object(s) to be outputted").EnableStdin(), }, Run: func(req cmds.Request, res cmds.Response) { node, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } readers, length, err := cat(req.Context(), node, req.Arguments()) if err != nil { res.SetError(err, cmds.ErrNormal) return } res.SetLength(length) reader := io.MultiReader(readers...) res.SetOutput(reader) }, PostRun: func(req cmds.Request, res cmds.Response) { if res.Length() < progressBarMinSize { return } bar := pb.New(int(res.Length())).SetUnits(pb.U_BYTES) bar.Output = res.Stderr() bar.Start() reader := bar.NewProxyReader(res.Output().(io.Reader)) res.SetOutput(&clearlineReader{reader, res.Stderr()}) }, }
var CommandsDaemonCmd = CommandsCmd(Root)
commandsDaemonCmd is the "ipfs commands" command for daemon
var CommandsDaemonROCmd = CommandsCmd(RootRO)
var ConfigCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "get and set IPFS config values", Synopsis: ` ipfs config <key> - Get value of <key> ipfs config <key> <value> - Set value of <key> to <value> ipfs config show - Show config file ipfs config edit - Edit config file in $EDITOR ipfs config replace <file> - Replaces the config file with <file> `, ShortDescription: ` ipfs config controls configuration variables. It works like 'git config'. The configuration values are stored in a config file inside your IPFS repository.`, LongDescription: ` ipfs config controls configuration variables. It works much like 'git config'. The configuration values are stored in a config file inside your IPFS repository. EXAMPLES: Get the value of the 'datastore.path' key: ipfs config datastore.path Set the value of the 'datastore.path' key: ipfs config datastore.path ~/.ipfs/datastore `, }, Arguments: []cmds.Argument{ cmds.StringArg("key", true, false, "The key of the config entry (e.g. \"Addresses.API\")"), cmds.StringArg("value", false, false, "The value to set the config entry to"), }, Options: []cmds.Option{ cmds.BoolOption("bool", "Set a boolean value"), cmds.BoolOption("json", "Parse stringified JSON"), }, Run: func(req cmds.Request, res cmds.Response) { args := req.Arguments() key := args[0] r, err := fsrepo.Open(req.InvocContext().ConfigRoot) if err != nil { res.SetError(err, cmds.ErrNormal) return } defer r.Close() var output *ConfigField if len(args) == 2 { value := args[1] if parseJson, _, _ := req.Option("json").Bool(); parseJson { var jsonVal interface{} if err := json.Unmarshal([]byte(value), &jsonVal); err != nil { err = fmt.Errorf("failed to unmarshal json. %s", err) res.SetError(err, cmds.ErrNormal) return } output, err = setConfig(r, key, jsonVal) } else if isbool, _, _ := req.Option("bool").Bool(); isbool { output, err = setConfig(r, key, value == "true") } else { output, err = setConfig(r, key, value) } } else { output, err = getConfig(r, key) } if err != nil { res.SetError(err, cmds.ErrNormal) return } res.SetOutput(output) }, Marshalers: cmds.MarshalerMap{ cmds.Text: func(res cmds.Response) (io.Reader, error) { if len(res.Request().Arguments()) == 2 { return nil, nil } v := res.Output() if v == nil { k := res.Request().Arguments()[0] return nil, fmt.Errorf("config does not contain key: %s", k) } vf, ok := v.(*ConfigField) if !ok { return nil, u.ErrCast() } buf, err := config.HumanOutput(vf.Value) if err != nil { return nil, err } buf = append(buf, byte('\n')) return bytes.NewReader(buf), nil }, }, Type: ConfigField{}, Subcommands: map[string]*cmds.Command{ "show": configShowCmd, "edit": configEditCmd, "replace": configReplaceCmd, }, }
var DNSCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "DNS link resolver", ShortDescription: ` Multihashes are hard to remember, but domain names are usually easy to remember. To create memorable aliases for multihashes, DNS TXT records can point to other DNS links, IPFS objects, IPNS keys, etc. This command resolves those links to the referenced object. `, LongDescription: ` Multihashes are hard to remember, but domain names are usually easy to remember. To create memorable aliases for multihashes, DNS TXT records can point to other DNS links, IPFS objects, IPNS keys, etc. This command resolves those links to the referenced object. For example, with this DNS TXT record: ipfs.io. TXT "dnslink=/ipfs/QmRzTuh2Lpuz7Gr39stNr6mTFdqAghsZec1JoUnfySUzcy ..." The resolver will give: > ipfs dns ipfs.io /ipfs/QmRzTuh2Lpuz7Gr39stNr6mTFdqAghsZec1JoUnfySUzcy And with this DNS TXT record: ipfs.ipfs.io. TXT "dnslink=/dns/ipfs.io ..." The resolver will give: > ipfs dns ipfs.io /dns/ipfs.io > ipfs dns --recursive /ipfs/QmRzTuh2Lpuz7Gr39stNr6mTFdqAghsZec1JoUnfySUzcy `, }, Arguments: []cmds.Argument{ cmds.StringArg("domain-name", true, false, "The domain-name name to resolve.").EnableStdin(), }, Options: []cmds.Option{ cmds.BoolOption("recursive", "r", "Resolve until the result is not a DNS link"), }, Run: func(req cmds.Request, res cmds.Response) { recursive, _, _ := req.Option("recursive").Bool() name := req.Arguments()[0] resolver := namesys.NewDNSResolver() depth := 1 if recursive { depth = namesys.DefaultDepthLimit } output, err := resolver.ResolveN(req.Context(), name, depth) if err != nil { res.SetError(err, cmds.ErrNormal) return } res.SetOutput(&ResolvedPath{output}) }, Marshalers: cmds.MarshalerMap{ cmds.Text: func(res cmds.Response) (io.Reader, error) { output, ok := res.Output().(*ResolvedPath) if !ok { return nil, util.ErrCast() } return strings.NewReader(output.Path.String()), nil }, }, Type: ResolvedPath{}, }
var DefaultDiagnosticTimeout = time.Second * 20
var DhtCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Issue commands directly through the DHT", ShortDescription: ``, }, Subcommands: map[string]*cmds.Command{ "query": queryDhtCmd, "findprovs": findProvidersDhtCmd, "findpeer": findPeerDhtCmd, "get": getValueDhtCmd, "put": putValueDhtCmd, }, }
var DiagCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Generates diagnostic reports", }, Subcommands: map[string]*cmds.Command{ "net": diagNetCmd, }, }
var ErrDepthLimitExceeded = fmt.Errorf("depth limit exceeded")
Error indicating the max depth has been exceded.
var ErrEmptyNode = errors.New("no data or links in this node")
ErrEmptyNode is returned when the input to 'ipfs object put' contains no data
var ErrInvalidCompressionLevel = errors.New("Compression level must be between 1 and 9")
var ErrNotDHT = errors.New("routing service is not a DHT")
var ErrObjectTooLarge = errors.New("input object was too large. limit is 512kbytes")
ErrObjectTooLarge is returned when too much data was read from stdin. current limit 512k
var ErrUnknownObjectEnc = errors.New("unknown object encoding")
ErrUnknownObjectEnc is returned if a invalid encoding is supplied
var GetCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Download IPFS objects", ShortDescription: ` Retrieves the object named by <ipfs-or-ipns-path> and stores the data to disk. By default, the output will be stored at ./<ipfs-path>, but an alternate path can be specified with '--output=<path>' or '-o=<path>'. To output a TAR archive instead of unpacked files, use '--archive' or '-a'. To compress the output with GZIP compression, use '--compress' or '-C'. You may also specify the level of compression by specifying '-l=<1-9>'. `, }, Arguments: []cmds.Argument{ cmds.StringArg("ipfs-path", true, false, "The path to the IPFS object(s) to be outputted").EnableStdin(), }, Options: []cmds.Option{ cmds.StringOption("output", "o", "The path where output should be stored"), cmds.BoolOption("archive", "a", "Output a TAR archive"), cmds.BoolOption("compress", "C", "Compress the output with GZIP compression"), cmds.IntOption("compression-level", "l", "The level of compression (1-9)"), }, PreRun: func(req cmds.Request) error { _, err := getCompressOptions(req) return err }, Run: func(req cmds.Request, res cmds.Response) { cmplvl, err := getCompressOptions(req) if err != nil { res.SetError(err, cmds.ErrClient) return } node, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } p := path.Path(req.Arguments()[0]) ctx := req.Context() dn, err := core.Resolve(ctx, node, p) if err != nil { res.SetError(err, cmds.ErrNormal) return } archive, _, _ := req.Option("archive").Bool() reader, err := uarchive.DagArchive(ctx, dn, p.String(), node.DAG, archive, cmplvl) if err != nil { res.SetError(err, cmds.ErrNormal) return } res.SetOutput(reader) }, PostRun: func(req cmds.Request, res cmds.Response) { if res.Output() == nil { return } outReader := res.Output().(io.Reader) res.SetOutput(nil) outPath, _, _ := req.Option("output").String() if len(outPath) == 0 { _, outPath = gopath.Split(req.Arguments()[0]) outPath = gopath.Clean(outPath) } cmplvl, err := getCompressOptions(req) if err != nil { res.SetError(err, cmds.ErrClient) return } archive, _, _ := req.Option("archive").Bool() gw := getWriter{ Out: os.Stdout, Err: os.Stderr, Archive: archive, Compression: cmplvl, } if err := gw.Write(outReader, outPath); err != nil { res.SetError(err, cmds.ErrNormal) return } }, }
var IDCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Show IPFS Node ID info", ShortDescription: ` Prints out information about the specified peer, if no peer is specified, prints out local peers info. ipfs id supports the format option for output with the following keys: <id> : the peers id <aver>: agent version <pver>: protocol version <pubkey>: public key <addrs>: addresses (newline delimited) `, }, Arguments: []cmds.Argument{ cmds.StringArg("peerid", false, false, "peer.ID of node to look up").EnableStdin(), }, Options: []cmds.Option{ cmds.StringOption("f", "format", "optional output format"), }, Run: func(req cmds.Request, res cmds.Response) { node, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } if len(req.Arguments()) == 0 { output, err := printSelf(node) if err != nil { res.SetError(err, cmds.ErrNormal) return } res.SetOutput(output) return } pid := req.Arguments()[0] id := peer.ID(b58.Decode(pid)) if len(id) == 0 { res.SetError(cmds.ClientError("Invalid peer id"), cmds.ErrClient) return } if !node.OnlineMode() { res.SetError(errors.New(offlineIdErrorMessage), cmds.ErrClient) return } p, err := node.Routing.FindPeer(req.Context(), id) if err == kb.ErrLookupFailure { res.SetError(errors.New(offlineIdErrorMessage), cmds.ErrClient) return } if err != nil { res.SetError(err, cmds.ErrNormal) return } output, err := printPeer(node.Peerstore, p.ID) if err != nil { res.SetError(err, cmds.ErrNormal) return } res.SetOutput(output) }, Marshalers: cmds.MarshalerMap{ cmds.Text: func(res cmds.Response) (io.Reader, error) { val, ok := res.Output().(*IdOutput) if !ok { return nil, u.ErrCast() } format, found, err := res.Request().Option("format").String() if err != nil { return nil, err } if found { output := format output = strings.Replace(output, "<id>", val.ID, -1) output = strings.Replace(output, "<aver>", val.AgentVersion, -1) output = strings.Replace(output, "<pver>", val.ProtocolVersion, -1) output = strings.Replace(output, "<pubkey>", val.PublicKey, -1) output = strings.Replace(output, "<addrs>", strings.Join(val.Addresses, "\n"), -1) output = strings.Replace(output, "\\n", "\n", -1) output = strings.Replace(output, "\\t", "\t", -1) return strings.NewReader(output), nil } else { marshaled, err := json.MarshalIndent(val, "", "\t") if err != nil { return nil, err } return bytes.NewReader(marshaled), nil } }, }, Type: IdOutput{}, }
var IpnsCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Gets the value currently published at an IPNS name", ShortDescription: ` IPNS is a PKI namespace, where names are the hashes of public keys, and the private key enables publishing new (signed) values. In resolve, the default value of <name> is your own identity public key. `, LongDescription: ` IPNS is a PKI namespace, where names are the hashes of public keys, and the private key enables publishing new (signed) values. In resolve, the default value of <name> is your own identity public key. Examples: Resolve the value of your identity: > ipfs name resolve QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy Resolve the value of another name: > ipfs name resolve QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy `, }, Arguments: []cmds.Argument{ cmds.StringArg("name", false, false, "The IPNS name to resolve. Defaults to your node's peerID.").EnableStdin(), }, Options: []cmds.Option{ cmds.BoolOption("recursive", "r", "Resolve until the result is not an IPNS name"), }, Run: func(req cmds.Request, res cmds.Response) { n, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } if !n.OnlineMode() { err := n.SetupOfflineRouting() if err != nil { res.SetError(err, cmds.ErrNormal) return } } var name string if len(req.Arguments()) == 0 { if n.Identity == "" { res.SetError(errors.New("Identity not loaded!"), cmds.ErrNormal) return } name = n.Identity.Pretty() } else { name = req.Arguments()[0] } recursive, _, _ := req.Option("recursive").Bool() depth := 1 if recursive { depth = namesys.DefaultDepthLimit } resolver := namesys.NewRoutingResolver(n.Routing) output, err := resolver.ResolveN(req.Context(), name, depth) if err != nil { res.SetError(err, cmds.ErrNormal) return } res.SetOutput(&ResolvedPath{output}) }, Marshalers: cmds.MarshalerMap{ cmds.Text: func(res cmds.Response) (io.Reader, error) { output, ok := res.Output().(*ResolvedPath) if !ok { return nil, u.ErrCast() } return strings.NewReader(output.Path.String()), nil }, }, Type: ResolvedPath{}, }
var LogCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Interact with the daemon log output", ShortDescription: ` 'ipfs log' contains utility commands to affect or read the logging output of a running daemon. `, }, Subcommands: map[string]*cmds.Command{ "level": logLevelCmd, "tail": logTailCmd, }, }
var LsCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "List links from an object.", ShortDescription: ` Retrieves the object named by <ipfs-or-ipns-path> and displays the links it contains, with the following format: <link base58 hash> <link size in bytes> <link name> `, }, Arguments: []cmds.Argument{ cmds.StringArg("ipfs-path", true, true, "The path to the IPFS object(s) to list links from").EnableStdin(), }, Options: []cmds.Option{ cmds.BoolOption("headers", "", "Print table headers (Hash, Name, Size)"), }, Run: func(req cmds.Request, res cmds.Response) { node, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } if _, _, err := req.Option("headers").Bool(); err != nil { res.SetError(err, cmds.ErrNormal) return } paths := req.Arguments() var dagnodes []*merkledag.Node for _, fpath := range paths { dagnode, err := core.Resolve(req.Context(), node, path.Path(fpath)) if err != nil { res.SetError(err, cmds.ErrNormal) return } dagnodes = append(dagnodes, dagnode) } output := make([]LsObject, len(req.Arguments())) for i, dagnode := range dagnodes { output[i] = LsObject{ Hash: paths[i], Links: make([]LsLink, len(dagnode.Links)), } for j, link := range dagnode.Links { link.Node, err = link.GetNode(req.Context(), node.DAG) if err != nil { res.SetError(err, cmds.ErrNormal) return } d, err := unixfs.FromBytes(link.Node.Data) if err != nil { res.SetError(err, cmds.ErrNormal) return } output[i].Links[j] = LsLink{ Name: link.Name, Hash: link.Hash.B58String(), Size: link.Size, Type: d.GetType(), } } } res.SetOutput(&LsOutput{output}) }, Marshalers: cmds.MarshalerMap{ cmds.Text: func(res cmds.Response) (io.Reader, error) { headers, _, _ := res.Request().Option("headers").Bool() output := res.Output().(*LsOutput) buf := new(bytes.Buffer) w := tabwriter.NewWriter(buf, 1, 2, 1, ' ', 0) for _, object := range output.Objects { if len(output.Objects) > 1 { fmt.Fprintf(w, "%s:\n", object.Hash) } if headers { fmt.Fprintln(w, "Hash\tSize\tName") } for _, link := range object.Links { if link.Type == unixfspb.Data_Directory { link.Name += "/" } fmt.Fprintf(w, "%s\t%v\t%s\n", link.Hash, link.Size, link.Name) } if len(output.Objects) > 1 { fmt.Fprintln(w) } } w.Flush() return buf, nil }, }, Type: LsOutput{}, }
var MountCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Mounts IPFS to the filesystem (read-only)", Synopsis: ` ipfs mount [-f <ipfs mount path>] [-n <ipns mount path>] `, ShortDescription: ` Mount ipfs at a read-only mountpoint on the OS (default: /ipfs and /ipns). All ipfs objects will be accessible under that directory. Note that the root will not be listable, as it is virtual. Access known paths directly. You may have to create /ipfs and /ipns before using 'ipfs mount': > sudo mkdir /ipfs /ipns > sudo chown ` + "`" + `whoami` + "`" + ` /ipfs /ipns > ipfs daemon & > ipfs mount `, LongDescription: ` Mount ipfs at a read-only mountpoint on the OS (default: /ipfs and /ipns). All ipfs objects will be accessible under that directory. Note that the root will not be listable, as it is virtual. Access known paths directly. You may have to create /ipfs and /ipns before using 'ipfs mount': > sudo mkdir /ipfs /ipns > sudo chown ` + "`" + `whoami` + "`" + ` /ipfs /ipns > ipfs daemon & > ipfs mount EXAMPLE: # setup > mkdir foo > echo "baz" > foo/bar > ipfs add -r foo added QmWLdkp93sNxGRjnFHPaYg8tCQ35NBY3XPn6KiETd3Z4WR foo/bar added QmSh5e7S6fdcu75LAbXNZAFY2nGyZUJXyLCJDvn2zRkWyC foo > ipfs ls QmSh5e7S6fdcu75LAbXNZAFY2nGyZUJXyLCJDvn2zRkWyC QmWLdkp93sNxGRjnFHPaYg8tCQ35NBY3XPn6KiETd3Z4WR 12 bar > ipfs cat QmWLdkp93sNxGRjnFHPaYg8tCQ35NBY3XPn6KiETd3Z4WR baz # mount > ipfs daemon & > ipfs mount IPFS mounted at: /ipfs IPNS mounted at: /ipns > cd /ipfs/QmSh5e7S6fdcu75LAbXNZAFY2nGyZUJXyLCJDvn2zRkWyC > ls bar > cat bar baz > cat /ipfs/QmSh5e7S6fdcu75LAbXNZAFY2nGyZUJXyLCJDvn2zRkWyC/bar baz > cat /ipfs/QmWLdkp93sNxGRjnFHPaYg8tCQ35NBY3XPn6KiETd3Z4WR baz `, }, Options: []cmds.Option{ cmds.StringOption("ipfs-path", "f", "The path where IPFS should be mounted"), cmds.StringOption("ipns-path", "n", "The path where IPNS should be mounted"), }, Run: func(req cmds.Request, res cmds.Response) { cfg, err := req.InvocContext().GetConfig() if err != nil { res.SetError(err, cmds.ErrNormal) return } node, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } if !node.OnlineMode() { res.SetError(errNotOnline, cmds.ErrClient) return } fsdir, found, err := req.Option("f").String() if err != nil { res.SetError(err, cmds.ErrNormal) return } if !found { fsdir = cfg.Mounts.IPFS } nsdir, found, err := req.Option("n").String() if err != nil { res.SetError(err, cmds.ErrNormal) return } if !found { nsdir = cfg.Mounts.IPNS } err = Mount(node, fsdir, nsdir) if err != nil { res.SetError(err, cmds.ErrNormal) return } var output config.Mounts output.IPFS = fsdir output.IPNS = nsdir res.SetOutput(&output) }, Type: config.Mounts{}, Marshalers: cmds.MarshalerMap{ cmds.Text: func(res cmds.Response) (io.Reader, error) { v := res.Output().(*config.Mounts) s := fmt.Sprintf("IPFS mounted at: %s\n", v.IPFS) s += fmt.Sprintf("IPNS mounted at: %s\n", v.IPNS) return strings.NewReader(s), nil }, }, }
var NameCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "IPFS namespace (IPNS) tool", Synopsis: ` ipfs name publish [<name>] <ipfs-path> - Publish an object to IPNS ipfs name resolve [<name>] - Gets the value currently published at an IPNS name `, ShortDescription: ` IPNS is a PKI namespace, where names are the hashes of public keys, and the private key enables publishing new (signed) values. In both publish and resolve, the default value of <name> is your own identity public key. `, LongDescription: ` IPNS is a PKI namespace, where names are the hashes of public keys, and the private key enables publishing new (signed) values. In both publish and resolve, the default value of <name> is your own identity public key. Examples: Publish an <ipfs-path> to your identity name: > ipfs name publish /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy Published to QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n: /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy Publish an <ipfs-path> to another public key: > ipfs name publish /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n Published to QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n: /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy Resolve the value of your identity: > ipfs name resolve /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy Resolve the value of another name: > ipfs name resolve QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy `, }, Subcommands: map[string]*cmds.Command{ "publish": PublishCmd, "resolve": IpnsCmd, }, }
var ObjectCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Interact with ipfs objects", ShortDescription: ` 'ipfs object' is a plumbing command used to manipulate DAG objects directly.`, Synopsis: ` ipfs object get <key> - Get the DAG node named by <key> ipfs object put <data> - Stores input, outputs its key ipfs object data <key> - Outputs raw bytes in an object ipfs object links <key> - Outputs links pointed to by object ipfs object stat <key> - Outputs statistics of object ipfs object new <template> - Create new ipfs objects ipfs object patch <args> - Create new object from old ones `, }, Subcommands: map[string]*cmds.Command{ "data": objectDataCmd, "links": objectLinksCmd, "get": objectGetCmd, "put": objectPutCmd, "stat": objectStatCmd, "new": objectNewCmd, "patch": objectPatchCmd, }, }
var PinCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Pin (and unpin) objects to local storage", }, Subcommands: map[string]*cmds.Command{ "add": addPinCmd, "rm": rmPinCmd, "ls": listPinCmd, }, }
var PingCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "send echo request packets to IPFS hosts", Synopsis: ` Send pings to a peer using the routing system to discover its address `, ShortDescription: ` ipfs ping is a tool to test sending data to other nodes. It finds nodes via the routing system, send pings, wait for pongs, and print out round- trip latency information. `, }, Arguments: []cmds.Argument{ cmds.StringArg("peer ID", true, true, "ID of peer to be pinged").EnableStdin(), }, Options: []cmds.Option{ cmds.IntOption("count", "n", "number of ping messages to send"), }, Marshalers: cmds.MarshalerMap{ cmds.Text: func(res cmds.Response) (io.Reader, error) { outChan, ok := res.Output().(<-chan interface{}) if !ok { fmt.Println(reflect.TypeOf(res.Output())) return nil, u.ErrCast() } marshal := func(v interface{}) (io.Reader, error) { obj, ok := v.(*PingResult) if !ok { return nil, u.ErrCast() } buf := new(bytes.Buffer) if len(obj.Text) > 0 { buf = bytes.NewBufferString(obj.Text + "\n") } else if obj.Success { fmt.Fprintf(buf, "Pong received: time=%.2f ms\n", obj.Time.Seconds()*1000) } else { fmt.Fprintf(buf, "Pong failed\n") } return buf, nil } return &cmds.ChannelMarshaler{ Channel: outChan, Marshaler: marshal, Res: res, }, nil }, }, Run: func(req cmds.Request, res cmds.Response) { ctx := req.Context() n, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } if !n.OnlineMode() { res.SetError(errNotOnline, cmds.ErrClient) return } addr, peerID, err := ParsePeerParam(req.Arguments()[0]) if err != nil { res.SetError(err, cmds.ErrNormal) return } if addr != nil { n.Peerstore.AddAddr(peerID, addr, peer.TempAddrTTL) } numPings := 10 val, found, err := req.Option("count").Int() if err != nil { res.SetError(err, cmds.ErrNormal) return } if found { numPings = val } outChan := pingPeer(ctx, n, peerID, numPings) res.SetOutput(outChan) }, Type: PingResult{}, }
var PublishCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Publish an object to IPNS", ShortDescription: ` IPNS is a PKI namespace, where names are the hashes of public keys, and the private key enables publishing new (signed) values. In publish, the default value of <name> is your own identity public key. `, LongDescription: ` IPNS is a PKI namespace, where names are the hashes of public keys, and the private key enables publishing new (signed) values. In publish, the default value of <name> is your own identity public key. Examples: Publish an <ipfs-path> to your identity name: > ipfs name publish /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy Published to QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n: /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy Publish an <ipfs-path> to another public key (not implemented): > ipfs name publish /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n Published to QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n: /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy `, }, Arguments: []cmds.Argument{ cmds.StringArg("name", false, false, "The IPNS name to publish to. Defaults to your node's peerID"), cmds.StringArg("ipfs-path", true, false, "IPFS path of the obejct to be published at <name>").EnableStdin(), }, Run: func(req cmds.Request, res cmds.Response) { log.Debug("Begin Publish") n, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } if !n.OnlineMode() { err := n.SetupOfflineRouting() if err != nil { res.SetError(err, cmds.ErrNormal) return } } args := req.Arguments() if n.Identity == "" { res.SetError(errors.New("Identity not loaded!"), cmds.ErrNormal) return } var name string var pstr string switch len(args) { case 2: name = args[0] pstr = args[1] if name != n.Identity.Pretty() { res.SetError(errors.New("keychains not yet implemented"), cmds.ErrNormal) return } case 1: pstr = args[0] } output, err := publish(req.Context(), n, n.PrivateKey, path.Path(pstr)) if err != nil { res.SetError(err, cmds.ErrNormal) return } res.SetOutput(output) }, Marshalers: cmds.MarshalerMap{ cmds.Text: func(res cmds.Response) (io.Reader, error) { v := res.Output().(*IpnsEntry) s := fmt.Sprintf("Published to %s: %s\n", v.Name, v.Value) return strings.NewReader(s), nil }, }, Type: IpnsEntry{}, }
var RefsCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Lists links (references) from an object", ShortDescription: ` Retrieves the object named by <ipfs-path> and displays the link hashes it contains, with the following format: <link base58 hash> Note: list all refs recursively with -r. `, }, Subcommands: map[string]*cmds.Command{ "local": RefsLocalCmd, }, Arguments: []cmds.Argument{ cmds.StringArg("ipfs-path", true, true, "Path to the object(s) to list refs from").EnableStdin(), }, Options: []cmds.Option{ cmds.StringOption("format", "Emit edges with given format. tokens: <src> <dst> <linkname>"), cmds.BoolOption("edges", "e", "Emit edge format: `<from> -> <to>`"), cmds.BoolOption("unique", "u", "Omit duplicate refs from output"), cmds.BoolOption("recursive", "r", "Recursively list links of child nodes"), }, Run: func(req cmds.Request, res cmds.Response) { ctx := req.Context() n, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } unique, _, err := req.Option("unique").Bool() if err != nil { res.SetError(err, cmds.ErrNormal) return } recursive, _, err := req.Option("recursive").Bool() if err != nil { res.SetError(err, cmds.ErrNormal) return } edges, _, err := req.Option("edges").Bool() if err != nil { res.SetError(err, cmds.ErrNormal) return } format, _, err := req.Option("format").String() if err != nil { res.SetError(err, cmds.ErrNormal) return } objs, err := objectsForPaths(ctx, n, req.Arguments()) if err != nil { res.SetError(err, cmds.ErrNormal) return } out := make(chan interface{}) res.SetOutput((<-chan interface{})(out)) go func() { defer close(out) rw := RefWriter{ out: out, DAG: n.DAG, Ctx: ctx, Unique: unique, PrintEdge: edges, PrintFmt: format, Recursive: recursive, } for _, o := range objs { if _, err := rw.WriteRefs(o); err != nil { out <- &RefWrapper{Err: err.Error()} return } } }() }, Marshalers: cmds.MarshalerMap{ cmds.Text: func(res cmds.Response) (io.Reader, error) { outChan, ok := res.Output().(<-chan interface{}) if !ok { return nil, u.ErrCast() } marshal := func(v interface{}) (io.Reader, error) { obj, ok := v.(*RefWrapper) if !ok { fmt.Println("%#v", v) return nil, u.ErrCast() } if obj.Err != "" { return nil, errors.New(obj.Err) } return strings.NewReader(obj.Ref + "\n"), nil } return &cmds.ChannelMarshaler{ Channel: outChan, Marshaler: marshal, Res: res, }, nil }, }, Type: RefWrapper{}, }
var RefsLocalCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Lists all local references", ShortDescription: ` Displays the hashes of all local objects. `, }, Run: func(req cmds.Request, res cmds.Response) { ctx := req.Context() n, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } allKeys, err := n.Blockstore.AllKeysChan(ctx) if err != nil { res.SetError(err, cmds.ErrNormal) return } piper, pipew := io.Pipe() go func() { defer pipew.Close() for k := range allKeys { s := k.Pretty() + "\n" if _, err := pipew.Write([]byte(s)); err != nil { log.Error("pipe write error: ", err) return } } }() res.SetOutput(piper) }, }
var RefsROCmd = &cmds.Command{}
var RepoCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Manipulate the IPFS repo", ShortDescription: ` 'ipfs repo' is a plumbing command used to manipulate the repo. `, }, Subcommands: map[string]*cmds.Command{ "gc": repoGcCmd, }, }
var ResolveCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Resolve the value of names to IPFS", ShortDescription: ` There are a number of mutable name protocols that can link among themselves and into IPNS. This command accepts any of these identifiers and resolves them to the referenced item. `, LongDescription: ` There are a number of mutable name protocols that can link among themselves and into IPNS. For example IPNS references can (currently) point at IPFS object, and DNS links can point at other DNS links, IPNS entries, or IPFS objects. This command accepts any of these identifiers and resolves them to the referenced item. Examples: Resolve the value of your identity: > ipfs resolve /ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy /ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj Resolve the value of another name: > ipfs resolve /ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n /ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy Resolve the value of another name recursively: > ipfs resolve -r /ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n /ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj `, }, Arguments: []cmds.Argument{ cmds.StringArg("name", true, false, "The name to resolve.").EnableStdin(), }, Options: []cmds.Option{ cmds.BoolOption("recursive", "r", "Resolve until the result is an IPFS name"), }, Run: func(req cmds.Request, res cmds.Response) { n, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } if !n.OnlineMode() { err := n.SetupOfflineRouting() if err != nil { res.SetError(err, cmds.ErrNormal) return } } name := req.Arguments()[0] recursive, _, _ := req.Option("recursive").Bool() depth := 1 if recursive { depth = namesys.DefaultDepthLimit } output, err := n.Namesys.ResolveN(req.Context(), name, depth) if err != nil { res.SetError(err, cmds.ErrNormal) return } res.SetOutput(&ResolvedPath{output}) }, Marshalers: cmds.MarshalerMap{ cmds.Text: func(res cmds.Response) (io.Reader, error) { output, ok := res.Output().(*ResolvedPath) if !ok { return nil, u.ErrCast() } return strings.NewReader(output.Path.String()), nil }, }, Type: ResolvedPath{}, }
var Root = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "global p2p merkle-dag filesystem", Synopsis: ` ipfs [<flags>] <command> [<arg>] ... `, ShortDescription: ` BASIC COMMANDS init Initialize ipfs local configuration add <path> Add an object to ipfs cat <ref> Show ipfs object data get <ref> Download ipfs objects ls <ref> List links from an object refs <ref> List hashes of links from an object DATA STRUCTURE COMMANDS block Interact with raw blocks in the datastore object Interact with raw dag nodes file Interact with Unix filesystem objects ADVANCED COMMANDS daemon Start a long-running daemon process mount Mount an ipfs read-only mountpoint resolve Resolve any type of name name Publish or resolve IPNS names dns Resolve DNS links pin Pin objects to local storage repo gc Garbage collect unpinned objects NETWORK COMMANDS id Show info about ipfs peers bootstrap Add or remove bootstrap peers swarm Manage connections to the p2p network dht Query the dht for values or peers ping Measure the latency of a connection diag Print diagnostics TOOL COMMANDS config Manage configuration version Show ipfs version information update Download and apply go-ipfs updates commands List all available commands Use 'ipfs <command> --help' to learn more about each command. `, }, Options: []cmds.Option{ cmds.StringOption("config", "c", "Path to the configuration file to use"), cmds.BoolOption("debug", "D", "Operate in debug mode"), cmds.BoolOption("help", "Show the full command help text"), cmds.BoolOption("h", "Show a short version of the command help text"), cmds.BoolOption("local", "L", "Run the command locally, instead of using the daemon"), cmds.StringOption(ApiOption, "Overrides the routing option (dht, supernode)"), }, }
var RootRO = &cmds.Command{}
RootRO is the readonly version of Root
var StatsCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Query IPFS statistics", ShortDescription: ``, }, Subcommands: map[string]*cmds.Command{ "bw": statBwCmd, }, }
var SwarmCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "swarm inspection tool", Synopsis: ` ipfs swarm peers - List peers with open connections ipfs swarm addrs - List known addresses. Useful to debug. ipfs swarm connect <address> - Open connection to a given address ipfs swarm disconnect <address> - Close connection to a given address ipfs swarm filters - Manipulate filters addresses `, ShortDescription: ` ipfs swarm is a tool to manipulate the network swarm. The swarm is the component that opens, listens for, and maintains connections to other ipfs peers in the internet. `, }, Subcommands: map[string]*cmds.Command{ "peers": swarmPeersCmd, "addrs": swarmAddrsCmd, "connect": swarmConnectCmd, "disconnect": swarmDisconnectCmd, "filters": swarmFiltersCmd, }, }
var TarCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "utility functions for tar files in ipfs", }, Subcommands: map[string]*cmds.Command{ "add": tarAddCmd, "cat": tarCatCmd, }, }
var UpdateCheckCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Checks if updates are available", ShortDescription: "'ipfs update check' checks if any updates are available for IPFS.\nNothing will be downloaded or installed.", }, Run: func(req cmds.Request, res cmds.Response) { n, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } output, err := updateCheck(n) if err != nil { res.SetError(err, cmds.ErrNormal) return } res.SetOutput(output) }, Type: UpdateOutput{}, Marshalers: cmds.MarshalerMap{ cmds.Text: func(res cmds.Response) (io.Reader, error) { v := res.Output().(*UpdateOutput) buf := new(bytes.Buffer) if v.NewVersion != v.OldVersion { buf.WriteString(fmt.Sprintf("A new version of IPFS is available ('%s', currently running '%s')\n", v.NewVersion, v.OldVersion)) } else { buf.WriteString(fmt.Sprintf("Already updated to latest version ('%s')\n", v.NewVersion)) } return buf, nil }, }, }
var UpdateCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Downloads and installs updates for IPFS (disabled)", ShortDescription: `ipfs update is disabled until we can deploy the binaries to you over ipfs itself. please use 'go get -u github.com/ipfs/go-ipfs/cmd/ipfs' until then.`, }, }
var UpdateLogCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "List the changelog for the latest versions of IPFS", ShortDescription: "This command is not yet implemented.", }, Run: func(req cmds.Request, res cmds.Response) { n, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } output, err := updateLog(n) if err != nil { res.SetError(err, cmds.ErrNormal) return } res.SetOutput(output) }, }
var VersionCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Shows ipfs version information", ShortDescription: "Returns the current version of ipfs and exits.", }, Options: []cmds.Option{ cmds.BoolOption("number", "n", "Only show the version number"), }, Run: func(req cmds.Request, res cmds.Response) { res.SetOutput(&VersionOutput{ Version: config.CurrentVersionNumber, }) }, Marshalers: cmds.MarshalerMap{ cmds.Text: func(res cmds.Response) (io.Reader, error) { v := res.Output().(*VersionOutput) number, found, err := res.Request().Option("number").Bool() if err != nil { return nil, err } if found && number { return strings.NewReader(fmt.Sprintln(v.Version)), nil } return strings.NewReader(fmt.Sprintf("ipfs version %s\n", v.Version)), nil }, }, Type: VersionOutput{}, }
Functions ¶
func CommandsCmd ¶
CommandsCmd takes in a root command, and returns a command that lists the subcommands in that root
func KeyListTextMarshaler ¶
KeyListTextMarshaler outputs a KeyList as plaintext, one key per line
func NewMemoryDagService ¶ added in v0.3.8
func NewMemoryDagService() dag.DAGService
Types ¶
type AddedObject ¶
type BootstrapOutput ¶
type BootstrapOutput struct {
Peers []string
}
type ConfigField ¶
type ConfigField struct { Key string Value interface{} }
type DiagnosticConnection ¶
type DiagnosticOutput ¶
type DiagnosticOutput struct {
Peers []DiagnosticPeer
}
type DiagnosticPeer ¶
type DiagnosticPeer struct { ID string UptimeSeconds uint64 BandwidthBytesIn uint64 BandwidthBytesOut uint64 Connections []DiagnosticConnection }
type LsLink ¶ added in v0.3.2
type LsLink struct {
Name, Hash string
Size uint64
Type unixfspb.Data_DataType
}
type MessageOutput ¶
type MessageOutput struct {
Message string
}
type RefKeyList ¶ added in v0.3.2
type RefKeyList struct {
Keys map[string]RefKeyObject
}
type RefKeyObject ¶ added in v0.3.4
type RefWrapper ¶ added in v0.3.5
type RefWriter ¶
type RefWriter struct { DAG dag.DAGService Ctx context.Context Unique bool Recursive bool PrintEdge bool PrintFmt string // contains filtered or unexported fields }
type ResolvedPath ¶ added in v0.3.3
type TestOutput ¶
type UpdateOutput ¶
type VersionOutput ¶
type VersionOutput struct {
Version string
}
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package incfusever is only here to prevent go src tools (like godep) from thinking fuseversion is not a required package.
|
Package incfusever is only here to prevent go src tools (like godep) from thinking fuseversion is not a required package. |