Skip to content

Commit aa56ab3

Browse files
authored
Merge pull request #11492 from jhrotko/use-listeners-for-file-metadata
Use listener for file metadata
2 parents 07bda59 + 16c8099 commit aa56ab3

File tree

17 files changed

+54
-37
lines changed

17 files changed

+54
-37
lines changed

cmd/compose/build.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ func buildCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
136136
}
137137

138138
func runBuild(ctx context.Context, dockerCli command.Cli, backend api.Service, opts buildOptions, services []string) error {
139-
project, err := opts.ToProject(ctx, dockerCli, services, cli.WithResolvedPaths(true), cli.WithoutEnvironmentResolution)
139+
project, _, err := opts.ToProject(ctx, dockerCli, services, cli.WithResolvedPaths(true), cli.WithoutEnvironmentResolution)
140140
if err != nil {
141141
return err
142142
}

cmd/compose/completion.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func noCompletion() validArgsFn {
3737
func completeServiceNames(dockerCli command.Cli, p *ProjectOptions) validArgsFn {
3838
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
3939
p.Offline = true
40-
project, err := p.ToProject(cmd.Context(), dockerCli, nil)
40+
project, _, err := p.ToProject(cmd.Context(), dockerCli, nil)
4141
if err != nil {
4242
return nil, cobra.ShellCompDirectiveNoFileComp
4343
}
@@ -72,7 +72,7 @@ func completeProjectNames(backend api.Service) func(cmd *cobra.Command, args []s
7272
func completeProfileNames(dockerCli command.Cli, p *ProjectOptions) validArgsFn {
7373
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
7474
p.Offline = true
75-
project, err := p.ToProject(cmd.Context(), dockerCli, nil)
75+
project, _, err := p.ToProject(cmd.Context(), dockerCli, nil)
7676
if err != nil {
7777
return nil, cobra.ShellCompDirectiveNoFileComp
7878
}

cmd/compose/compose.go

+18-9
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import (
3636
"github.com/docker/cli/cli-plugins/manager"
3737
"github.com/docker/cli/cli/command"
3838
"github.com/docker/compose/v2/cmd/formatter"
39+
"github.com/docker/compose/v2/internal/tracing"
3940
"github.com/docker/compose/v2/pkg/api"
4041
"github.com/docker/compose/v2/pkg/compose"
4142
ui "github.com/docker/compose/v2/pkg/progress"
@@ -141,11 +142,13 @@ func (o *ProjectOptions) WithServices(dockerCli command.Cli, fn ProjectServicesF
141142
cli.WithDiscardEnvFile,
142143
}
143144

144-
project, err := o.ToProject(ctx, dockerCli, args, options...)
145+
project, metrics, err := o.ToProject(ctx, dockerCli, args, options...)
145146
if err != nil {
146147
return err
147148
}
148149

150+
ctx = context.WithValue(ctx, tracing.Metrics{}, metrics)
151+
149152
return fn(ctx, project, args)
150153
})
151154
}
@@ -166,7 +169,7 @@ func (o *ProjectOptions) projectOrName(ctx context.Context, dockerCli command.Cl
166169
name := o.ProjectName
167170
var project *types.Project
168171
if len(o.ConfigPaths) > 0 || o.ProjectName == "" {
169-
p, err := o.ToProject(ctx, dockerCli, services, cli.WithDiscardEnvFile)
172+
p, _, err := o.ToProject(ctx, dockerCli, services, cli.WithDiscardEnvFile)
170173
if err != nil {
171174
envProjectName := os.Getenv(ComposeProjectName)
172175
if envProjectName != "" {
@@ -190,14 +193,15 @@ func (o *ProjectOptions) toProjectName(ctx context.Context, dockerCli command.Cl
190193
return envProjectName, nil
191194
}
192195

193-
project, err := o.ToProject(ctx, dockerCli, nil)
196+
project, _, err := o.ToProject(ctx, dockerCli, nil)
194197
if err != nil {
195198
return "", err
196199
}
197200
return project.Name, nil
198201
}
199202

200-
func (o *ProjectOptions) ToProject(ctx context.Context, dockerCli command.Cli, services []string, po ...cli.ProjectOptionsFn) (*types.Project, error) {
203+
func (o *ProjectOptions) ToProject(ctx context.Context, dockerCli command.Cli, services []string, po ...cli.ProjectOptionsFn) (*types.Project, tracing.Metrics, error) {
204+
var metrics tracing.Metrics
201205
if !o.Offline {
202206
po = append(po, o.remoteLoaders(dockerCli)...)
203207
}
@@ -206,25 +210,30 @@ func (o *ProjectOptions) ToProject(ctx context.Context, dockerCli command.Cli, s
206210

207211
options, err := o.toProjectOptions(po...)
208212
if err != nil {
209-
return nil, compose.WrapComposeError(err)
213+
return nil, metrics, compose.WrapComposeError(err)
210214
}
211215

216+
options.WithListeners(func(event string, metadata map[string]any) {
217+
if event == "extends" {
218+
metrics.CountExtends++
219+
}
220+
})
212221
if o.Compatibility || utils.StringToBool(options.Environment[ComposeCompatibility]) {
213222
api.Separator = "_"
214223
}
215224

216225
project, err := cli.ProjectFromOptions(options)
217226
if err != nil {
218-
return nil, compose.WrapComposeError(err)
227+
return nil, metrics, compose.WrapComposeError(err)
219228
}
220229

221230
if project.Name == "" {
222-
return nil, errors.New("project name can't be empty. Use `--project-name` to set a valid name")
231+
return nil, metrics, errors.New("project name can't be empty. Use `--project-name` to set a valid name")
223232
}
224233

225234
project, err = project.WithServicesEnabled(services...)
226235
if err != nil {
227-
return nil, err
236+
return nil, metrics, err
228237
}
229238

230239
for name, s := range project.Services {
@@ -245,7 +254,7 @@ func (o *ProjectOptions) ToProject(ctx context.Context, dockerCli command.Cli, s
245254
project = project.WithoutUnnecessaryResources()
246255

247256
project, err = project.WithSelectedServices(services)
248-
return project, err
257+
return project, metrics, err
249258
}
250259

251260
func (o *ProjectOptions) remoteLoaders(dockerCli command.Cli) []cli.ProjectOptionsFn {

cmd/compose/config.go

+8-7
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"github.com/docker/cli/cli/command"
3030
"github.com/spf13/cobra"
3131

32+
"github.com/docker/compose/v2/internal/tracing"
3233
"github.com/docker/compose/v2/pkg/api"
3334
"github.com/docker/compose/v2/pkg/compose"
3435
)
@@ -50,7 +51,7 @@ type configOptions struct {
5051
noConsistency bool
5152
}
5253

53-
func (o *configOptions) ToProject(ctx context.Context, dockerCli command.Cli, services []string, po ...cli.ProjectOptionsFn) (*types.Project, error) {
54+
func (o *configOptions) ToProject(ctx context.Context, dockerCli command.Cli, services []string, po ...cli.ProjectOptionsFn) (*types.Project, tracing.Metrics, error) {
5455
po = append(po,
5556
cli.WithInterpolation(!o.noInterpolate),
5657
cli.WithResolvedPaths(!o.noResolvePath),
@@ -124,7 +125,7 @@ func configCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service
124125

125126
func runConfig(ctx context.Context, dockerCli command.Cli, backend api.Service, opts configOptions, services []string) error {
126127
var content []byte
127-
project, err := opts.ToProject(ctx, dockerCli, services)
128+
project, _, err := opts.ToProject(ctx, dockerCli, services)
128129
if err != nil {
129130
return err
130131
}
@@ -154,7 +155,7 @@ func runConfig(ctx context.Context, dockerCli command.Cli, backend api.Service,
154155
}
155156

156157
func runServices(ctx context.Context, dockerCli command.Cli, opts configOptions) error {
157-
project, err := opts.ToProject(ctx, dockerCli, nil, cli.WithoutEnvironmentResolution)
158+
project, _, err := opts.ToProject(ctx, dockerCli, nil, cli.WithoutEnvironmentResolution)
158159
if err != nil {
159160
return err
160161
}
@@ -166,7 +167,7 @@ func runServices(ctx context.Context, dockerCli command.Cli, opts configOptions)
166167
}
167168

168169
func runVolumes(ctx context.Context, dockerCli command.Cli, opts configOptions) error {
169-
project, err := opts.ToProject(ctx, dockerCli, nil, cli.WithoutEnvironmentResolution)
170+
project, _, err := opts.ToProject(ctx, dockerCli, nil, cli.WithoutEnvironmentResolution)
170171
if err != nil {
171172
return err
172173
}
@@ -181,7 +182,7 @@ func runHash(ctx context.Context, dockerCli command.Cli, opts configOptions) err
181182
if opts.hash != "*" {
182183
services = append(services, strings.Split(opts.hash, ",")...)
183184
}
184-
project, err := opts.ToProject(ctx, dockerCli, nil, cli.WithoutEnvironmentResolution)
185+
project, _, err := opts.ToProject(ctx, dockerCli, nil, cli.WithoutEnvironmentResolution)
185186
if err != nil {
186187
return err
187188
}
@@ -217,7 +218,7 @@ func runHash(ctx context.Context, dockerCli command.Cli, opts configOptions) err
217218

218219
func runProfiles(ctx context.Context, dockerCli command.Cli, opts configOptions, services []string) error {
219220
set := map[string]struct{}{}
220-
project, err := opts.ToProject(ctx, dockerCli, services, cli.WithoutEnvironmentResolution)
221+
project, _, err := opts.ToProject(ctx, dockerCli, services, cli.WithoutEnvironmentResolution)
221222
if err != nil {
222223
return err
223224
}
@@ -238,7 +239,7 @@ func runProfiles(ctx context.Context, dockerCli command.Cli, opts configOptions,
238239
}
239240

240241
func runConfigImages(ctx context.Context, dockerCli command.Cli, opts configOptions, services []string) error {
241-
project, err := opts.ToProject(ctx, dockerCli, services, cli.WithoutEnvironmentResolution)
242+
project, _, err := opts.ToProject(ctx, dockerCli, services, cli.WithoutEnvironmentResolution)
242243
if err != nil {
243244
return err
244245
}

cmd/compose/publish.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func publishCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Servic
5050
}
5151

5252
func runPublish(ctx context.Context, dockerCli command.Cli, backend api.Service, opts publishOptions, repository string) error {
53-
project, err := opts.ToProject(ctx, dockerCli, nil)
53+
project, _, err := opts.ToProject(ctx, dockerCli, nil)
5454
if err != nil {
5555
return err
5656
}

cmd/compose/pull.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func (opts pullOptions) apply(project *types.Project, services []string) (*types
9494
}
9595

9696
func runPull(ctx context.Context, dockerCli command.Cli, backend api.Service, opts pullOptions, services []string) error {
97-
project, err := opts.ToProject(ctx, dockerCli, services)
97+
project, _, err := opts.ToProject(ctx, dockerCli, services)
9898
if err != nil {
9999
return err
100100
}

cmd/compose/push.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func pushCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
5454
}
5555

5656
func runPush(ctx context.Context, dockerCli command.Cli, backend api.Service, opts pushOptions, services []string) error {
57-
project, err := opts.ToProject(ctx, dockerCli, services)
57+
project, _, err := opts.ToProject(ctx, dockerCli, services)
5858
if err != nil {
5959
return err
6060
}

cmd/compose/run.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ func runCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *
156156
return nil
157157
}),
158158
RunE: Adapt(func(ctx context.Context, args []string) error {
159-
project, err := p.ToProject(ctx, dockerCli, []string{options.Service}, cgo.WithResolvedPaths(true), cgo.WithDiscardEnvFile)
159+
project, _, err := p.ToProject(ctx, dockerCli, []string{options.Service}, cgo.WithResolvedPaths(true), cgo.WithDiscardEnvFile)
160160
if err != nil {
161161
return err
162162
}

cmd/compose/scale.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func scaleCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
6161

6262
func runScale(ctx context.Context, dockerCli command.Cli, backend api.Service, opts scaleOptions, serviceReplicaTuples map[string]int) error {
6363
services := maps.Keys(serviceReplicaTuples)
64-
project, err := opts.ToProject(ctx, dockerCli, services)
64+
project, _, err := opts.ToProject(ctx, dockerCli, services)
6565
if err != nil {
6666
return err
6767
}

cmd/compose/viz.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func vizCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *
6565

6666
func runViz(ctx context.Context, dockerCli command.Cli, backend api.Service, opts *vizOptions) error {
6767
_, _ = fmt.Fprintln(os.Stderr, "viz command is EXPERIMENTAL")
68-
project, err := opts.ToProject(ctx, dockerCli, nil)
68+
project, _, err := opts.ToProject(ctx, dockerCli, nil)
6969
if err != nil {
7070
return err
7171
}

cmd/compose/watch.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func watchCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
6363
}
6464

6565
func runWatch(ctx context.Context, dockerCli command.Cli, backend api.Service, watchOpts watchOptions, buildOpts buildOptions, services []string) error {
66-
project, err := watchOpts.ToProject(ctx, dockerCli, nil)
66+
project, _, err := watchOpts.ToProject(ctx, dockerCli, nil)
6767
if err != nil {
6868
return err
6969
}

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ require (
66
github.com/AlecAivazis/survey/v2 v2.3.7
77
github.com/Microsoft/go-winio v0.6.1
88
github.com/buger/goterm v1.0.4
9-
github.com/compose-spec/compose-go/v2 v2.0.0-rc.5
9+
github.com/compose-spec/compose-go/v2 v2.0.0-rc.6
1010
github.com/containerd/console v1.0.3
1111
github.com/containerd/containerd v1.7.12
1212
github.com/davecgh/go-spew v1.1.1

go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+g
8686
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
8787
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE=
8888
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4=
89-
github.com/compose-spec/compose-go/v2 v2.0.0-rc.5 h1:YoGsuVzxve1m5SdCfZqI8wJoMVZWu7SelHoqiCqb+iQ=
90-
github.com/compose-spec/compose-go/v2 v2.0.0-rc.5/go.mod h1:bEPizBkIojlQ20pi2vNluBa58tevvj0Y18oUSHPyfdc=
89+
github.com/compose-spec/compose-go/v2 v2.0.0-rc.6 h1:sv9W3U0IEYqgGqTbSDpU2c8cttWQmlbJ0D6jdt//Dv8=
90+
github.com/compose-spec/compose-go/v2 v2.0.0-rc.6/go.mod h1:bEPizBkIojlQ20pi2vNluBa58tevvj0Y18oUSHPyfdc=
9191
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
9292
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
9393
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=

internal/tracing/attributes.go

+11-4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package tracing
1818

1919
import (
20+
"context"
2021
"crypto/sha256"
2122
"encoding/json"
2223
"fmt"
@@ -34,6 +35,9 @@ import (
3435
// SpanOptions is a small helper type to make it easy to share the options helpers between
3536
// downstream functions that accept slices of trace.SpanStartOption and trace.EventOption.
3637
type SpanOptions []trace.SpanStartEventOption
38+
type Metrics struct {
39+
CountExtends int
40+
}
3741

3842
func (s SpanOptions) SpanStartOptions() []trace.SpanStartOption {
3943
out := make([]trace.SpanStartOption, len(s))
@@ -56,31 +60,34 @@ func (s SpanOptions) EventOptions() []trace.EventOption {
5660
// For convenience, it's returned as a SpanOptions object to allow it to be
5761
// passed directly to the wrapping helper methods in this package such as
5862
// SpanWrapFunc.
59-
func ProjectOptions(proj *types.Project) SpanOptions {
63+
func ProjectOptions(ctx context.Context, proj *types.Project) SpanOptions {
6064
if proj == nil {
6165
return nil
6266
}
63-
6467
capabilities, gpu, tpu := proj.ServicesWithCapabilities()
6568
attrs := []attribute.KeyValue{
6669
attribute.String("project.name", proj.Name),
6770
attribute.String("project.dir", proj.WorkingDir),
6871
attribute.StringSlice("project.compose_files", proj.ComposeFiles),
69-
attribute.StringSlice("project.services.active", proj.ServiceNames()),
70-
attribute.StringSlice("project.services.disabled", proj.DisabledServiceNames()),
7172
attribute.StringSlice("project.profiles", proj.Profiles),
7273
attribute.StringSlice("project.volumes", proj.VolumeNames()),
7374
attribute.StringSlice("project.networks", proj.NetworkNames()),
7475
attribute.StringSlice("project.secrets", proj.SecretNames()),
7576
attribute.StringSlice("project.configs", proj.ConfigNames()),
7677
attribute.StringSlice("project.extensions", keys(proj.Extensions)),
7778
attribute.StringSlice("project.includes", flattenIncludeReferences(proj.IncludeReferences)),
79+
attribute.StringSlice("project.services.active", proj.ServiceNames()),
80+
attribute.StringSlice("project.services.disabled", proj.DisabledServiceNames()),
7881
attribute.StringSlice("project.services.build", proj.ServicesWithBuild()),
7982
attribute.StringSlice("project.services.depends_on", proj.ServicesWithDependsOn()),
8083
attribute.StringSlice("project.services.capabilities", capabilities),
8184
attribute.StringSlice("project.services.capabilities.gpu", gpu),
8285
attribute.StringSlice("project.services.capabilities.tpu", tpu),
8386
}
87+
if metrics, ok := ctx.Value(Metrics{}).(Metrics); ok {
88+
attrs = append(attrs, attribute.Int("project.services.extends", metrics.CountExtends))
89+
}
90+
8491
if projHash, ok := projectHash(proj); ok {
8592
attrs = append(attrs, attribute.String("project.hash", projHash))
8693
}

pkg/compose/build.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ func (s *composeService) ensureImagesExists(ctx context.Context, project *types.
221221
return err
222222
}
223223

224-
err = tracing.SpanWrapFunc("project/pull", tracing.ProjectOptions(project),
224+
err = tracing.SpanWrapFunc("project/pull", tracing.ProjectOptions(ctx, project),
225225
func(ctx context.Context) error {
226226
return s.pullRequiredImages(ctx, project, images, quietPull)
227227
},
@@ -231,7 +231,7 @@ func (s *composeService) ensureImagesExists(ctx context.Context, project *types.
231231
}
232232

233233
if buildOpts != nil {
234-
err = tracing.SpanWrapFunc("project/build", tracing.ProjectOptions(project),
234+
err = tracing.SpanWrapFunc("project/build", tracing.ProjectOptions(ctx, project),
235235
func(ctx context.Context) error {
236236
builtImages, err := s.build(ctx, project, *buildOpts, images)
237237
if err != nil {

pkg/compose/scale.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import (
2525
)
2626

2727
func (s *composeService) Scale(ctx context.Context, project *types.Project, options api.ScaleOptions) error {
28-
return progress.Run(ctx, tracing.SpanWrapFunc("project/scale", tracing.ProjectOptions(project), func(ctx context.Context) error {
28+
return progress.Run(ctx, tracing.SpanWrapFunc("project/scale", tracing.ProjectOptions(ctx, project), func(ctx context.Context) error {
2929
err := s.create(ctx, project, api.CreateOptions{Services: options.Services})
3030
if err != nil {
3131
return err

pkg/compose/up.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import (
3232
)
3333

3434
func (s *composeService) Up(ctx context.Context, project *types.Project, options api.UpOptions) error { //nolint:gocyclo
35-
err := progress.Run(ctx, tracing.SpanWrapFunc("project/up", tracing.ProjectOptions(project), func(ctx context.Context) error {
35+
err := progress.Run(ctx, tracing.SpanWrapFunc("project/up", tracing.ProjectOptions(ctx, project), func(ctx context.Context) error {
3636
w := progress.ContextWriter(ctx)
3737
w.HasMore(options.Start.Attach == nil)
3838
err := s.create(ctx, project, options.Create)

0 commit comments

Comments
 (0)