Show client info even if remote connection fails

When people report issues, we often ask for the result of `podman info`.
However, if the problem is the remote connection, it will error out with
no information at all.  This PR at least will report client information
before disclosing the connection error.  For example on Windows:

> .\bin\windows\podman.exe info
client:
  OS: windows/amd64
  provider: hyperv
  version: 4.8.0-dev
  host: null

Satisfies: RUN-1720

Signed-off-by: Brent Baude <bbaude@redhat.com>
This commit is contained in:
Brent Baude
2023-10-10 19:13:46 -05:00
parent 3e86bece98
commit 29f5c563e4
6 changed files with 72 additions and 1 deletions

25
cmd/podman/client.go Normal file
View File

@ -0,0 +1,25 @@
package main
import "github.com/containers/podman/v4/libpod/define"
type clientInfo struct {
OSArch string `json:"OS"`
Provider string `json:"provider"`
Version string `json:"version"`
}
func getClientInfo() (*clientInfo, error) {
p, err := getProvider()
if err != nil {
return nil, err
}
vinfo, err := define.GetVersion()
if err != nil {
return nil, err
}
return &clientInfo{
OSArch: vinfo.OsArch,
Provider: p,
Version: vinfo.Version,
}, nil
}

View File

@ -0,0 +1,16 @@
//go:build amd64 || arm64
// +build amd64 arm64
package main
import (
"github.com/containers/podman/v4/pkg/machine/provider"
)
func getProvider() (string, error) {
p, err := provider.Get()
if err != nil {
return "", err
}
return p.VMType().String(), nil
}

View File

@ -0,0 +1,7 @@
//go:build !amd64 && !arm64
package main
func getProvider() (string, error) {
return "", nil
}

View File

@ -24,6 +24,7 @@ import (
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"sigs.k8s.io/yaml"
)
// HelpTemplate is the help template for podman commands
@ -296,6 +297,15 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error {
// Prep the engines
if _, err := registry.NewImageEngine(cmd, args); err != nil {
// Note: this is gross, but it is the hand we are dealt
if registry.IsRemote() && errors.As(err, &bindings.ConnectError{}) && cmd.Name() == "info" && cmd.Parent() == cmd.Root() {
clientDesc, err := getClientInfo()
// we eat the error here. if this fails, they just don't any client info
if err == nil {
b, _ := yaml.Marshal(clientDesc)
fmt.Println(string(b))
}
}
return err
}
if _, err := registry.NewContainerEngine(cmd, args); err != nil {

View File

@ -6,6 +6,7 @@ import (
"os/exec"
"os/user"
"path/filepath"
"runtime"
"strconv"
. "github.com/containers/podman/v4/test/utils"
@ -240,4 +241,16 @@ var _ = Describe("Podman Info", func() {
// Don't check absolute numbers because there is a decent chance of contamination, containers that were never removed properly, etc.
Expect(free1).To(Equal(free2 + 1))
})
It("Podman info: check for client information when no system service", func() {
// the output for this information is not really something we can marshall
want := runtime.GOOS + "/" + runtime.GOARCH
podmanTest.StopRemoteService()
SkipIfNotRemote("Specifically testing a failed remote connection")
info := podmanTest.Podman([]string{"info"})
info.WaitWithDefaultTimeout()
Expect(info.OutputToString()).To(ContainSubstring(want))
Expect(info).ToNot(ExitCleanly())
podmanTest.StartRemoteService() // Start service again so teardown runs clean
})
})

View File

@ -102,7 +102,7 @@ $c2[ ]\+tcp://localhost:54321[ ]\+true" \
# when invoking podman.
_run_podman_remote 125 info
is "$output" \
"Cannot connect to Podman. Please verify.*dial tcp.*connection refused" \
"OS: .*provider:.*Cannot connect to Podman. Please verify.*dial tcp.*connection refused" \
"podman info, without active service"
# Start service. Now podman info should work fine. The %%-remote*