Пример #1
0
func (h *transportHandle) ServiceGenerator() ServiceGenerator {
	if !h.Running.Load() {
		panic(fmt.Sprintf("handle for plugin %q has already been closed", h.name))
	}

	if _, hasFeature := h.Features[api.FeatureServiceGenerator]; !hasFeature {
		return nil
	}

	return &serviceGenerator{
		handle:  h,
		Running: h.Running,
		ServiceGenerator: api.NewServiceGeneratorClient(multiplex.NewClient(
			"ServiceGenerator",
			envelope.NewClient(_proto, h.Transport),
		)),
	}
}
Пример #2
0
func fakeEnvelopeClient() (envelope.Client, func()) {
	in, out, done := fakeStreams()
	return envelope.NewClient(_proto, frame.NewClient(in, out)), done
}
Пример #3
0
// NewTransportHandle builds a new Handle which speaks to the given transport.
//
// If the transport is an io.Closer, it will be closed when the handle is closed.
func NewTransportHandle(name string, t envelope.Transport) (Handle, error) {
	client := api.NewPluginClient(multiplex.NewClient(
		"Plugin",
		envelope.NewClient(_proto, t),
	))

	handshake, err := client.Handshake(&api.HandshakeRequest{})
	if err != nil {
		return nil, errHandshakeFailed{Name: name, Reason: err}
	}

	if handshake.Name != name {
		return nil, errHandshakeFailed{
			Name:   name,
			Reason: errNameMismatch{Want: name, Got: handshake.Name},
		}
	}

	if handshake.APIVersion != api.APIVersion {
		return nil, errHandshakeFailed{
			Name:   name,
			Reason: errAPIVersionMismatch{Want: api.APIVersion, Got: handshake.APIVersion},
		}
	}

	// If we got here, the API version matches so the plugin must have
	// provided the Version
	if handshake.LibraryVersion == nil {
		return nil, errHandshakeFailed{
			Name:   name,
			Reason: errVersionIsRequired,
		}
	}

	version, err := semver.Parse(*handshake.LibraryVersion)
	if err != nil {
		return nil, errHandshakeFailed{Name: name, Reason: err}
	}

	if !compatRange.Contains(version) {
		return nil, errHandshakeFailed{
			Name: name,
			Reason: errVersionMismatch{
				Want: compatRange,
				Got:  *handshake.LibraryVersion,
			},
		}
	}

	features := make(map[api.Feature]struct{}, len(handshake.Features))
	for _, feature := range handshake.Features {
		features[feature] = struct{}{}
	}

	return &transportHandle{
		name:      name,
		Transport: t,
		Client:    client,
		Running:   atomic.NewBool(true),
		Features:  features,
	}, nil
}