@@ -17,10 +17,19 @@ import (
17
17
"errors"
18
18
19
19
"github.com/aws/amazon-ecs-agent/agent/engine/dockeriface"
20
+ "github.com/aws/amazon-ecs-agent/agent/utils"
20
21
log "github.com/cihub/seelog"
21
22
docker "github.com/fsouza/go-dockerclient"
22
23
)
23
24
25
+ const (
26
+ // minDockerAPILinux is the min Docker API version supported by agent
27
+ minDockerAPILinux = Version_1_17
28
+ // minAPIVersionKey is the docker.Env key for min API version
29
+ minAPIVersionKey = "MinAPIVersion"
30
+ // apiVersionKey is the docker.Env key for API version
31
+ apiVersionKey = "ApiVersion"
32
+ )
24
33
// Factory provides a collection of docker remote clients that include a
25
34
// recommended client version as well as a set of alternative supported
26
35
// docker clients.
@@ -110,6 +119,11 @@ func (f *factory) getClient(version DockerVersion) (dockeriface.Client, error) {
110
119
// findDockerVersions loops over all known API versions and finds which ones
111
120
// are supported by the docker daemon on the host
112
121
func findDockerVersions (endpoint string ) map [DockerVersion ]dockeriface.Client {
122
+ // if the client version returns a min version and api version, then use it to return
123
+ // Docker versions
124
+ if clients , ok := findDockerVersionsfromMinMaxVersions (endpoint ); ok {
125
+ return clients
126
+ }
113
127
clients := make (map [DockerVersion ]dockeriface.Client )
114
128
for _ , version := range getKnownAPIVersions () {
115
129
client , err := newVersionedClient (endpoint , string (version ))
@@ -121,8 +135,54 @@ func findDockerVersions(endpoint string) map[DockerVersion]dockeriface.Client {
121
135
err = client .Ping ()
122
136
if err != nil {
123
137
log .Infof ("Failed to ping with Docker version %s: %v" , version , err )
138
+ continue
124
139
}
125
140
clients [version ] = client
126
141
}
127
142
return clients
128
143
}
144
+
145
+ func findDockerVersionsfromMinMaxVersions (endpoint string ) (map [DockerVersion ]dockeriface.Client , bool ) {
146
+ clients := make (map [DockerVersion ]dockeriface.Client )
147
+ // get a Docker client with the default supported version
148
+ client , err := newVersionedClient (endpoint , string (minDockerAPILinux ))
149
+ if err != nil {
150
+ log .Infof ("Error while creating client: %v" , err )
151
+ return nil , false
152
+ }
153
+
154
+ clientVersion , err := client .Version ()
155
+ if err != nil {
156
+ log .Infof ("Error while getting client version: %v" , err )
157
+ return nil , false
158
+ }
159
+
160
+ // check if the docker.Env obj has MinAPIVersion key
161
+ if clientVersion .Exists (minAPIVersionKey ) {
162
+ minAPIVersion := clientVersion .Get (minAPIVersionKey )
163
+ apiVersion := clientVersion .Get (apiVersionKey )
164
+ for _ , version := range getKnownAPIVersions () {
165
+ lessThanMinCheck := "<" + minAPIVersion
166
+ moreThanMaxCheck := ">" + apiVersion
167
+ minVersionCheck , minErr := utils .Version (version ).Matches (lessThanMinCheck )
168
+ maxVersionCheck , maxErr := utils .Version (version ).Matches (moreThanMaxCheck )
169
+ if minErr != nil || maxErr != nil {
170
+ log .Infof ("Error while comparing Docker API versions: %v, %v" , minErr , maxErr )
171
+ continue
172
+ }
173
+ // do not add the version when it is less than min api version or greater
174
+ // than api version
175
+ if minVersionCheck || maxVersionCheck {
176
+ continue
177
+ }
178
+ client , err := newVersionedClient (endpoint , string (version ))
179
+ if err != nil {
180
+ log .Infof ("Error while creating client: %v" , err )
181
+ continue
182
+ }
183
+ clients [version ] = client
184
+ }
185
+ return clients , true
186
+ }
187
+ return nil , false
188
+ }
0 commit comments