Merge pull request #786 from stevvooe/edit-content-command
cmd/dist: add ability to edit content
This commit is contained in:
commit
b12f18919d
113
cmd/dist/edit.go
vendored
Normal file
113
cmd/dist/edit.go
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
contentapi "github.com/containerd/containerd/api/services/content"
|
||||
contentservice "github.com/containerd/containerd/services/content"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var editCommand = cli.Command{
|
||||
Name: "edit",
|
||||
Usage: "edit a blob and return a new digest.",
|
||||
ArgsUsage: "[flags] <digest>",
|
||||
Description: `Edit a blob and return a new digest.`,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "validate",
|
||||
Usage: "validate the result against a format (json, mediatype, etc.)",
|
||||
},
|
||||
},
|
||||
Action: func(context *cli.Context) error {
|
||||
var (
|
||||
ctx = background
|
||||
validate = context.String("validate")
|
||||
object = context.Args().First()
|
||||
)
|
||||
|
||||
if validate != "" {
|
||||
return errors.New("validating the edit result not supported")
|
||||
}
|
||||
|
||||
// TODO(stevvooe): Support looking up objects by a reference through
|
||||
// the image metadata storage.
|
||||
|
||||
dgst, err := digest.Parse(object)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
conn, err := connectGRPC(context)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
provider := contentservice.NewProviderFromClient(contentapi.NewContentClient(conn))
|
||||
ingester := contentservice.NewIngesterFromClient(contentapi.NewContentClient(conn))
|
||||
|
||||
rc, err := provider.Reader(ctx, dgst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer rc.Close()
|
||||
|
||||
nrc, err := edit(rc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
wr, err := ingester.Writer(ctx, "edit-"+object, 0, "") // TODO(stevvooe): Choose a better key?
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := io.Copy(wr, nrc); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := wr.Commit(0, wr.Digest()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(wr.Digest())
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func edit(rd io.Reader) (io.ReadCloser, error) {
|
||||
tmp, err := ioutil.TempFile("", "edit-")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := io.Copy(tmp, rd); err != nil {
|
||||
tmp.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmd := exec.Command("sh", "-c", "$EDITOR "+tmp.Name())
|
||||
|
||||
cmd.Stdin = os.Stdin
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Env = os.Environ()
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
tmp.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := tmp.Seek(0, io.SeekStart); err != nil {
|
||||
tmp.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return tmp, nil
|
||||
}
|
1
cmd/dist/main.go
vendored
1
cmd/dist/main.go
vendored
@ -106,6 +106,7 @@ var contentCommand = cli.Command{
|
||||
ingestCommand,
|
||||
activeCommand,
|
||||
getCommand,
|
||||
editCommand,
|
||||
deleteCommand,
|
||||
},
|
||||
}
|
||||
|
@ -127,6 +127,9 @@ func (rw *remoteWriter) Write(p []byte) (n int, err error) {
|
||||
}
|
||||
|
||||
rw.offset += int64(n)
|
||||
if resp.Digest != "" {
|
||||
rw.digest = resp.Digest
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -149,6 +152,8 @@ func (rw *remoteWriter) Commit(size int64, expected digest.Digest) error {
|
||||
return errors.Errorf("unexpected digest: %v != %v", resp.Digest, expected)
|
||||
}
|
||||
|
||||
rw.digest = resp.Digest
|
||||
rw.offset = resp.Offset
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -304,9 +304,9 @@ func (s *Service) Write(session api.Content_WriteServer) (err error) {
|
||||
if err := wr.Commit(total, expected); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg.Digest = wr.Digest()
|
||||
}
|
||||
|
||||
msg.Digest = wr.Digest()
|
||||
case api.WriteActionAbort:
|
||||
return s.store.Abort(ref)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user