use container image platform only on docker 1.41+ (#591)
Commit af5140f13e
introduced support for
specifying a container image platform for cross-platform image building.
Unfortunately, attempting to execute a docker command that includes the
`--platform` flag against Docker daemons using API Version 1.40 and
before results in the following error:
```
"specify container image platform" requires API version 1.41, but the Docker daemon API version is 1.40
```
To allow `act` to be used on the 19.03 Docker CE and earlier versions,
this patch simply checks the Docker daemon API version and only
specifies platform specification when the daemon API version is 1.41 or
greater.
Fixes Issue #586
This commit is contained in:
parent
737dfaff3d
commit
d67e282f68
5 changed files with 36 additions and 10 deletions
|
@ -87,7 +87,7 @@ It will save that information to `~/.actrc`, please refer to [Configuration](#co
|
|||
```none
|
||||
-a, --actor string user that triggered the event (default "nektos/act")
|
||||
-b, --bind bind working directory to container, rather than copy
|
||||
--container-architecture string Architecture which should be used to run containers, e.g.: linux/amd64. Defaults to linux/<your machine architecture> [linux/amd64]
|
||||
--container-architecture string Architecture which should be used to run containers, e.g.: linux/amd64. Defaults to linux/<your machine architecture> [linux/amd64]. Requires Docker server API Version 1.41+. Ignored on earlier Docker server platforms.
|
||||
--defaultbranch string the name of the main branch
|
||||
--detect-event Use first event type from workflow as event that triggered the workflow
|
||||
-C, --directory string working directory (default ".")
|
||||
|
|
|
@ -58,7 +58,7 @@ func Execute(ctx context.Context, version string) {
|
|||
rootCmd.PersistentFlags().StringVarP(&input.secretfile, "secret-file", "", ".secrets", "file with list of secrets to read from (e.g. --secret-file .secrets)")
|
||||
rootCmd.PersistentFlags().BoolVarP(&input.insecureSecrets, "insecure-secrets", "", false, "NOT RECOMMENDED! Doesn't hide secrets while printing logs.")
|
||||
rootCmd.PersistentFlags().StringVarP(&input.envfile, "env-file", "", ".env", "environment file to read and use as env in the containers")
|
||||
rootCmd.PersistentFlags().StringVarP(&input.containerArchitecture, "container-architecture", "", "", "Architecture which should be used to run containers, e.g.: linux/amd64. Defaults to linux/<your machine architecture> [linux/"+runtime.GOARCH+"]")
|
||||
rootCmd.PersistentFlags().StringVarP(&input.containerArchitecture, "container-architecture", "", "", "Architecture which should be used to run containers, e.g.: linux/amd64. Defaults to linux/<your machine architecture> [linux/"+runtime.GOARCH+"]. Requires Docker server API Version 1.41+. Ignored on earlier Docker server platforms.")
|
||||
rootCmd.SetArgs(args())
|
||||
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
|
|
1
go.mod
1
go.mod
|
@ -4,6 +4,7 @@ go 1.14
|
|||
|
||||
require (
|
||||
github.com/AlecAivazis/survey/v2 v2.2.7
|
||||
github.com/Masterminds/semver v1.5.0
|
||||
github.com/MichaelTJones/walk v0.0.0-20161122175330-4748e29d5718 // indirect
|
||||
github.com/andreaskoch/go-fswatch v1.0.0
|
||||
github.com/containerd/containerd v1.4.1 // indirect
|
||||
|
|
1
go.sum
1
go.sum
|
@ -93,6 +93,7 @@ github.com/Djarvur/go-err113 v0.0.0-20200410182137-af658d038157/go.mod h1:4UJr5H
|
|||
github.com/Djarvur/go-err113 v0.1.0/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
|
||||
github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20191009163259-e802c2cb94ae/go.mod h1:mjwGPas4yKduTyubHvD1Atl9r1rUq8DfVy+gkVvZ+oo=
|
||||
github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190822182118-27a4ced34534/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14=
|
||||
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
||||
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Masterminds/semver/v3 v3.0.3/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
"github.com/docker/docker/pkg/stdcopy"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
|
||||
"github.com/Masterminds/semver"
|
||||
"github.com/pkg/errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/term"
|
||||
|
@ -77,6 +78,25 @@ func NewContainer(input *NewContainerInput) Container {
|
|||
return cr
|
||||
}
|
||||
|
||||
// supportsContainerImagePlatform returns true if the underlying Docker server
|
||||
// API version is 1.41 and beyond
|
||||
func supportsContainerImagePlatform(cli *client.Client) bool {
|
||||
ctx := context.TODO()
|
||||
logger := common.Logger(ctx)
|
||||
ver, err := cli.ServerVersion(ctx)
|
||||
if err != nil {
|
||||
logger.Panicf("Failed to get Docker API Version: %s", err)
|
||||
return false
|
||||
}
|
||||
sv, err := semver.NewVersion(ver.APIVersion)
|
||||
if err != nil {
|
||||
logger.Panicf("Failed to unmarshal Docker Version: %s", err)
|
||||
return false
|
||||
}
|
||||
constraint, _ := semver.NewConstraint(">= 1.41")
|
||||
return constraint.Check(sv)
|
||||
}
|
||||
|
||||
func (cr *containerReference) Create() common.Executor {
|
||||
return common.
|
||||
NewDebugExecutor("%sdocker create image=%s platform=%s entrypoint=%+q cmd=%+q", logPrefix, cr.input.Image, cr.input.Platform, cr.input.Entrypoint, cr.input.Cmd).
|
||||
|
@ -272,22 +292,26 @@ func (cr *containerReference) create() common.Executor {
|
|||
})
|
||||
}
|
||||
|
||||
desiredPlatform := strings.SplitN(cr.input.Platform, `/`, 2)
|
||||
var platSpecs *specs.Platform
|
||||
if supportsContainerImagePlatform(cr.cli) {
|
||||
desiredPlatform := strings.SplitN(cr.input.Platform, `/`, 2)
|
||||
|
||||
if len(desiredPlatform) != 2 {
|
||||
logger.Panicf("Incorrect container platform option. %s is not a valid platform.", cr.input.Platform)
|
||||
if len(desiredPlatform) != 2 {
|
||||
logger.Panicf("Incorrect container platform option. %s is not a valid platform.", cr.input.Platform)
|
||||
}
|
||||
|
||||
platSpecs = &specs.Platform{
|
||||
Architecture: desiredPlatform[1],
|
||||
OS: desiredPlatform[0],
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := cr.cli.ContainerCreate(ctx, config, &container.HostConfig{
|
||||
Binds: input.Binds,
|
||||
Mounts: mounts,
|
||||
NetworkMode: container.NetworkMode(input.NetworkMode),
|
||||
Privileged: input.Privileged,
|
||||
UsernsMode: container.UsernsMode(input.UsernsMode),
|
||||
}, nil, &specs.Platform{
|
||||
Architecture: desiredPlatform[1],
|
||||
OS: desiredPlatform[0],
|
||||
}, input.Name)
|
||||
}, nil, platSpecs, input.Name)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue