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

Move from crossbar/autobahn to gRPC #1469

Merged
merged 38 commits into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
2099ee2
treewide: replace autobahn and crossbar with gRPC
jluebbe Jun 20, 2024
d7ac3e7
remote/exporter: make coordinator port default to 20408
Bastian-Krause Aug 2, 2024
db9a326
remote/coordinator: catch exceptions from poll steps separately
jluebbe Jul 3, 2024
829acab
remote/coordinator: simplify _update_acquired_places()
jluebbe Jul 3, 2024
2ca1329
remote/coordinator: split out code to acquire a resource on the exporter
jluebbe Jul 3, 2024
33126fa
remote/client: explicitly handle orphaned resources in the client
jluebbe Jul 3, 2024
fc7b802
remote/coordinator: refactor handling of orphaned resources
jluebbe Jul 3, 2024
bef539e
remote: rework grpc timeout configuration
jluebbe Jul 3, 2024
f32d418
remote/coordinator: disable so_reuseport
jluebbe Jul 3, 2024
9ad28c3
remote/coordinator: store event loop in loop attribute
Bastian-Krause Aug 1, 2024
1bd0f99
remote/client: drop error check already done by argparser
Bastian-Krause Jul 23, 2024
5679fa5
remote/client: replace manual place checks with helper method calls
Bastian-Krause Aug 8, 2024
4230591
remote/client: drop redundant checks
Bastian-Krause Jul 23, 2024
624667c
remote/client: be more explicit about expected place acquired state i…
Bastian-Krause Jul 23, 2024
da95c44
remote: use more explicit event loop handling
Bastian-Krause Aug 1, 2024
0e1e4fb
remote/client: rework event loop handling in start_session()
Bastian-Krause Aug 1, 2024
545d240
remote/client: provide default for ClientSession.env to make it optional
Bastian-Krause Aug 2, 2024
37a92b5
remote: make start_session() args more explicit
Bastian-Krause Aug 2, 2024
606af35
tests/test_ethernetport: create and set event loop for test
Bastian-Krause Jul 31, 2024
cb9ecde
tests/conftest: turn exporter fixture into class
Bastian-Krause Jul 2, 2024
373874b
tests/conftest: move common Exporter functionality into generic Labgr…
Bastian-Krause Jul 17, 2024
15da271
tests/conftest: make coordinator fixture use a helper class Coordinator
Bastian-Krause Jul 17, 2024
5b2776d
tests/conftest: move suspend_tree/resume_tree into LabgridComponent
Bastian-Krause Jul 17, 2024
df8df52
tests/test_remote: add test_exporter_start_coordinator_unreachable
Bastian-Krause Jul 17, 2024
8462aeb
tests/test_remote: add test_exporter_coordinator_becomes_unreachable
Bastian-Krause Jul 17, 2024
61516b6
contrib/systemd: update service for new versions of coordinator/exporter
Bastian-Krause Aug 7, 2024
394864e
contrib/coordinator-statsd: migrate to gRPC
Bastian-Krause Aug 2, 2024
b589897
contrib/labgrid-webapp: migrate to gRPC
Bastian-Krause Aug 2, 2024
5a49429
contrib/sync-places: migrate to gRPC
Bastian-Krause Aug 2, 2024
13969df
examples: migrate to gRPC
Bastian-Krause Aug 7, 2024
c613f1e
dockerfiles: migrate to gRPC
Bastian-Krause Jul 22, 2024
81f5801
man: update for gRPC
Bastian-Krause Aug 8, 2024
e0167ae
doc: update for gRPC
Bastian-Krause Aug 8, 2024
045634b
github/workflows/reusable-unit-tests: skip pylint for python3.8
Bastian-Krause Jul 22, 2024
bf4379c
pyproject: advertise python3.12 compatibility
Bastian-Krause Aug 7, 2024
0ea9fe5
debian: install labgrid-coordinator
Bastian-Krause Aug 13, 2024
1a406bc
debian: numpy is no longer an indirect dependency
Bastian-Krause Aug 13, 2024
ab8f79a
CHANGES: add gRPC migration to new 24.1 release
Bastian-Krause Aug 13, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .crossbar/.gitignore

This file was deleted.

47 changes: 0 additions & 47 deletions .crossbar/config-anonymous.yaml

This file was deleted.

9 changes: 3 additions & 6 deletions .github/workflows/reusable-unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
${{ runner.os }}-pip-
- name: Install system dependencies
run: |
sudo apt-get install -yq libow-dev openssh-server openssh-client libsnappy-dev graphviz openocd
sudo apt-get install -yq libow-dev openssh-server openssh-client graphviz openocd
sudo mkdir -p /var/cache/labgrid/runner && sudo chown runner /var/cache/labgrid/runner
- name: Prepare local SSH
run: |
Expand All @@ -46,17 +46,14 @@ jobs:
- name: Install labgrid
run: |
pip install -e ".[dev]"
- name: Install crossbar in virtualenv
run: |
virtualenv -p python3 crossbar-venv
crossbar-venv/bin/pip install -r crossbar-requirements.txt
- name: Lint with pylint
if: inputs.python-version != '3.8'
run: |
pylint --list-msgs-enabled
pylint labgrid
- name: Test with pytest
run: |
pytest --cov-config .coveragerc --cov=labgrid --local-sshmanager --ssh-username runner --crossbar-venv crossbar-venv -k "not test_docker_with_daemon"
pytest --cov-config .coveragerc --cov=labgrid --local-sshmanager --ssh-username runner -k "not test_docker_with_daemon"
- name: Build documentation
run: |
make -C doc clean
Expand Down
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@
/.pytest_cache/
/htmlcov/
/labgrid/_version.py
/dockerfiles/staging/crossbar/*
!/dockerfiles/staging/crossbar/places_example.yaml
/dockerfiles/staging/coordinator/*
!/dockerfiles/staging/coordinator/places_example.yaml
/.idea
51 changes: 51 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,54 @@
Release 24.1 (Unreleased)
-------------------------
As announced
`before <https://github.com/labgrid-project/labgrid/discussions/1467#discussioncomment-10314852>`_,
this is the first release using gRPC instead of crossbar/autobahn for
communication between client/exporter and coordinator.

Crossbar/autobahn are unfortunately not very well maintained anymore. The
crossbar component was moved to its own virtualenv to cope with the high number
of dependencies leading to conflicts. Support for Python 3.13 is still not
available in a crossbar release on PyPI.

That's why labgrid moves to gRPC with this release. gRPC is a well maintained
RPC framework with a lot of users. As a side effect, the message transfer is
more performant and the import times are shorter.

New Features in 24.1
~~~~~~~~~~~~~~~~~~~~
- All components can be installed into the same virtualenv again.

Bug fixes in 24.1
~~~~~~~~~~~~~~~~~

FIXME

Breaking changes in 24.1
~~~~~~~~~~~~~~~~~~~~~~~~
Maintaining support for both crossbar/autobahn as well as gRPC in labgrid would
be a lot of effort due to the different architectures of those frameworks.
Therefore, a hard migration to gRPC is deemed the lesser issue.

Due to the migration, 24.1 includes the following breaking changes:

- The labgrid environment config option ``crossbar_url`` was renamed to
``coordinator_address``. The environment variable ``LG_CROSSBAR`` was renamed
to ``LG_COORDINATOR``.
- The labgrid environment config option ``crossbar_realm`` is now obsolete as
well as the environment variable ``LG_CROSSBAR_REALM``.
- The coordinator is available as ``labgrid-coordinator`` (instead of
``crossbar start``). No additional configuration file is required.
- The systemd services in ``contrib/systemd/`` were updated.

Other breaking changes include:

FIXME

Known issues in 24.1
~~~~~~~~~~~~~~~~~~~~

FIXME

Release 24.0 (Released Aug 12, 2024)
------------------------------------

Expand Down
6 changes: 3 additions & 3 deletions contrib/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ Quick Start
$ source venv/bin/activate
venv $ pip install -r contrib/requirements-webapp.txt
venv $ ./contrib/labgrid-webapp --help
usage: labgrid-webapp [-h] [--crossbar URL] [--port PORT] [--proxy PROXY]
usage: labgrid-webapp [-h] [--coordinator ADDRESS] [--port PORT] [--proxy PROXY]

Labgrid webapp

options:
-h, --help show this help message and exit
--crossbar URL, -x URL
Crossbar websocket URL (default: ws://127.0.0.1:20408/ws)
--coordinator ADDRESS, -x ADDRESS
Coordinator address as HOST[:PORT] (default: 127.0.0.1:20408)
--port PORT Port to serve on
--proxy PROXY, -P PROXY

Expand Down
6 changes: 3 additions & 3 deletions contrib/completion/labgrid-client.bash
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

# options top level and subcommands support
_labgrid_shared_options="--help"
_labgrid_main_opts_with_value="@(-x|--crossbar|-c|--config|-p|--place|-s|--state|-i|--initial-state|-P|--proxy)"
_labgrid_main_opts_with_value="@(-x|--coordinator|-c|--config|-p|--place|-s|--state|-i|--initial-state|-P|--proxy)"

# Parses labgrid-client arguments
# Sets arg to subcommand, excluding options and their values.
# Sets last_arg_opt_with_value to true if the last argument is an option requiring a value, else
# false.
# Sets base_cmd to the labgrid-client base command up to subcommand and removes trailing
# option requiring a value - useful to call 'labgrid-client complete' with place/crossbar/proxy set
# option requiring a value - useful to call 'labgrid-client complete' with place/coordinator/proxy set
# Before calling this function, make sure arg, base_cmd and last_arg_opt_with_value are local
_labgrid_parse_args()
{
Expand Down Expand Up @@ -867,7 +867,7 @@ _labgrid_client()
case "$cur" in
--*)
# top level args completion
local options="--crossbar \
local options="--coordinator \
--config \
--place \
--state \
Expand Down
45 changes: 22 additions & 23 deletions contrib/coordinator-statsd.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,14 @@

import sys
import argparse
import statsd
import os
import labgrid.remote.client
import time
import asyncio
import txaio

from labgrid.remote.client import start_session, Error
from labgrid.remote.generated import labgrid_coordinator_pb2
from labgrid.remote.common import Reservation
import statsd


def inc_gauge(gauges, key):
Expand All @@ -56,12 +58,13 @@ def inc_gauge(gauges, key):


async def report_reservations(session, tags, gauges):
reservations = await session.call("org.labgrid.coordinator.get_reservations")
request = labgrid_coordinator_pb2.GetReservationsRequest()

for token, config in reservations.items():
state = config["state"]
response = await session.stub.GetReservations(request)
reservations = [Reservation.from_pb2(x) for x in response.reservations]

groups = config.get("filters", {})
for reservation in reservations:
groups = reservation.filters

if not groups:
groups = {"": {}}
Expand All @@ -72,7 +75,7 @@ async def report_reservations(session, tags, gauges):
".".join(
["reservations", group_name]
+ [group.get(t, "") for t in tags]
+ [state]
+ [reservation.state.name]
),
)

Expand All @@ -94,10 +97,10 @@ def main():
)
parser.add_argument(
"-x",
"--crossbar",
metavar="URL",
help="Crossbar URL for the coordinator",
default=os.environ.get("LG_CROSSBAR", "ws://127.0.0.1:20408/ws"),
"--coordinator",
metavar="ADDRESS",
help="Coordinator address as HOST[:PORT]. Default is %(default)s",
default=os.environ.get("LG_COORDINATOR", "127.0.0.1:20408"),
)
parser.add_argument(
"--period",
Expand Down Expand Up @@ -142,8 +145,8 @@ def main():

args = parser.parse_args()

txaio.use_asyncio()
txaio.config.loop = asyncio.get_event_loop()
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)

statsd_client = None
gauges = {}
Expand Down Expand Up @@ -175,22 +178,18 @@ def main():

next_time = time.monotonic() + args.period
try:
extra = {}
session = labgrid.remote.client.start_session(
args.crossbar,
os.environ.get("LG_CROSSBAR_REALM", "realm1"),
extra,
)
session = start_session(args.coordinator, loop=loop)
try:
session.loop.run_until_complete(
loop.run_until_complete(
asyncio.gather(
report_places(session, args.tags, gauges),
report_reservations(session, args.tags, gauges),
)
)
finally:
session.leave()
except labgrid.remote.client.Error as e:
loop.run_until_complete(session.stop())
loop.run_until_complete(session.close())
except Error as e:
print(f"Error communicating with labgrid: {e}")
continue

Expand Down
23 changes: 16 additions & 7 deletions contrib/labgrid-webapp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env python3
import argparse
import asyncio
import logging
import os
import sys
Expand Down Expand Up @@ -118,11 +119,11 @@ def main():
formatter_class=argparse.RawDescriptionHelpFormatter,
)
parser.add_argument(
'--crossbar',
'--coordinator',
'-x',
metavar='URL',
default=os.environ.get('LG_CROSSBAR', 'ws://127.0.0.1:20408/ws'),
help='Crossbar websocket URL (default: %(default)s)',
default=os.environ.get('LG_COORDINATOR', '127.0.0.1:20408'),
help='Coordinator address as HOST[:PORT] (default: %(default)s)',
)
parser.add_argument('--port', type=int, default=8800, help='Port to serve on')
parser.add_argument('--proxy', '-P', help='Proxy connections via given ssh host')
Expand All @@ -132,16 +133,20 @@ def main():
if args.proxy:
proxymanager.force_proxy(args.proxy)

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)

try:
session = start_session(
args.crossbar, os.environ.get('LG_CROSSBAR_REALM', 'realm1'), {},
args.coordinator,
loop=loop,
)
except ConnectionRefusedError:
logger.fatal('Unable to connect to labgrid crossbar')
logger.fatal('Unable to connect to labgrid coordinator')
return

server = uvicorn.Server(config=uvicorn.Config(
loop=session.loop,
loop=loop,
host='0.0.0.0',
port=args.port,
app=app,
Expand All @@ -153,7 +158,11 @@ def main():
if route.path not in reserved_routes:
logger.info(f' - {route.path}')

session.loop.run_until_complete(server.serve())
try:
loop.run_until_complete(server.serve())
finally:
loop.run_until_complete(session.stop())
loop.run_until_complete(session.close())


if __name__ == '__main__':
Expand Down
Loading
Loading