replace passing parameters by context with singletons

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Nicolas De Loof 2021-03-11 11:43:40 +01:00
parent 9301c298ef
commit 48402585fd
No known key found for this signature in database
GPG Key ID: 9858809D6F8F6E7E
47 changed files with 169 additions and 205 deletions

View File

@ -17,7 +17,6 @@
package aci package aci
import ( import (
"context"
"strings" "strings"
"github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2019-12-01/containerinstance" "github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2019-12-01/containerinstance"
@ -68,9 +67,9 @@ func init() {
backend.Register(backendType, backendType, service, getCloudService) backend.Register(backendType, backendType, service, getCloudService)
} }
func service(ctx context.Context) (backend.Service, error) { func service() (backend.Service, error) {
contextStore := store.ContextStore(ctx) contextStore := store.Instance()
currentContext := apicontext.CurrentContext(ctx) currentContext := apicontext.Current()
var aciContext store.AciContext var aciContext store.AciContext
if err := contextStore.GetEndpoint(currentContext, &aciContext); err != nil { if err := contextStore.GetEndpoint(currentContext, &aciContext); err != nil {

View File

@ -17,7 +17,6 @@
package backend package backend
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
@ -38,7 +37,7 @@ var (
errTypeRegistered = errors.New("backend: already registered") errTypeRegistered = errors.New("backend: already registered")
) )
type initFunc func(context.Context) (Service, error) type initFunc func() (Service, error)
type getCloudServiceFunc func() (cloud.Service, error) type getCloudServiceFunc func() (cloud.Service, error)
type registeredBackend struct { type registeredBackend struct {
@ -52,6 +51,18 @@ var backends = struct {
r []*registeredBackend r []*registeredBackend
}{} }{}
var instance Service
// Current return the active backend instance
func Current() Service {
return instance
}
// WithBackend set the active backend instance
func WithBackend(s Service) {
instance = s
}
// Service aggregates the service interfaces // Service aggregates the service interfaces
type Service interface { type Service interface {
ContainerService() containers.Service ContainerService() containers.Service
@ -85,10 +96,10 @@ func Register(name string, backendType string, init initFunc, getCoudService get
// Get returns the backend registered for a particular type, it returns // Get returns the backend registered for a particular type, it returns
// an error if there is no registered backends for the given type. // an error if there is no registered backends for the given type.
func Get(ctx context.Context, backendType string) (Service, error) { func Get(backendType string) (Service, error) {
for _, b := range backends.r { for _, b := range backends.r {
if b.backendType == backendType { if b.backendType == backendType {
return b.init(ctx) return b.init()
} }
} }
@ -97,7 +108,7 @@ func Get(ctx context.Context, backendType string) (Service, error) {
// GetCloudService returns the backend registered for a particular type, it returns // GetCloudService returns the backend registered for a particular type, it returns
// an error if there is no registered backends for the given type. // an error if there is no registered backends for the given type.
func GetCloudService(ctx context.Context, backendType string) (cloud.Service, error) { func GetCloudService(backendType string) (cloud.Service, error) {
for _, b := range backends.r { for _, b := range backends.r {
if b.backendType == backendType { if b.backendType == backendType {
return b.getCloudService() return b.getCloudService()

View File

@ -25,6 +25,7 @@ import (
"github.com/docker/compose-cli/api/containers" "github.com/docker/compose-cli/api/containers"
apicontext "github.com/docker/compose-cli/api/context" apicontext "github.com/docker/compose-cli/api/context"
"github.com/docker/compose-cli/api/context/store" "github.com/docker/compose-cli/api/context/store"
"github.com/docker/compose-cli/api/errdefs"
"github.com/docker/compose-cli/api/resources" "github.com/docker/compose-cli/api/resources"
"github.com/docker/compose-cli/api/secrets" "github.com/docker/compose-cli/api/secrets"
"github.com/docker/compose-cli/api/volumes" "github.com/docker/compose-cli/api/volumes"
@ -32,31 +33,17 @@ import (
// New returns a backend client associated with current context // New returns a backend client associated with current context
func New(ctx context.Context) (*Client, error) { func New(ctx context.Context) (*Client, error) {
return newWithDefaultBackend(ctx, "") currentContext := apicontext.Current()
} s := store.Instance()
// NewWithDefaultLocalBackend returns a backend client associated with current context or local backend if on default context type
func NewWithDefaultLocalBackend(ctx context.Context) (*Client, error) {
return newWithDefaultBackend(ctx, store.LocalContextType)
}
func newWithDefaultBackend(ctx context.Context, defaultBackend string) (*Client, error) {
currentContext := apicontext.CurrentContext(ctx)
s := store.ContextStore(ctx)
cc, err := s.Get(currentContext) cc, err := s.Get(currentContext)
if err != nil { if err != nil {
return nil, err return nil, err
} }
backendName := cc.Type() service := backend.Current()
if backendName == store.DefaultContextType && defaultBackend != "" { if service == nil {
backendName = defaultBackend return nil, errdefs.ErrNotFound
}
service, err := backend.Get(ctx, backendName)
if err != nil {
return nil, err
} }
client := NewClient(cc.Type(), service) client := NewClient(cc.Type(), service)
@ -73,7 +60,7 @@ func NewClient(backendType string, service backend.Service) Client {
// GetCloudService returns a backend CloudService (typically login, create context) // GetCloudService returns a backend CloudService (typically login, create context)
func GetCloudService(ctx context.Context, backendType string) (cloud.Service, error) { func GetCloudService(ctx context.Context, backendType string) (cloud.Service, error) {
return backend.GetCloudService(ctx, backendType) return backend.GetCloudService(backendType)
} }
// Client is a multi-backend client // Client is a multi-backend client

View File

@ -17,7 +17,6 @@
package config package config
import ( import (
"context"
"encoding/json" "encoding/json"
"io/ioutil" "io/ioutil"
"os" "os"
@ -28,17 +27,16 @@ import (
"github.com/docker/compose-cli/api/context/store" "github.com/docker/compose-cli/api/context/store"
) )
type dirKey struct{} var configDir string
// WithDir sets the config directory path in the context // WithDir sets the config directory path in the context
func WithDir(ctx context.Context, path string) context.Context { func WithDir(path string) {
return context.WithValue(ctx, dirKey{}, path) configDir = path
} }
// Dir returns the config directory path // Dir returns the config directory path
func Dir(ctx context.Context) string { func Dir() string {
cd, _ := ctx.Value(dirKey{}).(string) return configDir
return cd
} }
// LoadFile loads the docker configuration // LoadFile loads the docker configuration

View File

@ -16,35 +16,14 @@
package context package context
import ( var current string
gocontext "context"
"golang.org/x/net/context"
cliflags "github.com/docker/cli/cli/flags"
)
type currentContextKey struct{}
type cliOptionsKey struct{}
// WithCurrentContext sets the name of the current docker context // WithCurrentContext sets the name of the current docker context
func WithCurrentContext(ctx gocontext.Context, contextName string) context.Context { func WithCurrentContext(contextName string) {
return context.WithValue(ctx, currentContextKey{}, contextName) current = contextName
} }
// CurrentContext returns the current context name // Current returns the current context name
func CurrentContext(ctx context.Context) string { func Current() string {
cc, _ := ctx.Value(currentContextKey{}).(string) return current
return cc
}
// WithCliOptions sets CLI options
func WithCliOptions(ctx gocontext.Context, options cliflags.CommonOptions) context.Context {
return context.WithValue(ctx, cliOptionsKey{}, options)
}
// CliOptions returns common cli options
func CliOptions(ctx context.Context) cliflags.CommonOptions {
cc, _ := ctx.Value(cliOptionsKey{}).(cliflags.CommonOptions)
return cc
} }

View File

@ -17,7 +17,6 @@
package store package store
import ( import (
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
@ -67,17 +66,16 @@ const (
metaFile = "meta.json" metaFile = "meta.json"
) )
type contextStoreKey struct{} var instance Store
// WithContextStore adds the store to the context // WithContextStore adds the store to the context
func WithContextStore(ctx context.Context, store Store) context.Context { func WithContextStore(store Store) {
return context.WithValue(ctx, contextStoreKey{}, store) instance = store
} }
// ContextStore returns the store from the context // Instance returns the store from the context
func ContextStore(ctx context.Context) Store { func Instance() Store {
s, _ := ctx.Value(contextStoreKey{}).(Store) return instance
return s
} }
// Store is the context store // Store is the context store

View File

@ -63,7 +63,7 @@ func buildCommand(p *projectOptions) *cobra.Command {
} }
func runBuild(ctx context.Context, opts buildOptions, services []string) error { func runBuild(ctx context.Context, opts buildOptions, services []string) error {
c, err := client.NewWithDefaultLocalBackend(ctx) c, err := client.New(ctx)
if err != nil { if err != nil {
return err return err
} }

View File

@ -77,7 +77,7 @@ func convertCommand(p *projectOptions) *cobra.Command {
func runConvert(ctx context.Context, opts convertOptions, services []string) error { func runConvert(ctx context.Context, opts convertOptions, services []string) error {
var json []byte var json []byte
c, err := client.NewWithDefaultLocalBackend(ctx) c, err := client.New(ctx)
if err != nil { if err != nil {
return err return err
} }
@ -88,7 +88,7 @@ func runConvert(ctx context.Context, opts convertOptions, services []string) err
} }
if opts.resolve { if opts.resolve {
configFile, err := cliconfig.Load(config.Dir(ctx)) configFile, err := cliconfig.Load(config.Dir())
if err != nil { if err != nil {
return err return err
} }

View File

@ -69,7 +69,7 @@ func downCommand(p *projectOptions, contextType string) *cobra.Command {
} }
func runDown(ctx context.Context, opts downOptions) error { func runDown(ctx context.Context, opts downOptions) error {
c, err := client.NewWithDefaultLocalBackend(ctx) c, err := client.New(ctx)
if err != nil { if err != nil {
return err return err
} }

View File

@ -51,7 +51,7 @@ func eventsCommand(p *projectOptions) *cobra.Command {
} }
func runEvents(ctx context.Context, opts eventsOpts, services []string) error { func runEvents(ctx context.Context, opts eventsOpts, services []string) error {
c, err := client.NewWithDefaultLocalBackend(ctx) c, err := client.New(ctx)
if err != nil { if err != nil {
return err return err
} }

View File

@ -75,7 +75,7 @@ func execCommand(p *projectOptions) *cobra.Command {
} }
func runExec(ctx context.Context, opts execOpts) error { func runExec(ctx context.Context, opts execOpts) error {
c, err := client.NewWithDefaultLocalBackend(ctx) c, err := client.New(ctx)
if err != nil { if err != nil {
return err return err
} }

View File

@ -49,7 +49,7 @@ func killCommand(p *projectOptions) *cobra.Command {
} }
func runKill(ctx context.Context, opts killOptions, services []string) error { func runKill(ctx context.Context, opts killOptions, services []string) error {
c, err := client.NewWithDefaultLocalBackend(ctx) c, err := client.New(ctx)
if err != nil { if err != nil {
return err return err
} }

View File

@ -69,7 +69,7 @@ func runList(ctx context.Context, opts lsOptions) error {
return err return err
} }
c, err := client.NewWithDefaultLocalBackend(ctx) c, err := client.New(ctx)
if err != nil { if err != nil {
return err return err
} }

View File

@ -62,7 +62,7 @@ func logsCommand(p *projectOptions, contextType string) *cobra.Command {
} }
func runLogs(ctx context.Context, opts logsOptions, services []string) error { func runLogs(ctx context.Context, opts logsOptions, services []string) error {
c, err := client.NewWithDefaultLocalBackend(ctx) c, err := client.New(ctx)
if err != nil { if err != nil {
return err return err
} }

View File

@ -44,7 +44,7 @@ func pauseCommand(p *projectOptions) *cobra.Command {
} }
func runPause(ctx context.Context, opts pauseOptions, services []string) error { func runPause(ctx context.Context, opts pauseOptions, services []string) error {
c, err := client.NewWithDefaultLocalBackend(ctx) c, err := client.New(ctx)
if err != nil { if err != nil {
return err return err
} }
@ -79,7 +79,7 @@ func unpauseCommand(p *projectOptions) *cobra.Command {
} }
func runUnPause(ctx context.Context, opts unpauseOptions, services []string) error { func runUnPause(ctx context.Context, opts unpauseOptions, services []string) error {
c, err := client.NewWithDefaultLocalBackend(ctx) c, err := client.New(ctx)
if err != nil { if err != nil {
return err return err
} }

View File

@ -58,7 +58,7 @@ func psCommand(p *projectOptions) *cobra.Command {
} }
func runPs(ctx context.Context, opts psOptions) error { func runPs(ctx context.Context, opts psOptions) error {
c, err := client.NewWithDefaultLocalBackend(ctx) c, err := client.New(ctx)
if err != nil { if err != nil {
return err return err
} }

View File

@ -49,7 +49,7 @@ func pullCommand(p *projectOptions) *cobra.Command {
} }
func runPull(ctx context.Context, opts pullOptions, services []string) error { func runPull(ctx context.Context, opts pullOptions, services []string) error {
c, err := client.NewWithDefaultLocalBackend(ctx) c, err := client.New(ctx)
if err != nil { if err != nil {
return err return err
} }

View File

@ -50,7 +50,7 @@ func pushCommand(p *projectOptions) *cobra.Command {
} }
func runPush(ctx context.Context, opts pushOptions, services []string) error { func runPush(ctx context.Context, opts pushOptions, services []string) error {
c, err := client.NewWithDefaultLocalBackend(ctx) c, err := client.New(ctx)
if err != nil { if err != nil {
return err return err
} }

View File

@ -61,7 +61,7 @@ Any data which is not in a volume will be lost.`,
} }
func runRemove(ctx context.Context, opts removeOptions, services []string) error { func runRemove(ctx context.Context, opts removeOptions, services []string) error {
c, err := client.NewWithDefaultLocalBackend(ctx) c, err := client.New(ctx)
if err != nil { if err != nil {
return err return err
} }

View File

@ -45,7 +45,7 @@ func startCommand(p *projectOptions) *cobra.Command {
} }
func runStart(ctx context.Context, opts startOptions, services []string) error { func runStart(ctx context.Context, opts startOptions, services []string) error {
c, err := client.NewWithDefaultLocalBackend(ctx) c, err := client.New(ctx)
if err != nil { if err != nil {
return err return err
} }

View File

@ -52,7 +52,7 @@ func stopCommand(p *projectOptions) *cobra.Command {
} }
func runStop(ctx context.Context, opts stopOptions, services []string) error { func runStop(ctx context.Context, opts stopOptions, services []string) error {
c, err := client.NewWithDefaultLocalBackend(ctx) c, err := client.New(ctx)
if err != nil { if err != nil {
return err return err
} }

View File

@ -49,7 +49,7 @@ func topCommand(p *projectOptions) *cobra.Command {
} }
func runTop(ctx context.Context, opts topOptions, services []string) error { func runTop(ctx context.Context, opts topOptions, services []string) error {
c, err := client.NewWithDefaultLocalBackend(ctx) c, err := client.New(ctx)
if err != nil { if err != nil {
return err return err
} }

View File

@ -338,7 +338,7 @@ func setServiceScale(project *types.Project, name string, replicas int) error {
} }
func setup(ctx context.Context, opts composeOptions, services []string) (*client.Client, *types.Project, error) { func setup(ctx context.Context, opts composeOptions, services []string) (*client.Client, *types.Project, error) {
c, err := client.NewWithDefaultLocalBackend(ctx) c, err := client.New(ctx)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }

View File

@ -17,7 +17,6 @@
package context package context
import ( import (
"context"
"fmt" "fmt"
"strings" "strings"
@ -103,15 +102,15 @@ func createLocalCommand() *cobra.Command {
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
Hidden: true, Hidden: true,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
return createDockerContext(cmd.Context(), args[0], store.LocalContextType, opts.description, store.LocalContext{}) return createDockerContext(args[0], store.LocalContextType, opts.description, store.LocalContext{})
}, },
} }
addDescriptionFlag(cmd, &opts.description) addDescriptionFlag(cmd, &opts.description)
return cmd return cmd
} }
func createDockerContext(ctx context.Context, name string, contextType string, description string, data interface{}) error { func createDockerContext(name string, contextType string, description string, data interface{}) error {
s := store.ContextStore(ctx) s := store.Instance()
result := s.Create( result := s.Create(
name, name,
contextType, contextType,
@ -122,8 +121,8 @@ func createDockerContext(ctx context.Context, name string, contextType string, d
return result return result
} }
func contextExists(ctx context.Context, name string) bool { func contextExists(name string) bool {
s := store.ContextStore(ctx) s := store.Instance()
return s.ContextExists(name) return s.ContextExists(name)
} }

View File

@ -57,7 +57,7 @@ func createAciCommand() *cobra.Command {
} }
func runCreateAci(ctx context.Context, contextName string, opts aci.ContextParams) error { func runCreateAci(ctx context.Context, contextName string, opts aci.ContextParams) error {
if contextExists(ctx, contextName) { if contextExists(contextName) {
return errors.Wrapf(errdefs.ErrAlreadyExists, "context %s", contextName) return errors.Wrapf(errdefs.ErrAlreadyExists, "context %s", contextName)
} }
contextData, description, err := getAciContextData(ctx, opts) contextData, description, err := getAciContextData(ctx, opts)
@ -67,7 +67,7 @@ func runCreateAci(ctx context.Context, contextName string, opts aci.ContextParam
} }
return err return err
} }
return createDockerContext(ctx, contextName, store.AciContextType, description, contextData) return createDockerContext(contextName, store.AciContextType, description, contextData)
} }

View File

@ -109,7 +109,7 @@ func parseAccessKeysFile(file string, opts *ecs.ContextParams) error {
} }
func runCreateLocalSimulation(ctx context.Context, contextName string, opts ecs.ContextParams) error { func runCreateLocalSimulation(ctx context.Context, contextName string, opts ecs.ContextParams) error {
if contextExists(ctx, contextName) { if contextExists(contextName) {
return errors.Wrapf(errdefs.ErrAlreadyExists, "context %q", contextName) return errors.Wrapf(errdefs.ErrAlreadyExists, "context %q", contextName)
} }
cs, err := client.GetCloudService(ctx, store.EcsLocalSimulationContextType) cs, err := client.GetCloudService(ctx, store.EcsLocalSimulationContextType)
@ -120,18 +120,18 @@ func runCreateLocalSimulation(ctx context.Context, contextName string, opts ecs.
if err != nil { if err != nil {
return err return err
} }
return createDockerContext(ctx, contextName, store.EcsLocalSimulationContextType, description, data) return createDockerContext(contextName, store.EcsLocalSimulationContextType, description, data)
} }
func runCreateEcs(ctx context.Context, contextName string, opts ecs.ContextParams) error { func runCreateEcs(ctx context.Context, contextName string, opts ecs.ContextParams) error {
if contextExists(ctx, contextName) { if contextExists(contextName) {
return errors.Wrapf(errdefs.ErrAlreadyExists, "context %q", contextName) return errors.Wrapf(errdefs.ErrAlreadyExists, "context %q", contextName)
} }
contextData, description, err := getEcsContextData(ctx, opts) contextData, description, err := getEcsContextData(ctx, opts)
if err != nil { if err != nil {
return err return err
} }
return createDockerContext(ctx, contextName, store.EcsContextType, description, contextData) return createDockerContext(contextName, store.EcsContextType, description, contextData)
} }

View File

@ -19,8 +19,6 @@
package context package context
import ( import (
"context"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -45,7 +43,7 @@ func createKubeCommand() *cobra.Command {
Short: "Create context for a Kubernetes Cluster", Short: "Create context for a Kubernetes Cluster",
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
return runCreateKube(cmd.Context(), args[0], opts) return runCreateKube(args[0], opts)
}, },
} }
@ -56,8 +54,8 @@ func createKubeCommand() *cobra.Command {
return cmd return cmd
} }
func runCreateKube(ctx context.Context, contextName string, opts kube.ContextParams) error { func runCreateKube(contextName string, opts kube.ContextParams) error {
if contextExists(ctx, contextName) { if contextExists(contextName) {
return errors.Wrapf(errdefs.ErrAlreadyExists, "context %q", contextName) return errors.Wrapf(errdefs.ErrAlreadyExists, "context %q", contextName)
} }
@ -65,5 +63,5 @@ func runCreateKube(ctx context.Context, contextName string, opts kube.ContextPar
if err != nil { if err != nil {
return err return err
} }
return createDockerContext(ctx, contextName, store.KubeContextType, description, contextData) return createDockerContext(contextName, store.KubeContextType, description, contextData)
} }

View File

@ -73,9 +73,8 @@ func runList(cmd *cobra.Command, opts lsOpts) error {
return nil return nil
} }
ctx := cmd.Context() currentContext := apicontext.Current()
currentContext := apicontext.CurrentContext(ctx) s := store.Instance()
s := store.ContextStore(ctx)
contexts, err := s.List() contexts, err := s.List()
if err != nil { if err != nil {
return err return err

View File

@ -17,7 +17,6 @@
package context package context
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
@ -41,7 +40,7 @@ func removeCommand() *cobra.Command {
Aliases: []string{"remove"}, Aliases: []string{"remove"},
Args: cobra.MinimumNArgs(1), Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
return runRemove(cmd.Context(), args, opts.force) return runRemove(args, opts.force)
}, },
} }
cmd.Flags().BoolVarP(&opts.force, "force", "f", false, "Force removing current context") cmd.Flags().BoolVarP(&opts.force, "force", "f", false, "Force removing current context")
@ -49,15 +48,15 @@ func removeCommand() *cobra.Command {
return cmd return cmd
} }
func runRemove(ctx context.Context, args []string, force bool) error { func runRemove(args []string, force bool) error {
currentContext := apicontext.CurrentContext(ctx) currentContext := apicontext.Current()
s := store.ContextStore(ctx) s := store.Instance()
var errs *multierror.Error var errs *multierror.Error
for _, contextName := range args { for _, contextName := range args {
if currentContext == contextName { if currentContext == contextName {
if force { if force {
if err := runUse(ctx, "default"); err != nil { if err := runUse("default"); err != nil {
errs = multierror.Append(errs, errors.New("cannot delete current context")) errs = multierror.Append(errs, errors.New("cannot delete current context"))
} else { } else {
errs = removeContext(s, contextName, errs) errs = removeContext(s, contextName, errs)

View File

@ -17,7 +17,6 @@
package context package context
import ( import (
"context"
"fmt" "fmt"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -32,16 +31,16 @@ func showCommand() *cobra.Command {
Short: "Print the current context", Short: "Print the current context",
Args: cobra.NoArgs, Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
return runShow(cmd.Context()) return runShow()
}, },
} }
} }
func runShow(ctx context.Context) error { func runShow() error {
name := apicontext.CurrentContext(ctx) name := apicontext.Current()
// Match behavior of existing CLI // Match behavior of existing CLI
if name != store.DefaultContextName { if name != store.DefaultContextName {
s := store.ContextStore(ctx) s := store.Instance()
if _, err := s.Get(name); err != nil { if _, err := s.Get(name); err != nil {
return err return err
} }

View File

@ -72,7 +72,7 @@ $ docker context update my-context --description "some description" --docker "ho
} }
func runUpdate(cmd *cobra.Command, name string) error { func runUpdate(cmd *cobra.Command, name string) error {
s := store.ContextStore(cmd.Context()) s := store.Instance()
dockerContext, err := s.Get(name) dockerContext, err := s.Get(name)
if err == nil && dockerContext != nil { if err == nil && dockerContext != nil {
if dockerContext.Type() != store.DefaultContextType { if dockerContext.Type() != store.DefaultContextType {

View File

@ -17,7 +17,6 @@
package context package context
import ( import (
"context"
"fmt" "fmt"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -32,20 +31,20 @@ func useCommand() *cobra.Command {
Short: "Set the default context", Short: "Set the default context",
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
return runUse(cmd.Context(), args[0]) return runUse(args[0])
}, },
} }
} }
func runUse(ctx context.Context, name string) error { func runUse(name string) error {
s := store.ContextStore(ctx) s := store.Instance()
// Match behavior of existing CLI // Match behavior of existing CLI
if name != store.DefaultContextName { if name != store.DefaultContextName {
if _, err := s.Get(name); err != nil { if _, err := s.Get(name); err != nil {
return err return err
} }
} }
if err := config.WriteCurrentContext(config.Dir(ctx), name); err != nil { if err := config.WriteCurrentContext(config.Dir(), name); err != nil {
return err return err
} }
fmt.Println(name) fmt.Println(name)

View File

@ -28,10 +28,14 @@ import (
"syscall" "syscall"
"time" "time"
"github.com/docker/cli/cli/command"
cliconfig "github.com/docker/cli/cli/config"
cliflags "github.com/docker/cli/cli/flags"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/docker/compose-cli/api/backend"
"github.com/docker/compose-cli/api/config" "github.com/docker/compose-cli/api/config"
apicontext "github.com/docker/compose-cli/api/context" apicontext "github.com/docker/compose-cli/api/context"
"github.com/docker/compose-cli/api/context/store" "github.com/docker/compose-cli/api/context/store"
@ -46,8 +50,7 @@ import (
"github.com/docker/compose-cli/cli/metrics" "github.com/docker/compose-cli/cli/metrics"
"github.com/docker/compose-cli/cli/mobycli" "github.com/docker/compose-cli/cli/mobycli"
cliopts "github.com/docker/compose-cli/cli/options" cliopts "github.com/docker/compose-cli/cli/options"
"github.com/docker/compose-cli/local"
cliflags "github.com/docker/cli/cli/flags"
// Backend registrations // Backend registrations
_ "github.com/docker/compose-cli/aci" _ "github.com/docker/compose-cli/aci"
@ -191,16 +194,17 @@ func main() {
if opts.Config == "" { if opts.Config == "" {
fatal(errors.New("config path cannot be empty")) fatal(errors.New("config path cannot be empty"))
} }
configDir := opts.Config configDir := opts.Config
ctx = config.WithDir(ctx, configDir) config.WithDir(configDir)
currentContext := determineCurrentContext(opts.Context, configDir, opts.Hosts) currentContext := determineCurrentContext(opts.Context, configDir, opts.Hosts)
apicontext.WithCurrentContext(currentContext)
s, err := store.New(configDir) s, err := store.New(configDir)
if err != nil { if err != nil {
mobycli.Exec(root) mobycli.Exec(root)
} }
store.WithContextStore(s)
ctype := store.DefaultContextType ctype := store.DefaultContextType
cc, _ := s.Get(currentContext) cc, _ := s.Get(currentContext)
@ -208,28 +212,17 @@ func main() {
ctype = cc.Type() ctype = cc.Type()
} }
service, err := getBackend(ctype, configDir, opts)
if err != nil {
fatal(err)
}
backend.WithBackend(service)
root.AddCommand( root.AddCommand(
run.Command(ctype), run.Command(ctype),
compose.Command(ctype), compose.Command(ctype),
volume.Command(ctype), volume.Command(ctype),
) )
if ctype == store.DefaultContextType || ctype == store.LocalContextType {
cnxOptions := cliflags.CommonOptions{
Context: opts.Context,
Debug: opts.Debug,
Hosts: opts.Hosts,
LogLevel: opts.LogLevel,
TLS: opts.TLS,
TLSVerify: opts.TLSVerify,
}
if opts.TLSVerify {
cnxOptions.TLSOptions = opts.TLSOptions
}
ctx = apicontext.WithCliOptions(ctx, cnxOptions)
}
ctx = apicontext.WithCurrentContext(ctx, currentContext)
ctx = store.WithContextStore(ctx, s)
if err = root.ExecuteContext(ctx); err != nil { if err = root.ExecuteContext(ctx); err != nil {
handleError(ctx, err, ctype, currentContext, cc, root) handleError(ctx, err, ctype, currentContext, cc, root)
@ -237,6 +230,38 @@ func main() {
metrics.Track(ctype, os.Args[1:], metrics.SuccessStatus) metrics.Track(ctype, os.Args[1:], metrics.SuccessStatus)
} }
func getBackend(ctype string, configDir string, opts cliopts.GlobalOpts) (backend.Service, error) {
switch ctype {
case store.DefaultContextType, store.LocalContextType:
configFile, err := cliconfig.Load(configDir)
if err != nil {
return nil, err
}
options := cliflags.CommonOptions{
Context: opts.Context,
Debug: opts.Debug,
Hosts: opts.Hosts,
LogLevel: opts.LogLevel,
}
if opts.TLSVerify {
options.TLS = opts.TLS
options.TLSVerify = opts.TLSVerify
options.TLSOptions = opts.TLSOptions
}
apiClient, err := command.NewAPIClientFromFlags(&options, configFile)
if err != nil {
return nil, err
}
return local.NewService(apiClient), nil
}
service, err := backend.Get(ctype)
if errdefs.IsNotFoundError(err) {
return service, nil
}
return service, err
}
func handleError(ctx context.Context, err error, ctype string, currentContext string, cc *store.DockerContext, root *cobra.Command) { func handleError(ctx context.Context, err error, ctype string, currentContext string, cc *store.DockerContext, root *cobra.Command) {
// if user canceled request, simply exit without any error message // if user canceled request, simply exit without any error message
if errdefs.IsErrCanceled(err) || errors.Is(ctx.Err(), context.Canceled) { if errdefs.IsErrCanceled(err) || errors.Is(ctx.Err(), context.Canceled) {

View File

@ -39,9 +39,9 @@ const ComDockerCli = "com.docker.cli"
// ExecIfDefaultCtxType delegates to com.docker.cli if on moby context // ExecIfDefaultCtxType delegates to com.docker.cli if on moby context
func ExecIfDefaultCtxType(ctx context.Context, root *cobra.Command) { func ExecIfDefaultCtxType(ctx context.Context, root *cobra.Command) {
currentContext := apicontext.CurrentContext(ctx) currentContext := apicontext.Current()
s := store.ContextStore(ctx) s := store.Instance()
currentCtx, err := s.Get(currentContext) currentCtx, err := s.Get(currentContext)
// Only run original docker command if the current context is not ours. // Only run original docker command if the current context is not ours.

View File

@ -40,7 +40,7 @@ func unaryServerInterceptor(clictx context.Context) grpc.UnaryServerInterceptor
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
currentContext, err := getIncomingContext(ctx) currentContext, err := getIncomingContext(ctx)
if err != nil { if err != nil {
currentContext, err = getConfigContext(clictx) currentContext, err = getConfigContext()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -59,7 +59,7 @@ func streamServerInterceptor(clictx context.Context) grpc.StreamServerIntercepto
return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
currentContext, err := getIncomingContext(ss.Context()) currentContext, err := getIncomingContext(ss.Context())
if err != nil { if err != nil {
currentContext, err = getConfigContext(clictx) currentContext, err = getConfigContext()
if err != nil { if err != nil {
return err return err
} }
@ -77,8 +77,8 @@ func streamServerInterceptor(clictx context.Context) grpc.StreamServerIntercepto
} }
// Returns the current context from the configuration file // Returns the current context from the configuration file
func getConfigContext(ctx context.Context) (string, error) { func getConfigContext() (string, error) {
configDir := config.Dir(ctx) configDir := config.Dir()
configFile, err := config.LoadFile(configDir) configFile, err := config.LoadFile(configDir)
if err != nil { if err != nil {
return "", err return "", err
@ -100,9 +100,9 @@ func getIncomingContext(ctx context.Context) (string, error) {
// configureContext populates the request context with objects the client // configureContext populates the request context with objects the client
// needs: the context store and the api client // needs: the context store and the api client
func configureContext(ctx context.Context, currentContext string, method string) (context.Context, error) { func configureContext(ctx context.Context, currentContext string, method string) (context.Context, error) {
configDir := config.Dir(ctx) configDir := config.Dir()
ctx = apicontext.WithCurrentContext(ctx, currentContext) apicontext.WithCurrentContext(currentContext)
// The contexts service doesn't need the client // The contexts service doesn't need the client
if !strings.Contains(method, "/com.docker.api.protos.context.v1.Contexts") { if !strings.Contains(method, "/com.docker.api.protos.context.v1.Contexts") {
@ -118,7 +118,7 @@ func configureContext(ctx context.Context, currentContext string, method string)
if err != nil { if err != nil {
return nil, err return nil, err
} }
ctx = store.WithContextStore(ctx, s) store.WithContextStore(s)
return ctx, nil return ctx, nil
} }

View File

@ -41,7 +41,7 @@ func testContext(t *testing.T) context.Context {
}) })
ctx := context.Background() ctx := context.Background()
ctx = config.WithDir(ctx, dir) config.WithDir(dir)
err = ioutil.WriteFile(path.Join(dir, "config.json"), []byte(`{"currentContext": "default"}`), 0644) err = ioutil.WriteFile(path.Join(dir, "config.json"), []byte(`{"currentContext": "default"}`), 0644)
assert.NilError(t, err) assert.NilError(t, err)
@ -100,7 +100,7 @@ func callStream(ctx context.Context, t *testing.T, interceptor grpc.StreamServer
}, &grpc.StreamServerInfo{ }, &grpc.StreamServerInfo{
FullMethod: "/com.docker.api.protos.context.v1.Contexts/test", FullMethod: "/com.docker.api.protos.context.v1.Contexts/test",
}, func(srv interface{}, stream grpc.ServerStream) error { }, func(srv interface{}, stream grpc.ServerStream) error {
currentContext = apicontext.CurrentContext(stream.Context()) currentContext = apicontext.Current()
return nil return nil
}) })
@ -114,7 +114,7 @@ func callUnary(ctx context.Context, t *testing.T, interceptor grpc.UnaryServerIn
resp, err := interceptor(ctx, nil, &grpc.UnaryServerInfo{ resp, err := interceptor(ctx, nil, &grpc.UnaryServerInfo{
FullMethod: "/com.docker.api.protos.context.v1.Contexts/test", FullMethod: "/com.docker.api.protos.context.v1.Contexts/test",
}, func(ctx context.Context, req interface{}) (interface{}, error) { }, func(ctx context.Context, req interface{}) (interface{}, error) {
currentContext = apicontext.CurrentContext(ctx) currentContext = apicontext.Current()
return nil, nil return nil, nil
}) })

View File

@ -37,7 +37,7 @@ func (cp *contextsProxy) SetCurrent(ctx context.Context, request *contextsv1.Set
} }
func (cp *contextsProxy) List(ctx context.Context, request *contextsv1.ListRequest) (*contextsv1.ListResponse, error) { func (cp *contextsProxy) List(ctx context.Context, request *contextsv1.ListRequest) (*contextsv1.ListResponse, error) {
s := store.ContextStore(ctx) s := store.Instance()
configFile, err := config.LoadFile(cp.configDir) configFile, err := config.LoadFile(cp.configDir)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -62,7 +62,7 @@ type proxy struct {
// New creates a new proxy server // New creates a new proxy server
func New(ctx context.Context) Proxy { func New(ctx context.Context) Proxy {
configDir := config.Dir(ctx) configDir := config.Dir()
return &proxy{ return &proxy{
configDir: configDir, configDir: configDir,
streams: map[string]*streams.Stream{}, streams: map[string]*streams.Stream{},

View File

@ -63,9 +63,9 @@ func init() {
backend.Register(backendType, backendType, service, getCloudService) backend.Register(backendType, backendType, service, getCloudService)
} }
func service(ctx context.Context) (backend.Service, error) { func service() (backend.Service, error) {
contextStore := store.ContextStore(ctx) contextStore := store.Instance()
currentContext := apicontext.CurrentContext(ctx) currentContext := apicontext.Current()
var ecsContext store.EcsContext var ecsContext store.EcsContext
if err := contextStore.GetEndpoint(currentContext, &ecsContext); err != nil { if err := contextStore.GetEndpoint(currentContext, &ecsContext); err != nil {

View File

@ -104,7 +104,7 @@ func (b *ecsAPIService) Convert(ctx context.Context, project *types.Project, opt
} }
func (b *ecsAPIService) resolveServiceImagesDigests(ctx context.Context, project *types.Project) error { func (b *ecsAPIService) resolveServiceImagesDigests(ctx context.Context, project *types.Project) error {
configFile, err := cliconfig.Load(config.Dir(ctx)) configFile, err := cliconfig.Load(config.Dir())
if err != nil { if err != nil {
return err return err
} }

View File

@ -17,8 +17,6 @@
package local package local
import ( import (
"context"
local_compose "github.com/docker/compose-cli/local/compose" local_compose "github.com/docker/compose-cli/local/compose"
"github.com/docker/docker/client" "github.com/docker/docker/client"
@ -44,7 +42,7 @@ type ecsLocalSimulation struct {
compose compose.Service compose compose.Service
} }
func service(ctx context.Context) (backend.Service, error) { func service() (backend.Service, error) {
apiClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) apiClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil { if err != nil {
return nil, err return nil, err

1
go.mod
View File

@ -54,7 +54,6 @@ require (
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.6.1 github.com/stretchr/testify v1.6.1
github.com/valyala/fasttemplate v1.2.1 // indirect github.com/valyala/fasttemplate v1.2.1 // indirect
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58 golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
google.golang.org/grpc v1.33.2 google.golang.org/grpc v1.33.2

View File

@ -19,8 +19,6 @@
package kube package kube
import ( import (
"context"
"github.com/docker/compose-cli/api/backend" "github.com/docker/compose-cli/api/backend"
"github.com/docker/compose-cli/api/cloud" "github.com/docker/compose-cli/api/cloud"
"github.com/docker/compose-cli/api/compose" "github.com/docker/compose-cli/api/compose"
@ -41,8 +39,8 @@ func init() {
backend.Register(backendType, backendType, service, cloud.NotImplementedCloudService) backend.Register(backendType, backendType, service, cloud.NotImplementedCloudService)
} }
func service(ctx context.Context) (backend.Service, error) { func service() (backend.Service, error) {
s, err := NewComposeService(ctx) s, err := NewComposeService()
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -42,9 +42,9 @@ type composeService struct {
} }
// NewComposeService create a kubernetes implementation of the compose.Service API // NewComposeService create a kubernetes implementation of the compose.Service API
func NewComposeService(ctx context.Context) (compose.Service, error) { func NewComposeService() (compose.Service, error) {
contextStore := store.ContextStore(ctx) contextStore := store.Instance()
currentContext := apicontext.CurrentContext(ctx) currentContext := apicontext.Current()
var kubeContext store.KubeContext var kubeContext store.KubeContext
if err := contextStore.GetEndpoint(currentContext, &kubeContext); err != nil { if err := contextStore.GetEndpoint(currentContext, &kubeContext); err != nil {

View File

@ -17,22 +17,15 @@
package local package local
import ( import (
"context" "github.com/docker/docker/client"
"github.com/docker/cli/cli/command"
"github.com/docker/compose-cli/api/backend" "github.com/docker/compose-cli/api/backend"
"github.com/docker/compose-cli/api/cloud"
"github.com/docker/compose-cli/api/compose" "github.com/docker/compose-cli/api/compose"
apiconfig "github.com/docker/compose-cli/api/config"
"github.com/docker/compose-cli/api/containers" "github.com/docker/compose-cli/api/containers"
apicontext "github.com/docker/compose-cli/api/context"
"github.com/docker/compose-cli/api/resources" "github.com/docker/compose-cli/api/resources"
"github.com/docker/compose-cli/api/secrets" "github.com/docker/compose-cli/api/secrets"
"github.com/docker/compose-cli/api/volumes" "github.com/docker/compose-cli/api/volumes"
local_compose "github.com/docker/compose-cli/local/compose" local_compose "github.com/docker/compose-cli/local/compose"
cliconfig "github.com/docker/cli/cli/config"
) )
type local struct { type local struct {
@ -41,27 +34,13 @@ type local struct {
composeService compose.Service composeService compose.Service
} }
func init() { // NewService build a backend for "local" context, using Docker API client
backend.Register("local", "local", service, cloud.NotImplementedCloudService) func NewService(apiClient client.APIClient) backend.Service {
}
func service(ctx context.Context) (backend.Service, error) {
options := apicontext.CliOptions(ctx)
config := apiconfig.Dir(ctx)
configFile, err := cliconfig.Load(config)
if err != nil {
return nil, err
}
apiClient, err := command.NewAPIClientFromFlags(&options, configFile)
if err != nil {
return nil, err
}
return &local{ return &local{
containerService: &containerService{apiClient}, containerService: &containerService{apiClient},
volumeService: &volumeService{apiClient}, volumeService: &volumeService{apiClient},
composeService: local_compose.NewComposeService(apiClient), composeService: local_compose.NewComposeService(apiClient),
}, nil }
} }
func (s *local) ContainerService() containers.Service { func (s *local) ContainerService() containers.Service {

View File

@ -37,7 +37,7 @@ import (
) )
func (s *composeService) Pull(ctx context.Context, project *types.Project) error { func (s *composeService) Pull(ctx context.Context, project *types.Project) error {
configFile, err := cliconfig.Load(config.Dir(ctx)) configFile, err := cliconfig.Load(config.Dir())
if err != nil { if err != nil {
return err return err
} }

View File

@ -39,7 +39,7 @@ import (
) )
func (s *composeService) Push(ctx context.Context, project *types.Project, options compose.PushOptions) error { func (s *composeService) Push(ctx context.Context, project *types.Project, options compose.PushOptions) error {
configFile, err := cliconfig.Load(config.Dir(ctx)) configFile, err := cliconfig.Load(config.Dir())
if err != nil { if err != nil {
return err return err
} }