Example #1
0
func (d *driver) PutFile(file *pfs.File, shard uint64, offset int64, reader io.Reader) (retErr error) {
	d.lock.RLock()
	diffInfo, ok := d.started.get(&pfs.Diff{
		Commit: file.Commit,
		Shard:  shard,
	})
	d.lock.RUnlock()
	if !ok {
		return fmt.Errorf("commit %s/%s not found", file.Commit.Repo.Name, file.Commit.Id)
	}
	blockClient, err := d.getBlockClient()
	if err != nil {
		return err
	}
	blockRefs, err := pfsutil.PutBlock(blockClient, reader)
	if err != nil {
		return err
	}
	d.lock.Lock()
	defer d.lock.Unlock()
	diffInfo, ok = d.started.get(&pfs.Diff{
		Commit: file.Commit,
		Shard:  shard,
	})
	if !ok {
		// This is a weird case since the commit existed above, it means someone
		// deleted the commit while the above code was running
		return fmt.Errorf("commit %s/%s not found", file.Commit.Repo.Name, file.Commit.Id)
	}
	addDirs(diffInfo, file)
	_append, ok := diffInfo.Appends[path.Clean(file.Path)]
	if !ok {
		_append = &pfs.Append{}
		if diffInfo.ParentCommit != nil {
			_append.LastRef = d.lastRef(
				pfsutil.NewFile(
					diffInfo.ParentCommit.Repo.Name,
					diffInfo.ParentCommit.Id,
					file.Path,
				),
				shard,
			)
		}
		diffInfo.Appends[path.Clean(file.Path)] = _append
	}
	_append.BlockRefs = append(_append.BlockRefs, blockRefs.BlockRef...)
	for _, blockRef := range blockRefs.BlockRef {
		diffInfo.SizeBytes += blockRef.Range.Upper - blockRef.Range.Lower
	}
	return nil
}
Example #2
0
func doBlockWrites(tb testing.TB, apiClient pfs.APIClient, repoName string, commitID string) {
	var wg sync.WaitGroup
	defer wg.Wait()
	for i := 0; i < testSize; i++ {
		i := i
		wg.Add(1)
		go func() {
			defer wg.Done()
			_, iErr := pfsutil.PutBlock(apiClient, repoName, commitID,
				fmt.Sprintf("a/d/file%d", i), strings.NewReader(fmt.Sprintf("hello%d", i)))
			require.NoError(tb, iErr)
		}()
	}
}
Example #3
0
File: main.go Project: sr/pachyderm
func do(appEnvObj interface{}) error {
	appEnv := appEnvObj.(*appEnv)
	logrus.Register()
	address := appEnv.PachydermPfsd1Port
	if address == "" {
		address = appEnv.Address
	} else {
		address = strings.Replace(address, "tcp://", "", -1)
	}
	clientConn, err := grpc.Dial(address, grpc.WithInsecure())
	if err != nil {
		return err
	}
	apiClient := pfs.NewApiClient(clientConn)

	var shard int
	var modulus int

	createRepo := cobramainutil.Command{
		Use:     "create-repo repo-name",
		Short:   "Create a new repo.",
		Long:    "Create a new repo.",
		NumArgs: 1,
		Run: func(cmd *cobra.Command, args []string) error {
			return pfsutil.CreateRepo(apiClient, args[0])
		},
	}.ToCobraCommand()

	inspectRepo := cobramainutil.Command{
		Use:     "inspect-repo repo-name",
		Short:   "Return info about a repo.",
		Long:    "Return info about a repo.",
		NumArgs: 1,
		Run: func(cmd *cobra.Command, args []string) error {
			repoInfo, err := pfsutil.InspectRepo(apiClient, args[0])
			if err != nil {
				return err
			}
			if repoInfo == nil {
				return fmt.Errorf("repo %s not found", args[0])
			}
			writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
			pretty.PrintRepoHeader(writer)
			pretty.PrintRepoInfo(writer, repoInfo)
			return writer.Flush()
		},
	}.ToCobraCommand()

	listRepo := cobramainutil.Command{
		Use:     "list-repo",
		Short:   "Return all repos.",
		Long:    "Reutrn all repos.",
		NumArgs: 0,
		Run: func(cmd *cobra.Command, args []string) error {
			repoInfos, err := pfsutil.ListRepo(apiClient)
			if err != nil {
				return err
			}
			writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
			pretty.PrintRepoHeader(writer)
			for _, repoInfo := range repoInfos {
				pretty.PrintRepoInfo(writer, repoInfo)
			}
			return writer.Flush()
		},
	}.ToCobraCommand()

	deleteRepo := cobramainutil.Command{
		Use:     "delete-repo repo-name",
		Short:   "Delete a repo.",
		Long:    "Delete a repo.",
		NumArgs: 1,
		Run: func(cmd *cobra.Command, args []string) error {
			return pfsutil.DeleteRepo(apiClient, args[0])
		},
	}.ToCobraCommand()

	startCommit := cobramainutil.Command{
		Use:     "start-commit repo-name parent-commit-id",
		Short:   "Start a new commit.",
		Long:    "Start a new commit with parent-commit-id as the parent.",
		NumArgs: 2,
		Run: func(cmd *cobra.Command, args []string) error {
			commit, err := pfsutil.StartCommit(apiClient, args[0], args[1])
			if err != nil {
				return err
			}
			fmt.Println(commit.Id)
			return nil
		},
	}.ToCobraCommand()

	finishCommit := cobramainutil.Command{
		Use:     "finish-commit repo-name commit-id",
		Short:   "Finish a started commit.",
		Long:    "Finish a started commit. Commit-id must be a writeable commit.",
		NumArgs: 2,
		Run: func(cmd *cobra.Command, args []string) error {
			return pfsutil.FinishCommit(apiClient, args[0], args[1])
		},
	}.ToCobraCommand()

	inspectCommit := cobramainutil.Command{
		Use:     "inspect-commit repo-name commit-id",
		Short:   "Return info about a commit.",
		Long:    "Return info about a commit.",
		NumArgs: 2,
		Run: func(cmd *cobra.Command, args []string) error {
			commitInfo, err := pfsutil.InspectCommit(apiClient, args[0], args[1])
			if err != nil {
				return err
			}
			if commitInfo == nil {
				return fmt.Errorf("commit %s not found", args[1])
			}
			writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
			pretty.PrintCommitInfoHeader(writer)
			pretty.PrintCommitInfo(writer, commitInfo)
			return writer.Flush()
		},
	}.ToCobraCommand()

	listCommit := cobramainutil.Command{
		Use:     "list-commit repo-name",
		Short:   "Return all commits on a repo.",
		Long:    "Return all commits on a repo.",
		NumArgs: 1,
		Run: func(cmd *cobra.Command, args []string) error {
			commitInfos, err := pfsutil.ListCommit(apiClient, args[0])
			if err != nil {
				return err
			}
			writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
			pretty.PrintCommitInfoHeader(writer)
			for _, commitInfo := range commitInfos {
				pretty.PrintCommitInfo(writer, commitInfo)
			}
			return writer.Flush()
		},
	}.ToCobraCommand()

	deleteCommit := cobramainutil.Command{
		Use:     "delete-commit repo-name commit-id",
		Short:   "Delete a commit.",
		Long:    "Delete a commit.",
		NumArgs: 2,
		Run: func(cmd *cobra.Command, args []string) error {
			return pfsutil.DeleteCommit(apiClient, args[0], args[1])
		},
	}.ToCobraCommand()

	putBlock := cobramainutil.Command{
		Use:     "put-block repo-name commit-id path/to/file",
		Short:   "Put a block from stdin",
		Long:    "Put a block from stdin. Directories must exist. commit-id must be a writeable commit.",
		NumArgs: 3,
		Run: func(cmd *cobra.Command, args []string) error {
			block, err := pfsutil.PutBlock(apiClient, args[0], args[1], args[2], os.Stdin)
			if err != nil {
				return err
			}
			fmt.Println(block.Hash)
			return nil
		},
	}.ToCobraCommand()

	getBlock := cobramainutil.Command{
		Use:     "get-block hash",
		Short:   "Return the contents of a block.",
		Long:    "Return the contents of a block.",
		NumArgs: 1,
		Run: func(cmd *cobra.Command, args []string) error {
			return pfsutil.GetBlock(apiClient, args[0], os.Stdout)
		},
	}.ToCobraCommand()

	inspectBlock := cobramainutil.Command{
		Use:     "inspect-block hash",
		Short:   "Return info about a block.",
		Long:    "Return info about a block.",
		NumArgs: 1,
		Run: func(cmd *cobra.Command, args []string) error {
			blockInfo, err := pfsutil.InspectBlock(apiClient, args[0])
			if err != nil {
				return err
			}
			if blockInfo == nil {
				return fmt.Errorf("block %s not found", args[2])
			}
			writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
			pretty.PrintBlockInfoHeader(writer)
			pretty.PrintBlockInfo(writer, blockInfo)
			return writer.Flush()
		},
	}.ToCobraCommand()

	listBlock := cobramainutil.Command{
		Use:     "list-block",
		Short:   "Return the blocks in a directory.",
		Long:    "Return the blocks in a directory.",
		NumArgs: 0,
		Run: func(cmd *cobra.Command, args []string) error {
			blockInfos, err := pfsutil.ListBlock(apiClient, uint64(shard), uint64(modulus))
			if err != nil {
				return err
			}
			writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
			pretty.PrintBlockInfoHeader(writer)
			for _, blockInfo := range blockInfos {
				pretty.PrintBlockInfo(writer, blockInfo)
			}
			return writer.Flush()
		},
	}.ToCobraCommand()
	listBlock.Flags().IntVarP(&shard, "shard", "s", 0, "shard to read from")
	listBlock.Flags().IntVarP(&modulus, "modulus", "m", 1, "modulus of the shards")

	mkdir := cobramainutil.Command{
		Use:     "mkdir repo-name commit-id path/to/dir",
		Short:   "Make a directory.",
		Long:    "Make a directory. Parent directories need not exist.",
		NumArgs: 3,
		Run: func(cmd *cobra.Command, args []string) error {
			return pfsutil.MakeDirectory(apiClient, args[0], args[1], args[2])
		},
	}.ToCobraCommand()

	putFile := cobramainutil.Command{
		Use:     "put-file repo-name commit-id path/to/file",
		Short:   "Put a file from stdin",
		Long:    "Put a file from stdin. Directories must exist. commit-id must be a writeable commit.",
		NumArgs: 3,
		Run: func(cmd *cobra.Command, args []string) error {
			_, err := pfsutil.PutFile(apiClient, args[0], args[1], args[2], 0, os.Stdin)
			return err
		},
	}.ToCobraCommand()

	getFile := cobramainutil.Command{
		Use:     "get-file repo-name commit-id path/to/file",
		Short:   "Return the contents of a file.",
		Long:    "Return the contents of a file.",
		NumArgs: 3,
		Run: func(cmd *cobra.Command, args []string) error {
			return pfsutil.GetFile(apiClient, args[0], args[1], args[2], 0, math.MaxInt64, os.Stdout)
		},
	}.ToCobraCommand()

	inspectFile := cobramainutil.Command{
		Use:     "inspect-file repo-name commit-id path/to/file",
		Short:   "Return info about a file.",
		Long:    "Return info about a file.",
		NumArgs: 3,
		Run: func(cmd *cobra.Command, args []string) error {
			fileInfo, err := pfsutil.InspectFile(apiClient, args[0], args[1], args[2])
			if err != nil {
				return err
			}
			if fileInfo == nil {
				return fmt.Errorf("file %s not found", args[2])
			}
			writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
			pretty.PrintFileInfoHeader(writer)
			pretty.PrintFileInfo(writer, fileInfo)
			return writer.Flush()
		},
	}.ToCobraCommand()

	listFile := cobramainutil.Command{
		Use:     "list-file repo-name commit-id path/to/dir",
		Short:   "Return the files in a directory.",
		Long:    "Return the files in a directory.",
		NumArgs: 3,
		Run: func(cmd *cobra.Command, args []string) error {
			fileInfos, err := pfsutil.ListFile(apiClient, args[0], args[1], args[2], uint64(shard), uint64(modulus))
			if err != nil {
				return err
			}
			writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
			pretty.PrintFileInfoHeader(writer)
			for _, fileInfo := range fileInfos {
				pretty.PrintFileInfo(writer, fileInfo)
			}
			return writer.Flush()
		},
	}.ToCobraCommand()
	listFile.Flags().IntVarP(&shard, "shard", "s", 0, "shard to read from")
	listFile.Flags().IntVarP(&modulus, "modulus", "m", 1, "modulus of the shards")

	deleteFile := cobramainutil.Command{
		Use:     "delete-file repo-name commit-id path/to/file",
		Short:   "Delete a file.",
		Long:    "Delete a file.",
		NumArgs: 2,
		Run: func(cmd *cobra.Command, args []string) error {
			return pfsutil.DeleteFile(apiClient, args[0], args[1], args[2])
		},
	}.ToCobraCommand()

	listChange := cobramainutil.Command{
		Use:     "list-change repo-name commit-id path/to/dir",
		Short:   "Return the changes in a directory.",
		Long:    "Return the changes in a directory.",
		NumArgs: 3,
		Run: func(cmd *cobra.Command, args []string) error {
			changeInfos, err := pfsutil.ListChange(apiClient, args[0], args[1], args[2], uint64(shard), uint64(modulus))
			if err != nil {
				return err
			}
			writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
			pretty.PrintChangeHeader(writer)
			for _, changeInfo := range changeInfos {
				pretty.PrintChange(writer, changeInfo)
			}
			return writer.Flush()
		},
	}.ToCobraCommand()
	listChange.Flags().IntVarP(&shard, "shard", "s", 0, "shard to read from")
	listChange.Flags().IntVarP(&modulus, "modulus", "m", 1, "modulus of the shards")

	inspectServer := cobramainutil.Command{
		Use:     "inspect-server server-id",
		Short:   "Inspect a server.",
		Long:    "Inspect a server.",
		NumArgs: 1,
		Run: func(cmd *cobra.Command, args []string) error {
			serverInfo, err := pfsutil.InspectServer(apiClient, args[0])
			if err != nil {
				return err
			}
			writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
			pretty.PrintServerInfoHeader(writer)
			pretty.PrintServerInfo(writer, serverInfo)
			return writer.Flush()
		},
	}.ToCobraCommand()

	listServer := cobramainutil.Command{
		Use:     "list-server",
		Short:   "Return all servers in the cluster.",
		Long:    "Return all servers in the cluster.",
		NumArgs: 0,
		Run: func(cmd *cobra.Command, args []string) error {
			serverInfos, err := pfsutil.ListServer(apiClient)
			if err != nil {
				return err
			}
			writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
			pretty.PrintServerInfoHeader(writer)
			for _, serverInfo := range serverInfos {
				pretty.PrintServerInfo(writer, serverInfo)
			}
			return writer.Flush()
		},
	}.ToCobraCommand()

	mount := cobramainutil.Command{
		Use:        "mount mountpoint repo-name [commit-id]",
		Short:      "Mount a repo as a local file system.",
		Long:       "Mount a repo as a local file system.",
		MinNumArgs: 2,
		MaxNumArgs: 3,
		Run: func(cmd *cobra.Command, args []string) error {
			mountPoint := args[0]
			repo := args[1]
			commitID := ""
			if len(args) == 3 {
				commitID = args[2]
			}
			mounter := fuse.NewMounter(apiClient)
			if err := mounter.Mount(repo, commitID, mountPoint, uint64(shard), uint64(modulus)); err != nil {
				return err
			}
			return mounter.Wait(mountPoint)
		},
	}.ToCobraCommand()
	mount.Flags().IntVarP(&shard, "shard", "s", 0, "shard to read from")
	mount.Flags().IntVarP(&modulus, "modulus", "m", 1, "modulus of the shards")

	rootCmd := &cobra.Command{
		Use: "pfs",
		Long: `Access the PFS API.

Note that this CLI is experimental and does not even check for common errors.
The environment variable PFS_ADDRESS controls what server the CLI connects to, the default is 0.0.0.0:650.`,
	}

	rootCmd.AddCommand(protoclient.NewVersionCommand(clientConn, pachyderm.Version, nil))
	rootCmd.AddCommand(createRepo)
	rootCmd.AddCommand(inspectRepo)
	rootCmd.AddCommand(listRepo)
	rootCmd.AddCommand(deleteRepo)
	rootCmd.AddCommand(startCommit)
	rootCmd.AddCommand(finishCommit)
	rootCmd.AddCommand(inspectCommit)
	rootCmd.AddCommand(listCommit)
	rootCmd.AddCommand(deleteCommit)
	rootCmd.AddCommand(mkdir)
	rootCmd.AddCommand(putBlock)
	rootCmd.AddCommand(getBlock)
	rootCmd.AddCommand(inspectBlock)
	rootCmd.AddCommand(listBlock)
	rootCmd.AddCommand(putFile)
	rootCmd.AddCommand(getFile)
	rootCmd.AddCommand(inspectFile)
	rootCmd.AddCommand(listFile)
	rootCmd.AddCommand(deleteFile)
	rootCmd.AddCommand(listChange)
	rootCmd.AddCommand(inspectServer)
	rootCmd.AddCommand(listServer)
	rootCmd.AddCommand(mount)
	return rootCmd.Execute()
}
Example #4
0
func Cmds(address string) ([]*cobra.Command, error) {
	var number int
	var modulus int
	shard := func() *pfs.Shard {
		return &pfs.Shard{Number: uint64(number), Modulus: uint64(modulus)}
	}

	createRepo := &cobra.Command{
		Use:   "create-repo repo-name",
		Short: "Create a new repo.",
		Long:  "Create a new repo.",
		Run: pkgcobra.RunFixedArgs(1, func(args []string) error {
			apiClient, err := getAPIClient(address)
			if err != nil {
				return err
			}
			return pfsutil.CreateRepo(apiClient, args[0])
		}),
	}

	inspectRepo := &cobra.Command{
		Use:   "inspect-repo repo-name",
		Short: "Return info about a repo.",
		Long:  "Return info about a repo.",
		Run: pkgcobra.RunFixedArgs(1, func(args []string) error {
			apiClient, err := getAPIClient(address)
			if err != nil {
				return err
			}
			repoInfo, err := pfsutil.InspectRepo(apiClient, args[0])
			if err != nil {
				return err
			}
			if repoInfo == nil {
				return fmt.Errorf("repo %s not found", args[0])
			}
			writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
			pretty.PrintRepoHeader(writer)
			pretty.PrintRepoInfo(writer, repoInfo)
			return writer.Flush()
		}),
	}

	listRepo := &cobra.Command{
		Use:   "list-repo",
		Short: "Return all repos.",
		Long:  "Reutrn all repos.",
		Run: pkgcobra.RunFixedArgs(0, func(args []string) error {
			apiClient, err := getAPIClient(address)
			if err != nil {
				return err
			}
			repoInfos, err := pfsutil.ListRepo(apiClient)
			if err != nil {
				return err
			}
			writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
			pretty.PrintRepoHeader(writer)
			for _, repoInfo := range repoInfos {
				pretty.PrintRepoInfo(writer, repoInfo)
			}
			return writer.Flush()
		}),
	}

	deleteRepo := &cobra.Command{
		Use:   "delete-repo repo-name",
		Short: "Delete a repo.",
		Long:  "Delete a repo.",
		Run: pkgcobra.RunFixedArgs(1, func(args []string) error {
			apiClient, err := getAPIClient(address)
			if err != nil {
				return err
			}
			return pfsutil.DeleteRepo(apiClient, args[0])
		}),
	}

	startCommit := &cobra.Command{
		Use:   "start-commit repo-name [parent-commit-id]",
		Short: "Start a new commit.",
		Long:  "Start a new commit with parent-commit-id as the parent.",
		Run: pkgcobra.RunBoundedArgs(pkgcobra.Bounds{Min: 1, Max: 2}, func(args []string) error {
			apiClient, err := getAPIClient(address)
			if err != nil {
				return err
			}
			parentCommitID := ""
			if len(args) == 2 {
				parentCommitID = args[1]
			}
			commit, err := pfsutil.StartCommit(apiClient, args[0], parentCommitID)
			if err != nil {
				return err
			}
			fmt.Println(commit.Id)
			return nil
		}),
	}

	finishCommit := &cobra.Command{
		Use:   "finish-commit repo-name commit-id",
		Short: "Finish a started commit.",
		Long:  "Finish a started commit. Commit-id must be a writeable commit.",
		Run: pkgcobra.RunFixedArgs(2, func(args []string) error {
			apiClient, err := getAPIClient(address)
			if err != nil {
				return err
			}
			return pfsutil.FinishCommit(apiClient, args[0], args[1])
		}),
	}

	inspectCommit := &cobra.Command{
		Use:   "inspect-commit repo-name commit-id",
		Short: "Return info about a commit.",
		Long:  "Return info about a commit.",
		Run: pkgcobra.RunFixedArgs(2, func(args []string) error {
			apiClient, err := getAPIClient(address)
			if err != nil {
				return err
			}
			commitInfo, err := pfsutil.InspectCommit(apiClient, args[0], args[1])
			if err != nil {
				return err
			}
			if commitInfo == nil {
				return fmt.Errorf("commit %s not found", args[1])
			}
			writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
			pretty.PrintCommitInfoHeader(writer)
			pretty.PrintCommitInfo(writer, commitInfo)
			return writer.Flush()
		}),
	}

	listCommit := &cobra.Command{
		Use:   "list-commit repo-name",
		Short: "Return all commits on a repo.",
		Long:  "Return all commits on a repo.",
		Run: pkgcobra.RunFixedArgs(1, func(args []string) error {
			apiClient, err := getAPIClient(address)
			if err != nil {
				return err
			}
			commitInfos, err := pfsutil.ListCommit(apiClient, args[0])
			if err != nil {
				return err
			}
			writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
			pretty.PrintCommitInfoHeader(writer)
			for _, commitInfo := range commitInfos {
				pretty.PrintCommitInfo(writer, commitInfo)
			}
			return writer.Flush()
		}),
	}

	deleteCommit := &cobra.Command{
		Use:   "delete-commit repo-name commit-id",
		Short: "Delete a commit.",
		Long:  "Delete a commit.",
		Run: pkgcobra.RunFixedArgs(2, func(args []string) error {
			apiClient, err := getAPIClient(address)
			if err != nil {
				return err
			}
			return pfsutil.DeleteCommit(apiClient, args[0], args[1])
		}),
	}

	putBlock := &cobra.Command{
		Use:   "put-block repo-name commit-id path/to/file",
		Short: "Put a block from stdin",
		Long:  "Put a block from stdin. Directories must exist. commit-id must be a writeable commit.",
		Run: pkgcobra.RunFixedArgs(3, func(args []string) error {
			apiClient, err := getAPIClient(address)
			if err != nil {
				return err
			}
			block, err := pfsutil.PutBlock(apiClient, args[0], args[1], args[2], os.Stdin)
			if err != nil {
				return err
			}
			fmt.Println(block.Hash)
			return nil
		}),
	}

	getBlock := &cobra.Command{
		Use:   "get-block hash",
		Short: "Return the contents of a block.",
		Long:  "Return the contents of a block.",
		Run: pkgcobra.RunFixedArgs(1, func(args []string) error {
			apiClient, err := getAPIClient(address)
			if err != nil {
				return err
			}
			return pfsutil.GetBlock(apiClient, args[0], shard(), os.Stdout)
		}),
	}
	getBlock.Flags().IntVarP(&number, "shard", "s", 0, "shard to read from")
	getBlock.Flags().IntVarP(&modulus, "modulus", "m", 1, "modulus of the shards")

	inspectBlock := &cobra.Command{
		Use:   "inspect-block hash",
		Short: "Return info about a block.",
		Long:  "Return info about a block.",
		Run: pkgcobra.RunFixedArgs(1, func(args []string) error {
			apiClient, err := getAPIClient(address)
			if err != nil {
				return err
			}
			blockInfo, err := pfsutil.InspectBlock(apiClient, args[0], shard())
			if err != nil {
				return err
			}
			if blockInfo == nil {
				return fmt.Errorf("block %s not found", args[2])
			}
			writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
			pretty.PrintBlockInfoHeader(writer)
			pretty.PrintBlockInfo(writer, blockInfo)
			return writer.Flush()
		}),
	}
	inspectBlock.Flags().IntVarP(&number, "shard", "s", 0, "shard to read from")
	inspectBlock.Flags().IntVarP(&modulus, "modulus", "m", 1, "modulus of the shards")

	listBlock := &cobra.Command{
		Use:   "list-block",
		Short: "Return the blocks in a directory.",
		Long:  "Return the blocks in a directory.",
		Run: pkgcobra.RunFixedArgs(0, func(args []string) error {
			apiClient, err := getAPIClient(address)
			if err != nil {
				return err
			}
			blockInfos, err := pfsutil.ListBlock(apiClient, shard())
			if err != nil {
				return err
			}
			writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
			pretty.PrintBlockInfoHeader(writer)
			for _, blockInfo := range blockInfos {
				pretty.PrintBlockInfo(writer, blockInfo)
			}
			return writer.Flush()
		}),
	}
	listBlock.Flags().IntVarP(&number, "shard", "s", 0, "shard to read from")
	listBlock.Flags().IntVarP(&modulus, "modulus", "m", 1, "modulus of the shards")

	mkdir := &cobra.Command{
		Use:   "mkdir repo-name commit-id path/to/dir",
		Short: "Make a directory.",
		Long:  "Make a directory. Parent directories need not exist.",
		Run: pkgcobra.RunFixedArgs(3, func(args []string) error {
			apiClient, err := getAPIClient(address)
			if err != nil {
				return err
			}
			return pfsutil.MakeDirectory(apiClient, args[0], args[1], args[2])
		}),
	}

	putFile := &cobra.Command{
		Use:   "put-file repo-name commit-id path/to/file",
		Short: "Put a file from stdin",
		Long:  "Put a file from stdin. Directories must exist. commit-id must be a writeable commit.",
		Run: pkgcobra.RunFixedArgs(3, func(args []string) error {
			apiClient, err := getAPIClient(address)
			if err != nil {
				return err
			}
			_, err = pfsutil.PutFile(apiClient, args[0], args[1], args[2], 0, os.Stdin)
			return err
		}),
	}

	getFile := &cobra.Command{
		Use:   "get-file repo-name commit-id path/to/file",
		Short: "Return the contents of a file.",
		Long:  "Return the contents of a file.",
		Run: pkgcobra.RunFixedArgs(3, func(args []string) error {
			apiClient, err := getAPIClient(address)
			if err != nil {
				return err
			}
			return pfsutil.GetFile(apiClient, args[0], args[1], args[2], 0, math.MaxInt64, shard(), os.Stdout)
		}),
	}
	getFile.Flags().IntVarP(&number, "shard", "s", 0, "shard to read from")
	getFile.Flags().IntVarP(&modulus, "modulus", "m", 1, "modulus of the shards")

	inspectFile := &cobra.Command{
		Use:   "inspect-file repo-name commit-id path/to/file",
		Short: "Return info about a file.",
		Long:  "Return info about a file.",
		Run: pkgcobra.RunFixedArgs(3, func(args []string) error {
			apiClient, err := getAPIClient(address)
			if err != nil {
				return err
			}
			fileInfo, err := pfsutil.InspectFile(apiClient, args[0], args[1], args[2], shard())
			if err != nil {
				return err
			}
			if fileInfo == nil {
				return fmt.Errorf("file %s not found", args[2])
			}
			writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
			pretty.PrintFileInfoHeader(writer)
			pretty.PrintFileInfo(writer, fileInfo)
			return writer.Flush()
		}),
	}
	inspectFile.Flags().IntVarP(&number, "shard", "s", 0, "shard to read from")
	inspectFile.Flags().IntVarP(&modulus, "modulus", "m", 1, "modulus of the shards")

	listFile := &cobra.Command{
		Use:   "list-file repo-name commit-id path/to/dir",
		Short: "Return the files in a directory.",
		Long:  "Return the files in a directory.",
		Run: pkgcobra.RunFixedArgs(3, func(args []string) error {
			apiClient, err := getAPIClient(address)
			if err != nil {
				return err
			}
			fileInfos, err := pfsutil.ListFile(apiClient, args[0], args[1], args[2], shard())
			if err != nil {
				return err
			}
			writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
			pretty.PrintFileInfoHeader(writer)
			for _, fileInfo := range fileInfos {
				pretty.PrintFileInfo(writer, fileInfo)
			}
			return writer.Flush()
		}),
	}
	listFile.Flags().IntVarP(&number, "shard", "s", 0, "shard to read from")
	listFile.Flags().IntVarP(&modulus, "modulus", "m", 1, "modulus of the shards")

	deleteFile := &cobra.Command{
		Use:   "delete-file repo-name commit-id path/to/file",
		Short: "Delete a file.",
		Long:  "Delete a file.",
		Run: pkgcobra.RunFixedArgs(2, func(args []string) error {
			apiClient, err := getAPIClient(address)
			if err != nil {
				return err
			}
			return pfsutil.DeleteFile(apiClient, args[0], args[1], args[2])
		}),
	}

	listChange := &cobra.Command{
		Use:   "list-change repo-name commit-id path/to/dir",
		Short: "Return the changes in a directory.",
		Long:  "Return the changes in a directory.",
		Run: pkgcobra.RunFixedArgs(3, func(args []string) error {
			apiClient, err := getAPIClient(address)
			if err != nil {
				return err
			}
			changeInfos, err := pfsutil.ListChange(apiClient, args[0], args[1], args[2], shard())
			if err != nil {
				return err
			}
			writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
			pretty.PrintChangeHeader(writer)
			for _, changeInfo := range changeInfos {
				pretty.PrintChange(writer, changeInfo)
			}
			return writer.Flush()
		}),
	}
	listChange.Flags().IntVarP(&number, "shard", "s", 0, "shard to read from")
	listChange.Flags().IntVarP(&modulus, "modulus", "m", 1, "modulus of the shards")

	inspectServer := &cobra.Command{
		Use:   "inspect-server server-id",
		Short: "Inspect a server.",
		Long:  "Inspect a server.",
		Run: pkgcobra.RunFixedArgs(1, func(args []string) error {
			clusterAPIClient, err := getClusterAPIClient(address)
			if err != nil {
				return err
			}
			serverInfo, err := pfsutil.InspectServer(clusterAPIClient, args[0])
			if err != nil {
				return err
			}
			writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
			pretty.PrintServerInfoHeader(writer)
			pretty.PrintServerInfo(writer, serverInfo)
			return writer.Flush()
		}),
	}

	listServer := &cobra.Command{
		Use:   "list-server",
		Short: "Return all servers in the cluster.",
		Long:  "Return all servers in the cluster.",
		Run: pkgcobra.RunFixedArgs(0, func(args []string) error {
			clusterAPIClient, err := getClusterAPIClient(address)
			if err != nil {
				return err
			}
			serverInfos, err := pfsutil.ListServer(clusterAPIClient)
			if err != nil {
				return err
			}
			writer := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
			pretty.PrintServerInfoHeader(writer)
			for _, serverInfo := range serverInfos {
				pretty.PrintServerInfo(writer, serverInfo)
			}
			return writer.Flush()
		}),
	}

	mount := &cobra.Command{
		Use:   "mount [mountpoint]",
		Short: "Mount pfs locally.",
		Long:  "Mount pfs locally.",
		Run: pkgcobra.RunBoundedArgs(pkgcobra.Bounds{Min: 0, Max: 1}, func(args []string) error {
			apiClient, err := getAPIClient(address)
			if err != nil {
				return err
			}
			mountPoint := "/pfs"
			if len(args) > 0 {
				mountPoint = args[0]
			}
			mounter := fuse.NewMounter(address, apiClient)
			return mounter.Mount(mountPoint, shard(), nil, nil)
		}),
	}
	mount.Flags().IntVarP(&number, "shard", "s", 0, "shard to read from")
	mount.Flags().IntVarP(&modulus, "modulus", "m", 1, "modulus of the shards")

	var result []*cobra.Command
	result = append(result, createRepo)
	result = append(result, inspectRepo)
	result = append(result, listRepo)
	result = append(result, deleteRepo)
	result = append(result, startCommit)
	result = append(result, finishCommit)
	result = append(result, inspectCommit)
	result = append(result, listCommit)
	result = append(result, deleteCommit)
	result = append(result, mkdir)
	result = append(result, putBlock)
	result = append(result, getBlock)
	result = append(result, inspectBlock)
	result = append(result, listBlock)
	result = append(result, putFile)
	result = append(result, getFile)
	result = append(result, inspectFile)
	result = append(result, listFile)
	result = append(result, deleteFile)
	result = append(result, listChange)
	result = append(result, inspectServer)
	result = append(result, listServer)
	result = append(result, mount)
	return result, nil
}
Example #5
0
func (d *driver) PutFile(file *pfs.File, shard uint64, offset int64, reader io.Reader) (retErr error) {
	d.lock.RLock()
	diffInfo, ok := d.started.get(&drive.Diff{
		Commit: file.Commit,
		Shard:  shard,
	})
	d.lock.RUnlock()
	if !ok {
		return fmt.Errorf("commit %s/%s not found", file.Commit.Repo.Name, file.Commit.Id)
	}
	var blockRefs []*drive.BlockRef
	scanner := bufio.NewScanner(reader)
	scanner.Split(blockSplitFunc)
	var wg sync.WaitGroup
	var loopErr error
	var sizeBytes uint64
	for scanner.Scan() {
		data := scanner.Bytes()
		blockRef := &drive.BlockRef{
			Range: &drive.ByteRange{
				Lower: 0,
				Upper: uint64(len(data)),
			},
		}
		blockRefs = append(blockRefs, blockRef)
		sizeBytes += blockRef.Range.Upper - blockRef.Range.Lower
		wg.Add(1)
		go func() {
			defer wg.Done()
			block, err := pfsutil.PutBlock(d.driveClient, bytes.NewReader(data))
			if err != nil && loopErr == nil {
				loopErr = err
				return
			}
			blockRef.Block = block
		}()
	}
	wg.Wait()
	if err := scanner.Err(); err != nil {
		return err
	}
	if loopErr != nil {
		return loopErr
	}
	d.lock.Lock()
	defer d.lock.Unlock()
	diffInfo, ok = d.started.get(&drive.Diff{
		Commit: file.Commit,
		Shard:  shard,
	})
	if !ok {
		// This is a weird case since the commit existed above, it means someone
		// deleted the commit while the above code was running
		return fmt.Errorf("commit %s/%s not found", file.Commit.Repo.Name, file.Commit.Id)
	}
	addDirs(diffInfo, file)
	_append, ok := diffInfo.Appends[path.Clean(file.Path)]
	if !ok {
		_append = &drive.Append{}
		if diffInfo.ParentCommit != nil {
			_append.LastRef = d.lastRef(
				pfsutil.NewFile(
					diffInfo.ParentCommit.Repo.Name,
					diffInfo.ParentCommit.Id,
					file.Path,
				),
				shard,
			)
		}
		diffInfo.Appends[path.Clean(file.Path)] = _append
	}
	_append.BlockRefs = append(_append.BlockRefs, blockRefs...)
	diffInfo.SizeBytes += sizeBytes
	return nil
}