2018-05-22 19:43:36 +00:00
|
|
|
// Copyright 2016-2018, Pulumi Corporation.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
2017-08-30 01:24:12 +00:00
|
|
|
|
|
|
|
package plugin
|
|
|
|
|
|
|
|
import (
|
2022-10-04 08:58:01 +00:00
|
|
|
"context"
|
2017-08-30 01:24:12 +00:00
|
|
|
"io"
|
2017-08-31 21:31:33 +00:00
|
|
|
|
2022-08-15 13:55:04 +00:00
|
|
|
"github.com/blang/semver"
|
2022-10-17 14:21:11 +00:00
|
|
|
"github.com/hashicorp/hcl/v2"
|
2023-10-20 10:44:16 +00:00
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
|
2021-03-17 13:20:05 +00:00
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/resource/config"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/workspace"
|
2017-08-30 01:24:12 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// LanguageRuntime is a convenient interface for interacting with language runtime plugins. These tend to be
|
|
|
|
// dynamically loaded as plugins, although this interface hides this fact from the calling code.
|
|
|
|
type LanguageRuntime interface {
|
|
|
|
// Closer closes any underlying OS resources associated with this plugin (like processes, RPC channels, etc).
|
|
|
|
io.Closer
|
2018-02-06 17:57:32 +00:00
|
|
|
// GetRequiredPlugins computes the complete set of anticipated plugins required by a program.
|
2022-08-26 14:51:14 +00:00
|
|
|
GetRequiredPlugins(info ProgInfo) ([]workspace.PluginSpec, error)
|
2019-03-20 18:54:32 +00:00
|
|
|
// Run executes a program in the language runtime for planning or deployment purposes. If
|
|
|
|
// info.DryRun is true, the code must not assume that side-effects or final values resulting
|
|
|
|
// from resource deployments are actually available. If it is false, on the other hand, a real
|
|
|
|
// deployment is occurring and it may safely depend on these.
|
|
|
|
//
|
|
|
|
// Returns a triple of "error message", "bail", or real "error". If "bail", the caller should
|
|
|
|
// return result.Bail immediately and not print any further messages to the user.
|
|
|
|
Run(info RunInfo) (string, bool, error)
|
2017-12-01 21:50:32 +00:00
|
|
|
// GetPluginInfo returns this plugin's information.
|
2018-02-06 17:57:32 +00:00
|
|
|
GetPluginInfo() (workspace.PluginInfo, error)
|
2022-04-03 14:54:59 +00:00
|
|
|
|
|
|
|
// InstallDependencies will install dependencies for the project, e.g. by running `npm install` for nodejs projects.
|
Pass root and main info to language host methods (#14654)
<!---
Thanks so much for your contribution! If this is your first time
contributing, please ensure that you have read the
[CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md)
documentation.
-->
# Description
<!--- Please include a summary of the change and which issue is fixed.
Please also include relevant motivation and context. -->
This is two changes rolled together in a way.
Firstly passing some of the data that we pass on language runtime
startup to also pass it to Run/GetRequiredPlugins/etc. This is needed
for matrix testing, as we only get to start the language runtime up once
for that but want to execute multiple programs with it.
I feel it's also a little more consistent as we use the language
runtimes in other contexts (codegen) where there isn't really a root
directory, and aren't any options (and if we did do options the options
for codegen are not going to be the same as for execution). It also
means we can reuse a language host for shimless and substack programs,
as before they heavily relied on their current working directory to
calculate paths, and obviosly could only take one set of options at
startup. Imagine a shimless python package + a python root program, that
would have needed two startups of the python language host to deal with,
this unblocks it so we can make the engine smarter and only use one.
Secondly renaming some of the fields we pass to
Run/GetRequiredPlugins/etc today. `Pwd` and `Program` were not very
descriptive and had pretty non-obvious documentation:
```
string pwd = 3; // the program's working directory.
string program = 4; // the path to the program to execute.
```
`pwd` will remain, although probably rename it to `working_directory` at
some point, because while today we always start programs up with the
working directory equal to the program directory that definitely is
going to change in the future (at least for MLCs and substack programs).
But the name `pwd` doesn't make it clear that this was intended to be
the working directory _and_ the directory which contains the program.
`program` was in fact nearly always ".", and if it wasn't that it was
just a filename. The engine never sent a path for `program` (although we
did have some unit tests to check how that worked for the nodejs and
python hosts).
These are now replaced by a new structure with (I think) more clearly
named and documented fields (see ProgramInfo in langauge.proto).
The engine still sends the old data for now, we need to update
dotnet/yaml/java before we break the old interface and give Virtus Labs
a chance to update [besom](https://github.com/VirtusLab/besom).
## Checklist
- [x] I have run `make tidy` to update any new dependencies
- [x] I have run `make lint` to verify my code passes the lint check
- [ ] I have formatted my code using `gofumpt`
<!--- Please provide details if the checkbox below is to be left
unchecked. -->
- [x] I have added tests that prove my fix is effective or that my
feature works
<!---
User-facing changes require a CHANGELOG entry.
-->
- [ ] I have run `make changelog` and committed the
`changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the
Pulumi Cloud,
then the service should honor older versions of the CLI where this
change would not exist.
You must then bump the API version in
/pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi
Cloud API version
<!-- @Pulumi employees: If yes, you must submit corresponding changes in
the service repo. -->
2023-12-10 17:30:51 +00:00
|
|
|
InstallDependencies(pwd, main string) error
|
2022-08-15 13:55:04 +00:00
|
|
|
|
|
|
|
// About returns information about the language runtime.
|
|
|
|
About() (AboutInfo, error)
|
|
|
|
|
|
|
|
// GetProgramDependencies returns information about the dependencies for the given program.
|
|
|
|
GetProgramDependencies(info ProgInfo, transitiveDependencies bool) ([]DependencyInfo, error)
|
2022-10-04 08:58:01 +00:00
|
|
|
|
|
|
|
// RunPlugin executes a plugin program and returns its result asynchronously.
|
|
|
|
RunPlugin(info RunPluginInfo) (io.Reader, io.Reader, context.CancelFunc, error)
|
2022-10-17 14:21:11 +00:00
|
|
|
|
|
|
|
// GenerateProject generates a program project in the given directory. This will include metadata files such
|
|
|
|
// as Pulumi.yaml and package.json.
|
2023-07-27 09:27:07 +00:00
|
|
|
GenerateProject(sourceDirectory, targetDirectory, project string,
|
2023-08-03 10:40:05 +00:00
|
|
|
strict bool, loaderTarget string, localDependencies map[string]string) (hcl.Diagnostics, error)
|
2022-10-17 14:21:11 +00:00
|
|
|
|
|
|
|
// GeneratePlugin generates an SDK package.
|
2023-12-05 17:47:52 +00:00
|
|
|
GeneratePackage(
|
|
|
|
directory string, schema string, extraFiles map[string][]byte, loaderTarget string,
|
|
|
|
) (hcl.Diagnostics, error)
|
2022-10-17 14:21:11 +00:00
|
|
|
|
|
|
|
// GenerateProgram is similar to GenerateProject but doesn't include any metadata files, just the program
|
|
|
|
// source code.
|
2023-07-27 09:27:07 +00:00
|
|
|
GenerateProgram(program map[string]string, loaderTarget string) (map[string][]byte, hcl.Diagnostics, error)
|
2023-07-27 21:39:36 +00:00
|
|
|
|
|
|
|
// Pack packs a library package into a language specific artifact in the given destination directory.
|
|
|
|
Pack(packageDirectory string, version semver.Version, destinationDirectory string) (string, error)
|
2022-08-15 13:55:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type DependencyInfo struct {
|
|
|
|
Name string
|
|
|
|
Version semver.Version
|
|
|
|
}
|
|
|
|
|
|
|
|
type AboutInfo struct {
|
|
|
|
Executable string
|
|
|
|
Version string
|
|
|
|
Metadata map[string]string
|
2018-02-06 17:57:32 +00:00
|
|
|
}
|
|
|
|
|
2022-10-04 08:58:01 +00:00
|
|
|
type RunPluginInfo struct {
|
|
|
|
Pwd string
|
|
|
|
Program string
|
|
|
|
Args []string
|
|
|
|
Env []string
|
|
|
|
}
|
|
|
|
|
2018-02-06 17:57:32 +00:00
|
|
|
// ProgInfo contains minimal information about the program to be run.
|
|
|
|
type ProgInfo struct {
|
2024-01-16 17:06:14 +00:00
|
|
|
Pwd string // the program's working directory.
|
|
|
|
Program string // the path to the program to execute.
|
2017-08-30 01:24:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// RunInfo contains all of the information required to perform a plan or deployment operation.
|
|
|
|
type RunInfo struct {
|
2023-10-20 10:44:16 +00:00
|
|
|
MonitorAddress string // the RPC address to the host resource monitor.
|
|
|
|
Project string // the project name housing the program being run.
|
|
|
|
Stack string // the stack name being evaluated.
|
|
|
|
Pwd string // the program's working directory.
|
|
|
|
Program string // the path to the program to execute.
|
|
|
|
Args []string // any arguments to pass to the program.
|
|
|
|
Config map[config.Key]string // the configuration variables to apply before running.
|
|
|
|
ConfigSecretKeys []config.Key // the configuration keys that have secret values.
|
|
|
|
ConfigPropertyMap resource.PropertyMap // the configuration as a property map.
|
|
|
|
DryRun bool // true if we are performing a dry-run (preview).
|
|
|
|
QueryMode bool // true if we're only doing a query.
|
|
|
|
Parallel int // the degree of parallelism for resource operations (<=1 for serial).
|
|
|
|
Organization string // the organization name housing the program being run (might be empty).
|
2017-08-30 01:24:12 +00:00
|
|
|
}
|