Commit graph

32 commits

Author SHA1 Message Date
CyrusNajmabadi 5a52c1c080
Actually export function. (#1710) 2018-08-06 15:45:06 -04:00
CyrusNajmabadi 0614b1d052
Move node_module inclusion logic down to pulumi/pulumi so we can use it from both aws and azure. (#1705) 2018-08-06 14:12:19 -04:00
Joe Duffy 091c0e1c23
Upgrade Node.js SDK to TypeScript 3.0 (#1669)
Per pulumi/pulumi#1668. No code changes required, just package.json
and lockfile updates.
2018-07-30 23:19:28 -07:00
CyrusNajmabadi 48df5bfe1e
Update pulumi/pulumi to run on Nodejs v10. (#1658) 2018-07-25 16:55:20 -07:00
Matt Ellis 9b24ad9738 Update gRPC to 1.12.2
This version has an updated protobufs dependency, which will remove
the warnings from `npm audit`.

Fixes #1350
2018-05-30 15:42:10 -07:00
joeduffy 12a2626c59 Prepare package for public publishing
This adds a warning to the top of the README.md and adds a license
to the package.json (to eliminate the associated warning).
2018-05-18 11:21:32 -07:00
Sean Gillespie 68911900fd
Graceful shutdown (#1320)
* Graceful RPC shutdown: CLI side

* Handle unavailable resource monitor in language hosts

* Fix a comment

* Don't commit package-lock.json

* fix mangled pylint pragma

* Rebase against master and fix Gopkg.lock

* Code review feedback

* Fix a race between closing the callerEventsOpt channel and terminating a goroutine that writes to it

* glog -> logging
2018-05-16 15:37:34 -07:00
Joe Duffy a74aa51662
Rename pulumi package to @pulumi/pulumi (#917)
In order to begin publishing our core SDK package to NPM, we will
need it to be underneath the @pulumi scope so that it may remain
private.  Eventually, we can alias pulumi back to it.

This is part of pulumi/pulumi#915.
2018-02-12 13:13:13 -08:00
Pat Gavlin f848090479 Return all computed inputs from Provider.Check.
As documented in issue #616, the inputs/defaults/outputs model we have
today has fundamental problems. The crux of the issue is that our
current design requires that defaults present in the old state of a
resource are applied to the new inputs for that resource.
Unfortunately, it is not possible for the engine to decide which
defaults remain applicable and which do not; only the provider has that
knowledge.

These changes take a more tactical approach to resolving this issue than
that originally proposed in #616 that avoids breaking compatibility with
existing checkpoints. Rather than treating the Pulumi inputs as the
provider input properties for a resource, these inputs are first
translated by `Check`. In order to accommodate provider defaults that
were chosen for the old resource but should not change for the new,
`Check` now takes the old provider inputs as well as the new Pulumi
inputs. Rather than the Pulumi inputs and provider defaults, the
provider inputs returned by `Check` are recorded in the checkpoint file.

Put simply, these changes remove defaults as a first-class concept
(except inasmuch as is required to retain the ability to read old
checkpoint files) and move the responsibilty for manging and
merging defaults into the provider that supplies them.

Fixes #616.
2017-12-03 09:33:16 -08:00
Joe Duffy 16ade183d8
Add a manifest to checkpoint files (#630)
This change adds a new manifest section to the checkpoint files.
The existing time moves into it, and we add to it the version of
the Pulumi CLI that created it, along with the names, types, and
versions of all plugins used to generate the file.  There is a
magic cookie that we also use during verification.

This is to help keep us sane when debugging problems "in the wild,"
and I'm sure we will add more to it over time (checksum, etc).

For example, after an up, you can now see this in `pulumi stack`:

```
Current stack is demo:
    Last updated at 2017-12-01 13:48:49.815740523 -0800 PST
    Pulumi version v0.8.3-79-g1ab99ad
    Plugin pulumi-provider-aws [resource] version v0.8.3-22-g4363e77
    Plugin pulumi-langhost-nodejs [language] version v0.8.3-79-g77bb6b6
    Checkpoint file is /Users/joeduffy/dev/code/src/github.com/pulumi/pulumi-aws/.pulumi/stacks/webserver/demo.json
```

This addresses pulumi/pulumi#628.
2017-12-01 13:50:32 -08:00
CyrusNajmabadi d007f040b9 Move from acorn to TypeScript as the parser we use when computing free variables. (#431) 2017-10-18 13:29:53 -07:00
pat@pulumi.com 9453f86c2e Implement dynamic resources.
A dynamic resource is a resource whose provider is implemented alongside
the resource itself. This provider may close over and use orther
resources in the implementation of its CRUD operations. The provider
itself must be stateless, as each CRUD operation for a particular
dynamic resource type may use an independent instance of the provider.
Changes to the definition of a resource's provider result in replacement
of the resource itself (rather than a simple update), as this allows the
old provider definition to delete the old resource and the new provider
definition to create an appropriate replacement.
2017-10-16 23:06:53 -07:00
Matt Ellis fc14329cfc Stop using yarn scripts for building
We have Makefiles, so we might as well use them, instead of spliting
build logic across two systems.
2017-10-16 10:47:37 -07:00
Matt Ellis e7c3aaba69 Merge pull request #395 from pulumi/pulumi-service-interface
More engine refactoring
2017-10-11 13:44:36 -07:00
CyrusNajmabadi b713990b5e Enable 'use const' linter rule. (#405)
* Enable 'use const' linter rule.
2017-10-10 14:50:55 -07:00
Matt Ellis 6bab1dbad4 Pass $(YARNFLAGS) to all yarn invocations
This let's you set things like YARNFLAGS==--offline which is helpful
when you are on an airplane. Yarn can still pick up stuff that you had
pulled down recently from its local cache
2017-10-09 18:21:55 -07:00
Joe Duffy f6e694c72b Rename pulumi-fabric to pulumi
This includes a few changes:

* The repo name -- and hence the Go modules -- changes from pulumi-fabric to pulumi.

* The Node.js SDK package changes from @pulumi/pulumi-fabric to just pulumi.

* The CLI is renamed from lumi to pulumi.
2017-09-21 19:18:21 -07:00
joeduffy 94207acf65 Upgrade to TypeScript ^2.5.2 2017-09-14 15:02:41 -07:00
joeduffy 8aba3aae12 Upgrade gRPC to 1.6.0; use full addresses
This change upgrades gRPC to 1.6.0 to pick up a few bug fixes.

We also use the full address for gRPC endpoints, including the
interface name, as otherwise we pick the wrong interface on Linux.
2017-09-09 07:37:10 -07:00
joeduffy 88a87569f5 Link the bin/ directory
This moves us closer to what we'll have with real NPM packages.
2017-09-07 12:43:12 -07:00
joeduffy 6147afb7d1 Fix cp command on Linux 2017-09-07 07:36:10 -07:00
joeduffy 8d3708f34d Use portable cps 2017-09-05 11:39:32 -07:00
joeduffy 8826c08116 Fix linting glob 2017-09-05 11:24:38 -07:00
joeduffy d7c90f12a8 Use yarn to run subcommands 2017-09-04 11:35:21 -07:00
joeduffy b80b6afcf1 Lint the test files 2017-09-04 11:35:21 -07:00
joeduffy d7688da5e3 Fix a few minor pathing things 2017-09-04 11:35:21 -07:00
joeduffy 3427647f93 Implement free variable calculations
This change implements free variable calculations and wires it up
to closure serialization.  This is recursive, in the sense that
the serializer may need to call back to fetch free variables for
nested functions encountered during serialization.

The free variable calculation works by parsing the serialized
function text and walking the AST, applying the usual scoping rules
to determine what is free.  In particular, it respects nested
function boundaries, and rules around var, let, and const scoping.

We are using Acorn to perform the parsing.  I'd originally gone
down the path of using V8, so that we have one consistent parser
in the game, however unfortunately neither V8's parser nor its AST
is a stable API meant for 3rd parties.  Unlike the exising internal
V8 dependencies, this one got very deep very quickly, and I became
nervous about maintaining all those dependencies.  Furthermore,
by doing it this way, we can write the free variable logic in
JavaScript, which means one fewer C++ component to maintain.

This also includes a fairly significant amount of testing, all
of which passes! 🎉
2017-09-04 11:35:21 -07:00
joeduffy 97c5f0a568 Take an initial stab at closure serialization
This change contains an initial implementation of closure serialization
built atop V8, rather than our own custom runtime.  This requires that
we use a Node.js dynamic C++ module, so that we can access the V8
APIs directly.  No build magic is required beyond node-gyp.

For the most part, this was straight forward, except for one part: we
have to use internal V8 APIs.  This is required for two reasons:

1) We need access to the function's lexical closure environment, so
   that we may look up closure variables.  Although there is a
   tantalizingly-close v8::Object::CreationContext, its implementation
   intentionally pokes through closure contexts in order to recover
   the Function constructor context instead.  That's not what we
   want.  We want the raw, unadulterated Function::context.

2) We need to control the lexical lookups of free variables so that
   they can look past chained contexts, lexical contexts, withs, and
   eval-style context extensions.  Simply runing a v8::Script, or
   simulating an eval, doesn't do the trick.  Hence, we need to access
   the unexported v8::internal::Context::Lookup function.

There is a third reason which is not yet implemented: free variable
calculation.  I could use Esprima, or do my own scanner for free
variables, but I'd prefer to simply use the V8 parser so that we're
using the same JavaScript parser across all components.  That too
is not part of the v8.h API, so we'll need to crack it open more.

To be clear, these are still exported public APIs, in proper headers
that are distributed with both Node and V8.  They simply aren't part
of the "stable" v8.h surface area.  As a result, I do expect that
maintaining this will be tricky, and I'd like to keep exploring how
to do this without needing the internal dependency.  For instance,
although this works with node-gyp just fine, we will probably be
brittle across versions of Node/V8, when the internal APIs might be
changing.  This will introduce unfortunate versioning headaches (all,
hopefully and thankfully, caught at compile-time).
2017-09-04 11:35:21 -07:00
joeduffy d8635fd4f3 Move modules to package root
The organization of packages underneath lib/ breaks the easy consumption
of submodules, a la

    import {FileAsset} from "@pulumi/pulumi-fabric/asset";

We will go back to having everything hanging off the module root directory.
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 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 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