Compare commits

...

19 Commits

Author SHA1 Message Date
CrazyMax
687feca9e8 Merge pull request #1877 from jedevc/cache-dockerutil-features
dockerutil: cache feature collection
2023-06-13 11:42:22 +02:00
Justin Chadwell
d4a2c8d0c3 dockerutil: cache feature collection
Signed-off-by: Justin Chadwell <me@jedevc.com>
2023-06-13 09:47:38 +01:00
Justin Chadwell
bef42b2441 Merge pull request #1876 from tonistiigi/remove-history-request 2023-06-13 09:38:05 +01:00
CrazyMax
2de333fdd3 check history api support once
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-06-13 10:29:22 +02:00
Tonis Tiigi
1138789f20 avoid extra client for history API detection
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2023-06-12 17:39:09 -07:00
Justin Chadwell
1f4ac09ffb Merge pull request #1874 from thaJeztah/bump_engine_24.0.2 2023-06-09 11:39:13 +01:00
CrazyMax
26a8ffb393 Merge pull request #1873 from jedevc/vendor-buildkit-master
vendor: update buildkit to master@67a08623b95a
2023-06-09 12:14:11 +02:00
CrazyMax
9b7aada99b Merge pull request #1716 from distorhead/use-docker-cli-in-stream
build(cli): allow passing in-stream using command.Cli
2023-06-09 12:11:47 +02:00
Sebastiaan van Stijn
fd6207695b vendor: github.com/docker/cli v24.0.2
no changes in vendored files

full diff: https://github.com/docker/cli/compare/v24.0.1...v24.0.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-09 12:07:44 +02:00
Sebastiaan van Stijn
def96d2bf4 vendor: github.com/docker/docker v24.0.2
no changes in vendored files

full diff: https://github.com/docker/docker/compare/v24.0.1...v24.0.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-09 12:07:01 +02:00
Justin Chadwell
f5f00e68ef bake(cli): allow passing in-stream using command.Cli
ReadLocalFiles should allow passing the stdin file as an argument, which
allows us to read from dockerCli.Stdin() to be consistent with other
commands in the same package.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2023-06-09 10:50:53 +01:00
Justin Chadwell
14aebe713e debug-shell(cli): allow passing in-stream using command.Cli
Signed-off-by: Justin Chadwell <me@jedevc.com>
2023-06-09 10:50:35 +01:00
Justin Chadwell
9d2388e6f5 vendor: update buildkit to master@67a08623b95a
Signed-off-by: Justin Chadwell <me@jedevc.com>
2023-06-09 10:36:52 +01:00
Timofey Kirillov
75e2c46295 build(cli): allow passing in-stream using command.Cli
Use command.Cli::In() which is always initialized either to os.Stdin, or to user-specified stream:
* 5be21394cb/cli/command/cli.go (L494)
* https://github.com/docker/cli/blob/master/cli/command/cli_options.go#L16C1-L26

Signed-off-by: Timofey Kirillov <timofey.kirillov@flant.com>
2023-06-09 12:19:02 +03:00
Justin Chadwell
2c02db8db4 Merge pull request #1835 from ktock/long-form-json 2023-06-08 17:10:37 +01:00
Kohei Tokunaga
e304a05d2a docs: monitor: mention about long form flag
Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
2023-06-08 17:05:03 +01:00
Kohei Tokunaga
14c1ea0e11 invoke: Allow JSON array for long form flags
This commit allows specifying a JSON array to the long-form arg, entrypoint and
envvars.
Non-JSON-array value can still be specified. Buildx treats the value as a JSON
array only when it can be parsed as a JSON array.

Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
2023-06-08 17:05:02 +01:00
Justin Chadwell
c30bcade2c Merge pull request #1870 from tianon/invoke-entrypoint-fixes 2023-06-08 16:03:24 +01:00
Tianon Gravi
62bfb19db4 Fix a couple --invoke entrypoint interaction bugs
When running `--invoke` against images that have `Cmd` set, the interactions with `Entrypoint` start to cause issues like the following:

    /usr/local/bin/bash: /usr/local/bin/bash: cannot execute binary file

Or:

    sh: can't open 'bash': No such file or directory

This patch fixes those by explicitly setting `Cmd` to be empty if it is unspecified and `Entrypoint` is being set, which matches `docker`'s behavior:

    $ docker image inspect --format '{{ json .Config.Entrypoint }} + {{ json .Config.Cmd }}' bash
    ["docker-entrypoint.sh"] + ["bash"]
    $ docker create --name foo --entrypoint bash bash
    $ docker container inspect --format '{{ json .Config.Entrypoint }} + {{ json .Config.Cmd }}' foo
    ["bash"] + null
    $ docker rm foo
    $ docker create --name foo bash ls
    $ docker container inspect --format '{{ json .Config.Entrypoint }} + {{ json .Config.Cmd }}' foo
    ["docker-entrypoint.sh"] + ["ls"]

(There are still some weird edge cases in the interaction between the `InvokeConfig` and the original image config, but this fixes the most irritating for me and the rest are going to be deeper changes that are possibly less acceptable. 😅)

Signed-off-by: Tianon Gravi <admwiggin@gmail.com>
2023-06-07 16:33:28 -07:00
32 changed files with 410 additions and 129 deletions

View File

@@ -55,7 +55,7 @@ func defaultFilenames() []string {
return names
}
func ReadLocalFiles(names []string) ([]File, error) {
func ReadLocalFiles(names []string, stdin io.Reader) ([]File, error) {
isDefault := false
if len(names) == 0 {
isDefault = true
@@ -67,7 +67,7 @@ func ReadLocalFiles(names []string) ([]File, error) {
var dt []byte
var err error
if n == "-" {
dt, err = io.ReadAll(os.Stdin)
dt, err = io.ReadAll(stdin)
if err != nil {
return nil, err
}

View File

@@ -1398,7 +1398,7 @@ func TestReadLocalFilesDefault(t *testing.T) {
for _, tf := range tt.filenames {
require.NoError(t, os.WriteFile(tf, []byte(tf), 0644))
}
files, err := ReadLocalFiles(nil)
files, err := ReadLocalFiles(nil, nil)
require.NoError(t, err)
if len(files) == 0 {
require.Equal(t, len(tt.expected), len(files))

View File

@@ -948,7 +948,7 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
} else {
rr, err = c.Build(ctx, so, "buildx", buildFunc, ch)
}
if node.Driver.Features(ctx)[driver.HistoryAPI] && desktop.BuildBackendEnabled() {
if desktop.BuildBackendEnabled() && node.Driver.HistoryAPISupported(ctx) {
buildRef := fmt.Sprintf("%s/%s/%s", node.Builder, node.Name, so.Ref)
if err != nil {
return &desktop.ErrorWithBuildRef{
@@ -1262,7 +1262,7 @@ func createTempDockerfile(r io.Reader) (string, error) {
return dir, err
}
func LoadInputs(ctx context.Context, d driver.Driver, inp Inputs, pw progress.Writer, target *client.SolveOpt) (func(), error) {
func LoadInputs(ctx context.Context, d *driver.DriverHandle, inp Inputs, pw progress.Writer, target *client.SolveOpt) (func(), error) {
if inp.ContextPath == "" {
return nil, errors.New("please specify build context (e.g. \".\" for the current directory)")
}

View File

@@ -13,7 +13,7 @@ import (
"github.com/pkg/errors"
)
func createTempDockerfileFromURL(ctx context.Context, d driver.Driver, url string, pw progress.Writer) (string, error) {
func createTempDockerfileFromURL(ctx context.Context, d *driver.DriverHandle, url string, pw progress.Writer) (string, error) {
c, err := driver.Boot(ctx, ctx, d, pw)
if err != nil {
return "", err

View File

@@ -22,7 +22,7 @@ import (
type Node struct {
store.Node
Builder string
Driver driver.Driver
Driver *driver.DriverHandle
DriverInfo *driver.Info
Platforms []ocispecs.Platform
GCPolicy []client.PruneInfo

View File

@@ -146,7 +146,7 @@ func runBake(dockerCli command.Cli, targets []string, in bakeOptions, cFlags com
if url != "" {
files, inp, err = bake.ReadRemoteFiles(ctx, nodes, url, in.files, printer)
} else {
files, err = bake.ReadLocalFiles(in.files)
files, err = bake.ReadLocalFiles(in.files, dockerCli.In())
}
if err != nil {
return err

View File

@@ -312,7 +312,7 @@ func getImageID(resp map[string]string) string {
}
func runBasicBuild(ctx context.Context, dockerCli command.Cli, opts *controllerapi.BuildOptions, options buildOptions, printer *progress.Printer) (*client.SolveResponse, error) {
resp, res, err := cbuild.RunBuild(ctx, dockerCli, *opts, os.Stdin, printer, false)
resp, res, err := cbuild.RunBuild(ctx, dockerCli, *opts, dockerCli.In(), printer, false)
if res != nil {
res.Done()
}
@@ -346,7 +346,7 @@ func runControllerBuild(ctx context.Context, dockerCli command.Cli, opts *contro
var retErr error
var resp *client.SolveResponse
f := ioset.NewSingleForwarder()
f.SetReader(os.Stdin)
f.SetReader(dockerCli.In())
if !options.noBuild {
pr, pw := io.Pipe()
f.SetWriter(pw, func() io.WriteCloser {
@@ -704,6 +704,7 @@ func parseInvokeConfig(invoke string) (cfg invokeConfig, err error) {
}
csvReader := csv.NewReader(strings.NewReader(invoke))
csvReader.LazyQuotes = true
fields, err := csvReader.Read()
if err != nil {
return cfg, err
@@ -723,11 +724,14 @@ func parseInvokeConfig(invoke string) (cfg invokeConfig, err error) {
value := parts[1]
switch key {
case "args":
cfg.Cmd = append(cfg.Cmd, value) // TODO: support JSON
cfg.Cmd = append(cfg.Cmd, maybeJSONArray(value)...)
case "entrypoint":
cfg.Entrypoint = append(cfg.Entrypoint, value) // TODO: support JSON
cfg.Entrypoint = append(cfg.Entrypoint, maybeJSONArray(value)...)
if cfg.Cmd == nil {
cfg.Cmd = []string{}
}
case "env":
cfg.Env = append(cfg.Env, value)
cfg.Env = append(cfg.Env, maybeJSONArray(value)...)
case "user":
cfg.User = value
cfg.NoUser = false
@@ -746,6 +750,14 @@ func parseInvokeConfig(invoke string) (cfg invokeConfig, err error) {
return cfg, nil
}
func maybeJSONArray(v string) []string {
var list []string
if err := json.Unmarshal([]byte(v), &list); err == nil {
return list
}
return []string{v}
}
func listToMap(values []string, defaultEnv bool) map[string]string {
result := make(map[string]string, len(values))
for _, value := range values {

View File

@@ -47,7 +47,7 @@ func debugShellCmd(dockerCli command.Cli) *cobra.Command {
err = monitor.RunMonitor(ctx, "", nil, controllerapi.InvokeConfig{
Tty: true,
}, c, os.Stdin, os.Stdout, os.Stderr, printer)
}, c, dockerCli.In(), os.Stdout, os.Stderr, printer)
con.Reset()
return err
},

View File

@@ -49,6 +49,16 @@ bin etc lib mnt proc run srv tmp var
dev home media opt root sbin sys usr work
```
Optional long form allows you specifying detailed configurations of the process.
It must be CSV-styled comma-separated key-value pairs.
Supported keys are `args` (can be JSON array format), `entrypoint` (can be JSON array format), `env` (can be JSON array format), `user`, `cwd` and `tty` (bool).
Example:
```
$ docker buildx build --invoke 'entrypoint=["sh"],"args=[""-c"", ""env | grep -e FOO -e AAA""]","env=[""FOO=bar"", ""AAA=bbb""]"' .
```
#### `on-error`
If you want to start a debug session when a build fails, you can use
@@ -151,4 +161,4 @@ Attached to process "3ug8iqaufiwwnukimhqqt06jz". Press Ctrl-a-c to switch to the
bin etc lib mnt proc run srv tmp var
dev home media opt root sbin sys usr work
/ #
```
```

View File

@@ -388,18 +388,11 @@ func (d *Driver) Factory() driver.Factory {
}
func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool {
var historyAPI bool
c, err := d.Client(ctx)
if err == nil {
historyAPI = driver.HistoryAPISupported(ctx, c)
c.Close()
}
return map[driver.Feature]bool{
driver.OCIExporter: true,
driver.DockerExporter: true,
driver.CacheExport: true,
driver.MultiPlatform: true,
driver.HistoryAPI: historyAPI,
}
}

View File

@@ -60,7 +60,6 @@ func (d *Driver) Client(ctx context.Context) (*client.Client, error) {
func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool {
var useContainerdSnapshotter bool
var historyAPI bool
c, err := d.Client(ctx)
if err == nil {
workers, _ := c.ListWorkers(ctx)
@@ -69,7 +68,6 @@ func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool {
useContainerdSnapshotter = true
}
}
historyAPI = driver.HistoryAPISupported(ctx, c)
c.Close()
}
return map[driver.Feature]bool{
@@ -77,7 +75,6 @@ func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool {
driver.DockerExporter: useContainerdSnapshotter,
driver.CacheExport: useContainerdSnapshotter,
driver.MultiPlatform: useContainerdSnapshotter,
driver.HistoryAPI: historyAPI,
}
}

View File

@@ -64,7 +64,7 @@ type Driver interface {
Config() InitConfig
}
func Boot(ctx, clientContext context.Context, d Driver, pw progress.Writer) (*client.Client, error) {
func Boot(ctx, clientContext context.Context, d *DriverHandle, pw progress.Writer) (*client.Client, error) {
try := 0
for {
info, err := d.Info(ctx)
@@ -92,7 +92,7 @@ func Boot(ctx, clientContext context.Context, d Driver, pw progress.Writer) (*cl
}
}
func HistoryAPISupported(ctx context.Context, c *client.Client) bool {
func historyAPISupported(ctx context.Context, c *client.Client) bool {
cl, err := c.ControlClient().ListenBuildHistory(ctx, &controlapi.BuildHistoryRequest{
ActiveOnly: true,
Ref: "buildx-test-history-api-feature", // dummy ref to check if the server supports the API

View File

@@ -7,5 +7,3 @@ const DockerExporter Feature = "Docker exporter"
const CacheExport Feature = "Cache export"
const MultiPlatform Feature = "Multiple platforms"
const HistoryAPI Feature = "History API"

View File

@@ -229,17 +229,10 @@ func (d *Driver) Factory() driver.Factory {
}
func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool {
var historyAPI bool
c, err := d.Client(ctx)
if err == nil {
historyAPI = driver.HistoryAPISupported(ctx, c)
c.Close()
}
return map[driver.Feature]bool{
driver.OCIExporter: true,
driver.DockerExporter: d.DockerAPI != nil,
driver.CacheExport: true,
driver.MultiPlatform: true, // Untested (needs multiple Driver instances)
driver.HistoryAPI: historyAPI,
}
}

View File

@@ -104,7 +104,7 @@ func GetFactory(name string, instanceRequired bool) (Factory, error) {
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) (*DriverHandle, error) {
ic := InitConfig{
EndpointAddr: endpointAddr,
DockerAPI: api,
@@ -128,7 +128,7 @@ func GetDriver(ctx context.Context, name string, f Factory, endpointAddr string,
if err != nil {
return nil, err
}
return &cachedDriver{Driver: d}, nil
return &DriverHandle{Driver: d}, nil
}
func GetFactories(instanceRequired bool) []Factory {
@@ -145,25 +145,36 @@ func GetFactories(instanceRequired bool) []Factory {
return ds
}
type cachedDriver struct {
type DriverHandle struct {
Driver
client *client.Client
err error
once sync.Once
featuresOnce sync.Once
features map[Feature]bool
client *client.Client
err error
once sync.Once
featuresOnce sync.Once
features map[Feature]bool
historyAPISupportedOnce sync.Once
historyAPISupported bool
}
func (d *cachedDriver) Client(ctx context.Context) (*client.Client, error) {
func (d *DriverHandle) Client(ctx context.Context) (*client.Client, error) {
d.once.Do(func() {
d.client, d.err = d.Driver.Client(ctx)
})
return d.client, d.err
}
func (d *cachedDriver) Features(ctx context.Context) map[Feature]bool {
func (d *DriverHandle) Features(ctx context.Context) map[Feature]bool {
d.featuresOnce.Do(func() {
d.features = d.Driver.Features(ctx)
})
return d.features
}
func (d *DriverHandle) HistoryAPISupported(ctx context.Context) bool {
d.historyAPISupportedOnce.Do(func() {
if c, err := d.Client(ctx); err == nil {
d.historyAPISupported = historyAPISupported(ctx, c)
}
})
return d.historyAPISupported
}

View File

@@ -88,18 +88,11 @@ func (d *Driver) Client(ctx context.Context) (*client.Client, error) {
}
func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool {
var historyAPI bool
c, err := d.Client(ctx)
if err == nil {
historyAPI = driver.HistoryAPISupported(ctx, c)
c.Close()
}
return map[driver.Feature]bool{
driver.OCIExporter: true,
driver.DockerExporter: true,
driver.CacheExport: true,
driver.MultiPlatform: true,
driver.HistoryAPI: historyAPI,
}
}

8
go.mod
View File

@@ -7,13 +7,13 @@ require (
github.com/aws/aws-sdk-go-v2/config v1.18.16
github.com/compose-spec/compose-go v1.14.0
github.com/containerd/console v1.0.3
github.com/containerd/containerd v1.7.1
github.com/containerd/containerd v1.7.2
github.com/containerd/continuity v0.4.1
github.com/containerd/typeurl/v2 v2.1.1
github.com/docker/cli v24.0.1+incompatible
github.com/docker/cli v24.0.2+incompatible
github.com/docker/cli-docs-tool v0.5.1
github.com/docker/distribution v2.8.2+incompatible
github.com/docker/docker v24.0.1+incompatible
github.com/docker/docker v24.0.2+incompatible
github.com/docker/go-units v0.5.0
github.com/gofrs/flock v0.8.1
github.com/gogo/protobuf v1.3.2
@@ -22,7 +22,7 @@ require (
github.com/google/uuid v1.3.0
github.com/hashicorp/go-cty-funcs v0.0.0-20200930094925-2721b1e36840
github.com/hashicorp/hcl/v2 v2.8.2
github.com/moby/buildkit v0.11.0-rc3.0.20230530080511-c36941f4a10e
github.com/moby/buildkit v0.11.0-rc3.0.20230609092854-67a08623b95a
github.com/moby/sys/mountinfo v0.6.2
github.com/moby/sys/signal v0.7.0
github.com/morikuni/aec v1.0.0

19
go.sum
View File

@@ -127,8 +127,8 @@ github.com/compose-spec/compose-go v1.14.0/go.mod h1:m0o4G6MQDHjjz9rY7No9FpnNi+9
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
github.com/containerd/containerd v1.7.1 h1:k8DbDkSOwt5rgxQ3uCI4WMKIJxIndSCBUaGm5oRn+Go=
github.com/containerd/containerd v1.7.1/go.mod h1:gA+nJUADRBm98QS5j5RPROnt0POQSMK+r7P7EGMC/Qc=
github.com/containerd/containerd v1.7.2 h1:UF2gdONnxO8I6byZXDi5sXWiWvlW3D/sci7dTQimEJo=
github.com/containerd/containerd v1.7.2/go.mod h1:afcz74+K10M/+cjGHIVQrCt3RAQhUSCAjJ9iMYhhkuI=
github.com/containerd/continuity v0.4.1 h1:wQnVrjIyQ8vhU2sgOiL5T07jo+ouqc2bnKsv5/EqGhU=
github.com/containerd/continuity v0.4.1/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ=
github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY=
@@ -149,14 +149,14 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/distribution/distribution/v3 v3.0.0-20230214150026-36d8c594d7aa h1:L9Ay/slwQ4ERSPaurC+TVkZrM0K98GNrEEo1En3e8as=
github.com/distribution/distribution/v3 v3.0.0-20230214150026-36d8c594d7aa/go.mod h1:WHNsWjnIn2V1LYOrME7e8KxSeKunYHsxEm4am0BUtcI=
github.com/docker/cli v24.0.1+incompatible h1:uVl5Xv/39kZJpDo9VaktTOYBc702sdYYF33FqwUG/dM=
github.com/docker/cli v24.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli v24.0.2+incompatible h1:QdqR7znue1mtkXIJ+ruQMGQhpw2JzMJLRXp6zpzF6tM=
github.com/docker/cli v24.0.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli-docs-tool v0.5.1 h1:jIk/cCZurZERhALPVKhqlNxTQGxn2kcI+56gE57PQXg=
github.com/docker/cli-docs-tool v0.5.1/go.mod h1:zMjqTFCU361PRh8apiXzeAZ1Q/xupbIwTusYpzCXS/o=
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v24.0.1+incompatible h1:NxN81beIxDlUaVt46iUQrYHD9/W3u9EGl52r86O/IGw=
github.com/docker/docker v24.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v24.0.2+incompatible h1:eATx+oLz9WdNVkQrr0qjQ8HvRJ4bOOxfzEo8R+dA3cg=
github.com/docker/docker v24.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
@@ -371,8 +371,8 @@ github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzC
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
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/moby/buildkit v0.11.0-rc3.0.20230530080511-c36941f4a10e h1:d5nOEUewXcVebVTyUVeQHXX8+Ofb/+TSlqZSn9xIg3k=
github.com/moby/buildkit v0.11.0-rc3.0.20230530080511-c36941f4a10e/go.mod h1:nWISTd0U2LNfp6z0W5T0NO73xO5rrdRiTTQkSF6uIjc=
github.com/moby/buildkit v0.11.0-rc3.0.20230609092854-67a08623b95a h1:1k3bAXwxC2N1FncWijq/43sLj2OVIZ11FT0APIXWhMg=
github.com/moby/buildkit v0.11.0-rc3.0.20230609092854-67a08623b95a/go.mod h1:4sM7BBBqXOQ+vV6LrVAOAMhZI9cVNYV5RhZCl906a64=
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/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo=
@@ -411,7 +411,6 @@ github.com/opencontainers/runc v1.1.7/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh
github.com/opencontainers/runtime-spec v1.1.0-rc.2 h1:ucBtEms2tamYYW/SvGpvq9yUN0NEVL6oyLEwDcTSrk8=
github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/package-url/packageurl-go v0.1.1-0.20220428063043-89078438f170 h1:DiLBVp4DAcZlBVBEtJpNWZpZVq0AEeCY7Hqk8URVs4o=
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg=
@@ -460,7 +459,7 @@ github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spdx/tools-golang v0.5.0 h1:/fqihV2Jna7fmow65dHpgKNsilgLK7ICpd2tkCnPEyY=
github.com/spdx/tools-golang v0.5.1 h1:fJg3SVOGG+eIva9ZUBm/hvyA7PIPVFjRxUKe6fdAgwE=
github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw=
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=

View File

@@ -282,6 +282,7 @@ func (m *monitor) startInvoke(ctx context.Context, pid string, cfg controllerapi
}
if len(cfg.Entrypoint) == 0 && len(cfg.Cmd) == 0 {
cfg.Entrypoint = []string{"sh"} // launch shell by default
cfg.Cmd = []string{}
}
go func() {
// Start a new invoke

View File

@@ -19,7 +19,7 @@ func Disable(cmd *cobra.Command, args []string, toComplete string) ([]string, co
func BakeTargets(files []string) ValidArgsFn {
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
f, err := bake.ReadLocalFiles(files)
f, err := bake.ReadLocalFiles(files, nil)
if err != nil {
return nil, cobra.ShellCompDirectiveError
}

View File

@@ -13,6 +13,9 @@ import (
// Client represents an active docker object.
type Client struct {
cli command.Cli
featuresOnce sync.Once
featuresCache map[Feature]bool
}
// NewClient initializes a new docker client.
@@ -64,6 +67,13 @@ func (c *Client) LoadImage(ctx context.Context, name string, status progress.Wri
}
func (c *Client) Features(ctx context.Context, name string) map[Feature]bool {
c.featuresOnce.Do(func() {
c.featuresCache = c.features(ctx, name)
})
return c.featuresCache
}
func (c *Client) features(ctx context.Context, name string) map[Feature]bool {
features := make(map[Feature]bool)
if dapi, err := c.API(name); err == nil {
if info, err := dapi.Info(ctx); err == nil {

View File

@@ -98,25 +98,30 @@ type ResolverOptions struct {
Tracker StatusTracker
// Authorizer is used to authorize registry requests
// Deprecated: use Hosts
//
// Deprecated: use Hosts.
Authorizer Authorizer
// Credentials provides username and secret given a host.
// If username is empty but a secret is given, that secret
// is interpreted as a long lived token.
// Deprecated: use Hosts
//
// Deprecated: use Hosts.
Credentials func(string) (string, string, error)
// Host provides the hostname given a namespace.
// Deprecated: use Hosts
//
// Deprecated: use Hosts.
Host func(string) (string, error)
// PlainHTTP specifies to use plain http and not https
// Deprecated: use Hosts
//
// Deprecated: use Hosts.
PlainHTTP bool
// Client is the http client to used when making registry requests
// Deprecated: use Hosts
//
// Deprecated: use Hosts.
Client *http.Client
}

View File

@@ -23,7 +23,7 @@ var (
Package = "github.com/containerd/containerd"
// Version holds the complete version number. Filled in at linking time.
Version = "1.7.1+unknown"
Version = "1.7.2+unknown"
// Revision is filled with the VCS (e.g. git) revision being used to build
// the program at linking time.

View File

@@ -0,0 +1,75 @@
package exptypes
import commonexptypes "github.com/moby/buildkit/exporter/exptypes"
type ImageExporterOptKey string
// Options keys supported by the image exporter output.
var (
// Name of the image.
// Value: string
OptKeyName ImageExporterOptKey = "name"
// Push after creating image.
// Value: bool <true|false>
OptKeyPush ImageExporterOptKey = "push"
// Push unnamed image.
// Value: bool <true|false>
OptKeyPushByDigest ImageExporterOptKey = "push-by-digest"
// Allow pushing to insecure HTTP registry.
// Value: bool <true|false>
OptKeyInsecure ImageExporterOptKey = "registry.insecure"
// Unpack image after it's created (containerd).
// Value: bool <true|false>
OptKeyUnpack ImageExporterOptKey = "unpack"
// Fallback image name prefix if image name isn't provided.
// If used, image will be named as <value>@<digest>
// Value: string
OptKeyDanglingPrefix ImageExporterOptKey = "dangling-name-prefix"
// Creates additional image name with format <name>@<digest>
// Value: bool <true|false>
OptKeyNameCanonical ImageExporterOptKey = "name-canonical"
// Store the resulting image along with all of the content it references.
// Ignored if the worker doesn't have image store (e.g. OCI worker).
// Value: bool <true|false>
OptKeyStore ImageExporterOptKey = "store"
// Use OCI mediatypes instead of Docker in JSON configs.
// Value: bool <true|false>
OptKeyOCITypes ImageExporterOptKey = "oci-mediatypes"
// Force attestation to be attached.
// Value: bool <true|false>
OptKeyForceInlineAttestations ImageExporterOptKey = "attestation-inline"
// Mark layers as non-distributable if they are found to use a
// non-distributable media type. When this option is not set, the exporter
// will change the media type of the layer to a distributable one.
// Value: bool <true|false>
OptKeyPreferNondistLayers ImageExporterOptKey = "prefer-nondist-layers"
// Clamp produced timestamps. For more information see the
// SOURCE_DATE_EPOCH specification.
// Value: int (number of seconds since Unix epoch)
OptKeySourceDateEpoch ImageExporterOptKey = ImageExporterOptKey(commonexptypes.OptKeySourceDateEpoch)
// Compression type for newly created and cached layers.
// estargz should be used with OptKeyOCITypes set to true.
// Value: string <uncompressed|gzip|estargz|zstd>
OptKeyLayerCompression ImageExporterOptKey = "compression"
// Force compression on all (including existing) layers.
// Value: bool <true|false>
OptKeyForceCompression ImageExporterOptKey = "force-compression"
// Compression level
// Value: int (0-9) for gzip and estargz
// Value: int (0-22) for zstd
OptKeyCompressionLevel ImageExporterOptKey = "compression-level"
)

View File

@@ -12,7 +12,6 @@ const (
ExporterImageDescriptorKey = "containerimage.descriptor"
ExporterInlineCache = "containerimage.inlinecache"
ExporterPlatformsKey = "refs.platforms"
ExporterEpochKey = "source.date.epoch"
)
// KnownRefMetadataKeys are the subset of exporter keys that can be suffixed by

View File

@@ -0,0 +1,15 @@
package exptypes
const (
ExporterEpochKey = "source.date.epoch"
)
type ExporterOptKey string
// Options keys supported by all exporters.
var (
// Clamp produced timestamps. For more information see the
// SOURCE_DATE_EPOCH specification.
// Value: int (number of seconds since Unix epoch)
OptKeySourceDateEpoch ExporterOptKey = "source-date-epoch"
)

View File

@@ -29,6 +29,8 @@ import (
)
const defaultExpiration = 60
const dockerHubConfigfileKey = "https://index.docker.io/v1/"
const dockerHubRegistryHost = "registry-1.docker.io"
func NewDockerAuthProvider(cfg *configfile.ConfigFile) session.Attachable {
return &authProvider{
@@ -183,10 +185,12 @@ func (ap *authProvider) VerifyTokenAuthority(ctx context.Context, req *auth.Veri
func (ap *authProvider) getAuthConfig(host string) (*types.AuthConfig, error) {
ap.mu.Lock()
defer ap.mu.Unlock()
if host == dockerHubRegistryHost {
host = dockerHubConfigfileKey
}
if _, exists := ap.authConfigCache[host]; !exists {
if host == "registry-1.docker.io" {
host = "https://index.docker.io/v1/"
}
ac, err := ap.config.GetAuthConfig(host)
if err != nil {
return nil, err

View File

@@ -143,10 +143,13 @@ func (p *textMux) printVtx(t *trace, dgst digest.Digest) {
}
for i, l := range v.logs {
if i == 0 {
if i == 0 && v.logsOffset != 0 { // index has already been printed
l = l[v.logsOffset:]
fmt.Fprintf(p.w, "%s", l)
} else {
fmt.Fprintf(p.w, "#%d %s", v.index, []byte(l))
}
fmt.Fprintf(p.w, "#%d %s", v.index, []byte(l))
if i != len(v.logs)-1 || !v.logsPartial {
fmt.Fprintln(p.w, "")
}

View File

@@ -1,5 +1,13 @@
package system
import (
"path"
"path/filepath"
"strings"
"github.com/pkg/errors"
)
// DefaultPathEnvUnix is unix style list of directories to search for
// executables. Each directory is separated from the next by a colon
// ':' character .
@@ -16,3 +24,202 @@ func DefaultPathEnv(os string) string {
}
return DefaultPathEnvUnix
}
// NormalizePath cleans the path based on the operating system the path is meant for.
// It takes into account a potential parent path, and will join the path to the parent
// if the path is relative. Additionally, it will apply the folliwing rules:
// - always return an absolute path
// - always strip drive letters for Windows paths
// - optionally keep the trailing slashes on paths
// - paths are returned using forward slashes
func NormalizePath(parent, newPath, inputOS string, keepSlash bool) (string, error) {
if inputOS == "" {
inputOS = "linux"
}
newPath = toSlash(newPath, inputOS)
parent = toSlash(parent, inputOS)
origPath := newPath
if parent == "" {
parent = "/"
}
var err error
parent, err = CheckSystemDriveAndRemoveDriveLetter(parent, inputOS)
if err != nil {
return "", errors.Wrap(err, "removing drive letter")
}
if !IsAbs(parent, inputOS) {
parent = path.Join("/", parent)
}
if newPath == "" {
// New workdir is empty. Use the "current" workdir. It should already
// be an absolute path.
newPath = parent
}
newPath, err = CheckSystemDriveAndRemoveDriveLetter(newPath, inputOS)
if err != nil {
return "", errors.Wrap(err, "removing drive letter")
}
if !IsAbs(newPath, inputOS) {
// The new WD is relative. Join it to the previous WD.
newPath = path.Join(parent, newPath)
}
if keepSlash {
if strings.HasSuffix(origPath, "/") && !strings.HasSuffix(newPath, "/") {
newPath += "/"
} else if strings.HasSuffix(origPath, "/.") {
if newPath != "/" {
newPath += "/"
}
newPath += "."
}
}
return toSlash(newPath, inputOS), nil
}
func toSlash(inputPath, inputOS string) string {
separator := "/"
if inputOS == "windows" {
separator = "\\"
}
return strings.Replace(inputPath, separator, "/", -1)
}
func fromSlash(inputPath, inputOS string) string {
separator := "/"
if inputOS == "windows" {
separator = "\\"
}
return strings.Replace(inputPath, "/", separator, -1)
}
// NormalizeWorkdir will return a normalized version of the new workdir, given
// the currently configured workdir and the desired new workdir. When setting a
// new relative workdir, it will be joined to the previous workdir or default to
// the root folder.
// On Windows we remove the drive letter and convert the path delimiter to "\".
// Paths that begin with os.PathSeparator are considered absolute even on Windows.
func NormalizeWorkdir(current, wd string, inputOS string) (string, error) {
if inputOS == "" {
inputOS = "linux"
}
wd, err := NormalizePath(current, wd, inputOS, false)
if err != nil {
return "", errors.Wrap(err, "normalizing working directory")
}
// Make sure we use the platform specific path separator. HCS does not like forward
// slashes in CWD.
return fromSlash(wd, inputOS), nil
}
// IsAbs returns a boolean value indicating whether or not the path
// is absolute. On Linux, this is just a wrapper for filepath.IsAbs().
// On Windows, we strip away the drive letter (if any), clean the path,
// and check whether or not the path starts with a filepath.Separator.
// This function is meant to check if a path is absolute, in the context
// of a COPY, ADD or WORKDIR, which have their root set in the mount point
// of the writable layer we are mutating. The filepath.IsAbs() function on
// Windows will not work in these scenatios, as it will return true for paths
// that:
// - Begin with drive letter (DOS style paths)
// - Are volume paths \\?\Volume{UUID}
// - Are UNC paths
func IsAbs(pth, inputOS string) bool {
if inputOS == "" {
inputOS = "linux"
}
cleanedPath, err := CheckSystemDriveAndRemoveDriveLetter(pth, inputOS)
if err != nil {
return false
}
cleanedPath = toSlash(cleanedPath, inputOS)
// We stripped any potential drive letter and converted any backslashes to
// forward slashes. We can safely use path.IsAbs() for both Windows and Linux.
return path.IsAbs(cleanedPath)
}
// CheckSystemDriveAndRemoveDriveLetter verifies and manipulates a Windows path.
// For linux, this is a no-op.
//
// This is used, for example, when validating a user provided path in docker cp.
// If a drive letter is supplied, it must be the system drive. The drive letter
// is always removed. It also converts any backslash to forward slash. The conversion
// to OS specific separator should happen as late as possible (ie: before passing the
// value to the function that will actually use it). Paths are parsed and code paths are
// triggered starting with the client and all the way down to calling into the runtime
// environment. The client may run on a foreign OS from the one the build will be triggered
// (Windows clients connecting to Linux or vice versa).
// Keeping the file separator consistent until the last moment is desirable.
//
// We need the Windows path without the drive letter so that it can ultimately be concatenated with
// a Windows long-path which doesn't support drive-letters. Examples:
// C: --> Fail
// C:somepath --> somepath // This is a relative path to the CWD set for that drive letter
// C:\ --> \
// a --> a
// /a --> \a
// d:\ --> Fail
//
// UNC paths can refer to multiple types of paths. From local filesystem paths,
// to remote filesystems like SMB or named pipes.
// There is no sane way to support this without adding a lot of complexity
// which I am not sure is worth it.
// \\.\C$\a --> Fail
func CheckSystemDriveAndRemoveDriveLetter(path string, inputOS string) (string, error) {
if inputOS == "" {
inputOS = "linux"
}
if inputOS != "windows" {
return path, nil
}
if len(path) == 2 && string(path[1]) == ":" {
return "", errors.Errorf("No relative path specified in %q", path)
}
// UNC paths should error out
if len(path) >= 2 && toSlash(path[:2], inputOS) == "//" {
return "", errors.Errorf("UNC paths are not supported")
}
parts := strings.SplitN(path, ":", 2)
// Path does not have a drive letter. Just return it.
if len(parts) < 2 {
return toSlash(filepath.Clean(path), inputOS), nil
}
// We expect all paths to be in C:
if !strings.EqualFold(parts[0], "c") {
return "", errors.New("The specified path is not on the system drive (C:)")
}
// A path of the form F:somepath, is a path that is relative CWD set for a particular
// drive letter. See:
// https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#fully-qualified-vs-relative-paths
//
// C:\>mkdir F:somepath
// C:\>dir F:\
// Volume in drive F is New Volume
// Volume Serial Number is 86E5-AB64
//
// Directory of F:\
//
// 11/27/2022 02:22 PM <DIR> somepath
// 0 File(s) 0 bytes
// 1 Dir(s) 1,052,876,800 bytes free
//
// We must return the second element of the split path, as is, without attempting to convert
// it to an absolute path. We have no knowledge of the CWD; that is treated elsewhere.
return toSlash(filepath.Clean(parts[1]), inputOS), nil
}

View File

@@ -1,10 +0,0 @@
//go:build !windows
// +build !windows
package system
// CheckSystemDriveAndRemoveDriveLetter verifies that a path, if it includes a drive letter,
// is the system drive. This is a no-op on Linux.
func CheckSystemDriveAndRemoveDriveLetter(path string) (string, error) {
return path, nil
}

View File

@@ -1,35 +0,0 @@
//go:build windows
// +build windows
package system
import (
"path/filepath"
"strings"
"github.com/pkg/errors"
)
// CheckSystemDriveAndRemoveDriveLetter verifies and manipulates a Windows path.
// This is used, for example, when validating a user provided path in docker cp.
// If a drive letter is supplied, it must be the system drive. The drive letter
// is always removed. Also, it translates it to OS semantics (IOW / to \). We
// need the path in this syntax so that it can ultimately be contatenated with
// a Windows long-path which doesn't support drive-letters. Examples:
// C: --> Fail
// C:\ --> \
// a --> a
// /a --> \a
// d:\ --> Fail
func CheckSystemDriveAndRemoveDriveLetter(path string) (string, error) {
if len(path) == 2 && string(path[1]) == ":" {
return "", errors.Errorf("No relative path specified in %q", path)
}
if !filepath.IsAbs(path) || len(path) < 2 {
return filepath.FromSlash(path), nil
}
if string(path[1]) == ":" && !strings.EqualFold(string(path[0]), "c") {
return "", errors.New("The specified path is not on the system drive (C:)")
}
return filepath.FromSlash(path[2:]), nil
}

9
vendor/modules.txt vendored
View File

@@ -147,7 +147,7 @@ github.com/compose-spec/compose-go/utils
# github.com/containerd/console v1.0.3
## explicit; go 1.13
github.com/containerd/console
# github.com/containerd/containerd v1.7.1
# github.com/containerd/containerd v1.7.2
## explicit; go 1.19
github.com/containerd/containerd/api/services/content/v1
github.com/containerd/containerd/archive/compression
@@ -206,7 +206,7 @@ github.com/davecgh/go-spew/spew
# github.com/distribution/distribution/v3 v3.0.0-20230214150026-36d8c594d7aa
## explicit; go 1.18
github.com/distribution/distribution/v3/reference
# github.com/docker/cli v24.0.1+incompatible
# github.com/docker/cli v24.0.2+incompatible
## explicit
github.com/docker/cli/cli
github.com/docker/cli/cli-plugins/manager
@@ -254,7 +254,7 @@ github.com/docker/distribution/registry/client/transport
github.com/docker/distribution/registry/storage/cache
github.com/docker/distribution/registry/storage/cache/memory
github.com/docker/distribution/uuid
# github.com/docker/docker v24.0.1+incompatible
# github.com/docker/docker v24.0.2+incompatible
## explicit
github.com/docker/docker/api
github.com/docker/docker/api/types
@@ -498,7 +498,7 @@ github.com/mitchellh/go-wordwrap
# github.com/mitchellh/mapstructure v1.5.0
## explicit; go 1.14
github.com/mitchellh/mapstructure
# github.com/moby/buildkit v0.11.0-rc3.0.20230530080511-c36941f4a10e
# github.com/moby/buildkit v0.11.0-rc3.0.20230609092854-67a08623b95a
## explicit; go 1.20
github.com/moby/buildkit/api/services/control
github.com/moby/buildkit/api/types
@@ -513,6 +513,7 @@ github.com/moby/buildkit/client/ociindex
github.com/moby/buildkit/cmd/buildkitd/config
github.com/moby/buildkit/exporter/containerimage/exptypes
github.com/moby/buildkit/exporter/containerimage/image
github.com/moby/buildkit/exporter/exptypes
github.com/moby/buildkit/frontend/attestations
github.com/moby/buildkit/frontend/dockerfile/dockerignore
github.com/moby/buildkit/frontend/dockerui