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