mirror of
https://github.com/docker/compose.git
synced 2025-07-22 21:24:38 +02:00
Change the current context of the client on each request
* the interceptor takes the current context from the metadat * each handler needs to call `client.SetContext()` before using the sevices
This commit is contained in:
parent
40a3a20f78
commit
9ea91791b4
@ -21,7 +21,7 @@ var PsCommand = cobra.Command{
|
|||||||
return errors.Wrap(err, "cannot connect to backend")
|
return errors.Wrap(err, "cannot connect to backend")
|
||||||
}
|
}
|
||||||
|
|
||||||
containers, err := c.ContainerService(ctx).List(ctx)
|
containers, err := c.ContainerService().List(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "fetch containers")
|
return errors.Wrap(err, "fetch containers")
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ func runServe(ctx context.Context, opts serveOpts) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
p := proxy.NewContainerApi(c.ContainerService(ctx))
|
p := proxy.NewContainerApi(c)
|
||||||
|
|
||||||
containersv1.RegisterContainersServer(s, p)
|
containersv1.RegisterContainersServer(s, p)
|
||||||
cliv1.RegisterCliServer(s, &cliServer{
|
cliv1.RegisterCliServer(s, &cliServer{
|
||||||
|
14
cli/main.go
14
cli/main.go
@ -119,7 +119,19 @@ func main() {
|
|||||||
ctx, cancel := util.NewSigContext()
|
ctx, cancel := util.NewSigContext()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
ctx, err := apicontext.WithCurrentContext(ctx, opts.Config, opts.Context)
|
config, err := apicontext.LoadConfigFile(opts.Config, "config.json")
|
||||||
|
if err != nil {
|
||||||
|
logrus.Fatal("unable ot find configuration")
|
||||||
|
}
|
||||||
|
currentContext := opts.Context
|
||||||
|
if currentContext == "" {
|
||||||
|
currentContext = config.CurrentContext
|
||||||
|
}
|
||||||
|
if currentContext == "" {
|
||||||
|
currentContext = "default"
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = apicontext.WithCurrentContext(ctx, opts.Context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,21 @@ type Client struct {
|
|||||||
cc containers.ContainerService
|
cc containers.ContainerService
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) ContainerService(ctx context.Context) containers.ContainerService {
|
func (c *Client) SetContext(ctx context.Context, contextType string) error {
|
||||||
|
b, err := backend.Get(ctx, contextType)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ba, ok := b.(containers.ContainerService)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("unknown context type")
|
||||||
|
}
|
||||||
|
|
||||||
|
c.cc = ba
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) ContainerService() containers.ContainerService {
|
||||||
return c.cc
|
return c.cc
|
||||||
}
|
}
|
||||||
|
@ -3,23 +3,29 @@ package proxy
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/docker/api/containers"
|
"github.com/docker/api/client"
|
||||||
v1 "github.com/docker/api/containers/v1"
|
v1 "github.com/docker/api/containers/v1"
|
||||||
|
apicontext "github.com/docker/api/context"
|
||||||
"github.com/golang/protobuf/ptypes/empty"
|
"github.com/golang/protobuf/ptypes/empty"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewContainerApi(client containers.ContainerService) v1.ContainersServer {
|
func NewContainerApi(client *client.Client) v1.ContainersServer {
|
||||||
return &proxyContainerApi{
|
return &proxyContainerApi{
|
||||||
client: client,
|
client: client,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type proxyContainerApi struct {
|
type proxyContainerApi struct {
|
||||||
client containers.ContainerService
|
client *client.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *proxyContainerApi) List(ctx context.Context, _ *v1.ListRequest) (*v1.ListResponse, error) {
|
func (p *proxyContainerApi) List(ctx context.Context, _ *v1.ListRequest) (*v1.ListResponse, error) {
|
||||||
c, err := p.client.List(ctx)
|
currentContext := apicontext.CurrentContext(ctx)
|
||||||
|
if err := p.client.SetContext(ctx, currentContext); err != nil {
|
||||||
|
return &v1.ListResponse{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
c, err := p.client.ContainerService().List(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &v1.ListResponse{}, nil
|
return &v1.ListResponse{}, nil
|
||||||
}
|
}
|
||||||
|
@ -3,29 +3,15 @@ package context
|
|||||||
import (
|
import (
|
||||||
gocontext "context"
|
gocontext "context"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const KEY = "context_key"
|
||||||
|
|
||||||
type currentContextKey struct{}
|
type currentContextKey struct{}
|
||||||
|
|
||||||
func WithCurrentContext(ctx gocontext.Context, configName string, contextName string) (context.Context, error) {
|
func WithCurrentContext(ctx gocontext.Context, contextName string) context.Context {
|
||||||
config, err := LoadConfigFile(configName, "config.json")
|
return context.WithValue(ctx, currentContextKey{}, contextName)
|
||||||
if err != nil {
|
|
||||||
return ctx, err
|
|
||||||
}
|
|
||||||
|
|
||||||
currentContext := contextName
|
|
||||||
if currentContext == "" {
|
|
||||||
currentContext = config.CurrentContext
|
|
||||||
}
|
|
||||||
if currentContext == "" {
|
|
||||||
currentContext = "default"
|
|
||||||
}
|
|
||||||
|
|
||||||
logrus.Debugf("Current context %q", currentContext)
|
|
||||||
|
|
||||||
return context.WithValue(ctx, currentContextKey{}, currentContext), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CurrentContext returns the current context name
|
// CurrentContext returns the current context name
|
||||||
|
@ -29,17 +29,23 @@ package server
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
apicontext "github.com/docker/api/context"
|
||||||
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
|
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/health"
|
"google.golang.org/grpc/health"
|
||||||
"google.golang.org/grpc/health/grpc_health_v1"
|
"google.golang.org/grpc/health/grpc_health_v1"
|
||||||
|
"google.golang.org/grpc/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
// New returns a new GRPC server.
|
// New returns a new GRPC server.
|
||||||
func New() *grpc.Server {
|
func New() *grpc.Server {
|
||||||
s := grpc.NewServer(
|
s := grpc.NewServer(
|
||||||
grpc.UnaryInterceptor(unary),
|
grpc.ChainUnaryInterceptor(
|
||||||
|
unaryMeta,
|
||||||
|
unary,
|
||||||
|
),
|
||||||
grpc.StreamInterceptor(stream),
|
grpc.StreamInterceptor(stream),
|
||||||
)
|
)
|
||||||
hs := health.NewServer()
|
hs := health.NewServer()
|
||||||
@ -54,3 +60,16 @@ func unary(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, han
|
|||||||
func stream(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
|
func stream(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
|
||||||
return grpc_prometheus.StreamServerInterceptor(srv, ss, info, handler)
|
return grpc_prometheus.StreamServerInterceptor(srv, ss, info, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func unaryMeta(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||||
|
md, ok := metadata.FromIncomingContext(ctx)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("missing metadata")
|
||||||
|
}
|
||||||
|
key := md[apicontext.KEY]
|
||||||
|
if len(key) == 1 {
|
||||||
|
ctx = apicontext.WithCurrentContext(ctx, key[0])
|
||||||
|
}
|
||||||
|
m, err := handler(ctx, req)
|
||||||
|
return m, err
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user