github.com/olljanat/moby@v1.13.1/cli/command/formatter/service.go (about)

     1  package formatter
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"time"
     7  
     8  	mounttypes "github.com/docker/docker/api/types/mount"
     9  	"github.com/docker/docker/api/types/swarm"
    10  	"github.com/docker/docker/cli/command/inspect"
    11  	units "github.com/docker/go-units"
    12  )
    13  
    14  const serviceInspectPrettyTemplate Format = `
    15  ID:		{{.ID}}
    16  Name:		{{.Name}}
    17  {{- if .Labels }}
    18  Labels:
    19  {{- range $k, $v := .Labels }}
    20   {{ $k }}{{if $v }}={{ $v }}{{ end }}
    21  {{- end }}{{ end }}
    22  Service Mode:
    23  {{- if .IsModeGlobal }}	Global
    24  {{- else if .IsModeReplicated }}	Replicated
    25  {{- if .ModeReplicatedReplicas }}
    26   Replicas:	{{ .ModeReplicatedReplicas }}
    27  {{- end }}{{ end }}
    28  {{- if .HasUpdateStatus }}
    29  UpdateStatus:
    30   State:		{{ .UpdateStatusState }}
    31   Started:	{{ .UpdateStatusStarted }}
    32  {{- if .UpdateIsCompleted }}
    33   Completed:	{{ .UpdateStatusCompleted }}
    34  {{- end }}
    35   Message:	{{ .UpdateStatusMessage }}
    36  {{- end }}
    37  Placement:
    38  {{- if .TaskPlacementConstraints -}}
    39   Contraints:	{{ .TaskPlacementConstraints }}
    40  {{- end }}
    41  {{- if .HasUpdateConfig }}
    42  UpdateConfig:
    43   Parallelism:	{{ .UpdateParallelism }}
    44  {{- if .HasUpdateDelay}}
    45   Delay:		{{ .UpdateDelay }}
    46  {{- end }}
    47   On failure:	{{ .UpdateOnFailure }}
    48  {{- if .HasUpdateMonitor}}
    49   Monitoring Period: {{ .UpdateMonitor }}
    50  {{- end }}
    51   Max failure ratio: {{ .UpdateMaxFailureRatio }}
    52  {{- end }}
    53  ContainerSpec:
    54   Image:		{{ .ContainerImage }}
    55  {{- if .ContainerArgs }}
    56   Args:		{{ range $arg := .ContainerArgs }}{{ $arg }} {{ end }}
    57  {{- end -}}
    58  {{- if .ContainerEnv }}
    59   Env:		{{ range $env := .ContainerEnv }}{{ $env }} {{ end }}
    60  {{- end -}}
    61  {{- if .ContainerWorkDir }}
    62   Dir:		{{ .ContainerWorkDir }}
    63  {{- end -}}
    64  {{- if .ContainerUser }}
    65   User: {{ .ContainerUser }}
    66  {{- end }}
    67  {{- if .ContainerMounts }}
    68  Mounts:
    69  {{- end }}
    70  {{- range $mount := .ContainerMounts }}
    71    Target = {{ $mount.Target }}
    72     Source = {{ $mount.Source }}
    73     ReadOnly = {{ $mount.ReadOnly }}
    74     Type = {{ $mount.Type }}
    75  {{- end -}}
    76  {{- if .HasResources }}
    77  Resources:
    78  {{- if .HasResourceReservations }}
    79   Reservations:
    80  {{- if gt .ResourceReservationNanoCPUs 0.0 }}
    81    CPU:		{{ .ResourceReservationNanoCPUs }}
    82  {{- end }}
    83  {{- if .ResourceReservationMemory }}
    84    Memory:	{{ .ResourceReservationMemory }}
    85  {{- end }}{{ end }}
    86  {{- if .HasResourceLimits }}
    87   Limits:
    88  {{- if gt .ResourceLimitsNanoCPUs 0.0 }}
    89    CPU:		{{ .ResourceLimitsNanoCPUs }}
    90  {{- end }}
    91  {{- if .ResourceLimitMemory }}
    92    Memory:	{{ .ResourceLimitMemory }}
    93  {{- end }}{{ end }}{{ end }}
    94  {{- if .Networks }}
    95  Networks:
    96  {{- range $network := .Networks }} {{ $network }}{{ end }} {{ end }}
    97  Endpoint Mode:	{{ .EndpointMode }}
    98  {{- if .Ports }}
    99  Ports:
   100  {{- range $port := .Ports }}
   101   PublishedPort {{ $port.PublishedPort }}
   102    Protocol = {{ $port.Protocol }}
   103    TargetPort = {{ $port.TargetPort }}
   104  {{- end }} {{ end -}}
   105  `
   106  
   107  // NewServiceFormat returns a Format for rendering using a Context
   108  func NewServiceFormat(source string) Format {
   109  	switch source {
   110  	case PrettyFormatKey:
   111  		return serviceInspectPrettyTemplate
   112  	default:
   113  		return Format(strings.TrimPrefix(source, RawFormatKey))
   114  	}
   115  }
   116  
   117  // ServiceInspectWrite renders the context for a list of services
   118  func ServiceInspectWrite(ctx Context, refs []string, getRef inspect.GetRefFunc) error {
   119  	if ctx.Format != serviceInspectPrettyTemplate {
   120  		return inspect.Inspect(ctx.Output, refs, string(ctx.Format), getRef)
   121  	}
   122  	render := func(format func(subContext subContext) error) error {
   123  		for _, ref := range refs {
   124  			serviceI, _, err := getRef(ref)
   125  			if err != nil {
   126  				return err
   127  			}
   128  			service, ok := serviceI.(swarm.Service)
   129  			if !ok {
   130  				return fmt.Errorf("got wrong object to inspect")
   131  			}
   132  			if err := format(&serviceInspectContext{Service: service}); err != nil {
   133  				return err
   134  			}
   135  		}
   136  		return nil
   137  	}
   138  	return ctx.Write(&serviceInspectContext{}, render)
   139  }
   140  
   141  type serviceInspectContext struct {
   142  	swarm.Service
   143  	subContext
   144  }
   145  
   146  func (ctx *serviceInspectContext) MarshalJSON() ([]byte, error) {
   147  	return marshalJSON(ctx)
   148  }
   149  
   150  func (ctx *serviceInspectContext) ID() string {
   151  	return ctx.Service.ID
   152  }
   153  
   154  func (ctx *serviceInspectContext) Name() string {
   155  	return ctx.Service.Spec.Name
   156  }
   157  
   158  func (ctx *serviceInspectContext) Labels() map[string]string {
   159  	return ctx.Service.Spec.Labels
   160  }
   161  
   162  func (ctx *serviceInspectContext) IsModeGlobal() bool {
   163  	return ctx.Service.Spec.Mode.Global != nil
   164  }
   165  
   166  func (ctx *serviceInspectContext) IsModeReplicated() bool {
   167  	return ctx.Service.Spec.Mode.Replicated != nil
   168  }
   169  
   170  func (ctx *serviceInspectContext) ModeReplicatedReplicas() *uint64 {
   171  	return ctx.Service.Spec.Mode.Replicated.Replicas
   172  }
   173  
   174  func (ctx *serviceInspectContext) HasUpdateStatus() bool {
   175  	return ctx.Service.UpdateStatus.State != ""
   176  }
   177  
   178  func (ctx *serviceInspectContext) UpdateStatusState() swarm.UpdateState {
   179  	return ctx.Service.UpdateStatus.State
   180  }
   181  
   182  func (ctx *serviceInspectContext) UpdateStatusStarted() string {
   183  	return units.HumanDuration(time.Since(ctx.Service.UpdateStatus.StartedAt))
   184  }
   185  
   186  func (ctx *serviceInspectContext) UpdateIsCompleted() bool {
   187  	return ctx.Service.UpdateStatus.State == swarm.UpdateStateCompleted
   188  }
   189  
   190  func (ctx *serviceInspectContext) UpdateStatusCompleted() string {
   191  	return units.HumanDuration(time.Since(ctx.Service.UpdateStatus.CompletedAt))
   192  }
   193  
   194  func (ctx *serviceInspectContext) UpdateStatusMessage() string {
   195  	return ctx.Service.UpdateStatus.Message
   196  }
   197  
   198  func (ctx *serviceInspectContext) TaskPlacementConstraints() []string {
   199  	if ctx.Service.Spec.TaskTemplate.Placement != nil {
   200  		return ctx.Service.Spec.TaskTemplate.Placement.Constraints
   201  	}
   202  	return nil
   203  }
   204  
   205  func (ctx *serviceInspectContext) HasUpdateConfig() bool {
   206  	return ctx.Service.Spec.UpdateConfig != nil
   207  }
   208  
   209  func (ctx *serviceInspectContext) UpdateParallelism() uint64 {
   210  	return ctx.Service.Spec.UpdateConfig.Parallelism
   211  }
   212  
   213  func (ctx *serviceInspectContext) HasUpdateDelay() bool {
   214  	return ctx.Service.Spec.UpdateConfig.Delay.Nanoseconds() > 0
   215  }
   216  
   217  func (ctx *serviceInspectContext) UpdateDelay() time.Duration {
   218  	return ctx.Service.Spec.UpdateConfig.Delay
   219  }
   220  
   221  func (ctx *serviceInspectContext) UpdateOnFailure() string {
   222  	return ctx.Service.Spec.UpdateConfig.FailureAction
   223  }
   224  
   225  func (ctx *serviceInspectContext) HasUpdateMonitor() bool {
   226  	return ctx.Service.Spec.UpdateConfig.Monitor.Nanoseconds() > 0
   227  }
   228  
   229  func (ctx *serviceInspectContext) UpdateMonitor() time.Duration {
   230  	return ctx.Service.Spec.UpdateConfig.Monitor
   231  }
   232  
   233  func (ctx *serviceInspectContext) UpdateMaxFailureRatio() float32 {
   234  	return ctx.Service.Spec.UpdateConfig.MaxFailureRatio
   235  }
   236  
   237  func (ctx *serviceInspectContext) ContainerImage() string {
   238  	return ctx.Service.Spec.TaskTemplate.ContainerSpec.Image
   239  }
   240  
   241  func (ctx *serviceInspectContext) ContainerArgs() []string {
   242  	return ctx.Service.Spec.TaskTemplate.ContainerSpec.Args
   243  }
   244  
   245  func (ctx *serviceInspectContext) ContainerEnv() []string {
   246  	return ctx.Service.Spec.TaskTemplate.ContainerSpec.Env
   247  }
   248  
   249  func (ctx *serviceInspectContext) ContainerWorkDir() string {
   250  	return ctx.Service.Spec.TaskTemplate.ContainerSpec.Dir
   251  }
   252  
   253  func (ctx *serviceInspectContext) ContainerUser() string {
   254  	return ctx.Service.Spec.TaskTemplate.ContainerSpec.User
   255  }
   256  
   257  func (ctx *serviceInspectContext) ContainerMounts() []mounttypes.Mount {
   258  	return ctx.Service.Spec.TaskTemplate.ContainerSpec.Mounts
   259  }
   260  
   261  func (ctx *serviceInspectContext) HasResources() bool {
   262  	return ctx.Service.Spec.TaskTemplate.Resources != nil
   263  }
   264  
   265  func (ctx *serviceInspectContext) HasResourceReservations() bool {
   266  	if ctx.Service.Spec.TaskTemplate.Resources == nil || ctx.Service.Spec.TaskTemplate.Resources.Reservations == nil {
   267  		return false
   268  	}
   269  	return ctx.Service.Spec.TaskTemplate.Resources.Reservations.NanoCPUs > 0 || ctx.Service.Spec.TaskTemplate.Resources.Reservations.MemoryBytes > 0
   270  }
   271  
   272  func (ctx *serviceInspectContext) ResourceReservationNanoCPUs() float64 {
   273  	if ctx.Service.Spec.TaskTemplate.Resources.Reservations.NanoCPUs == 0 {
   274  		return float64(0)
   275  	}
   276  	return float64(ctx.Service.Spec.TaskTemplate.Resources.Reservations.NanoCPUs) / 1e9
   277  }
   278  
   279  func (ctx *serviceInspectContext) ResourceReservationMemory() string {
   280  	if ctx.Service.Spec.TaskTemplate.Resources.Reservations.MemoryBytes == 0 {
   281  		return ""
   282  	}
   283  	return units.BytesSize(float64(ctx.Service.Spec.TaskTemplate.Resources.Reservations.MemoryBytes))
   284  }
   285  
   286  func (ctx *serviceInspectContext) HasResourceLimits() bool {
   287  	if ctx.Service.Spec.TaskTemplate.Resources == nil || ctx.Service.Spec.TaskTemplate.Resources.Limits == nil {
   288  		return false
   289  	}
   290  	return ctx.Service.Spec.TaskTemplate.Resources.Limits.NanoCPUs > 0 || ctx.Service.Spec.TaskTemplate.Resources.Limits.MemoryBytes > 0
   291  }
   292  
   293  func (ctx *serviceInspectContext) ResourceLimitsNanoCPUs() float64 {
   294  	return float64(ctx.Service.Spec.TaskTemplate.Resources.Limits.NanoCPUs) / 1e9
   295  }
   296  
   297  func (ctx *serviceInspectContext) ResourceLimitMemory() string {
   298  	if ctx.Service.Spec.TaskTemplate.Resources.Limits.MemoryBytes == 0 {
   299  		return ""
   300  	}
   301  	return units.BytesSize(float64(ctx.Service.Spec.TaskTemplate.Resources.Limits.MemoryBytes))
   302  }
   303  
   304  func (ctx *serviceInspectContext) Networks() []string {
   305  	var out []string
   306  	for _, n := range ctx.Service.Spec.Networks {
   307  		out = append(out, n.Target)
   308  	}
   309  	return out
   310  }
   311  
   312  func (ctx *serviceInspectContext) EndpointMode() string {
   313  	if ctx.Service.Spec.EndpointSpec == nil {
   314  		return ""
   315  	}
   316  
   317  	return string(ctx.Service.Spec.EndpointSpec.Mode)
   318  }
   319  
   320  func (ctx *serviceInspectContext) Ports() []swarm.PortConfig {
   321  	return ctx.Service.Endpoint.Ports
   322  }