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 using IPFS from outside of the Go language.
Index ¶
- Constants
- Variables
- func CommandsCmd(root *cmds.Command) *cmds.Command
- func ExternalBinary() *cmds.Command
- func KeyListTextMarshaler(res cmds.Response) (io.Reader, error)
- func MessageTextMarshaler(res cmds.Response) (io.Reader, error)
- func ParsePeerParam(text string) (ma.Multiaddr, peer.ID, error)
- type BlockStat
- type BootstrapOutput
- type Command
- type ConfigField
- type DiagnosticConnection
- type DiagnosticOutput
- type DiagnosticPeer
- type IdOutput
- type IpnsEntry
- type KeyList
- type LsLink
- type LsObject
- type LsOutput
- type MessageOutput
- type Option
- type PinOutput
- type PingResult
- type RefKeyList
- type RefKeyObject
- type RefWrapper
- type RefWriter
- type RepoVersion
- type ResolvedPath
- type VerifyProgress
- type VersionOutput
Constants ¶
View Source
const (
ApiOption = "api"
)
Variables ¶
View Source
var ActiveReqsCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "List commands run on this ipfs node.",
ShortDescription: `
Lists running and recently run commands.
`,
},
Run: func(req cmds.Request, res cmds.Response) {
res.SetOutput(req.InvocContext().ReqLog.Report())
},
Options: []cmds.Option{
cmds.BoolOption("verbose", "v", "Print extra information.").Default(false),
},
Subcommands: map[string]*cmds.Command{
"clear": clearInactiveCmd,
"set-time": setRequestClearCmd,
},
Marshalers: map[cmds.EncodingType]cmds.Marshaler{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
out, ok := res.Output().(*[]*cmds.ReqLogEntry)
if !ok {
log.Errorf("%#v", res.Output())
return nil, cmds.ErrIncorrectType
}
buf := new(bytes.Buffer)
verbose, _, _ := res.Request().Option("v").Bool()
w := tabwriter.NewWriter(buf, 4, 4, 2, ' ', 0)
if verbose {
fmt.Fprint(w, "ID\t")
}
fmt.Fprint(w, "Command\t")
if verbose {
fmt.Fprint(w, "Arguments\tOptions\t")
}
fmt.Fprintln(w, "Active\tStartTime\tRunTime")
for _, req := range *out {
if verbose {
fmt.Fprintf(w, "%d\t", req.ID)
}
fmt.Fprintf(w, "%s\t", req.Command)
if verbose {
fmt.Fprintf(w, "%v\t[", req.Args)
var keys []string
for k, _ := range req.Options {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
fmt.Fprintf(w, "%s=%v,", k, req.Options[k])
}
fmt.Fprintf(w, "]\t")
}
var live time.Duration
if req.Active {
live = time.Now().Sub(req.StartTime)
} else {
live = req.EndTime.Sub(req.StartTime)
}
t := req.StartTime.Format(time.Stamp)
fmt.Fprintf(w, "%t\t%s\t%s\n", req.Active, t, live)
}
w.Flush()
return buf, nil
},
},
Type: []*cmds.ReqLogEntry{},
}
View Source
var AddCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Add a file 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.
`,
LongDescription: `
Adds contents of <path> to ipfs. Use -r to add directories.
Note that directories are added recursively, to form the ipfs
MerkleDAG.
The wrap option, '-w', wraps the file (or files, if using the
recursive option) in a directory. This directory contains only
the files which have been added, and means that the file retains
its filename. For example:
> ipfs add example.jpg
added QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH example.jpg
> ipfs add example.jpg -w
added QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH example.jpg
added QmaG4FuMqEBnQNn3C8XJ5bpW8kLs7zq2ZXgHptJHbKDDVx
You can now refer to the added file in a gateway, like so:
/ipfs/QmaG4FuMqEBnQNn3C8XJ5bpW8kLs7zq2ZXgHptJHbKDDVx/example.jpg
`,
},
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.").Default(false),
cmds.BoolOption(silentOptionName, "Write no output.").Default(false),
cmds.BoolOption(progressOptionName, "p", "Stream progress data."),
cmds.BoolOption(trickleOptionName, "t", "Use trickle-dag format for dag generation.").Default(false),
cmds.BoolOption(onlyHashOptionName, "n", "Only chunk and hash - do not write to disk.").Default(false),
cmds.BoolOption(wrapOptionName, "w", "Wrap files with a directory object.").Default(false),
cmds.BoolOption(hiddenOptionName, "H", "Include files that are hidden. Only takes effect on recursive add.").Default(false),
cmds.StringOption(chunkerOptionName, "s", "Chunking algorithm to use."),
cmds.BoolOption(pinOptionName, "Pin this object when adding.").Default(true),
},
PreRun: func(req cmds.Request) error {
if quiet, _, _ := req.Option(quietOptionName).Bool(); quiet {
return nil
}
_, found, _ := req.Option(progressOptionName).Bool()
if !found {
req.SetOption(progressOptionName, true)
}
sizeFile, ok := req.Files().(files.SizeFile)
if !ok {
log.Warning("cannnot determine size of input file")
return nil
}
sizeCh := make(chan int64, 1)
req.Values()["size"] = sizeCh
go func() {
size, err := sizeFile.Size()
if err != nil {
log.Warningf("error getting files size: %s", err)
return
}
log.Debugf("Total size of file being added: %v\n", size)
sizeCh <- 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()
silent, _, _ := req.Option(silentOptionName).Bool()
chunker, _, _ := req.Option(chunkerOptionName).String()
dopin, _, _ := req.Option(pinOptionName).Bool()
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, err := coreunix.NewAdder(req.Context(), n.Pinning, n.Blockstore, n.DAG)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
fileAdder.Out = outChan
fileAdder.Chunker = chunker
fileAdder.Progress = progress
fileAdder.Hidden = hidden
fileAdder.Trickle = trickle
fileAdder.Wrap = wrap
fileAdder.Pin = dopin
fileAdder.Silent = silent
if hash {
md := dagtest.Mock()
mr, err := mfs.NewRoot(req.Context(), md, ft.EmptyDirNode(), nil)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
fileAdder.SetMfsRoot(mr)
}
addAllAndPin := func(f files.File) error {
for {
file, err := f.NextFile()
if err == io.EOF {
break
} else if err != nil {
return err
}
if err := fileAdder.AddFile(file); err != nil {
return err
}
}
_, err := fileAdder.Finalize()
if err != nil {
return err
}
if hash {
return nil
}
return fileAdder.PinRoot()
}
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
}
progress, _, err := req.Option(progressOptionName).Bool()
if err != nil {
res.SetError(u.ErrCast(), cmds.ErrNormal)
return
}
silent, _, err := req.Option(silentOptionName).Bool()
if err != nil {
res.SetError(u.ErrCast(), cmds.ErrNormal)
return
}
if !quiet && !silent {
progress = true
}
var bar *pb.ProgressBar
if progress {
bar = pb.New64(0).SetUnits(pb.U_BYTES)
bar.ManualUpdate = true
bar.ShowTimeLeft = false
bar.ShowPercent = false
bar.Output = res.Stderr()
bar.Start()
}
var sizeChan chan int64
s, found := req.Values()["size"]
if found {
sizeChan = s.(chan int64)
}
lastFile := ""
var totalProgress, prevFiles, lastBytes int64
LOOP:
for {
select {
case out, ok := <-outChan:
if !ok {
break LOOP
}
output := out.(*coreunix.AddedObject)
if len(output.Hash) > 0 {
if progress {
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 !progress {
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 progress {
bar.Update()
}
case size := <-sizeChan:
if progress {
bar.Total = size
bar.ShowPercent = true
bar.ShowBar = true
bar.ShowTimeLeft = true
}
case <-req.Context().Done():
res.SetError(req.Context().Err(), cmds.ErrNormal)
return
}
}
},
Type: coreunix.AddedObject{},
}
View Source
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,
},
}
View Source
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,
},
}
View Source
var BootstrapCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Show or edit the list of bootstrap peers.",
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,
},
}
View Source
var CatCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Show IPFS object data.",
ShortDescription: "Displays the data contained by an IPFS or IPNS object(s) at the given path.",
},
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
}
if !node.OnlineMode() {
if err := node.SetupOfflineRouting(); 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
}
if err := corerepo.ConditionalGC(req.Context(), node, length); 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, reader := progressBarForReader(res.Stderr(), res.Output().(io.Reader), int64(res.Length()))
bar.Start()
res.SetOutput(reader)
},
}
View Source
var CommandsDaemonCmd = CommandsCmd(Root)
commandsDaemonCmd is the "ipfs commands" command for daemon
View Source
var CommandsDaemonROCmd = CommandsCmd(RootRO)
View Source
var ConfigCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Get and set IPFS config values.",
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.").Default(false),
cmds.BoolOption("json", "Parse stringified JSON.").Default(false),
},
Run: func(req cmds.Request, res cmds.Response) {
args := req.Arguments()
key := args[0]
switch strings.ToLower(key) {
case "identity", "identity.privkey":
res.SetError(fmt.Errorf("cannot show or change private key through API"), cmds.ErrNormal)
return
default:
}
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,
},
}
View Source
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:
> dig +short TXT ipfs.io
dnslink=/ipfs/QmRzTuh2Lpuz7Gr39stNr6mTFdqAghsZec1JoUnfySUzcy
The resolver will give:
> ipfs dns ipfs.io
/ipfs/QmRzTuh2Lpuz7Gr39stNr6mTFdqAghsZec1JoUnfySUzcy
The resolver can recursively resolve:
> dig +short TXT recursive.ipfs.io
dnslink=/ipns/ipfs.io
> ipfs dns -r recursive.ipfs.io
/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.").Default(false),
},
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() + "\n"), nil
},
},
Type: ResolvedPath{},
}
View Source
var DefaultDiagnosticTimeout = time.Second * 20
View Source
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,
},
}
View Source
var DiagCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Generates diagnostic reports.",
},
Subcommands: map[string]*cmds.Command{
"net": diagNetCmd,
"sys": sysDiagCmd,
"cmds": ActiveReqsCmd,
},
}
View Source
var ErrDepthLimitExceeded = fmt.Errorf("depth limit exceeded")
Error indicating the max depth has been exceded.
View Source
var ErrInvalidCompressionLevel = errors.New("Compression level must be between 1 and 9")
View Source
var ErrNotDHT = errors.New("routing service is not a DHT")
View Source
var GetCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Download IPFS objects.",
ShortDescription: `
Stores to disk the data contained an IPFS or IPNS object(s) at the given path.
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 the output should be stored."),
cmds.BoolOption("archive", "a", "Output a TAR archive.").Default(false),
cmds.BoolOption("compress", "C", "Compress the output with GZIP compression.").Default(false),
cmds.IntOption("compression-level", "l", "The level of compression (1-9).").Default(-1),
},
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
}
size, err := dn.Size()
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
res.SetLength(size)
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,
Size: int64(res.Length()),
}
if err := gw.Write(outReader, outPath); err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
},
}
View Source
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 information for local peers.
'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).
EXAMPLE:
ipfs id Qmece2RkXhsKe5CRooNisBTh4SK119KrXXGmoK6V3kb8aH -f="<addrs>\n"
`,
},
Arguments: []cmds.Argument{
cmds.StringArg("peerid", false, false, "Peer.ID of node to look up."),
},
Options: []cmds.Option{
cmds.StringOption("format", "f", "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
}
var id peer.ID
if len(req.Arguments()) > 0 {
id = peer.ID(b58.Decode(req.Arguments()[0]))
if len(id) == 0 {
res.SetError(cmds.ClientError("Invalid peer id"), cmds.ErrClient)
return
}
} else {
id = node.Identity
}
if id == node.Identity {
output, err := printSelf(node)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
res.SetOutput(output)
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
}
marshaled = append(marshaled, byte('\n'))
return bytes.NewReader(marshaled), nil
}
},
},
Type: IdOutput{},
}
View Source
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
/ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
Resolve the value of another name:
> ipfs name resolve QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ
/ipfs/QmSiTko9JZyabH56y2fussEt1A5oDqsFXB3CkvAqraFryz
Resolve the value of a reference:
> ipfs name resolve ipfs.io
/ipfs/QmaBvfZooxWkrv7D3r8LS9moNjzD2o525XMZze69hhoxf5
`,
},
Arguments: []cmds.Argument{
cmds.StringArg("name", false, false, "The IPNS name to resolve. Defaults to your node's peerID."),
},
Options: []cmds.Option{
cmds.BoolOption("recursive", "r", "Resolve until the result is not an IPNS name.").Default(false),
cmds.BoolOption("nocache", "n", "Do not use cached entries.").Default(false),
},
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
}
}
nocache, _, _ := req.Option("nocache").Bool()
local, _, _ := req.Option("local").Bool()
// default to nodes namesys resolver
var resolver namesys.Resolver = n.Namesys
if local && nocache {
res.SetError(errors.New("cannot specify both local and nocache"), cmds.ErrNormal)
return
}
if local {
offroute := offline.NewOfflineRouter(n.Repo.Datastore(), n.PrivateKey)
resolver = namesys.NewRoutingResolver(offroute, 0)
}
if nocache {
resolver = namesys.NewNameSystem(n.Routing, n.Repo.Datastore(), 0)
}
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
}
if !strings.HasPrefix(name, "/ipns/") {
name = "/ipns/" + name
}
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() + "\n"), nil
},
},
Type: ResolvedPath{},
}
View Source
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,
"ls": logLsCmd,
"tail": logTailCmd,
},
}
View Source
var LsCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "List links from an object.",
ShortDescription: `
Displays the links an IPFS or IPNS object(s) 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", "v", "Print table headers (Hash, Size, Name).").Default(false),
cmds.BoolOption("resolve-type", "Resolve linked objects to find out their types.").Default(true),
},
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
}
resolve, _, err := req.Option("resolve-type").Bool()
if 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 {
var linkNode *merkledag.Node
t := unixfspb.Data_DataType(-1)
linkKey := key.Key(link.Hash)
if ok, err := node.Blockstore.Has(linkKey); ok && err == nil {
b, err := node.Blockstore.Get(linkKey)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
linkNode, err = merkledag.DecodeProtobuf(b.Data())
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
}
if linkNode == nil && resolve {
linkNode, err = link.GetNode(req.Context(), node.DAG)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
}
if linkNode != nil {
d, err := unixfs.FromBytes(linkNode.Data())
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
t = d.GetType()
}
output[i].Links[j] = LsLink{
Name: link.Name,
Hash: link.Hash.B58String(),
Size: link.Size,
Type: t,
}
}
}
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{},
}
View Source
var MountCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Mounts IPFS to the filesystem (read-only).",
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. The default, /ipfs and /ipns,
are set in the configutation file, but can be overriden by the options.
All ipfs objects will be accessible under this 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 = nodeMount.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
},
},
}
View Source
var NameCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "IPFS namespace (IPNS) tool.",
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 QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ
/ipfs/QmSiTko9JZyabH56y2fussEt1A5oDqsFXB3CkvAqraFryz
Resolve the value of a reference:
> ipfs name resolve ipfs.io
/ipfs/QmaBvfZooxWkrv7D3r8LS9moNjzD2o525XMZze69hhoxf5
`,
},
Subcommands: map[string]*cmds.Command{
"publish": PublishCmd,
"resolve": IpnsCmd,
},
}
View Source
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,
},
}
View Source
var PingCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Send echo request packets to IPFS hosts.",
ShortDescription: `
'ipfs ping' is a tool to test sending data to other nodes. It finds nodes
via the routing system, sends pings, waits for pongs, and prints 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.").Default(10),
},
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, pstore.TempAddrTTL)
}
numPings, _, err := req.Option("count").Int()
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
outChan := pingPeer(ctx, n, peerID, numPings)
res.SetOutput(outChan)
},
Type: PingResult{},
}
View Source
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("ipfs-path", true, false, "IPFS path of the object to be published.").EnableStdin(),
},
Options: []cmds.Option{
cmds.BoolOption("resolve", "Resolve given path before publishing.").Default(true),
cmds.StringOption("lifetime", "t",
`Time duration that the record will be valid for. <default>
This accepts durations such as "300s", "1.5h" or "2h45m". Valid time units are
"ns", "us" (or "µs"), "ms", "s", "m", "h".`).Default("24h"),
cmds.StringOption("ttl", "Time duration this record should be cached for (caution: experimental)."),
},
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
}
}
if n.Mounts.Ipns != nil && n.Mounts.Ipns.IsActive() {
res.SetError(errors.New("You cannot manually publish while IPNS is mounted."), cmds.ErrNormal)
return
}
pstr := req.Arguments()[0]
if n.Identity == "" {
res.SetError(errors.New("Identity not loaded!"), cmds.ErrNormal)
return
}
popts := new(publishOpts)
popts.verifyExists, _, _ = req.Option("resolve").Bool()
validtime, _, _ := req.Option("lifetime").String()
d, err := time.ParseDuration(validtime)
if err != nil {
res.SetError(fmt.Errorf("error parsing lifetime option: %s", err), cmds.ErrNormal)
return
}
popts.pubValidTime = d
ctx := req.Context()
if ttl, found, _ := req.Option("ttl").String(); found {
d, err := time.ParseDuration(ttl)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
ctx = context.WithValue(ctx, "ipns-publish-ttl", d)
}
output, err := publish(ctx, n, n.PrivateKey, path.Path(pstr), popts)
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{},
}
View Source
var RefsCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Lists links (references) from an object.",
ShortDescription: `
Lists the hashes of all the links an IPFS or IPNS object(s) contains,
with the following format:
<link base58 hash>
NOTE: List all references recursively by using the flag '-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. Available tokens: <src> <dst> <linkname>.").Default("<dst>"),
cmds.BoolOption("edges", "e", "Emit edge format: `<from> -> <to>`.").Default(false),
cmds.BoolOption("unique", "u", "Omit duplicate refs from output.").Default(false),
cmds.BoolOption("recursive", "r", "Recursively list links of child nodes.").Default(false),
},
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
}
format, _, err := req.Option("format").String()
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
edges, _, err := req.Option("edges").Bool()
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
if edges {
if format != "<dst>" {
res.SetError(errors.New("using format arguement with edges is not allowed"),
cmds.ErrClient)
return
}
format = "<src> -> <dst>"
}
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,
PrintFmt: format,
Recursive: recursive,
}
for _, o := range objs {
if _, err := rw.WriteRefs(o); err != nil {
out <- &RefWrapper{Err: err.Error()}
return
}
}
}()
},
Marshalers: refsMarshallerMap,
Type: RefWrapper{},
}
View Source
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
}
out := make(chan interface{})
res.SetOutput((<-chan interface{})(out))
go func() {
defer close(out)
for k := range allKeys {
out <- &RefWrapper{Ref: k.B58String()}
}
}()
},
Marshalers: refsMarshallerMap,
Type: RefWrapper{},
}
View Source
var RefsROCmd = &cmds.Command{}
View Source
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,
"stat": repoStatCmd,
"fsck": RepoFsckCmd,
"version": repoVersionCmd,
"verify": repoVerifyCmd,
},
}
View Source
var RepoFsckCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Removes repo lockfiles.",
ShortDescription: `
'ipfs repo fsck' is a plumbing command that will remove repo and level db
lockfiles, as well as the api file. This command can only run when no ipfs
daemons are running.
`,
},
Run: func(req cmds.Request, res cmds.Response) {
configRoot := req.InvocContext().ConfigRoot
dsPath, err := config.DataStorePath(configRoot)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
dsLockFile := filepath.Join(dsPath, "LOCK")
repoLockFile := filepath.Join(configRoot, lockfile.LockFile)
apiFile := filepath.Join(configRoot, "api")
log.Infof("Removing repo lockfile: %s", repoLockFile)
log.Infof("Removing datastore lockfile: %s", dsLockFile)
log.Infof("Removing api file: %s", apiFile)
err = os.Remove(repoLockFile)
if err != nil && !os.IsNotExist(err) {
res.SetError(err, cmds.ErrNormal)
return
}
err = os.Remove(dsLockFile)
if err != nil && !os.IsNotExist(err) {
res.SetError(err, cmds.ErrNormal)
return
}
err = os.Remove(apiFile)
if err != nil && !os.IsNotExist(err) {
res.SetError(err, cmds.ErrNormal)
return
}
res.SetOutput(&MessageOutput{"Lockfiles have been removed.\n"})
},
Type: MessageOutput{},
Marshalers: cmds.MarshalerMap{
cmds.Text: MessageTextMarshaler,
},
}
View Source
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 an 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
Resolve the value of an IPFS DAG path:
$ ipfs resolve /ipfs/QmeZy1fGbwgVSrqbfh9fKQrAWgeyRnj7h8fsHS1oy3k99x/beep/boop
/ipfs/QmYRMjyvAiHKN9UTi8Bzt1HUspmSRD8T8DwxfSMzLgBon1
`,
},
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.").Default(false),
},
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()
if strings.HasPrefix(name, "/ipns/") && !recursive {
p, err := n.Namesys.ResolveN(req.Context(), name, 1)
if err != nil && err != ns.ErrResolveRecursion {
res.SetError(err, cmds.ErrNormal)
return
}
res.SetOutput(&ResolvedPath{p})
return
}
p, err := path.ParsePath(name)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
node, err := core.Resolve(req.Context(), n, p)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
key, err := node.Key()
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
res.SetOutput(&ResolvedPath{path.FromKey(key)})
},
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() + "\n"), nil
},
},
Type: ResolvedPath{},
}
View Source
var Root = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Global p2p merkle-dag filesystem.",
Synopsis: "ipfs [--config=<config> | -c] [--debug=<debug> | -D] [--help=<help>] [-h=<h>] [--local=<local> | -L] [--api=<api>] <command> ...",
Subcommands: `
BASIC COMMANDS
init Initialize ipfs local configuration
add <path> Add a file 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
files Interact with objects as if they were a unix filesystem
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 Manipulate the IPFS repository
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.
ipfs uses a repository in the local file system. By default, the repo is located
at ~/.ipfs. To change the repo location, set the $IPFS_PATH environment variable:
export IPFS_PATH=/path/to/ipfsrepo
`,
},
Options: []cmds.Option{
cmds.StringOption("config", "c", "Path to the configuration file to use."),
cmds.BoolOption("debug", "D", "Operate in debug mode.").Default(false),
cmds.BoolOption("help", "Show the full command help text.").Default(false),
cmds.BoolOption("h", "Show a short version of the command help text.").Default(false),
cmds.BoolOption("local", "L", "Run the command locally, instead of using the daemon.").Default(false),
cmds.StringOption(ApiOption, "Use a specific API instance (defaults to /ip4/127.0.0.1/tcp/5001)"),
},
}
View Source
var RootRO = &cmds.Command{}
RootRO is the readonly version of Root
View Source
var StatsCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Query ipfs statistics.",
ShortDescription: `'ipfs stats' is a set of commands to help look at statistics
for your ipfs node.
`,
LongDescription: `'ipfs stats' is a set of commands to help look at statistics
for your ipfs node.`,
},
Subcommands: map[string]*cmds.Command{
"bw": statBwCmd,
"repo": repoStatCmd,
"bitswap": bitswapStatCmd,
},
}
View Source
var SwarmCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Swarm inspection tool.",
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{
"addrs": swarmAddrsCmd,
"connect": swarmConnectCmd,
"disconnect": swarmDisconnectCmd,
"filters": swarmFiltersCmd,
"peers": swarmPeersCmd,
},
}
View Source
var TarCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Utility functions for tar files in IPFS.",
},
Subcommands: map[string]*cmds.Command{
"add": tarAddCmd,
"cat": tarCatCmd,
},
}
View Source
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.").Default(false),
cmds.BoolOption("commit", "Show the commit hash.").Default(false),
cmds.BoolOption("repo", "Show repo version.").Default(false),
cmds.BoolOption("all", "Show all version information").Default(false),
},
Run: func(req cmds.Request, res cmds.Response) {
res.SetOutput(&VersionOutput{
Version: config.CurrentVersionNumber,
Commit: config.CurrentCommit,
Repo: fmt.Sprint(fsrepo.RepoVersion),
System: runtime.GOARCH + "/" + runtime.GOOS,
Golang: runtime.Version(),
})
},
Marshalers: cmds.MarshalerMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
v := res.Output().(*VersionOutput)
repo, _, err := res.Request().Option("repo").Bool()
if err != nil {
return nil, err
}
if repo {
return strings.NewReader(v.Repo + "\n"), nil
}
commit, _, err := res.Request().Option("commit").Bool()
commitTxt := ""
if err != nil {
return nil, err
}
if commit {
commitTxt = "-" + v.Commit
}
number, _, err := res.Request().Option("number").Bool()
if err != nil {
return nil, err
}
if number {
return strings.NewReader(fmt.Sprintln(v.Version + commitTxt)), nil
}
all, _, err := res.Request().Option("all").Bool()
if err != nil {
return nil, err
}
if all {
out := fmt.Sprintf("go-ipfs version: %s-%s\n"+
"Repo version: %s\nSystem version: %s\nGolang version: %s\n",
v.Version, v.Commit, v.Repo, v.System, v.Golang)
return strings.NewReader(out), nil
}
return strings.NewReader(fmt.Sprintf("ipfs version %s%s\n", v.Version, commitTxt)), nil
},
},
Type: VersionOutput{},
}
Functions ¶
func CommandsCmd ¶
func CommandsCmd(root *cmds.Command) *cmds.Command
CommandsCmd takes in a root command, and returns a command that lists the subcommands in that root
func ExternalBinary ¶ added in v0.3.10
func ExternalBinary() *cmds.Command
func KeyListTextMarshaler ¶
func KeyListTextMarshaler(res cmds.Response) (io.Reader, error)
KeyListTextMarshaler outputs a KeyList as plaintext, one key per line
func MessageTextMarshaler ¶
func MessageTextMarshaler(res cmds.Response) (io.Reader, error)
func ParsePeerParam ¶
func ParsePeerParam(text string) (ma.Multiaddr, peer.ID, error)
Types ¶
type BootstrapOutput ¶
type BootstrapOutput struct {
Peers []string
}
type ConfigField ¶
type ConfigField struct {
Key string
Value interface{}
}
type DiagnosticConnection ¶
type DiagnosticConnection struct {
ID string
// TODO use milliseconds or microseconds for human readability
NanosecondsLatency uint64
Count int
}
type DiagnosticOutput ¶
type DiagnosticOutput struct {
Peers []DiagnosticPeer
}
type DiagnosticPeer ¶
type DiagnosticPeer struct {
ID string
UptimeSeconds uint64
BandwidthBytesIn uint64
BandwidthBytesOut uint64
Connections []DiagnosticConnection
}
type IdOutput ¶
type IdOutput struct {
ID string
PublicKey string
Addresses []string
AgentVersion string
ProtocolVersion string
}
type KeyList ¶
type KeyList struct {
Keys []key.Key
}
KeyList is a general type for outputting lists of keys
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 PingResult ¶
type PingResult struct {
Success bool
Time time.Duration
Text string
}
type RefKeyList ¶ added in v0.3.2
type RefKeyList struct {
Keys map[string]RefKeyObject
}
type RefKeyObject ¶ added in v0.3.4
type RefKeyObject struct {
Type string
}
type RefWrapper ¶ added in v0.3.5
type RefWrapper struct {
Ref string
Err string
}
type RefWriter ¶
type RefWriter struct {
DAG dag.DAGService
Ctx context.Context
Unique bool
Recursive bool
PrintFmt string
// contains filtered or unexported fields
}
type RepoVersion ¶ added in v0.4.3
type RepoVersion struct {
Version string
}
type ResolvedPath ¶ added in v0.3.3
type ResolvedPath struct {
Path path.Path
}
type VerifyProgress ¶ added in v0.4.3
type VerifyProgress struct {
Message string
Progress int
}
type VersionOutput ¶
type VersionOutput struct {
Version string
Commit string
Repo string
System string
Golang string
}
Source Files
¶
Click to show internal directories.
Click to hide internal directories.