11package generate
22
33import (
4+ "context"
45 "encoding/json"
56 "fmt"
67 "os"
78 "os/exec"
89 "path"
910
11+ "github.com/Masterminds/semver"
12+ "github.com/docker/docker/client"
1013 petname "github.com/dustinkirkland/golang-petname"
1114 bettererrors "github.com/xtuc/better-errors"
1215
1316 "github.com/bytearena/ba/subcommand/build"
17+ "github.com/bytearena/core/common/dockerfile"
1418 "github.com/bytearena/core/common/types"
1519)
1620
@@ -133,6 +137,17 @@ func Main(name string) (bool, error) {
133137 return false , berror
134138 }
135139
140+ // assert Docker supports multistaged
141+ assertErr := assertDockerSupportsMultiStageBuild (path .Join (dest , build .DOCKER_BUILD_FILE ))
142+
143+ if assertErr != nil {
144+ berror := bettererrors .
145+ New ("assert Docker version failed" ).
146+ With (assertErr )
147+
148+ return false , berror
149+ }
150+
136151 // Build agent
137152 showUsage , err := build .Main (dest )
138153
@@ -146,3 +161,51 @@ func Main(name string) (bool, error) {
146161
147162 return false , nil
148163}
164+
165+ func assertDockerSupportsMultiStageBuild (dockerfileLocation string ) error {
166+ reader , openErr := os .Open (dockerfileLocation )
167+
168+ if openErr != nil {
169+ return bettererrors .NewFromErr (openErr )
170+ }
171+
172+ froms , parseError := dockerfile .DockerfileParserGetFroms (reader )
173+
174+ if parseError != nil {
175+ return bettererrors .NewFromErr (parseError )
176+ }
177+
178+ // Abord here because it's not a multistage-build
179+ if len (froms ) == 1 {
180+ return nil
181+ }
182+
183+ cli , clientErr := client .NewEnvClient ()
184+
185+ if clientErr != nil {
186+ return bettererrors .NewFromErr (clientErr )
187+ }
188+
189+ serverVersion , getVersionErr := cli .ServerVersion (context .Background ())
190+
191+ if getVersionErr != nil {
192+ return bettererrors .NewFromErr (getVersionErr )
193+ }
194+
195+ expectedRange := ">=17.05.0-ce"
196+ semverExpectedRange , _ := semver .NewConstraint (expectedRange )
197+ current , cliVersionError := semver .NewVersion (serverVersion .Version )
198+
199+ if cliVersionError != nil {
200+ return bettererrors .NewFromErr (cliVersionError )
201+ }
202+
203+ if ok , _ := semverExpectedRange .Validate (current ); ! ok {
204+ return bettererrors .
205+ New ("Invalid Docker version" ).
206+ SetContext ("expected" , expectedRange ).
207+ SetContext ("current" , serverVersion .Version )
208+ }
209+
210+ return nil
211+ }
0 commit comments