@@ -35,12 +35,13 @@ import (
35
35
)
36
36
37
37
const (
38
- StackTraceOnErrors = "COBRA_STACK_TRACE_ON_ERRORS"
39
- trueString = "true"
40
- Stdout = "stdout"
41
- Unwrap = "unwrap"
42
- dockerVersionTimeout time.Duration = 5 * time .Second
43
- FunctionsCatalogURL = "https://catalog.kpt.dev/catalog-v2.json"
38
+ StackTraceOnErrors = "COBRA_STACK_TRACE_ON_ERRORS"
39
+ trueString = "true"
40
+ Stdout = "stdout"
41
+ Unwrap = "unwrap"
42
+ dockerVersionTimeout time.Duration = 5 * time .Second
43
+ FunctionsCatalogURL = "https://catalog.kpt.dev/catalog-v2.json"
44
+ minSupportedDockerVersion string = "v20.10.0"
44
45
)
45
46
46
47
// FixDocs replaces instances of old with new in the docs for c
@@ -88,22 +89,39 @@ func ResolveAbsAndRelPaths(path string) (string, string, error) {
88
89
return relPath , absPath , nil
89
90
}
90
91
91
- // DockerCmdAvailable runs `docker ps` to check that the docker command is
92
- // available, and returns an error with installation instructions if it is not
92
+ // DockerCmdAvailable runs `docker version` to check that the docker command is
93
+ // available and is a supported version. Returns an error with installation
94
+ // instructions if it is not
93
95
func DockerCmdAvailable () error {
94
96
suggestedText := `docker must be running to use this command
95
97
To install docker, follow the instructions at https://docs.docker.com/get-docker/.
96
98
`
97
- buffer := & bytes.Buffer {}
99
+ cmdOut := & bytes.Buffer {}
98
100
99
101
ctx , cancel := context .WithTimeout (context .Background (), dockerVersionTimeout )
100
102
defer cancel ()
101
- cmd := exec .CommandContext (ctx , "docker" , "version" )
102
- cmd .Stderr = buffer
103
+ cmd := exec .CommandContext (ctx , "docker" , "version" , "--format" , "{{.Client.Version}}" )
104
+ cmd .Stdout = cmdOut
103
105
err := cmd .Run ()
104
- if err != nil {
106
+ if err != nil || cmdOut . String () == "" {
105
107
return fmt .Errorf ("%s" , suggestedText )
106
108
}
109
+ return isSupportedDockerVersion (strings .TrimSuffix (cmdOut .String (), "\n " ))
110
+ }
111
+
112
+ // isSupportedDockerVersion returns an error if a given docker version is invalid
113
+ // or is less than minSupportedDockerVersion
114
+ func isSupportedDockerVersion (v string ) error {
115
+ suggestedText := fmt .Sprintf (`docker client version must be %s or greater` , minSupportedDockerVersion )
116
+ // docker version output does not have a leading v which is required by semver, so we prefix it
117
+ currentDockerVersion := fmt .Sprintf ("v%s" , v )
118
+ if ! semver .IsValid (currentDockerVersion ) {
119
+ return fmt .Errorf ("%s: found invalid version %s" , suggestedText , currentDockerVersion )
120
+ }
121
+ // if currentDockerVersion is less than minDockerClientVersion, compare returns +1
122
+ if semver .Compare (minSupportedDockerVersion , currentDockerVersion ) > 0 {
123
+ return fmt .Errorf ("%s: found %s" , suggestedText , currentDockerVersion )
124
+ }
107
125
return nil
108
126
}
109
127
0 commit comments