mirror of https://github.com/pulumi/pulumi.git
cb8277d6a4
Several Pulumi NodeJS SDKs support passing NodeJS closures directly to resources in lieu of e.g. source files that must be managed separately on the file system. The example below, for instance, shows how a NodeJS closure can be used to declare an AWS Lambda that responds to objects being created in an S3 bucket: ```typescript const bucket = new aws.s3.Bucket("my-bucket") bucket.onObjectCreated("listener", () => { console.log("An object was created in the S3 bucket!") }) ``` Under the hood, Pulumi serializes the passed closure to a piece of code and takes care of packaging that code appropriately for use as a Lambda function. This serialization is non-trivial: for packaged code to work, Pulumi must be careful to capture and serialize the transitive dependency graph of the closure passed -- the functions and values that the closure depends on, as well as the dependencies of those dependencies, and so on. This change fixes a regression whereby code that transitively depends on the Pulumi SDK no longer serializes to working code. Let's modify the above example to use `@pulumi/pulumi` types and values: ```typescript const bucket = new aws.s3.Bucket("my-bucket") const task = new awsx.ecs.FargateTaskDefinition("task", { container: { name: "container", image: "node", }, }) bucket.onObjectCreated("listener", () => { console.log(task.taskDefinition.get()) }) ``` When this code is serialized, it captures parts of the Pulumi SDK, since `task.taskDefinition.get()` involves SDK classes and their members. The Pulumi SDK is marked as a `deploymentOnlyModule`, meaning that it is not intended to be captured in its entirety, since it is not expected to work in its entirety in such a context. However, there may be select parts of the SDK (or other `deploymentOnlyModule`s) that _do_ work and so the serialization code tries to grab just the referenced values. One such referenced value is the `Resource.getProvider` method, which was recently refactored to use a helper method, `pkgFromType`, defined in the `runtime/resource` module. This causes the serializer to generate a `require("@pulumi/pulumi/runtime/resource")` call, which fails since the remainder of the SDK has not been captured. It might be possible to fix this "properly" with a better or more considered approach to serialization in the presence of `deploymentOnlyModule`, but in the interests of fixing the regression this commit takes the lazier option. Since `sdk/nodejs/resource` and `sdk/nodejs/runtime/resource` _already_ depend on each other cyclically (this is permitted by NodeJS), we just move the `pkgFromType` helper function (which is used by `resource` and `runtime/resource`) to `resource` instead. Thus, when we serialize `resource`, we don't generate the import to `runtime/resource`. In theory, moving the function like this could create the same issue in the opposite direction (whereby the use of `runtime/resource` generates a bad `require` of `resource`). However, it feels even less likely that `pulumi.runtime.*` functions should be supported inside serializable closures, and the only indirect caller of the majority of `runtime/resource`'s exports _is_ `resource` (the others being `Callable`s, `settings`, and `rpc`, which again feel like they have no business being in a serialized closure). As a result, this is hopefully safe. If it turns out not to be, duplicating the function would be the next step to take. Fixes #14671 |
||
---|---|---|
.. | ||
pending | ||
config.yaml |