github.com/containers/podman/v2@v2.2.2-0.20210501105131-c1e07d070c4c/pkg/bindings/system/system.go (about)

     1  package system
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"fmt"
     7  	"io"
     8  	"net/http"
     9  	"net/url"
    10  	"strconv"
    11  	"time"
    12  
    13  	"github.com/containers/podman/v2/libpod/define"
    14  	"github.com/containers/podman/v2/pkg/bindings"
    15  	"github.com/containers/podman/v2/pkg/domain/entities"
    16  	"github.com/pkg/errors"
    17  	"github.com/sirupsen/logrus"
    18  )
    19  
    20  // Events allows you to monitor libdpod related events like container creation and
    21  // removal.  The events are then passed to the eventChan provided. The optional cancelChan
    22  // can be used to cancel the read of events and close down the HTTP connection.
    23  func Events(ctx context.Context, eventChan chan entities.Event, cancelChan chan bool, since, until *string, filters map[string][]string, stream *bool) error {
    24  	conn, err := bindings.GetClient(ctx)
    25  	if err != nil {
    26  		return err
    27  	}
    28  	params := url.Values{}
    29  	if since != nil {
    30  		params.Set("since", *since)
    31  	}
    32  	if until != nil {
    33  		params.Set("until", *until)
    34  	}
    35  	if stream != nil {
    36  		params.Set("stream", strconv.FormatBool(*stream))
    37  	}
    38  	if filters != nil {
    39  		filterString, err := bindings.FiltersToString(filters)
    40  		if err != nil {
    41  			return errors.Wrap(err, "invalid filters")
    42  		}
    43  		params.Set("filters", filterString)
    44  	}
    45  	response, err := conn.DoRequest(nil, http.MethodGet, "/events", params, nil)
    46  	if err != nil {
    47  		return err
    48  	}
    49  	if cancelChan != nil {
    50  		go func() {
    51  			<-cancelChan
    52  			err = response.Body.Close()
    53  			logrus.Error(errors.Wrap(err, "unable to close event response body"))
    54  		}()
    55  	}
    56  
    57  	dec := json.NewDecoder(response.Body)
    58  	for err = (error)(nil); err == nil; {
    59  		var e = entities.Event{}
    60  		err = dec.Decode(&e)
    61  		if err == nil {
    62  			eventChan <- e
    63  		}
    64  	}
    65  	close(eventChan)
    66  	switch {
    67  	case err == nil:
    68  		return nil
    69  	case errors.Is(err, io.EOF):
    70  		return nil
    71  	default:
    72  		return errors.Wrap(err, "unable to decode event response")
    73  	}
    74  }
    75  
    76  // Prune removes all unused system data.
    77  func Prune(ctx context.Context, all, volumes *bool) (*entities.SystemPruneReport, error) {
    78  	var (
    79  		report entities.SystemPruneReport
    80  	)
    81  	conn, err := bindings.GetClient(ctx)
    82  	if err != nil {
    83  		return nil, err
    84  	}
    85  	params := url.Values{}
    86  	if all != nil {
    87  		params.Set("All", strconv.FormatBool(*all))
    88  	}
    89  	if volumes != nil {
    90  		params.Set("Volumes", strconv.FormatBool(*volumes))
    91  	}
    92  	response, err := conn.DoRequest(nil, http.MethodPost, "/system/prune", params, nil)
    93  	if err != nil {
    94  		return nil, err
    95  	}
    96  	return &report, response.Process(&report)
    97  }
    98  
    99  func Version(ctx context.Context) (*entities.SystemVersionReport, error) {
   100  	var report entities.SystemVersionReport
   101  	var component entities.ComponentVersion
   102  
   103  	version, err := define.GetVersion()
   104  	if err != nil {
   105  		return nil, err
   106  	}
   107  	report.Client = &version
   108  
   109  	conn, err := bindings.GetClient(ctx)
   110  	if err != nil {
   111  		return nil, err
   112  	}
   113  	response, err := conn.DoRequest(nil, http.MethodGet, "/version", nil, nil)
   114  	if err != nil {
   115  		return nil, err
   116  	}
   117  
   118  	if err = response.Process(&component); err != nil {
   119  		return nil, err
   120  	}
   121  
   122  	b, _ := time.Parse(time.RFC3339, component.BuildTime)
   123  	report.Server = &define.Version{
   124  		APIVersion: component.APIVersion,
   125  		Version:    component.Version.Version,
   126  		GoVersion:  component.GoVersion,
   127  		GitCommit:  component.GitCommit,
   128  		BuiltTime:  time.Unix(b.Unix(), 0).Format(time.ANSIC),
   129  		Built:      b.Unix(),
   130  		OsArch:     fmt.Sprintf("%s/%s", component.Os, component.Arch),
   131  	}
   132  
   133  	for _, c := range component.Components {
   134  		if c.Name == "Podman Engine" {
   135  			report.Server.APIVersion = c.Details["APIVersion"]
   136  		}
   137  	}
   138  	return &report, err
   139  }
   140  
   141  // DiskUsage returns information about image, container, and volume disk
   142  // consumption
   143  func DiskUsage(ctx context.Context) (*entities.SystemDfReport, error) {
   144  	var report entities.SystemDfReport
   145  	conn, err := bindings.GetClient(ctx)
   146  	if err != nil {
   147  		return nil, err
   148  	}
   149  	response, err := conn.DoRequest(nil, http.MethodGet, "/system/df", nil, nil)
   150  	if err != nil {
   151  		return nil, err
   152  	}
   153  	return &report, response.Process(&report)
   154  }