Commit graph

2411 commits

Author SHA1 Message Date
Sean Gillespie 1011989369
Produce better error messages when the main module is not found (#976)
* Produce better error messages when the main module is not found

If we fail to load a program's main module, inspect the program's
package.json and attempt to diagnose why the main module load failed.

* Code review feedback: entrypoint -> entry point, call out npm build explicitly, simplify control flow

* Code review feedback: add a little more levity to the unknown exception error message
2018-02-26 10:54:56 -08:00
Luke Hoban ff87af1a44
Workaround for issue with python setup.py (#980)
Pass `--prefix=` to avoid hitting: `error: can't combine user with with prefix/exec_prefix/home or install_(plat)base`.
2018-02-24 17:50:54 -08:00
Joe Duffy cc5ce42dc9
Merge pull request #800 from pulumi/754_python
Python support
2018-02-24 11:18:43 -08:00
joeduffy 1acb0eb226 Use new package name for empty test 2018-02-24 10:39:18 -08:00
joeduffy 329a003aff Rejigger Protobuf binplacing on Windows 2018-02-24 09:59:17 -08:00
joeduffy a1c4115fa6 Also setup.py with --user
This ensures we can properly install the built package in Travis's
images, which have everything owned by root by default.
2018-02-24 09:52:30 -08:00
joeduffy 4f591bed76 Use a newer pylint
This ensures the new exclusion syntax is accepted, which is required
to ignore the Protobuf-generated files which have numerous lint warnings.
2018-02-24 09:52:30 -08:00
joeduffy 4de49a8600 Create symlink for Travis on Mac
Pip is called `pip2.7` in Travis' Mac image.  Our script already
had to deal with this, but did so by conditionalizing the name we
use in our scripts.  Rather than doing that, let's create a symlink
with the name `pip` so that everything can just use the good name.
2018-02-24 09:52:20 -08:00
joeduffy 153344354c Pip install to user homedir
This change passes --user to pip install, so that it installs packages
underneath the home directory.  This is required because, except for the
"python" image in Travis, all Python and Pip-related directories are
root-owned.  The --user approach avoids needing to sudo all over the place.
2018-02-24 09:21:16 -08:00
joeduffy a045e2fb1e Implement more of the Python runtime
This change includes a lot more functionality.  Enough to actually
run the webserver-py example through previews, updates, and destroys!

* Actually wire up the gRPC connections to the engine/monitor.

* Move the Node.js and Python generated Protobuf/gRPC files underneath
  the actual SDK directories to simplify this generally.  No more
  copying during `make` and, in fact, this was required to give a smoother
  experience with good packages/modules for the Python's SDK development.

* Build the Python egg during `make build`.

* Add support for program stacks.  Just like with the Node.js runtime,
  we will auto-parent any resources without explicit parents to a single
  top-level resource component.

* Add support for component resource output properties.

* Add get_project() and get_stack() functions for retrieving the current
  project and stack names.

* Properly use UNKNOWN sentinels.

* Add a set_outputs() function on Resource.  This is defined by the
  code-generator and allows custom logic for output property setting.
  This is cleaner than the way we do this in Node.js, and gives us a
  way to ensure that output properties are "real" properties, complete
  with member documentation.  This also gives us a hook to perform
  name demangling, which the code-generator typically controls anyway.

* Add package dependencies to setuptools.py and requirements.txt.
2018-02-24 08:58:34 -08:00
Joe Duffy fa2377dc61
Fix spinner erasure (#979)
The spinner code used \b, but didn't overwrite with spaces, so part
of the message could get left behind when other writes to stdout/err
occurred.  This change simply overwrites characters with spaces.
2018-02-23 19:36:44 -08:00
joeduffy 74563afdc8 Get the empty Python program working
This change gets enough of the Python SDK up and running that the
empty Python program will work.  Mostly just scaffolding, but the
basic structure is now in place.  The primary remaining work is to
wire up resource creation to the gRPC interfaces.

In summary:

* The basic structure is as follows:

    - Everything goes into sdk/python/.

    - sdk/python/cmd/pulumi-langhost-python is a Go language host
      that simply knows how to spawn Python processes to run out
      entrypoint in response to requests by the engine.

    - sdk/python/cmd/pulumi-langhost-python-exec is a little Python
      shim that is invoked by the language host to run Python programs,
      and is responsible for setting up the minimal goo before we can
      do so (RPC connections and the like).

    - sdk/python/lib/ contains a Python Pip package suitable for PyPi.

    - In there, we have two packages: the root pulumi package that
      contains all of the basic Pulumi programming model abstractions,
      and pulumi.runtime, which contains the implementation of
      resource registration, RPC interfacing with the engine, and so on.

* Add logic in our test framework to conditionalize on the language
  type and react accordingly.  This will allow us to skip Yarn for
  Python projects and eventually run Pip if there's a requirements.txt.

* Created the basic project structure, including all of the usual
  Make targets for installing into the proper places.

* Building also runs Pylint and we are clean.

There are a few other minor things in here:

* Add an "empty" test for both Node.js and Python.  These pass.

* Fix an existing bug in plugin shutdown logic.  At some point, we
  started waiting for stderr/stdout to flush before shutting down
  the plugin; but if certain failures happen "early" during the
  plugin launch process, these channels will never get initialized
  and so waiting for them deadlocks.

* Recently we seem to have added logic to delete test temp
  directories  if a failure happened during initialization of said
  temp directories.  This is unfortunate, because you often need to
  look at the temp directory to see what failed.  We already clean
  them up elsewhere after the full test completes successfully, so
  I don't think we need to be doing this, and I've removed it.

Still many loose ends (config, resources, etc), but it's a start!
2018-02-23 19:33:02 -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 99da1f5350
Spruce up the stack graph command:
1. Output different-colored edges for parent-child resource
    relationships
    2. Allow the changing of edge colors via command-line parameters
    3. Allow the skipping of the parent-child graph or the
    dependency graph when calculating all edges

This modifies the Graph interface slightly to allow an edge to specify
what color should be used when drawing it.
2018-02-22 17:31:45 -08:00
Sean Gillespie 30826a34f5
Code review feedback: rework graph construction to be done eagerly and efficiently, gate under PULUMI_DEBUG_COMMANDS 2018-02-22 15:52:06 -08:00
Joe Duffy 01859a70ed
Update README.md to use a valid CLI command 2018-02-22 14:26:04 -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
Matt Ellis 258c34620d Guard BirthTime checks with HasBirthTimes
Some file systems do not record BithTimes and BirthTime panics in
these cases. We use HasBirthTimes to guard against this and print n/a
when we do not have a BirthTime.
2018-02-22 10:32:21 -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
Sean Gillespie d68bc0db63
Revert "Rollback #882 (#888)" (#964)
This reverts commit 71beb2a51f.
2018-02-21 09:43:17 -08:00
Joe Duffy 811759fb77
Fix missing emojis on Windows (#966)
I was reminded of this yesterday with unprintable characters as I
debugged some things on Windows.  Inspired by Yarn, this change adds
a new flag --emoji (-e for short) that can be used to control whether
we show ASCII-only characters or not in the console.  On Mac, it
defaults to true, and on Windows and Linux, it defaults to false.

This also brings back the retro ASCII-friendly progress spinner
when --emoji is disabled.
2018-02-21 09:42:06 -08:00
Justin Van Patten ed9716f6ef
Create backups of all local stack checkpoint files (#949)
Backup copies of local stack checkpoints are now saved to the
user's home directory (`~/.pulumi/backups`) by default.

This enables users to recover after accidentally deleting their
local `.pulumi` directory (e.g. via `git clean`).

The behavior can be disabled by setting the
PULUMI_DISABLE_CHECKPOINT_BACKUPS environment variable, which
we use to disable backups when running all tests other than the
test for this functionality.
2018-02-20 21:05:57 -08:00
joeduffy e5e58fd5ec Fix history command URL
This is a minor improvement on https://github.com/pulumi/pulumi/issues/965,
but we clearly have a lot more work to do (captured in that work item).
2018-02-20 18:31:25 -08:00
Joe Duffy 7aedf80fa2
Merge pull request #879 from pulumi/pulumi/home/11_plugins
Implement basic plugin management
2018-02-20 16:35:52 -08:00
joeduffy b3c3c0797b Use os/user for home directory
This was PR feedback from @justinvp, and ensures we're consistent
with how we retrive the user's home directory elsewhere.
2018-02-20 15:35:07 -08:00
joeduffy 88dcdd8d2b Substitute ${VERSION} on Windows builds too
This change refactors the way we do ${VERSION} substitution in both
the Node.js SDK's version.js and package.json, so that it can work on
Windows.  This is required now that we are actually parsing semvers.
2018-02-20 14:37:28 -08:00
joeduffy 09a819f801 Echo the dynamic provider's location 2018-02-20 14:14:05 -08:00
Matt Ellis 9bf6c976bc Install fixed versions of our tools
For some tools we used, like `dep` and `gometalinter` we were just
calling `go install` which caused us to pick up whatever was in `HEAD`
at that time. Now, we move to a model where we install fixed versions,
which will change per milestone.

While doing this, I changed the way our .travis.yml file runs
everything to move as much as possible out into scripts and do so in a
way that allows us to share as much common logic across our
repositories.
2018-02-20 11:50:08 -08:00
joeduffy d7194e0125 LookPath without an extension
This permits the extension to vary on Windows, e.g. ".exe" vs. ".cmd".
2018-02-19 18:47:26 -08:00
joeduffy 365a96f9ad Add custom NODE_PATH to resource cmd 2018-02-19 18:45:12 -08:00
joeduffy 9903adf822 Produce -exec without file extensions
On Windows, when we launch the language host, it will end up with
a ".exe" file extension at the end of os.Args[0].  This leads us to
produce a garbage filename for the -exec script -- namely,
pulumi-language-nodejs.exe-exec -- which, of course fails.  We simply
need to trim off the ".exe" bit before producing the script name.
2018-02-19 14:39:26 -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 e4cf4e3b31 Delete errant plugin command 2018-02-19 13:37:59 -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 932e755305 Move plugins to their own directories
Prior to this change, we had a flat list of files in the
~/.pulumi/plugins directory.  This was simple but unfortunately
too naive, since we in fact have multi-file plugins already.
Dumping them in the same directory increases the risk of a
collision.  Instead, let's put them in their own directories.

This means, for example, you'll see things like

    ~/.pulumi/plugins/
        resource-aws-v0.11.0-dev-8-g57a0d62/
            README.txt
            pulumi-resource-aws

Notice that the binary name stays the same -- e.g., in this
case pulumi-resource-aws -- and does not include the version.
This makes it simple to add it to your $PATH in the usual ways
and have it loaded as a preferred location.
2018-02-19 09:31:00 -08:00
joeduffy ffe8c4681a Rename plugin prune to rm
This change renames prune to rm, to match what we use for other
similar commands.  Someday perhaps we will add a prune that uses
some smarts to prune old plugins, etc.

Also tidy up some minor things about the command.  For example,
we now require --all if you want to truly clear the entire plugin
cache.  We also print more detail, like the full list of plugins
to be removed, in the confirmation prompt.
2018-02-19 09:06:02 -08:00
joeduffy c86a799d15 Fix some more scripts 2018-02-18 08:11:14 -08:00
joeduffy e242601133 Do not use absolute paths for main/proj 2018-02-18 08:08:15 -08:00
joeduffy ca3516d3e5 Fix language script merge 2018-02-18 08:08:15 -08:00
joeduffy 90ebca4aea Fix up API URLs
The API/REST logic auto-prepended "/api", which we don't want
for the release downloads.  This change just alters callsites
to specify the full path (which I prefer being explicit anyway).
2018-02-18 08:08:15 -08:00
joeduffy 041e44beff Skip reinstalling existing plugins
This change introduces logic to skip installing plugins that already
exist, unless --reinstall is explicitly passed to `pulumi plugin install`.
2018-02-18 08:08:15 -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 4614aa6f22 Enable installing plugins from files
This enables you to install a plugin directly from a file, rather
than the default of downloading it from our release share.  This is
primarily useful as a test tool, but will also be a useful escape
hatch for 3rd party extensibility, where we do not have a share.

    $ pulumi plugin install resource aws v0.1.0 -f my_aws_provider.tgz
2018-02-18 08:08:15 -08:00
joeduffy f2cdc8a9ee Use os.Create when expanding plugins 2018-02-18 08:08:15 -08:00
joeduffy 96088dd56f Implement Node.js GetRequiredPlugins function
This change implements the Node.js language host's GetRequiredPlugins
function.  This merely scans all node_modules/*/package.json files in
the program directory, looking for those that have associated plugins.
It returns a list of any found along with their version numbers.
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