Beispiel #1
0
func (s *server) Serve() (retErr error) {
	start := make(chan struct{})
	var listener net.Listener
	var spec string
	var err error
	var addr string
	switch s.protocol {
	case protocolTCP:
		listener, spec, err = newTCPListener(s.volumeDriverName, s.groupOrAddress, start)
		addr = s.groupOrAddress
	case protocolUnix:
		listener, spec, err = newUnixListener(s.volumeDriverName, s.groupOrAddress, start)
		addr = s.volumeDriverName
	default:
		return fmt.Errorf("unknown protocol: %d", s.protocol)
	}
	if err != nil {
		return err
	}
	grpcPort := s.opts.GRPCPort
	if grpcPort == 0 {
		grpcPort = DefaultGRPCPort
	}
	return protoserver.Serve(
		grpcPort,
		func(grpcServer *grpc.Server) {
			RegisterAPIServer(grpcServer, s.apiServer)
		},
		protoserver.ServeOptions{
			DebugPort: s.opts.GRPCDebugPort,
			HTTPRegisterFunc: func(ctx context.Context, mux *runtime.ServeMux, clientConn *grpc.ClientConn) error {
				return RegisterAPIHandler(ctx, mux, clientConn)
			},
			HTTPAddress:  addr,
			HTTPListener: listener,
			ServeMuxOptions: []runtime.ServeMuxOption{
				runtime.WithForwardResponseOption(
					func(_ context.Context, responseWriter http.ResponseWriter, _ proto.Message) error {
						responseWriter.Header().Set("Content-Type", "application/vnd.docker.plugins.v1.1+json")
						return nil
					},
				),
			},
			HTTPBeforeShutdown: func() { _ = s.cleanup() },
			HTTPShutdownInitiated: func() {
				if spec != "" {
					_ = os.Remove(spec)
				}
			},
			HTTPStart: start,
		},
	)
}
func TestIntegration(t *testing.T) {
	if testing.Short() {
		t.Skip()
		return
	}

	go func() {
		if err := server.Run(); err != nil {
			t.Errorf("server.Run() failed with %v; want success", err)
			return
		}
	}()
	go func() {
		if err := Run(":8080"); err != nil {
			t.Errorf("gw.Run() failed with %v; want success", err)
			return
		}
	}()

	time.Sleep(100 * time.Millisecond)
	testEcho(t, 8080, "application/json")
	testEchoBody(t)
	testABECreate(t)
	testABECreateBody(t)
	testABEBulkCreate(t)
	testABELookup(t)
	testABELookupNotFound(t)
	testABEList(t)
	testAdditionalBindings(t)

	go func() {
		if err := Run(
			":8081",
			runtime.WithForwardResponseOption(
				func(_ context.Context, w http.ResponseWriter, _ proto.Message) error {
					w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1.1+json")
					return nil
				},
			),
		); err != nil {
			t.Errorf("gw.Run() failed with %v; want success", err)
			return
		}
	}()

	time.Sleep(100 * time.Millisecond)
	testEcho(t, 8081, "application/vnd.docker.plugins.v1.1+json")
}
Beispiel #3
0
func (s *server) Serve() (retErr error) {
	var listener net.Listener
	var spec string
	var err error
	var addr string
	switch s.protocol {
	case protocolTCP:
		listener, spec, err = newTCPListener(s.driverName, s.groupOrAddress)
		addr = s.groupOrAddress
	case protocolUnix:
		listener, spec, err = newUnixListener(s.driverName, s.groupOrAddress)
		addr = s.driverName
	default:
		return fmt.Errorf("unknown protocol: %d", s.protocol)
	}
	if err != nil {
		return err
	}
	grpcPort := s.opts.GRPCPort
	if grpcPort == 0 {
		grpcPort = DefaultGRPCPort
	}

	grpcServer := grpc.NewServer(grpc.MaxConcurrentStreams(math.MaxUint32))
	RegisterAPIServer(grpcServer, s.apiServer)
	s.registerFunc(grpcServer)
	grpcListener, err := net.Listen("tcp", fmt.Sprintf(":%d", grpcPort))
	if err != nil {
		return err
	}
	grpcErrC := make(chan error)
	httpErrC := make(chan error)
	errCCount := 1
	go func() { grpcErrC <- grpcServer.Serve(grpcListener) }()
	time.Sleep(1 * time.Second)
	ctx, cancel := context.WithCancel(context.Background())
	mux := runtime.NewServeMux(
		runtime.WithForwardResponseOption(
			func(_ context.Context, responseWriter http.ResponseWriter, _ proto.Message) error {
				responseWriter.Header().Set("Content-Type", "application/vnd.docker.plugins.v1.1+json")
				return nil
			},
		),
	)
	conn, err := grpc.Dial(fmt.Sprintf("0.0.0.0:%d", grpcPort), grpc.WithInsecure())
	if err != nil {
		glog.Flush()
		cancel()
		return err
	}
	go func() {
		<-ctx.Done()
		_ = conn.Close()
	}()
	if err := RegisterAPIHandler(ctx, mux, conn); err != nil {
		_ = conn.Close()
		glog.Flush()
		cancel()
		return err
	}
	if err := s.httpRegisterFunc(ctx, mux, conn); err != nil {
		_ = conn.Close()
		glog.Flush()
		cancel()
		return err
	}
	httpServer := &http.Server{
		Addr:    addr,
		Handler: mux,
	}
	gracefulServer := &graceful.Server{
		Timeout: 1 * time.Second,
		ShutdownInitiated: func() {
			glog.Flush()
			cancel()
			if spec != "" {
				_ = os.Remove(spec)
			}
		},
		Server: httpServer,
	}
	errCCount++
	go func() {
		httpErrC <- gracefulServer.Serve(listener)
	}()
	var errs []error
	grpcStopped := false
	for i := 0; i < errCCount; i++ {
		select {
		case grpcErr := <-grpcErrC:
			if grpcErr != nil {
				errs = append(errs, fmt.Errorf("grpc error: %s", grpcErr.Error()))
			}
			grpcStopped = true
		case httpErr := <-httpErrC:
			if httpErr != nil {
				errs = append(errs, fmt.Errorf("http error: %s", httpErr.Error()))
			}
			if !grpcStopped {
				grpcServer.Stop()
				_ = listener.Close()
				grpcStopped = true
			}
		}
	}
	if len(errs) > 0 {
		return fmt.Errorf("%v", errs)
	}
	return nil
}