...

Source file src/github.com/redhat-developer/odo/pkg/podman/version.go

Documentation: github.com/redhat-developer/odo/pkg/podman

     1  package podman
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"encoding/json"
     7  	"fmt"
     8  	"os/exec"
     9  	"time"
    10  
    11  	"k8s.io/klog"
    12  )
    13  
    14  type Version struct {
    15  	APIVersion string
    16  	Version    string
    17  	GoVersion  string
    18  	GitCommit  string
    19  	BuiltTime  string
    20  	Built      int64
    21  	OsArch     string
    22  	Os         string
    23  }
    24  
    25  type SystemVersionReport struct {
    26  	Client *Version `json:",omitempty"`
    27  }
    28  
    29  // Version returns the version of the Podman client.
    30  func (o *PodmanCli) Version(ctx context.Context) (SystemVersionReport, error) {
    31  	// Because Version is used at the very beginning of odo, when resolving and injecting dependencies (for commands that might require the Podman client),
    32  	// it is expected to return in a timely manner (hence this configurable timeout).
    33  	// This is to avoid situations like the one described in https://github.com/redhat-developer/odo/issues/6575
    34  	// (where a podman CLI that takes too long to respond affects the "odo dev" command, even if the user did not intend to use the Podman platform).
    35  
    36  	cmd := exec.CommandContext(ctx, o.podmanCmd, "version", "--format", "json")
    37  	klog.V(3).Infof("executing %v", cmd.Args)
    38  
    39  	outbuf, errbuf := new(bytes.Buffer), new(bytes.Buffer)
    40  	cmd.Stdout, cmd.Stderr = outbuf, errbuf
    41  
    42  	err := cmd.Start()
    43  	if err != nil {
    44  		return SystemVersionReport{}, err
    45  	}
    46  
    47  	// Use a channel to signal completion so we can use a select statement
    48  	done := make(chan error)
    49  	go func() { done <- cmd.Wait() }()
    50  
    51  	var timeoutErr error
    52  	select {
    53  	case <-time.After(o.podmanCmdInitTimeout):
    54  		err = cmd.Process.Kill()
    55  		if err != nil {
    56  			klog.V(3).Infof("unable to kill podman version process: %s", err)
    57  		}
    58  		timeoutErr = fmt.Errorf("timeout (%s) while waiting for Podman version", o.podmanCmdInitTimeout.Round(time.Second).String())
    59  		klog.V(3).Infof(timeoutErr.Error())
    60  
    61  	case err = <-done:
    62  		if err != nil {
    63  			klog.V(3).Infof("Non-zero exit code for podman version: %v", err)
    64  
    65  			stderr := errbuf.String()
    66  			if len(stderr) > 0 {
    67  				klog.V(3).Infof("podman version stderr: %v", stderr)
    68  			}
    69  
    70  			return SystemVersionReport{}, err
    71  		}
    72  	}
    73  
    74  	var result SystemVersionReport
    75  	err = json.NewDecoder(outbuf).Decode(&result)
    76  	if err != nil {
    77  		klog.V(3).Infof("unable to decode output: %v", err)
    78  		if timeoutErr != nil {
    79  			return SystemVersionReport{}, timeoutErr
    80  		}
    81  		return SystemVersionReport{}, err
    82  	}
    83  
    84  	return result, nil
    85  }
    86  

View as plain text