Commit graph

556 commits

Author SHA1 Message Date
Pat Gavlin 74df0e67db
Allow previews when operations are pending. (#1999)
The preview will proceed as if the operations had not been issued (i.e.
we will not speculate on a new state for the stack). This is consistent
with our behavior prior to the changes that added pending operations to
the checkpoint.
2018-10-01 09:48:48 -07:00
Sean Gillespie ed0353e251
Process deletions conservatively in parallel (#1963)
* Process deletions conservatively in parallel

This commit allows the engine to conservatively delete resources in
parallel when it is sure that it is legal to do so. In the absence of a
true data-flow oriented step scheduler, this approach provides a
significant improvement over the existing serial deletion mechanism.

Instead of processing deletes serially, this commit will partition the
set of condemned resources into sets of resources that are known to be
legally deletable in parallel. The step executor will then execute those
independent lists of steps one-by-one until all steps are complete.

* CR: Make ResourceSet a normal map

* Only use the dependency graph if we can trust it

* Reverse polarity of pendingDeletesAreReplaces

* CR: un-export a few types

* CR: simplify control flow in step generator when scheduling

* CR: parents are dependencies, fix loop index

* CR: Remove ParentOf, add new test for parent dependencies
2018-09-27 15:49:08 -07:00
joeduffy 3468393490 Make a smattering of CLI UX improvements
Since I was digging around over the weekend after the change to move
away from light black, and the impact it had on less important
information showing more prominently than it used to, I took a step
back and did a deeper tidying up of things. Another side goal of this
exercise was to be a little more respectful of terminal width; when
we could say things with fewer words, I did so.

* Stylize the preview/update summary differently, so that it stands
  out as a section. Also highlight the total changes with bold -- it
  turns out this has a similar effect to the bright white colorization,
  just without the negative effects on e.g. white terminals.

* Eliminate some verbosity in the phrasing of change summaries.

* Make all heading sections stylized consistently. This includes
  the color (bright magenta) and the vertical spacing (always a newline
  separating headings). We were previously inconsistent on this (e.g.,
  outputs were under "---outputs---"). Now   the headings are:
  Previewing (etc), Diagnostics, Outputs, Resources, Duration, and Permalink.

* Fix an issue where we'd parent things to "global" until the stack
  object later showed up. Now we'll simply mock up a stack resource.

* Don't show messages like "no change" or "unchanged". Prior to the
  light black removal, these faded into the background of the terminal.
  Now they just clutter up the display. Similar to the elision of "*"
  for OpSames in a prior commit, just leave these out. Now anything
  that's written is actually a meaningful status for the user to note.

* Don't show the "3 info messages," etc. summaries in the Info column
  while an update is ongoing. Instead, just show the latest line. This
  is more respectful of width -- I often find that the important
  messages scroll off the right of my screen before this change.

    For discussion:

        - I actually wonder if we should eliminate the summary
          altogether and always just show the latest line. Or even
          blank it out. The summary feels better suited for the
          Diagnostics section, and the Status concisely tells us
          how a resource's update ended up (failed, succeeded, etc).

        - Similarly, I question the idea of showing only the "worst"
          message. I'd vote for always showing the latest, and again
          leaving it to the Status column for concisely telling the
          user about the final state a resource ended up in.

* Stop prepending "info: " to every stdout/stderr message. It adds
  no value, clutters up the display, and worsens horizontal usage.

* Lessen the verbosity of update headline messages, so we now instead
  of e.g. "Previewing update of stack 'x':", we just say
  "Previewing update (x):".

* Eliminate vertical whitespace in the Diagnostics section. Every
  independent console.out previously was separated by an entire newline,
  which made the section look cluttered to my eyes. These are just
  streams of logs, there's no reason for the extra newlines.

* Colorize the resource headers in the Diagnostic section light blue.

Note that this will change various test baselines, which I will
update next. I didn't want those in the same commit.
2018-09-24 08:43:46 -07:00
joeduffy be9ead855d Eliminate the same prefix
Recently, we eliminated bright black text, which IMHO makes the
"same" lines really stand out more than we want them to. This is
partly just due to the heavyweight nature of the "*" character,
which we precede every line with. This has the effect of making it
toughter to scan the update to see what's going to happen. The goal
of SpecUnimportant (bright black) was that we wanted to draw less
attention to certain elements of the CLI text -- and have them fade
into the background (apparently it was too successful at this ;-))

So, this change eliminates the "*" prefix for same operations
altogether. It reads better to my eyes and keeps the original intent.
2018-09-22 13:34:43 -07:00
Pat Gavlin 8f55a379f6
Return errors for unknown/invalid path archives. (#1970)
- Attempting to read an archive with an unknown type now returns an
  error
- Attempting to read a path archive that is neither a known archive
  format or a directory now returns an error

Fixes #1529.
Fixes #1953.
2018-09-21 11:53:39 -07:00
Sean Gillespie 2d4a3f7a6a
Move management of root resource state to engine (#1944)
* Protobuf changes

* Move management of root resource state to engine

This commit fixes a persistent side-by-side issue in the NodeJS SDK by
moving the management of root resource state to the engine. Doing so
adds two new endpoints to the Engine gRPC service: 1) GetRootResource
and 2) SetRootResource, which get and set the root resource
respectively.

* Rebase against master, regenerate proto
2018-09-18 11:47:34 -07:00
Sean Gillespie a35aba137b
Retire pending deletions at start of plan (#1886)
* Retire pending deletions at start of plan

Instead of letting pending deletions pile up to be retired at the end of
a plan, this commit eagerly disposes of any pending deletions that were
pending at the end of the previous plan. This is a nice usability win
and also reclaims an invariant that at most one resource with a given
URN is live and at most one is pending deletion at any point in time.

* Rebase against master

* Fix a test issue arising from shared snapshots

* CR feedback

* plan -> replacement

* Use ephemeral statuses to communicate deletions
2018-09-10 16:48:14 -07:00
Pat Gavlin 4a550e308f
Fix provider cancellation. (#1914)
We signal provider cancellation by hangning a goroutine off of the plan
executor's parent context. To ensure clean shutdown, this goroutine also
listens on a channel that closes once the plan has finished executing.
Unfortunately, we were closing this channel too early, and the close was
racing with the cancellation signal. These changes ensure that the
channel closes after the plan has fully completed.

Fixes #1906.
Fixes pulumi/pulumi-kubernetes#185.
2018-09-10 15:18:25 -07:00
Sean Gillespie 679f55c355
Validate type tokens before using them (#1904)
* Validate type tokens before using them

When registering or reading a resource, we take the type token given to
us from the language host and assume that it's valid, which resulted in
assertion failures in various places in the engine. This commit
validates the format of type tokens given to us from the language host
and issues an appropriate error if it's not valid.

Along the way, this commit also improves the way that fatal exceptions
are rendered in the Node language host.

* Pre-allocate an exception for ReadResource

* Fix integration test

* CR Feedback

This commit is a lower-impact change that fixes the bugs associated with
invalid types on component resources and only checks that a type is
valid on custom resources.

* CR Take 2: Fix up IsProviderType instead of fixing call sites

* Please gometalinter
2018-09-07 15:19:18 -07:00
Sean Gillespie ca58b8117f
Clarify control flow in step generator (#1843)
* Introduce Result type to engine

The Result type can be used to signal the failure of a computation due
to both internal and non-internal reasons. If a computation failed due
to an internal error, the Result type carries that error with it and
provides it when the 'Error' method on a Result is called. If a
computation failed gracefully, but wished to bail instead of continue a
doomed plan, the 'Error' method provides a value of null.

* CR feedback
2018-09-05 15:08:09 -07:00
Pat Gavlin df1a5e653d
Fail refreshes with init errors. (#1882)
And ensure that refreshes continue on errors.

Fixes #1881.
2018-09-05 14:00:28 -07:00
Alex Clemmer dea68b8b37 Implement status sinks
This commit reverts most of #1853 and replaces it with functionally
identical logic, using the notion of status message-specific sinks.

In other words, where the original commit implemented ephemeral status
messages by adding an `isStatus` parameter to most of the logging
methdos in pulumi/pulumi, this implements ephemeral status messages as a
parallel logging sink, which emits _only_ ephemeral status messages.

The original commit message in that PR was:

> Allow log events to be marked "status" events
>
> This commit will introduce a field, IsStatus to LogRequest. A "status"
> logging event will be displayed in the Info column of the main
> display, but will not be printed out at the end, when resource
> operations complete.
>
> For example, for complex resource initialization, we'd like to display
> a series of intermediate results: [1/4] Service object created, for
> example. We'd like these to appear in the Info column, but not at the
> end, where they are not helpful to the user.
2018-08-31 15:56:53 -07:00
Alex Clemmer 9e58fd1aaa Revert "Plumb LogRequest.IsStatus through the logging subsystem"
This reverts commit 3066cbcbd7.
2018-08-31 15:56:53 -07:00
Alex Clemmer 3066cbcbd7 Plumb LogRequest.IsStatus through the logging subsystem 2018-08-30 17:17:20 -07:00
Pat Gavlin 0634c1852a
Fix some potential bugs in the refresher. (#1845)
- Create all refresh steps before issuing any. This is important as the
  state update loop expects all steps to exist.
- Check for cancellation later in the refresher.

This also fixes races in the SnapshotManager and the test journal that
could cause panics during cancellation.
2018-08-29 21:00:05 -07:00
Alex Clemmer 2fa98a8dad Generate empty update steps for partial failures
This commit will greatly improve the experience of dealing with partial
failures by simply re-trying to initialize the relevant resources on
every subsequent `pulumi up`, instead of printing a list of reasons the
resource had previously failed to initialize.

As motivation, consider our behavior in the following common, painful
scenario:

  * The user creates a `Service` and a `Deployment`.
  * The `Pod`s in the `Deployment` fail to become live. This causes the
    `Service` to fail, since it does not target any live `Pod`s.
  * The user fixes the `Deployment`. A run of `pulumi up` sees the
    `Pod`s successfully initialize.
  * Users will expect that the `Service` is now in a state of success,
    as the `Pod`s it targets are alive. But, because we don't update the
    `Service` by default, it perpetually exists in a state of error.
  * The user is now required to change some trivial feature of the
    `Service` just to trigger an update, so that we can see it succeed.

There are many situations like this. Another very common one is waiting
for test `Pod`s that are meant to successfully complete when some object
becomes live.

By triggering an empty update step for all resources that have any
initialization errors, we avoid all problems like this.

This commit will implement this empty-update semantics for partial
failures, as well as fix the display UX to correctly render the diff in
these cases.
2018-08-28 18:00:35 -07:00
Pat Gavlin 73f4f2c464
Reimplement refresh. (#1814)
Replace the Source-based implementation of refresh with a phase that
runs as the first part of plan execution and rewrites the snapshot in-memory.

In order to fit neatly within the existing framework for resource operations,
these changes introduce a new kind of step, RefreshStep, to represent
refreshes. RefreshSteps operate similar to ReadSteps but do not imply that
the resource being read is not managed by Pulumi.

In addition to the refresh reimplementation, these changes incorporate those
from #1394 to run refresh in the integration test framework.

Fixes #1598.
Fixes pulumi/pulumi-terraform#165.
Contributes to #1449.
2018-08-22 17:52:46 -07:00
Pat Gavlin 91e20289a8
Remove deploy.PlanSummary. (#1809)
Nothing actually uses this information.
2018-08-21 19:33:59 -07:00
Pat Gavlin 734f7beba7
Refactor plan execution in preparation for refresh. (#1801)
These changes simplify a couple aspects of plan execution in the hopes of
clarifying some responsibilities and preparing the code for changes to the
implementation of refresh.

1. All aspects of plan execution are now managed by the plan executor,
   which is no longer exported. Instead, it is abstracted behind
   `Plan.Execute`.
2. The plan executor's error-handling and reporting have been unified
   and simplified somewhat.
2018-08-21 14:05:00 -07:00
Sean Gillespie d1524e1081
Log errors coming from the language host (#1780)
* Log errors coming from the language host

Similar to pulumi/pulumi#1762, fixes pulumi/pulumi#1775. The language
host can fail without issuing any diagnostics and it is very unclear
what happens if the engine does not log the error.

* CR feedback
2018-08-20 16:41:07 -07:00
Matt Ellis acf0fb278a Fix wierd interactions due to Cobra and glog
The glog package force the use of golang's underyling flag package,
which Cobra does not use. To work around this, we had a complicated
dance around defining flags in multiple places, calling flag.Parse
explicitly and then stomping values in the flag package with values we
got from Cobra.

Because we ended up parsing parts of the command line twice, each with
a different set of semantics, we ended up with bad UX in some
cases. For example:

`$ pulumi -v=10 --logflow update`

Would fail with an error message that looked nothing like normal CLI
errors, where as:

`$ pulumi -v=10 update --logflow`

Would behave as you expect. To address this, we now do two things:

- We never call flag.Parse() anymore. Wacking the flags with values we
  got from Cobra is sufficent for what we care about.

- We use a forked copy of glog which does not complain when
  flag.Parse() is not called before logging.

Fixes #301
Fixes #710
Fixes #968
2018-08-20 14:08:40 -07:00
CyrusNajmabadi 89d5dd004e
Do not add the same file multiple times to a zip or tar file. (#1783) 2018-08-15 22:44:55 -07:00
Sean Gillespie d83774ca96
Fix two issues that can cause hangs during refresh (#1770)
1. 'readID' was never assigned to and was always the default value,
leading the refresh source to believe a resource was deleted
2. The refresh source could hang when a resource is deleted.
2018-08-13 21:43:10 -07:00
Sean Gillespie d9c56eab23
Emit diagnostics for errors coming from step generation (#1766)
The plan executor assumed that the step generator was responsible for
logging its own diagnostics, which it sort-of is but also doesn't log a
majority of the diagnositcs that come out of it. This commit logs all
errors coming out of step generation so that we don't unintentionally
drop errors.
2018-08-13 13:41:01 -07:00
Sean Gillespie 491bcdc602
Add a list of in-flight operations to the deployment (#1759)
* Add a list of in-flight operations to the deployment

This commit augments 'DeploymentV2' with a list of operations that are
currently in flight. This information is used by the engine to keep
track of whether or not a particular deployment is in a valid state.

The SnapshotManager is responsible for inserting and removing operations
from the in-flight operation list. When the engine registers an intent
to perform an operation, SnapshotManager inserts an Operation into this
list and saves it to the snapshot. When an operation completes, the
SnapshotManager removes it from the snapshot. From this, the engine can
infer that if it ever sees a deployment with pending operations, the
Pulumi CLI must have crashed or otherwise abnormally terminated before
seeing whether or not an operation completed successfully.

To remedy this state, this commit also adds code to 'pulumi stack
import' that clears all pending operations from a deployment, as well as
code to plan generation that will reject any deployments that have
pending operations present.

At the CLI level, if we see that we are in a state where pending
operations were in-flight when the engine died, we'll issue a
human-friendly error message that indicates which resources are in a bad
state and how to recover their stack.

* CR: Multi-line string literals, renaming in-flight -> pending

* CR: Add enum to apitype for operation type, also name status -> type for clarity

* Fix the yaml type

* Fix missed renames

* Add implementation for lifecycle_test.go

* Rebase against master
2018-08-10 21:39:59 -07:00
Alex Clemmer a172f1a048 Implement partial Read
Some time ago, we introduced the concept of the initialization error to
Pulumi (i.e., an error where the resource was successfully created but
failed to fully initialize). This was originally implemented in `Create`
and `Update`  methods of the resource provider interface; when we
detected an initialization failure, we'd pack the live version of the
object into the error, and return that to the engine.

Omitted from this initial implementation was a similar semantics for
`Read`. There are many implications of this, but one of them is that a
`pulumi refresh` will erase any initialization errors that had
previously been observed, even if the initialization errors still exist
in the resource.

This commit will introduce the initialization error semantics to `Read`,
fixing this issue.
2018-08-10 15:10:14 -07:00
Sean Gillespie 623e5f1be2
Emit reads for external resources when refreshing (#1749)
* Emit reads for external resources when refreshing

Fixes pulumi/pulumi#1744. This commit educates the refresh source about
external resources. If a refresh source encounters a resource with the
External bit set, it'll send a Read event to the engine and the engine
will process it accordingly.

* CR: save last event channel instead of last event, style fixes
2018-08-09 12:45:39 -07:00
Sean Gillespie 9a5f4044fa
Serialize SourceEvents coming from the refresh source (#1725)
* Serialize SourceEvents coming from the refresh source

The engine requires that a source event coming from a source be "ready
to execute" at the moment that it is sent to the engine. Since the
refresh source sent all goal states eagerly through its source iterator,
the engine assumed that it was legal to execute them all in parallel and
did so. This is a problem for the snapshot, since the snapshot expects
to be in an order that is a legal topological ordering of the dependency
DAG.

This PR fixes the issue by sending refresh source events one-at-a-time
through the refresh source iterator, only unblocking to send the next
step as soon as the previous step completes.

* Fix deadlock in refresh test

* Fix an issue where the engine "completed" steps too early

By signalling that a step is done before committing the step's results
to the snapshot, the engine was left with a race where dependent
resources could find themselves completely executed and committed before
a resource that they depend on has been committed.

Fixes pulumi/pulumi#1726

* Fix an issue with Replace steps at the end of a plan

If the last step that was executed successfully was a Replace, we could
end up in a situation where we unintentionally left the snapshot
invalid.

* Add a test

* CR: pass context.Context as first parameter to Iterate

* CR: null->nil
2018-08-08 13:45:48 -07:00
Pat Gavlin 5513f08669
Do not call Read in read steps with unknown IDs. (#1734)
This is consistent with the behavior prior to the introduction of Read
steps. In order to avoid a breaking change we must do this check in the
engine itself, which causes a bit of a layering violation: because IDs
are marshaled as raw strings rather than PropertyValues, the engine must
check against the marshaled form of an unknown directly (i.e.
`plugin.UnknownStringValue`).
2018-08-08 12:06:20 -07:00
Pat Gavlin 94802f5c16
Fix deletes with duplicate URNs. (#1716)
When calculating deletes, we will only issue a single delete step for a
particular URN. This is incorrect in the presence of pending deletes
that share URNs with a live resource if the pending deletes follow the
live resource in the checkpoint: instead of issuing a delete for
every resource with a particular URN, we will only issue deletes for
the pending deletes.

Before first-class providers, this was mostly benigin: any remaining
resources could be deleted by re-running the destroy. With the
first-class provider changes, however, the provider for the undeleted
resources will be deleted, leaving the checkpoint in an invalid state.

These changes fix this issue by allowing the step generator to issue
multiple deletes for a single URN and add a test for this scenario.
2018-08-07 11:01:08 -07:00
Pat Gavlin a222705143
Implement first-class providers. (#1695)
### First-Class Providers
These changes implement support for first-class providers. First-class
providers are provider plugins that are exposed as resources via the
Pulumi programming model so that they may be explicitly and multiply
instantiated. Each instance of a provider resource may be configured
differently, and configuration parameters may be source from the
outputs of other resources.

### Provider Plugin Changes
In order to accommodate the need to verify and diff provider
configuration and configure providers without complete configuration
information, these changes adjust the high-level provider plugin
interface. Two new methods for validating a provider's configuration
and diffing changes to the same have been added (`CheckConfig` and
`DiffConfig`, respectively), and the type of the configuration bag
accepted by `Configure` has been changed to a `PropertyMap`.

These changes have not yet been reflected in the provider plugin gRPC
interface. We will do this in a set of follow-up changes. Until then,
these methods are implemented by adapters:
- `CheckConfig` validates that all configuration parameters are string
  or unknown properties. This is necessary because existing plugins
  only accept string-typed configuration values.
- `DiffConfig` either returns "never replace" if all configuration
  values are known or "must replace" if any configuration value is
  unknown. The justification for this behavior is given
  [here](https://github.com/pulumi/pulumi/pull/1695/files#diff-a6cd5c7f337665f5bb22e92ca5f07537R106)
- `Configure` converts the config bag to a legacy config map and
  configures the provider plugin if all config values are known. If any
  config value is unknown, the underlying plugin is not configured and
  the provider may only perform `Check`, `Read`, and `Invoke`, all of
  which return empty results. We justify this behavior becuase it is
  only possible during a preview and provides the best experience we
  can manage with the existing gRPC interface.

### Resource Model Changes
Providers are now exposed as resources that participate in a stack's
dependency graph. Like other resources, they are explicitly created,
may have multiple instances, and may have dependencies on other
resources. Providers are referred to using provider references, which
are a combination of the provider's URN and its ID. This design
addresses the need during a preview to refer to providers that have not
yet been physically created and therefore have no ID.

All custom resources that are not themselves providers must specify a
single provider via a provider reference. The named provider will be
used to manage that resource's CRUD operations. If a resource's
provider reference changes, the resource must be replaced. Though its
URN is not present in the resource's dependency list, the provider
should be treated as a dependency of the resource when topologically
sorting the dependency graph.

Finally, `Invoke` operations must now specify a provider to use for the
invocation via a provider reference.

### Engine Changes
First-class providers support requires a few changes to the engine:
- The engine must have some way to map from provider references to
  provider plugins. It must be possible to add providers from a stack's
  checkpoint to this map and to register new/updated providers during
  the execution of a plan in response to CRUD operations on provider
  resources.
- In order to support updating existing stacks using existing Pulumi
  programs that may not explicitly instantiate providers, the engine
  must be able to manage the "default" providers for each package
  referenced by a checkpoint or Pulumi program. The configuration for
  a "default" provider is taken from the stack's configuration data.

The former need is addressed by adding a provider registry type that is
responsible for managing all of the plugins required by a plan. In
addition to loading plugins froma checkpoint and providing the ability
to map from a provider reference to a provider plugin, this type serves
as the provider plugin for providers themselves (i.e. it is the
"provider provider").

The latter need is solved via two relatively self-contained changes to
plan setup and the eval source.

During plan setup, the old checkpoint is scanned for custom resources
that do not have a provider reference in order to compute the set of
packages that require a default provider. Once this set has been
computed, the required default provider definitions are conjured and
prepended to the checkpoint's resource list. Each resource that
requires a default provider is then updated to refer to the default
provider for its package.

While an eval source is running, each custom resource registration,
resource read, and invoke that does not name a provider is trapped
before being returned by the source iterator. If no default provider
for the appropriate package has been registered, the eval source
synthesizes an appropriate registration, waits for it to complete, and
records the registered provider's reference. This reference is injected
into the original request, which is then processed as usual. If a
default provider was already registered, the recorded reference is
used and no new registration occurs.

### SDK Changes
These changes only expose first-class providers from the Node.JS SDK.
- A new abstract class, `ProviderResource`, can be subclassed and used
  to instantiate first-class providers.
- A new field in `ResourceOptions`, `provider`, can be used to supply
  a particular provider instance to manage a `CustomResource`'s CRUD
  operations.
- A new type, `InvokeOptions`, can be used to specify options that
  control the behavior of a call to `pulumi.runtime.invoke`. This type
  includes a `provider` field that is analogous to
  `ResourceOptions.provider`.
2018-08-06 17:50:29 -07:00
Sean Gillespie 0d0129e400
Execute non-delete step chains in parallel (#1673)
* Execute chains of steps in parallel

Fixes pulumi/pulumi#1624. Since register resource steps are known to be
ready to execute the moment the engine sees them, we can effectively
parallelize all incoming step chains. This commit adds the machinery
necessary to do so - namely a step executor and a plan executor.

* Remove dead code

* CR: use atomic.Value to be explicit about what values are atomically loaded and stored

* CR: Initialize atomics to 'false'

* Add locks around data structures in event callbacks

* CR: Add DegreeOfParallelism method on Options and add comment on select in Execute

* CR: Use context.Context for cancellation instead of cancel.Source

* CR: improve cancellation

* Rebase against master: execute read steps in parallel

* Please gometalinter

* CR: Inline a few methods in stepExecutor

* CR: Feedback and bug fixes

1. Simplify step_executor.go by 'bubbling' up errors as far as possible
and reporting diagnostics and cancellation in one place
2. Fix a bug where the CLI claimed that a plan was cancelled even if it
wasn't (it just has an error)

* Comments

* CR: Add comment around problematic select, move workers.Add outside of goroutine, return instead of break
2018-08-06 16:46:17 -07:00
Matt Ellis 645ca2eb56 Allow more types for runtimeOptions
Instead of just allowing booleans, type the map as string->interface{}
so in the future we could pass string or number options to the
language host.
2018-08-06 14:00:58 -07:00
Matt Ellis ce5eaa8343 Support TypeScript in a more first-class way
This change lets us set runtime specific options in Pulumi.yaml, which
will flow as arguments to the language hosts. We then teach the nodejs
host that when the `typescript` is set to `true` that it should load
ts-node before calling into user code. This allows using typescript
natively without an explicit compile step outside of Pulumi.

This works even when a tsconfig.json file is not present in the
application and should provide a nicer inner loop for folks writing
typescript (I'm pretty sure everyone has run into the "but I fixed
that bug!  Why isn't it getting picked up?  Oh, I forgot to run tsc"
problem.

Fixes #958
2018-08-06 14:00:58 -07:00
Sean Gillespie 48aa5e73f8
Save resources obtained from ".get" in the snapshot (#1654)
* Protobuf changes to record dependencies for read resources

* Add a number of tests for read resources, especially around replacement

* Place read resources in the snapshot with "external" bit set

Fixes pulumi/pulumi#1521. This commit introduces two new step ops: Read
and ReadReplacement. The engine generates Read and ReadReplacement steps
when servicing ReadResource RPC calls from the language host.

* Fix an omission of OpReadReplace from the step list

* Rebase against master

* Transition to use V2 Resources by default

* Add a semantic "relinquish" operation to the engine

If the engine observes that a resource is read and also that the
resource exists in the snapshot as a non-external resource, it will not
delete the resource if the IDs of the old and new resources match.

* Typo fix

* CR: add missing comments, DeserializeDeployment -> DeserializeDeploymentV2, ID check
2018-08-03 14:06:00 -07:00
CyrusNajmabadi 58ae413bca
Do not add a newline between a stream of info messages. The contract is that these will just be appended continguously. (#1688) 2018-08-02 10:55:15 -04:00
Sean Gillespie c4f08db78b
Fix an issue where we fail to catch duplicate URNs in the same plan (#1687) 2018-08-01 21:32:29 -07:00
Alex Clemmer b0c383e1e8 Add URN argument to HostClient#Log
This will make it possible to correlate log messages to specific
resources.
2018-08-01 11:00:48 -07:00
Sean Gillespie ad3b931bea
Merge pull request #1664 from pulumi/swgillespie/resource-break
Round out the breaking changes for ResourceV2
2018-07-27 18:44:37 -07:00
Pat Gavlin d70d36b887
Handle non-{unknown,partial} statuses in Create/Update. (#1663)
For example resource.StatusOK. Unenlightened providers may return errors
that result in this status; we should not crash if this is the case.
2018-07-27 16:08:11 -07:00
Sean Gillespie 48d095d66f Remove "down" operation for migration - it is not semantically valid in
general.
2018-07-27 14:52:28 -07:00
Alex Clemmer f037c7d143 Checkpoint resource initialization errors
When a resource fails to initialize (i.e., it is successfully created,
but fails to transition to a fully-initialized state), and a user
subsequently runs `pulumi update` without changing that resource, our
CLI will fail to warn the user that this resource is not initialized.

This commit begins the process of allowing our CLI to report this by
storing a list of initialization errors in the checkpoint.
2018-07-20 17:59:06 -07:00
Sean Gillespie 80c28c00d2
Add a migrate package for migrating to and from differently-versioned API types (#1647)
* Add a migrate package for migrating to and from differently-versioned
API types

* travis: gofmt -s deployment_test.go
2018-07-20 13:31:41 -07:00
Sean Gillespie 57ae7289f3
Work around a potentially bad assert in the engine (#1644)
* Work around a potentially bad assert in the engine

The engine asserts if presented with a plan that deletes the same URN
more than once. This has been empirically proven to be possible, so I am
removing the assert.

* CR: Add log for multiple pending-delete deletes
2018-07-18 15:48:55 -07:00
Alex Clemmer d182525fec Add signal cancellation to resource provider 2018-07-15 11:05:44 -10:00
Sean Gillespie 89f2f8abb5
[Parallelism] Introduce a "step generator" component in the engine (#1622)
* [Parallelism] Introduce a "step generator" component by refactoring all
step generation logic out of PlanIterator

* CR: remove dead fields on PlanIterator
2018-07-12 14:24:38 -07:00
CyrusNajmabadi 4761a32cc1
Add support for providing a log stream-id to our RPC interface. (#1627) 2018-07-11 15:04:00 -07:00
Alex Clemmer 582a002ccb FIX: Build break in partial update integration test 2018-07-06 18:03:42 -07:00
Alex Clemmer db9277f934
Merge pull request #1590 from hausdorff/hausdorff/partial-update
Add partial state update
2018-07-06 16:14:49 -07:00
Alex Clemmer 456deaf442 Small cleanups and comments 2018-07-06 15:57:08 -07:00
Joe Duffy b9a0907161
Support empty text assets (#1599)
Per #1481, we unintentionally disallowed empty text assets, simply
because of the way we did discriminated union testing.  It's easy
enough to just treat the empty asset like an empty string asset.
2018-07-05 14:30:35 -07:00
Sean Gillespie 1cbf8bdc40 Partial status for resource providers
This commit adds CLI support for resource providers to provide partial
state upon failure. For resource providers that model resource
operations across multiple API calls, the Provider RPC interface can now
accomodate saving bags of state for resource operations that failed.
This is a common pattern for Terraform-backed providers that try to do
post-creation steps on resource as part of Create or Update resource
operations.
2018-07-02 13:32:23 -07:00
Pat Gavlin 0c8dedec22
Issue an error when attempting to read an invalid Asset. (#1528)
As an alternative we could consider simply returning an empty `Blob`.
I think it's better to fail loudly, though, as this situation can result
from unexpected/invalid archives (which we need to do a better job of
validating).

Fixes #1493.
2018-06-18 11:08:17 -07:00
Matthew Riley bdb3e98aa0 Use an even more reasonable modtime in ZIP entries
The ZIP format started with MS-DOS dates, which start in 1980. Other dates
have been layered on, but the ZIP file handler used by Azure websites still
relies on the MS-DOS dates.

Using the Unix epoch here (1970) results in ZIP entries that (e.g.)
OSX `unzip` sees as 12-31-1969 (timezones) but Azure websites sees as
01/01/2098.
2018-06-11 19:36:04 -07:00
Pat Gavlin e6849a283f Appease linters.
- Fix a couple self-assignment issues in the Go language support
- Disable `megacheck` for `fh.SetModTime`, which we use for go1.9
  compat.
2018-06-11 14:32:27 -07:00
joeduffy 7d8995991b Support Pulumi programs written in Go
This adds rudimentary support for Pulumi programs written in Go.  It
is not complete yet but the basic resource registration works.

Note that, stylistically speaking, Go is a bit different from our other
languages.  This made it a bit easier to build this initial prototype,
since what we want is actually a rather thin veneer atop our existing
RPC interfaces.  The lack of generics, however, adds some friction and
is something I'm continuing to hammer on; this will most likely lead to
little specialized types (e.g. StringOutput) once the dust settles.

There are two primary components:

1) A new language host, `pulumi-language-go`, which is responsible for
   communicating with the engine through the usual gRPC interfaces.
   Because Go programs are pre-compiled, it very simply loads a binary
   with the same name as the project.

2) A client SDK library that Pulumi programs bind against.  This exports
   the core resource types -- including assets -- properties -- including
   output properties -- and configuration.

Most remaining TODOs are marked as such in the code, and this will not
be merged until they have been addressed, and some better tests written.
2018-06-08 10:36:10 -07:00
Matthew Riley 9916cd5e6b
Merge pull request #1475 from pulumi/zip-header
Use a reasonable value for Modified in ZIP headers
2018-06-07 14:40:10 -07:00
Matthew Riley 2fe284a139 Use a reasonable value for Modified in ZIP headers
Azure websites can't extract the archive without this.

We can't use the `Modified` field of `FileHeader` because it was added in
Go 1.10.
2018-06-07 14:21:03 -07:00
Sean Gillespie b5e4d87687
Improve the error message when data source invocations fail (#1472) 2018-06-07 11:21:38 -07:00
Sean Gillespie 924c49d7e0
Fail fast when attempting to load a too-new or too-old deployment (#1382)
* Error when loading a deployment that is not a version that the CLI understands

* Add a test for 'pulumi stack import' on a badly-versioned deployment

* Move current deployment version to 'apitype'

* Rebase against master

* CR: emit CLI-friendly error message at the two points outside of the engine calling 'DeserializeDeployment'
2018-05-25 13:29:59 -07:00
Sean Gillespie 1a51507206
Delete Before Create (#1365)
* Delete Before Create

This commit implements the full semantics of delete before create. If a
resource is replaced and requires deletion before creation, the engine
will use the dependency graph saved in the snapshot to delete all
resources that depend on the resource being replaced prior to the
deletion of the resource to be replaced.

* Rebase against master

* CR: Simplify the control flow in makeRegisterResourceSteps

* Run Check on new inputs when re-creating a resource

* Fix an issue where the planner emitted benign but incorrect deletes of DBR-deleted resources

* CR: produce the list of dependent resources in dependency order and iterate over the list in reverse

* CR: deps->dependents, fix an issue with DependingOn where duplicate nodes could be added to the dependent set

* CR: Fix an issue where we were considering old defaults and new inputs
inappropriately when re-creating a deleted resource

* CR: save 'iter.deletes[urn]' as a local, iterate starting at cursorIndex + 1 for dependency graph
2018-05-23 14:43:17 -07:00
joeduffy 5967259795 Add license headers 2018-05-22 15:02:47 -07:00
Sean Gillespie 7b7870cdaa
Remove unused stack name from deploy.Snapshot (#1386) 2018-05-18 11:15:35 -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
CyrusNajmabadi 72e00810c4
Filter the logs we emit to glog so that we don't leak out secrets. (#1371) 2018-05-15 15:28:00 -07:00
Joe Duffy 369c619ab9
Skip loading language plugins when not needed (#1367)
In pulumi/pulumi#1356, we observed that we can fail during a destroy
because we attempt to load the language plugin, which now eagerly looks
for the @pulumi/pulumi package.

This is also blocking ingestion of the latest engine bits into the PPC.

It turns out that for destroy (and refresh), we have no need for the
language plugin.  So, let's skip loading it when appropriate.
2018-05-14 20:32:53 -07:00
Joe Duffy 457c34ff50
Add a PULUMI_DEV flag, and suppress warnings (#1361)
This change suppresses the warning

    warning: resource plugin aws is expected to have version >=0.11.3,
        but has 0.11.1-dev-1523506162-g06ec765; the wrong version may
        be on your path, or this may be a bug in the plugin

when the PULUMI_DEV envvar is set to a truthy value.

This warning keeps popping up in demos since I'm always using dev builds
and I'd like a way to shut it off, even though this can legitimately
point out a problem.  Eventually I'll switch to official buildsa but,
until then, it seems worth having a simple way to suppress.
2018-05-11 20:59:01 -07:00
Pat Gavlin bb5b7da650 Revert "Revert the changes from #1261." 2018-05-08 11:46:15 -07:00
Pat Gavlin 97ace29ab1
Begin tracing Pulumi API calls. (#1330)
These changes enable tracing of Pulumi API calls.

The span with which to associate an API call is passed via a
`context.Context` parameter. This required plumbing a
`context.Context` parameter through a rather large number of APIs,
especially in the backend.

In general, all API calls are associated with a new root span that
exists for essentially the entire lifetime of an invocation of the
Pulumi CLI. There were a few places where the plumbing got a bit hairier
than I was willing to address with these changes; I've used
`context.Background()` in these instances. API calls that receive this
context will create new root spans, but will still be traced.
2018-05-07 18:23:03 -07:00
CyrusNajmabadi 092696948d
Restore streaming of plugin outputs to the progress display. (#1333) 2018-05-07 15:11:52 -07:00
Joe Duffy f92eb0a4e8 Run Configure calls in parallel (#1321)
As of this change, the engine will run all Configure calls in parallel.
This improves startup performance, since otherwise, we would block
waiting for all plugins to be configured before proceeding to run a
program.  Emperically, this is about 1.5-2s for AWS programs, and
manifests as a delay between the purple "Previewing update of stack"
being printed, and the corresponding grey "Previewing update" message.

This is done simply by using a Goroutine for Configure, and making sure
to synchronize on all actual CRUD operations.  I toyed with using double
checked locking to eliminate lock acquisitions -- something we may want
to consider as we add more fine-grained parallelism -- however, I've
kept it simple to avoid all the otherwise implied memory model woes.

I made the judgment call that GetPluginInfo may proceed before
Configure has settled.  (Otherwise, we'd immediately call it and block
after loading the plugin, obviating the parallelism benefits.)  I also
made the judgment call to do this in the engine, after flip flopping
several times about possibly making it a provider's own decision.
2018-05-04 14:29:47 -07:00
Pat Gavlin 639e605bed Revert the changes from #1261.
Restore the provider-first diff logic these changes disabled.

Part of #1251.
2018-05-01 10:01:18 -07:00
Luke Hoban 7dac925bcf
Fix handling of nested archives (#1283)
AssetArchives which include nested archives were not embedding content from the nested archive underneath the key of the nest archive.

Fixes #1272.
2018-04-27 17:10:50 -07:00
Sean Gillespie 14baf866f6
Snapshot management overhaul and refactor (#1273)
* Refactor the SnapshotManager interface

Lift snapshot management out of the engine by delegating it to the
SnapshotManager implementation in pkg/backend.

* Add a event interface for plugin loads and use that interface to record plugins in the snapshot

* Remove dead code

* Add comments to Events

* Add a number of tests for SnapshotManager

* CR feedback: use a successful bit on 'End' instead of having a separate 'Abort' API

* CR feedback

* CR feedback: register plugins one-at-a-time instead of the entire state at once
2018-04-25 17:20:08 -07:00
pat@pulumi.com ca2e996428 Work around issue #1251.
This issue arises becuase the behavior we're currently getting from Diff
for TF-based providers differs from the behavior we expect. We are
presenting the provider with the old state and new inputs. If the old
state contains output properties that differ from the new inputs, the
provider will detect a diff where we may expect no changes.

Rather than deferring to the provider for all diffs, these changes only
defer to the provider if a legacy diff was detected (i.e. there is some
difference between the old and new provider-calculated inputs).
2018-04-24 10:35:27 -07:00
pat@pulumi.com 42b67a4dbc Fix a couple of typos.
- Restore a dropped "update"
- %s/Resouce/Resource/g
2018-04-20 11:09:54 -07:00
Matt Ellis cc938a3bc8 Merge remote-tracking branch 'origin/master' into ellismg/identity 2018-04-20 01:56:41 -04:00
joeduffy bac58d7922 Respond to CR feedback
Incorporate feedback from @swgillespie and @pgavlin.
2018-04-18 11:46:37 -07:00
joeduffy b77403b4bb Implement a refresh command
This change implements a `pulumi refresh` command.  It operates a bit
like `pulumi update`, and friends, in that it supports `--preview` and
`--diff`, along with the usual flags, and will update your checkpoint.

It works through substitution of the deploy.Source abstraction, which
generates a sequence of resource registration events.  This new
deploy.RefreshSource takes in a prior checkpoint and will walk it,
refreshing the state via the associated resource providers by invoking
Read for each resource encountered, and merging the resulting state with
the prior checkpoint, to yield a new resource.Goal state.  This state is
then fed through the engine in the usual ways with a few minor caveats:
namely, although the engine must generate steps for the logical
operations (permitting us to get nice summaries, progress, and diffs),
it mustn't actually carry them out because the state being imported
already reflects reality (a deleted resource has *already* been deleted,
so of course the engine need not perform the deletion).  The diffing
logic also needs to know how to treat the case of refresh slightly
differently, because we are going to be diffing outputs and not inputs.

Note that support for managed stacks is not yet complete, since that
requires updates to the service to support a refresh endpoint.  That
will be coming soon ...
2018-04-18 10:57:16 -07:00
Matt Ellis b5129dba19 Don't leak a file from asset_test.go 2018-04-18 04:54:02 -07:00
Matt Ellis bac02f1df1 Remove the need to pulumi init for the local backend
This change removes the need to `pulumi init` when targeting the local
backend. A fair amount of the change lays the foundation that the next
set of changes to stop having `pulumi init` be used for cloud stacks
as well.

Previously, `pulumi init` logically did two things:

1. It created the bookkeeping directory for local stacks, this was
stored in `<repository-root>/.pulumi`, where `<repository-root>` was
the path to what we belived the "root" of your project was. In the
case of git repositories, this was the directory that contained your
`.git` folder.

2. It recorded repository information in
`<repository-root>/.pulumi/repository.json`. This was used by the
cloud backend when computing what project to interact with on
Pulumi.com

The new identity model will remove the need for (2), since we only
need an owner and stack name to fully qualify a stack on
pulumi.com, so it's easy enough to stop creating a folder just for
that.

However, for the local backend, we need to continue to retain some
information about stacks (e.g. checkpoints, history, etc). In
addition, we need to store our workspace settings (which today just
contains the selected stack) somehere.

For state stored by the local backend, we change the URL scheme from
`local://` to `local://<optional-root-path>`. When
`<optional-root-path>` is unset, it defaults to `$HOME`. We create our
`.pulumi` folder in that directory. This is important because stack
names now must be unique within the backend, but we have some tests
using local stacks which use fixed stack names, so each integration
test really wants its own "view" of the world.

For the workspace settings, we introduce a new `workspaces` directory
in `~/.pulumi`. In this folder we write the workspace settings file
for each project. The file name is the name of the project, combined
with the SHA1 of the path of the project file on disk, to ensure that
multiple pulumi programs with the same project name have different
workspace settings.

This does mean that moving a project's location on disk will cause the
CLI to "forget" what the selected stack was, which is unfortunate, but
not the end of the world. If this ends up being a big pain point, we
can certianly try to play games in the future (for example, if we saw
a .git folder in a parent folder, we could store data in there).

With respect to compatibility, we don't attempt to migrate older files
to their newer locations. For long lived stacks managed using the
local backend, we can provide information on where to move things
to. For all stacks (regardless of backend) we'll require the user to
`pulumi stack select` their stack again, but that seems like the
correct trade-off vs writing complicated upgrade code.
2018-04-18 04:53:49 -07:00
Sean Gillespie 55711e4ca3
Revert "Lift snapshot management out of the engine and serialize writes to snapshot (#1069)" (#1216)
This reverts commit 2c479c172d.
2018-04-16 23:04:56 -07:00
Joe Duffy 10f4f2c7c4
Revert "Temporarily work around pulumi/pulumi#1147 (#1161)" (#1207)
This reverts commit 9c243720a6.
2018-04-16 12:29:52 -07:00
CyrusNajmabadi 7b96b8cdcf
Produce a single message for the text we receive when running, not a message per line of output. (#1191) 2018-04-13 15:44:35 -07:00
Joe Duffy 9c243720a6
Temporarily work around pulumi/pulumi#1147 (#1161)
This reverts back to our old diff behavior, temporarily, while we
work on a fix to pulumi/pulumi#1147 and validate that it works broadly.
2018-04-12 10:59:25 -07:00
Sean Gillespie 2c479c172d
Lift snapshot management out of the engine and serialize writes to snapshot (#1069)
* Lift snapshot management out of the engine

This PR is a prerequisite for parallelism by addressing a major problem
that the engine has to deal with when performing parallel resource
construction: parallel mutation of the global snapshot. This PR adds
a `SnapshotManager` type that is responsible for maintaining and
persisting the current resource snapshot. It serializes all reads and
writes to the global snapshot and persists the snapshot to persistent
storage upon every write.

As a side-effect of this, the core engine no longer needs to know about
snapshot management at all; all snapshot operations can be handled as
callbacks on deployment events. This will greatly simplify the
parallelization of the core engine.

Worth noting is that the core engine will still need to be able to read
the current snapshot, since it is interested in the dependency graphs
contained within. The full implications of that are out of scope of this
PR.

Remove dead code, Steps no longer need a reference to the plan iterator that created them

Fixing various issues that arise when bringing up pulumi-aws

Line length broke the build

Code review: remove dead field, fix yaml name error

Rebase against master, provide implementation of StackPersister for cloud backend

Code review feedback: comments on MutationStatus, style in snapshot.go

Code review feedback: move SnapshotManager to pkg/backend, change engine to use an interface SnapshotManager

Code review feedback: use a channel for synchronization

Add a comment and a new test

* Maintain two checkpoints, an immutable base and a mutable delta, and
periodically merge the two to produce snapshots

* Add a lot of tests - covers all of the non-error paths of BeginMutation and End

* Fix a test resource provider

* Add a few tests, fix a few issues

* Rebase against master, fixed merge
2018-04-12 09:55:34 -07:00
Matt Ellis 50843a98c1 Retry some HTTP operations
We've seen failures in CI where DNS lookups fail which cause our
operations against the service to fail, as well as other sorts of
timeouts.

Add a set of helper methods in a new httputil package that helps us do
retries on these operations, and then update our client library to use
them when we are doing GET requests. We also provide a way for non GET
requests to be retried, and use this when updating a lease (since it
is safe to retry multiple requests in this case).
2018-04-11 14:58:25 -07:00
Joe Duffy 479a2e6ad5
Add an ID property to ReadResponse (#1145)
The RPC provider interface needs a way to convey back to the engine
that a resource being read no longer exists.  To do this, we'll return
the ID property that was read back.  If it is empty, it means the
resource is gone.  If it is non-empty, we expect it to match the input.
2018-04-10 12:58:50 -07:00
CyrusNajmabadi a759f2e085
Switch to a resource-progress oriented view for pulumi preview/update/destroy (#1116) 2018-04-10 12:03:11 -07:00
Joe Duffy b33d4d762c
Skip reading unknown IDs (#1124)
This change skips unknown IDs during read operations.  This can happen
when a read is performed using the output property of another resource
during planning.  This is intentionally supported via ID being an
Input<ID> and all we need to do for this to work correctly is skip the
actual provider RPC and the runtime will propagate unknown outputs as
usual.
2018-04-07 07:52:10 -07:00
Joe Duffy f2ae3a7afc
Permit plugin versions to float (#1122)
This change lets plugin versions to float in two ways:

1) If a `pulumi plugin install` detects a newer version is available
   already, there's no need to download and install the older version.

2) If the engine attempts to load a plugin at a particular version,
   if a newer version is available, it will be accepted without error.

As part of this, we permit $PATH to have the final say when determining
which version to accept.  That is, it can always override the choice.

Note that I highly suspect, in the limit, that we'll want to stop doing
this for major version incompatibilities. For now, since we don't
envision any such version changes imminently, this will suffice.
2018-04-05 16:37:50 -07:00
joeduffy 5e28a4ab07 Add the ability to read an existing resource
This change wires up the new Read RPC method in such a manner that
Pulumi programs can invoke it.  This is technically not required for
refreshing state programmatically (as in pulumi/pulumi#1081), however
it's a feature we had eons ago and have wanted since (see
pulumi/pulumi#83), and will allow us to write code like

    let vm = aws.ec2.Instance.get("my-vm", "i-07043cd97bd2c9cfc");
    // use any property from here on out ...

The way this works is simply by bridging the Pulumi program via its
existing RPC connection to the engine, much like Invoke and
RegisterResource RPC requests already do, and then invoking the proper
resource provider in order to read the state.  Note that some resources
cannot be uniquely identified by their ID alone, and so an extra
resource state bag may be provided with just those properties required.

This came almost for free (okay, not exactly) and will come in handy as
we start gaining experience with reading live state from resources.
2018-04-05 09:48:09 -07:00
joeduffy 22584e7e37 Make some resource model changes
This commit changes two things about our resource model:

* Stop performing Pulumi Engine-side diffing of resource state.
  Instead, we defer to the resource plugins themselves to determine
  whether a change was made and, if so, the extent of it.  This
  manifests as a simple change to the Diff function; it is done in
  a backwards compatible way so that we continue with legacy diffing
  for existing resource provider plugins.

* Add a Read RPC method for resource providers.  It simply takes a
  resource's ID and URN, plus an optional bag of further qualifying
  state, and it returns the current property state as read back from
  the actual live environment.  Note that the optional bag of state
  must at least include enough additional properties for resources
  wherein the ID is insufficient for the provider to perform a lookup.
  It may, however, include the full bag of prior state, for instance
  in the case of a refresh operation.

This is part of pulumi/pulumi#1108.
2018-04-05 08:14:25 -07:00
Sean Gillespie a3a6101e79
Improve the error message arising from missing required configs for resource providers (#1097)
* Improve the error message arising from missing required configs for
resource providers

If the resource provider that we are speaking to is new enough, it will send
across a list of keys and their descriptions alongside an error
indicating that the provider we are configuring is missing required
config. This commit packages up the list of missing keys into an error
that can be presented nicely to the user.

* Code review feedback: renaming simplification and correcting errors in comments
2018-04-04 10:08:17 -07:00
CyrusNajmabadi 4b761f9fc1
Include richer information in events so that final display can flexibly chose how to present it. (#1088) 2018-03-31 12:08:48 -07:00
Sean Gillespie 91c550f1e0
Send structured errors across RPC boundaries (#1072)
* Send structured errors across RPC boundaries

This brings us closer to gRPC best practices where we send structured
errors with error codes across RPC endpoints. The new "rpcerrors"
package can wrap errors from RPC endpoints, so RPC servers can attach
some additional context as to why a request failed.

* Code review feedback:

1. Rename rpcerrors -> rpcerror, better package name
2. Rename RPCError -> Error, RPCErrorCause -> ErrorCause, names
suggested by gometalinter to improve their package-qualified names
3. Fix import organization in rpcerror.go
2018-03-28 17:07:35 -07:00
joeduffy 16e45dc92a Remove some outdated comments 2018-03-28 07:56:35 -07:00
joeduffy 8b5874dab5 General prep work for refresh
This change includes a bunch of refactorings I made in prep for
doing refresh (first, the command, see pulumi/pulumi#1081):

* The primary change is to change the way the engine's core update
  functionality works with respect to deploy.Source.  This is the
  way we can plug in new sources of resource information during
  planning (and, soon, diffing).  The way I intend to model refresh
  is by having a new kind of source, deploy.RefreshSource, which
  will let us do virtually everything about an update/diff the same
  way with refreshes, which avoid otherwise duplicative effort.

  This includes changing the planOptions (nee deployOptions) to
  take a new SourceFunc callback, which is responsible for creating
  a source specific to the kind of plan being requested.

  Preview, Update, and Destroy now are primarily differentiated by
  the kind of deploy.Source that they return, rather than sprinkling
  things like `if Destroying` throughout.  This tidies up some logic
  and, more importantly, gives us precisely the refresh hook we need.

* Originally, we used the deploy.NullSource for Destroy operations.
  This simply returns nothing, which is how Destroy works.  For some
  reason, we were no longer doing this, and instead had some
  `if Destroying` cases sprinkled throughout the deploy.EvalSource.
  I think this is a vestige of some old way we did configuration, at
  least judging by a comment, which is apparently no longer relevant.

* Move diff and diff-printing logic within the engine into its own
  pkg/engine/diff.go file, to prepare for upcoming work.

* I keep noticing benign diffs anytime I regenerate protobufs.  I
  suspect this is because we're also on different versions.  I changed
  generate.sh to also dump the version into grpc_version.txt.  At
  least we can understand where the diffs are coming from, decide
  whether to take them (i.e., a newer version), and ensure that as
  a team we are monotonically increasing, and not going backwards.

* I also tidied up some tiny things I noticed while in there, like
  comments, incorrect types, lint suppressions, and so on.
2018-03-28 07:45:23 -07:00
Pat Gavlin a23b10a9bf
Update the copyright end date to 2018. (#1068)
Just what it says on the tin.
2018-03-21 12:43:21 -07:00
Joe Duffy 5924f6b8c3
Ensure destroy plugins are present (#1043)
This change uses the prior checkpoint's deployment manifest to pre-
populate all plugins required to complete the destroy operation.  This
allows for subsequent attempts to load a resource's plugin to match the
already-loaded version.  This approach obviously doesn't work in a
hypothetical future world where plugins for the same resource provider
are loaded side-by-side, but we already know that.
2018-03-12 16:27:39 -07:00
Matt Ellis 936cab0c22 Add a version property to checkpoints
This takes the existing `apitype.Checkpoint` type and renames it to
`apitype.CheckpointV1` locking in the shape. In addition, we introduce
a `apitype.VersionedCheckpoint` type, which holds a version number and
a json document representing a checkpoint at that version. Now, when
reading a checkpoint, the CLI can determine if it's in a format it
understands, and fail gracefully if it is not.

While the CLI understands the older checkpoint version, it always
writes the newest version format, meaning that if you manage a
fire-and-forget stack with this version of the CLI, it will be
un-readable by previous versions.

Stacks managed by Pulumi.com are not impacted by this change.

Fixes: #887
2018-03-10 13:03:05 -08:00
Sean Gillespie 703a954839
Improve error messages output by the CLI (#1011)
* Improve error messages output by the CLI

This fixes a couple known issues with the way that we present errors
from the Pulumi CLI:
    1. Any errors from RPC endpoints were bubbling up as they were to
    the top-level, which was unfortunate because they contained
    RPC-specific noise that we don't want to present to the user. This
    commit unwraps errors from resource providers.
    2. The "catastrophic error" message often got printed twice
    3. Fatal errors are often printed twice, because our CLI top-level
    prints out the fatal error that it receives before exiting. A lot of
    the time this error has already been printed.
    4. Errors were prefixed by PU####.

* Feedback: Omit the 'catastrophic' error message and use a less verbose error message as the final error

* Code review feedback: interpretRPCError -> resourceStateAndError

* Code review feedback: deleting some commented-out code, error capitalization

* Cleanup after rebase
2018-03-09 15:43:16 -08:00
Matt Ellis 344d9b4424
Merge pull request #1025 from pulumi/SerializePluginLoads
Serialize plugin loads.
2018-03-09 15:20:42 -08:00
Matt Ellis 96d39b60d1 Filter secrets from Pulumi's outputs
When a stack has secrets, we now take the secret values and construct
a regular expression which is just an alternation of all the secret
values. Then, before pushing any string data into an Event, we run the
regular expression and replace all matches with '[secret]'.

Fixes #747
2018-03-09 13:23:25 -08:00
pat@pulumi.com dc36b9569a Serialize plugin loads.
As it stands, we allow plugin load requests to race. Not only does this
create a situation in which we may load and then immediately throw away
a plugin (potentially leaking its process), it also creates the
possibility of races when reading from/writing to the various plugin
caches. These changes serialize all plugin loads and cache accesses by
running all accesses for a particular host in a single goroutine.

Fixes #1020.
2018-03-09 11:31:02 -08:00
Matt Ellis 731463c282 Have MakeKey fail if namespace contains a colon
This helper method is only really used for testing, but we should not
allow it to create a Key who's namespace has a colon (as ParseKey
would not build something like this).
2018-03-08 11:52:48 -08:00
Matt Ellis 5dfd720bc3 Remove config.AsModuleMember()
This API was introduced to aid the refactoring, but it isn't something
we want to support long term. Remove it and for a few places, push
passing config.Key around more, instead of converting to the old type
eagerly.
2018-03-08 10:52:25 -08:00
Matt Ellis 9f363a1322 Change JSON/YAML representation of config.Key
When serializing config.Key's we now write them as <package>:<name>
instead of <package>:config:<name>. We continue to support reading the
older format for compatability with older files.
2018-03-08 10:52:25 -08:00
Matt Ellis fd84c11ca5 Don't export config.FromModuleMember
config.ParseKey should be used instead.
2018-03-08 10:52:25 -08:00
Matt Ellis 81a273c7bb Change represention of config.Key
config.Key has become a pair of namespace and name. Because the whole
world has not changed yet, there continues to be a way to convert
between a tokens.ModuleMember and config.Key, however now sometime the
conversion from tokens.ModuleMember can fail (when the module member
is not of the form `<package>:config:<name>`).
2018-03-08 10:52:25 -08:00
Matt Ellis 36ab2ce9f2 Add JSON and YAML marhsalling tests for config.{Key,Map}
I'll be changing the structure of the representation of config.Key, so
let's write some tests first to ensure we can continue to treat
everything as JSON and YAML.
2018-03-08 10:52:25 -08:00
Matt Ellis 9ae36e78dd Split value.go into a few files
No code changes, just re-ordering some things into seperate files
which are logically distinct.
2018-03-08 10:52:25 -08:00
Matt Ellis 7c39620e9a Introduce config.Key
Right now, config.Key is a type alias for tokens.ModuleMember. I did a
pass over the codebase such that we use config.Key everywhere it
looked like the value did not leak to some external process (e.g a
resource provider or a langhost).

Doing this makes it a little clearer (hopefully) where code is
depending on a module member structure (e.g. <package>:config:<value>)
instead of just an opaque type.
2018-03-08 10:52:25 -08:00
pat@pulumi.com 45a4a41e0d Configure resource providers upon load.
As it stands, we only configure those providers for which configuration
is present. This can lead to surprising failure modes if those providers
are then used to create resources. These changes ensure that all
resource providers that are not configured during plan initialization
are configured upon first load.

Fixes #758.
2018-03-06 16:38:53 -08:00
Joe Duffy 09cceb4e9e
Remove a few outdated references (#997) 2018-03-04 13:34:20 -08:00
Matt Ellis 4b850dcb15 Remove pkg/resource/idl
A hold-over from a previous experiment (LumiIDL) which we don't use
anymore. If we decide to bring that back, we can easily restore these
types, but for now, let's just remove this dead code.
2018-02-28 17:41:04 -08:00
Matt Ellis eb1b9d685f Remove pkg/compiler/errors
Most of the errors in this package are holdovers from our previous
syetem where we had our own custom compiler and evaluator and are no
longer needed. The few we still use during plan applicaton (via the
diagnostics system, which is another component from the old system
that we still use) have been promoted into the diag package. Doing so,
allows us to not have to import "github.com/pkg/errors" as "goerr" in
some parts of the engine, a nice cleaup.
2018-02-28 17:41:04 -08:00
joeduffy 2362d45a5c Eliminate type redundancy
Despite our good progress moving towards having an apitype package,
where our exchange types live and can be shared among the engine and
our services, there were a few major types that were still duplciated.
Resource was the biggest example -- and indeed, the apitype varirant
was missing the new Dependencies property -- but there were others,
like Manfiest, PluginInfo, etc.  These too had semi-random omissions.

This change merges all of these types into the apitype package.  This
not only cleans up the redundancy and missing properties, but will
"force the issue" with respect to keeping them in sync and properly
versioning the information in a backwards compatible way.

The resource/stack package still exists as a simple marshaling layer
to and from the engine's core data types.

Finally, I've made the controversial change to share the actual
Deployment data structure at the apitype layer also.  This will force
us to confront differences in that data structure similarly, and will
allow us to leverage the strong typing throughout to catch issues.
2018-02-28 12:44:55 -08:00
Matt Ellis ed7a4d9157 Check plugin cache first; make version mismatch a warning
Previously, we would prefer a plugin on the $PATH which is more or
less always the case for people hacking on `pulumi`. Later, when we
went to check the loaded plugin version matched the one we requested,
we fail.

Now, if we have a version, we'll first consult the local plugin
cache. If that fails, we'll fall back to the $PATH as we used to.

When we are loading a plugin without a version, we continue to use the
one on the $PATH (without testing the cache) on the assumption it is
newer.

In addition, we've turned the "plugin versions are mis-matched" from
an error into a warning. We expect that we'll only ever see this
warning when something strange is going on (since in the normal case,
we'll have found the exact version in the cache) but having it not
hard fail does help in development cases.

Fixes #977
2018-02-26 11:39:50 -08:00
joeduffy d9a143c8a1 Implement the Python langhost RPC server
This change adds a basic Python langhost RPC server.  It's fairly
barebones and merely acts as a jumping off point for the Pulumi engine
to spawn a Python program.  The host is written in Go, in contrast to
implementing the host in Python, and more closely resembles how I
expect the Node.js language host to work once pulumi/pulumi#331 is done.
2018-02-23 19:33:02 -08:00
Sean Gillespie 9757d069ed
Merge pull request #972 from pulumi/swgillespie/dependency-view
Save resource dependency information in the checkpoint file
2018-02-23 11:19:38 -08:00
Sean Gillespie b84320b45e
Code review feedback:
1. Various idiomatic Go and TypeScript fixes
    2. Add an integration test that end-to-end roundtrips dependency
    information for a simple Pulumi program
    3. Add an additional test assert that tests that dependency information
    comes from the language host as expected
2018-02-22 13:33:50 -08:00
Joe Duffy d57a456269
Tolerate missing GetRequiredPlugins RPC method (#973)
This change makes the engine backwards compatible with older
language host binaries, by simply ignoring GetRequiredPlugins
calls when the RPC server has not yet implemented it.  This
is benign, since we will eventually fault plugins in on demand,
although it does mean that commands like `pulumi plugin install`
will become no-ops (which, thankfully, is what we want).
2018-02-22 07:50:37 -08:00
Sean Gillespie ad06e9b0d8
Save resource dependency information in the checkpoint file
This commit does two things:
    1. All dependencies of a resource, both implicit and explicit, are
    communicated directly to the engine when registering a resource. The
    engine keeps track of these dependencies and ultimately serializes
    them out to the checkpoint file upon successful deployment.
    2. Once a successful deployment is done, the new `pulumi stack
    graph` command reads the checkpoint file and outputs the dependency
    information within in the DOT format.

Keeping track of dependency information within the checkpoint file is
desirable for a number of reasons, most notably delete-before-create,
where we want to delete resources before we have created their
replacement when performing an update.
2018-02-21 17:49:09 -08:00
Joe Duffy e7af13e144
Capture plugin names in the manifest (#967)
Previously, the checkpoint manifest contained the full path to a plugin
binary, in places of its friendly name.  Now that we must move to a model
where we install plugins in the PPC based on the manifest contents, we
actually need to store the name, in addition to the version (which is
already there).  We still also capture the path for debugging purposes.
2018-02-21 10:32:31 -08:00
joeduffy 225bfd46b3 Don't block on nil channels
We have had a long-standing bug in here where we waiting on a
stdout channel that never got populated, when the language plugin
fails to load entirely.  This would lead to hung processes.  The
fix is simple: only wait for stdout/stderr channels to drain that
have actually been wired up to enjoy the requisite signaling.
2018-02-19 14:06:15 -08:00
joeduffy 25f5a71568 Add support for project plugins
This adds support for two things:

* Installing all plugins that a project requires with a single command:

    $ pulumi plugin install

* Listing the plugins that this project requires:

    $ pulumi plugin ls --project
    $ pulumi plugin ls -p
2018-02-19 11:24:19 -08:00
joeduffy 548c22d014 Reimplement GetRequiredPlugins in Go
This brings back the Node.js language plugin's GetRequiredPlugins
function, reimplemented in Go now that the language host has been
rewritten from JavaScript.  Fairly rote translation, along with
some random fixes required to get tests passing again.
2018-02-18 08:08:15 -08:00
joeduffy c04341edb2 Consult the program for its list of plugins
This change adds a GetRequiredPlugins RPC method to the language
host, enabling us to query it for its list of plugin requirements.
This is language-specific because it requires looking at the set
of dependencies (e.g., package.json files).

It also adds a call up front during any update/preview operation
to compute the set of plugins and require that they are present.
These plugins are populated in the cache and will be used for all
subsequent plugin-related operations during the engine's activity.

We now cache the language plugins, so that we may load them
eagerly too, which we never did previously due to the fact that
we needed to pass the monitor address at load time.  This was a
bit bizarre anyhow, since it's really the Run RPC function that
needs this information.  So, to enable caching and eager loading
-- which we need in order to invoke GetRequiredPlugins -- the
"phone home" monitor RPC address is passed at Run time.

In a subsequent change, we will switch to faulting in the plugins
that are missing -- rather than erroring -- in addition to
supporting the `pulumi plugin install` CLI command.
2018-02-18 08:08:15 -08:00
joeduffy 5d16fc936a Add workspace.GetPluginPath, and use it
This change introduces a workspace.GetPluginPath function that probes
the central workspace cache of plugins for a matching plugin binary that
matches the desired kind, name, and, optionally, version.  It also permits
overriding this with $PATH for developer scenarios.

The analyzer, language, and resource plugin logic now uses this function
for deciding which binary path to load at runtime.
2018-02-18 08:08:15 -08:00
Joe Duffy 902d646215
Rename package to project (#935)
This addresses pulumi/pulumi#446: what we used to call "package" is
now called "project".  This has gotten more confusing over time, now
that we're doing real package management.

Also fixes pulumi/pulumi#426, while in here.
2018-02-14 13:56:16 -08:00
Sean Gillespie 402a599fc7
Don't use shebangs to launch providers and correctly kill child process trees on Unix (#934)
* Don't use shebangs to launch providers and correctly kill child process trees on Unix

* Link to relevant documentation
2018-02-14 13:56:07 -08:00
CyrusNajmabadi 275670692b
Introduce Output<T> and update Resource construction code to properly handle it. (#834)
This PR adds a new formalisms at the Resource layer.  First all inputs to a Resource are typed as ```Input<T>```.  This is either a T, ```Promise<T>``
2018-02-05 14:44:23 -08:00
Pat Gavlin 88a22515df Supply unknown properties to providers during preview.
My previous change to stop supplying unknown properties to providers
broke `pulumi preview` in the case of unknown inputs. This change
restores the previous behavior for previews only; the new unknown-free
behavior remains for applies.

Fixes #790.
2018-01-09 18:41:47 -08:00
pat@pulumi.com f3cb37ef95 Do not expose unknowns to resource providers.
Before these changes, we were inconsistent in our treatment of unknown
property values across the resource provider RPC interface. `Check` and
`Diff` were retaining unknown properties in inputs and outputs;
`Create`, `Update`, and `Delete` were not. This interacted badly with
recent changes to `Check` to return all provider inputs--i.e. not just
defaults--from that method: if an unknown input was provided, it would
be present in the returned inputs, which would eventually confuse the
differ by giving the appearance of changes where none were present.

These changes remove unknowns from the provider interface entirely:
unknown property values are never passed to a provider, and a provider
must never return an unknown property value.

This is the primary piece of the fix for pulumi/pulumi-terraform#93.
2018-01-09 12:21:47 -08:00
pat@pulumi.com c56e716c31 Refactor the engine's entrypoints.
These changes refactor the engine's entrypoints--Deploy, Destroy, and
Preview--to be update-centric rather than stack-centric. Each of these
methods now takes a value of a new type, Update, that abstracts away the
vagaries of fetching and maintaining the update's state. This
refactoring also reinforces Pulumi.yaml as a CLI concept rather than an
engine concept; the CLI is now the only reader/writer of this format.

These changes will smooth the way for a few refactorings on the service
side that will aid in update isolation.
2018-01-08 14:15:16 -08:00
Matthew Riley 9e3976513c AssertNoError instead of Assert(err == nil)
This may not be exhaustive, but I replaced all instances I could find.
2018-01-08 13:46:21 -08:00
Joe Duffy d419229301
Add additional linting (#768)
This adds additional linting checks.  Most importantly, it will
check calls to our custom format routines for missing arguments.
2017-12-27 17:10:12 -08:00
Pat Gavlin a7fbdff7ea
Merge pull request #761 from pulumi/UpdateNoMerge
Do not merge old state and inputs for Update.
2017-12-24 14:47:15 -08:00
Pat Gavlin 1bd1eaff50 Do not merge old state and inputs for Update.
This merging causes similar issues to those it did in `Check`, and
differs from the approach we take to `Diff`. This can causes problems
such as an inability to remove properties.
2017-12-22 18:18:14 -08:00
Pat Gavlin e4d9eb6fd3 Support secrets for cloud stacks.
Use the new {en,de}crypt endpoints in the Pulumi.com API to secure
secret config values. The ciphertext for a secret config value is bound
to the stack to which it applies and cannot be shared with other stacks
(e.g. by copy/pasting it around in Pulumi.yaml). All secrets will need
to be encrypted once per target stack.
2017-12-22 07:59:27 -08:00
Joe Duffy bc2cf55463
Implement resource protection (#751)
This change implements resource protection, as per pulumi/pulumi#689.
The overall idea is that a resource can be marked as "protect: true",
which will prevent deletion of that resource for any reason whatsoever
(straight deletion, replacement, etc).  This is expressed in the
program.  To "unprotect" a resource, one must perform an update setting
"protect: false", and then afterwards, they can delete the resource.

For example:

    let res = new MyResource("precious", { .. }, { protect: true });

Afterwards, the resource will display in the CLI with a lock icon, and
any attempts to remove it will fail in the usual ways (in planning or,
worst case, during an actual update).

This was done by adding a new ResourceOptions bag parameter to the
base Resource types.  This is unfortunately a breaking change, but now
is the right time to take this one.  We had been adding new settings
one by one -- like parent and dependsOn -- and this new approach will
set us up to add any number of additional settings down the road,
without needing to worry about breaking anything ever again.

This is related to protected stacks, as described in
pulumi/pulumi-service#399.  Most likely this will serve as a foundational
building block that enables the coarser grained policy management.
2017-12-20 14:31:07 -08:00
Pat Gavlin 9d038c1d88 Only pass old inputs to Check.
We do not need all of the information in the old state for this call, as
outputs will not be read by the provider during validation or defaults
computation.
2017-12-15 11:04:43 -08:00
joeduffy 668e56f2c7 Use old.All() to be consistent with Update
This changes the inputs to Check/Diff to match what we also
pass to the Update function later on (old.All() vs. old.Outputs).
2017-12-15 07:37:15 -08:00
joeduffy 675fe38269 Add more tracing context to RPC marshaling
This change adds a bit more tracing context to RPC marshaling
logging so that it's easier to attribute certain marshaling calls.
Prior to this, we'd just have a flat list of "marshaled property X"
without any information about what the marshaling pertained to.
2017-12-15 07:22:49 -08:00
joeduffy 8492e6100f Pass old *outputs*, not *inputs*, to Check/Diff
This change passes a resource's old output state, so that it contains
everything -- defaults included -- for purposes of the provider's diffing.
Not doing so can lead the provider into thinking some of the requisite
state is missing.
2017-12-15 07:01:11 -08:00
Luke Hoban 6f15fa8ed8
Pass more stack info to ExtraRuntimeValidation (#717)
This will allow us to remove a lot of current boilerplate in individual tests, and move it into the test harness.

Note that this will require updating users of the integration test framework.  By moving to a property bag of inputs, we should avoid needing future breaking changes to this API though.
2017-12-13 16:09:14 -08:00
joeduffy 92ea5b5bdd Add a test case for delete-before-recreate 2017-12-13 10:47:18 -08:00
joeduffy 3a13621c32 Add rudimentary delete-before-create support
This change adds rudimentary delete-before-create support (see
pulumi/pulumi#450).  This cannot possibly be complete until we also
implement pulumi/pulumi#624, becuase we may try to delete a resource
while it still has dependent resources (which almost certainly will
fail).  But until then, we can use this to manually unwedge ourselves
for leaf-node resources that do not support old and new resources
living side-by-side.
2017-12-13 10:47:18 -08:00
Joe Duffy b6a386995a
Set pwd for plugins (#706)
This change just flows the project's "main" directory all the way
through to the plugins, fixing #667.  In that work item, we discussed
alternative approaches, such as rewriting the asset paths, but this
is tricky because it's very tough to do without those absolute paths
somehow ending up in the checkpoint files.  Just launching the
processes with the right pwd is far easier and safer, and it turns
out that, conveniently, we set up the plugin context in exactly the
same place that we read the project information.
2017-12-12 12:31:09 -08:00