From 639b4f7b740faf63abfa23fa6af70a2a7c4d9bb4 Mon Sep 17 00:00:00 2001 From: Justin Van Patten Date: Fri, 19 Jul 2024 15:56:25 -0700 Subject: [PATCH] Indicate the PyPi package doesn't have a plugin Pulumi automatically determines required plugins for a program. For Python programs, it essentially does this by running `python -m pip list --format json`, and any packages prefixed with `pulumi-` or `pulumi_` are assumed to have associated plugins, unless the package includes a `pulumi-plugin.json` file that has indicated there is no plugin via `{ "resource": false }`. When the `GetRequiredPlugins` support was originally added to the Python language host, it [hardcoded](https://github.com/pulumi/pulumi/blob/e6d20d26f7f64a624238f86204d862642ff27e16/sdk/python/cmd/pulumi-language-python/main.go#L428-L430) that `pulumi-policy` did not have an associated plugin. The hardcode mainly for older versions of `pulumi-policy` that did not contain a `pulumi-plugin.json` file. `pulumi-plugin.json` was actually originally named `pulumiplugin.json` (no dash). This file wasn't used anywhere, aside from in `pulumi-policy`, but the hardcod prevented it from ever being loaded in that case. It turned out that there was a bug parsing `pulumiplugin.json` that caused the CLI to error when that file existed in other packages. Since we were planning to expand the use of the file to other languages, and make it generated by default by SDKgen, we changed the name from `pulumiplugin.json` to `pulumi-plugin.json` to avoid breaking older CLIs with the bug (see https://github.com/pulumi/pulumi/pull/8593). After making that change, we never followed up to rename the `pulumiplugin.json` file in `pulumi-policy` to `pulumi-plugin.json`, largely because it didn't matter since we had the hardcode. However, this hardcode no longer works with the latest version of `pulumi-policy` (v1.11.0). This version was built with a newer version of `setuptools` which has a behavior change where the package name in the metadata will now allow underscores, instead of having underscores replaced with dashes (https://github.com/pypa/setuptools/pull/4159). This means that the package name reported from `pip list` is now `pulumi_policy` instead of `pulumi-policy`, which doesn't match the hardcoded list. And since there is no `pulumi-plugin.json` file in the package (it's still the old `pulumiplugin.json` name), the Pulumi Python language host thinks this package needs a plugin and tries to retrieve one that doesn't exist. This change addresses the issue by renaming `pulumiplugin.json` to `pulumi-plugin.json` in the package. --- CHANGELOG.md | 5 ++++ .../{pulumiplugin.json => pulumi-plugin.json} | 0 sdk/python/lib/setup.py | 2 +- tests/integration/integration_test.go | 28 +++++++++++++++++++ 4 files changed, 34 insertions(+), 1 deletion(-) rename sdk/python/lib/pulumi_policy/{pulumiplugin.json => pulumi-plugin.json} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c4720d..1d5ab84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ --- +## Unreleased + +- Python: Indicate that the PyPi package doesn't have an associated Pulumi plugin + (https://github.com/pulumi/pulumi-policy/pull/358). + ## 1.11.0 (2024-04-17) - Fix panic when a stack policy with a "remediate" level reports a violation diff --git a/sdk/python/lib/pulumi_policy/pulumiplugin.json b/sdk/python/lib/pulumi_policy/pulumi-plugin.json similarity index 100% rename from sdk/python/lib/pulumi_policy/pulumiplugin.json rename to sdk/python/lib/pulumi_policy/pulumi-plugin.json diff --git a/sdk/python/lib/setup.py b/sdk/python/lib/setup.py index 79d4d23..a84e464 100644 --- a/sdk/python/lib/setup.py +++ b/sdk/python/lib/setup.py @@ -36,7 +36,7 @@ def readme(): package_data={ 'pulumi_policy': [ 'py.typed', - 'pulumiplugin.json' + 'pulumi-plugin.json' ] }, install_requires=[ diff --git a/tests/integration/integration_test.go b/tests/integration/integration_test.go index 7181eea..2ceb682 100644 --- a/tests/integration/integration_test.go +++ b/tests/integration/integration_test.go @@ -26,6 +26,7 @@ import ( ptesting "github.com/pulumi/pulumi/sdk/v3/go/common/testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) type Runtime int @@ -869,3 +870,30 @@ func TestRemoteComponent(t *testing.T) { }, }) } + +func TestPythonDoesNotTryToInstallPlugin(t *testing.T) { + e := ptesting.NewEnvironment(t) + t.Log(e.RootPath) + defer e.DeleteIfNotFailed() + + pulumiHome := t.TempDir() + t.Setenv("PULUMI_HOME", pulumiHome) + + e.RunCommand("pulumi", "login", "--local") + e.RunCommand("pulumi", "new", "python", "--generate-only", "--yes", "--force") + + requirementsTxtPath := filepath.Join(e.RootPath, "requirements.txt") + + dep, err := filepath.Abs(filepath.Join("..", "..", "sdk", "python", "lib")) + require.NoError(t, err) + + file, err := os.OpenFile(requirementsTxtPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644) + require.NoError(t, err) + defer file.Close() + _, err = file.WriteString(dep) + require.NoError(t, err) + + // Pulumi should not try to install a plugin for pulumi_policy. + // This command will fail if it tries to install the non-existent pulumi_policy plugin. + e.RunCommand("pulumi", "install") +}