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"
|
2024-01-25 23:28:58 +00:00
|
|
|
"fmt"
|
2017-08-30 01:24:12 +00:00
|
|
|
"io"
|
2024-01-25 23:28:58 +00:00
|
|
|
"path/filepath"
|
2017-08-31 21:31:33 +00:00
|
|
|
|
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"
|
2024-01-25 23:28:58 +00:00
|
|
|
pulumirpc "github.com/pulumi/pulumi/sdk/v3/proto/go"
|
|
|
|
structpb "google.golang.org/protobuf/types/known/structpb"
|
2017-08-30 01:24:12 +00:00
|
|
|
)
|
|
|
|
|
2024-01-25 23:28:58 +00:00
|
|
|
// ProgramInfo contains minimal information about the program to be run.
|
|
|
|
type ProgramInfo struct {
|
|
|
|
root string
|
|
|
|
program string
|
|
|
|
entryPoint string
|
|
|
|
options map[string]any
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewProgramInfo(rootDirectory, programDirectory, entryPoint string, options map[string]any) ProgramInfo {
|
|
|
|
isFileName := func(path string) bool {
|
|
|
|
return filepath.Base(path) == path
|
|
|
|
}
|
|
|
|
|
2024-02-22 11:43:18 +00:00
|
|
|
if !filepath.IsAbs(rootDirectory) {
|
2024-01-25 23:28:58 +00:00
|
|
|
panic(fmt.Sprintf("rootDirectory '%s' is not a valid path when creating ProgramInfo", rootDirectory))
|
|
|
|
}
|
|
|
|
|
2024-02-22 11:43:18 +00:00
|
|
|
if !filepath.IsAbs(programDirectory) {
|
2024-01-25 23:28:58 +00:00
|
|
|
panic(fmt.Sprintf("programDirectory '%s' is not a valid path when creating ProgramInfo", programDirectory))
|
|
|
|
}
|
|
|
|
|
|
|
|
if !isFileName(entryPoint) && entryPoint != "." {
|
|
|
|
panic(fmt.Sprintf("entryPoint '%s' was not a valid file name when creating ProgramInfo", entryPoint))
|
|
|
|
}
|
|
|
|
|
|
|
|
return ProgramInfo{
|
|
|
|
root: rootDirectory,
|
|
|
|
program: programDirectory,
|
|
|
|
entryPoint: entryPoint,
|
|
|
|
options: options,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// The programs root directory, i.e. where the Pulumi.yaml file is.
|
|
|
|
func (info ProgramInfo) RootDirectory() string {
|
|
|
|
return info.root
|
|
|
|
}
|
|
|
|
|
|
|
|
// The programs directory, generally the same as or a subdirectory of the root directory.
|
|
|
|
func (info ProgramInfo) ProgramDirectory() string {
|
|
|
|
return info.program
|
|
|
|
}
|
|
|
|
|
|
|
|
// The programs main entrypoint, either a file path relative to the program directory or "." for the program directory.
|
|
|
|
func (info ProgramInfo) EntryPoint() string {
|
|
|
|
return info.entryPoint
|
|
|
|
}
|
|
|
|
|
|
|
|
// Runtime plugin options for the program
|
|
|
|
func (info ProgramInfo) Options() map[string]any {
|
|
|
|
return info.options
|
|
|
|
}
|
|
|
|
|
|
|
|
func (info ProgramInfo) String() string {
|
|
|
|
return fmt.Sprintf("root=%s, program=%s, entryPoint=%s", info.root, info.program, info.entryPoint)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (info ProgramInfo) Marshal() (*pulumirpc.ProgramInfo, error) {
|
|
|
|
opts, err := structpb.NewStruct(info.options)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to marshal options: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &pulumirpc.ProgramInfo{
|
|
|
|
RootDirectory: info.root,
|
|
|
|
ProgramDirectory: info.program,
|
|
|
|
EntryPoint: info.entryPoint,
|
|
|
|
Options: opts,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
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.
|
2024-01-25 23:28:58 +00:00
|
|
|
GetRequiredPlugins(info ProgramInfo) ([]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.
|
2024-01-25 23:28:58 +00:00
|
|
|
InstallDependencies(info ProgramInfo) 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.
|
2024-01-25 23:28:58 +00:00
|
|
|
GetProgramDependencies(info ProgramInfo, 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(
|
2024-03-26 13:10:34 +00:00
|
|
|
directory string, schema string, extraFiles map[string][]byte,
|
|
|
|
loaderTarget string, localDependencies map[string]string,
|
2023-12-05 17:47:52 +00:00
|
|
|
) (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.
|
Add SupportPack to schemas to write out in the new style (#15713)
<!---
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 adds a new flag to the schema metadata to tell codegen to use the
new proposed style of SDKs where we fill in versions and write go.mods
etc.
I've reworked pack to operate on packages assuming they're in this new
style. That is pack no longer has the responsibility to fill in any
version information.
This updates python and node codegen to write out SDKs in this new
style, and fixes their core libraries to still be buildable via pack.
There are two approaches to fixing those, I've chosen option 1 below but
could pretty easily rework for option 2.
1) Write the version information directly to the SDKs at the same time
as we edit the .version file. To simplify this I've added a new
'set-version.py' script that takes a version string an writes it to all
the relevant places (.version, package.json, etc).
2) Write "pack" in the language host to search up the directory tree for
the ".version" file and then fill in the version information as we we're
doing before with envvar tricks and copying and editing package.json.
I think 1 is simpler long term, but does force some amount of cleanup in
unrelated bits of the system right now (release makefiles need a small
edit). 2 is much more localised but keeps this complexity that
sdk/nodejs sdk/python aren't actually valid source modules.
## 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
- [x] 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. -->
2024-03-22 09:25:46 +00:00
|
|
|
Pack(packageDirectory string, destinationDirectory string) (string, error)
|
2022-08-15 13:55:04 +00:00
|
|
|
}
|
|
|
|
|
2024-02-09 22:18:42 +00:00
|
|
|
// DependencyInfo contains information about a dependency reported by a language runtime.
|
|
|
|
// These are the languages dependencies, they are not necessarily Pulumi packages.
|
2022-08-15 13:55:04 +00:00
|
|
|
type DependencyInfo struct {
|
2024-02-09 22:18:42 +00:00
|
|
|
// The name of the dependency.
|
|
|
|
Name string
|
|
|
|
// The version of the dependency. Unlike most versions in the system this is not guaranteed to be a semantic
|
|
|
|
// version.
|
|
|
|
Version string
|
2022-08-15 13:55:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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 {
|
2024-01-25 23:28:58 +00:00
|
|
|
Info ProgramInfo
|
|
|
|
WorkingDirectory string
|
|
|
|
Args []string
|
|
|
|
Env []string
|
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 {
|
2024-01-25 23:28:58 +00:00
|
|
|
Info ProgramInfo // the information about the program to run.
|
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.
|
|
|
|
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
|
|
|
}
|