Merge pull request #786 from stevvooe/edit-content-command

cmd/dist: add ability to edit content
This commit is contained in:
Derek McGowan 2017-05-08 10:59:22 -07:00 committed by GitHub
commit b12f18919d
4 changed files with 121 additions and 2 deletions

113
cmd/dist/edit.go vendored Normal file
View 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
View File

@ -106,6 +106,7 @@ var contentCommand = cli.Command{
ingestCommand, ingestCommand,
activeCommand, activeCommand,
getCommand, getCommand,
editCommand,
deleteCommand, deleteCommand,
}, },
} }

View File

@ -127,6 +127,9 @@ func (rw *remoteWriter) Write(p []byte) (n int, err error) {
} }
rw.offset += int64(n) rw.offset += int64(n)
if resp.Digest != "" {
rw.digest = resp.Digest
}
return 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) return errors.Errorf("unexpected digest: %v != %v", resp.Digest, expected)
} }
rw.digest = resp.Digest
rw.offset = resp.Offset
return nil return nil
} }

View File

@ -304,9 +304,9 @@ func (s *Service) Write(session api.Content_WriteServer) (err error) {
if err := wr.Commit(total, expected); err != nil { if err := wr.Commit(total, expected); err != nil {
return err return err
} }
msg.Digest = wr.Digest()
} }
msg.Digest = wr.Digest()
case api.WriteActionAbort: case api.WriteActionAbort:
return s.store.Abort(ref) return s.store.Abort(ref)
} }