package main
import (
"fmt"
"html/template"
"os"
rt "runtime"
"strings"
"github.com/containers/buildah/pkg/formats"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/pkg/adapter"
"github.com/containers/libpod/version"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
var (
infoCommand cliconfig.InfoValues
infoDescription = `Display information pertaining to the host, current storage stats, and build of podman.
Useful for the user and when reporting issues.
`
_infoCommand = &cobra.Command{
Use: "info",
Args: noSubArgs,
Long: infoDescription,
Short: "Display podman system information",
RunE: func(cmd *cobra.Command, args []string) error {
infoCommand.InputArgs = args
infoCommand.GlobalFlags = MainGlobalOpts
infoCommand.Remote = remoteclient
return infoCmd(&infoCommand)
},
Example: `podman info`,
}
)
func init() {
infoCommand.Command = _infoCommand
infoCommand.SetHelpTemplate(HelpTemplate())
infoCommand.SetUsageTemplate(UsageTemplate())
flags := infoCommand.Flags()
flags.BoolVarP(&infoCommand.Debug, "debug", "D", false, "Display additional debug information")
flags.StringVarP(&infoCommand.Format, "format", "f", "", "Change the output format to JSON or a Go template")
}
func infoCmd(c *cliconfig.InfoValues) error {
runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
defer runtime.DeferredShutdown(false)
i, err := runtime.Info()
if err != nil {
return errors.Wrapf(err, "error getting info")
}
info := infoWithExtra{Info: i}
if runtime.Remote {
endpoint, err := runtime.RemoteEndpoint()
if err != nil {
return err
}
info.Remote = getRemote(endpoint)
}
if !runtime.Remote && c.Debug {
d, err := getDebug()
if err != nil {
return err
}
info.Debug = d
}
var out formats.Writer
infoOutputFormat := c.Format
if strings.Join(strings.Fields(infoOutputFormat), "") == "{{json.}}" {
infoOutputFormat = formats.JSONString
}
switch infoOutputFormat {
case formats.JSONString:
out = formats.JSONStruct{Output: info}
case "":
out = formats.YAMLStruct{Output: info}
default:
tmpl, err := template.New("info").Parse(c.Format)
if err != nil {
return err
}
err = tmpl.Execute(os.Stdout, info)
return err
}
return out.Out()
}
// top-level "debug" info
func getDebug() (*debugInfo, error) {
v, err := define.GetVersion()
if err != nil {
return nil, err
}
return &debugInfo{
Compiler: rt.Compiler,
GoVersion: rt.Version(),
PodmanVersion: v.Version,
GitCommit: v.GitCommit,
}, nil
}
func getRemote(endpoint *adapter.Endpoint) *remoteInfo {
return &remoteInfo{
Connection: endpoint.Connection,
ConnectionType: endpoint.Type.String(),
RemoteAPIVersion: string(version.RemoteAPIVersion),
PodmanVersion: version.Version,
OSArch: fmt.Sprintf("%s/%s", rt.GOOS, rt.GOARCH),
}
}
type infoWithExtra struct {
*define.Info
Remote *remoteInfo `json:"remote,omitempty"`
Debug *debugInfo `json:"debug,omitempty"`
}
type remoteInfo struct {
Connection string `json:"connection"`
ConnectionType string `json:"connectionType"`
RemoteAPIVersion string `json:"remoteAPIVersion"`
PodmanVersion string `json:"podmanVersion"`
OSArch string `json:"OSArch"`
}
type debugInfo struct {
Compiler string `json:"compiler"`
GoVersion string `json:"goVersion"`
PodmanVersion string `json:"podmanVersion"`
GitCommit string `json:"gitCommit"`
}