mirror of https://github.com/docker/compose.git
use Docker go-sdk to manage Docker config
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
This commit is contained in:
parent
8f91793fb5
commit
c21cbc643a
|
@ -31,6 +31,7 @@ import (
|
|||
"github.com/compose-spec/compose-go/v2/types"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/compose/v2/cmd/formatter"
|
||||
"github.com/docker/go-sdk/config"
|
||||
"github.com/spf13/cobra"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
|
@ -203,7 +204,11 @@ func runConfigInterpolate(ctx context.Context, dockerCli command.Cli, opts confi
|
|||
}
|
||||
|
||||
if opts.resolveImageDigests {
|
||||
project, err = project.WithImagesResolved(compose.ImageDigestResolver(ctx, dockerCli.ConfigFile(), dockerCli.Client()))
|
||||
conf, err := config.Load()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
project, err = project.WithImagesResolved(compose.ImageDigestResolver(ctx, conf, dockerCli.Client()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -302,8 +307,11 @@ func resolveImageDigests(ctx context.Context, dockerCli command.Cli, model map[s
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
p, err = p.WithImagesResolved(compose.ImageDigestResolver(ctx, dockerCli.ConfigFile(), dockerCli.Client()))
|
||||
conf, err := config.Load()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p, err = p.WithImagesResolved(compose.ImageDigestResolver(ctx, conf, dockerCli.Client()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
6
go.mod
6
go.mod
|
@ -19,6 +19,8 @@ require (
|
|||
github.com/docker/cli-docs-tool v0.10.0
|
||||
github.com/docker/docker v28.3.2+incompatible
|
||||
github.com/docker/go-connections v0.5.0
|
||||
github.com/docker/go-sdk/config v0.1.0-alpha008
|
||||
github.com/docker/go-sdk/legacyadapters v0.0.0-00010101000000-000000000000
|
||||
github.com/docker/go-units v0.5.0
|
||||
github.com/eiannone/keyboard v0.0.0-20220611211555-0d226195f203
|
||||
github.com/fsnotify/fsevents v0.2.0
|
||||
|
@ -213,3 +215,7 @@ exclude (
|
|||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2
|
||||
)
|
||||
|
||||
replace github.com/docker/go-sdk/config => github.com/docker/go-sdk/config v0.0.0-20250721155554-2c7a2494f82e
|
||||
|
||||
replace github.com/docker/go-sdk/legacyadapters => github.com/docker/go-sdk/legacyadapters v0.0.0-20250721155554-2c7a2494f82e
|
||||
|
|
4
go.sum
4
go.sum
|
@ -148,6 +148,10 @@ github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6
|
|||
github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI=
|
||||
github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=
|
||||
github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
|
||||
github.com/docker/go-sdk/config v0.0.0-20250721155554-2c7a2494f82e h1:GMLGFIeWMC7ex8XIfguoiqKKcQCnGlUK+7PetQjeu5A=
|
||||
github.com/docker/go-sdk/config v0.0.0-20250721155554-2c7a2494f82e/go.mod h1:2lhg2sMZMKTtBVrsTG2Hn9P0dXMp1weecaJrE7OtNDM=
|
||||
github.com/docker/go-sdk/legacyadapters v0.0.0-20250721155554-2c7a2494f82e h1:SXZg7LU5EltuUN/fhrA5pY2twstAZRx/SvQQ8x8zevk=
|
||||
github.com/docker/go-sdk/legacyadapters v0.0.0-20250721155554-2c7a2494f82e/go.mod h1:hdc9zrN3gAxV4gg5yJAryDGNMSCSC4+BWaIXmoWmYC0=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4=
|
||||
|
|
|
@ -39,6 +39,7 @@ import (
|
|||
"github.com/docker/compose/v2/pkg/progress"
|
||||
"github.com/docker/compose/v2/pkg/utils"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
helpers "github.com/docker/go-sdk/legacyadapters/config" //nolint:staticcheck
|
||||
bclient "github.com/moby/buildkit/client"
|
||||
"github.com/moby/buildkit/session"
|
||||
"github.com/moby/buildkit/session/auth/authprovider"
|
||||
|
@ -416,7 +417,7 @@ func (s *composeService) toBuildOptions(project *types.Project, service types.Se
|
|||
|
||||
sessionConfig := []session.Attachable{
|
||||
authprovider.NewDockerAuthProvider(authprovider.DockerAuthProviderConfig{
|
||||
ConfigFile: s.configFile(),
|
||||
ConfigFile: helpers.ToConfigFile(s.config), //nolint:staticcheck
|
||||
}),
|
||||
}
|
||||
if len(options.SSHs) > 0 || len(service.Build.SSH) > 0 {
|
||||
|
|
|
@ -149,14 +149,9 @@ func (s *composeService) doBuildClassic(ctx context.Context, project *types.Proj
|
|||
progressOutput := streamformatter.NewProgressOutput(progBuff)
|
||||
body := progress.NewProgressReader(buildCtx, progressOutput, 0, "", "Sending build context to Docker daemon")
|
||||
|
||||
configFile := s.configFile()
|
||||
creds, err := configFile.GetAllCredentials()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
authConfigs := make(map[string]registry.AuthConfig, len(creds))
|
||||
for k, auth := range creds {
|
||||
authConfigs[k] = registry.AuthConfig(auth)
|
||||
authConfigs := make(map[string]registry.AuthConfig, len(s.config.AuthConfigs))
|
||||
for k, auth := range s.config.AuthConfigs {
|
||||
authConfigs[k] = auth.ToRegistryAuthConfig()
|
||||
}
|
||||
buildOptions := imageBuildOptions(s.dockerCli, project, service, options)
|
||||
imageName := api.GetImageNameOrDefault(service, project.Name)
|
||||
|
|
|
@ -27,7 +27,6 @@ import (
|
|||
|
||||
"github.com/compose-spec/compose-go/v2/types"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/config/configfile"
|
||||
"github.com/docker/cli/cli/flags"
|
||||
"github.com/docker/cli/cli/streams"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
|
@ -36,6 +35,7 @@ import (
|
|||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/api/types/volume"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/go-sdk/config"
|
||||
"github.com/jonboulle/clockwork"
|
||||
|
||||
"github.com/docker/compose/v2/internal/desktop"
|
||||
|
@ -54,11 +54,17 @@ func init() {
|
|||
|
||||
// NewComposeService create a local implementation of the compose.Service API
|
||||
func NewComposeService(dockerCli command.Cli) api.Service {
|
||||
configuration, err := config.Load()
|
||||
if err != nil {
|
||||
_, _ = fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
return &composeService{
|
||||
dockerCli: dockerCli,
|
||||
clock: clockwork.NewRealClock(),
|
||||
maxConcurrency: -1,
|
||||
dryRun: false,
|
||||
config: configuration,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,6 +72,7 @@ type composeService struct {
|
|||
dockerCli command.Cli
|
||||
desktopCli *desktop.Client
|
||||
experiments *experimental.State
|
||||
config config.Config
|
||||
|
||||
clock clockwork.Clock
|
||||
maxConcurrency int
|
||||
|
@ -91,10 +98,6 @@ func (s *composeService) apiClient() client.APIClient {
|
|||
return s.dockerCli.Client()
|
||||
}
|
||||
|
||||
func (s *composeService) configFile() *configfile.ConfigFile {
|
||||
return s.dockerCli.ConfigFile()
|
||||
}
|
||||
|
||||
func (s *composeService) MaxConcurrency(i int) {
|
||||
s.maxConcurrency = i
|
||||
}
|
||||
|
|
|
@ -192,8 +192,7 @@ func (s *composeService) getCreateConfigs(ctx context.Context,
|
|||
tty = service.Tty
|
||||
stdinOpen = service.StdinOpen
|
||||
)
|
||||
|
||||
proxyConfig := types.MappingWithEquals(s.configFile().ParseProxyConfig(s.apiClient().DaemonHost(), nil))
|
||||
proxyConfig := types.MappingWithEquals(s.config.ParseProxyConfig(s.apiClient().DaemonHost(), nil))
|
||||
env := proxyConfig.OverrideBy(service.Environment)
|
||||
|
||||
var mainNwName string
|
||||
|
|
|
@ -38,6 +38,7 @@ import (
|
|||
"github.com/docker/compose/v2/pkg/compose/transform"
|
||||
"github.com/docker/compose/v2/pkg/progress"
|
||||
"github.com/docker/compose/v2/pkg/prompt"
|
||||
helpers "github.com/docker/go-sdk/legacyadapters/config" //nolint:staticcheck
|
||||
)
|
||||
|
||||
func (s *composeService) Publish(ctx context.Context, project *types.Project, repository string, options api.PublishOptions) error {
|
||||
|
@ -63,9 +64,8 @@ func (s *composeService) publish(ctx context.Context, project *types.Project, re
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resolver := imagetools.New(imagetools.Opt{
|
||||
Auth: s.configFile(),
|
||||
Auth: helpers.ToConfigFile(s.config), //nolint:staticcheck
|
||||
})
|
||||
|
||||
var layers []ocipush.Pushable
|
||||
|
@ -216,7 +216,7 @@ func (s *composeService) generateImageDigestsOverride(ctx context.Context, proje
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
project, err = project.WithImagesResolved(ImageDigestResolver(ctx, s.configFile(), s.apiClient()))
|
||||
project, err = project.WithImagesResolved(ImageDigestResolver(ctx, s.config, s.apiClient()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ package compose
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
@ -29,12 +28,10 @@ import (
|
|||
|
||||
"github.com/compose-spec/compose-go/v2/types"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/buildx/driver"
|
||||
"github.com/docker/cli/cli/config/configfile"
|
||||
"github.com/docker/docker/api/types/image"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/docker/pkg/jsonmessage"
|
||||
"github.com/docker/docker/registry"
|
||||
"github.com/docker/go-sdk/config"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/opencontainers/go-digest"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
@ -117,7 +114,7 @@ func (s *composeService) pull(ctx context.Context, project *types.Project, opts
|
|||
|
||||
idx := i
|
||||
eg.Go(func() error {
|
||||
_, err := s.pullServiceImage(ctx, service, s.configFile(), w, opts.Quiet, project.Environment["DOCKER_DEFAULT_PLATFORM"])
|
||||
_, err := s.pullServiceImage(ctx, service, w, opts.Quiet, project.Environment["DOCKER_DEFAULT_PLATFORM"])
|
||||
if err != nil {
|
||||
pullErrors[idx] = err
|
||||
if service.Build != nil {
|
||||
|
@ -177,19 +174,18 @@ func getUnwrappedErrorMessage(err error) string {
|
|||
}
|
||||
|
||||
func (s *composeService) pullServiceImage(ctx context.Context, service types.ServiceConfig,
|
||||
configFile driver.Auth, w progress.Writer, quietPull bool, defaultPlatform string,
|
||||
w progress.Writer, quietPull bool, defaultPlatform string,
|
||||
) (string, error) {
|
||||
w.Event(progress.Event{
|
||||
ID: service.Name,
|
||||
Status: progress.Working,
|
||||
Text: "Pulling",
|
||||
})
|
||||
ref, err := reference.ParseNormalizedNamed(service.Image)
|
||||
_, auth, err := s.config.AuthConfigForImage(service.Image)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
encodedAuth, err := encodedAuth(ref, configFile)
|
||||
base64EncodedAuth, err := auth.EncodeBase64()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -200,7 +196,7 @@ func (s *composeService) pullServiceImage(ctx context.Context, service types.Ser
|
|||
}
|
||||
|
||||
stream, err := s.apiClient().ImagePull(ctx, service.Image, image.PullOptions{
|
||||
RegistryAuth: encodedAuth,
|
||||
RegistryAuth: base64EncodedAuth,
|
||||
Platform: platform,
|
||||
})
|
||||
|
||||
|
@ -265,13 +261,17 @@ func (s *composeService) pullServiceImage(ctx context.Context, service types.Ser
|
|||
}
|
||||
|
||||
// ImageDigestResolver creates a func able to resolve image digest from a docker ref,
|
||||
func ImageDigestResolver(ctx context.Context, file *configfile.ConfigFile, apiClient client.APIClient) func(named reference.Named) (digest.Digest, error) {
|
||||
func ImageDigestResolver(ctx context.Context, file config.Config, apiClient client.APIClient) func(named reference.Named) (digest.Digest, error) {
|
||||
return func(named reference.Named) (digest.Digest, error) {
|
||||
auth, err := encodedAuth(named, file)
|
||||
_, auth, err := file.AuthConfigForImage(named.Name())
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
inspect, err := apiClient.DistributionInspect(ctx, named.String(), auth)
|
||||
base64Auth, err := auth.EncodeBase64()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
inspect, err := apiClient.DistributionInspect(ctx, named.String(), base64Auth)
|
||||
if err != nil {
|
||||
return "",
|
||||
fmt.Errorf("failed to resolve digest for %s: %w", named.String(), err)
|
||||
|
@ -280,25 +280,6 @@ func ImageDigestResolver(ctx context.Context, file *configfile.ConfigFile, apiCl
|
|||
}
|
||||
}
|
||||
|
||||
func encodedAuth(ref reference.Named, configFile driver.Auth) (string, error) {
|
||||
repoInfo, err := registry.ParseRepositoryInfo(ref)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
key := registry.GetAuthConfigKey(repoInfo.Index)
|
||||
authConfig, err := configFile.GetAuthConfig(key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
buf, err := json.Marshal(authConfig)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return base64.URLEncoding.EncodeToString(buf), nil
|
||||
}
|
||||
|
||||
func (s *composeService) pullRequiredImages(ctx context.Context, project *types.Project, images map[string]api.ImageSummary, quietPull bool) error {
|
||||
needPull := map[string]types.ServiceConfig{}
|
||||
for name, service := range project.Services {
|
||||
|
@ -335,7 +316,7 @@ func (s *composeService) pullRequiredImages(ctx context.Context, project *types.
|
|||
var mutex sync.Mutex
|
||||
for name, service := range needPull {
|
||||
eg.Go(func() error {
|
||||
id, err := s.pullServiceImage(ctx, service, s.configFile(), w, quietPull, project.Environment["DOCKER_DEFAULT_PLATFORM"])
|
||||
id, err := s.pullServiceImage(ctx, service, w, quietPull, project.Environment["DOCKER_DEFAULT_PLATFORM"])
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
pulledImages[name] = api.ImageSummary{
|
||||
|
|
|
@ -18,7 +18,6 @@ package compose
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
@ -26,12 +25,8 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/compose-spec/compose-go/v2/types"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/buildx/driver"
|
||||
"github.com/docker/docker/api/types/image"
|
||||
"github.com/docker/docker/api/types/system"
|
||||
"github.com/docker/docker/pkg/jsonmessage"
|
||||
"github.com/docker/docker/registry"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/docker/compose/v2/pkg/api"
|
||||
|
@ -51,14 +46,6 @@ func (s *composeService) push(ctx context.Context, project *types.Project, optio
|
|||
eg, ctx := errgroup.WithContext(ctx)
|
||||
eg.SetLimit(s.maxConcurrency)
|
||||
|
||||
info, err := s.apiClient().Info(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.IndexServerAddress == "" {
|
||||
info.IndexServerAddress = registry.IndexServer
|
||||
}
|
||||
|
||||
w := progress.ContextWriter(ctx)
|
||||
for _, service := range project.Services {
|
||||
if service.Build == nil || service.Image == "" {
|
||||
|
@ -79,7 +66,7 @@ func (s *composeService) push(ctx context.Context, project *types.Project, optio
|
|||
|
||||
for _, tag := range tags {
|
||||
eg.Go(func() error {
|
||||
err := s.pushServiceImage(ctx, tag, info, s.configFile(), w, options.Quiet)
|
||||
err := s.pushServiceImage(ctx, tag, w, options.Quiet)
|
||||
if err != nil {
|
||||
if !options.IgnoreFailures {
|
||||
return err
|
||||
|
@ -93,33 +80,17 @@ func (s *composeService) push(ctx context.Context, project *types.Project, optio
|
|||
return eg.Wait()
|
||||
}
|
||||
|
||||
func (s *composeService) pushServiceImage(ctx context.Context, tag string, info system.Info, configFile driver.Auth, w progress.Writer, quietPush bool) error {
|
||||
ref, err := reference.ParseNormalizedNamed(tag)
|
||||
func (s *composeService) pushServiceImage(ctx context.Context, tag string, w progress.Writer, quietPush bool) error {
|
||||
_, auth, err := s.config.AuthConfigForImage(tag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
repoInfo, err := registry.ParseRepositoryInfo(ref)
|
||||
authBase64Encoded, err := auth.EncodeBase64()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
key := repoInfo.Index.Name
|
||||
if repoInfo.Index.Official {
|
||||
key = info.IndexServerAddress
|
||||
}
|
||||
authConfig, err := configFile.GetAuthConfig(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
buf, err := json.Marshal(authConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
stream, err := s.apiClient().ImagePush(ctx, tag, image.PushOptions{
|
||||
RegistryAuth: base64.URLEncoding.EncodeToString(buf),
|
||||
RegistryAuth: authBase64Encoded,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
Loading…
Reference in New Issue