Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: support --format (pb and json) #52

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions commands/apply.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package commands

import (
"io/ioutil"
"log"

"github.com/containerd/continuity"
Expand All @@ -14,14 +13,9 @@ var ApplyCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
root, path := args[0], args[1]

p, err := ioutil.ReadFile(path)
m, err := readManifest(path)
if err != nil {
log.Fatalf("error reading manifest: %v", err)
}

m, err := continuity.Unmarshal(p)
if err != nil {
log.Fatalf("error unmarshaling manifest: %v", err)
log.Fatal(err)
}

ctx, err := continuity.NewContext(root)
Expand Down
22 changes: 19 additions & 3 deletions commands/build.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package commands

import (
"fmt"
"log"
"os"

Expand All @@ -13,6 +14,13 @@ var (
format string
}

marshalers = map[string]func(*continuity.Manifest) ([]byte, error){
"pb": continuity.Marshal,
continuity.MediaTypeManifestV0Protobuf: continuity.Marshal,
"json": continuity.MarshalJSON,
continuity.MediaTypeManifestV0JSON: continuity.MarshalJSON,
}

BuildCmd = &cobra.Command{
Use: "build <root>",
Short: "Build a manifest for the provided root",
Expand All @@ -31,9 +39,15 @@ var (
log.Fatalf("error generating manifest: %v", err)
}

p, err := continuity.Marshal(m)
marshaler, ok := marshalers[buildCmdConfig.format]
if !ok {
log.Fatalf("unknown format %s", buildCmdConfig.format)
}

p, err := marshaler(m)
if err != nil {
log.Fatalf("error marshaling manifest: %v", err)
log.Fatalf("error marshalling manifest as %s: %v",
buildCmdConfig.format, err)
}

if _, err := os.Stdout.Write(p); err != nil {
Expand All @@ -44,5 +58,7 @@ var (
)

func init() {
BuildCmd.Flags().StringVar(&buildCmdConfig.format, "format", "pb", "specify the output format of the manifest")
BuildCmd.Flags().StringVar(&buildCmdConfig.format, "format", "pb",
fmt.Sprintf("specify the output format of the manifest (\"pb\"|%q|\"json\"|%q)",
continuity.MediaTypeManifestV0Protobuf, continuity.MediaTypeManifestV0JSON))
}
22 changes: 22 additions & 0 deletions commands/commandsutil.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package commands

import (
"fmt"
"io/ioutil"
"path/filepath"
"strings"

"github.com/containerd/continuity"
)

func readManifest(path string) (*continuity.Manifest, error) {
p, err := ioutil.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("error reading manifest: %v", err)
}
ext := strings.ToLower(filepath.Ext(path))
if ext == ".json" {
return continuity.UnmarshalJSON(p)
}
return continuity.Unmarshal(p)
}
10 changes: 2 additions & 8 deletions commands/mount.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package commands

import (
"io/ioutil"
"log"
"os"
"os/signal"
Expand Down Expand Up @@ -30,14 +29,9 @@ var MountCmd = &cobra.Command{

manifestName := filepath.Base(manifest)

p, err := ioutil.ReadFile(manifest)
m, err := readManifest(manifest)
if err != nil {
log.Fatalf("error reading manifest: %v", err)
}

m, err := continuity.Unmarshal(p)
if err != nil {
log.Fatalf("error unmarshaling manifest: %v", err)
log.Fatal(err)
}

driver, err := continuity.NewSystemDriver()
Expand Down
10 changes: 2 additions & 8 deletions commands/verify.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package commands

import (
"io/ioutil"
"log"

"github.com/containerd/continuity"
Expand All @@ -18,14 +17,9 @@ var VerifyCmd = &cobra.Command{

root, path := args[0], args[1]

p, err := ioutil.ReadFile(path)
m, err := readManifest(path)
if err != nil {
log.Fatalf("error reading manifest: %v", err)
}

m, err := continuity.Unmarshal(p)
if err != nil {
log.Fatalf("error unmarshaling manifest: %v", err)
log.Fatal(err)
}

ctx, err := continuity.NewContext(root)
Expand Down
57 changes: 43 additions & 14 deletions manifest.go
Original file line number Diff line number Diff line change
@@ -1,30 +1,37 @@
package continuity

import (
"bytes"
"fmt"
"io"
"log"
"os"
"sort"

pb "github.com/containerd/continuity/proto"
"github.com/golang/protobuf/jsonpb"
"github.com/golang/protobuf/proto"
)

const (
// MediaTypeManifestV0Protobuf is the media type for manifest formatted as protobuf.
// The format is unstable during v0.
MediaTypeManifestV0Protobuf = "application/vnd.continuity.manifest.v0+pb"
// MediaTypeManifestV0JSON is the media type for manifest formatted as JSON.
// JSON is marshalled from protobuf using jsonpb.Marshaler
// ({EnumAsInts = false, EmitDefaults = false, OrigName = false})
// The format is unstable during v0.
MediaTypeManifestV0JSON = "application/vnd.continuity.manifest.v0+json"
)

// Manifest provides the contents of a manifest. Users of this struct should
// not typically modify any fields directly.
type Manifest struct {
// Resources specifies all the resources for a manifest in order by path.
Resources []Resource
}

func Unmarshal(p []byte) (*Manifest, error) {
var bm pb.Manifest

if err := proto.Unmarshal(p, &bm); err != nil {
return nil, err
}

func manifestFromProto(bm *pb.Manifest) (*Manifest, error) {
var m Manifest
for _, b := range bm.Resource {
r, err := fromProto(b)
Expand All @@ -34,26 +41,48 @@ func Unmarshal(p []byte) (*Manifest, error) {

m.Resources = append(m.Resources, r)
}

return &m, nil
}

func Marshal(m *Manifest) ([]byte, error) {
func Unmarshal(p []byte) (*Manifest, error) {
var bm pb.Manifest
for _, resource := range m.Resources {
bm.Resource = append(bm.Resource, toProto(resource))
if err := proto.Unmarshal(p, &bm); err != nil {
return nil, err
}
return manifestFromProto(&bm)
}

return proto.Marshal(&bm)
func UnmarshalJSON(p []byte) (*Manifest, error) {
var bm pb.Manifest
if err := jsonpb.Unmarshal(bytes.NewReader(p), &bm); err != nil {
return nil, err
}
return manifestFromProto(&bm)
}

func MarshalText(w io.Writer, m *Manifest) error {
func manifestToProto(m *Manifest) *pb.Manifest {
var bm pb.Manifest
for _, resource := range m.Resources {
bm.Resource = append(bm.Resource, toProto(resource))
}
return &bm
}

return proto.MarshalText(w, &bm)
func Marshal(m *Manifest) ([]byte, error) {
return proto.Marshal(manifestToProto(m))
}

func MarshalText(w io.Writer, m *Manifest) error {
return proto.MarshalText(w, manifestToProto(m))
}

func MarshalJSON(m *Manifest) ([]byte, error) {
var b bytes.Buffer
marshaler := &jsonpb.Marshaler{}
if err := marshaler.Marshal(&b, manifestToProto(m)); err != nil {
return nil, err
}
return b.Bytes(), nil
}

// BuildManifest creates the manifest for the given context
Expand Down