Commit graph

532 commits

Author SHA1 Message Date
joeduffy 23493be8af Classify output properties as adds too 2017-06-01 08:39:48 -07:00
joeduffy e84c2d9388 Remember output properties in snapshot records
This change remembers which properties were computed as outputs,
or even just read back as default values, during a deployment.  This
information is required in the before/after comparison in order to
perform an intelligent diff that doesn't flag, for example, the absence
of "default" values in the after image as deletions (among other things).
As I was in here, I also cleaned up the way the provider interface
works, dealing with concrete resource types, making it feel a little
richer and less like we're doing in-memory RPC.
2017-06-01 08:39:48 -07:00
joeduffy 4d63e6d672 Add a few more RawResources: trues 2017-06-01 08:39:48 -07:00
joeduffy 08ca40c6c6 Unmap properties on the receive side
This change makes progress on a few things with respect to properly
receiving properties on the engine side, coming from the provider side,
of the RPC boundary.  The issues here are twofold:

    1. Properties need to get unmapped using a JSON-tag-sensitive
       marshaler, so that they are cased properly, etc.  For that, we
       have a new mapper.Unmap function (which is ultra lame -- see
       pulumi/lumi#138).

    2. We have the reverse problem with respect to resource IDs: on
       the send side, we must translate from URNs (which the engine
       knows about) and provider IDs (which the provider knows about);
       similarly, then, on the receive side, we must translate from
       provider IDs back into URNs.

As a result of these getting fixed, we can now properly marshal the
resulting properties back into the resource object during the plan
execution, alongside propagating and memoizing its ID.
2017-06-01 08:39:48 -07:00
joeduffy 87ad371107 Only flow logging to plugins if --logflow
The change to flow logging to plugins is nice, however, it can be
annoying because all writes to stderr are interepreted on the Lumi
side as errors.  After this change, we will only flow if
--logflow is passed, e.g. as in

    $ lumi --logtostderr --logflow -v=9 deploy ...
2017-06-01 08:37:56 -07:00
joeduffy 0a72d5360a Modify provider creates; use get for outs
This change modifies the existing resource provider RPC interface slightly.
Instead of the Create API returning the bag of output properties, we will
rely on the Get API to do so.  As a result, this change takes an initial
whack at implementing Get on all existing AWS resources.  The Get API needs
to return a fully populated structure containing all inputs and outputs.

Believe it or not, this is actually part of pulumi/lumi#90.

This was done because just returning output properties is insufficient.
Any input properties that weren't supplied may have default values, for
example, and it is wholly reasonable to expect Lumi scripts to depend on
those values in addition to output values.

This isn't fully functional in its current form, because doing this
change turned up many other related changes required to enable output
properties.  For instance, at the moment resource properties are defined
in terms of `resource.URN`s, and yet unfortunately the provider side
knows nothing of URNs (instead preferring to deal in `resource.ID`s).
I am going to handle that in a subsequent isolated change, since it will
have far-reaching implications beyond just modifying create and get.
2017-06-01 08:36:43 -07:00
joeduffy 7f98387820 Distinguish between computed and output properties
This change introduces the notion of a computed versus an output
property on resources.  Technically, output is a subset of computed,
however it is a special kind that we want to treat differently during
the evaluation of a deployment plan.  Specifically:

* An output property is any property that is populated by the resource
  provider, not code running in the Lumi type system.  Because these
  values aren't available during planning -- since we have not yet
  performed the deployment operations -- they will be latent values in
  our runtime and generally missing at the time of a plan.  This is no
  problem and we just want to avoid marshaling them in inopportune places.

* A computed property, on the other hand, is a different beast altogehter.
  Although true one of these is missing a value -- by virtue of the fact
  that they too are latent values, bottoming out in some manner on an
  output property -- they will appear in serializable input positions.
  Not only must we treat them differently during the RPC handshake and
  in the resource providers, but we also want to guarantee they are gone
  by the time we perform any CRUD operations on a resource.  They are
  purely a planning-time-only construct.
2017-06-01 08:36:43 -07:00
joeduffy e4462087a5 Add a @lumi.out decorator
This change adds a @lumi.out decorator and modifies LumIDL to emit it on
output properties of resource types.  There still isn't any runtime
awareness, however, this is an isolated change that will facilitate it.
2017-06-01 08:32:12 -07:00
joeduffy 706acb5fd8 Tolerate latent values in more places 2017-06-01 08:32:12 -07:00
joeduffy d79c41f620 Initial support for output properties (1 of 3)
This change includes approximately 1/3rd of the change necessary
to support output properties, as per pulumi/lumi#90.

In short, the runtime now has a new hidden type, Latent<T>, which
represents a "speculative" value, whose eventual type will be T,
that we can use during evaluation in various ways.  Namely,
operations against Latent<T>s generally produce new Latent<U>s.

During planning, any Latent<T>s that end up in resource properties
are transformed into "unknown" property values.  An unknown property
value is legal only during planning-time activities, such as Check,
Name, and InspectChange.  As a result, those RPC interfaces have
been updated to include lookaside maps indicating which properties
have unknown values.  My intent is to add some helper functions to
make dealing with this circumstance more correct-by-construction.

For now, using an unresolved Latent<T> in a conditional will lead
to an error.  See pulumi/lumi#67.  Speculating beyond these -- by
supporting iterative planning and application -- is something we
want to support eventually, but it makes sense to do that as an
additive change beyond this initial support.  That is a missing 1/3.

Finally, the other missing 1/3rd which will happen much sooner
than the rest is restructuing plan application so that it will
correctly observe resolution of Latent<T> values.  Right now, the
evaluation happens in one single pass, prior to the application, and
so Latent<T>s never actually get witnessed in a resolved state.
2017-06-01 08:32:12 -07:00
Luke Hoban 9531483e19 Add tests for AWS DynamoDB Table provider 2017-05-31 17:06:16 -07:00
Luke Hoban 99499792b3 Serialize lambda environment variables in stable order
When serializing a closure, we serialize the lambda environment into the
aws.lambda.Function Environment property.  We need to serialize the lambda
environment in a stable order to ensure that we don't cause Lumi to require
updates to the aws.lambda.Function resource.
2017-05-31 11:40:22 -07:00
joeduffy ab6e2466c7 Flow logging information to plugins
This change flows --logtostderr and -v=x settings to any dynamically
loaded plugins so that running Lumi's command line with these flags
will also result in the plugins logging at the requested levels.  I've
found this handy for debugging purposes.
2017-05-30 10:19:33 -07:00
Luke Hoban 7f8b1e59c1 Support for lambdas (#158)
Resolves #137.

This is an initial pass for supporting JavaScript lambda syntax for defining an AWS Lambda Function.

A higher level API for defining AWS Lambda Function objects `aws.lambda.FunctionX` is added which accepts a Lumi lambda as an argument, and uses that lambda to generate the AWS Lambda Function code package.

LumiJS lambdas are serialized as the JavaScript text of the lambda body, along with a serialized version of the environment that is deserialized at runtime and used as the context for the body of the lambda.

Remaining work to further improve support for lambdas is being tracked in #173, #174, #175, and #177.
2017-05-25 16:55:14 -07:00
Luke Hoban 6015c96fda Add jsonStringify intrinsic
This will eventually be used as the implementation of JSON.stringify in LumiJS.
2017-05-25 12:19:58 -07:00
Luke Hoban b8d978b22c Move Intrinsic into eval/rt package
Unifies the notion of BuiltinFunctions with the existing Intrinsic.

Intrinsic is now only a wrapper type, used to indicate the need to lookup the symbol in the
eval pacakges table of registered intrinsics.  It does not carry the invoker function used
to eval the intrinsic.
2017-05-25 12:06:13 -07:00
Luke Hoban a625117e72 Add a length property to Array objects
Also adds a `lumi.runtime.printf` function for debugging Lumi scripts and fixes a couple issues with getter/setter references.
2017-05-25 12:06:13 -07:00
joeduffy 8f1fa79230 Rewrite eval test to be self-contained
The eval test in its current form depends on the Lumi standard library
as an external dependency.  This means that, in order to run the test,
you must first install the standard library.  Not only is this poor
practice, it is also interfering with our ability to get our new CI/CD
system up and running.  This change fixes all of that by mocking the one
standard library runtime function that we need in order to hook the intrinsic.
2017-05-24 12:50:28 -07:00
Joe Duffy f541853226 Merge pull request #157 from pulumi/intrinsic-fix
Fix a few intrinsics bugs
2017-05-23 08:05:19 -07:00
joeduffy 2bbc4739bd Add some intrinsics tests
This change adds some machinery to make it easier to write evaluator tests,
and also implements some tests for the lumi:runtime/dynamic:isFunction intrinsic.
2017-05-23 08:03:14 -07:00
Luke Hoban 35a41f9e4a Support Update on IAM Role and Lambda Function 2017-05-22 22:57:55 -07:00
joeduffy bad62854a9 Fix a few intrinsics bugs
During various refactorings pertaining to dynamic vs static invoke, the
intrinsics machinery broke in a few ways:

* MaybeIntrinsic needs to happen elsewhere.  Rather than doing it at binding
  time, we can do it when populating the properties in the first place,
  reusing the same property symbol from one access to the next.

* Last week, I refactored the intrinsics module to also have a dynamic sub-
  module.  The tokens in the Intrinsics map needed to also get updated.

* As a result of the tokens now containing member parts, we can't use
  tokens.Token.Name, since it is assumed to be a simple name; instead, we
  need to convert to tokens.ModuleMember, and then fetch Name.  To be honest,
  this is probably worth revisiting, since I think most people would expect
  Name to just work regardless of the Token kind.  The assert that it be
  Simple might be a little overly aggressive...

This checkin fixes these issues.  I'm not pushing to master just yet,
however, until there are some solid tests in here to prevent future breakage.
2017-05-22 16:16:53 -07:00
joeduffy 6e0d388c90 Make argument objects optional when no required properties
If a resource has no required properties, there's no need for an
argument object.  (In the extreme case, perhaps the resource has
*no* properties.)  This is a minor usability thing, but it's far
nicer to write code like

    let buck = new Bucket("images");

than it is to write code like

    let buck = new Bucket("images", {});
2017-05-22 14:08:32 -07:00
joeduffy 3bad4fde98 Disable storing output properties
The storing of output properties won't work correctly until pulumi/lumi#90
is completed.  The update logic sees properties that weren't supplied by the
developer and thinks this means an update is required; this is easy to fix
but better to just roll into the overall pending change that will land soon.
2017-05-22 13:20:57 -07:00
joeduffy 94786ee1a2 Add an ast.WalkChildren function
This adds a WalkChildren function that can be useful when you want to
walk an AST node's children, but not the node itself.
2017-05-22 11:06:12 -07:00
Luke Hoban 0f99762e2e Add AWS Elastic Beanstalk resource providers (#154)
Includes support for:
* Application
* ApplicationVersion
* Environment
2017-05-21 21:45:28 -07:00
joeduffy 423e84df6e Fix workspace tests 2017-05-19 08:24:44 -07:00
joeduffy 4108c51549 Reclassify Lumi under the Apache 2.0 license
This is part of pulumi/lumi#147.
2017-05-18 14:51:52 -07:00
joeduffy b7f3d447a1 Preserve the lumi prefix on our CLI tools
This change keeps the lumi prefix on our CLI tools.

As @lukehoban pointed out in person, as soon as we do pulumi/coconut#98,
most people (other than compiler authors themselves) won't actually be
typing the commands.  And, furthermore, the commands aren't all that bad.

Eventually I assume we'll want something like `lumi-js`, or
`lumi-js-compiler`, so that binaries are discovered dynamically in a way
that is extensible for future languages.  We can tackle this during #98.
2017-05-18 12:38:58 -07:00
joeduffy dafeb77dff Rename Coconut to Lumi
This is part of pulumi/coconut#147.

After it has landed, I will rename the repo on GitHub.
2017-05-18 11:38:28 -07:00
joeduffy ec27cfd22c Update object test to use new pointer constructor 2017-05-16 15:27:32 -07:00
joeduffy 8d6f4c0d69 Fix a minor error message typo 2017-05-15 17:50:13 -07:00
joeduffy 85b888d1fa Fix a misattributed diagnostics message 2017-05-15 17:49:30 -07:00
joeduffy 82e3624ea1 Implement property accessors
This change implements property accessors (getters and setters).

The approach is fairly basic, but is heavily inspired by the ECMAScript5
approach of attaching a getter/setter to any property slot (even if we don't
yet fully exploit this capability).  The evaluator then needs to track and
utilize the appropriate accessor functions when loading locations.

This change includes CocoJS support and makes a dent in pulumi/coconut#66.
2017-05-15 17:46:14 -07:00
joeduffy cac52ae572 Fix two minor comment issues 2017-05-15 06:30:17 -07:00
joeduffy 78dc0b4a47 Add some handy internal RTTI helpers (and some tests) 2017-05-13 21:17:49 -04:00
joeduffy eee0f3b717 Fix some golint warnings 2017-05-13 20:04:35 -04:00
joeduffy 71855c7c44 Split intrinsics
This change just refactors out the dynamic intrinsics functions, from the general
intrinsics file, in preparation for some new ones.
2017-05-13 19:22:52 -04:00
joeduffy ea7658f338 Guard against nil diffs 2017-05-08 14:52:17 -05:00
joeduffy d3c1d7057b Add some tests for stable property ordering 2017-05-06 16:22:06 -07:00
joeduffy 7d8aadeb1e Implement chronological stable object keys
We need a stable object key enumeration order and we might as well leverage
ECMAScript's definition for this.  As of ES6, key ordering is specified; see
https://tc39.github.io/ecma262/#sec-ordinaryownpropertykeys.

I haven't fully implemented the "numbers come first part" (we can do this as
soon as we have support for Object.keys()), but the chronological part works.
2017-05-06 16:09:49 -07:00
joeduffy 3e73a6b8ba Add an alloc.NewDynamic helper function 2017-05-06 15:39:39 -07:00
joeduffy fb3a6612f6 Fix a lambda lexical environment bug
This addresses a bug where we did not reconstruct the correct lexical
environment when restoring a lambda's captured context.  Namely, the local
variables scope "drifted" with respect to the evaluation scope slots.

This is an example program that triggered it:

    function mkeighty() {
        let eighty = 80;
        return () => eighty;
    }
    let group = new ec2.SecurityGroup(..., {
        ingress: [ ..., fromPort: mkeighty()(), ... ],
    });

I am going to work on turning this into a regression test with my next
checkin; there's a fair bit of test infrastructure "machinery" I need
to put in place, but the time has come to lay the foundation.
2017-05-04 16:38:46 -07:00
joeduffy 240cdb8f0f Implement lambdas in the runtime
This change completes implementing lambdas in the runtime, closing
out pulumi/coconut#62.  The change is mostly straightforward, with
most changes coming down to the fact that functions may now exist
that themselves aren't definitions (like class/module members).
The function stub machinery has also been updated to retain the
environment in which a lambda was created, effectively "capturing"
the lexically available variables.  Note that this is *not* dynamic
scoping, which will be a problem down the road when/if we want to
support Ruby.  My guess is we'll just have a completely different
DynamicallyScopedLambdaExpression opcode.
2017-05-04 14:03:51 -07:00
joeduffy fde88b7cf4 Permit Statements in SequenceExpressions
The previous shape of SequenceExpression only permitted expressions
in the sequence.  This is pretty common in most ILs, however, it usually
leads to complicated manual spilling in the event that a statement is needed.
This is often necessary when, for example, a compiler is deeply nested in some
expression production, and then realizes the code expansion requires a
statement (e.g., maybe a new local variable must be declared, etc).

Instead of requiring complicated code-gen, this change permits SequenceExpression
to contain an arbitrary mixture of expression/statement prelude nodes, terminating
with a single, final Expression which yields the actual expression value.  The
runtime bears the burden of implementing this which, frankly, is pretty trivial.
2017-05-04 10:54:07 -07:00
joeduffy 1e67162331 Fix a couple silly mistakes 2017-05-04 09:53:52 -07:00
joeduffy 4e5140251b Implement support for computed property initializers
I've tripped over pulumi/coconut#141 a few times now, particularly with
the sort of dynamic payloads required when creating lambdas and API gateways.
This change implements support for computed property initializers.
2017-05-01 17:11:57 -07:00
joeduffy 6902d7e1b2 Update AWS Lambdas to take archives, not assets 2017-05-01 09:38:23 -07:00
joeduffy 335ea01275 Implement archives
Our initial implementation of assets was intentionally naive, because
they were limited to single-file assets.  However, it turns out that for
real scenarios (like lambdas), we want to support multi-file assets.

In this change, we introduce the concept of an Archive.  An archive is
what the term classically means: a collection of files, addressed as one.
For now, we support three kinds: tarfile archives (*.tar), gzip-compressed
tarfile archives (*.tgz, *.tar), and normal zipfile archives (*.zip).

There is a fair bit of library support for manipulating Archives as a
logical collection of Assets.  I've gone to great length to avoid making
copies, however, sometimes it is unavoidable (for example, when sizes
are required in order to emit offsets).  This is also complicated by the
fact that the AWS libraries often want seekable streams, if not actual
raw contiguous []byte slices.
2017-04-30 12:37:24 -07:00
joeduffy 0e16aa5d93 Make resource names the first constructor parameter
This reverts back to the old style of having the resource name as its
first parameter in the generated package.  Stylistically, this reads a
little nicer, and also ensures we don't need to rewrite all our existing
samples/test cases, etc.
2017-04-29 15:58:34 -07:00