Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Add a stub Rust crate (#12595)
Browse files Browse the repository at this point in the history
  • Loading branch information
erikjohnston authored Sep 6, 2022
1 parent 3d20115 commit c9b7e97
Show file tree
Hide file tree
Showing 23 changed files with 302 additions and 11 deletions.
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@
# things to include
!docker
!synapse
!rust
!README.rst
!pyproject.toml
!poetry.lock
!build_rust.py

rust/target

**/__pycache__
65 changes: 62 additions & 3 deletions .github/workflows/release-artifacts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ on:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: write

Expand Down Expand Up @@ -89,16 +89,75 @@ jobs:
name: debs
path: debs/*

build-wheels:
name: Build wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04, macos-10.15]
is_pr:
- ${{ startsWith(github.ref, 'refs/pull/') }}

exclude:
# Don't build macos wheels on PR CI.
- is_pr: true
os: "macos-10.15"

steps:
- uses: actions/checkout@v3

- uses: actions/setup-python@v3

- name: Install cibuildwheel
run: python -m pip install cibuildwheel==2.9.0 poetry==1.2.0

# Only build a single wheel in CI.
- name: Set env vars.
run: |
echo "CIBW_BUILD="cp37-manylinux_x86_64"" >> $GITHUB_ENV
if: startsWith(github.ref, 'refs/pull/')

- name: Build wheels
run: python -m cibuildwheel --output-dir wheelhouse
env:
# Skip testing for platforms which various libraries don't have wheels
# for, and so need extra build deps.
CIBW_TEST_SKIP: pp39-* *i686* *musl* pp37-macosx*

- uses: actions/upload-artifact@v3
with:
name: Wheel
path: ./wheelhouse/*.whl

build-sdist:
name: "Build pypi distribution files"
uses: "matrix-org/backend-meta/.github/workflows/packaging.yml@v1"
name: Build sdist
runs-on: ubuntu-latest
if: ${{ !startsWith(github.ref, 'refs/pull/') }}

steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.10'

- run: pip install build

- name: Build sdist
run: python -m build --sdist

- uses: actions/upload-artifact@v2
with:
name: Sdist
path: dist/*.tar.gz


# if it's a tag, create a release and attach the artifacts to it
attach-assets:
name: "Attach assets to release"
if: ${{ !failure() && !cancelled() && startsWith(github.ref, 'refs/tags/') }}
needs:
- build-debs
- build-wheels
- build-sdist
runs-on: ubuntu-latest
steps:
Expand Down
19 changes: 18 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,12 @@ jobs:
steps:
- uses: actions/checkout@v2

- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: 1.61.0
override: true

# There aren't wheels for some of the older deps, so we need to install
# their build dependencies
- run: |
Expand Down Expand Up @@ -175,7 +181,7 @@ jobs:
python-version: '3.7'
extras: "all test"

- run: poetry run trial -j 2 tests
- run: poetry run trial -j2 tests
- name: Dump logs
# Logs are most useful when the command fails, always include them.
if: ${{ always() }}
Expand Down Expand Up @@ -247,6 +253,11 @@ jobs:
- uses: actions/checkout@v2
- name: Prepare test blacklist
run: cat sytest-blacklist .ci/worker-blacklist > synapse-blacklist-with-workers
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: 1.61.0
override: true
- name: Run SyTest
run: /bootstrap.sh synapse
working-directory: /src
Expand Down Expand Up @@ -353,6 +364,12 @@ jobs:
with:
path: synapse

- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: 1.61.0
override: true

- name: Prepare Complement's Prerequisites
run: synapse/.ci/scripts/setup_complement_prerequisites.sh

Expand Down
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,10 @@ book/
# complement
/complement-*
/master.tar.gz

# rust
/target/
/synapse/*.so

# Poetry will create a setup.py, which we don't want to include.
/setup.py
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# We make the whole Synapse folder a workspace so that we can run `cargo`
# commands from the root (rather than having to cd into rust/).

[workspace]
members = ["rust"]
20 changes: 20 additions & 0 deletions build_rust.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# A build script for poetry that adds the rust extension.

import os
from typing import Any, Dict

from setuptools_rust import Binding, RustExtension


def build(setup_kwargs: Dict[str, Any]) -> None:
original_project_dir = os.path.dirname(os.path.realpath(__file__))
cargo_toml_path = os.path.join(original_project_dir, "rust", "Cargo.toml")

extension = RustExtension(
target="synapse.synapse_rust",
path=cargo_toml_path,
binding=Binding.PyO3,
py_limited_api=True,
)
setup_kwargs.setdefault("rust_extensions", []).append(extension)
setup_kwargs["zip_safe"] = False
1 change: 1 addition & 0 deletions changelog.d/12595.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add a stub Rust crate.
7 changes: 6 additions & 1 deletion debian/build_virtualenv
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ dh_virtualenv \
--extras="all,systemd,test" \
--requirements="exported_requirements.txt"

PACKAGE_BUILD_DIR="debian/matrix-synapse-py3"
PACKAGE_BUILD_DIR="$(pwd)/debian/matrix-synapse-py3"
VIRTUALENV_DIR="${PACKAGE_BUILD_DIR}${DH_VIRTUALENV_INSTALL_ROOT}/matrix-synapse"
TARGET_PYTHON="${VIRTUALENV_DIR}/bin/python"

Expand All @@ -78,9 +78,14 @@ case "$DEB_BUILD_OPTIONS" in

cp -r tests "$tmpdir"

# To avoid pulling in the unbuilt Synapse in the local directory
pushd /

PYTHONPATH="$tmpdir" \
"${TARGET_PYTHON}" -m twisted.trial --reporter=text -j2 tests

popd

;;
esac

Expand Down
4 changes: 4 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@ matrix-synapse-py3 (1.66.0) stable; urgency=medium

matrix-synapse-py3 (1.66.0~rc2+nmu1) UNRELEASED; urgency=medium

[ Jörg Behrmann ]
* Update debhelper to compatibility level 12.
* Drop the preinst script stopping synapse.
* Allocate a group for the system user.
* Change dpkg-statoverride to --force-statoverride-add.

[ Erik Johnston ]
* Disable `dh_auto_configure` as it broke during Rust build.

-- Jörg Behrmann <behrmann@physik.fu-berlin.de> Tue, 23 Aug 2022 17:17:00 +0100

matrix-synapse-py3 (1.66.0~rc2) stable; urgency=medium
Expand Down
2 changes: 2 additions & 0 deletions debian/rules
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ override_dh_installsystemd:
# we don't really want to strip the symbols from our object files.
override_dh_strip:

override_dh_auto_configure:

# many libraries pulled from PyPI have allocatable sections after
# non-allocatable ones on which dwz errors out. For those without the issue the
# gains are only marginal
Expand Down
14 changes: 12 additions & 2 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,20 @@ RUN \
libxml++2.6-dev \
libxslt1-dev \
openssl \
rustc \
zlib1g-dev \
git \
curl \
&& rm -rf /var/lib/apt/lists/*


# Install rust and ensure its in the PATH
ENV RUSTUP_HOME=/rust
ENV CARGO_HOME=/cargo
ENV PATH=/cargo/bin:/rust/bin:$PATH
RUN mkdir /rust /cargo

RUN curl -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path --default-toolchain stable

# To speed up rebuilds, install all of the dependencies before we copy over
# the whole synapse project, so that this layer in the Docker cache can be
# used while you develop on the source
Expand All @@ -108,8 +117,9 @@ RUN --mount=type=cache,target=/root/.cache/pip \

# Copy over the rest of the synapse source code.
COPY synapse /synapse/synapse/
COPY rust /synapse/rust/
# ... and what we need to `pip install`.
COPY pyproject.toml README.rst /synapse/
COPY pyproject.toml README.rst build_rust.py /synapse/

# Repeat of earlier build argument declaration, as this is a new build stage.
ARG TEST_ONLY_IGNORE_POETRY_LOCKFILE
Expand Down
10 changes: 10 additions & 0 deletions docker/Dockerfile-dhvirtualenv
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ RUN apt-get update -qq -o Acquire::Languages=none \
&& env DEBIAN_FRONTEND=noninteractive apt-get install \
-yqq --no-install-recommends -o Dpkg::Options::=--force-unsafe-io \
build-essential \
curl \
debhelper \
devscripts \
libsystemd-dev \
Expand All @@ -85,6 +86,15 @@ RUN apt-get update -qq -o Acquire::Languages=none \
libpq-dev \
xmlsec1

# Install rust and ensure it's in the PATH
ENV RUSTUP_HOME=/rust
ENV CARGO_HOME=/cargo
ENV PATH=/cargo/bin:/rust/bin:$PATH
RUN mkdir /rust /cargo

RUN curl -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path --default-toolchain stable


COPY --from=builder /dh-virtualenv_1.2.2-1_all.deb /

# install dhvirtualenv. Update the apt cache again first, in case we got a
Expand Down
13 changes: 13 additions & 0 deletions docs/deprecation_policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ documented at [https://endoflife.date/python](https://endoflife.date/python) and
[https://endoflife.date/postgresql](https://endoflife.date/postgresql).


A Rust compiler is required to build Synapse from source. For any given release
the minimum required version may be bumped up to a recent Rust version, and so
people building from source should ensure they can fetch recent versions of Rust
(e.g. by using [rustup](https://rustup.rs/)).


Context
-------

Expand All @@ -31,3 +37,10 @@ long process.
By following the upstream support life cycles Synapse can ensure that its
dependencies continue to get security patches, while not requiring system admins
to constantly update their platform dependencies to the latest versions.

For Rust, the situation is a bit different given that a) the Rust foundation
does not generally support older Rust versions, and b) the library ecosystem
generally bump their minimum support Rust versions frequently. In general, the
Synapse team will try to avoid updating the dependency on Rust to the absolute
latest version, but introducing a formal policy is hard given the constraints of
the ecosystem.
10 changes: 9 additions & 1 deletion docs/development/contributing_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ The source code of Synapse is hosted on GitHub. You will also need [a recent ver

For some tests, you will need [a recent version of Docker](https://docs.docker.com/get-docker/).

A recent version of the Rust compiler is needed to build the native modules. The
easiest way of installing the latest version is to use [rustup](https://rustup.rs/).


# 3. Get the source.

Expand Down Expand Up @@ -114,6 +117,11 @@ Some documentation also exists in [Synapse's GitHub
Wiki](https://github.com/matrix-org/synapse/wiki), although this is primarily
contributed to by community authors.

When changes are made to any Rust code then you must call either `poetry install`
or `maturin develop` (if installed) to rebuild the Rust code. Using [`maturin`](https://github.com/PyO3/maturin)
is quicker than `poetry install`, so is recommended when making frequent
changes to the Rust code.


# 8. Test, test, test!
<a name="test-test-test"></a>
Expand Down Expand Up @@ -195,7 +203,7 @@ The database file can then be inspected with:
sqlite3 _trial_temp/test.db
```

Note that the database file is cleared at the beginning of each test run. Thus it
Note that the database file is cleared at the beginning of each test run. Thus it
will always only contain the data generated by the *last run test*. Though generally
when debugging, one is only running a single test anyway.

Expand Down
4 changes: 4 additions & 0 deletions docs/setup/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ System requirements:
- Python 3.7 or later, up to Python 3.10.
- At least 1GB of free RAM if you want to join large public rooms like #matrix:matrix.org

If building on an uncommon architecture for which pre-built wheels are
unavailable, you will need to have a recent Rust compiler installed. The easiest
way of installing the latest version is to use [rustup](https://rustup.rs/).

To install the Synapse homeserver run:

```sh
Expand Down
6 changes: 5 additions & 1 deletion mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ files =
docker/,
scripts-dev/,
synapse/,
tests/
tests/,
build_rust.py

# Note: Better exclusion syntax coming in mypy > 0.910
# https://github.com/python/mypy/pull/11329
Expand Down Expand Up @@ -181,3 +182,6 @@ ignore_missing_imports = True

[mypy-incremental.*]
ignore_missing_imports = True

[mypy-setuptools_rust.*]
ignore_missing_imports = True
Loading

0 comments on commit c9b7e97

Please sign in to comment.