mirror of
https://github.com/clearlinux/rkt.git
synced 2026-09-06 05:41:50 +00:00
Merge pull request #886 from yifan-gu/img_cat
rkt/image: Add cat-manifest to print the image manifest to stdout.
This commit is contained in:
+63
-4
@@ -34,9 +34,10 @@ var (
|
||||
}
|
||||
helpFlags flag.FlagSet
|
||||
|
||||
globalUsageTemplate *template.Template
|
||||
commandUsageTemplate *template.Template
|
||||
templFuncs = template.FuncMap{
|
||||
globalUsageTemplate *template.Template
|
||||
commandUsageTemplate *template.Template
|
||||
subCommandUsageTemplate *template.Template
|
||||
templFuncs = template.FuncMap{
|
||||
"descToLines": func(s string) []string {
|
||||
// trim leading/trailing whitespace and split into slice of lines
|
||||
return strings.Split(strings.Trim(s, "\n\t "), "\n")
|
||||
@@ -86,6 +87,20 @@ DESCRIPTION:
|
||||
{{printOption .Name .DefValue .Usage}}{{end}}
|
||||
|
||||
{{end}}For help on global options run "{{.Executable}} help"
|
||||
`[1:]))
|
||||
subCommandUsageTemplate = template.Must(template.New("subcommand_usage").Funcs(templFuncs).Parse(`
|
||||
NAME:
|
||||
{{printf "\t%s %s - %s" .CmdName .SubCmd.Name .SubCmd.Summary}}
|
||||
|
||||
USAGE:
|
||||
{{printf "\t%s %s %s %s" .Executable .CmdName .SubCmd.Name .SubCmd.Usage}}
|
||||
|
||||
DESCRIPTION:
|
||||
{{range $line := descToLines .SubCmd.Description}}{{printf "\t%s" $line}}
|
||||
{{end}}
|
||||
{{if .SubCmdFlags}}OPTIONS:{{range .SubCmdFlags}}
|
||||
{{printOption .Name .DefValue .Usage}}{{end}}
|
||||
{{end}}
|
||||
`[1:]))
|
||||
}
|
||||
|
||||
@@ -95,7 +110,17 @@ func runHelp(args []string) (exit int) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := printCommandUsageByName(args[0]); err != nil {
|
||||
if len(args) == 1 {
|
||||
if err := printCommandUsageByName(args[0]); err != nil {
|
||||
printGlobalUsage()
|
||||
stderr("\nHelp error: %v\n", err)
|
||||
return 1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Help for sub-commands.
|
||||
if err := printSubCommandUsageByName(args[0], args[1], subCommands[args[0]]); err != nil {
|
||||
printGlobalUsage()
|
||||
stderr("\nHelp error: %v\n", err)
|
||||
return 1
|
||||
@@ -151,3 +176,37 @@ func printCommandUsageByName(name string) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func printSubCommandUsage(cmdName string, subCmd *Command) {
|
||||
subCommandUsageTemplate.Execute(tabOut, struct {
|
||||
Executable string
|
||||
CmdName string
|
||||
SubCmd *Command
|
||||
SubCmdFlags []*flag.Flag
|
||||
}{
|
||||
cliName,
|
||||
cmdName,
|
||||
subCmd,
|
||||
getFlags(subCmd.Flags),
|
||||
})
|
||||
tabOut.Flush()
|
||||
}
|
||||
|
||||
func printSubCommandUsageByName(name, subName string, subCommands []*Command) error {
|
||||
var cmd *Command
|
||||
|
||||
for _, c := range subCommands {
|
||||
if c.Name == subName {
|
||||
cmd = c
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if cmd == nil {
|
||||
return fmt.Errorf("unrecognized sub-command: %s", subName)
|
||||
}
|
||||
|
||||
printSubCommandUsage(name, cmd)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
// Copyright 2015 The rkt Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
)
|
||||
|
||||
var (
|
||||
cmdImage = &Command{
|
||||
Name: "image",
|
||||
Summary: "Operate on an image in the local store",
|
||||
Usage: "SUBCOMMAND IMAGE [args...]",
|
||||
Description: `SUBCOMMAND could be "cat-manifest". IMAGE should be a string referencing an image; either a hash, local file on disk, or URL.
|
||||
They will be checked in that order and the first match will be used.`,
|
||||
Run: runImage,
|
||||
Flags: &imageFlags,
|
||||
}
|
||||
imageFlags flag.FlagSet
|
||||
)
|
||||
|
||||
func init() {
|
||||
commands = append(commands, cmdImage)
|
||||
}
|
||||
|
||||
func runImage(args []string) (exit int) {
|
||||
if len(args) < 1 {
|
||||
printCommandUsageByName("image")
|
||||
return 1
|
||||
}
|
||||
|
||||
var subCmd *Command
|
||||
subArgs := args[1:]
|
||||
|
||||
// determine which Command should be run
|
||||
for _, c := range subCommands["image"] {
|
||||
if c.Name == args[0] {
|
||||
subCmd = c
|
||||
if err := c.Flags.Parse(subArgs); err != nil {
|
||||
stderr("%v", err)
|
||||
os.Exit(2)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if subCmd == nil {
|
||||
stderr("image: unknown subcommand: %q", args[0])
|
||||
os.Exit(2)
|
||||
}
|
||||
return subCmd.Run(subArgs[subCmd.Flags.NFlag():])
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
// Copyright 2015 The rkt Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
|
||||
"github.com/coreos/rkt/store"
|
||||
)
|
||||
|
||||
var (
|
||||
cmdImageCatManifest = &Command{
|
||||
Name: "cat-manifest",
|
||||
Summary: "Inspect and print the image manifest",
|
||||
Usage: "IMAGE",
|
||||
Description: `IMAGE should be a string referencing an image; either a hash, local file on disk, or URL.
|
||||
They will be checked in that order and the first match will be used.`,
|
||||
Run: runImageCatManifest,
|
||||
Flags: &imageCatManifestFlag,
|
||||
}
|
||||
imageCatManifestFlag flag.FlagSet
|
||||
flagPrettyPrint bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
subCommands["image"] = append(subCommands["image"], cmdImageCatManifest)
|
||||
|
||||
imageCatManifestFlag.BoolVar(&flagPrettyPrint, "pretty-print", false, "apply indent to format the output")
|
||||
}
|
||||
|
||||
func runImageCatManifest(args []string) (exit int) {
|
||||
if len(args) != 1 {
|
||||
printSubCommandUsageByName("image", "cat-manifest", subCommands["image"])
|
||||
return 1
|
||||
}
|
||||
|
||||
s, err := store.NewStore(globalFlags.Dir)
|
||||
if err != nil {
|
||||
stderr("image cat-manifest: cannot open store: %v\n", err)
|
||||
return 1
|
||||
}
|
||||
ks := getKeystore()
|
||||
|
||||
fn := &finder{
|
||||
imageActionData: imageActionData{
|
||||
s: s,
|
||||
ks: ks,
|
||||
insecureSkipVerify: true,
|
||||
debug: globalFlags.Debug,
|
||||
},
|
||||
local: true,
|
||||
withDeps: false,
|
||||
}
|
||||
|
||||
h, err := fn.findImage(args[0], "", true)
|
||||
if err != nil {
|
||||
stderr("image cat-manifest: cannot find image: %v\n", err)
|
||||
return 1
|
||||
}
|
||||
|
||||
manifest, err := fn.s.GetImageManifest(h.String())
|
||||
if err != nil {
|
||||
stderr("image cat-manifest: cannot get image manifest: %v\n", err)
|
||||
return 1
|
||||
}
|
||||
|
||||
var b []byte
|
||||
if flagPrettyPrint {
|
||||
b, err = json.MarshalIndent(manifest, "", "\t")
|
||||
} else {
|
||||
b, err = json.Marshal(manifest)
|
||||
}
|
||||
if err != nil {
|
||||
stderr("image cat-manifest: cannot read the image manifest: %v\n", err)
|
||||
return 1
|
||||
}
|
||||
|
||||
stdout(string(b))
|
||||
return 0
|
||||
}
|
||||
@@ -40,6 +40,7 @@ var (
|
||||
globalFlagset = flag.NewFlagSet(cliName, flag.ExitOnError)
|
||||
tabOut *tabwriter.Writer
|
||||
commands []*Command // Commands should register themselves by appending
|
||||
subCommands = make(map[string][]*Command)
|
||||
globalFlags = struct {
|
||||
Dir string
|
||||
SystemConfigDir string
|
||||
|
||||
Reference in New Issue
Block a user