Add --json to many of the CLI commands

Add a --json flag to most of the CLI commands, to force output that
would have gone to stdout to be output as JSON instead of whatever form
it would otherwise take.  Error messages sent to stderr are still plain
text.

Use this chance to rework the wrapping logic so that it's more
consistent: commands that take multiple IDs attempt the specified
operation on all of them, and report errors afterward.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
This commit is contained in:
Nalin Dahyabhai 2016-07-20 15:19:49 -04:00
parent 62e67e678d
commit b50f33bf70
13 changed files with 226 additions and 52 deletions

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"encoding/json"
"fmt" "fmt"
"os" "os"
@ -19,11 +20,19 @@ func container(flags *mflag.FlagSet, action string, m storage.Mall, args []strin
fmt.Fprintf(os.Stderr, "%v\n", err) fmt.Fprintf(os.Stderr, "%v\n", err)
return 1 return 1
} }
matches := []storage.Container{}
for _, container := range containers { for _, container := range containers {
for _, arg := range args { for _, arg := range args {
if container.ID != arg && container.Name != "" && container.Name != arg { if container.ID != arg && container.Name != "" && container.Name != arg {
continue continue
} }
matches = append(matches, container)
}
}
if jsonOutput {
json.NewEncoder(os.Stdout).Encode(matches)
} else {
for _, container := range matches {
fmt.Printf("ID: %s\n", container.ID) fmt.Printf("ID: %s\n", container.ID)
if container.Name != "" { if container.Name != "" {
fmt.Printf("Name: %s\n", container.Name) fmt.Printf("Name: %s\n", container.Name)
@ -37,6 +46,9 @@ func container(flags *mflag.FlagSet, action string, m storage.Mall, args []strin
fmt.Printf("Layer: %s\n", container.LayerID) fmt.Printf("Layer: %s\n", container.LayerID)
} }
} }
if len(matches) != len(args) {
return 1
}
return 0 return 0
} }
@ -47,5 +59,8 @@ func init() {
usage: "Examine a container", usage: "Examine a container",
action: container, action: container,
minArgs: 1, minArgs: 1,
addFlags: func(flags *mflag.FlagSet, cmd *command) {
flags.BoolVar(&jsonOutput, []string{"-json", "j"}, jsonOutput, "prefer JSON output")
},
}) })
} }

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"encoding/json"
"fmt" "fmt"
"os" "os"
@ -14,10 +15,14 @@ func containers(flags *mflag.FlagSet, action string, m storage.Mall, args []stri
fmt.Fprintf(os.Stderr, "%v\n", err) fmt.Fprintf(os.Stderr, "%v\n", err)
return 1 return 1
} }
for _, container := range containers { if jsonOutput {
fmt.Printf("%s\n", container.ID) json.NewEncoder(os.Stdout).Encode(containers)
if container.Name != "" { } else {
fmt.Printf("\t%s\n", container.Name) for _, container := range containers {
fmt.Printf("%s\n", container.ID)
if container.Name != "" {
fmt.Printf("\t%s\n", container.Name)
}
} }
} }
return 0 return 0
@ -30,5 +35,8 @@ func init() {
usage: "List containers", usage: "List containers",
action: containers, action: containers,
maxArgs: 0, maxArgs: 0,
addFlags: func(flags *mflag.FlagSet, cmd *command) {
flags.BoolVar(&jsonOutput, []string{"-json", "j"}, jsonOutput, "prefer JSON output")
},
}) })
} }

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os" "os"
@ -29,10 +30,14 @@ func createLayer(flags *mflag.FlagSet, action string, m storage.Mall, args []str
fmt.Fprintf(os.Stderr, "%v\n", err) fmt.Fprintf(os.Stderr, "%v\n", err)
return 1 return 1
} }
if layer.Name != "" { if jsonOutput {
fmt.Printf("%s\t%s\n", layer.ID, layer.Name) json.NewEncoder(os.Stdout).Encode(layer)
} else { } else {
fmt.Printf("%s\n", layer.ID) if layer.Name != "" {
fmt.Printf("%s\t%s\n", layer.ID, layer.Name)
} else {
fmt.Printf("%s\n", layer.ID)
}
} }
return 0 return 0
} }
@ -56,10 +61,14 @@ func createImage(flags *mflag.FlagSet, action string, m storage.Mall, args []str
fmt.Fprintf(os.Stderr, "%v\n", err) fmt.Fprintf(os.Stderr, "%v\n", err)
return 1 return 1
} }
if image.Name != "" { if jsonOutput {
fmt.Printf("%s\t%s\n", image.ID, image.Name) json.NewEncoder(os.Stdout).Encode(image)
} else { } else {
fmt.Printf("%s\n", image.ID) if image.Name != "" {
fmt.Printf("%s\t%s\n", image.ID, image.Name)
} else {
fmt.Printf("%s\n", image.ID)
}
} }
return 0 return 0
} }
@ -83,10 +92,14 @@ func createContainer(flags *mflag.FlagSet, action string, m storage.Mall, args [
fmt.Fprintf(os.Stderr, "%v\n", err) fmt.Fprintf(os.Stderr, "%v\n", err)
return 1 return 1
} }
if container.Name != "" { if jsonOutput {
fmt.Printf("%s\t%s\n", container.ID, container.Name) json.NewEncoder(os.Stdout).Encode(container)
} else { } else {
fmt.Printf("%s\n", container.ID) if container.Name != "" {
fmt.Printf("%s\t%s\n", container.ID, container.Name)
} else {
fmt.Printf("%s\n", container.ID)
}
} }
return 0 return 0
} }
@ -103,6 +116,7 @@ func init() {
flags.StringVar(&paramName, []string{"-name", "n"}, "", "Layer name") flags.StringVar(&paramName, []string{"-name", "n"}, "", "Layer name")
flags.StringVar(&paramID, []string{"-id", "i"}, "", "Layer ID") flags.StringVar(&paramID, []string{"-id", "i"}, "", "Layer ID")
flags.BoolVar(&paramCreateRO, []string{"-readonly", "r"}, false, "Mark as read-only") flags.BoolVar(&paramCreateRO, []string{"-readonly", "r"}, false, "Mark as read-only")
flags.BoolVar(&jsonOutput, []string{"-json", "j"}, jsonOutput, "prefer JSON output")
}, },
}) })
commands = append(commands, command{ commands = append(commands, command{
@ -117,6 +131,7 @@ func init() {
flags.StringVar(&paramID, []string{"-id", "i"}, "", "Image ID") flags.StringVar(&paramID, []string{"-id", "i"}, "", "Image ID")
flags.StringVar(&paramMetadata, []string{"-metadata", "m"}, "", "Metadata") flags.StringVar(&paramMetadata, []string{"-metadata", "m"}, "", "Metadata")
flags.StringVar(&paramMetadataFile, []string{"-metadata-file", "f"}, "", "Metadata File") flags.StringVar(&paramMetadataFile, []string{"-metadata-file", "f"}, "", "Metadata File")
flags.BoolVar(&jsonOutput, []string{"-json", "j"}, jsonOutput, "prefer JSON output")
}, },
}) })
commands = append(commands, command{ commands = append(commands, command{
@ -131,6 +146,7 @@ func init() {
flags.StringVar(&paramID, []string{"-id", "i"}, "", "Container ID") flags.StringVar(&paramID, []string{"-id", "i"}, "", "Container ID")
flags.StringVar(&paramMetadata, []string{"-metadata", "m"}, "", "Metadata") flags.StringVar(&paramMetadata, []string{"-metadata", "m"}, "", "Metadata")
flags.StringVar(&paramMetadataFile, []string{"-metadata-file", "f"}, "", "Metadata File") flags.StringVar(&paramMetadataFile, []string{"-metadata-file", "f"}, "", "Metadata File")
flags.BoolVar(&jsonOutput, []string{"-json", "j"}, jsonOutput, "prefer JSON output")
}, },
}) })
} }

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"encoding/json"
"fmt" "fmt"
"os" "os"
@ -12,10 +13,22 @@ func deleteThing(flags *mflag.FlagSet, action string, m storage.Mall, args []str
if len(args) < 1 { if len(args) < 1 {
return 1 return 1
} }
deleted := make(map[string]error)
for _, what := range args { for _, what := range args {
err := m.Delete(what) err := m.Delete(what)
deleted[what] = err
}
if jsonOutput {
json.NewEncoder(os.Stdout).Encode(deleted)
} else {
for what, err := range deleted {
if err != nil {
fmt.Fprintf(os.Stderr, "%s: %v\n", what, err)
}
}
}
for _, err := range deleted {
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "%s: %v\n", what, err)
return 1 return 1
} }
} }
@ -29,5 +42,8 @@ func init() {
usage: "Delete a layer or image or container", usage: "Delete a layer or image or container",
minArgs: 1, minArgs: 1,
action: deleteThing, action: deleteThing,
addFlags: func(flags *mflag.FlagSet, cmd *command) {
flags.BoolVar(&jsonOutput, []string{"-json", "j"}, jsonOutput, "prefer JSON output")
},
}) })
} }

View File

@ -1,7 +1,9 @@
package main package main
import ( import (
"encoding/json"
"fmt" "fmt"
"os"
"github.com/containers/storage/pkg/mflag" "github.com/containers/storage/pkg/mflag"
"github.com/containers/storage/storage" "github.com/containers/storage/storage"
@ -13,15 +15,25 @@ func exist(flags *mflag.FlagSet, action string, m storage.Mall, args []string) i
if len(args) < 1 { if len(args) < 1 {
return 1 return 1
} }
allExist := true anyMissing := false
existDict := make(map[string]bool)
for _, what := range args { for _, what := range args {
exists := m.Exists(what) exists := m.Exists(what)
if !existQuiet { existDict[what] = exists
fmt.Printf("%s: %v\n", what, exists) if !exists {
anyMissing = true
} }
allExist = allExist && exists
} }
if !allExist { if jsonOutput {
json.NewEncoder(os.Stdout).Encode(existDict)
} else {
if !existQuiet {
for what, exists := range existDict {
fmt.Printf("%s: %v\n", what, exists)
}
}
}
if anyMissing {
return 1 return 1
} }
return 0 return 0
@ -36,6 +48,7 @@ func init() {
action: exist, action: exist,
addFlags: func(flags *mflag.FlagSet, cmd *command) { addFlags: func(flags *mflag.FlagSet, cmd *command) {
flags.BoolVar(&existQuiet, []string{"-quiet", "q"}, existQuiet, "Don't print names") flags.BoolVar(&existQuiet, []string{"-quiet", "q"}, existQuiet, "Don't print names")
flags.BoolVar(&jsonOutput, []string{"-json", "j"}, jsonOutput, "prefer JSON output")
}, },
}) })
} }

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"encoding/json"
"fmt" "fmt"
"os" "os"
@ -14,11 +15,19 @@ func image(flags *mflag.FlagSet, action string, m storage.Mall, args []string) i
fmt.Fprintf(os.Stderr, "%v\n", err) fmt.Fprintf(os.Stderr, "%v\n", err)
return 1 return 1
} }
matched := []storage.Image{}
for _, image := range images { for _, image := range images {
for _, arg := range args { for _, arg := range args {
if image.ID != arg && image.Name != "" && image.Name != arg { if image.ID != arg && image.Name != "" && image.Name != arg {
continue continue
} }
matched = append(matched, image)
}
}
if jsonOutput {
json.NewEncoder(os.Stdout).Encode(matched)
} else {
for _, image := range matched {
fmt.Printf("ID: %s\n", image.ID) fmt.Printf("ID: %s\n", image.ID)
if image.Name != "" { if image.Name != "" {
fmt.Printf("Name: %s\n", image.Name) fmt.Printf("Name: %s\n", image.Name)
@ -26,6 +35,9 @@ func image(flags *mflag.FlagSet, action string, m storage.Mall, args []string) i
fmt.Printf("Top Layer: %s\n", image.TopLayer) fmt.Printf("Top Layer: %s\n", image.TopLayer)
} }
} }
if len(matched) != len(args) {
return 1
}
return 0 return 0
} }
@ -36,5 +48,8 @@ func init() {
usage: "Examine an image", usage: "Examine an image",
action: image, action: image,
minArgs: 1, minArgs: 1,
addFlags: func(flags *mflag.FlagSet, cmd *command) {
flags.BoolVar(&jsonOutput, []string{"-json", "j"}, jsonOutput, "prefer JSON output")
},
}) })
} }

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"encoding/json"
"fmt" "fmt"
"os" "os"
@ -14,10 +15,14 @@ func images(flags *mflag.FlagSet, action string, m storage.Mall, args []string)
fmt.Fprintf(os.Stderr, "%v\n", err) fmt.Fprintf(os.Stderr, "%v\n", err)
return 1 return 1
} }
for _, image := range images { if jsonOutput {
fmt.Printf("%s\n", image.ID) json.NewEncoder(os.Stdout).Encode(images)
if image.Name != "" { } else {
fmt.Printf("\t%s\n", image.Name) for _, image := range images {
fmt.Printf("%s\n", image.ID)
if image.Name != "" {
fmt.Printf("\t%s\n", image.Name)
}
} }
} }
return 0 return 0
@ -30,5 +35,8 @@ func init() {
usage: "List images", usage: "List images",
action: images, action: images,
maxArgs: 0, maxArgs: 0,
addFlags: func(flags *mflag.FlagSet, cmd *command) {
flags.BoolVar(&jsonOutput, []string{"-json", "j"}, jsonOutput, "prefer JSON output")
},
}) })
} }

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"encoding/json"
"fmt" "fmt"
"os" "os"
@ -16,6 +17,10 @@ func layers(flags *mflag.FlagSet, action string, m storage.Mall, args []string)
fmt.Fprintf(os.Stderr, "%v\n", err) fmt.Fprintf(os.Stderr, "%v\n", err)
return 1 return 1
} }
if jsonOutput {
json.NewEncoder(os.Stdout).Encode(layers)
return 0
}
imageMap := make(map[string]storage.Image) imageMap := make(map[string]storage.Image)
if images, err := m.Images(); err == nil { if images, err := m.Images(); err == nil {
for _, image := range images { for _, image := range images {
@ -92,6 +97,7 @@ func init() {
maxArgs: 0, maxArgs: 0,
addFlags: func(flags *mflag.FlagSet, cmd *command) { addFlags: func(flags *mflag.FlagSet, cmd *command) {
flags.BoolVar(&listLayersTree, []string{"-tree", "t"}, listLayersTree, "Use a tree") flags.BoolVar(&listLayersTree, []string{"-tree", "t"}, listLayersTree, "Use a tree")
flags.BoolVar(&jsonOutput, []string{"-json", "j"}, jsonOutput, "prefer JSON output")
}, },
}) })
} }

View File

@ -22,7 +22,10 @@ type command struct {
action func(*mflag.FlagSet, string, storage.Mall, []string) int action func(*mflag.FlagSet, string, storage.Mall, []string) int
} }
var commands = []command{} var (
commands = []command{}
jsonOutput = false
)
func main() { func main() {
if reexec.Init() { if reexec.Init() {
@ -30,18 +33,24 @@ func main() {
} }
graphRoot := "/var/lib/oci-storage" graphRoot := "/var/lib/oci-storage"
graphDriver := os.Getenv("DOCKER_GRAPHDRIVER") graphDriver := os.Getenv("STORAGE_DRIVER")
graphOptions := strings.Split(os.Getenv("DOCKER_STORAGE_OPTS"), ",") if graphDriver == "" {
graphDriver = os.Getenv("DOCKER_GRAPHDRIVER")
}
graphOptions := strings.Split(os.Getenv("STORAGE_OPTS"), ",")
if len(graphOptions) == 1 && graphOptions[0] == "" { if len(graphOptions) == 1 && graphOptions[0] == "" {
graphOptions = nil graphOptions = strings.Split(os.Getenv("DOCKER_STORAGE_OPTS"), ",")
if len(graphOptions) == 1 && graphOptions[0] == "" {
graphOptions = nil
}
} }
debug := false debug := false
makeFlags := func(command string, eh mflag.ErrorHandling) *mflag.FlagSet { makeFlags := func(command string, eh mflag.ErrorHandling) *mflag.FlagSet {
flags := mflag.NewFlagSet(command, eh) flags := mflag.NewFlagSet(command, eh)
flags.StringVar(&graphRoot, []string{"-graph", "g"}, graphRoot, "Root of the storage tree") flags.StringVar(&graphRoot, []string{"-graph", "g"}, graphRoot, "Root of the storage tree")
flags.StringVar(&graphDriver, []string{"-storage-driver", "s"}, graphDriver, "Storage driver to use ($DOCKER_GRAPHDRIVER)") flags.StringVar(&graphDriver, []string{"-storage-driver", "s"}, graphDriver, "Storage driver to use ($STORAGE_DRIVER)")
flags.Var(opts.NewListOptsRef(&graphOptions, nil), []string{"-storage-opt"}, "Set storage driver options ($DOCKER_STORAGE_OPTS)") flags.Var(opts.NewListOptsRef(&graphOptions, nil), []string{"-storage-opt"}, "Set storage driver options ($STORAGE_OPTS)")
flags.BoolVar(&debug, []string{"-debug", "D"}, debug, "Print debugging information") flags.BoolVar(&debug, []string{"-debug", "D"}, debug, "Print debugging information")
return flags return flags
} }

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os" "os"
@ -16,27 +17,29 @@ func metadata(flags *mflag.FlagSet, action string, m storage.Mall, args []string
if len(args) < 1 { if len(args) < 1 {
return 1 return 1
} }
allExist := true metadataDict := make(map[string]string)
missingAny := false
for _, what := range args { for _, what := range args {
exists := false
if container, err := m.GetContainer(what); err == nil { if container, err := m.GetContainer(what); err == nil {
exists = true metadataDict[what] = strings.TrimSuffix(container.Metadata, "\n")
if metadataQuiet {
fmt.Printf("%s\n", strings.TrimSuffix(container.Metadata, "\n"))
} else {
fmt.Printf("%s: %s\n", what, strings.TrimSuffix(container.Metadata, "\n"))
}
} else if image, err := m.GetImage(what); err == nil { } else if image, err := m.GetImage(what); err == nil {
exists = true metadataDict[what] = strings.TrimSuffix(image.Metadata, "\n")
} else {
missingAny = true
}
}
if jsonOutput {
json.NewEncoder(os.Stdout).Encode(metadataDict)
} else {
for id, metadata := range metadataDict {
if metadataQuiet { if metadataQuiet {
fmt.Printf("%s\n", strings.TrimSuffix(image.Metadata, "\n")) fmt.Printf("%s\n", metadata)
} else { } else {
fmt.Printf("%s: %s\n", what, strings.TrimSuffix(image.Metadata, "\n")) fmt.Printf("%s: %s\n", id, metadata)
} }
} }
allExist = allExist && exists
} }
if !allExist { if missingAny {
return 1 return 1
} }
return 0 return 0
@ -78,7 +81,8 @@ func init() {
minArgs: 1, minArgs: 1,
action: metadata, action: metadata,
addFlags: func(flags *mflag.FlagSet, cmd *command) { addFlags: func(flags *mflag.FlagSet, cmd *command) {
flags.BoolVar(&metadataQuiet, []string{"-quiet", "q"}, metadataQuiet, "Don't print names and IDs") flags.BoolVar(&metadataQuiet, []string{"-quiet", "q"}, metadataQuiet, "Omit names and IDs")
flags.BoolVar(&jsonOutput, []string{"-json", "j"}, jsonOutput, "prefer JSON output")
}, },
}) })
commands = append(commands, command{ commands = append(commands, command{

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"encoding/json"
"fmt" "fmt"
"os" "os"
@ -8,24 +9,61 @@ import (
"github.com/containers/storage/storage" "github.com/containers/storage/storage"
) )
type mountPointOrError struct {
ID string `json:"id"`
MountPoint string `json:"mountpoint"`
Error error `json:"error"`
}
type mountPointError struct {
ID string `json:"id"`
Error error `json:"error"`
}
func mount(flags *mflag.FlagSet, action string, m storage.Mall, args []string) int { func mount(flags *mflag.FlagSet, action string, m storage.Mall, args []string) int {
moes := []mountPointOrError{}
for _, arg := range args { for _, arg := range args {
result, err := m.Mount(arg, paramMountLabel) result, err := m.Mount(arg, paramMountLabel)
if err != nil { moes = append(moes, mountPointOrError{arg, result, err})
fmt.Fprintf(os.Stderr, "%s while mounting %s\n", err, arg) }
if jsonOutput {
json.NewEncoder(os.Stdout).Encode(moes)
} else {
for _, mountOrError := range moes {
if mountOrError.Error != nil {
fmt.Fprintf(os.Stderr, "%s while mounting %s\n", mountOrError.Error, mountOrError.ID)
}
fmt.Printf("%s\n", mountOrError.MountPoint)
}
}
for _, mountOrErr := range moes {
if mountOrErr.Error != nil {
return 1 return 1
} }
fmt.Printf("%s\n", result)
} }
return 0 return 0
} }
func unmount(flags *mflag.FlagSet, action string, m storage.Mall, args []string) int { func unmount(flags *mflag.FlagSet, action string, m storage.Mall, args []string) int {
mes := []mountPointError{}
errors := false
for _, arg := range args { for _, arg := range args {
if err := m.Unmount(arg); err != nil { err := m.Unmount(arg)
fmt.Fprintf(os.Stderr, "%s while unmounting %s\n", err, arg) if err != nil {
return 1 errors = true
} }
mes = append(mes, mountPointError{arg, err})
}
if jsonOutput {
json.NewEncoder(os.Stdout).Encode(mes)
} else {
for _, me := range mes {
if me.Error != nil {
fmt.Fprintf(os.Stderr, "%s while unmounting %s\n", me.Error, me.ID)
}
}
}
if errors {
return 1
} }
return 0 return 0
} }
@ -39,6 +77,7 @@ func init() {
action: mount, action: mount,
addFlags: func(flags *mflag.FlagSet, cmd *command) { addFlags: func(flags *mflag.FlagSet, cmd *command) {
flags.StringVar(&paramMountLabel, []string{"-label", "l"}, "", "Mount Label") flags.StringVar(&paramMountLabel, []string{"-label", "l"}, "", "Mount Label")
flags.BoolVar(&jsonOutput, []string{"-json", "j"}, jsonOutput, "prefer JSON output")
}, },
}) })
commands = append(commands, command{ commands = append(commands, command{
@ -47,5 +86,8 @@ func init() {
usage: "Unmount a layer or container", usage: "Unmount a layer or container",
minArgs: 1, minArgs: 1,
action: unmount, action: unmount,
addFlags: func(flags *mflag.FlagSet, cmd *command) {
flags.BoolVar(&jsonOutput, []string{"-json", "j"}, jsonOutput, "prefer JSON output")
},
}) })
} }

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"encoding/json"
"fmt" "fmt"
"os" "os"
@ -14,8 +15,12 @@ func status(flags *mflag.FlagSet, action string, m storage.Mall, args []string)
fmt.Fprintf(os.Stderr, "status: %v\n", err) fmt.Fprintf(os.Stderr, "status: %v\n", err)
return 1 return 1
} }
for _, pair := range status { if jsonOutput {
fmt.Fprintf(os.Stderr, "%s: %s\n", pair[0], pair[1]) json.NewEncoder(os.Stdout).Encode(status)
} else {
for _, pair := range status {
fmt.Fprintf(os.Stderr, "%s: %s\n", pair[0], pair[1])
}
} }
return 0 return 0
} }
@ -26,5 +31,8 @@ func init() {
usage: "Check on graph driver status", usage: "Check on graph driver status",
minArgs: 0, minArgs: 0,
action: status, action: status,
addFlags: func(flags *mflag.FlagSet, cmd *command) {
flags.BoolVar(&jsonOutput, []string{"-json", "j"}, jsonOutput, "prefer JSON output")
},
}) })
} }

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"encoding/json"
"fmt" "fmt"
"os" "os"
@ -10,8 +11,18 @@ import (
func wipe(flags *mflag.FlagSet, action string, m storage.Mall, args []string) int { func wipe(flags *mflag.FlagSet, action string, m storage.Mall, args []string) int {
err := m.Wipe() err := m.Wipe()
if jsonOutput {
if err == nil {
json.NewEncoder(os.Stdout).Encode(string(""))
} else {
json.NewEncoder(os.Stdout).Encode(err)
}
} else {
if err != nil {
fmt.Fprintf(os.Stderr, "%s: %v\n", action, err)
}
}
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "%s: %v\n", action, err)
return 1 return 1
} }
return 0 return 0
@ -23,5 +34,8 @@ func init() {
usage: "Wipe all layers, images, and containers", usage: "Wipe all layers, images, and containers",
minArgs: 0, minArgs: 0,
action: wipe, action: wipe,
addFlags: func(flags *mflag.FlagSet, cmd *command) {
flags.BoolVar(&jsonOutput, []string{"-json", "j"}, jsonOutput, "prefer JSON output")
},
}) })
} }