Commit graph

1514 commits

Author SHA1 Message Date
joeduffy 9f160a7f91 Configure providers at well-defined points
As explained in pulumi/pulumi-fabric#293, we were a little ad-hoc in
how configuration was "applied" to resource providers.

In fact, config wasn't ever communicated directly to providers; instead,
the resource providers would simply ask the engine to read random heap
locations (via tokens). Now that we're on a plan where configuration gets
handed to the program at startup, and that's that, and where generally
speaking resource providers never communicate directly with the language
runtime, we need to take a different approach.

As such, the resource provider interface now offers a Configure RPC
method that the resource planning engine will invoke at the right
times with the right subset of configuration variables filtered to
just that provider's package.  This fixes pulumi/pulumi#293.
2017-09-04 11:35:21 -07:00
joeduffy 375fc399c3 Eliminate yarn version printing
Apparently yarn requires a TTY to print the version.  (No idea why.)
This wasn't an essential change, so I'll just nix it for now.
2017-09-04 11:35:21 -07:00
joeduffy 70d0fac1c0 Simplify resource provider RPC interface
This change simplifies the provider RPC interface slightly:

1) Eliminate Get.  We really don't need it anymore.  There are
   several possibly-interesting scenarios down the road that may
   demand it, but when we get there, we can consider how best to
   bring this back.  Furthermore, the old-style Get remains mostly
   incompatible with Terraform anyway.

2) Pass URNs, not type tokens, across the RPC boundary.  This gives
   the provider access to more interesting information: the type,
   still, but also the name (which is no longer an object property).
2017-09-04 11:35:21 -07:00
joeduffy 8f742e1cd0 Run yarn install before integration tests 2017-09-04 11:35:21 -07:00
joeduffy 7c848bfff4 Add config to the basic/minimal test 2017-09-04 11:35:21 -07:00
joeduffy 590e9e539b Rename Lumi.yaml to Pulumi.yaml
And also eliminate lots of accumulated cruft around "packfiles", etc.
in the workspace code.
2017-09-04 11:35:21 -07:00
joeduffy 1e00bc7db4 Fix up .travis.yml to use Node.js SDK rather than LumiJS 2017-09-04 11:35:21 -07:00
joeduffy 1df1b6d572 Get integration tests passing
This makes a few tweaks to get the integration tests passing:

* Add `runtime: nodejs` to the minimal example's `Lumi.yaml` file.

* Remove usage of `@lumi/lumirt { printf }` and just use `console.log`.

* Remove calls to `lumijs` in the integration test framework and
  the minimal example's package.json.  Instead, we just run
  `yarn run build`, which itself internally just invokes `tsc`.

* Add package validation logic and eliminate the pkg/compiler/metadata
  library, in favor of the simpler code in pkg/engine.

* Simplify the Node.js langhost plugin CLI, and simply take an
  argument rather than requiring required and optional --flags.

* Use a default path of "." if the program path isn't provided.  This
  is a legal scenario if you've passed a pwd and just want to load
  the package's default module ("./index.js" or whatever main says).

* Add an executable script, lumi-langhost-nodejs, that fires up the
  `bin/cmd/langhost/index.js` file to serve the Node.js language plugin.
2017-09-04 11:35:21 -07:00
joeduffy 9599ea2e55 Get planning engine unit tests running again
We now build and run cleanly locally (for unit tests).  The
integration tests are still on the floor at the moment.
2017-09-04 11:35:21 -07:00
joeduffy f189c40f35 Wire up Lumi to the new runtime strategy
🔥 🔥 🔥  🔥 🔥 🔥

Getting closer on #311.
2017-09-04 11:35:21 -07:00
joeduffy dc3bf4bffb Regenerate Protobufs 2017-09-04 11:35:20 -07:00
joeduffy 9ffbb8d755 Eliminate lumi, lumijs, and lumirt packages
This change gets rid of the old-style @pulumi/lumi, @pulumi/lumijs,
and @pulumi/lumirt packages.  Instead, we have the new Node.js SDK.
2017-09-04 11:35:20 -07:00
joeduffy c6c74976ec Encapsulate Property creation
This changes Resource's constructor slightly, to take a map of
PropertyValues, rather than Properties.  This simplifies the interface,
lets us hide the creation of Properties (meaning we can also hide the
resolution capabilities entirely), and also avoids mistakes like
accidentally passing values and/or other resource properties directly.
2017-09-04 11:35:20 -07:00
joeduffy 2957314c18 Fix test case typos 2017-09-04 11:35:20 -07:00
joeduffy 2657035e5e Add the notion of "dry runs" (plans)
This change introduces the notion of a "dry run" into the property
serialization logic, since this controls whether we wait for dependent
linked property values to arrive or not.  It also changes the test
harness to run all tests both ways: once in planning mode (when properties
will show up as "unknown" and the second time in deployment mode (when
properties will have settled to their final values).
2017-09-04 11:35:20 -07:00
joeduffy 183fb328e4 Add a test case for linked properties 2017-09-04 11:35:20 -07:00
joeduffy 42ec6bcaf4 Add a 10x complex property test 2017-09-04 11:35:20 -07:00
joeduffy 695b1ba141 Test input/output properties
This adds a test case for the simple input/output property cases.

In particular, it neither covers "linked" properties resulting from
dataflow nor promise properties resulting from I/O operations.  But
it does test many basic JSON input and output cases.

Also fixes a few things:

* Property's `resolver` property must be set to undefined to prevent
  multiple resolutions.  (This is still in flux and I'm sure will
  change shape before being settled.)

* Use `this.link`, not `this.linked`, to tell if a property is linked.

* Push all property initialization down into the
  `runtime.registerResource` routine.  In practice, the old pattern
  didn't really work, since `this` is inaccessible prior to `super(..)`.

* Eliminate our custom marshaling and unmarshaling routines in favor
  of the nifty built-in gRPC ones.
2017-09-04 11:35:20 -07:00
joeduffy 4581469d80 Test more resource creation
This adds some additional test coverage for creation of resources.
2017-09-04 11:35:20 -07:00
joeduffy 200fecbbaa Implement initial Lumi-as-a-library
This is the initial step towards redefining Lumi as a library that runs
atop vanilla Node.js/V8, rather than as its own runtime.

This change is woefully incomplete but this includes some of the more
stable pieces of my current work-in-progress.

The new structure is that within the sdk/ directory we will have a client
library per language.  This client library contains the object model for
Lumi (resources, properties, assets, config, etc), in addition to the
"language runtime host" components required to interoperate with the
Lumi resource monitor.  This resource monitor is effectively what we call
"Lumi" today, in that it's the thing orchestrating plans and deployments.

Inside the sdk/ directory, you will find nodejs/, the Node.js client
library, alongside proto/, the definitions for RPC interop between the
different pieces of the system.  This includes existing RPC definitions
for resource providers, etc., in addition to the new ones for hosting
different language runtimes from within Lumi.

These new interfaces are surprisingly simple.  There is effectively a
bidirectional RPC channel between the Lumi resource monitor, represented
by the lumirpc.ResourceMonitor interface, and each language runtime,
represented by the lumirpc.LanguageRuntime interface.

The overall orchestration goes as follows:

1) Lumi decides it needs to run a program written in language X, so
   it dynamically loads the language runtime plugin for language X.

2) Lumi passes that runtime a loopback address to its ResourceMonitor
   service, while language X will publish a connection back to its
   LanguageRuntime service, which Lumi will talk to.

3) Lumi then invokes LanguageRuntime.Run, passing information like
   the desired working directory, program name, arguments, and optional
   configuration variables to make available to the program.

4) The language X runtime receives this, unpacks it and sets up the
   necessary context, and then invokes the program.  The program then
   calls into Lumi object model abstractions that internally communicate
   back to Lumi using the ResourceMonitor interface.

5) The key here is ResourceMonitor.NewResource, which Lumi uses to
   serialize state about newly allocated resources.  Lumi receives these
   and registers them as part of the plan, doing the usual diffing, etc.,
   to decide how to proceed.  This interface is perhaps one of the
   most subtle parts of the new design, as it necessitates the use of
   promises internally to allow parallel evaluation of the resource plan,
   letting dataflow determine the available concurrency.

6) The program exits, and Lumi continues on its merry way.  If the program
   fails, the RunResponse will include information about the failure.

Due to (5), all properties on resources are now instances of a new
Property<T> type.  A Property<T> is just a thin wrapper over a T, but it
encodes the special properties of Lumi resource properties.  Namely, it
is possible to create one out of a T, other Property<T>, Promise<T>, or
to freshly allocate one.  In all cases, the Property<T> does not "settle"
until its final state is known.  This cannot occur before the deployment
actually completes, and so in general it's not safe to depend on concrete
resolutions of values (unlike ordinary Promise<T>s which are usually
expected to resolve).  As a result, all derived computations are meant to
use the `then` function (as in `someValue.then(v => v+x)`).

Although this change includes tests that may be run in isolation to test
the various RPC interactions, we are nowhere near finished.  The remaining
work primarily boils down to three things:

    1) Wiring all of this up to the Lumi code.

    2) Fixing the handful of known loose ends required to make this work,
       primarily around the serialization of properties (waiting on
       unresolved ones, serializing assets properly, etc).

    3) Implementing lambda closure serialization as a native extension.

This ongoing work is part of pulumi/pulumi-fabric#311.
2017-09-04 11:35:20 -07:00
Luke Hoban 2e22c243bc Adopt Go 1.9 in Travis 2017-09-02 12:10:28 -07:00
Luke Hoban c39c4eda97 Merge pull request #327 from pulumi/defaultsinkmutex
Avoid concurrent map updates in default sink
2017-08-31 14:42:54 -07:00
Luke Hoban 7425c4d106 Avoid concurrent map updates in default sink
Fixes #324
2017-08-31 14:36:19 -07:00
Matt Ellis 9c54af2ef0 Merge pull request #326 from pulumi/add-environment-provider
Add environment provider
2017-08-31 13:54:54 -07:00
Matt Ellis 24ac95c998 Adopt github.com/pkg/errors in a few more places 2017-08-31 10:28:20 -07:00
Matt Ellis cda0fd9bca Add godoc comments 2017-08-31 10:28:02 -07:00
Matt Ellis 4e2d519744 Rename fileSystemEnvironmentProvider to localEnvProvider 2017-08-31 10:27:41 -07:00
Matt Ellis 4ecae0d77d Disable aligncheck linter 2017-08-30 16:47:33 -07:00
Matt Ellis be13c39586 Adopt EnvironmentProvider interface in engine
The existing implementation of the interface (backed by the file
system) has moved into cmd/lumi. The deployment service will start to
provide its own version.
2017-08-30 16:47:33 -07:00
Matt Ellis 34d52cc527 Add EnvironmentProvider interface 2017-08-29 18:47:32 -07:00
Matt Ellis fa033e985e Adopt error at API boundary 2017-08-29 18:47:29 -07:00
Matt Ellis a4c97d7225 Have saveEnv always override an existing environment
`saveEnv` had a flag which would prevent an environment from being
overwritten if it already existed, which was only used by `lumi env
init`. Refactor the code so the check is done inside `lumi` instead of
against this API. We don't need this functionality for the service and
so requiring support for this at the API boundary for environments
feels like a bad idea.
2017-08-29 18:05:42 -07:00
Matt Ellis 871b8ba962 Remove ability to specify a file name when saving an environment
We'd like to abstract out environment CRUD operations and I'd prefer
not to have to bake in the conspect of a file name like thing in the
abstraction. Since we were not really using this feature many places,
let's just get rid of it.
2017-08-29 18:00:28 -07:00
Matt Ellis 3becc6a4f4 Adopt glog for a few functions
The implementation of these functions will be moving out of the engine
and into `lumi` itself, it's a little easier if we move away from
spewing stuff to the diag interface, so just use glog instead (which
`lumi` already uses for logging)
2017-08-29 17:51:58 -07:00
Luke Hoban 24393cfe7b Read path assets into memory instead of holding open file handles
This helps avoid running into file handle limits when creating archives including thousands of node_modules files.

Tracking a more complete fix through all other codepaths related to assets as part of #325.
2017-08-29 13:33:02 -07:00
joeduffy 627d97d83f Close open Blobs
This change ensures we close all Blobs in the asset/archive logic.
In particular, the archive.Read function returns a map of files to
Blobs and after we are done copying the contents we must ensure
that we invoke Close, otherwise we may leak file handles, sockets,
and so on.  This may or may not be the culprit to the "too many
files open" errors we are hitting while deploying the M5 bits.
2017-08-28 18:52:51 -07:00
Matthew Riley fc17c146fd Merge pull request #322 from pulumi/log-plan-error
Bubble up errors from Plan.Apply. Should help debug #321.
2017-08-27 10:25:09 -07:00
Matt Ellis 56606bd649 Merge pull request #320 from pulumi/add-replace-config-to-engine
Add `ReplaceConfig` to the engine
2017-08-27 09:45:47 -07:00
Matthew Riley 63df03c556 Bubble up errors from Plan.Apply 2017-08-27 00:38:17 -07:00
Matt Ellis dee8114556 Add ReplaceConfig to the engine
The deployment service will use this before a deployment to copy the
config from the database to the local files that lumi will use when
deploying.
2017-08-25 10:52:44 -07:00
Matt Ellis 482c051120 Merge pull request #315 from pulumi/engine-refactor
Refactor guts of `lumi` into a package
2017-08-24 18:26:09 -07:00
Matt Ellis 95339b3511 Add comment about the engine 2017-08-24 18:09:37 -07:00
Matt Ellis 971b36b21a Fix lint issues 2017-08-24 18:09:37 -07:00
Matt Ellis fac6c7c91c Fix Makefile on Fedora 2017-08-24 18:09:37 -07:00
Matt Ellis b7388fa99a Clean up Destroy API boundary 2017-08-24 18:09:37 -07:00
Matt Ellis 73d64dc686 Fix prompt for env name in lumi destory 2017-08-24 18:09:37 -07:00
Matt Ellis 865422567c Alow multiple instances of engine.Engine
This refactors the engine so all of the APIs on it are instance
methods on the type instead of raw methods that float around and use
data from a global engine.

A mechcanical change as we remove the global `E` and then make
anything that interacted with that in pkg/engine to be an instance
method and the dealing with the fallout.
2017-08-24 18:09:37 -07:00
Matt Ellis be586a1fbf Wire up sink to custom stdout and stderr 2017-08-24 18:00:46 -07:00
Matt Ellis 14c2474e6f Remove use of ambient cmdutil.Diag(), instead consult the engine 2017-08-24 18:00:46 -07:00
Matt Ellis 5ae02ad581 Remove use of ambient stdout/stderr streams
Instead of talking directly to stdout or stderr via methods on fmt,
indirect through an Engine type (presently a global, but soon to
change) to allow control of where the streams actually end up.
2017-08-24 18:00:46 -07:00