-
Notifications
You must be signed in to change notification settings - Fork 602
/
versions.go
128 lines (106 loc) · 3.18 KB
/
versions.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
// Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may
// not use this file except in compliance with the License. A copy of the
// License is located at
//
// http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file is distributed
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
// express or implied. See the License for the specific language governing
// permissions and limitations under the License.
package dockerclient
import (
"sync"
"github.com/aws/amazon-ecs-agent/agent/engine/dockeriface"
log "github.com/cihub/seelog"
docker "github.com/fsouza/go-dockerclient"
)
type DockerVersion string
const (
Version_1_17 DockerVersion = "1.17"
Version_1_18 DockerVersion = "1.18"
Version_1_19 DockerVersion = "1.19"
Version_1_20 DockerVersion = "1.20"
Version_1_21 DockerVersion = "1.21"
Version_1_22 DockerVersion = "1.22"
Version_1_23 DockerVersion = "1.23"
defaultVersion = Version_1_17
)
var supportedVersions []DockerVersion
func init() {
supportedVersions = []DockerVersion{
Version_1_17,
Version_1_18,
Version_1_19,
Version_1_20,
Version_1_21,
Version_1_22,
Version_1_23,
}
}
type Factory interface {
// GetDefaultClient returns a versioned client for the default version
GetDefaultClient() (dockeriface.Client, error)
// GetClient returns a client with the specified version
GetClient(version DockerVersion) (dockeriface.Client, error)
// FindAvailableVersions tests each supported version and returns a slice
// of available versions
FindAvailableVersions() []DockerVersion
}
type factory struct {
endpoint string
lock sync.Mutex
clients map[DockerVersion]dockeriface.Client
}
// newVersionedClient is a variable such that the implementation can be
// swapped out for unit tests
var newVersionedClient = func(endpoint, version string) (dockeriface.Client, error) {
return docker.NewVersionedClient(endpoint, version)
}
func NewFactory(endpoint string) Factory {
return &factory{
endpoint: endpoint,
clients: make(map[DockerVersion]dockeriface.Client),
}
}
func (f *factory) GetDefaultClient() (dockeriface.Client, error) {
return f.GetClient(defaultVersion)
}
func (f *factory) GetClient(version DockerVersion) (dockeriface.Client, error) {
client, ok := f.clients[version]
if ok {
return client, nil
}
f.lock.Lock()
defer f.lock.Unlock()
// double-check now that we're in a lock
client, ok = f.clients[version]
if ok {
return client, nil
}
client, err := newVersionedClient(f.endpoint, string(version))
if err != nil {
return nil, err
}
err = client.Ping()
if err != nil {
return nil, err
}
f.clients[version] = client
return client, nil
}
func (f *factory) FindAvailableVersions() []DockerVersion {
var availableVersions []DockerVersion
for _, version := range supportedVersions {
_, err := f.GetClient(version)
if err == nil {
availableVersions = append(availableVersions, version)
} else {
log.Debugf("Failed to ping with Docker version %s: %v", version, err)
}
}
log.Infof("Detected Docker versions %v", availableVersions)
return availableVersions
}