parsec-cloud icon indicating copy to clipboard operation
parsec-cloud copied to clipboard

[Oxidation in prod] Release architecture

Open touilleMan opened this issue 3 years ago • 2 comments

Current situation

Server release

A platform-independent wheel is generated as the first step in the CI, then once all tests have passed it is uploaded to pypi.

Deploying to a PAAS (e.g. Heroku), correspond to create a minimal Python project with parsec-cloud[backend] as only dependency.

Client release

Release code is specific for each platform (Linux/Windows/MacOS).

Typically on Windows release is 1) build the project as a wheel, install it with it dependencies 2) use PyInstaller to bundle all this with a Python distribution 3) generate an installer with NSIS

The approach is pretty similir on Linux (using Snap) an MacOS (PyInstaller only)

New & old issues

  • issue 1: The current way of deploying with Pypi doesn't preserve dependency pinning (especially transitive ones). This is bad given it makes older version of parsec hard to install and we have no strong guarantee on what runs on the server :(
  • issue 2: On top of that we the wheel is going to be platform-dependent now that we ship Rust code within it.
  • issue 3: Snap tries very hard to reuse the system python & libraries, but it breaks because we run in unsandboxed mode (insert surprised Pikachu meme here), so we end up with a lot of fragile hack

Approach 1: Stick with the wheel

Server

The simplest solution is to keep the wheel system and accept that we are going to provide linux-only.

This reduce the usefulness of providing parsec on pypi (it used to be a valid way of installing parsec client) but it's not that bad given pypi was mostly used for server deployment (an nobody is going to anything other than linux for this use-case !)

However the generation of the wheel itself is a more tricky if we want to be portable given we should use manylinux to be compatible with most linux distributions.

Of course we can also go full yolo, just build the wheel on ubuntu and consider it is "fine enough" ;-)

Client

This should be transparent for the client scripts. Of course issues 2 and 3 still remain.

Approach 2: Pyoxidizer

Another more advanced solution is to use pyoxidizer to generate a full binary (including python distribution & parsec dependencies).

The good thing it we should be able to control precisely what should be installed (typically using poetry export to generate a requirements.txt containing all the pinned dependencies and there hash), so no more issue 1 \o/

On top of that, PyOxidizer provide a full distribution with static linking of it dependencies so we should be able to run it everywhere without compatibility issues. So no need for manylinux, and no more issue 3 given snap ship a single binary with no dependencies \o/

Last but not least, PyOxidizer comes with some tooling for building packages automatically. Among other we should try:

  • snap to further simplify issue 3
  • macOS given we won't use PyInstaller anymore
  • debian so that we can release the server as a .deb which can be easily installed on Heroku

What should we do then ?

Approach 1) is the simplest one (especially in yolo mode) so I think we should start with this one, while toying around with approach 2) which is more promising in the long run.

touilleMan avatar Jun 21 '22 14:06 touilleMan

Of course we can also go full yolo, just build the wheel on ubuntu and consider it is "fine enough" ;-)

No need to go yolo when when we have cibuildwheel!

A single github action and we build a robust wheel that is going to work on all (reasonable) linux. Building for windows and osx is also supported. We're already using this for winfspy: https://github.com/Scille/winfspy/blob/29391f21aa0210b67a44f73777badf64eae4ee6d/.github/workflows/ci.yml#L39-L44

Another example of one of my own project depending on cython c/c++ extensions: https://github.com/vxgmichel/gambatte-terminal/blob/dec93bdae38c4736341df3090c4d88343d561416/.github/workflows/build.yml#L12-L34

vxgmichel avatar Jun 22 '22 11:06 vxgmichel

From #2778 we now build platform depends wheels

FirelightFlagboy avatar Aug 08 '22 15:08 FirelightFlagboy

@touilleMan Should we close this issue ? We used the approach 1, but If we want to do more test on approach 2, I suggest to open a new issue for that

FirelightFlagboy avatar Aug 26 '22 09:08 FirelightFlagboy

@FirelightFlagboy I think our current system is good enough, no need to go further with pyoxidizer (especially given the test we did showed it is not mature enough for our needs)

touilleMan avatar Aug 26 '22 13:08 touilleMan