blob: 7336f9af239c1c5787c0230a013e32126222f1b4 [file] [log] [blame]
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package rpcapi
import (
"context"
"sync"
"github.com/hashicorp/terraform/internal/rpcapi/terraform1/setup"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
// setupServer is an implementation of the "Setup" service defined in our
// terraform1 package.
//
// This service is here mainly to offer the "Handshake" function, which clients
// must call to negotiate access to any other services. This is really just
// an adapter around a handshake function implemented on [corePlugin].
type setupServer struct {
setup.UnimplementedSetupServer
// initOthers is the callback used to perform the capability negotiation
// step and initialize all of the other API services based on what was
// negotiated.
initOthers func(context.Context, *setup.Handshake_Request, *stopper) (*setup.ServerCapabilities, error)
// stopper is used to track and stop long-running operations when the Stop
// RPC is called.
stopper *stopper
mu sync.Mutex
}
func newSetupServer(initOthers func(context.Context, *setup.Handshake_Request, *stopper) (*setup.ServerCapabilities, error)) setup.SetupServer {
return &setupServer{
initOthers: initOthers,
stopper: newStopper(),
}
}
func (s *setupServer) Handshake(ctx context.Context, req *setup.Handshake_Request) (*setup.Handshake_Response, error) {
s.mu.Lock()
defer s.mu.Unlock()
if s.initOthers == nil {
return nil, status.Error(codes.FailedPrecondition, "handshake already completed")
}
var serverCaps *setup.ServerCapabilities
var err error
{
ctx, span := tracer.Start(ctx, "initialize RPC services")
serverCaps, err = s.initOthers(ctx, req, s.stopper)
span.End()
}
s.initOthers = nil // cannot handshake again
if err != nil {
return nil, err
}
return &setup.Handshake_Response{
Capabilities: serverCaps,
}, nil
}
func (s *setupServer) Stop(ctx context.Context, req *setup.Stop_Request) (*setup.Stop_Response, error) {
s.mu.Lock()
defer s.mu.Unlock()
s.stopper.stop()
return &setup.Stop_Response{}, nil
}