2017-06-26 23:46:34 +02:00
|
|
|
// Copyright 2016-2017, Pulumi Corporation. All rights reserved.
|
Introduce an interface to read config
This change adds an engine gRPC interface, and associated implementation,
so that plugins may do interesting things that require "phoning home".
Previously, the engine would fire up plugins and talk to them directly,
but there was no way for a plugin to ask the engine to do anything.
The motivation here is so that plugins can read evaluator state, such
as config information, but this change also allows richer logging
functionality than previously possible. We will still auto-log any
stdout/stderr writes; however, explicit errors, warnings, informational,
and even debug messages may be written over the Log API.
2017-06-21 04:45:07 +02:00
|
|
|
|
|
|
|
package plugin
|
|
|
|
|
|
|
|
import (
|
2017-09-09 16:37:10 +02:00
|
|
|
"fmt"
|
Introduce an interface to read config
This change adds an engine gRPC interface, and associated implementation,
so that plugins may do interesting things that require "phoning home".
Previously, the engine would fire up plugins and talk to them directly,
but there was no way for a plugin to ask the engine to do anything.
The motivation here is so that plugins can read evaluator state, such
as config information, but this change also allows richer logging
functionality than previously possible. We will still auto-log any
stdout/stderr writes; however, explicit errors, warnings, informational,
and even debug messages may be written over the Log API.
2017-06-21 04:45:07 +02:00
|
|
|
|
|
|
|
pbempty "github.com/golang/protobuf/ptypes/empty"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"golang.org/x/net/context"
|
|
|
|
"google.golang.org/grpc"
|
|
|
|
|
2017-09-22 04:18:21 +02:00
|
|
|
"github.com/pulumi/pulumi/pkg/diag"
|
|
|
|
"github.com/pulumi/pulumi/pkg/util/rpcutil"
|
|
|
|
lumirpc "github.com/pulumi/pulumi/sdk/proto/go"
|
Introduce an interface to read config
This change adds an engine gRPC interface, and associated implementation,
so that plugins may do interesting things that require "phoning home".
Previously, the engine would fire up plugins and talk to them directly,
but there was no way for a plugin to ask the engine to do anything.
The motivation here is so that plugins can read evaluator state, such
as config information, but this change also allows richer logging
functionality than previously possible. We will still auto-log any
stdout/stderr writes; however, explicit errors, warnings, informational,
and even debug messages may be written over the Log API.
2017-06-21 04:45:07 +02:00
|
|
|
)
|
|
|
|
|
2017-06-21 19:31:06 +02:00
|
|
|
// hostServer is the server side of the host RPC machinery.
|
|
|
|
type hostServer struct {
|
Introduce an interface to read config
This change adds an engine gRPC interface, and associated implementation,
so that plugins may do interesting things that require "phoning home".
Previously, the engine would fire up plugins and talk to them directly,
but there was no way for a plugin to ask the engine to do anything.
The motivation here is so that plugins can read evaluator state, such
as config information, but this change also allows richer logging
functionality than previously possible. We will still auto-log any
stdout/stderr writes; however, explicit errors, warnings, informational,
and even debug messages may be written over the Log API.
2017-06-21 04:45:07 +02:00
|
|
|
host Host // the host for this RPC server.
|
|
|
|
ctx *Context // the associated plugin context.
|
2017-09-09 16:37:10 +02:00
|
|
|
addr string // the address the host is listening on.
|
Introduce an interface to read config
This change adds an engine gRPC interface, and associated implementation,
so that plugins may do interesting things that require "phoning home".
Previously, the engine would fire up plugins and talk to them directly,
but there was no way for a plugin to ask the engine to do anything.
The motivation here is so that plugins can read evaluator state, such
as config information, but this change also allows richer logging
functionality than previously possible. We will still auto-log any
stdout/stderr writes; however, explicit errors, warnings, informational,
and even debug messages may be written over the Log API.
2017-06-21 04:45:07 +02:00
|
|
|
cancel chan bool // a channel that can cancel the server.
|
|
|
|
done chan error // a channel that resolves when the server completes.
|
|
|
|
}
|
|
|
|
|
2017-06-21 19:31:06 +02:00
|
|
|
// newHostServer creates a new host server wired up to the given host and context.
|
|
|
|
func newHostServer(host Host, ctx *Context) (*hostServer, error) {
|
Introduce an interface to read config
This change adds an engine gRPC interface, and associated implementation,
so that plugins may do interesting things that require "phoning home".
Previously, the engine would fire up plugins and talk to them directly,
but there was no way for a plugin to ask the engine to do anything.
The motivation here is so that plugins can read evaluator state, such
as config information, but this change also allows richer logging
functionality than previously possible. We will still auto-log any
stdout/stderr writes; however, explicit errors, warnings, informational,
and even debug messages may be written over the Log API.
2017-06-21 04:45:07 +02:00
|
|
|
// New up an engine RPC server.
|
2017-06-21 19:31:06 +02:00
|
|
|
engine := &hostServer{
|
Introduce an interface to read config
This change adds an engine gRPC interface, and associated implementation,
so that plugins may do interesting things that require "phoning home".
Previously, the engine would fire up plugins and talk to them directly,
but there was no way for a plugin to ask the engine to do anything.
The motivation here is so that plugins can read evaluator state, such
as config information, but this change also allows richer logging
functionality than previously possible. We will still auto-log any
stdout/stderr writes; however, explicit errors, warnings, informational,
and even debug messages may be written over the Log API.
2017-06-21 04:45:07 +02:00
|
|
|
host: host,
|
|
|
|
ctx: ctx,
|
|
|
|
cancel: make(chan bool),
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fire up a gRPC server and start listening for incomings.
|
|
|
|
port, done, err := rpcutil.Serve(0, engine.cancel, []func(*grpc.Server) error{
|
|
|
|
func(srv *grpc.Server) error {
|
|
|
|
lumirpc.RegisterEngineServer(srv, engine)
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2017-09-21 19:56:45 +02:00
|
|
|
engine.addr = fmt.Sprintf("127.0.0.1:%d", port)
|
Introduce an interface to read config
This change adds an engine gRPC interface, and associated implementation,
so that plugins may do interesting things that require "phoning home".
Previously, the engine would fire up plugins and talk to them directly,
but there was no way for a plugin to ask the engine to do anything.
The motivation here is so that plugins can read evaluator state, such
as config information, but this change also allows richer logging
functionality than previously possible. We will still auto-log any
stdout/stderr writes; however, explicit errors, warnings, informational,
and even debug messages may be written over the Log API.
2017-06-21 04:45:07 +02:00
|
|
|
engine.done = done
|
|
|
|
|
|
|
|
return engine, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Address returns the address at which the engine's RPC server may be reached.
|
2017-06-21 19:31:06 +02:00
|
|
|
func (eng *hostServer) Address() string {
|
2017-09-09 16:37:10 +02:00
|
|
|
return eng.addr
|
Introduce an interface to read config
This change adds an engine gRPC interface, and associated implementation,
so that plugins may do interesting things that require "phoning home".
Previously, the engine would fire up plugins and talk to them directly,
but there was no way for a plugin to ask the engine to do anything.
The motivation here is so that plugins can read evaluator state, such
as config information, but this change also allows richer logging
functionality than previously possible. We will still auto-log any
stdout/stderr writes; however, explicit errors, warnings, informational,
and even debug messages may be written over the Log API.
2017-06-21 04:45:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Cancel signals that the engine should be terminated, awaits its termination, and returns any errors that result.
|
2017-06-21 19:31:06 +02:00
|
|
|
func (eng *hostServer) Cancel() error {
|
Introduce an interface to read config
This change adds an engine gRPC interface, and associated implementation,
so that plugins may do interesting things that require "phoning home".
Previously, the engine would fire up plugins and talk to them directly,
but there was no way for a plugin to ask the engine to do anything.
The motivation here is so that plugins can read evaluator state, such
as config information, but this change also allows richer logging
functionality than previously possible. We will still auto-log any
stdout/stderr writes; however, explicit errors, warnings, informational,
and even debug messages may be written over the Log API.
2017-06-21 04:45:07 +02:00
|
|
|
eng.cancel <- true
|
|
|
|
return <-eng.done
|
|
|
|
}
|
|
|
|
|
|
|
|
// Log logs a global message in the engine, including errors and warnings.
|
2017-06-21 19:31:06 +02:00
|
|
|
func (eng *hostServer) Log(ctx context.Context,
|
Introduce an interface to read config
This change adds an engine gRPC interface, and associated implementation,
so that plugins may do interesting things that require "phoning home".
Previously, the engine would fire up plugins and talk to them directly,
but there was no way for a plugin to ask the engine to do anything.
The motivation here is so that plugins can read evaluator state, such
as config information, but this change also allows richer logging
functionality than previously possible. We will still auto-log any
stdout/stderr writes; however, explicit errors, warnings, informational,
and even debug messages may be written over the Log API.
2017-06-21 04:45:07 +02:00
|
|
|
req *lumirpc.LogRequest) (*pbempty.Empty, error) {
|
|
|
|
var sev diag.Severity
|
|
|
|
switch req.Severity {
|
|
|
|
case lumirpc.LogSeverity_DEBUG:
|
|
|
|
sev = diag.Debug
|
|
|
|
case lumirpc.LogSeverity_INFO:
|
|
|
|
sev = diag.Info
|
|
|
|
case lumirpc.LogSeverity_WARNING:
|
|
|
|
sev = diag.Warning
|
|
|
|
case lumirpc.LogSeverity_ERROR:
|
|
|
|
sev = diag.Error
|
|
|
|
default:
|
|
|
|
return nil, errors.Errorf("Unrecognized logging severity: %v", req.Severity)
|
|
|
|
}
|
|
|
|
eng.host.Log(sev, req.Message)
|
|
|
|
return &pbempty.Empty{}, nil
|
|
|
|
}
|