Example #1
0
		res.SetOutput(bytes.NewReader(b.Data()))
	},
}

var blockPutCmd = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "Stores input as an IPFS block.",
		ShortDescription: `
'ipfs block put' is a plumbing command for storing raw ipfs blocks.
It reads from stdin, and <key> is a base58 encoded multihash.
`,
	},

	Arguments: []cmds.Argument{
		cmds.FileArg("data", true, false, "The data to be stored as an IPFS block.").EnableStdin(),
	},
	Run: func(req cmds.Request, res cmds.Response) {
		n, err := req.InvocContext().GetNode()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		file, err := req.Files().NextFile()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		data, err := ioutil.ReadAll(file)
Example #2
0
        "Data": "another",
        "Links": [ {
            "Name": "some link",
            "Hash": "QmXg9Pp2ytZ14xgmQjYEiHjVjMFXzCVVEcRTWJBmLgR39V",
            "Size": 8
        } ]
    }

And then run:

	$ ipfs object put node.json
`,
	},

	Arguments: []cmds.Argument{
		cmds.FileArg("data", true, false, "Data to be stored as a DAG object.").EnableStdin(),
	},
	Options: []cmds.Option{
		cmds.StringOption("inputenc", "Encoding type of input data. One of: {\"protobuf\", \"json\"}.").Default("json"),
		cmds.StringOption("datafieldenc", "Encoding type of the data field, either \"text\" or \"base64\".").Default("text"),
	},
	Run: func(req cmds.Request, res cmds.Response) {
		n, err := req.InvocContext().GetNode()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		input, err := req.Files().NextFile()
		if err != nil && err != io.EOF {
			res.SetError(err, cmds.ErrNormal)
Example #3
0
		Tagline: "Append data to the data segment of a dag node.",
		ShortDescription: `
Append data to what already exists in the data segment in the given object.

Example:

	$ echo "hello" | ipfs object patch $HASH append-data

NOTE: This does not append data to a file - it modifies the actual raw
data within an object. Objects have a max size of 1MB and objects larger than
the limit will not be respected by the network.
`,
	},
	Arguments: []cmds.Argument{
		cmds.StringArg("root", true, false, "The hash of the node to modify."),
		cmds.FileArg("data", true, false, "Data to append.").EnableStdin(),
	},
	Run: func(req cmds.Request, res cmds.Response) {
		nd, err := req.InvocContext().GetNode()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		root, err := path.ParsePath(req.Arguments()[0])
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		rootnd, err := core.Resolve(req.Context(), nd, root)
Example #4
0
	Bytes int64  `json:",omitempty"`
}

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, // a builtin option that allows recursive paths (-r, --recursive)
		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, "H", "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
		}
Example #5
0
			res.SetError(err, cmds.ErrNormal)
		}
	},
}

var configReplaceCmd = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "Replaces the config with <file>.",
		ShortDescription: `
Make sure to back up the config file first if neccessary, this operation
can't be undone.
`,
	},

	Arguments: []cmds.Argument{
		cmds.FileArg("file", true, false, "The file to use as the new config."),
	},
	Run: func(req cmds.Request, res cmds.Response) {
		r, err := fsrepo.Open(req.InvocContext().ConfigRoot)
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		defer r.Close()

		file, err := req.Files().NextFile()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}
		defer file.Close()
Example #6
0
const nBitsForKeypairDefault = 2048

var initCmd = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "Initializes IPFS config file.",
		ShortDescription: `
Initializes IPFS configuration files and generates a new keypair.

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
`,
	},
	Arguments: []cmds.Argument{
		cmds.FileArg("default-config", false, false, "Initialize with the given configuration.").EnableStdin(),
	},
	Options: []cmds.Option{
		cmds.IntOption("bits", "b", fmt.Sprintf("Number of bits to use in the generated RSA private key (defaults to %d)", nBitsForKeypairDefault)),
		cmds.BoolOption("empty-repo", "e", "Don't add and pin help files to the local storage."),

		// TODO need to decide whether to expose the override as a file or a
		// directory. That is: should we allow the user to also specify the
		// name of the file?
		// TODO cmds.StringOption("event-logs", "l", "Location for machine-readable event logs."),
	},
	PreRun: func(req cmds.Request) error {
		daemonLocked, err := fsrepo.LockedByOtherProcess(req.InvocContext().ConfigRoot)
		if err != nil {
			return err
		}
Example #7
0
		"add": tarAddCmd,
		"cat": tarCatCmd,
	},
}

var tarAddCmd = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "Import a tar file into ipfs.",
		ShortDescription: `
'ipfs tar add' will parse a tar file and create a merkledag structure to
represent it.
`,
	},

	Arguments: []cmds.Argument{
		cmds.FileArg("file", true, false, "Tar file to add.").EnableStdin(),
	},
	Run: func(req cmds.Request, res cmds.Response) {
		nd, err := req.InvocContext().GetNode()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		fi, err := req.Files().NextFile()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		node, err := tar.ImportTar(fi, nd.DAG)
Example #8
0
	Helptext: cmds.HelpText{
		Tagline: "Append data to the data segment of a dag node.",
		ShortDescription: `
Append data to what already exists in the data segment in the given object.

EXAMPLE:
	$ echo "hello" | ipfs object patch $HASH append-data

note: this does not append data to a 'file', it modifies the actual raw
data within an object. Objects have a max size of 1MB and objects larger than
the limit will not be respected by the network.
`,
	},
	Arguments: []cmds.Argument{
		cmds.StringArg("root", true, false, "the hash of the node to modify"),
		cmds.FileArg("data", true, false, "data to append").EnableStdin(),
	},
	Run: func(req cmds.Request, res cmds.Response) {
		nd, err := req.InvocContext().GetNode()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		root, err := path.ParsePath(req.Arguments()[0])
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		rootnd, err := core.Resolve(req.Context(), nd, root)
Example #9
0
EXAMPLE:

    echo "hello world" | ipfs files write --create /myfs/a/b/file
    echo "hello world" | ipfs files write --truncate /myfs/a/b/file

WARNING:

Usage of the '--flush=false' option does not guarantee data durability until
the tree has been flushed. This can be accomplished by running 'ipfs files
stat' on the file or any of its ancestors.
`,
	},
	Arguments: []cmds.Argument{
		cmds.StringArg("path", true, false, "Path to write to."),
		cmds.FileArg("data", true, false, "Data to write.").EnableStdin(),
	},
	Options: []cmds.Option{
		cmds.IntOption("offset", "o", "Byte offset to begin writing at."),
		cmds.BoolOption("create", "e", "Create the file if it does not exist."),
		cmds.BoolOption("truncate", "t", "Truncate the file to size zero before writing."),
		cmds.IntOption("count", "n", "Maximum number of bytes to read."),
	},
	Run: func(req cmds.Request, res cmds.Response) {
		path, err := checkPath(req.Arguments()[0])
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		create, _, _ := req.Option("create").Bool()
Example #10
0
}

type OutputObject struct {
	Cid *cid.Cid
}

var DagPutCmd = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "Add a dag node to ipfs.",
		ShortDescription: `
'ipfs dag put' accepts input from a file or stdin and parses it
into an object of the specified format.
`,
	},
	Arguments: []cmds.Argument{
		cmds.FileArg("object data", true, false, "The object to put").EnableStdin(),
	},
	Options: []cmds.Option{
		cmds.StringOption("format", "f", "Format that the object will be added as.").Default("cbor"),
		cmds.StringOption("input-enc", "Format that the input object will be.").Default("json"),
	},
	Run: func(req cmds.Request, res cmds.Response) {
		n, err := req.InvocContext().GetNode()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		fi, err := req.Files().NextFile()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
Example #11
0
func TestArgumentParsing(t *testing.T) {
	if runtime.GOOS == "windows" {
		t.Skip("stdin handling doesnt yet work on windows")
	}
	rootCmd := &commands.Command{
		Subcommands: map[string]*commands.Command{
			"noarg": {},
			"onearg": {
				Arguments: []commands.Argument{
					commands.StringArg("a", true, false, "some arg"),
				},
			},
			"twoargs": {
				Arguments: []commands.Argument{
					commands.StringArg("a", true, false, "some arg"),
					commands.StringArg("b", true, false, "another arg"),
				},
			},
			"variadic": {
				Arguments: []commands.Argument{
					commands.StringArg("a", true, true, "some arg"),
				},
			},
			"optional": {
				Arguments: []commands.Argument{
					commands.StringArg("b", false, true, "another arg"),
				},
			},
			"optionalsecond": {
				Arguments: []commands.Argument{
					commands.StringArg("a", true, false, "some arg"),
					commands.StringArg("b", false, false, "another arg"),
				},
			},
			"reversedoptional": {
				Arguments: []commands.Argument{
					commands.StringArg("a", false, false, "some arg"),
					commands.StringArg("b", true, false, "another arg"),
				},
			},
			"FileArg": {
				Arguments: []commands.Argument{
					commands.FileArg("a", true, false, "some arg"),
				},
			},
			"FileArg+Variadic": {
				Arguments: []commands.Argument{
					commands.FileArg("a", true, true, "some arg"),
				},
			},
			"FileArg+Stdin": {
				Arguments: []commands.Argument{
					commands.FileArg("a", true, true, "some arg").EnableStdin(),
				},
			},
			"StringArg+FileArg": {
				Arguments: []commands.Argument{
					commands.StringArg("a", true, false, "some arg"),
					commands.FileArg("a", true, false, "some arg"),
				},
			},
			"StringArg+FileArg+Stdin": {
				Arguments: []commands.Argument{
					commands.StringArg("a", true, false, "some arg"),
					commands.FileArg("a", true, true, "some arg").EnableStdin(),
				},
			},
			"StringArg+FileArg+Variadic": {
				Arguments: []commands.Argument{
					commands.StringArg("a", true, false, "some arg"),
					commands.FileArg("a", true, true, "some arg"),
				},
			},
			"StringArg+FileArg+Variadic+Stdin": {
				Arguments: []commands.Argument{
					commands.StringArg("a", true, false, "some arg"),
					commands.FileArg("a", true, true, "some arg"),
				},
			},
		},
	}

	test := func(cmd words, f *os.File, exp words) {
		if f != nil {
			if _, err := f.Seek(0, os.SEEK_SET); err != nil {
				t.Fatal(err)
			}
		}
		req, _, _, err := Parse(cmd, f, rootCmd)
		if err != nil {
			t.Errorf("Command '%v' should have passed parsing: %v", cmd, err)
		}

		parsedWords := make([]string, len(req.Arguments()))
		copy(parsedWords, req.Arguments())

		if files := req.Files(); files != nil {
			for file, err := files.NextFile(); err != io.EOF; file, err = files.NextFile() {
				parsedWords = append(parsedWords, file.FullPath())
			}
		}

		if !sameWords(parsedWords, exp) {
			t.Errorf("Arguments parsed from '%v' are '%v' instead of '%v'", cmd, parsedWords, exp)
		}
	}

	testFail := func(cmd words, fi *os.File, msg string) {
		_, _, _, err := Parse(cmd, nil, rootCmd)
		if err == nil {
			t.Errorf("Should have failed: %v", msg)
		}
	}

	test([]string{"noarg"}, nil, []string{})
	testFail([]string{"noarg", "value!"}, nil, "provided an arg, but command didn't define any")

	test([]string{"onearg", "value!"}, nil, []string{"value!"})
	testFail([]string{"onearg"}, nil, "didn't provide any args, arg is required")

	test([]string{"twoargs", "value1", "value2"}, nil, []string{"value1", "value2"})
	testFail([]string{"twoargs", "value!"}, nil, "only provided 1 arg, needs 2")
	testFail([]string{"twoargs"}, nil, "didn't provide any args, 2 required")

	test([]string{"variadic", "value!"}, nil, []string{"value!"})
	test([]string{"variadic", "value1", "value2", "value3"}, nil, []string{"value1", "value2", "value3"})
	testFail([]string{"variadic"}, nil, "didn't provide any args, 1 required")

	test([]string{"optional", "value!"}, nil, []string{"value!"})
	test([]string{"optional"}, nil, []string{})
	test([]string{"optional", "value1", "value2"}, nil, []string{"value1", "value2"})

	test([]string{"optionalsecond", "value!"}, nil, []string{"value!"})
	test([]string{"optionalsecond", "value1", "value2"}, nil, []string{"value1", "value2"})
	testFail([]string{"optionalsecond"}, nil, "didn't provide any args, 1 required")
	testFail([]string{"optionalsecond", "value1", "value2", "value3"}, nil, "provided too many args, takes 2 maximum")

	test([]string{"reversedoptional", "value1", "value2"}, nil, []string{"value1", "value2"})
	test([]string{"reversedoptional", "value!"}, nil, []string{"value!"})

	testFail([]string{"reversedoptional"}, nil, "didn't provide any args, 1 required")
	testFail([]string{"reversedoptional", "value1", "value2", "value3"}, nil, "provided too many args, only takes 1")

	// Since FileArgs are presently stored ordered by Path, the enum string
	// is used to construct a predictably ordered sequence of filenames.
	tmpFile := func(t *testing.T, enum string) *os.File {
		f, err := ioutil.TempFile("", enum)
		if err != nil {
			t.Fatal(err)
		}
		fn, err := filepath.EvalSymlinks(f.Name())
		if err != nil {
			t.Fatal(err)
		}
		f.Close()
		f, err = os.Create(fn)
		if err != nil {
			t.Fatal(err)
		}

		return f
	}
	file1 := tmpFile(t, "1")
	file2 := tmpFile(t, "2")
	file3 := tmpFile(t, "3")
	defer os.Remove(file3.Name())
	defer os.Remove(file2.Name())
	defer os.Remove(file1.Name())

	test([]string{"noarg"}, file1, []string{})
	test([]string{"FileArg", file1.Name()}, nil, []string{file1.Name()})
	test([]string{"FileArg+Variadic", file1.Name(), file2.Name()}, nil,
		[]string{file1.Name(), file2.Name()})
	test([]string{"FileArg+Stdin"}, file1, []string{file1.Name()})
	test([]string{"FileArg+Stdin", "-"}, file1, []string{file1.Name()})
	test([]string{"FileArg+Stdin", file1.Name(), "-"}, file2,
		[]string{file1.Name(), file2.Name()})
	test([]string{"StringArg+FileArg",
		"foo", file1.Name()}, nil, []string{"foo", file1.Name()})
	test([]string{"StringArg+FileArg+Variadic",
		"foo", file1.Name(), file2.Name()}, nil,
		[]string{"foo", file1.Name(), file2.Name()})
	test([]string{"StringArg+FileArg+Stdin",
		"foo", file1.Name(), "-"}, file2,
		[]string{"foo", file1.Name(), file2.Name()})
	test([]string{"StringArg+FileArg+Variadic+Stdin",
		"foo", file1.Name(), file2.Name()}, file3,
		[]string{"foo", file1.Name(), file2.Name()})
	test([]string{"StringArg+FileArg+Variadic+Stdin",
		"foo", file1.Name(), file2.Name(), "-"}, file3,
		[]string{"foo", file1.Name(), file2.Name(), file3.Name()})
}