forked from docker-archive/classicswarm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontainer.go
165 lines (139 loc) · 3.86 KB
/
container.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
package cluster
import (
"fmt"
"strings"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/stringid"
units "github.com/docker/go-units"
)
// Container is exported
type Container struct {
types.Container
Config *ContainerConfig
Info types.ContainerJSON
Engine *Engine
}
// StateString returns a single string to describe state
func StateString(state *types.ContainerState) string {
startedAt, _ := time.Parse(time.RFC3339Nano, state.StartedAt)
if state.Running {
if state.Paused {
return "paused"
}
if state.Restarting {
return "restarting"
}
return "running"
}
if state.Dead {
return "dead"
}
if startedAt.IsZero() {
return "created"
}
return "exited"
}
// HealthString returns a single string to describe health status.
func HealthString(state *types.ContainerState) string {
if state.Health == nil {
return types.NoHealthcheck
}
return state.Health.Status
}
// FullStateString returns human-readable description of the state
func FullStateString(state *types.ContainerState) string {
startedAt, _ := time.Parse(time.RFC3339Nano, state.StartedAt)
finishedAt, _ := time.Parse(time.RFC3339Nano, state.FinishedAt)
if state.Running {
if state.Paused {
return fmt.Sprintf("Up %s (Paused)", units.HumanDuration(time.Now().UTC().Sub(startedAt)))
}
if state.Restarting {
return fmt.Sprintf("Restarting (%d) %s ago", state.ExitCode, units.HumanDuration(time.Now().UTC().Sub(finishedAt)))
}
// Container is Up. Add Health check info when healthcheck is defined.
healthText := ""
if h := state.Health; h != nil {
switch h.Status {
case types.Starting:
healthText = "health: starting"
default: // Healthy and Unhealthy are clear on their own
healthText = h.Status
}
}
if len(healthText) > 0 {
return fmt.Sprintf("Up %s (%s)", units.HumanDuration(time.Now().UTC().Sub(startedAt)), healthText)
}
return fmt.Sprintf("Up %s", units.HumanDuration(time.Now().UTC().Sub(startedAt)))
}
if state.Dead {
return "Dead"
}
if startedAt.IsZero() {
return "Created"
}
if finishedAt.IsZero() {
return ""
}
return fmt.Sprintf("Exited (%d) %s ago", state.ExitCode, units.HumanDuration(time.Now().UTC().Sub(finishedAt)))
}
// Refresh container
func (c *Container) Refresh() (*Container, error) {
return c.Engine.refreshContainer(c.ID, true)
}
// Containers represents a list of containers
type Containers []*Container
// Get returns a container using its ID or Name
func (containers Containers) Get(IDOrName string) *Container {
// Abort immediately if the name is empty.
if len(IDOrName) == 0 {
return nil
}
// Match exact or short Container ID.
for _, container := range containers {
if container.ID == IDOrName || stringid.TruncateID(container.ID) == IDOrName {
return container
}
}
// Match exact Swarm ID.
for _, container := range containers {
if swarmID := container.Config.SwarmID(); swarmID == IDOrName || stringid.TruncateID(swarmID) == IDOrName {
return container
}
}
candidates := []*Container{}
// Match name, /name or engine/name.
for _, container := range containers {
found := false
for _, name := range container.Names {
if name == IDOrName || name == "/"+IDOrName || container.Engine.ID+name == IDOrName || container.Engine.Name+name == IDOrName {
found = true
}
}
if found {
candidates = append(candidates, container)
}
}
if size := len(candidates); size == 1 {
return candidates[0]
} else if size > 1 {
return nil
}
// Match Container ID prefix.
for _, container := range containers {
if strings.HasPrefix(container.ID, IDOrName) {
candidates = append(candidates, container)
}
}
// Match Swarm ID prefix.
for _, container := range containers {
if strings.HasPrefix(container.Config.SwarmID(), IDOrName) {
candidates = append(candidates, container)
}
}
if len(candidates) == 1 {
return candidates[0]
}
return nil
}