| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 | package cmdimport (	"context"	"net"	"github.com/pkg/errors"	"github.com/sirupsen/logrus"	cliv1 "github.com/docker/api/cli/v1"	containersv1 "github.com/docker/api/containers/v1"	"github.com/docker/api/context/store"	"github.com/docker/api/server"	"github.com/docker/api/server/proxy"	"github.com/spf13/cobra")type serveOpts struct {	address string}// ServeCommand returns the command to serve the APIfunc ServeCommand() *cobra.Command {	var opts serveOpts	cmd := &cobra.Command{		Use:   "serve",		Short: "Start an api server",		RunE: func(cmd *cobra.Command, args []string) error {			return runServe(cmd.Context(), opts)		},	}	cmd.Flags().StringVar(&opts.address, "address", "", "The address to listen to")	return cmd}func runServe(ctx context.Context, opts serveOpts) error {	s := server.New()	listener, err := net.Listen("unix", opts.address)	if err != nil {		return errors.Wrap(err, "listen unix socket")	}	// nolint	defer listener.Close()	p := proxy.NewContainerAPI()	containersv1.RegisterContainersServer(s, p)	cliv1.RegisterCliServer(s, &cliServer{		ctx,	})	go func() {		<-ctx.Done()		logrus.Info("stopping server")		s.Stop()	}()	logrus.WithField("address", opts.address).Info("serving daemon API")	// start the GRPC server to serve on the listener	return s.Serve(listener)}type cliServer struct {	ctx context.Context}func (cs *cliServer) Contexts(ctx context.Context, request *cliv1.ContextsRequest) (*cliv1.ContextsResponse, error) {	s, err := store.New()	if err != nil {		logrus.Error(err)		return &cliv1.ContextsResponse{}, err	}	contexts, err := s.List()	if err != nil {		logrus.Error(err)		return &cliv1.ContextsResponse{}, err	}	result := &cliv1.ContextsResponse{}	for _, c := range contexts {		result.Contexts = append(result.Contexts, &cliv1.Context{			Name:        c.Name,			ContextType: c.Metadata.Type,		})	}	return result, nil}
 |