mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-09-01 16:39:23 +08:00
Compare commits
24 Commits
v0.9.0-rc2
...
v0.9
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2af40b75b7 | ||
![]() |
83f3691c15 | ||
![]() |
4e93e87991 | ||
![]() |
3f1516d3fe | ||
![]() |
09d1e1ee99 | ||
![]() |
2e9906ba20 | ||
![]() |
ed00243a0c | ||
![]() |
1223e759a4 | ||
![]() |
4fd3ec1a50 | ||
![]() |
7f9cad1e4e | ||
![]() |
437b8b140f | ||
![]() |
8f0d9bd71f | ||
![]() |
9c22be5d9c | ||
![]() |
42dea89247 | ||
![]() |
982a332679 | ||
![]() |
441853f189 | ||
![]() |
611329fc7f | ||
![]() |
f3c135e583 | ||
![]() |
7f84582b37 | ||
![]() |
297526c49d | ||
![]() |
d01d394a2b | ||
![]() |
17d4369866 | ||
![]() |
fb5e1393a4 | ||
![]() |
18dbde9ed6 |
56
bake/bake.go
56
bake/bake.go
@@ -200,15 +200,15 @@ func ParseFiles(files []File, defaults map[string]string) (_ *Config, err error)
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
var c Config
|
var c Config
|
||||||
var fs []*hcl.File
|
var composeFiles []File
|
||||||
|
var hclFiles []*hcl.File
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
cfg, isCompose, composeErr := ParseComposeFile(f.Data, f.Name)
|
isCompose, composeErr := validateComposeFile(f.Data, f.Name)
|
||||||
if isCompose {
|
if isCompose {
|
||||||
if composeErr != nil {
|
if composeErr != nil {
|
||||||
return nil, composeErr
|
return nil, composeErr
|
||||||
}
|
}
|
||||||
c = mergeConfig(c, *cfg)
|
composeFiles = append(composeFiles, f)
|
||||||
c = dedupeConfig(c)
|
|
||||||
}
|
}
|
||||||
if !isCompose {
|
if !isCompose {
|
||||||
hf, isHCL, err := ParseHCLFile(f.Data, f.Name)
|
hf, isHCL, err := ParseHCLFile(f.Data, f.Name)
|
||||||
@@ -216,7 +216,7 @@ func ParseFiles(files []File, defaults map[string]string) (_ *Config, err error)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
fs = append(fs, hf)
|
hclFiles = append(hclFiles, hf)
|
||||||
} else if composeErr != nil {
|
} else if composeErr != nil {
|
||||||
return nil, fmt.Errorf("failed to parse %s: parsing yaml: %v, parsing hcl: %w", f.Name, composeErr, err)
|
return nil, fmt.Errorf("failed to parse %s: parsing yaml: %v, parsing hcl: %w", f.Name, composeErr, err)
|
||||||
} else {
|
} else {
|
||||||
@@ -225,8 +225,17 @@ func ParseFiles(files []File, defaults map[string]string) (_ *Config, err error)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(fs) > 0 {
|
if len(composeFiles) > 0 {
|
||||||
if err := hclparser.Parse(hcl.MergeFiles(fs), hclparser.Opt{
|
cfg, cmperr := ParseComposeFiles(composeFiles)
|
||||||
|
if cmperr != nil {
|
||||||
|
return nil, errors.Wrap(cmperr, "failed to parse compose file")
|
||||||
|
}
|
||||||
|
c = mergeConfig(c, *cfg)
|
||||||
|
c = dedupeConfig(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(hclFiles) > 0 {
|
||||||
|
if err := hclparser.Parse(hcl.MergeFiles(hclFiles), hclparser.Opt{
|
||||||
LookupVar: os.LookupEnv,
|
LookupVar: os.LookupEnv,
|
||||||
Vars: defaults,
|
Vars: defaults,
|
||||||
ValidateLabel: validateTargetName,
|
ValidateLabel: validateTargetName,
|
||||||
@@ -234,18 +243,25 @@ func ParseFiles(files []File, defaults map[string]string) (_ *Config, err error)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &c, nil
|
return &c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func dedupeConfig(c Config) Config {
|
func dedupeConfig(c Config) Config {
|
||||||
c2 := c
|
c2 := c
|
||||||
|
c2.Groups = make([]*Group, 0, len(c2.Groups))
|
||||||
|
for _, g := range c.Groups {
|
||||||
|
g1 := *g
|
||||||
|
g1.Targets = dedupSlice(g1.Targets)
|
||||||
|
c2.Groups = append(c2.Groups, &g1)
|
||||||
|
}
|
||||||
c2.Targets = make([]*Target, 0, len(c2.Targets))
|
c2.Targets = make([]*Target, 0, len(c2.Targets))
|
||||||
m := map[string]*Target{}
|
mt := map[string]*Target{}
|
||||||
for _, t := range c.Targets {
|
for _, t := range c.Targets {
|
||||||
if t2, ok := m[t.Name]; ok {
|
if t2, ok := mt[t.Name]; ok {
|
||||||
t2.Merge(t)
|
t2.Merge(t)
|
||||||
} else {
|
} else {
|
||||||
m[t.Name] = t
|
mt[t.Name] = t
|
||||||
c2.Targets = append(c2.Targets, t)
|
c2.Targets = append(c2.Targets, t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -256,26 +272,6 @@ func ParseFile(dt []byte, fn string) (*Config, error) {
|
|||||||
return ParseFiles([]File{{Data: dt, Name: fn}}, nil)
|
return ParseFiles([]File{{Data: dt, Name: fn}}, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseComposeFile(dt []byte, fn string) (*Config, bool, error) {
|
|
||||||
envs := sliceToMap(os.Environ())
|
|
||||||
if wd, err := os.Getwd(); err == nil {
|
|
||||||
envs, err = loadDotEnv(envs, wd)
|
|
||||||
if err != nil {
|
|
||||||
return nil, true, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fnl := strings.ToLower(fn)
|
|
||||||
if strings.HasSuffix(fnl, ".yml") || strings.HasSuffix(fnl, ".yaml") {
|
|
||||||
cfg, err := ParseCompose(dt, envs)
|
|
||||||
return cfg, true, err
|
|
||||||
}
|
|
||||||
if strings.HasSuffix(fnl, ".json") || strings.HasSuffix(fnl, ".hcl") {
|
|
||||||
return nil, false, nil
|
|
||||||
}
|
|
||||||
cfg, err := ParseCompose(dt, envs)
|
|
||||||
return cfg, err == nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Groups []*Group `json:"group" hcl:"group,block"`
|
Groups []*Group `json:"group" hcl:"group,block"`
|
||||||
Targets []*Target `json:"target" hcl:"target,block"`
|
Targets []*Target `json:"target" hcl:"target,block"`
|
||||||
|
@@ -530,7 +530,8 @@ func TestReadEmptyTargets(t *testing.T) {
|
|||||||
Name: "docker-compose.yml",
|
Name: "docker-compose.yml",
|
||||||
Data: []byte(`
|
Data: []byte(`
|
||||||
services:
|
services:
|
||||||
app2: {}
|
app2:
|
||||||
|
build: {}
|
||||||
`),
|
`),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1226,3 +1227,35 @@ target "f" {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUnknownExt(t *testing.T) {
|
||||||
|
dt := []byte(`
|
||||||
|
target "app" {
|
||||||
|
context = "dir"
|
||||||
|
args = {
|
||||||
|
v1 = "foo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
dt2 := []byte(`
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
build:
|
||||||
|
dockerfile: Dockerfile-alternate
|
||||||
|
args:
|
||||||
|
v2: "bar"
|
||||||
|
`)
|
||||||
|
|
||||||
|
c, err := ParseFiles([]File{
|
||||||
|
{Data: dt, Name: "c1.foo"},
|
||||||
|
{Data: dt2, Name: "c2.bar"},
|
||||||
|
}, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, 1, len(c.Targets))
|
||||||
|
require.Equal(t, "app", c.Targets[0].Name)
|
||||||
|
require.Equal(t, "foo", c.Targets[0].Args["v1"])
|
||||||
|
require.Equal(t, "bar", c.Targets[0].Args["v2"])
|
||||||
|
require.Equal(t, "dir", *c.Targets[0].Context)
|
||||||
|
require.Equal(t, "Dockerfile-alternate", *c.Targets[0].Dockerfile)
|
||||||
|
}
|
||||||
|
105
bake/compose.go
105
bake/compose.go
@@ -1,7 +1,6 @@
|
|||||||
package bake
|
package bake
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -13,25 +12,29 @@ import (
|
|||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// errComposeInvalid is returned when a compose file is invalid
|
func ParseComposeFiles(fs []File) (*Config, error) {
|
||||||
var errComposeInvalid = errors.New("invalid compose file")
|
envs, err := composeEnv()
|
||||||
|
|
||||||
func ParseCompose(dt []byte, envs map[string]string) (*Config, error) {
|
|
||||||
cfg, err := loader.Load(compose.ConfigDetails{
|
|
||||||
ConfigFiles: []compose.ConfigFile{
|
|
||||||
{
|
|
||||||
Content: dt,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Environment: envs,
|
|
||||||
}, func(options *loader.Options) {
|
|
||||||
options.SkipNormalization = true
|
|
||||||
options.SkipConsistencyCheck = true
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err = composeValidate(cfg); err != nil {
|
var cfgs []compose.ConfigFile
|
||||||
|
for _, f := range fs {
|
||||||
|
cfgs = append(cfgs, compose.ConfigFile{
|
||||||
|
Filename: f.Name,
|
||||||
|
Content: f.Data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return ParseCompose(cfgs, envs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseCompose(cfgs []compose.ConfigFile, envs map[string]string) (*Config, error) {
|
||||||
|
cfg, err := loader.Load(compose.ConfigDetails{
|
||||||
|
ConfigFiles: cfgs,
|
||||||
|
Environment: envs,
|
||||||
|
}, func(options *loader.Options) {
|
||||||
|
options.SkipNormalization = true
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +47,7 @@ func ParseCompose(dt []byte, envs map[string]string) (*Config, error) {
|
|||||||
|
|
||||||
for _, s := range cfg.Services {
|
for _, s := range cfg.Services {
|
||||||
if s.Build == nil {
|
if s.Build == nil {
|
||||||
s.Build = &compose.BuildConfig{}
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
targetName := sanitizeTargetName(s.Name)
|
targetName := sanitizeTargetName(s.Name)
|
||||||
@@ -110,6 +113,50 @@ func ParseCompose(dt []byte, envs map[string]string) (*Config, error) {
|
|||||||
return &c, nil
|
return &c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validateComposeFile(dt []byte, fn string) (bool, error) {
|
||||||
|
envs, err := composeEnv()
|
||||||
|
if err != nil {
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
fnl := strings.ToLower(fn)
|
||||||
|
if strings.HasSuffix(fnl, ".yml") || strings.HasSuffix(fnl, ".yaml") {
|
||||||
|
return true, validateCompose(dt, envs)
|
||||||
|
}
|
||||||
|
if strings.HasSuffix(fnl, ".json") || strings.HasSuffix(fnl, ".hcl") {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
err = validateCompose(dt, envs)
|
||||||
|
return err == nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateCompose(dt []byte, envs map[string]string) error {
|
||||||
|
_, err := loader.Load(compose.ConfigDetails{
|
||||||
|
ConfigFiles: []compose.ConfigFile{
|
||||||
|
{
|
||||||
|
Content: dt,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Environment: envs,
|
||||||
|
}, func(options *loader.Options) {
|
||||||
|
options.SkipNormalization = true
|
||||||
|
// consistency is checked later in ParseCompose to ensure multiple
|
||||||
|
// compose files can be merged together
|
||||||
|
options.SkipConsistencyCheck = true
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func composeEnv() (map[string]string, error) {
|
||||||
|
envs := sliceToMap(os.Environ())
|
||||||
|
if wd, err := os.Getwd(); err == nil {
|
||||||
|
envs, err = loadDotEnv(envs, wd)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return envs, nil
|
||||||
|
}
|
||||||
|
|
||||||
func loadDotEnv(curenv map[string]string, workingDir string) (map[string]string, error) {
|
func loadDotEnv(curenv map[string]string, workingDir string) (map[string]string, error) {
|
||||||
if curenv == nil {
|
if curenv == nil {
|
||||||
curenv = make(map[string]string)
|
curenv = make(map[string]string)
|
||||||
@@ -248,28 +295,6 @@ func (t *Target) composeExtTarget(exts map[string]interface{}) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// composeValidate validates a compose file
|
|
||||||
func composeValidate(project *compose.Project) error {
|
|
||||||
for _, s := range project.Services {
|
|
||||||
if s.Build != nil {
|
|
||||||
for _, secret := range s.Build.Secrets {
|
|
||||||
if _, ok := project.Secrets[secret.Source]; !ok {
|
|
||||||
return errors.Wrap(errComposeInvalid, fmt.Sprintf("service %q refers to undefined build secret %s", sanitizeTargetName(s.Name), secret.Source))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for name, secret := range project.Secrets {
|
|
||||||
if secret.External.External {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if secret.File == "" && secret.Environment == "" {
|
|
||||||
return errors.Wrap(errComposeInvalid, fmt.Sprintf("secret %q must declare either `file` or `environment`", name))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// composeToBuildkitSecret converts secret from compose format to buildkit's
|
// composeToBuildkitSecret converts secret from compose format to buildkit's
|
||||||
// csv format.
|
// csv format.
|
||||||
func composeToBuildkitSecret(inp compose.ServiceSecretConfig, psecret compose.SecretConfig) (string, error) {
|
func composeToBuildkitSecret(inp compose.ServiceSecretConfig, psecret compose.SecretConfig) (string, error) {
|
||||||
|
@@ -6,6 +6,8 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
compose "github.com/compose-spec/compose-go/types"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -38,7 +40,7 @@ secrets:
|
|||||||
file: /root/.aws/credentials
|
file: /root/.aws/credentials
|
||||||
`)
|
`)
|
||||||
|
|
||||||
c, err := ParseCompose(dt, nil)
|
c, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Equal(t, 1, len(c.Groups))
|
require.Equal(t, 1, len(c.Groups))
|
||||||
@@ -76,9 +78,10 @@ services:
|
|||||||
webapp:
|
webapp:
|
||||||
build: ./db
|
build: ./db
|
||||||
`)
|
`)
|
||||||
c, err := ParseCompose(dt, nil)
|
c, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, 1, len(c.Groups))
|
require.Equal(t, 1, len(c.Groups))
|
||||||
|
require.Equal(t, 1, len(c.Targets))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseComposeTarget(t *testing.T) {
|
func TestParseComposeTarget(t *testing.T) {
|
||||||
@@ -94,7 +97,7 @@ services:
|
|||||||
target: webapp
|
target: webapp
|
||||||
`)
|
`)
|
||||||
|
|
||||||
c, err := ParseCompose(dt, nil)
|
c, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Equal(t, 2, len(c.Targets))
|
require.Equal(t, 2, len(c.Targets))
|
||||||
@@ -119,7 +122,7 @@ services:
|
|||||||
target: webapp
|
target: webapp
|
||||||
`)
|
`)
|
||||||
|
|
||||||
c, err := ParseCompose(dt, nil)
|
c, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, 2, len(c.Targets))
|
require.Equal(t, 2, len(c.Targets))
|
||||||
sort.Slice(c.Targets, func(i, j int) bool {
|
sort.Slice(c.Targets, func(i, j int) bool {
|
||||||
@@ -153,7 +156,7 @@ services:
|
|||||||
os.Setenv("ZZZ_BAR", "zzz_foo")
|
os.Setenv("ZZZ_BAR", "zzz_foo")
|
||||||
defer os.Unsetenv("ZZZ_BAR")
|
defer os.Unsetenv("ZZZ_BAR")
|
||||||
|
|
||||||
c, err := ParseCompose(dt, sliceToMap(os.Environ()))
|
c, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, sliceToMap(os.Environ()))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, "bar", c.Targets[0].Args["FOO"])
|
require.Equal(t, "bar", c.Targets[0].Args["FOO"])
|
||||||
require.Equal(t, "zzz_foo", c.Targets[0].Args["BAR"])
|
require.Equal(t, "zzz_foo", c.Targets[0].Args["BAR"])
|
||||||
@@ -167,8 +170,8 @@ services:
|
|||||||
entrypoint: echo 1
|
entrypoint: echo 1
|
||||||
`)
|
`)
|
||||||
|
|
||||||
_, err := ParseCompose(dt, nil)
|
_, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
|
||||||
require.NoError(t, err)
|
require.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAdvancedNetwork(t *testing.T) {
|
func TestAdvancedNetwork(t *testing.T) {
|
||||||
@@ -192,7 +195,7 @@ networks:
|
|||||||
gateway: 10.5.0.254
|
gateway: 10.5.0.254
|
||||||
`)
|
`)
|
||||||
|
|
||||||
_, err := ParseCompose(dt, nil)
|
_, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +212,7 @@ services:
|
|||||||
- bar
|
- bar
|
||||||
`)
|
`)
|
||||||
|
|
||||||
c, err := ParseCompose(dt, nil)
|
c, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, []string{"foo", "bar"}, c.Targets[0].Tags)
|
require.Equal(t, []string{"foo", "bar"}, c.Targets[0].Tags)
|
||||||
}
|
}
|
||||||
@@ -246,7 +249,7 @@ networks:
|
|||||||
name: test-net
|
name: test-net
|
||||||
`)
|
`)
|
||||||
|
|
||||||
_, err := ParseCompose(dt, nil)
|
_, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,7 +302,7 @@ services:
|
|||||||
no-cache: true
|
no-cache: true
|
||||||
`)
|
`)
|
||||||
|
|
||||||
c, err := ParseCompose(dt, nil)
|
c, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, 2, len(c.Targets))
|
require.Equal(t, 2, len(c.Targets))
|
||||||
sort.Slice(c.Targets, func(i, j int) bool {
|
sort.Slice(c.Targets, func(i, j int) bool {
|
||||||
@@ -343,7 +346,7 @@ services:
|
|||||||
- type=local,dest=path/to/cache
|
- type=local,dest=path/to/cache
|
||||||
`)
|
`)
|
||||||
|
|
||||||
c, err := ParseCompose(dt, nil)
|
c, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, 1, len(c.Targets))
|
require.Equal(t, 1, len(c.Targets))
|
||||||
require.Equal(t, []string{"ct-addon:foo", "ct-addon:baz"}, c.Targets[0].Tags)
|
require.Equal(t, []string{"ct-addon:foo", "ct-addon:baz"}, c.Targets[0].Tags)
|
||||||
@@ -376,7 +379,7 @@ services:
|
|||||||
- ` + envf.Name() + `
|
- ` + envf.Name() + `
|
||||||
`)
|
`)
|
||||||
|
|
||||||
c, err := ParseCompose(dt, nil)
|
c, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, map[string]string{"CT_ECR": "foo", "FOO": "bsdf -csdf", "NODE_ENV": "test"}, c.Targets[0].Args)
|
require.Equal(t, map[string]string{"CT_ECR": "foo", "FOO": "bsdf -csdf", "NODE_ENV": "test"}, c.Targets[0].Args)
|
||||||
}
|
}
|
||||||
@@ -397,7 +400,10 @@ services:
|
|||||||
`)
|
`)
|
||||||
|
|
||||||
chdir(t, tmpdir)
|
chdir(t, tmpdir)
|
||||||
c, _, err := ParseComposeFile(dt, "docker-compose.yml")
|
c, err := ParseComposeFiles([]File{{
|
||||||
|
Name: "docker-compose.yml",
|
||||||
|
Data: dt,
|
||||||
|
}})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, map[string]string{"FOO": "bar"}, c.Targets[0].Args)
|
require.Equal(t, map[string]string{"FOO": "bar"}, c.Targets[0].Args)
|
||||||
}
|
}
|
||||||
@@ -419,7 +425,7 @@ services:
|
|||||||
published: "3306"
|
published: "3306"
|
||||||
protocol: tcp
|
protocol: tcp
|
||||||
`)
|
`)
|
||||||
_, err := ParseCompose(dt, nil)
|
_, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -465,12 +471,12 @@ func TestServiceName(t *testing.T) {
|
|||||||
for _, tt := range cases {
|
for _, tt := range cases {
|
||||||
tt := tt
|
tt := tt
|
||||||
t.Run(tt.svc, func(t *testing.T) {
|
t.Run(tt.svc, func(t *testing.T) {
|
||||||
_, err := ParseCompose([]byte(`
|
_, err := ParseCompose([]compose.ConfigFile{{Content: []byte(`
|
||||||
services:
|
services:
|
||||||
`+tt.svc+`:
|
` + tt.svc + `:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
`), nil)
|
`)}}, nil)
|
||||||
if tt.wantErr {
|
if tt.wantErr {
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
} else {
|
} else {
|
||||||
@@ -536,7 +542,84 @@ services:
|
|||||||
for _, tt := range cases {
|
for _, tt := range cases {
|
||||||
tt := tt
|
tt := tt
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
_, err := ParseCompose(tt.dt, nil)
|
_, err := ParseCompose([]compose.ConfigFile{{Content: tt.dt}}, nil)
|
||||||
|
if tt.wantErr {
|
||||||
|
require.Error(t, err)
|
||||||
|
} else {
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidateComposeFile(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
name string
|
||||||
|
fn string
|
||||||
|
dt []byte
|
||||||
|
isCompose bool
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "empty service",
|
||||||
|
fn: "docker-compose.yml",
|
||||||
|
dt: []byte(`
|
||||||
|
services:
|
||||||
|
foo:
|
||||||
|
`),
|
||||||
|
isCompose: true,
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "build",
|
||||||
|
fn: "docker-compose.yml",
|
||||||
|
dt: []byte(`
|
||||||
|
services:
|
||||||
|
foo:
|
||||||
|
build: .
|
||||||
|
`),
|
||||||
|
isCompose: true,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "image",
|
||||||
|
fn: "docker-compose.yml",
|
||||||
|
dt: []byte(`
|
||||||
|
services:
|
||||||
|
simple:
|
||||||
|
image: nginx
|
||||||
|
`),
|
||||||
|
isCompose: true,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "unknown ext",
|
||||||
|
fn: "docker-compose.foo",
|
||||||
|
dt: []byte(`
|
||||||
|
services:
|
||||||
|
simple:
|
||||||
|
image: nginx
|
||||||
|
`),
|
||||||
|
isCompose: true,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "hcl",
|
||||||
|
fn: "docker-bake.hcl",
|
||||||
|
dt: []byte(`
|
||||||
|
target "default" {
|
||||||
|
dockerfile = "test"
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
isCompose: false,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range cases {
|
||||||
|
tt := tt
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
isCompose, err := validateComposeFile(tt.dt, tt.fn)
|
||||||
|
assert.Equal(t, tt.isCompose, isCompose)
|
||||||
if tt.wantErr {
|
if tt.wantErr {
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
} else {
|
} else {
|
||||||
|
@@ -59,7 +59,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
printFallbackImage = "docker/dockerfile-upstream:1.4-outline@sha256:ccd574ab34a8875c64bb6a8fb3cfae2e6d62d31b28b9f688075cc14c9b669a59"
|
printFallbackImage = "docker/dockerfile-upstream:1.4-outline@sha256:627443ff4e2d0f635d429cfc1da5388bcd5a70949c38adcd3cd7c4e5df67c73c"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
|
@@ -479,7 +479,7 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
|
|||||||
flags.StringArrayVar(&options.platforms, "platform", platformsDefault, "Set target platform for build")
|
flags.StringArrayVar(&options.platforms, "platform", platformsDefault, "Set target platform for build")
|
||||||
|
|
||||||
if isExperimental() {
|
if isExperimental() {
|
||||||
flags.StringVar(&options.printFunc, "print", "", "Print result of information request (outline, targets)")
|
flags.StringVar(&options.printFunc, "print", "", "Print result of information request (e.g., outline, targets) [experimental]")
|
||||||
}
|
}
|
||||||
|
|
||||||
flags.BoolVar(&options.exportPush, "push", false, `Shorthand for "--output=type=registry"`)
|
flags.BoolVar(&options.exportPush, "push", false, `Shorthand for "--output=type=registry"`)
|
||||||
@@ -501,7 +501,7 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
|
|||||||
flags.Var(options.ulimits, "ulimit", "Ulimit options")
|
flags.Var(options.ulimits, "ulimit", "Ulimit options")
|
||||||
|
|
||||||
if isExperimental() {
|
if isExperimental() {
|
||||||
flags.StringVar(&options.invoke, "invoke", "", "Invoke a command after the build. BUILDX_EXPERIMENTAL=1 is required.")
|
flags.StringVar(&options.invoke, "invoke", "", "Invoke a command after the build [experimental]")
|
||||||
}
|
}
|
||||||
|
|
||||||
// hidden flags
|
// hidden flags
|
||||||
@@ -701,7 +701,7 @@ func (w *wrapped) Unwrap() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func isExperimental() bool {
|
func isExperimental() bool {
|
||||||
if v, ok := os.LookupEnv("BUILDKIT_EXPERIMENTAL"); ok {
|
if v, ok := os.LookupEnv("BUILDX_EXPERIMENTAL"); ok {
|
||||||
vv, _ := strconv.ParseBool(v)
|
vv, _ := strconv.ParseBool(v)
|
||||||
return vv
|
return vv
|
||||||
}
|
}
|
||||||
|
@@ -135,8 +135,8 @@ func runCreate(dockerCli command.Cli, in createOptions, args []string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if driver.GetFactory(driverName, true) == nil {
|
if _, err := driver.GetFactory(driverName, true); err != nil {
|
||||||
return errors.Errorf("failed to find driver %q", driverName)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOriginal := ng
|
ngOriginal := ng
|
||||||
@@ -282,7 +282,7 @@ func createCmd(dockerCli command.Cli) *cobra.Command {
|
|||||||
var options createOptions
|
var options createOptions
|
||||||
|
|
||||||
var drivers bytes.Buffer
|
var drivers bytes.Buffer
|
||||||
for _, d := range driver.GetFactories() {
|
for _, d := range driver.GetFactories(true) {
|
||||||
if len(drivers.String()) > 0 {
|
if len(drivers.String()) > 0 {
|
||||||
drivers.WriteString(", ")
|
drivers.WriteString(", ")
|
||||||
}
|
}
|
||||||
|
@@ -115,6 +115,9 @@ func runInspect(dockerCli command.Cli, in inspectOptions) error {
|
|||||||
if len(n.Flags) > 0 {
|
if len(n.Flags) > 0 {
|
||||||
fmt.Fprintf(w, "Flags:\t%s\n", strings.Join(n.Flags, " "))
|
fmt.Fprintf(w, "Flags:\t%s\n", strings.Join(n.Flags, " "))
|
||||||
}
|
}
|
||||||
|
if ngi.drivers[i].version != "" {
|
||||||
|
fmt.Fprintf(w, "Buildkit:\t%s\n", ngi.drivers[i].version)
|
||||||
|
}
|
||||||
fmt.Fprintf(w, "Platforms:\t%s\n", strings.Join(platformutil.FormatInGroups(n.Platforms, ngi.drivers[i].platforms), ", "))
|
fmt.Fprintf(w, "Platforms:\t%s\n", strings.Join(platformutil.FormatInGroups(n.Platforms, ngi.drivers[i].platforms), ", "))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -60,9 +60,10 @@ func driversForNodeGroup(ctx context.Context, dockerCli command.Cli, ng *store.N
|
|||||||
|
|
||||||
var f driver.Factory
|
var f driver.Factory
|
||||||
if ng.Driver != "" {
|
if ng.Driver != "" {
|
||||||
f = driver.GetFactory(ng.Driver, true)
|
var err error
|
||||||
if f == nil {
|
f, err = driver.GetFactory(ng.Driver, true)
|
||||||
return nil, errors.Errorf("failed to find driver %q", f)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// empty driver means nodegroup was implicitly created as a default
|
// empty driver means nodegroup was implicitly created as a default
|
||||||
|
@@ -20,6 +20,7 @@ target "_common" {
|
|||||||
args = {
|
args = {
|
||||||
GO_VERSION = GO_VERSION
|
GO_VERSION = GO_VERSION
|
||||||
BUILDKIT_CONTEXT_KEEP_GIT_DIR = 1
|
BUILDKIT_CONTEXT_KEEP_GIT_DIR = 1
|
||||||
|
BUILDX_EXPERIMENTAL = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,6 +25,7 @@ Start a build
|
|||||||
| [`--cgroup-parent`](https://docs.docker.com/engine/reference/commandline/build/#use-a-custom-parent-cgroup---cgroup-parent) | `string` | | Optional parent cgroup for the container |
|
| [`--cgroup-parent`](https://docs.docker.com/engine/reference/commandline/build/#use-a-custom-parent-cgroup---cgroup-parent) | `string` | | Optional parent cgroup for the container |
|
||||||
| [`-f`](https://docs.docker.com/engine/reference/commandline/build/#specify-a-dockerfile--f), [`--file`](https://docs.docker.com/engine/reference/commandline/build/#specify-a-dockerfile--f) | `string` | | Name of the Dockerfile (default: `PATH/Dockerfile`) |
|
| [`-f`](https://docs.docker.com/engine/reference/commandline/build/#specify-a-dockerfile--f), [`--file`](https://docs.docker.com/engine/reference/commandline/build/#specify-a-dockerfile--f) | `string` | | Name of the Dockerfile (default: `PATH/Dockerfile`) |
|
||||||
| `--iidfile` | `string` | | Write the image ID to the file |
|
| `--iidfile` | `string` | | Write the image ID to the file |
|
||||||
|
| `--invoke` | `string` | | Invoke a command after the build [experimental] |
|
||||||
| `--label` | `stringArray` | | Set metadata for an image |
|
| `--label` | `stringArray` | | Set metadata for an image |
|
||||||
| [`--load`](#load) | | | Shorthand for `--output=type=docker` |
|
| [`--load`](#load) | | | Shorthand for `--output=type=docker` |
|
||||||
| [`--metadata-file`](#metadata-file) | `string` | | Write build result metadata to the file |
|
| [`--metadata-file`](#metadata-file) | `string` | | Write build result metadata to the file |
|
||||||
@@ -33,6 +34,7 @@ Start a build
|
|||||||
| `--no-cache-filter` | `stringArray` | | Do not cache specified stages |
|
| `--no-cache-filter` | `stringArray` | | Do not cache specified stages |
|
||||||
| [`-o`](#output), [`--output`](#output) | `stringArray` | | Output destination (format: `type=local,dest=path`) |
|
| [`-o`](#output), [`--output`](#output) | `stringArray` | | Output destination (format: `type=local,dest=path`) |
|
||||||
| [`--platform`](#platform) | `stringArray` | | Set target platform for build |
|
| [`--platform`](#platform) | `stringArray` | | Set target platform for build |
|
||||||
|
| `--print` | `string` | | Print result of information request (e.g., outline, targets) [experimental] |
|
||||||
| [`--progress`](#progress) | `string` | `auto` | Set type of progress output (`auto`, `plain`, `tty`). Use plain to show container output |
|
| [`--progress`](#progress) | `string` | `auto` | Set type of progress output (`auto`, `plain`, `tty`). Use plain to show container output |
|
||||||
| `--pull` | | | Always attempt to pull all referenced images |
|
| `--pull` | | | Always attempt to pull all referenced images |
|
||||||
| [`--push`](#push) | | | Shorthand for `--output=type=registry` |
|
| [`--push`](#push) | | | Shorthand for `--output=type=registry` |
|
||||||
@@ -47,6 +49,9 @@ Start a build
|
|||||||
|
|
||||||
<!---MARKER_GEN_END-->
|
<!---MARKER_GEN_END-->
|
||||||
|
|
||||||
|
Flags marked with `[experimental]` need to be explicitly enabled by setting the
|
||||||
|
`BUILDX_EXPERIMENTAL=1` environment variable.
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
The `buildx build` command starts a build using BuildKit. This command is similar
|
The `buildx build` command starts a build using BuildKit. This command is similar
|
||||||
|
@@ -15,7 +15,7 @@ Create a new builder instance
|
|||||||
| `--bootstrap` | | | Boot builder after creation |
|
| `--bootstrap` | | | Boot builder after creation |
|
||||||
| [`--buildkitd-flags`](#buildkitd-flags) | `string` | | Flags for buildkitd daemon |
|
| [`--buildkitd-flags`](#buildkitd-flags) | `string` | | Flags for buildkitd daemon |
|
||||||
| [`--config`](#config) | `string` | | BuildKit config file |
|
| [`--config`](#config) | `string` | | BuildKit config file |
|
||||||
| [`--driver`](#driver) | `string` | | Driver to use (available: `docker`, `docker-container`, `kubernetes`, `remote`) |
|
| [`--driver`](#driver) | `string` | | Driver to use (available: `docker-container`, `kubernetes`, `remote`) |
|
||||||
| [`--driver-opt`](#driver-opt) | `stringArray` | | Options for the driver |
|
| [`--driver-opt`](#driver-opt) | `stringArray` | | Options for the driver |
|
||||||
| [`--leave`](#leave) | | | Remove a node from builder instead of changing it |
|
| [`--leave`](#leave) | | | Remove a node from builder instead of changing it |
|
||||||
| [`--name`](#name) | `string` | | Builder instance name |
|
| [`--name`](#name) | `string` | | Builder instance name |
|
||||||
|
@@ -44,7 +44,7 @@ The following example shows information about a builder instance named
|
|||||||
`elated_tesla`:
|
`elated_tesla`:
|
||||||
|
|
||||||
> **Note**
|
> **Note**
|
||||||
>
|
>
|
||||||
> Asterisk `*` next to node build platform(s) indicate they had been set manually during `buildx create`. Otherwise, it had been autodetected.
|
> Asterisk `*` next to node build platform(s) indicate they had been set manually during `buildx create`. Otherwise, it had been autodetected.
|
||||||
|
|
||||||
```console
|
```console
|
||||||
@@ -57,10 +57,12 @@ Nodes:
|
|||||||
Name: elated_tesla0
|
Name: elated_tesla0
|
||||||
Endpoint: unix:///var/run/docker.sock
|
Endpoint: unix:///var/run/docker.sock
|
||||||
Status: running
|
Status: running
|
||||||
|
Buildkit: v0.10.3
|
||||||
Platforms: linux/amd64
|
Platforms: linux/amd64
|
||||||
|
|
||||||
Name: elated_tesla1
|
Name: elated_tesla1
|
||||||
Endpoint: ssh://ubuntu@1.2.3.4
|
Endpoint: ssh://ubuntu@1.2.3.4
|
||||||
Status: running
|
Status: running
|
||||||
|
Buildkit: v0.10.3
|
||||||
Platforms: linux/arm64*, linux/arm/v7, linux/arm/v6
|
Platforms: linux/arm64*, linux/arm/v7, linux/arm/v6
|
||||||
```
|
```
|
||||||
|
@@ -357,11 +357,14 @@ func (d *Driver) Client(ctx context.Context) (*client.Client, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
td, _ := exp.(client.TracerDelegate)
|
var opts []client.ClientOpt
|
||||||
|
opts = append(opts, client.WithContextDialer(func(context.Context, string) (net.Conn, error) {
|
||||||
return client.New(ctx, "", client.WithContextDialer(func(context.Context, string) (net.Conn, error) {
|
|
||||||
return conn, nil
|
return conn, nil
|
||||||
}), client.WithTracerDelegate(td))
|
}))
|
||||||
|
if td, ok := exp.(client.TracerDelegate); ok {
|
||||||
|
opts = append(opts, client.WithTracerDelegate(td))
|
||||||
|
}
|
||||||
|
return client.New(ctx, "", opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) Factory() driver.Factory {
|
func (d *Driver) Factory() driver.Factory {
|
||||||
|
@@ -215,11 +215,14 @@ func (d *Driver) Client(ctx context.Context) (*client.Client, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
td, _ := exp.(client.TracerDelegate)
|
var opts []client.ClientOpt
|
||||||
|
opts = append(opts, client.WithContextDialer(func(context.Context, string) (net.Conn, error) {
|
||||||
return client.New(ctx, "", client.WithContextDialer(func(context.Context, string) (net.Conn, error) {
|
|
||||||
return conn, nil
|
return conn, nil
|
||||||
}), client.WithTracerDelegate(td))
|
}))
|
||||||
|
if td, ok := exp.(client.TracerDelegate); ok {
|
||||||
|
opts = append(opts, client.WithTracerDelegate(td))
|
||||||
|
}
|
||||||
|
return client.New(ctx, "", opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) Factory() driver.Factory {
|
func (d *Driver) Factory() driver.Factory {
|
||||||
|
@@ -213,6 +213,24 @@ func toRootless(d *appsv1.Deployment) error {
|
|||||||
d.Spec.Template.ObjectMeta.Annotations = make(map[string]string, 1)
|
d.Spec.Template.ObjectMeta.Annotations = make(map[string]string, 1)
|
||||||
}
|
}
|
||||||
d.Spec.Template.ObjectMeta.Annotations["container.apparmor.security.beta.kubernetes.io/"+containerName] = "unconfined"
|
d.Spec.Template.ObjectMeta.Annotations["container.apparmor.security.beta.kubernetes.io/"+containerName] = "unconfined"
|
||||||
|
|
||||||
|
// Dockerfile has `VOLUME /home/user/.local/share/buildkit` by default too,
|
||||||
|
// but the default VOLUME does not work with rootless on Google's Container-Optimized OS
|
||||||
|
// as it is mounted with `nosuid,nodev`.
|
||||||
|
// https://github.com/moby/buildkit/issues/879#issuecomment-1240347038
|
||||||
|
// https://github.com/moby/buildkit/pull/3097
|
||||||
|
const emptyDirVolName = "buildkitd"
|
||||||
|
d.Spec.Template.Spec.Containers[0].VolumeMounts = append(d.Spec.Template.Spec.Containers[0].VolumeMounts, corev1.VolumeMount{
|
||||||
|
Name: emptyDirVolName,
|
||||||
|
MountPath: "/home/user/.local/share/buildkit",
|
||||||
|
})
|
||||||
|
d.Spec.Template.Spec.Volumes = append(d.Spec.Template.Spec.Volumes, corev1.Volume{
|
||||||
|
Name: emptyDirVolName,
|
||||||
|
VolumeSource: corev1.VolumeSource{
|
||||||
|
EmptyDir: &corev1.EmptyDirVolumeSource{},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -92,16 +92,16 @@ func GetDefaultFactory(ctx context.Context, ep string, c dockerclient.APIClient,
|
|||||||
return dd[0].f, nil
|
return dd[0].f, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetFactory(name string, instanceRequired bool) Factory {
|
func GetFactory(name string, instanceRequired bool) (Factory, error) {
|
||||||
for _, f := range drivers {
|
for _, f := range drivers {
|
||||||
if instanceRequired && !f.AllowsInstances() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if f.Name() == name {
|
if f.Name() == name {
|
||||||
return f
|
if instanceRequired && !f.AllowsInstances() {
|
||||||
|
return nil, errors.Errorf("additional instances of driver %q cannot be created", name)
|
||||||
|
}
|
||||||
|
return f, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil, errors.Errorf("failed to find driver %q", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetDriver(ctx context.Context, name string, f Factory, endpointAddr string, api dockerclient.APIClient, auth Auth, kcc KubeClientConfig, flags []string, files map[string][]byte, do map[string]string, platforms []specs.Platform, contextPathHash string) (Driver, error) {
|
func GetDriver(ctx context.Context, name string, f Factory, endpointAddr string, api dockerclient.APIClient, auth Auth, kcc KubeClientConfig, flags []string, files map[string][]byte, do map[string]string, platforms []specs.Platform, contextPathHash string) (Driver, error) {
|
||||||
@@ -131,9 +131,12 @@ func GetDriver(ctx context.Context, name string, f Factory, endpointAddr string,
|
|||||||
return &cachedDriver{Driver: d}, nil
|
return &cachedDriver{Driver: d}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetFactories() []Factory {
|
func GetFactories(instanceRequired bool) []Factory {
|
||||||
ds := make([]Factory, 0, len(drivers))
|
ds := make([]Factory, 0, len(drivers))
|
||||||
for _, d := range drivers {
|
for _, d := range drivers {
|
||||||
|
if instanceRequired && !d.AllowsInstances() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
ds = append(ds, d)
|
ds = append(ds, d)
|
||||||
}
|
}
|
||||||
sort.Slice(ds, func(i, j int) bool {
|
sort.Slice(ds, func(i, j int) bool {
|
||||||
|
2
go.mod
2
go.mod
@@ -15,7 +15,7 @@ require (
|
|||||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
||||||
github.com/hashicorp/go-cty-funcs v0.0.0-20200930094925-2721b1e36840
|
github.com/hashicorp/go-cty-funcs v0.0.0-20200930094925-2721b1e36840
|
||||||
github.com/hashicorp/hcl/v2 v2.8.2
|
github.com/hashicorp/hcl/v2 v2.8.2
|
||||||
github.com/moby/buildkit v0.10.1-0.20220809151411-8488654e899b
|
github.com/moby/buildkit v0.10.1-0.20220816171719-55ba9d14360a
|
||||||
github.com/morikuni/aec v1.0.0
|
github.com/morikuni/aec v1.0.0
|
||||||
github.com/opencontainers/go-digest v1.0.0
|
github.com/opencontainers/go-digest v1.0.0
|
||||||
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799
|
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799
|
||||||
|
4
go.sum
4
go.sum
@@ -411,8 +411,8 @@ github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZX
|
|||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
github.com/moby/buildkit v0.10.1-0.20220809151411-8488654e899b h1:F/f/Ixaw8REoF5EjkMLh/2RBrsP0jeCPGBlczfqy9aw=
|
github.com/moby/buildkit v0.10.1-0.20220816171719-55ba9d14360a h1:NI01Z14Hbwo1MHq8ylu4HNkmKGnhk8UZsD6c6FVMcA8=
|
||||||
github.com/moby/buildkit v0.10.1-0.20220809151411-8488654e899b/go.mod h1:Wa+LkeUQ9NJTVXTAY38rhkfKVQcuCIo2fbavRSuGsbI=
|
github.com/moby/buildkit v0.10.1-0.20220816171719-55ba9d14360a/go.mod h1:Wa+LkeUQ9NJTVXTAY38rhkfKVQcuCIo2fbavRSuGsbI=
|
||||||
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
|
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
|
||||||
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
|
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
|
||||||
github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
|
github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
|
||||||
|
@@ -14,6 +14,7 @@ RUN apk add --no-cache rsync git
|
|||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY --from=docsgen /out/docsgen /usr/bin
|
COPY --from=docsgen /out/docsgen /usr/bin
|
||||||
ARG FORMATS
|
ARG FORMATS
|
||||||
|
ARG BUILDX_EXPERIMENTAL
|
||||||
RUN --mount=target=/context \
|
RUN --mount=target=/context \
|
||||||
--mount=target=.,type=tmpfs <<EOT
|
--mount=target=.,type=tmpfs <<EOT
|
||||||
set -e
|
set -e
|
||||||
|
@@ -8,6 +8,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
@@ -112,7 +113,9 @@ func (p *Printer) Print(raw bool, out io.Writer) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
imageconfigs := make(map[string]*ocispecs.Image)
|
imageconfigs := make(map[string]*ocispecs.Image)
|
||||||
|
imageconfigsMutex := sync.Mutex{}
|
||||||
buildinfos := make(map[string]*binfotypes.BuildInfo)
|
buildinfos := make(map[string]*binfotypes.BuildInfo)
|
||||||
|
buildinfosMutex := sync.Mutex{}
|
||||||
|
|
||||||
eg, _ := errgroup.WithContext(p.ctx)
|
eg, _ := errgroup.WithContext(p.ctx)
|
||||||
for _, platform := range p.platforms {
|
for _, platform := range p.platforms {
|
||||||
@@ -122,12 +125,16 @@ func (p *Printer) Print(raw bool, out io.Writer) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
} else if img != nil {
|
} else if img != nil {
|
||||||
|
imageconfigsMutex.Lock()
|
||||||
imageconfigs[platforms.Format(platform)] = img
|
imageconfigs[platforms.Format(platform)] = img
|
||||||
|
imageconfigsMutex.Unlock()
|
||||||
}
|
}
|
||||||
if bi, err := imageutil.BuildInfo(dtic); err != nil {
|
if bi, err := imageutil.BuildInfo(dtic); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if bi != nil {
|
} else if bi != nil {
|
||||||
|
buildinfosMutex.Lock()
|
||||||
buildinfos[platforms.Format(platform)] = bi
|
buildinfos[platforms.Format(platform)] = bi
|
||||||
|
buildinfosMutex.Unlock()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
8
vendor/github.com/moby/buildkit/frontend/subrequests/outline/outline.go
generated
vendored
8
vendor/github.com/moby/buildkit/frontend/subrequests/outline/outline.go
generated
vendored
@@ -101,7 +101,7 @@ func PrintOutline(dt []byte, w io.Writer) error {
|
|||||||
fmt.Fprintf(tw, "DESCRIPTION:\t%s\n", o.Description)
|
fmt.Fprintf(tw, "DESCRIPTION:\t%s\n", o.Description)
|
||||||
}
|
}
|
||||||
tw.Flush()
|
tw.Flush()
|
||||||
fmt.Println()
|
fmt.Fprintln(tw)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(o.Args) > 0 {
|
if len(o.Args) > 0 {
|
||||||
@@ -111,7 +111,7 @@ func PrintOutline(dt []byte, w io.Writer) error {
|
|||||||
fmt.Fprintf(tw, "%s\t%s\t%s\n", a.Name, a.Value, a.Description)
|
fmt.Fprintf(tw, "%s\t%s\t%s\n", a.Name, a.Value, a.Description)
|
||||||
}
|
}
|
||||||
tw.Flush()
|
tw.Flush()
|
||||||
fmt.Println()
|
fmt.Fprintln(tw)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(o.Secrets) > 0 {
|
if len(o.Secrets) > 0 {
|
||||||
@@ -125,7 +125,7 @@ func PrintOutline(dt []byte, w io.Writer) error {
|
|||||||
fmt.Fprintf(tw, "%s\t%s\n", s.Name, b)
|
fmt.Fprintf(tw, "%s\t%s\n", s.Name, b)
|
||||||
}
|
}
|
||||||
tw.Flush()
|
tw.Flush()
|
||||||
fmt.Println()
|
fmt.Fprintln(tw)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(o.SSH) > 0 {
|
if len(o.SSH) > 0 {
|
||||||
@@ -139,7 +139,7 @@ func PrintOutline(dt []byte, w io.Writer) error {
|
|||||||
fmt.Fprintf(tw, "%s\t%s\n", s.Name, b)
|
fmt.Fprintf(tw, "%s\t%s\n", s.Name, b)
|
||||||
}
|
}
|
||||||
tw.Flush()
|
tw.Flush()
|
||||||
fmt.Println()
|
fmt.Fprintln(tw)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
17
vendor/github.com/moby/buildkit/util/progress/progress.go
generated
vendored
17
vendor/github.com/moby/buildkit/util/progress/progress.go
generated
vendored
@@ -274,3 +274,20 @@ func (pw *noOpWriter) Write(_ string, _ interface{}) error {
|
|||||||
func (pw *noOpWriter) Close() error {
|
func (pw *noOpWriter) Close() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func OneOff(ctx context.Context, id string) func(err error) error {
|
||||||
|
pw, _, _ := NewFromContext(ctx)
|
||||||
|
now := time.Now()
|
||||||
|
st := Status{
|
||||||
|
Started: &now,
|
||||||
|
}
|
||||||
|
pw.Write(id, st)
|
||||||
|
return func(err error) error {
|
||||||
|
// TODO: set error on status
|
||||||
|
now := time.Now()
|
||||||
|
st.Completed = &now
|
||||||
|
pw.Write(id, st)
|
||||||
|
pw.Close()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@@ -358,7 +358,7 @@ github.com/mitchellh/go-wordwrap
|
|||||||
# github.com/mitchellh/mapstructure v1.5.0
|
# github.com/mitchellh/mapstructure v1.5.0
|
||||||
## explicit; go 1.14
|
## explicit; go 1.14
|
||||||
github.com/mitchellh/mapstructure
|
github.com/mitchellh/mapstructure
|
||||||
# github.com/moby/buildkit v0.10.1-0.20220809151411-8488654e899b
|
# github.com/moby/buildkit v0.10.1-0.20220816171719-55ba9d14360a
|
||||||
## explicit; go 1.17
|
## explicit; go 1.17
|
||||||
github.com/moby/buildkit/api/services/control
|
github.com/moby/buildkit/api/services/control
|
||||||
github.com/moby/buildkit/api/types
|
github.com/moby/buildkit/api/types
|
||||||
|
Reference in New Issue
Block a user