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:
parent
62e67e678d
commit
b50f33bf70
|
|
@ -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")
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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(¶mName, []string{"-name", "n"}, "", "Layer name")
|
flags.StringVar(¶mName, []string{"-name", "n"}, "", "Layer name")
|
||||||
flags.StringVar(¶mID, []string{"-id", "i"}, "", "Layer ID")
|
flags.StringVar(¶mID, []string{"-id", "i"}, "", "Layer ID")
|
||||||
flags.BoolVar(¶mCreateRO, []string{"-readonly", "r"}, false, "Mark as read-only")
|
flags.BoolVar(¶mCreateRO, []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(¶mID, []string{"-id", "i"}, "", "Image ID")
|
flags.StringVar(¶mID, []string{"-id", "i"}, "", "Image ID")
|
||||||
flags.StringVar(¶mMetadata, []string{"-metadata", "m"}, "", "Metadata")
|
flags.StringVar(¶mMetadata, []string{"-metadata", "m"}, "", "Metadata")
|
||||||
flags.StringVar(¶mMetadataFile, []string{"-metadata-file", "f"}, "", "Metadata File")
|
flags.StringVar(¶mMetadataFile, []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(¶mID, []string{"-id", "i"}, "", "Container ID")
|
flags.StringVar(¶mID, []string{"-id", "i"}, "", "Container ID")
|
||||||
flags.StringVar(¶mMetadata, []string{"-metadata", "m"}, "", "Metadata")
|
flags.StringVar(¶mMetadata, []string{"-metadata", "m"}, "", "Metadata")
|
||||||
flags.StringVar(¶mMetadataFile, []string{"-metadata-file", "f"}, "", "Metadata File")
|
flags.StringVar(¶mMetadataFile, []string{"-metadata-file", "f"}, "", "Metadata File")
|
||||||
|
flags.BoolVar(&jsonOutput, []string{"-json", "j"}, jsonOutput, "prefer JSON output")
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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{
|
||||||
|
|
|
||||||
|
|
@ -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(¶mMountLabel, []string{"-label", "l"}, "", "Mount Label")
|
flags.StringVar(¶mMountLabel, []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")
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue