github.com/sijibomii/docker@v0.0.0-20231230191044-5cf6ca554647/api/client/formatter/custom.go (about)

     1  package formatter
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  	"strings"
     7  	"time"
     8  
     9  	"github.com/docker/docker/api"
    10  	"github.com/docker/docker/pkg/stringid"
    11  	"github.com/docker/docker/pkg/stringutils"
    12  	"github.com/docker/engine-api/types"
    13  	"github.com/docker/go-units"
    14  )
    15  
    16  const (
    17  	tableKey = "table"
    18  
    19  	containerIDHeader  = "CONTAINER ID"
    20  	imageHeader        = "IMAGE"
    21  	namesHeader        = "NAMES"
    22  	commandHeader      = "COMMAND"
    23  	createdSinceHeader = "CREATED"
    24  	createdAtHeader    = "CREATED AT"
    25  	runningForHeader   = "CREATED"
    26  	statusHeader       = "STATUS"
    27  	portsHeader        = "PORTS"
    28  	sizeHeader         = "SIZE"
    29  	labelsHeader       = "LABELS"
    30  	imageIDHeader      = "IMAGE ID"
    31  	repositoryHeader   = "REPOSITORY"
    32  	tagHeader          = "TAG"
    33  	digestHeader       = "DIGEST"
    34  	mountsHeader       = "MOUNTS"
    35  )
    36  
    37  type containerContext struct {
    38  	baseSubContext
    39  	trunc bool
    40  	c     types.Container
    41  }
    42  
    43  func (c *containerContext) ID() string {
    44  	c.addHeader(containerIDHeader)
    45  	if c.trunc {
    46  		return stringid.TruncateID(c.c.ID)
    47  	}
    48  	return c.c.ID
    49  }
    50  
    51  func (c *containerContext) Names() string {
    52  	c.addHeader(namesHeader)
    53  	names := stripNamePrefix(c.c.Names)
    54  	if c.trunc {
    55  		for _, name := range names {
    56  			if len(strings.Split(name, "/")) == 1 {
    57  				names = []string{name}
    58  				break
    59  			}
    60  		}
    61  	}
    62  	return strings.Join(names, ",")
    63  }
    64  
    65  func (c *containerContext) Image() string {
    66  	c.addHeader(imageHeader)
    67  	if c.c.Image == "" {
    68  		return "<no image>"
    69  	}
    70  	if c.trunc {
    71  		if trunc := stringid.TruncateID(c.c.ImageID); trunc == stringid.TruncateID(c.c.Image) {
    72  			return trunc
    73  		}
    74  	}
    75  	return c.c.Image
    76  }
    77  
    78  func (c *containerContext) Command() string {
    79  	c.addHeader(commandHeader)
    80  	command := c.c.Command
    81  	if c.trunc {
    82  		command = stringutils.Truncate(command, 20)
    83  	}
    84  	return strconv.Quote(command)
    85  }
    86  
    87  func (c *containerContext) CreatedAt() string {
    88  	c.addHeader(createdAtHeader)
    89  	return time.Unix(int64(c.c.Created), 0).String()
    90  }
    91  
    92  func (c *containerContext) RunningFor() string {
    93  	c.addHeader(runningForHeader)
    94  	createdAt := time.Unix(int64(c.c.Created), 0)
    95  	return units.HumanDuration(time.Now().UTC().Sub(createdAt))
    96  }
    97  
    98  func (c *containerContext) Ports() string {
    99  	c.addHeader(portsHeader)
   100  	return api.DisplayablePorts(c.c.Ports)
   101  }
   102  
   103  func (c *containerContext) Status() string {
   104  	c.addHeader(statusHeader)
   105  	return c.c.Status
   106  }
   107  
   108  func (c *containerContext) Size() string {
   109  	c.addHeader(sizeHeader)
   110  	srw := units.HumanSize(float64(c.c.SizeRw))
   111  	sv := units.HumanSize(float64(c.c.SizeRootFs))
   112  
   113  	sf := srw
   114  	if c.c.SizeRootFs > 0 {
   115  		sf = fmt.Sprintf("%s (virtual %s)", srw, sv)
   116  	}
   117  	return sf
   118  }
   119  
   120  func (c *containerContext) Labels() string {
   121  	c.addHeader(labelsHeader)
   122  	if c.c.Labels == nil {
   123  		return ""
   124  	}
   125  
   126  	var joinLabels []string
   127  	for k, v := range c.c.Labels {
   128  		joinLabels = append(joinLabels, fmt.Sprintf("%s=%s", k, v))
   129  	}
   130  	return strings.Join(joinLabels, ",")
   131  }
   132  
   133  func (c *containerContext) Label(name string) string {
   134  	n := strings.Split(name, ".")
   135  	r := strings.NewReplacer("-", " ", "_", " ")
   136  	h := r.Replace(n[len(n)-1])
   137  
   138  	c.addHeader(h)
   139  
   140  	if c.c.Labels == nil {
   141  		return ""
   142  	}
   143  	return c.c.Labels[name]
   144  }
   145  
   146  func (c *containerContext) Mounts() string {
   147  	c.addHeader(mountsHeader)
   148  
   149  	var name string
   150  	var mounts []string
   151  	for _, m := range c.c.Mounts {
   152  		if m.Name == "" {
   153  			name = m.Source
   154  		} else {
   155  			name = m.Name
   156  		}
   157  		if c.trunc {
   158  			name = stringutils.Truncate(name, 15)
   159  		}
   160  		mounts = append(mounts, name)
   161  	}
   162  	return strings.Join(mounts, ",")
   163  }
   164  
   165  type imageContext struct {
   166  	baseSubContext
   167  	trunc  bool
   168  	i      types.Image
   169  	repo   string
   170  	tag    string
   171  	digest string
   172  }
   173  
   174  func (c *imageContext) ID() string {
   175  	c.addHeader(imageIDHeader)
   176  	if c.trunc {
   177  		return stringid.TruncateID(c.i.ID)
   178  	}
   179  	return c.i.ID
   180  }
   181  
   182  func (c *imageContext) Repository() string {
   183  	c.addHeader(repositoryHeader)
   184  	return c.repo
   185  }
   186  
   187  func (c *imageContext) Tag() string {
   188  	c.addHeader(tagHeader)
   189  	return c.tag
   190  }
   191  
   192  func (c *imageContext) Digest() string {
   193  	c.addHeader(digestHeader)
   194  	return c.digest
   195  }
   196  
   197  func (c *imageContext) CreatedSince() string {
   198  	c.addHeader(createdSinceHeader)
   199  	createdAt := time.Unix(int64(c.i.Created), 0)
   200  	return units.HumanDuration(time.Now().UTC().Sub(createdAt))
   201  }
   202  
   203  func (c *imageContext) CreatedAt() string {
   204  	c.addHeader(createdAtHeader)
   205  	return time.Unix(int64(c.i.Created), 0).String()
   206  }
   207  
   208  func (c *imageContext) Size() string {
   209  	c.addHeader(sizeHeader)
   210  	return units.HumanSize(float64(c.i.Size))
   211  }
   212  
   213  type subContext interface {
   214  	fullHeader() string
   215  	addHeader(header string)
   216  }
   217  
   218  type baseSubContext struct {
   219  	header []string
   220  }
   221  
   222  func (c *baseSubContext) fullHeader() string {
   223  	if c.header == nil {
   224  		return ""
   225  	}
   226  	return strings.Join(c.header, "\t")
   227  }
   228  
   229  func (c *baseSubContext) addHeader(header string) {
   230  	if c.header == nil {
   231  		c.header = []string{}
   232  	}
   233  	c.header = append(c.header, strings.ToUpper(header))
   234  }
   235  
   236  func stripNamePrefix(ss []string) []string {
   237  	sss := make([]string, len(ss))
   238  	for i, s := range ss {
   239  		sss[i] = s[1:]
   240  	}
   241  
   242  	return sss
   243  }