Skip to content

Allow passing arbitrary args to PEX invocation when building FaaS artifacts #20237

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Dec 11, 2023

Conversation

huonw
Copy link
Contributor

@huonw huonw commented Nov 23, 2023

This adds an pex3_venv_create_extra_args field to all FaaS targets (python_aws_lambda_function, python_aws_lambda_layer, python_google_cloud_function). This allows adding arbitrary extra arguments that are passed to the pex3 venv create --layout=flat-zipped ... invocation that is used to create the final zip file.

Most acutely, this is driven by making it possible to pass the --collisions-ok flag. This allows work around dependencies that are packaged with files outside a namespaced directories, e.g. commonly a LICENCE or README file, or tests/ directory, since they'll have different content. A command like pip install ... will happily install them and have one of the files "win" arbitrarily, while PEX is more correct and flags that it doesn't know what to do in that circumstance.

Fixes #20224

This is marked for cherry picking back to 2.18 because it can block adoption of the new layout, and the old (lambdex) layout is deprecated and using it is noisy in 2.18.

@huonw huonw added this to the 2.18.x milestone Nov 23, 2023
@huonw huonw marked this pull request as ready for review November 24, 2023 00:19
@huonw huonw requested a review from benjyw November 24, 2023 00:21
Copy link
Contributor

@benjyw benjyw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if we want an option under [pex] to set this globally. And if we have that, do we need to be able to set this at the target level as well?

@@ -342,3 +342,75 @@ def test_layer_must_have_dependencies(rule_runner: PythonRuleRunner) -> None:
expected_extra_log_lines=(" Runtime: python3.7",),
layer=True,
)


def test_collisions_ok(rule_runner: PythonRuleRunner) -> None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need these tests given the generic one in pex_venv_test.py ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was assuming we want to validate we've hooked up the field appropriately.

I guess technically this could be a normal test that checks the pex_venv.py rule is called with the expected args, rather than needing to be a full integration test...

Do you think it's worth switching over?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have so many large lumbering tests, our CI is already so heavyweight, that yeah, I think it's worth keeping this light.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've switched them all to be fully mocked, basically just testing that PexCliProcess gets the expected args.

@huonw
Copy link
Contributor Author

huonw commented Nov 26, 2023

I'm wondering if we want an option under [pex] to set this globally. And if we have that, do we need to be able to set this at the target level as well?

Hm, not a bad idea, to simplify the code.

However, personally, I'd prefer to be able to set this only on targets where it matters (i.e. this particular lambda happens to use conflicting dependencies), rather than having a blanket allow that might let an unexpected/undesirable collision slip through in a different artifact. If someone has a lot of conflicts, __defaults__ allows avoiding the repetition.

What do you think?

@benjyw
Copy link
Contributor

benjyw commented Nov 26, 2023

I'm wondering if we want an option under [pex] to set this globally. And if we have that, do we need to be able to set this at the target level as well?

Hm, not a bad idea, to simplify the code.

However, personally, I'd prefer to be able to set this only on targets where it matters (i.e. this particular lambda happens to use conflicting dependencies), rather than having a blanket allow that might let an unexpected/undesirable collision slip through in a different artifact. If someone has a lot of conflicts, __defaults__ allows avoiding the repetition.

What do you think?

I'm not convinced we need this level of granularity yet. Note that pip, the de facto standard, silently allows collisions, so users clearly accept it as normal, and in some cases distributions expect it to work... The fact that pex is far stricter is nice-to-have, but I think a global - allow/warn/error setting might be fine to start with.

@huonw
Copy link
Contributor Author

huonw commented Nov 26, 2023

Okay, I'll add a setting like [pex] venv_create_collisions = "allow" / "error", and try to make the docs reference it so that users can find it when they have problems with their otherwise-unrelated python_aws_lambda_function targets.

@huonw
Copy link
Contributor Author

huonw commented Nov 26, 2023

Hm, alternative: what if we just allow passing extra_pex_venv_create_args=["..."] as referenced in the description, and we're likely to do for #20227?

This feels like less of a proliferation of narrow-use-case arguments, and is more clearly attached to the relevant targets.

@benjyw
Copy link
Contributor

benjyw commented Nov 27, 2023

Hm, alternative: what if we just allow passing extra_pex_venv_create_args=["..."] as referenced in the description, and we're likely to do for #20227?

This feels like less of a proliferation of narrow-use-case arguments, and is more clearly attached to the relevant targets.

That works for me.

@cedric-fauth
Copy link

Hi, do you have any updates on this? Would be great if this feature will be out soon for pants 2.18. Thanks for working on it!

@huonw
Copy link
Contributor Author

huonw commented Dec 8, 2023

Sorry, had a bit of work crunch over the last weeks, so this has had to pause; maybe over the next day/week.

@huonw
Copy link
Contributor Author

huonw commented Dec 11, 2023

Okay, this now exists as the pex3_venv_create_extra_args field, including a call-out in the long-form docs about this specific failure mode because it seems to be common enough to be worth it. I've tested I can reproduce the issue from #20224 and that adding pex3_venv_create_extra_args=["--collisions-ok"], gets it working again 🎉

@huonw huonw changed the title Allow passing --collisions-ok when building FaaS artifacts Allow passing arbitrary args to PEX invocation when building FaaS artifacts Dec 11, 2023
@huonw huonw merged commit 9d13e70 into main Dec 11, 2023
@huonw huonw deleted the huonw/20224-collisions-ok branch December 11, 2023 04:20
WorkerPants pushed a commit that referenced this pull request Dec 11, 2023
…ifacts (#20237)

This adds an `pex3_venv_create_extra_args` field to all FaaS targets
(`python_aws_lambda_function`, `python_aws_lambda_layer`,
`python_google_cloud_function`). This allows adding arbitrary extra
arguments that are passed to the `pex3 venv create --layout=flat-zipped
...` invocation that is used to create the final zip file.

Most acutely, this is driven by making it possible to pass the
`--collisions-ok` flag. This allows work around dependencies that are
packaged with files outside a namespaced directories, e.g. commonly a
LICENCE or README file, or `tests/` directory, since they'll have
different content. A command like `pip install ...` will happily install
them and have one of the files "win" arbitrarily, while PEX is more
correct and flags that it doesn't know what to do in that circumstance.

Fixes #20224

This is marked for cherry picking back to 2.18 because it can block
adoption of the new layout, and the old (lambdex) layout is deprecated
and using it is noisy in 2.18.
@WorkerPants
Copy link
Member

I tried to automatically cherry-pick this change back to each relevant milestone, so that it is available in those older releases of Pants.

❌ 2.18.x

I was unable to cherry-pick this PR to 2.18.x, likely due to merge-conflicts.

Steps to Cherry-Pick locally

To resolve:

  1. (Ensure your git working directory is clean)
  2. Run the following script to reproduce the merge-conflicts:
    git fetch https://github.com/pantsbuild/pants main \
      && git fetch https://github.com/pantsbuild/pants 2.18.x \
      && git checkout -b cherry-pick-20237-to-2.18.x FETCH_HEAD \
      && git cherry-pick 9d13e70f744c808b8691a582bfddf6e2b990a9b0
  3. Fix the merge conflicts and commit the changes
  4. Run build-support/cherry_pick/make_pr.sh "20237" "2.18.x"

Please note that I cannot re-run CI if a job fails. Please work with your PR approver(s) to re-run CI if necessary.

✔️ 2.19.x

Successfully opened #20280.


When you're done manually cherry-picking, please remove the needs-cherrypick label on this PR.

Thanks again for your contributions!

🤖 Beep Boop here's my run link

@WorkerPants WorkerPants added the auto-cherry-picking-failed Auto Cherry-Picking Failed label Dec 11, 2023
huonw added a commit that referenced this pull request Dec 11, 2023
…ifacts (#20237)

This adds an `pex3_venv_create_extra_args` field to all FaaS targets
(`python_aws_lambda_function`, `python_aws_lambda_layer`,
`python_google_cloud_function`). This allows adding arbitrary extra
arguments that are passed to the `pex3 venv create --layout=flat-zipped
...` invocation that is used to create the final zip file.

Most acutely, this is driven by making it possible to pass the
`--collisions-ok` flag. This allows work around dependencies that are
packaged with files outside a namespaced directories, e.g. commonly a
LICENCE or README file, or `tests/` directory, since they'll have
different content. A command like `pip install ...` will happily install
them and have one of the files "win" arbitrarily, while PEX is more
correct and flags that it doesn't know what to do in that circumstance.

Fixes #20224

This is marked for cherry picking back to 2.18 because it can block
adoption of the new layout, and the old (lambdex) layout is deprecated
and using it is noisy in 2.18.
huonw added a commit that referenced this pull request Dec 11, 2023
…ifacts (Cherry-pick of #20237) (#20280)

This adds an `pex3_venv_create_extra_args` field to all FaaS targets
(`python_aws_lambda_function`, `python_aws_lambda_layer`,
`python_google_cloud_function`). This allows adding arbitrary extra
arguments that are passed to the `pex3 venv create --layout=flat-zipped
...` invocation that is used to create the final zip file.

Most acutely, this is driven by making it possible to pass the
`--collisions-ok` flag. This allows work around dependencies that are
packaged with files outside a namespaced directories, e.g. commonly a
LICENCE or README file, or `tests/` directory, since they'll have
different content. A command like `pip install ...` will happily install
them and have one of the files "win" arbitrarily, while PEX is more
correct and flags that it doesn't know what to do in that circumstance.

Fixes #20224

This is marked for cherry picking back to 2.18 because it can block
adoption of the new layout, and the old (lambdex) layout is deprecated
and using it is noisy in 2.18.

Co-authored-by: Huon Wilson <huon@exoflare.io>
huonw added a commit that referenced this pull request Dec 12, 2023
…ifacts (Cherry-pick of #20237) (#20281)

This adds an `pex3_venv_create_extra_args` field to all FaaS targets
(`python_aws_lambda_function`, `python_aws_lambda_layer`,
`python_google_cloud_function`). This allows adding arbitrary extra
arguments that are passed to the `pex3 venv create --layout=flat-zipped
...` invocation that is used to create the final zip file.

Most acutely, this is driven by making it possible to pass the
`--collisions-ok` flag. This allows work around dependencies that are
packaged with files outside a namespaced directories, e.g. commonly a
LICENCE or README file, or `tests/` directory, since they'll have
different content. A command like `pip install ...` will happily install
them and have one of the files "win" arbitrarily, while PEX is more
correct and flags that it doesn't know what to do in that circumstance.

Fixes #20224

This is marked for cherry picking back to 2.18 because it can block
adoption of the new layout, and the old (lambdex) layout is deprecated
and using it is noisy in 2.18.
huonw added a commit that referenced this pull request May 23, 2024
Similar to #20237, this allows passing arbitrary arguments to the first
pex invocation when building a FaaS (AWS Lambda or Google Cloud
Function) artifact.

This can serve as a stop-gap for #19256, because a user can write then
pass `--exclude` themselves when they really need that (or similar)
functionality.

---------

Co-authored-by: Huon Wilson <huon@exoflare.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow silencing dependency collision warnings when packaging python_aws_lambda_function
4 participants