Skip to content
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

cmake: embed Python dependencies #47501

Closed
wants to merge 2 commits into from
Closed

Conversation

pereman2
Copy link
Contributor

@pereman2 pereman2 commented Aug 8, 2022

With these changes python dependencies are embedded inside a
__pypackages__ folder in pybind/mgr which will be preprended to the
PYTHONPATH so that that folder is the first one checked for
dependencies.

ceph.spec.in is updated to disable installing dashboard dependencies by
default and instead we provide a --without embedded_pip_pkgs option to disable embedded
dependencies.

New dependencies are added to pybind/mgr/requirements-mgr.txt and a lock
file is generated with pip-tools through a tox command: tox -e gen-mgr-requirements.

A script is introduced, in script/pypackages.sh, to generate the pypackages folder which holds
the dependencies and later used by the mgr to import them.

Signed-off-by: Pere Diaz Bou pdiazbou@redhat.com

Contribution Guidelines

Checklist

  • Tracker (select at least one)
    • References tracker ticket
    • Very recent bug; references commit where it was introduced
    • New feature (ticket optional)
    • Doc update (no ticket needed)
    • Code cleanup (no ticket needed)
  • Component impact
    • Affects Dashboard, opened tracker ticket
    • Affects Orchestrator, opened tracker ticket
    • No impact that needs to be tracked
  • Documentation (select at least one)
    • Updates relevant documentation
    • No doc update is appropriate
  • Tests (select at least one)
Show available Jenkins commands
  • jenkins retest this please
  • jenkins test classic perf
  • jenkins test crimson perf
  • jenkins test signed
  • jenkins test make check
  • jenkins test make check arm64
  • jenkins test submodules
  • jenkins test dashboard
  • jenkins test dashboard cephadm
  • jenkins test api
  • jenkins test docs
  • jenkins render docs
  • jenkins test ceph-volume all
  • jenkins test ceph-volume tox
  • jenkins test windows

@pereman2 pereman2 added this to In progress in Dashboard via automation Aug 8, 2022
@pereman2 pereman2 requested review from a team as code owners August 8, 2022 15:49
@pereman2 pereman2 requested review from nSedrickm and melissa-kun-li and removed request for a team August 8, 2022 15:49
@pereman2 pereman2 requested review from tchaikov, djgalloway and epuertat and removed request for nSedrickm and melissa-kun-li August 8, 2022 15:51
@epuertat
Copy link
Member

@pereman2 apart from regular (old-fashioned) pip, we can explore modern incarnations of that, like pipenv, pip-compile or poetry. The idea of having the plain requirements defined, and later the whole list of pinned dependencies is closer to our (not so bad) experience with npm and package.json and package-lock.json.

Dependabot supports the following formats for defining Python dependencies:

Language Ecosystem Manifest file Dependency scope supported
Python Poetry poetry.lock
Python Poetry pyproject.toml
Python pip requirements.txt ✔ Scope is development if the filename contains test or dev, else it is runtime
Python pip pipfile.lock
Python pip pipfile

Copy link
Contributor

@rzarzynski rzarzynski 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 not a cmake nor mgr expert but I don't see any obvious issues here, so – FWIW – LGTM.

cmake/modules/InstallPipDep.cmake Outdated Show resolved Hide resolved
src/mgr/PyModule.cc Outdated Show resolved Hide resolved
Dashboard automation moved this from In progress to Reviewer approved Aug 19, 2022
Copy link
Member

@epuertat epuertat left a comment

Choose a reason for hiding this comment

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

Really nice PoC, @pereman2 !

My observations:

  • We cannot assume that during cmake the system will have access to the internet, so we should act otherwise. In fact, that's already the assumption and why install-deps.sh scans the requirements.txt and prefetches those Python deps.
  • There are (at least) 2 possible approaches here:
    • Downloading but not installing the packages (e.g.: install-deps.sh and make-dist running pip download) and then cmake runs the pip install from these downloaded packages.
    • The approach already used for npm packages: Python packages are downloaded and installed to their locations in the Ceph repo, and then are tarballed and 'injected' in the package stage
  • We need to add the requirements lock file and a check that fails if there's a mismatch between the requirements and the lock file (npm install and other tools implement this behaviour by default).

@pereman2 pereman2 force-pushed the pip-dep branch 2 times, most recently from 6b0ba8f to 2016ea2 Compare August 22, 2022 16:22
@pereman2 pereman2 requested a review from s0nea August 22, 2022 16:23
@pereman2
Copy link
Contributor Author

jenkins test make check

Copy link
Member

@epuertat epuertat left a comment

Choose a reason for hiding this comment

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

LGTM! Just a few suggestions.

ceph.spec.in Outdated Show resolved Hide resolved
ceph.spec.in Outdated Show resolved Hide resolved
install-deps.sh Outdated Show resolved Hide resolved
install-deps.sh Outdated Show resolved Hide resolved
make-dist Outdated Show resolved Hide resolved
Comment on lines 1 to 6
CherryPy==18.8.0
pyjwt==2.4.0
routes==2.5.1
werkzeug==2.0.3
saml==0.9.0
setuptools==59.6.0
Copy link
Member

Choose a reason for hiding this comment

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

Are these the latest or the current ones?

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 updated:
cherrypy from 18.4.0 > 18.8.0
saml 1.9.0 > 0.9.0, looks like a downgrade but pip install has these versions: 0.2.0, 0.2.1, 0.3.0, 0.3.1, 0.3.2, 0.3.3, 0.4.0, 0.5.0, 0.6.0, 0.7.0, 0.8.0, 0.9.0 reported when I try to install 1.9.0
the rest of packages have the same issue as the two above, so I had to either upgrade or to point to a similar version

Copy link
Member

Choose a reason for hiding this comment

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

Interestingly we've been using the wrong python package for a while: it's the python-saml, not the saml one.

Dashboard automation moved this from Reviewer approved to Review in progress Aug 23, 2022
Copy link
Contributor

@tchaikov tchaikov left a comment

Choose a reason for hiding this comment

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

the commit message is practically empty. would be better to put the content of cover letter into the commit message.

but a bigger problem is, this change makes the process of introducing dashboard simpler, but it defeats the purpose of packaging. and make the life of downstream maintainer more difficult.

i've been working on facilitating the process by introducing the .requires files, for instance https://github.com/ceph/ceph/blob/main/debian/ceph-mgr-dashboard.requires . i understand this is far from a complete solution. but instead of reinventing the wheel, i believe a better solution is to work with the packaging machinery instead of vendoring python dependencies.

i see two approaches here

  1. to package dashboard as a proper python package. so the packaging tools is able to extract the dependencies from, for instance, egg-info.
  2. to use the homebrew scripts to generate the dependencies from requirements.txt and insert them into ceph.spec.in and debian/control. the .requires files is an early attempt in this direction.

@epuertat
Copy link
Member

@pereman2 this should be quicker to test & troubleshoot without teuthology, just Shaman (or a local rpmbuild) + simple vstart (ceph-dev) cluster running on RPMs. Here you have an example.

@epuertat
Copy link
Member

@pereman2: I think I got it: there's a missing install(DIRECTORY __pypackages__ ...) in the src/pybind/mgr/CMakeLists.txt.

@cbodley
Copy link
Contributor

cbodley commented Mar 10, 2023

looks like that worked for https://pulpito.ceph.com/cbodley-2023-03-10_17:38:32-rgw:verify-wip-pereman2-testing-2022-09-05-1259-distro-default-smithi/

the find command listed everything, and ceph-mgr seems to have started up okay. there were several warnings about missing NOTIFY_TYPES, is that related somehow?

2023-03-10T17:56:21.074+0000 7f016c819040 -1 mgr[py] Module rbd_support has missing NOTIFY_TYPES member
2023-03-10T17:56:22.302+0000 7fd769c15040 -1 mgr[py] Module devicehealth has missing NOTIFY_TYPES member
...

@pereman2
Copy link
Contributor Author

looks like that worked for https://pulpito.ceph.com/cbodley-2023-03-10_17:38:32-rgw:verify-wip-pereman2-testing-2022-09-05-1259-distro-default-smithi/

the find command listed everything, and ceph-mgr seems to have started up okay. there were several warnings about missing NOTIFY_TYPES, is that related somehow?

2023-03-10T17:56:21.074+0000 7f016c819040 -1 mgr[py] Module rbd_support has missing NOTIFY_TYPES member
2023-03-10T17:56:22.302+0000 7fd769c15040 -1 mgr[py] Module devicehealth has missing NOTIFY_TYPES member
...

great news, thanks @epuertat and @cbodley for the pointers. Those warnings are expected

@pereman2
Copy link
Contributor Author

jenkins test make check

@cbodley
Copy link
Contributor

cbodley commented Mar 15, 2023

@pereman2 have you had a chance to investigate the PR check failures?

@pereman2 pereman2 force-pushed the pip-dep branch 2 times, most recently from bdb03bd to 8385317 Compare March 16, 2023 18:12
@pereman2
Copy link
Contributor Author

@cbodley should be fixed now... It was a stupid mistake

@pereman2
Copy link
Contributor Author

pereman2 commented Mar 17, 2023

there is a failure in tox-mgr where some nested dependecies of folders are not added to requirements I thought would happen by installing a dependency. For example:

ERROR __pypackages__/lib/python3/site-packages/asyncssh/gss_unix.py - ModuleNotFoundError: No module named 'gssapi'
ERROR __pypackages__/lib/python3/site-packages/asyncssh/gss_win32.py - ModuleNotFoundError: No module named 'sspi'

if you do locally pip install --target deps asyncssh it won't install gssapi nor sspi. So I'm not sure how to deal with this @epuertat, any idea?

On the other hand, If I run vstart.sh this isn't a problem somehow

@pereman2
Copy link
Contributor Author

ERROR lib64/python3.10/site-packages/virtualenv/discovery/windows/__init__.py - ModuleNotFoundError: No module named 'winreg'
ERROR lib64/python3.10/site-packages/virtualenv/discovery/windows/pep514.py - ModuleNotFoundError: No module named 'winreg'

for example it tries to import things like winreg which are windows specific and in the previous example asyncssh has an optional feature gssapi which is added manually if the asyncssh user wants it

@epuertat
Copy link
Member

there is a failure in tox-mgr where some nested dependecies of folders are not added to requirements I thought would happen by installing a dependency. For example:

ERROR __pypackages__/lib/python3/site-packages/asyncssh/gss_unix.py - ModuleNotFoundError: No module named 'gssapi'
ERROR __pypackages__/lib/python3/site-packages/asyncssh/gss_win32.py - ModuleNotFoundError: No module named 'sspi'

if you do locally pip install --target deps asyncssh it won't install gssapi nor sspi. So I'm not sure how to deal with this @epuertat, any idea?

On the other hand, If I run vstart.sh this isn't a problem somehow

Based on https://github.com/ronf/asyncssh#optional-extras and https://github.com/ronf/asyncssh/blob/8c0b42ca4fce32a4ee1979b20de85a7b7b84f80b/setup.py#L61-L69, those packages are extras, so they need to be explicitly installed via pip install ... asyncssh[gssapi].

With these changes python dependencies are embedded inside a
`__pypackages__` folder in pybind/mgr which will be preprended to the
`PYTHONPATH` so that that folder is the first one checked for
dependencies.

ceph.spec.in is updated to disable installing dashboard dependencies by
default and instead we provide a `--without embedded_pip_pkgs` option to disable embedded
dependencies.

New dependencies are added to pybind/mgr/requirements-mgr.txt and a lock
file is generated with pip-tools through a tox command: `tox -e gen-mgr-requirements`.

A script is introduced, in script/pypackages.sh, to generate the __pypackages__ folder which holds
the dependencies and later used by the mgr to import them.

Signed-off-by: Pere Diaz Bou <pdiazbou@redhat.com>
ceph.spec.in: move without_pypackges

Signed-off-by: Pere Diaz Bou <pdiazbou@redhat.com>
@rzarzynski
Copy link
Contributor

A note from bug scrub: this PR (and its related ticket) have been discussed during a CLT meeting. The outcome in our memory is that the Dashboard Folks we'll take care (please correct if I'm wrong).

@github-actions
Copy link

github-actions bot commented Jul 3, 2023

This pull request has been automatically marked as stale because it has not had any activity for 60 days. It will be closed if no further activity occurs for another 30 days.
If you are a maintainer or core committer, please follow-up on this pull request to identify what steps should be taken by the author to move this proposed change forward.
If you are the author of this pull request, thank you for your proposed contribution. If you believe this change is still appropriate, please ensure that any feedback has been addressed and ask for a code review.

@github-actions github-actions bot added the stale label Jul 3, 2023
@rzarzynski rzarzynski removed the stale label Jul 24, 2023
@rzarzynski
Copy link
Contributor

jenkins retest this please

@rzarzynski
Copy link
Contributor

@ceph/dashboard: ping.

@epuertat
Copy link
Member

@rzarzynski IMHO this is still a sensible approach... but not as urgent as when the CentOS 9 Python deps were blocking Reef. I'd keep it open, even if PEP 582 (local __pypackages__) has been rejected after a 5-year deliberation.

@github-actions
Copy link

This pull request has been automatically marked as stale because it has not had any activity for 60 days. It will be closed if no further activity occurs for another 30 days.
If you are a maintainer or core committer, please follow-up on this pull request to identify what steps should be taken by the author to move this proposed change forward.
If you are the author of this pull request, thank you for your proposed contribution. If you believe this change is still appropriate, please ensure that any feedback has been addressed and ask for a code review.

@github-actions github-actions bot added the stale label Sep 24, 2023
@github-actions
Copy link

This pull request has been automatically closed because there has been no activity for 90 days. Please feel free to reopen this pull request (or open a new one) if the proposed change is still appropriate. Thank you for your contribution!

@github-actions github-actions bot closed this Oct 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Dashboard
  
Review in progress
7 participants