From 44c9ed9049acc0475f016a7a524888013b04619d Mon Sep 17 00:00:00 2001 From: Asher Pemberton Date: Thu, 28 May 2026 16:43:44 +0100 Subject: [PATCH 1/3] coordinator/client: add lease-based place locking Place acquisition is currently indefinite, which can lead to stale locks when users stop interacting with a place without releasing it. Add a lease-based locking mode that allows places to be acquired for a limited time and expire automatically unless extended. Leases are tied to the lifetime of a reservation. This prevents stale locks and reduces the need for manual cleanup. Signed-off-by: Asher Pemberton Reviewed-by: Asher Pemberton # gatekeeper Co-authored-by: Idan Saadon --- doc/getting_started.rst | 8 + doc/man/client.rst | 39 ++ doc/usage.rst | 60 +++ labgrid/remote/client.py | 162 +++++- labgrid/remote/common.py | 27 +- labgrid/remote/coordinator.py | 301 +++++++++-- labgrid/remote/exporter.py | 45 ++ .../generated/labgrid_coordinator_pb2.py | 285 ++++++----- .../generated/labgrid_coordinator_pb2.pyi | 66 ++- .../generated/labgrid_coordinator_pb2_grpc.py | 474 +++++++++++++++--- .../remote/proto/labgrid-coordinator.proto | 40 ++ man/labgrid-client.1 | 87 ++++ tests/conftest.py | 15 +- tests/test_client.py | 194 ++++++- 14 files changed, 1542 insertions(+), 261 deletions(-) diff --git a/doc/getting_started.rst b/doc/getting_started.rst index 842a5aa1f..717a80e74 100644 --- a/doc/getting_started.rst +++ b/doc/getting_started.rst @@ -311,6 +311,14 @@ To interact with this place, it needs to be acquired first, this is done by labgrid-venv $ labgrid-client -p example-place acquire +For short-lived access, a place can also be leased using a reservation: + +.. code-block:: bash + + labgrid-venv $ labgrid-client reserve board=example --shell + labgrid-venv $ labgrid-client wait + labgrid-venv $ labgrid-client -p + lease + Now we can connect to the serial console: .. code-block:: bash diff --git a/doc/man/client.rst b/doc/man/client.rst index 309e36365..b71f70e6d 100644 --- a/doc/man/client.rst +++ b/doc/man/client.rst @@ -88,6 +88,23 @@ a name defined within the exporter, cls is the class of the exported resource and name is its name. Wild cards in match patterns are explicitly allowed, * matches anything. +Leases +------ +A lease is a time-limited acquisition of a place. + +Leases are always associated with a reservation. The reserved place is referenced +using ``-p +``. To keep a lease active, the reservation must be extended using +the ``extend`` command. + +Use ``labgrid-client extend`` to refresh the lease once, or +``labgrid-client extend --keepalive`` to keep it alive automatically. + +If a lease extension fails, the coordinator cancels the lease and releases the +place to avoid leaving the system in an inconsistent state. + +If the reservation expires, the coordinator automatically releases the leased +place. + Adding Named Resources ---------------------- If a target contains multiple Resources of the same type, named matches need to @@ -122,6 +139,28 @@ Open a console to the acquired place: $ labgrid-client -p console +Lease a place using a reservation: + +.. code-block:: bash + + $ labgrid-client reserve board=imx8 --shell + $ labgrid-client wait + $ labgrid-client -p + lease + +Extend the lease to keep it alive: + +.. code-block:: bash + + # refresh once by passing the token explicitly + $ labgrid-client extend ABC123 + + # or take the token from the environment (LG_TOKEN) + $ export LG_TOKEN=ABC123 + $ labgrid-client extend + + # keep the lease alive automatically + $ labgrid-client extend --keepalive + Add all resources with the group "example-group" to the place example-place: .. code-block:: bash diff --git a/doc/usage.rst b/doc/usage.rst index 37527fb40..b1208fcd4 100644 --- a/doc/usage.rst +++ b/doc/usage.rst @@ -117,6 +117,7 @@ can lock that place. timeout: 2019-08-06 12:59:11.840780 $ labgrid-client -p +SP37P5OQRU console + When using reservation in a CI job or to save some typing, the ``labgrid-client reserve`` command supports a ``--shell`` command to print code for evaluating in the shell. @@ -166,6 +167,65 @@ allocated before returning. A reservation will time out after a short time, if it is neither refreshed nor used by locked places. +Leasing a place using a reservation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +After a reservation has been allocated, the reserved place can be acquired +either indefinitely or as a lease. + +First, create a reservation and export the reservation token: + +.. code-block:: bash + + $ labgrid-client reserve board=imx8 --shell + export LG_TOKEN=ABC123 + +Once the reservation is allocated, the reserved place can be referenced using +``-p +``, which expands to the place allocated to the reservation. + +.. code-block:: bash + + $ labgrid-client -p + lease + leased place board-01 + +A lease is time-limited and must be kept alive by extending the reservation. +This is done using the ``extend`` command. + +To refresh the reservation once: + +.. code-block:: bash + + $ labgrid-client extend ABC123 + +The reservation token can also be taken from the environment variable +``LG_TOKEN``: + +.. code-block:: bash + + $ export LG_TOKEN=ABC123 + $ labgrid-client extend + +To continuously keep the reservation alive, use the keepalive mode: + +.. code-block:: bash + + $ labgrid-client extend --keepalive + +In keepalive mode, the client automatically renews the lease at a suitable interval. + +If a lease extension fails (for example due to exporter issues), the lease is +cancelled and the place is released to avoid inconsistent state. + +To acquire the place indefinitely (unchanged behaviour), use ``lock`` or +``acquire`` without lease mode: + +.. code-block:: bash + + $ labgrid-client -p + lock + # or + $ labgrid-client -p + acquire + + Library ------- labgrid can be used directly as a Python library, without the infrastructure diff --git a/labgrid/remote/client.py b/labgrid/remote/client.py index 4d2eb0bfa..56dbbb779 100755 --- a/labgrid/remote/client.py +++ b/labgrid/remote/client.py @@ -382,6 +382,19 @@ async def print_resources(self): else: print(line) + async def _get_reservation_by_token(self, token): + request = labgrid_coordinator_pb2.GetReservationsRequest() + try: + response = await self.stub.GetReservations(request) + except grpc.aio.AioRpcError as e: + raise ServerError(e.details()) from e + + for res_pb in response.reservations: + res = Reservation.from_pb2(res_pb) + if res.token == token: + return res + return None + async def print_places(self): """Print out the places""" if self.args.sort_last_changed: @@ -524,8 +537,13 @@ def get_acquired_place(self, place=None): async def print_place(self): """Print out the current place and related resources""" place = self.get_place() + reservation = None + if place.reservation: + reservation = await self._get_reservation_by_token(place.reservation) + print(f"Place '{place.name}':") - place.show(level=1) + place.show(level=1, reservation=reservation) + if place.acquired: for resource_path in place.acquired_resources: (exporter, group_name, cls, resource_name) = resource_path @@ -722,6 +740,20 @@ async def acquire(self): raise errors[0] raise ErrorGroup("Multiple errors occurred during acquire", errors) + async def lease(self): + errors = [] + places = self.get_place_names_from_env() if self.env else [self.args.place] + for place in places: + try: + await self._lease_place(place) + except Error as e: + errors.append(e) + + if errors: + if len(errors) == 1: + raise errors[0] + raise ErrorGroup("Multiple errors occurred during lease", errors) + async def _acquire_place(self, place): """Acquire a place, marking it unavailable for other clients""" place = self.get_place(place) @@ -768,6 +800,55 @@ async def _acquire_place(self, place): raise ServerError(e.details()) + async def _lease_place(self, place): + """Lease a place using a reservation""" + place = self.get_place(place) + + if place.acquired: + host, user = place.acquired.split("/") + allowhelp = f"'labgrid-client -p {place.name} allow {self.gethostname()}/{self.getuser()}' on {host}." + + if self.getuser() != user: + raise UserError( + f"Place {place.name} is already acquired by {place.acquired}. " + f"To work simultaneously, {user} can execute {allowhelp}" + ) + + if self.gethostname() == host: + raise UserError(f"You have already acquired place {place.name}.") + + raise UserError( + f"You have already acquired place {place.name} on {host}. To work simultaneously, execute {allowhelp}" + ) + + if not self.args.allow_unmatched: + self.check_matches(place) + + request = labgrid_coordinator_pb2.LeasePlaceRequest(placename=place.name) + + try: + await self.stub.LeasePlace(request) + await self.sync_with_coordinator() + print(f"leased place {place.name}") + except grpc.aio.AioRpcError as e: + # check potential failure causes + for exporter, groups in sorted(self.resources.items()): + for group_name, group in sorted(groups.items()): + for resource_name, resource in sorted(group.items()): + resource_path = (exporter, group_name, resource.cls, resource_name) + if not resource.acquired: + continue + match = place.getmatch(resource_path) + if match is None: + continue + name = resource_name + if match.rename: + name = match.rename + print( + f"Matching resource '{name}' ({exporter}/{group_name}/{resource.cls}/{resource_name}) already acquired by place '{resource.acquired}'" + ) # pylint: disable=line-too-long + raise ServerError(e.details()) + async def release(self): errors = [] places = self.get_place_names_from_env() if self.env else [self.args.place] @@ -1591,16 +1672,25 @@ async def cancel_reservation(self): except grpc.aio.AioRpcError as e: raise ServerError(e.details()) - async def _wait_reservation(self, token: str, verbose=True): - while True: - request = labgrid_coordinator_pb2.PollReservationRequest(token=token) + async def _extend_lease(self, token: str) -> Reservation: + request = labgrid_coordinator_pb2.ExtendLeaseRequest(token=token) + try: + response = await self.stub.ExtendLease(request) + except grpc.aio.AioRpcError as e: + raise ServerError(e.details()) + return Reservation.from_pb2(response.reservation) - try: - response: labgrid_coordinator_pb2.PollReservationResponse = await self.stub.PollReservation(request) - except grpc.aio.AioRpcError as e: - raise ServerError(e.details()) + async def _poll_reservation(self, token: str) -> Reservation: + request = labgrid_coordinator_pb2.PollReservationRequest(token=token) + try: + response: labgrid_coordinator_pb2.PollReservationResponse = await self.stub.PollReservation(request) + except grpc.aio.AioRpcError as e: + raise ServerError(e.details()) + return Reservation.from_pb2(response.reservation) - res = Reservation.from_pb2(response.reservation) + async def _wait_reservation(self, token: str, verbose=True): + while True: + res = await self._poll_reservation(token) if verbose: res.show() if res.state is ReservationState.waiting: @@ -1612,6 +1702,37 @@ async def wait_reservation(self): token = self.args.token await self._wait_reservation(token) + async def _get_lease_config(self): + request = labgrid_coordinator_pb2.GetLeaseConfigRequest() + try: + response = await self.stub.GetLeaseConfig(request) + except grpc.aio.AioRpcError as e: + raise ServerError(e.details()) from e + return response + + async def extend_reservation(self): + token = self.args.token + + if not self.args.keepalive: + res = await self._extend_lease(token) + if not self.args.quiet: + print(f"extended lease {res.token} until {datetime.fromtimestamp(res.timeout)}") + return + + lease_config = await self._get_lease_config() + interval = max(1.0, lease_config.default_extend_duration / 2.0) + + while True: + res = await self._extend_lease(token) + if res.state is ReservationState.expired: + raise UserError("Reservation is expired; cannot extend lease") + if not self.args.quiet: + print( + f"extended lease {res.token} until {datetime.fromtimestamp(res.timeout)} " + f"(next keepalive in {interval:.1f}s)" + ) + await asyncio.sleep(interval) + async def print_reservations(self): request = labgrid_coordinator_pb2.GetReservationsRequest() @@ -1959,6 +2080,12 @@ def get_parser(auto_doc_mode=False) -> "argparse.ArgumentParser | AutoProgramArg ) subparser.set_defaults(func=ClientSession.acquire) + subparser = subparsers.add_parser("lease", help="lease a place (time-limited, requires extension)") + subparser.add_argument( + "--allow-unmatched", action="store_true", help="allow missing resources for matches when locking the place" + ) + subparser.set_defaults(func=ClientSession.lease) + subparser = subparsers.add_parser("release", aliases=("unlock",), help="release a place") subparser.add_argument( "-k", "--kick", action="store_true", help="release a place even if it is acquired by a different user" @@ -2217,6 +2344,21 @@ def get_parser(auto_doc_mode=False) -> "argparse.ArgumentParser | AutoProgramArg subparser.add_argument("token", type=str, nargs="?") subparser.set_defaults(func=ClientSession.wait_reservation) + subparser = subparsers.add_parser("extend", help="extend a lease by the coordinator default duration") + subparser.add_argument("token", type=str, nargs="?") + subparser.add_argument( + "--keepalive", + action="store_true", + help="keep extending the lease automatically using coordinator policy", + ) + subparser.add_argument( + "-q", + "--quiet", + action="store_true", + help="do not print lease status on each extension", + ) + subparser.set_defaults(func=ClientSession.extend_reservation) + subparser = subparsers.add_parser("reservations", help="list current reservations") subparser.set_defaults(func=ClientSession.print_reservations) @@ -2281,7 +2423,7 @@ def main(): if args.initial_state is None: args.initial_state = initial_state - if args.command in ["cancel-reservation", "wait"] and args.token is None: + if args.command in ["cancel-reservation", "wait", "extend"] and args.token is None: if token: args.token = token else: diff --git a/labgrid/remote/common.py b/labgrid/remote/common.py index 14c8a2d74..87b310c13 100644 --- a/labgrid/remote/common.py +++ b/labgrid/remote/common.py @@ -5,9 +5,9 @@ import re import string import logging -from datetime import datetime +from datetime import datetime, timezone from fnmatch import fnmatchcase - +from google.protobuf import timestamp_pb2 # pylint: disable=no-name-in-module import attr from .generated import labgrid_coordinator_pb2 @@ -58,6 +58,16 @@ def build_dict_from_map(m): return d +def timestamp_from_float(value: float): + ts = timestamp_pb2.Timestamp() # pylint: disable=no-member + ts.FromDatetime(datetime.fromtimestamp(value, tz=timezone.utc)) + return ts + + +def float_from_timestamp(ts) -> float: + return ts.ToDatetime(tzinfo=timezone.utc).timestamp() + + @attr.s(eq=False) class ResourceEntry: data = attr.ib() # cls, params @@ -268,7 +278,7 @@ def update_from_pb2(self, place_pb2): continue setattr(self, k, v) - def show(self, level=0): + def show(self, level=0, reservation=None): indent = " " * level if self.aliases: print(indent + f"aliases: {', '.join(sorted(self.aliases))}") @@ -299,6 +309,11 @@ def show(self, level=0): if self.reservation: print(indent + f"reservation: {self.reservation}") + if reservation is not None: + print(indent + f"lease timeout: {datetime.fromtimestamp(reservation.timeout)}") + if reservation.state is ReservationState.leased: + print(indent + f"lease started: {datetime.fromtimestamp(reservation.lease_start_time)}") + def getmatch(self, resource_path): """Return the ResourceMatch object for the given resource path or None if not found. @@ -386,6 +401,7 @@ class ReservationState(enum.Enum): acquired = 2 expired = 3 invalid = 4 + leased = 5 @attr.s(eq=False) @@ -406,6 +422,7 @@ class Reservation: allocations = attr.ib(default=attr.Factory(dict), validator=attr.validators.instance_of(dict)) created = attr.ib(default=attr.Factory(time.time)) timeout = attr.ib(default=attr.Factory(lambda: time.time() + 60)) + lease_start_time = attr.ib(default=0.0, validator=attr.validators.instance_of(float)) def asdict(self): return { @@ -416,6 +433,7 @@ def asdict(self): "allocations": self.allocations, "created": self.created, "timeout": self.timeout, + "lease_start_time": self.lease_start_time, } def refresh(self, delta=60): @@ -459,6 +477,8 @@ def as_pb2(self): res.allocations.update({"main": allocation[0]}) res.created = self.created res.timeout = self.timeout + if self.lease_start_time > 0: + res.lease_start_time.CopyFrom(timestamp_from_float(self.lease_start_time)) return res @classmethod @@ -478,6 +498,7 @@ def from_pb2(cls, pb2: labgrid_coordinator_pb2.Reservation): allocations=allocations, created=pb2.created, timeout=pb2.timeout, + lease_start_time=float_from_timestamp(pb2.lease_start_time) if pb2.HasField("lease_start_time") else 0.0, ) diff --git a/labgrid/remote/coordinator.py b/labgrid/remote/coordinator.py index ea60f4933..6f098f5d9 100644 --- a/labgrid/remote/coordinator.py +++ b/labgrid/remote/coordinator.py @@ -10,7 +10,7 @@ import copy import random import signal - +import os import attr import grpc from grpc_reflection.v1alpha import reflection @@ -183,7 +183,8 @@ async def wrapper(self, *args, **kwargs): class ExporterCommand: - def __init__(self, request) -> None: + def __init__(self, kind, request) -> None: + self.kind = kind self.request = request self.response = None self.completed = asyncio.Event() @@ -219,6 +220,29 @@ def __init__(self) -> None: self.lock = asyncio.Lock() self.exporters: dict[str, ExporterSession] = {} self.clients: dict[str, ClientSession] = {} + self.default_lease_duration = int( + os.environ.get("LG_DEFAULT_LEASE_DURATION", 15 * 60) + ) # lease starts with 15 minutes + self.default_extend_duration = int( + os.environ.get("LG_DEFAULT_EXTEND_DURATION", 5 * 60) + ) # every extend adds 5 minutes + self.max_lease_duration = int( + os.environ.get("LG_MAX_LEASE_DURATION", 2 * 60 * 60) + ) # total from lease start can never exceed 2 hours + self.poll_interval = float(os.environ.get("LG_COORDINATOR_POLL_INTERVAL", 15.0)) + + if self.default_lease_duration <= 0: + raise ValueError("LG_DEFAULT_LEASE_DURATION must be > 0") + if self.default_extend_duration <= 0: + raise ValueError("LG_DEFAULT_EXTEND_DURATION must be > 0") + if self.max_lease_duration <= 0: + raise ValueError("LG_MAX_LEASE_DURATION must be > 0") + if self.default_lease_duration > self.max_lease_duration: + raise ValueError("LG_DEFAULT_LEASE_DURATION must be <= LG_MAX_LEASE_DURATION") + if self.default_extend_duration > self.max_lease_duration: + raise ValueError("LG_DEFAULT_EXTEND_DURATION must be <= LG_MAX_LEASE_DURATION") + if self.poll_interval <= 0: + raise ValueError("LG_COORDINATOR_POLL_INTERVAL must be > 0") self.load() self.loop = asyncio.get_running_loop() @@ -243,12 +267,12 @@ async def _poll_step_schedule(self): # update reservations async with self.lock: with warn_if_slow("schedule reservations"): - self.schedule_reservations() + await self.schedule_reservations() async def poll(self, step_func): while not self.loop.is_closed(): try: - await asyncio.sleep(15.0) + await asyncio.sleep(self.poll_interval) await step_func() except asyncio.CancelledError: break @@ -478,7 +502,12 @@ async def request_task(): async for cmd in queue_as_aiter(command_queue): logging.debug("exporter cmd %s", cmd) out_msg = labgrid_coordinator_pb2.ExporterOutMessage() - out_msg.set_acquired_request.CopyFrom(cmd.request) + if cmd.kind == "set_acquired_request": + out_msg.set_acquired_request.CopyFrom(cmd.request) + elif cmd.kind == "lease_extended_request": + out_msg.lease_extended_request.CopyFrom(cmd.request) + else: + raise ValueError(f"unknown exporter command kind {cmd.kind}") pending_commands.append(cmd) yield out_msg except asyncio.exceptions.CancelledError: @@ -649,7 +678,7 @@ async def _acquire_resource(self, place, resource): request.group_name = resource.path[1] request.resource_name = resource.path[3] request.place_name = place.name - cmd = ExporterCommand(request) + cmd = ExporterCommand("set_acquired_request", request) self.get_exporter_by_name(resource.path[0]).queue.put_nowait(cmd) await cmd.wait() if not cmd.response.success: @@ -691,6 +720,31 @@ async def _acquire_resources(self, place, resources): return True + async def _notify_lease_extended_resource(self, place, resource, duration): + assert self.lock.locked() + + request = labgrid_coordinator_pb2.ExporterLeaseExtendedRequest() + request.group_name = resource.path[1] + request.resource_name = resource.path[3] + if place is not None: + request.place_name = place.name + request.duration = duration + + cmd = ExporterCommand("lease_extended_request", request) + self.get_exporter_by_name(resource.path[0]).queue.put_nowait(cmd) + await cmd.wait() + + if not cmd.response.success: + raise ExporterError(f"failed to notify lease extension for {resource} ({cmd.response.reason})") + + async def _notify_lease_extended(self, place, duration): + assert self.lock.locked() + + for resource in place.acquired_resources: + if getattr(resource, "orphaned", False): + continue + await self._notify_lease_extended_resource(place, resource, duration) + async def _release_resources(self, place, resources, callback=True): assert self.lock.locked() @@ -713,7 +767,7 @@ async def _release_resources(self, place, resources, callback=True): request.group_name = resource.path[1] request.resource_name = resource.path[3] # request.place_name is left unset to indicate release - cmd = ExporterCommand(request) + cmd = ExporterCommand("set_acquired_request", request) self.get_exporter_by_name(resource.path[0]).queue.put_nowait(cmd) await cmd.wait() if not cmd.response.success: @@ -847,6 +901,22 @@ async def _synchronize_resources(self): idx = place.acquired_resources.index(oldresource) place.acquired_resources[idx] = newresource + async def _acquire_place_resources(self, place, owner): + assert self.lock.locked() + + place.acquired = owner + resources = [] + for _, session in sorted(self.exporters.items()): + for _, group in sorted(session.groups.items()): + for _, resource in sorted(group.items()): + if place.hasmatch(resource.path): + resources.append(resource) + + if not await self._acquire_resources(place, resources): + place.acquired = None + return False + return True + @locked async def AcquirePlace(self, request, context): peer = context.peer() @@ -870,25 +940,58 @@ async def AcquirePlace(self, request, context): # FIXME use the session object instead? or something else which # survives disconnecting clients? - place.acquired = username - resources = [] - for _, session in sorted(self.exporters.items()): - for _, group in sorted(session.groups.items()): - for _, resource in sorted(group.items()): - if not place.hasmatch(resource.path): - continue - resources.append(resource) - if not await self._acquire_resources(place, resources): - # revert earlier change - place.acquired = None + if not await self._acquire_place_resources(place, username): await context.abort(grpc.StatusCode.FAILED_PRECONDITION, f"Failed to acquire resources for place {name}") + if place.reservation: + res = self.reservations[place.reservation] + res.state = ReservationState.acquired + res.refresh() place.touch() self._publish_place(place) self.save_later() - self.schedule_reservations() + await self.schedule_reservations() print(f"{place.name}: place acquired by {place.acquired}") return labgrid_coordinator_pb2.AcquirePlaceResponse() + @locked + async def LeasePlace(self, request, context): + peer = context.peer() + username = self.clients[peer].name + name = request.placename + + place = self.places.get(name) + if place is None: + await context.abort(grpc.StatusCode.INVALID_ARGUMENT, f"Place {name} does not exist") + if place.acquired: + await context.abort(grpc.StatusCode.FAILED_PRECONDITION, f"Place {name} is already acquired") + if not place.reservation: + await context.abort( + grpc.StatusCode.FAILED_PRECONDITION, + f"Place {name} is not reserved; leasing requires a reservation", + ) + + res = self.reservations[place.reservation] + if res.owner != username: + await context.abort( + grpc.StatusCode.PERMISSION_DENIED, + f"Place {name} is reserved by a different user", + ) + + if not await self._acquire_place_resources(place, username): + await context.abort(grpc.StatusCode.FAILED_PRECONDITION, f"Failed to lease resources for place {name}") + + now = time.time() + res.state = ReservationState.leased + res.lease_start_time = now + res.timeout = now + self.default_lease_duration + + place.touch() + self._publish_place(place) + self.save_later() + await self.schedule_reservations() + print(f"{place.name}: place leased by {place.acquired}") + return labgrid_coordinator_pb2.LeasePlaceResponse() + @locked async def ReleasePlace(self, request, context): name = request.placename @@ -905,16 +1008,31 @@ async def ReleasePlace(self, request, context): if fromuser and place.acquired != fromuser: return labgrid_coordinator_pb2.ReleasePlaceResponse() + await self._release_place(place) + await self.schedule_reservations() + return labgrid_coordinator_pb2.ReleasePlaceResponse() + + async def _release_place(self, place): + assert self.lock.locked() await self._release_resources(place, place.acquired_resources) + if place.reservation and place.reservation in self.reservations: + reservation = self.reservations[place.reservation] + if reservation.state is ReservationState.leased: + reservation.state = ReservationState.expired + reservation.allocations.clear() + reservation.refresh() + place.reservation = None + elif reservation.state is ReservationState.acquired: + reservation.state = ReservationState.allocated + reservation.refresh() + place.acquired = None place.allowed = set() place.touch() self._publish_place(place) self.save_later() - self.schedule_reservations() print(f"{place.name}: place released") - return labgrid_coordinator_pb2.ReleasePlaceResponse() @locked async def AllowPlace(self, request, context): @@ -952,7 +1070,7 @@ async def GetPlaces(self, unused_request, unused_context): except Exception: logging.exception("error during get places") - def schedule_reservations(self): + async def schedule_reservations(self): # The primary information is stored in the reservations and the places # only have a copy for convenience. @@ -962,9 +1080,24 @@ def schedule_reservations(self): if res.state is ReservationState.acquired: # acquired reservations do not expire res.refresh() + if not res.expired: continue - if res.state is not ReservationState.expired: + if res.state is ReservationState.leased: + released = False + for place in list(self.places.values()): + if place.reservation == res.token and place.acquired == res.owner: + await self._release_place(place) + print(f"marked leased reservation expired ({res.owner}/{res.token})") + released = True + break + if not released: + res.state = ReservationState.expired + res.allocations.clear() + res.refresh() + print(f"marked leased reservation expired ({res.owner}/{res.token})") + continue + elif res.state is not ReservationState.expired: res.state = ReservationState.expired res.allocations.clear() res.refresh() @@ -986,15 +1119,23 @@ def schedule_reservations(self): res.allocations.clear() res.refresh(300) print(f"reservation ({res.owner}/{res.token}) is now {res.state.name}") + elif res.state is ReservationState.leased and place.acquired != res.owner: + res.state = ReservationState.expired + res.allocations.clear() + res.refresh(300) + logging.info("marked leased reservation expired (%s/%s)", res.owner, res.token) + break if place.acquired is not None: acquired_places.add(name) assert name not in allocated_places, "conflicting allocation" allocated_places.add(name) - if acquired_places and res.state is ReservationState.allocated: - # an allocated place was acquired - res.state = ReservationState.acquired - res.refresh() - print(f"reservation ({res.owner}/{res.token}) is now {res.state.name}") + else: + continue # inner loop didn't break + break # inner loop broke -> break group loop + # if the reservation was deleted, skip the rest + if res.token not in self.reservations: + continue + if not acquired_places and res.state is ReservationState.acquired: # all allocated places were released res.state = ReservationState.allocated @@ -1079,7 +1220,7 @@ async def CreateReservation(self, request: labgrid_coordinator_pb2.CreateReserva owner = self.clients[peer].name res = Reservation(owner=owner, prio=request.prio, filters=fltrs) self.reservations[res.token] = res - self.schedule_reservations() + await self.schedule_reservations() return labgrid_coordinator_pb2.CreateReservationResponse(reservation=res.as_pb2()) @locked @@ -1089,8 +1230,17 @@ async def CancelReservation(self, request: labgrid_coordinator_pb2.CancelReserva await context.abort(grpc.StatusCode.INVALID_ARGUMENT, f"Invalid token {token}") if token not in self.reservations: await context.abort(grpc.StatusCode.FAILED_PRECONDITION, f"Reservation {token} does not exist") + + reservation = self.reservations[token] + owner = reservation.owner + + # release any places currently leased under this token + for place in list(self.places.values()): + if place.reservation == token and place.acquired == owner: + await self._release_place(place) + del self.reservations[token] - self.schedule_reservations() + await self.schedule_reservations() return labgrid_coordinator_pb2.CancelReservationResponse() @locked @@ -1100,7 +1250,10 @@ async def PollReservation(self, request: labgrid_coordinator_pb2.PollReservation res = self.reservations[token] except KeyError: await context.abort(grpc.StatusCode.FAILED_PRECONDITION, f"Reservation {token} does not exist") - res.refresh() + + if res.state in (ReservationState.waiting, ReservationState.allocated): + res.refresh() + return labgrid_coordinator_pb2.PollReservationResponse(reservation=res.as_pb2()) @locked @@ -1108,6 +1261,92 @@ async def GetReservations(self, request: labgrid_coordinator_pb2.GetReservations reservations = [x.as_pb2() for x in self.reservations.values()] return labgrid_coordinator_pb2.GetReservationsResponse(reservations=reservations) + async def GetLeaseConfig(self, request, context): + return labgrid_coordinator_pb2.GetLeaseConfigResponse( + default_lease_duration=self.default_lease_duration, + default_extend_duration=self.default_extend_duration, + max_lease_duration=self.max_lease_duration, + ) + + @locked + async def ExtendLease(self, request, context): + token = request.token + + if not isinstance(token, str) or not token: + await context.abort(grpc.StatusCode.INVALID_ARGUMENT, f"Invalid token {token}") + + if token not in self.reservations: + await context.abort( + grpc.StatusCode.FAILED_PRECONDITION, + f"Reservation {token} does not exist", + ) + + peer = context.peer() + try: + username = self.clients[peer].name + except KeyError: + await context.abort(grpc.StatusCode.FAILED_PRECONDITION, f"Peer {peer} does not have a valid session") + + reservation = self.reservations[token] + + if reservation.owner != username: + await context.abort( + grpc.StatusCode.PERMISSION_DENIED, + f"Reservation {token} is owned by a different user", + ) + + if reservation.state is not ReservationState.leased: + await context.abort( + grpc.StatusCode.FAILED_PRECONDITION, + f"Reservation {token} is not in leased state", + ) + + if reservation.lease_start_time <= 0: + await context.abort( + grpc.StatusCode.FAILED_PRECONDITION, + f"Reservation {token} has invalid lease start time", + ) + + extend_duration = self.default_extend_duration + requested_timeout = reservation.timeout + extend_duration + max_timeout = reservation.lease_start_time + self.max_lease_duration + remaining = max_timeout - reservation.timeout + + if requested_timeout > max_timeout: + await context.abort( + grpc.StatusCode.FAILED_PRECONDITION, + f"Lease cannot be extended by {extend_duration} seconds; only {max(0, int(remaining))} seconds remain before reaching the maximum total lease duration of {self.max_lease_duration} seconds", + ) + + leased_place = None + for place in self.places.values(): + if place.reservation == token and place.acquired == reservation.owner: + leased_place = place + break + + if leased_place is None: + await context.abort( + grpc.StatusCode.FAILED_PRECONDITION, + f"Reservation {token} is leased but no acquired place was found", + ) + + try: + await self._notify_lease_extended(leased_place, extend_duration) + except ExporterError as e: + try: + await self._release_place(leased_place) + await self.schedule_reservations() + except Exception: + logging.exception("failed to clean up lease after extension failure") + await context.abort( + grpc.StatusCode.FAILED_PRECONDITION, + f"Lease extension failed and the lease was cancelled: {e}", + ) + reservation.timeout = requested_timeout + self.save_later() + + return labgrid_coordinator_pb2.ExtendLeaseResponse(reservation=reservation.as_pb2()) + async def serve(listen, cleanup) -> None: asyncio.current_task().set_name("coordinator-serve") diff --git a/labgrid/remote/exporter.py b/labgrid/remote/exporter.py index 68c4fa708..b47d52469 100755 --- a/labgrid/remote/exporter.py +++ b/labgrid/remote/exporter.py @@ -936,6 +936,31 @@ async def message_pump(self): logging.debug("queuing %s", in_message) self.out_queue.put_nowait(in_message) logging.debug("queued %s", in_message) + elif kind == "lease_extended_request": + logging.debug("lease extended request") + success = False + reason = None + try: + await self.lease_extended( + out_message.lease_extended_request.group_name, + out_message.lease_extended_request.resource_name, + out_message.lease_extended_request.place_name + if out_message.lease_extended_request.HasField("place_name") + else None, + out_message.lease_extended_request.duration, + ) + success = True + except (BrokenResourceError, InvalidResourceRequestError, UnknownResourceError) as e: + reason = e.args[0] + logging.warning("lease_extended_request failed: %s", reason) + finally: + in_message = labgrid_coordinator_pb2.ExporterInMessage() + in_message.response.success = success + if reason: + in_message.response.reason = reason + logging.debug("queuing %s", in_message) + self.out_queue.put_nowait(in_message) + logging.debug("queued %s", in_message) else: logging.debug("unknown request: %s", kind) except grpc.aio.AioRpcError as e: @@ -988,6 +1013,26 @@ async def release(self, group_name, resource_name): finally: await self.update_resource(group_name, resource_name) + async def lease_extended(self, group_name, resource_name, place_name, duration): + resource = self.groups.get(group_name, {}).get(resource_name) + if resource is None: + raise UnknownResourceError(f"lease extension request for unknown resource {group_name}/{resource_name}") + + if not resource.acquired: + raise InvalidResourceRequestError(f"Resource {group_name}/{resource_name} is not acquired") + + if place_name is not None and resource.acquired != place_name: + raise InvalidResourceRequestError( + f"Resource {group_name}/{resource_name} is acquired by {resource.acquired}, not {place_name}" + ) + + logging.info( + "received lease extension for %s/%s by %s seconds", + group_name, + resource_name, + duration, + ) + async def _poll_step(self): for group_name, group in self.groups.items(): for resource_name, resource in group.items(): diff --git a/labgrid/remote/generated/labgrid_coordinator_pb2.py b/labgrid/remote/generated/labgrid_coordinator_pb2.py index 37652bff7..8b73871df 100644 --- a/labgrid/remote/generated/labgrid_coordinator_pb2.py +++ b/labgrid/remote/generated/labgrid_coordinator_pb2.py @@ -1,158 +1,183 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE # source: labgrid-coordinator.proto -# Protobuf Python Version: 4.25.1 +# Protobuf Python Version: 6.31.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 31, + 1, + '', + 'labgrid-coordinator.proto' +) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() +from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19labgrid-coordinator.proto\x12\x07labgrid\"\x8a\x01\n\x0f\x43lientInMessage\x12\x1d\n\x04sync\x18\x01 \x01(\x0b\x32\r.labgrid.SyncH\x00\x12\'\n\x07startup\x18\x02 \x01(\x0b\x32\x14.labgrid.StartupDoneH\x00\x12\'\n\tsubscribe\x18\x03 \x01(\x0b\x32\x12.labgrid.SubscribeH\x00\x42\x06\n\x04kind\"\x12\n\x04Sync\x12\n\n\x02id\x18\x01 \x01(\x04\",\n\x0bStartupDone\x12\x0f\n\x07version\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"r\n\tSubscribe\x12\x1b\n\x0eis_unsubscribe\x18\x01 \x01(\x08H\x01\x88\x01\x01\x12\x14\n\nall_places\x18\x02 \x01(\x08H\x00\x12\x17\n\rall_resources\x18\x03 \x01(\x08H\x00\x42\x06\n\x04kindB\x11\n\x0f_is_unsubscribe\"g\n\x10\x43lientOutMessage\x12 \n\x04sync\x18\x01 \x01(\x0b\x32\r.labgrid.SyncH\x00\x88\x01\x01\x12(\n\x07updates\x18\x02 \x03(\x0b\x32\x17.labgrid.UpdateResponseB\x07\n\x05_sync\"\xa5\x01\n\x0eUpdateResponse\x12%\n\x08resource\x18\x01 \x01(\x0b\x32\x11.labgrid.ResourceH\x00\x12.\n\x0c\x64\x65l_resource\x18\x02 \x01(\x0b\x32\x16.labgrid.Resource.PathH\x00\x12\x1f\n\x05place\x18\x03 \x01(\x0b\x32\x0e.labgrid.PlaceH\x00\x12\x13\n\tdel_place\x18\x04 \x01(\tH\x00\x42\x06\n\x04kind\"\x9a\x01\n\x11\x45xporterInMessage\x12%\n\x08resource\x18\x01 \x01(\x0b\x32\x11.labgrid.ResourceH\x00\x12\'\n\x07startup\x18\x02 \x01(\x0b\x32\x14.labgrid.StartupDoneH\x00\x12-\n\x08response\x18\x03 \x01(\x0b\x32\x19.labgrid.ExporterResponseH\x00\x42\x06\n\x04kind\"\x9e\x03\n\x08Resource\x12$\n\x04path\x18\x01 \x01(\x0b\x32\x16.labgrid.Resource.Path\x12\x0b\n\x03\x63ls\x18\x02 \x01(\t\x12-\n\x06params\x18\x03 \x03(\x0b\x32\x1d.labgrid.Resource.ParamsEntry\x12+\n\x05\x65xtra\x18\x04 \x03(\x0b\x32\x1c.labgrid.Resource.ExtraEntry\x12\x10\n\x08\x61\x63quired\x18\x05 \x01(\t\x12\r\n\x05\x61vail\x18\x06 \x01(\x08\x1a_\n\x04Path\x12\x1a\n\rexporter_name\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x12\n\ngroup_name\x18\x02 \x01(\t\x12\x15\n\rresource_name\x18\x03 \x01(\tB\x10\n\x0e_exporter_name\x1a@\n\x0bParamsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12 \n\x05value\x18\x02 \x01(\x0b\x32\x11.labgrid.MapValue:\x02\x38\x01\x1a?\n\nExtraEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12 \n\x05value\x18\x02 \x01(\x0b\x32\x11.labgrid.MapValue:\x02\x38\x01\"\x82\x01\n\x08MapValue\x12\x14\n\nbool_value\x18\x01 \x01(\x08H\x00\x12\x13\n\tint_value\x18\x02 \x01(\x03H\x00\x12\x14\n\nuint_value\x18\x03 \x01(\x04H\x00\x12\x15\n\x0b\x66loat_value\x18\x04 \x01(\x01H\x00\x12\x16\n\x0cstring_value\x18\x05 \x01(\tH\x00\x42\x06\n\x04kind\"C\n\x10\x45xporterResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x13\n\x06reason\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_reason\"\x18\n\x05Hello\x12\x0f\n\x07version\x18\x01 \x01(\t\"\x82\x01\n\x12\x45xporterOutMessage\x12\x1f\n\x05hello\x18\x01 \x01(\x0b\x32\x0e.labgrid.HelloH\x00\x12\x43\n\x14set_acquired_request\x18\x02 \x01(\x0b\x32#.labgrid.ExporterSetAcquiredRequestH\x00\x42\x06\n\x04kind\"o\n\x1a\x45xporterSetAcquiredRequest\x12\x12\n\ngroup_name\x18\x01 \x01(\t\x12\x15\n\rresource_name\x18\x02 \x01(\t\x12\x17\n\nplace_name\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\r\n\x0b_place_name\"\x1f\n\x0f\x41\x64\x64PlaceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x12\n\x10\x41\x64\x64PlaceResponse\"\"\n\x12\x44\x65letePlaceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x15\n\x13\x44\x65letePlaceResponse\"\x12\n\x10GetPlacesRequest\"3\n\x11GetPlacesResponse\x12\x1e\n\x06places\x18\x01 \x03(\x0b\x32\x0e.labgrid.Place\"\xd2\x02\n\x05Place\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07\x61liases\x18\x02 \x03(\t\x12\x0f\n\x07\x63omment\x18\x03 \x01(\t\x12&\n\x04tags\x18\x04 \x03(\x0b\x32\x18.labgrid.Place.TagsEntry\x12\'\n\x07matches\x18\x05 \x03(\x0b\x32\x16.labgrid.ResourceMatch\x12\x15\n\x08\x61\x63quired\x18\x06 \x01(\tH\x00\x88\x01\x01\x12\x1a\n\x12\x61\x63quired_resources\x18\x07 \x03(\t\x12\x0f\n\x07\x61llowed\x18\x08 \x03(\t\x12\x0f\n\x07\x63reated\x18\t \x01(\x01\x12\x0f\n\x07\x63hanged\x18\n \x01(\x01\x12\x18\n\x0breservation\x18\x0b \x01(\tH\x01\x88\x01\x01\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x0b\n\t_acquiredB\x0e\n\x0c_reservation\"y\n\rResourceMatch\x12\x10\n\x08\x65xporter\x18\x01 \x01(\t\x12\r\n\x05group\x18\x02 \x01(\t\x12\x0b\n\x03\x63ls\x18\x03 \x01(\t\x12\x11\n\x04name\x18\x04 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06rename\x18\x05 \x01(\tH\x01\x88\x01\x01\x42\x07\n\x05_nameB\t\n\x07_rename\"8\n\x14\x41\x64\x64PlaceAliasRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\r\n\x05\x61lias\x18\x02 \x01(\t\"\x17\n\x15\x41\x64\x64PlaceAliasResponse\";\n\x17\x44\x65letePlaceAliasRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\r\n\x05\x61lias\x18\x02 \x01(\t\"\x1a\n\x18\x44\x65letePlaceAliasResponse\"\x8b\x01\n\x13SetPlaceTagsRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\x34\n\x04tags\x18\x02 \x03(\x0b\x32&.labgrid.SetPlaceTagsRequest.TagsEntry\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x16\n\x14SetPlaceTagsResponse\"<\n\x16SetPlaceCommentRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\x0f\n\x07\x63omment\x18\x02 \x01(\t\"\x19\n\x17SetPlaceCommentResponse\"Z\n\x14\x41\x64\x64PlaceMatchRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\x0f\n\x07pattern\x18\x02 \x01(\t\x12\x13\n\x06rename\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_rename\"\x17\n\x15\x41\x64\x64PlaceMatchResponse\"]\n\x17\x44\x65letePlaceMatchRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\x0f\n\x07pattern\x18\x02 \x01(\t\x12\x13\n\x06rename\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_rename\"\x1a\n\x18\x44\x65letePlaceMatchResponse\"(\n\x13\x41\x63quirePlaceRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\"\x16\n\x14\x41\x63quirePlaceResponse\"L\n\x13ReleasePlaceRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\x15\n\x08\x66romuser\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0b\n\t_fromuser\"\x16\n\x14ReleasePlaceResponse\"4\n\x11\x41llowPlaceRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\x0c\n\x04user\x18\x02 \x01(\t\"\x14\n\x12\x41llowPlaceResponse\"\xb6\x01\n\x18\x43reateReservationRequest\x12?\n\x07\x66ilters\x18\x01 \x03(\x0b\x32..labgrid.CreateReservationRequest.FiltersEntry\x12\x0c\n\x04prio\x18\x02 \x01(\x01\x1aK\n\x0c\x46iltersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12*\n\x05value\x18\x02 \x01(\x0b\x32\x1b.labgrid.Reservation.Filter:\x02\x38\x01\"F\n\x19\x43reateReservationResponse\x12)\n\x0breservation\x18\x01 \x01(\x0b\x32\x14.labgrid.Reservation\"\xcd\x03\n\x0bReservation\x12\r\n\x05owner\x18\x01 \x01(\t\x12\r\n\x05token\x18\x02 \x01(\t\x12\r\n\x05state\x18\x03 \x01(\x05\x12\x0c\n\x04prio\x18\x04 \x01(\x01\x12\x32\n\x07\x66ilters\x18\x05 \x03(\x0b\x32!.labgrid.Reservation.FiltersEntry\x12:\n\x0b\x61llocations\x18\x06 \x03(\x0b\x32%.labgrid.Reservation.AllocationsEntry\x12\x0f\n\x07\x63reated\x18\x07 \x01(\x01\x12\x0f\n\x07timeout\x18\x08 \x01(\x01\x1ap\n\x06\x46ilter\x12\x37\n\x06\x66ilter\x18\x01 \x03(\x0b\x32\'.labgrid.Reservation.Filter.FilterEntry\x1a-\n\x0b\x46ilterEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1aK\n\x0c\x46iltersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12*\n\x05value\x18\x02 \x01(\x0b\x32\x1b.labgrid.Reservation.Filter:\x02\x38\x01\x1a\x32\n\x10\x41llocationsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\")\n\x18\x43\x61ncelReservationRequest\x12\r\n\x05token\x18\x01 \x01(\t\"\x1b\n\x19\x43\x61ncelReservationResponse\"\'\n\x16PollReservationRequest\x12\r\n\x05token\x18\x01 \x01(\t\"D\n\x17PollReservationResponse\x12)\n\x0breservation\x18\x01 \x01(\x0b\x32\x14.labgrid.Reservation\"E\n\x17GetReservationsResponse\x12*\n\x0creservations\x18\x01 \x03(\x0b\x32\x14.labgrid.Reservation\"\x18\n\x16GetReservationsRequest2\xd2\x0b\n\x0b\x43oordinator\x12I\n\x0c\x43lientStream\x12\x18.labgrid.ClientInMessage\x1a\x19.labgrid.ClientOutMessage\"\x00(\x01\x30\x01\x12O\n\x0e\x45xporterStream\x12\x1a.labgrid.ExporterInMessage\x1a\x1b.labgrid.ExporterOutMessage\"\x00(\x01\x30\x01\x12\x41\n\x08\x41\x64\x64Place\x12\x18.labgrid.AddPlaceRequest\x1a\x19.labgrid.AddPlaceResponse\"\x00\x12J\n\x0b\x44\x65letePlace\x12\x1b.labgrid.DeletePlaceRequest\x1a\x1c.labgrid.DeletePlaceResponse\"\x00\x12\x44\n\tGetPlaces\x12\x19.labgrid.GetPlacesRequest\x1a\x1a.labgrid.GetPlacesResponse\"\x00\x12P\n\rAddPlaceAlias\x12\x1d.labgrid.AddPlaceAliasRequest\x1a\x1e.labgrid.AddPlaceAliasResponse\"\x00\x12Y\n\x10\x44\x65letePlaceAlias\x12 .labgrid.DeletePlaceAliasRequest\x1a!.labgrid.DeletePlaceAliasResponse\"\x00\x12M\n\x0cSetPlaceTags\x12\x1c.labgrid.SetPlaceTagsRequest\x1a\x1d.labgrid.SetPlaceTagsResponse\"\x00\x12V\n\x0fSetPlaceComment\x12\x1f.labgrid.SetPlaceCommentRequest\x1a .labgrid.SetPlaceCommentResponse\"\x00\x12P\n\rAddPlaceMatch\x12\x1d.labgrid.AddPlaceMatchRequest\x1a\x1e.labgrid.AddPlaceMatchResponse\"\x00\x12Y\n\x10\x44\x65letePlaceMatch\x12 .labgrid.DeletePlaceMatchRequest\x1a!.labgrid.DeletePlaceMatchResponse\"\x00\x12M\n\x0c\x41\x63quirePlace\x12\x1c.labgrid.AcquirePlaceRequest\x1a\x1d.labgrid.AcquirePlaceResponse\"\x00\x12M\n\x0cReleasePlace\x12\x1c.labgrid.ReleasePlaceRequest\x1a\x1d.labgrid.ReleasePlaceResponse\"\x00\x12G\n\nAllowPlace\x12\x1a.labgrid.AllowPlaceRequest\x1a\x1b.labgrid.AllowPlaceResponse\"\x00\x12\\\n\x11\x43reateReservation\x12!.labgrid.CreateReservationRequest\x1a\".labgrid.CreateReservationResponse\"\x00\x12\\\n\x11\x43\x61ncelReservation\x12!.labgrid.CancelReservationRequest\x1a\".labgrid.CancelReservationResponse\"\x00\x12V\n\x0fPollReservation\x12\x1f.labgrid.PollReservationRequest\x1a .labgrid.PollReservationResponse\"\x00\x12V\n\x0fGetReservations\x12\x1f.labgrid.GetReservationsRequest\x1a .labgrid.GetReservationsResponse\"\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19labgrid-coordinator.proto\x12\x07labgrid\x1a\x1fgoogle/protobuf/timestamp.proto\"\x8a\x01\n\x0f\x43lientInMessage\x12\x1d\n\x04sync\x18\x01 \x01(\x0b\x32\r.labgrid.SyncH\x00\x12\'\n\x07startup\x18\x02 \x01(\x0b\x32\x14.labgrid.StartupDoneH\x00\x12\'\n\tsubscribe\x18\x03 \x01(\x0b\x32\x12.labgrid.SubscribeH\x00\x42\x06\n\x04kind\"\x12\n\x04Sync\x12\n\n\x02id\x18\x01 \x01(\x04\",\n\x0bStartupDone\x12\x0f\n\x07version\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"r\n\tSubscribe\x12\x1b\n\x0eis_unsubscribe\x18\x01 \x01(\x08H\x01\x88\x01\x01\x12\x14\n\nall_places\x18\x02 \x01(\x08H\x00\x12\x17\n\rall_resources\x18\x03 \x01(\x08H\x00\x42\x06\n\x04kindB\x11\n\x0f_is_unsubscribe\"g\n\x10\x43lientOutMessage\x12 \n\x04sync\x18\x01 \x01(\x0b\x32\r.labgrid.SyncH\x00\x88\x01\x01\x12(\n\x07updates\x18\x02 \x03(\x0b\x32\x17.labgrid.UpdateResponseB\x07\n\x05_sync\"\xa5\x01\n\x0eUpdateResponse\x12%\n\x08resource\x18\x01 \x01(\x0b\x32\x11.labgrid.ResourceH\x00\x12.\n\x0c\x64\x65l_resource\x18\x02 \x01(\x0b\x32\x16.labgrid.Resource.PathH\x00\x12\x1f\n\x05place\x18\x03 \x01(\x0b\x32\x0e.labgrid.PlaceH\x00\x12\x13\n\tdel_place\x18\x04 \x01(\tH\x00\x42\x06\n\x04kind\"\x9a\x01\n\x11\x45xporterInMessage\x12%\n\x08resource\x18\x01 \x01(\x0b\x32\x11.labgrid.ResourceH\x00\x12\'\n\x07startup\x18\x02 \x01(\x0b\x32\x14.labgrid.StartupDoneH\x00\x12-\n\x08response\x18\x03 \x01(\x0b\x32\x19.labgrid.ExporterResponseH\x00\x42\x06\n\x04kind\"\x9e\x03\n\x08Resource\x12$\n\x04path\x18\x01 \x01(\x0b\x32\x16.labgrid.Resource.Path\x12\x0b\n\x03\x63ls\x18\x02 \x01(\t\x12-\n\x06params\x18\x03 \x03(\x0b\x32\x1d.labgrid.Resource.ParamsEntry\x12+\n\x05\x65xtra\x18\x04 \x03(\x0b\x32\x1c.labgrid.Resource.ExtraEntry\x12\x10\n\x08\x61\x63quired\x18\x05 \x01(\t\x12\r\n\x05\x61vail\x18\x06 \x01(\x08\x1a_\n\x04Path\x12\x1a\n\rexporter_name\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x12\n\ngroup_name\x18\x02 \x01(\t\x12\x15\n\rresource_name\x18\x03 \x01(\tB\x10\n\x0e_exporter_name\x1a@\n\x0bParamsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12 \n\x05value\x18\x02 \x01(\x0b\x32\x11.labgrid.MapValue:\x02\x38\x01\x1a?\n\nExtraEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12 \n\x05value\x18\x02 \x01(\x0b\x32\x11.labgrid.MapValue:\x02\x38\x01\"\x82\x01\n\x08MapValue\x12\x14\n\nbool_value\x18\x01 \x01(\x08H\x00\x12\x13\n\tint_value\x18\x02 \x01(\x03H\x00\x12\x14\n\nuint_value\x18\x03 \x01(\x04H\x00\x12\x15\n\x0b\x66loat_value\x18\x04 \x01(\x01H\x00\x12\x16\n\x0cstring_value\x18\x05 \x01(\tH\x00\x42\x06\n\x04kind\"C\n\x10\x45xporterResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x13\n\x06reason\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_reason\"\x18\n\x05Hello\x12\x0f\n\x07version\x18\x01 \x01(\t\"\xcb\x01\n\x12\x45xporterOutMessage\x12\x1f\n\x05hello\x18\x01 \x01(\x0b\x32\x0e.labgrid.HelloH\x00\x12\x43\n\x14set_acquired_request\x18\x02 \x01(\x0b\x32#.labgrid.ExporterSetAcquiredRequestH\x00\x12G\n\x16lease_extended_request\x18\x03 \x01(\x0b\x32%.labgrid.ExporterLeaseExtendedRequestH\x00\x42\x06\n\x04kind\"o\n\x1a\x45xporterSetAcquiredRequest\x12\x12\n\ngroup_name\x18\x01 \x01(\t\x12\x15\n\rresource_name\x18\x02 \x01(\t\x12\x17\n\nplace_name\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\r\n\x0b_place_name\"\x83\x01\n\x1c\x45xporterLeaseExtendedRequest\x12\x12\n\ngroup_name\x18\x01 \x01(\t\x12\x15\n\rresource_name\x18\x02 \x01(\t\x12\x17\n\nplace_name\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x10\n\x08\x64uration\x18\x04 \x01(\x04\x42\r\n\x0b_place_name\"\x1f\n\x0f\x41\x64\x64PlaceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x12\n\x10\x41\x64\x64PlaceResponse\"\"\n\x12\x44\x65letePlaceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x15\n\x13\x44\x65letePlaceResponse\"\x12\n\x10GetPlacesRequest\"3\n\x11GetPlacesResponse\x12\x1e\n\x06places\x18\x01 \x03(\x0b\x32\x0e.labgrid.Place\"\xd2\x02\n\x05Place\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07\x61liases\x18\x02 \x03(\t\x12\x0f\n\x07\x63omment\x18\x03 \x01(\t\x12&\n\x04tags\x18\x04 \x03(\x0b\x32\x18.labgrid.Place.TagsEntry\x12\'\n\x07matches\x18\x05 \x03(\x0b\x32\x16.labgrid.ResourceMatch\x12\x15\n\x08\x61\x63quired\x18\x06 \x01(\tH\x00\x88\x01\x01\x12\x1a\n\x12\x61\x63quired_resources\x18\x07 \x03(\t\x12\x0f\n\x07\x61llowed\x18\x08 \x03(\t\x12\x0f\n\x07\x63reated\x18\t \x01(\x01\x12\x0f\n\x07\x63hanged\x18\n \x01(\x01\x12\x18\n\x0breservation\x18\x0b \x01(\tH\x01\x88\x01\x01\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x0b\n\t_acquiredB\x0e\n\x0c_reservation\"y\n\rResourceMatch\x12\x10\n\x08\x65xporter\x18\x01 \x01(\t\x12\r\n\x05group\x18\x02 \x01(\t\x12\x0b\n\x03\x63ls\x18\x03 \x01(\t\x12\x11\n\x04name\x18\x04 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06rename\x18\x05 \x01(\tH\x01\x88\x01\x01\x42\x07\n\x05_nameB\t\n\x07_rename\"8\n\x14\x41\x64\x64PlaceAliasRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\r\n\x05\x61lias\x18\x02 \x01(\t\"\x17\n\x15\x41\x64\x64PlaceAliasResponse\";\n\x17\x44\x65letePlaceAliasRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\r\n\x05\x61lias\x18\x02 \x01(\t\"\x1a\n\x18\x44\x65letePlaceAliasResponse\"\x8b\x01\n\x13SetPlaceTagsRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\x34\n\x04tags\x18\x02 \x03(\x0b\x32&.labgrid.SetPlaceTagsRequest.TagsEntry\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x16\n\x14SetPlaceTagsResponse\"<\n\x16SetPlaceCommentRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\x0f\n\x07\x63omment\x18\x02 \x01(\t\"\x19\n\x17SetPlaceCommentResponse\"Z\n\x14\x41\x64\x64PlaceMatchRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\x0f\n\x07pattern\x18\x02 \x01(\t\x12\x13\n\x06rename\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_rename\"\x17\n\x15\x41\x64\x64PlaceMatchResponse\"]\n\x17\x44\x65letePlaceMatchRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\x0f\n\x07pattern\x18\x02 \x01(\t\x12\x13\n\x06rename\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_rename\"\x1a\n\x18\x44\x65letePlaceMatchResponse\"(\n\x13\x41\x63quirePlaceRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\"\x16\n\x14\x41\x63quirePlaceResponse\"&\n\x11LeasePlaceRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\"\x14\n\x12LeasePlaceResponse\"#\n\x12\x45xtendLeaseRequest\x12\r\n\x05token\x18\x01 \x01(\t\"@\n\x13\x45xtendLeaseResponse\x12)\n\x0breservation\x18\x01 \x01(\x0b\x32\x14.labgrid.Reservation\"\x17\n\x15GetLeaseConfigRequest\"u\n\x16GetLeaseConfigResponse\x12\x1e\n\x16\x64\x65\x66\x61ult_lease_duration\x18\x01 \x01(\r\x12\x1f\n\x17\x64\x65\x66\x61ult_extend_duration\x18\x02 \x01(\r\x12\x1a\n\x12max_lease_duration\x18\x03 \x01(\r\"L\n\x13ReleasePlaceRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\x15\n\x08\x66romuser\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0b\n\t_fromuser\"\x16\n\x14ReleasePlaceResponse\"4\n\x11\x41llowPlaceRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\x0c\n\x04user\x18\x02 \x01(\t\"\x14\n\x12\x41llowPlaceResponse\"\xb6\x01\n\x18\x43reateReservationRequest\x12?\n\x07\x66ilters\x18\x01 \x03(\x0b\x32..labgrid.CreateReservationRequest.FiltersEntry\x12\x0c\n\x04prio\x18\x02 \x01(\x01\x1aK\n\x0c\x46iltersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12*\n\x05value\x18\x02 \x01(\x0b\x32\x1b.labgrid.Reservation.Filter:\x02\x38\x01\"F\n\x19\x43reateReservationResponse\x12)\n\x0breservation\x18\x01 \x01(\x0b\x32\x14.labgrid.Reservation\"\x83\x04\n\x0bReservation\x12\r\n\x05owner\x18\x01 \x01(\t\x12\r\n\x05token\x18\x02 \x01(\t\x12\r\n\x05state\x18\x03 \x01(\x05\x12\x0c\n\x04prio\x18\x04 \x01(\x01\x12\x32\n\x07\x66ilters\x18\x05 \x03(\x0b\x32!.labgrid.Reservation.FiltersEntry\x12:\n\x0b\x61llocations\x18\x06 \x03(\x0b\x32%.labgrid.Reservation.AllocationsEntry\x12\x0f\n\x07\x63reated\x18\x07 \x01(\x01\x12\x0f\n\x07timeout\x18\x08 \x01(\x01\x12\x34\n\x10lease_start_time\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x1ap\n\x06\x46ilter\x12\x37\n\x06\x66ilter\x18\x01 \x03(\x0b\x32\'.labgrid.Reservation.Filter.FilterEntry\x1a-\n\x0b\x46ilterEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1aK\n\x0c\x46iltersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12*\n\x05value\x18\x02 \x01(\x0b\x32\x1b.labgrid.Reservation.Filter:\x02\x38\x01\x1a\x32\n\x10\x41llocationsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\")\n\x18\x43\x61ncelReservationRequest\x12\r\n\x05token\x18\x01 \x01(\t\"\x1b\n\x19\x43\x61ncelReservationResponse\"\'\n\x16PollReservationRequest\x12\r\n\x05token\x18\x01 \x01(\t\"D\n\x17PollReservationResponse\x12)\n\x0breservation\x18\x01 \x01(\x0b\x32\x14.labgrid.Reservation\"E\n\x17GetReservationsResponse\x12*\n\x0creservations\x18\x01 \x03(\x0b\x32\x14.labgrid.Reservation\"\x18\n\x16GetReservationsRequest2\xb6\r\n\x0b\x43oordinator\x12I\n\x0c\x43lientStream\x12\x18.labgrid.ClientInMessage\x1a\x19.labgrid.ClientOutMessage\"\x00(\x01\x30\x01\x12O\n\x0e\x45xporterStream\x12\x1a.labgrid.ExporterInMessage\x1a\x1b.labgrid.ExporterOutMessage\"\x00(\x01\x30\x01\x12\x41\n\x08\x41\x64\x64Place\x12\x18.labgrid.AddPlaceRequest\x1a\x19.labgrid.AddPlaceResponse\"\x00\x12J\n\x0b\x44\x65letePlace\x12\x1b.labgrid.DeletePlaceRequest\x1a\x1c.labgrid.DeletePlaceResponse\"\x00\x12\x44\n\tGetPlaces\x12\x19.labgrid.GetPlacesRequest\x1a\x1a.labgrid.GetPlacesResponse\"\x00\x12P\n\rAddPlaceAlias\x12\x1d.labgrid.AddPlaceAliasRequest\x1a\x1e.labgrid.AddPlaceAliasResponse\"\x00\x12Y\n\x10\x44\x65letePlaceAlias\x12 .labgrid.DeletePlaceAliasRequest\x1a!.labgrid.DeletePlaceAliasResponse\"\x00\x12M\n\x0cSetPlaceTags\x12\x1c.labgrid.SetPlaceTagsRequest\x1a\x1d.labgrid.SetPlaceTagsResponse\"\x00\x12V\n\x0fSetPlaceComment\x12\x1f.labgrid.SetPlaceCommentRequest\x1a .labgrid.SetPlaceCommentResponse\"\x00\x12P\n\rAddPlaceMatch\x12\x1d.labgrid.AddPlaceMatchRequest\x1a\x1e.labgrid.AddPlaceMatchResponse\"\x00\x12Y\n\x10\x44\x65letePlaceMatch\x12 .labgrid.DeletePlaceMatchRequest\x1a!.labgrid.DeletePlaceMatchResponse\"\x00\x12M\n\x0c\x41\x63quirePlace\x12\x1c.labgrid.AcquirePlaceRequest\x1a\x1d.labgrid.AcquirePlaceResponse\"\x00\x12\x45\n\nLeasePlace\x12\x1a.labgrid.LeasePlaceRequest\x1a\x1b.labgrid.LeasePlaceResponse\x12Q\n\x0eGetLeaseConfig\x12\x1e.labgrid.GetLeaseConfigRequest\x1a\x1f.labgrid.GetLeaseConfigResponse\x12M\n\x0cReleasePlace\x12\x1c.labgrid.ReleasePlaceRequest\x1a\x1d.labgrid.ReleasePlaceResponse\"\x00\x12G\n\nAllowPlace\x12\x1a.labgrid.AllowPlaceRequest\x1a\x1b.labgrid.AllowPlaceResponse\"\x00\x12\\\n\x11\x43reateReservation\x12!.labgrid.CreateReservationRequest\x1a\".labgrid.CreateReservationResponse\"\x00\x12\\\n\x11\x43\x61ncelReservation\x12!.labgrid.CancelReservationRequest\x1a\".labgrid.CancelReservationResponse\"\x00\x12V\n\x0fPollReservation\x12\x1f.labgrid.PollReservationRequest\x1a .labgrid.PollReservationResponse\"\x00\x12H\n\x0b\x45xtendLease\x12\x1b.labgrid.ExtendLeaseRequest\x1a\x1c.labgrid.ExtendLeaseResponse\x12V\n\x0fGetReservations\x12\x1f.labgrid.GetReservationsRequest\x1a .labgrid.GetReservationsResponse\"\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'labgrid_coordinator_pb2', _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - _globals['_RESOURCE_PARAMSENTRY']._options = None +if not _descriptor._USE_C_DESCRIPTORS: + DESCRIPTOR._loaded_options = None + _globals['_RESOURCE_PARAMSENTRY']._loaded_options = None _globals['_RESOURCE_PARAMSENTRY']._serialized_options = b'8\001' - _globals['_RESOURCE_EXTRAENTRY']._options = None + _globals['_RESOURCE_EXTRAENTRY']._loaded_options = None _globals['_RESOURCE_EXTRAENTRY']._serialized_options = b'8\001' - _globals['_PLACE_TAGSENTRY']._options = None + _globals['_PLACE_TAGSENTRY']._loaded_options = None _globals['_PLACE_TAGSENTRY']._serialized_options = b'8\001' - _globals['_SETPLACETAGSREQUEST_TAGSENTRY']._options = None + _globals['_SETPLACETAGSREQUEST_TAGSENTRY']._loaded_options = None _globals['_SETPLACETAGSREQUEST_TAGSENTRY']._serialized_options = b'8\001' - _globals['_CREATERESERVATIONREQUEST_FILTERSENTRY']._options = None + _globals['_CREATERESERVATIONREQUEST_FILTERSENTRY']._loaded_options = None _globals['_CREATERESERVATIONREQUEST_FILTERSENTRY']._serialized_options = b'8\001' - _globals['_RESERVATION_FILTER_FILTERENTRY']._options = None + _globals['_RESERVATION_FILTER_FILTERENTRY']._loaded_options = None _globals['_RESERVATION_FILTER_FILTERENTRY']._serialized_options = b'8\001' - _globals['_RESERVATION_FILTERSENTRY']._options = None + _globals['_RESERVATION_FILTERSENTRY']._loaded_options = None _globals['_RESERVATION_FILTERSENTRY']._serialized_options = b'8\001' - _globals['_RESERVATION_ALLOCATIONSENTRY']._options = None + _globals['_RESERVATION_ALLOCATIONSENTRY']._loaded_options = None _globals['_RESERVATION_ALLOCATIONSENTRY']._serialized_options = b'8\001' - _globals['_CLIENTINMESSAGE']._serialized_start=39 - _globals['_CLIENTINMESSAGE']._serialized_end=177 - _globals['_SYNC']._serialized_start=179 - _globals['_SYNC']._serialized_end=197 - _globals['_STARTUPDONE']._serialized_start=199 - _globals['_STARTUPDONE']._serialized_end=243 - _globals['_SUBSCRIBE']._serialized_start=245 - _globals['_SUBSCRIBE']._serialized_end=359 - _globals['_CLIENTOUTMESSAGE']._serialized_start=361 - _globals['_CLIENTOUTMESSAGE']._serialized_end=464 - _globals['_UPDATERESPONSE']._serialized_start=467 - _globals['_UPDATERESPONSE']._serialized_end=632 - _globals['_EXPORTERINMESSAGE']._serialized_start=635 - _globals['_EXPORTERINMESSAGE']._serialized_end=789 - _globals['_RESOURCE']._serialized_start=792 - _globals['_RESOURCE']._serialized_end=1206 - _globals['_RESOURCE_PATH']._serialized_start=980 - _globals['_RESOURCE_PATH']._serialized_end=1075 - _globals['_RESOURCE_PARAMSENTRY']._serialized_start=1077 - _globals['_RESOURCE_PARAMSENTRY']._serialized_end=1141 - _globals['_RESOURCE_EXTRAENTRY']._serialized_start=1143 - _globals['_RESOURCE_EXTRAENTRY']._serialized_end=1206 - _globals['_MAPVALUE']._serialized_start=1209 - _globals['_MAPVALUE']._serialized_end=1339 - _globals['_EXPORTERRESPONSE']._serialized_start=1341 - _globals['_EXPORTERRESPONSE']._serialized_end=1408 - _globals['_HELLO']._serialized_start=1410 - _globals['_HELLO']._serialized_end=1434 - _globals['_EXPORTEROUTMESSAGE']._serialized_start=1437 - _globals['_EXPORTEROUTMESSAGE']._serialized_end=1567 - _globals['_EXPORTERSETACQUIREDREQUEST']._serialized_start=1569 - _globals['_EXPORTERSETACQUIREDREQUEST']._serialized_end=1680 - _globals['_ADDPLACEREQUEST']._serialized_start=1682 - _globals['_ADDPLACEREQUEST']._serialized_end=1713 - _globals['_ADDPLACERESPONSE']._serialized_start=1715 - _globals['_ADDPLACERESPONSE']._serialized_end=1733 - _globals['_DELETEPLACEREQUEST']._serialized_start=1735 - _globals['_DELETEPLACEREQUEST']._serialized_end=1769 - _globals['_DELETEPLACERESPONSE']._serialized_start=1771 - _globals['_DELETEPLACERESPONSE']._serialized_end=1792 - _globals['_GETPLACESREQUEST']._serialized_start=1794 - _globals['_GETPLACESREQUEST']._serialized_end=1812 - _globals['_GETPLACESRESPONSE']._serialized_start=1814 - _globals['_GETPLACESRESPONSE']._serialized_end=1865 - _globals['_PLACE']._serialized_start=1868 - _globals['_PLACE']._serialized_end=2206 - _globals['_PLACE_TAGSENTRY']._serialized_start=2134 - _globals['_PLACE_TAGSENTRY']._serialized_end=2177 - _globals['_RESOURCEMATCH']._serialized_start=2208 - _globals['_RESOURCEMATCH']._serialized_end=2329 - _globals['_ADDPLACEALIASREQUEST']._serialized_start=2331 - _globals['_ADDPLACEALIASREQUEST']._serialized_end=2387 - _globals['_ADDPLACEALIASRESPONSE']._serialized_start=2389 - _globals['_ADDPLACEALIASRESPONSE']._serialized_end=2412 - _globals['_DELETEPLACEALIASREQUEST']._serialized_start=2414 - _globals['_DELETEPLACEALIASREQUEST']._serialized_end=2473 - _globals['_DELETEPLACEALIASRESPONSE']._serialized_start=2475 - _globals['_DELETEPLACEALIASRESPONSE']._serialized_end=2501 - _globals['_SETPLACETAGSREQUEST']._serialized_start=2504 - _globals['_SETPLACETAGSREQUEST']._serialized_end=2643 - _globals['_SETPLACETAGSREQUEST_TAGSENTRY']._serialized_start=2134 - _globals['_SETPLACETAGSREQUEST_TAGSENTRY']._serialized_end=2177 - _globals['_SETPLACETAGSRESPONSE']._serialized_start=2645 - _globals['_SETPLACETAGSRESPONSE']._serialized_end=2667 - _globals['_SETPLACECOMMENTREQUEST']._serialized_start=2669 - _globals['_SETPLACECOMMENTREQUEST']._serialized_end=2729 - _globals['_SETPLACECOMMENTRESPONSE']._serialized_start=2731 - _globals['_SETPLACECOMMENTRESPONSE']._serialized_end=2756 - _globals['_ADDPLACEMATCHREQUEST']._serialized_start=2758 - _globals['_ADDPLACEMATCHREQUEST']._serialized_end=2848 - _globals['_ADDPLACEMATCHRESPONSE']._serialized_start=2850 - _globals['_ADDPLACEMATCHRESPONSE']._serialized_end=2873 - _globals['_DELETEPLACEMATCHREQUEST']._serialized_start=2875 - _globals['_DELETEPLACEMATCHREQUEST']._serialized_end=2968 - _globals['_DELETEPLACEMATCHRESPONSE']._serialized_start=2970 - _globals['_DELETEPLACEMATCHRESPONSE']._serialized_end=2996 - _globals['_ACQUIREPLACEREQUEST']._serialized_start=2998 - _globals['_ACQUIREPLACEREQUEST']._serialized_end=3038 - _globals['_ACQUIREPLACERESPONSE']._serialized_start=3040 - _globals['_ACQUIREPLACERESPONSE']._serialized_end=3062 - _globals['_RELEASEPLACEREQUEST']._serialized_start=3064 - _globals['_RELEASEPLACEREQUEST']._serialized_end=3140 - _globals['_RELEASEPLACERESPONSE']._serialized_start=3142 - _globals['_RELEASEPLACERESPONSE']._serialized_end=3164 - _globals['_ALLOWPLACEREQUEST']._serialized_start=3166 - _globals['_ALLOWPLACEREQUEST']._serialized_end=3218 - _globals['_ALLOWPLACERESPONSE']._serialized_start=3220 - _globals['_ALLOWPLACERESPONSE']._serialized_end=3240 - _globals['_CREATERESERVATIONREQUEST']._serialized_start=3243 - _globals['_CREATERESERVATIONREQUEST']._serialized_end=3425 - _globals['_CREATERESERVATIONREQUEST_FILTERSENTRY']._serialized_start=3350 - _globals['_CREATERESERVATIONREQUEST_FILTERSENTRY']._serialized_end=3425 - _globals['_CREATERESERVATIONRESPONSE']._serialized_start=3427 - _globals['_CREATERESERVATIONRESPONSE']._serialized_end=3497 - _globals['_RESERVATION']._serialized_start=3500 - _globals['_RESERVATION']._serialized_end=3961 - _globals['_RESERVATION_FILTER']._serialized_start=3720 - _globals['_RESERVATION_FILTER']._serialized_end=3832 - _globals['_RESERVATION_FILTER_FILTERENTRY']._serialized_start=3787 - _globals['_RESERVATION_FILTER_FILTERENTRY']._serialized_end=3832 - _globals['_RESERVATION_FILTERSENTRY']._serialized_start=3350 - _globals['_RESERVATION_FILTERSENTRY']._serialized_end=3425 - _globals['_RESERVATION_ALLOCATIONSENTRY']._serialized_start=3911 - _globals['_RESERVATION_ALLOCATIONSENTRY']._serialized_end=3961 - _globals['_CANCELRESERVATIONREQUEST']._serialized_start=3963 - _globals['_CANCELRESERVATIONREQUEST']._serialized_end=4004 - _globals['_CANCELRESERVATIONRESPONSE']._serialized_start=4006 - _globals['_CANCELRESERVATIONRESPONSE']._serialized_end=4033 - _globals['_POLLRESERVATIONREQUEST']._serialized_start=4035 - _globals['_POLLRESERVATIONREQUEST']._serialized_end=4074 - _globals['_POLLRESERVATIONRESPONSE']._serialized_start=4076 - _globals['_POLLRESERVATIONRESPONSE']._serialized_end=4144 - _globals['_GETRESERVATIONSRESPONSE']._serialized_start=4146 - _globals['_GETRESERVATIONSRESPONSE']._serialized_end=4215 - _globals['_GETRESERVATIONSREQUEST']._serialized_start=4217 - _globals['_GETRESERVATIONSREQUEST']._serialized_end=4241 - _globals['_COORDINATOR']._serialized_start=4244 - _globals['_COORDINATOR']._serialized_end=5734 + _globals['_CLIENTINMESSAGE']._serialized_start=72 + _globals['_CLIENTINMESSAGE']._serialized_end=210 + _globals['_SYNC']._serialized_start=212 + _globals['_SYNC']._serialized_end=230 + _globals['_STARTUPDONE']._serialized_start=232 + _globals['_STARTUPDONE']._serialized_end=276 + _globals['_SUBSCRIBE']._serialized_start=278 + _globals['_SUBSCRIBE']._serialized_end=392 + _globals['_CLIENTOUTMESSAGE']._serialized_start=394 + _globals['_CLIENTOUTMESSAGE']._serialized_end=497 + _globals['_UPDATERESPONSE']._serialized_start=500 + _globals['_UPDATERESPONSE']._serialized_end=665 + _globals['_EXPORTERINMESSAGE']._serialized_start=668 + _globals['_EXPORTERINMESSAGE']._serialized_end=822 + _globals['_RESOURCE']._serialized_start=825 + _globals['_RESOURCE']._serialized_end=1239 + _globals['_RESOURCE_PATH']._serialized_start=1013 + _globals['_RESOURCE_PATH']._serialized_end=1108 + _globals['_RESOURCE_PARAMSENTRY']._serialized_start=1110 + _globals['_RESOURCE_PARAMSENTRY']._serialized_end=1174 + _globals['_RESOURCE_EXTRAENTRY']._serialized_start=1176 + _globals['_RESOURCE_EXTRAENTRY']._serialized_end=1239 + _globals['_MAPVALUE']._serialized_start=1242 + _globals['_MAPVALUE']._serialized_end=1372 + _globals['_EXPORTERRESPONSE']._serialized_start=1374 + _globals['_EXPORTERRESPONSE']._serialized_end=1441 + _globals['_HELLO']._serialized_start=1443 + _globals['_HELLO']._serialized_end=1467 + _globals['_EXPORTEROUTMESSAGE']._serialized_start=1470 + _globals['_EXPORTEROUTMESSAGE']._serialized_end=1673 + _globals['_EXPORTERSETACQUIREDREQUEST']._serialized_start=1675 + _globals['_EXPORTERSETACQUIREDREQUEST']._serialized_end=1786 + _globals['_EXPORTERLEASEEXTENDEDREQUEST']._serialized_start=1789 + _globals['_EXPORTERLEASEEXTENDEDREQUEST']._serialized_end=1920 + _globals['_ADDPLACEREQUEST']._serialized_start=1922 + _globals['_ADDPLACEREQUEST']._serialized_end=1953 + _globals['_ADDPLACERESPONSE']._serialized_start=1955 + _globals['_ADDPLACERESPONSE']._serialized_end=1973 + _globals['_DELETEPLACEREQUEST']._serialized_start=1975 + _globals['_DELETEPLACEREQUEST']._serialized_end=2009 + _globals['_DELETEPLACERESPONSE']._serialized_start=2011 + _globals['_DELETEPLACERESPONSE']._serialized_end=2032 + _globals['_GETPLACESREQUEST']._serialized_start=2034 + _globals['_GETPLACESREQUEST']._serialized_end=2052 + _globals['_GETPLACESRESPONSE']._serialized_start=2054 + _globals['_GETPLACESRESPONSE']._serialized_end=2105 + _globals['_PLACE']._serialized_start=2108 + _globals['_PLACE']._serialized_end=2446 + _globals['_PLACE_TAGSENTRY']._serialized_start=2374 + _globals['_PLACE_TAGSENTRY']._serialized_end=2417 + _globals['_RESOURCEMATCH']._serialized_start=2448 + _globals['_RESOURCEMATCH']._serialized_end=2569 + _globals['_ADDPLACEALIASREQUEST']._serialized_start=2571 + _globals['_ADDPLACEALIASREQUEST']._serialized_end=2627 + _globals['_ADDPLACEALIASRESPONSE']._serialized_start=2629 + _globals['_ADDPLACEALIASRESPONSE']._serialized_end=2652 + _globals['_DELETEPLACEALIASREQUEST']._serialized_start=2654 + _globals['_DELETEPLACEALIASREQUEST']._serialized_end=2713 + _globals['_DELETEPLACEALIASRESPONSE']._serialized_start=2715 + _globals['_DELETEPLACEALIASRESPONSE']._serialized_end=2741 + _globals['_SETPLACETAGSREQUEST']._serialized_start=2744 + _globals['_SETPLACETAGSREQUEST']._serialized_end=2883 + _globals['_SETPLACETAGSREQUEST_TAGSENTRY']._serialized_start=2374 + _globals['_SETPLACETAGSREQUEST_TAGSENTRY']._serialized_end=2417 + _globals['_SETPLACETAGSRESPONSE']._serialized_start=2885 + _globals['_SETPLACETAGSRESPONSE']._serialized_end=2907 + _globals['_SETPLACECOMMENTREQUEST']._serialized_start=2909 + _globals['_SETPLACECOMMENTREQUEST']._serialized_end=2969 + _globals['_SETPLACECOMMENTRESPONSE']._serialized_start=2971 + _globals['_SETPLACECOMMENTRESPONSE']._serialized_end=2996 + _globals['_ADDPLACEMATCHREQUEST']._serialized_start=2998 + _globals['_ADDPLACEMATCHREQUEST']._serialized_end=3088 + _globals['_ADDPLACEMATCHRESPONSE']._serialized_start=3090 + _globals['_ADDPLACEMATCHRESPONSE']._serialized_end=3113 + _globals['_DELETEPLACEMATCHREQUEST']._serialized_start=3115 + _globals['_DELETEPLACEMATCHREQUEST']._serialized_end=3208 + _globals['_DELETEPLACEMATCHRESPONSE']._serialized_start=3210 + _globals['_DELETEPLACEMATCHRESPONSE']._serialized_end=3236 + _globals['_ACQUIREPLACEREQUEST']._serialized_start=3238 + _globals['_ACQUIREPLACEREQUEST']._serialized_end=3278 + _globals['_ACQUIREPLACERESPONSE']._serialized_start=3280 + _globals['_ACQUIREPLACERESPONSE']._serialized_end=3302 + _globals['_LEASEPLACEREQUEST']._serialized_start=3304 + _globals['_LEASEPLACEREQUEST']._serialized_end=3342 + _globals['_LEASEPLACERESPONSE']._serialized_start=3344 + _globals['_LEASEPLACERESPONSE']._serialized_end=3364 + _globals['_EXTENDLEASEREQUEST']._serialized_start=3366 + _globals['_EXTENDLEASEREQUEST']._serialized_end=3401 + _globals['_EXTENDLEASERESPONSE']._serialized_start=3403 + _globals['_EXTENDLEASERESPONSE']._serialized_end=3467 + _globals['_GETLEASECONFIGREQUEST']._serialized_start=3469 + _globals['_GETLEASECONFIGREQUEST']._serialized_end=3492 + _globals['_GETLEASECONFIGRESPONSE']._serialized_start=3494 + _globals['_GETLEASECONFIGRESPONSE']._serialized_end=3611 + _globals['_RELEASEPLACEREQUEST']._serialized_start=3613 + _globals['_RELEASEPLACEREQUEST']._serialized_end=3689 + _globals['_RELEASEPLACERESPONSE']._serialized_start=3691 + _globals['_RELEASEPLACERESPONSE']._serialized_end=3713 + _globals['_ALLOWPLACEREQUEST']._serialized_start=3715 + _globals['_ALLOWPLACEREQUEST']._serialized_end=3767 + _globals['_ALLOWPLACERESPONSE']._serialized_start=3769 + _globals['_ALLOWPLACERESPONSE']._serialized_end=3789 + _globals['_CREATERESERVATIONREQUEST']._serialized_start=3792 + _globals['_CREATERESERVATIONREQUEST']._serialized_end=3974 + _globals['_CREATERESERVATIONREQUEST_FILTERSENTRY']._serialized_start=3899 + _globals['_CREATERESERVATIONREQUEST_FILTERSENTRY']._serialized_end=3974 + _globals['_CREATERESERVATIONRESPONSE']._serialized_start=3976 + _globals['_CREATERESERVATIONRESPONSE']._serialized_end=4046 + _globals['_RESERVATION']._serialized_start=4049 + _globals['_RESERVATION']._serialized_end=4564 + _globals['_RESERVATION_FILTER']._serialized_start=4323 + _globals['_RESERVATION_FILTER']._serialized_end=4435 + _globals['_RESERVATION_FILTER_FILTERENTRY']._serialized_start=4390 + _globals['_RESERVATION_FILTER_FILTERENTRY']._serialized_end=4435 + _globals['_RESERVATION_FILTERSENTRY']._serialized_start=3899 + _globals['_RESERVATION_FILTERSENTRY']._serialized_end=3974 + _globals['_RESERVATION_ALLOCATIONSENTRY']._serialized_start=4514 + _globals['_RESERVATION_ALLOCATIONSENTRY']._serialized_end=4564 + _globals['_CANCELRESERVATIONREQUEST']._serialized_start=4566 + _globals['_CANCELRESERVATIONREQUEST']._serialized_end=4607 + _globals['_CANCELRESERVATIONRESPONSE']._serialized_start=4609 + _globals['_CANCELRESERVATIONRESPONSE']._serialized_end=4636 + _globals['_POLLRESERVATIONREQUEST']._serialized_start=4638 + _globals['_POLLRESERVATIONREQUEST']._serialized_end=4677 + _globals['_POLLRESERVATIONRESPONSE']._serialized_start=4679 + _globals['_POLLRESERVATIONRESPONSE']._serialized_end=4747 + _globals['_GETRESERVATIONSRESPONSE']._serialized_start=4749 + _globals['_GETRESERVATIONSRESPONSE']._serialized_end=4818 + _globals['_GETRESERVATIONSREQUEST']._serialized_start=4820 + _globals['_GETRESERVATIONSREQUEST']._serialized_end=4844 + _globals['_COORDINATOR']._serialized_start=4847 + _globals['_COORDINATOR']._serialized_end=6565 # @@protoc_insertion_point(module_scope) diff --git a/labgrid/remote/generated/labgrid_coordinator_pb2.pyi b/labgrid/remote/generated/labgrid_coordinator_pb2.pyi index 366f4e438..5e6e6f704 100644 --- a/labgrid/remote/generated/labgrid_coordinator_pb2.pyi +++ b/labgrid/remote/generated/labgrid_coordinator_pb2.pyi @@ -1,7 +1,11 @@ +import datetime + +from google.protobuf import timestamp_pb2 as _timestamp_pb2 from google.protobuf.internal import containers as _containers from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message -from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union +from collections.abc import Iterable as _Iterable, Mapping as _Mapping +from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union DESCRIPTOR: _descriptor.FileDescriptor @@ -137,12 +141,14 @@ class Hello(_message.Message): def __init__(self, version: _Optional[str] = ...) -> None: ... class ExporterOutMessage(_message.Message): - __slots__ = ("hello", "set_acquired_request") + __slots__ = ("hello", "set_acquired_request", "lease_extended_request") HELLO_FIELD_NUMBER: _ClassVar[int] SET_ACQUIRED_REQUEST_FIELD_NUMBER: _ClassVar[int] + LEASE_EXTENDED_REQUEST_FIELD_NUMBER: _ClassVar[int] hello: Hello set_acquired_request: ExporterSetAcquiredRequest - def __init__(self, hello: _Optional[_Union[Hello, _Mapping]] = ..., set_acquired_request: _Optional[_Union[ExporterSetAcquiredRequest, _Mapping]] = ...) -> None: ... + lease_extended_request: ExporterLeaseExtendedRequest + def __init__(self, hello: _Optional[_Union[Hello, _Mapping]] = ..., set_acquired_request: _Optional[_Union[ExporterSetAcquiredRequest, _Mapping]] = ..., lease_extended_request: _Optional[_Union[ExporterLeaseExtendedRequest, _Mapping]] = ...) -> None: ... class ExporterSetAcquiredRequest(_message.Message): __slots__ = ("group_name", "resource_name", "place_name") @@ -154,6 +160,18 @@ class ExporterSetAcquiredRequest(_message.Message): place_name: str def __init__(self, group_name: _Optional[str] = ..., resource_name: _Optional[str] = ..., place_name: _Optional[str] = ...) -> None: ... +class ExporterLeaseExtendedRequest(_message.Message): + __slots__ = ("group_name", "resource_name", "place_name", "duration") + GROUP_NAME_FIELD_NUMBER: _ClassVar[int] + RESOURCE_NAME_FIELD_NUMBER: _ClassVar[int] + PLACE_NAME_FIELD_NUMBER: _ClassVar[int] + DURATION_FIELD_NUMBER: _ClassVar[int] + group_name: str + resource_name: str + place_name: str + duration: int + def __init__(self, group_name: _Optional[str] = ..., resource_name: _Optional[str] = ..., place_name: _Optional[str] = ..., duration: _Optional[int] = ...) -> None: ... + class AddPlaceRequest(_message.Message): __slots__ = ("name",) NAME_FIELD_NUMBER: _ClassVar[int] @@ -324,6 +342,42 @@ class AcquirePlaceResponse(_message.Message): __slots__ = () def __init__(self) -> None: ... +class LeasePlaceRequest(_message.Message): + __slots__ = ("placename",) + PLACENAME_FIELD_NUMBER: _ClassVar[int] + placename: str + def __init__(self, placename: _Optional[str] = ...) -> None: ... + +class LeasePlaceResponse(_message.Message): + __slots__ = () + def __init__(self) -> None: ... + +class ExtendLeaseRequest(_message.Message): + __slots__ = ("token",) + TOKEN_FIELD_NUMBER: _ClassVar[int] + token: str + def __init__(self, token: _Optional[str] = ...) -> None: ... + +class ExtendLeaseResponse(_message.Message): + __slots__ = ("reservation",) + RESERVATION_FIELD_NUMBER: _ClassVar[int] + reservation: Reservation + def __init__(self, reservation: _Optional[_Union[Reservation, _Mapping]] = ...) -> None: ... + +class GetLeaseConfigRequest(_message.Message): + __slots__ = () + def __init__(self) -> None: ... + +class GetLeaseConfigResponse(_message.Message): + __slots__ = ("default_lease_duration", "default_extend_duration", "max_lease_duration") + DEFAULT_LEASE_DURATION_FIELD_NUMBER: _ClassVar[int] + DEFAULT_EXTEND_DURATION_FIELD_NUMBER: _ClassVar[int] + MAX_LEASE_DURATION_FIELD_NUMBER: _ClassVar[int] + default_lease_duration: int + default_extend_duration: int + max_lease_duration: int + def __init__(self, default_lease_duration: _Optional[int] = ..., default_extend_duration: _Optional[int] = ..., max_lease_duration: _Optional[int] = ...) -> None: ... + class ReleasePlaceRequest(_message.Message): __slots__ = ("placename", "fromuser") PLACENAME_FIELD_NUMBER: _ClassVar[int] @@ -370,7 +424,7 @@ class CreateReservationResponse(_message.Message): def __init__(self, reservation: _Optional[_Union[Reservation, _Mapping]] = ...) -> None: ... class Reservation(_message.Message): - __slots__ = ("owner", "token", "state", "prio", "filters", "allocations", "created", "timeout") + __slots__ = ("owner", "token", "state", "prio", "filters", "allocations", "created", "timeout", "lease_start_time") class Filter(_message.Message): __slots__ = ("filter",) class FilterEntry(_message.Message): @@ -405,6 +459,7 @@ class Reservation(_message.Message): ALLOCATIONS_FIELD_NUMBER: _ClassVar[int] CREATED_FIELD_NUMBER: _ClassVar[int] TIMEOUT_FIELD_NUMBER: _ClassVar[int] + LEASE_START_TIME_FIELD_NUMBER: _ClassVar[int] owner: str token: str state: int @@ -413,7 +468,8 @@ class Reservation(_message.Message): allocations: _containers.ScalarMap[str, str] created: float timeout: float - def __init__(self, owner: _Optional[str] = ..., token: _Optional[str] = ..., state: _Optional[int] = ..., prio: _Optional[float] = ..., filters: _Optional[_Mapping[str, Reservation.Filter]] = ..., allocations: _Optional[_Mapping[str, str]] = ..., created: _Optional[float] = ..., timeout: _Optional[float] = ...) -> None: ... + lease_start_time: _timestamp_pb2.Timestamp + def __init__(self, owner: _Optional[str] = ..., token: _Optional[str] = ..., state: _Optional[int] = ..., prio: _Optional[float] = ..., filters: _Optional[_Mapping[str, Reservation.Filter]] = ..., allocations: _Optional[_Mapping[str, str]] = ..., created: _Optional[float] = ..., timeout: _Optional[float] = ..., lease_start_time: _Optional[_Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping]] = ...) -> None: ... class CancelReservationRequest(_message.Message): __slots__ = ("token",) diff --git a/labgrid/remote/generated/labgrid_coordinator_pb2_grpc.py b/labgrid/remote/generated/labgrid_coordinator_pb2_grpc.py index debfb24f2..43bd47957 100644 --- a/labgrid/remote/generated/labgrid_coordinator_pb2_grpc.py +++ b/labgrid/remote/generated/labgrid_coordinator_pb2_grpc.py @@ -1,9 +1,29 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! """Client and server classes corresponding to protobuf-defined services.""" import grpc +import warnings from . import labgrid_coordinator_pb2 as labgrid__coordinator__pb2 +GRPC_GENERATED_VERSION = '1.76.0' +GRPC_VERSION = grpc.__version__ +_version_not_supported = False + +try: + from grpc._utilities import first_version_is_lower + _version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION) +except ImportError: + _version_not_supported = True + +if _version_not_supported: + raise RuntimeError( + f'The grpc package installed is at version {GRPC_VERSION},' + + ' but the generated code in labgrid_coordinator_pb2_grpc.py depends on' + + f' grpcio>={GRPC_GENERATED_VERSION}.' + + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' + ) + class CoordinatorStub(object): """Missing associated documentation comment in .proto file.""" @@ -18,92 +38,107 @@ def __init__(self, channel): '/labgrid.Coordinator/ClientStream', request_serializer=labgrid__coordinator__pb2.ClientInMessage.SerializeToString, response_deserializer=labgrid__coordinator__pb2.ClientOutMessage.FromString, - ) + _registered_method=True) self.ExporterStream = channel.stream_stream( '/labgrid.Coordinator/ExporterStream', request_serializer=labgrid__coordinator__pb2.ExporterInMessage.SerializeToString, response_deserializer=labgrid__coordinator__pb2.ExporterOutMessage.FromString, - ) + _registered_method=True) self.AddPlace = channel.unary_unary( '/labgrid.Coordinator/AddPlace', request_serializer=labgrid__coordinator__pb2.AddPlaceRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.AddPlaceResponse.FromString, - ) + _registered_method=True) self.DeletePlace = channel.unary_unary( '/labgrid.Coordinator/DeletePlace', request_serializer=labgrid__coordinator__pb2.DeletePlaceRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.DeletePlaceResponse.FromString, - ) + _registered_method=True) self.GetPlaces = channel.unary_unary( '/labgrid.Coordinator/GetPlaces', request_serializer=labgrid__coordinator__pb2.GetPlacesRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.GetPlacesResponse.FromString, - ) + _registered_method=True) self.AddPlaceAlias = channel.unary_unary( '/labgrid.Coordinator/AddPlaceAlias', request_serializer=labgrid__coordinator__pb2.AddPlaceAliasRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.AddPlaceAliasResponse.FromString, - ) + _registered_method=True) self.DeletePlaceAlias = channel.unary_unary( '/labgrid.Coordinator/DeletePlaceAlias', request_serializer=labgrid__coordinator__pb2.DeletePlaceAliasRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.DeletePlaceAliasResponse.FromString, - ) + _registered_method=True) self.SetPlaceTags = channel.unary_unary( '/labgrid.Coordinator/SetPlaceTags', request_serializer=labgrid__coordinator__pb2.SetPlaceTagsRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.SetPlaceTagsResponse.FromString, - ) + _registered_method=True) self.SetPlaceComment = channel.unary_unary( '/labgrid.Coordinator/SetPlaceComment', request_serializer=labgrid__coordinator__pb2.SetPlaceCommentRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.SetPlaceCommentResponse.FromString, - ) + _registered_method=True) self.AddPlaceMatch = channel.unary_unary( '/labgrid.Coordinator/AddPlaceMatch', request_serializer=labgrid__coordinator__pb2.AddPlaceMatchRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.AddPlaceMatchResponse.FromString, - ) + _registered_method=True) self.DeletePlaceMatch = channel.unary_unary( '/labgrid.Coordinator/DeletePlaceMatch', request_serializer=labgrid__coordinator__pb2.DeletePlaceMatchRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.DeletePlaceMatchResponse.FromString, - ) + _registered_method=True) self.AcquirePlace = channel.unary_unary( '/labgrid.Coordinator/AcquirePlace', request_serializer=labgrid__coordinator__pb2.AcquirePlaceRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.AcquirePlaceResponse.FromString, - ) + _registered_method=True) + self.LeasePlace = channel.unary_unary( + '/labgrid.Coordinator/LeasePlace', + request_serializer=labgrid__coordinator__pb2.LeasePlaceRequest.SerializeToString, + response_deserializer=labgrid__coordinator__pb2.LeasePlaceResponse.FromString, + _registered_method=True) + self.GetLeaseConfig = channel.unary_unary( + '/labgrid.Coordinator/GetLeaseConfig', + request_serializer=labgrid__coordinator__pb2.GetLeaseConfigRequest.SerializeToString, + response_deserializer=labgrid__coordinator__pb2.GetLeaseConfigResponse.FromString, + _registered_method=True) self.ReleasePlace = channel.unary_unary( '/labgrid.Coordinator/ReleasePlace', request_serializer=labgrid__coordinator__pb2.ReleasePlaceRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.ReleasePlaceResponse.FromString, - ) + _registered_method=True) self.AllowPlace = channel.unary_unary( '/labgrid.Coordinator/AllowPlace', request_serializer=labgrid__coordinator__pb2.AllowPlaceRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.AllowPlaceResponse.FromString, - ) + _registered_method=True) self.CreateReservation = channel.unary_unary( '/labgrid.Coordinator/CreateReservation', request_serializer=labgrid__coordinator__pb2.CreateReservationRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.CreateReservationResponse.FromString, - ) + _registered_method=True) self.CancelReservation = channel.unary_unary( '/labgrid.Coordinator/CancelReservation', request_serializer=labgrid__coordinator__pb2.CancelReservationRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.CancelReservationResponse.FromString, - ) + _registered_method=True) self.PollReservation = channel.unary_unary( '/labgrid.Coordinator/PollReservation', request_serializer=labgrid__coordinator__pb2.PollReservationRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.PollReservationResponse.FromString, - ) + _registered_method=True) + self.ExtendLease = channel.unary_unary( + '/labgrid.Coordinator/ExtendLease', + request_serializer=labgrid__coordinator__pb2.ExtendLeaseRequest.SerializeToString, + response_deserializer=labgrid__coordinator__pb2.ExtendLeaseResponse.FromString, + _registered_method=True) self.GetReservations = channel.unary_unary( '/labgrid.Coordinator/GetReservations', request_serializer=labgrid__coordinator__pb2.GetReservationsRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.GetReservationsResponse.FromString, - ) + _registered_method=True) class CoordinatorServicer(object): @@ -181,6 +216,18 @@ def AcquirePlace(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def LeasePlace(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetLeaseConfig(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def ReleasePlace(self, request, context): """Missing associated documentation comment in .proto file.""" context.set_code(grpc.StatusCode.UNIMPLEMENTED) @@ -211,6 +258,12 @@ def PollReservation(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def ExtendLease(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def GetReservations(self, request, context): """Missing associated documentation comment in .proto file.""" context.set_code(grpc.StatusCode.UNIMPLEMENTED) @@ -280,6 +333,16 @@ def add_CoordinatorServicer_to_server(servicer, server): request_deserializer=labgrid__coordinator__pb2.AcquirePlaceRequest.FromString, response_serializer=labgrid__coordinator__pb2.AcquirePlaceResponse.SerializeToString, ), + 'LeasePlace': grpc.unary_unary_rpc_method_handler( + servicer.LeasePlace, + request_deserializer=labgrid__coordinator__pb2.LeasePlaceRequest.FromString, + response_serializer=labgrid__coordinator__pb2.LeasePlaceResponse.SerializeToString, + ), + 'GetLeaseConfig': grpc.unary_unary_rpc_method_handler( + servicer.GetLeaseConfig, + request_deserializer=labgrid__coordinator__pb2.GetLeaseConfigRequest.FromString, + response_serializer=labgrid__coordinator__pb2.GetLeaseConfigResponse.SerializeToString, + ), 'ReleasePlace': grpc.unary_unary_rpc_method_handler( servicer.ReleasePlace, request_deserializer=labgrid__coordinator__pb2.ReleasePlaceRequest.FromString, @@ -305,6 +368,11 @@ def add_CoordinatorServicer_to_server(servicer, server): request_deserializer=labgrid__coordinator__pb2.PollReservationRequest.FromString, response_serializer=labgrid__coordinator__pb2.PollReservationResponse.SerializeToString, ), + 'ExtendLease': grpc.unary_unary_rpc_method_handler( + servicer.ExtendLease, + request_deserializer=labgrid__coordinator__pb2.ExtendLeaseRequest.FromString, + response_serializer=labgrid__coordinator__pb2.ExtendLeaseResponse.SerializeToString, + ), 'GetReservations': grpc.unary_unary_rpc_method_handler( servicer.GetReservations, request_deserializer=labgrid__coordinator__pb2.GetReservationsRequest.FromString, @@ -314,6 +382,7 @@ def add_CoordinatorServicer_to_server(servicer, server): generic_handler = grpc.method_handlers_generic_handler( 'labgrid.Coordinator', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) + server.add_registered_method_handlers('labgrid.Coordinator', rpc_method_handlers) # This class is part of an EXPERIMENTAL API. @@ -331,11 +400,21 @@ def ClientStream(request_iterator, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.stream_stream(request_iterator, target, '/labgrid.Coordinator/ClientStream', + return grpc.experimental.stream_stream( + request_iterator, + target, + '/labgrid.Coordinator/ClientStream', labgrid__coordinator__pb2.ClientInMessage.SerializeToString, labgrid__coordinator__pb2.ClientOutMessage.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def ExporterStream(request_iterator, @@ -348,11 +427,21 @@ def ExporterStream(request_iterator, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.stream_stream(request_iterator, target, '/labgrid.Coordinator/ExporterStream', + return grpc.experimental.stream_stream( + request_iterator, + target, + '/labgrid.Coordinator/ExporterStream', labgrid__coordinator__pb2.ExporterInMessage.SerializeToString, labgrid__coordinator__pb2.ExporterOutMessage.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def AddPlace(request, @@ -365,11 +454,21 @@ def AddPlace(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/AddPlace', + return grpc.experimental.unary_unary( + request, + target, + '/labgrid.Coordinator/AddPlace', labgrid__coordinator__pb2.AddPlaceRequest.SerializeToString, labgrid__coordinator__pb2.AddPlaceResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def DeletePlace(request, @@ -382,11 +481,21 @@ def DeletePlace(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/DeletePlace', + return grpc.experimental.unary_unary( + request, + target, + '/labgrid.Coordinator/DeletePlace', labgrid__coordinator__pb2.DeletePlaceRequest.SerializeToString, labgrid__coordinator__pb2.DeletePlaceResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def GetPlaces(request, @@ -399,11 +508,21 @@ def GetPlaces(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/GetPlaces', + return grpc.experimental.unary_unary( + request, + target, + '/labgrid.Coordinator/GetPlaces', labgrid__coordinator__pb2.GetPlacesRequest.SerializeToString, labgrid__coordinator__pb2.GetPlacesResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def AddPlaceAlias(request, @@ -416,11 +535,21 @@ def AddPlaceAlias(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/AddPlaceAlias', + return grpc.experimental.unary_unary( + request, + target, + '/labgrid.Coordinator/AddPlaceAlias', labgrid__coordinator__pb2.AddPlaceAliasRequest.SerializeToString, labgrid__coordinator__pb2.AddPlaceAliasResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def DeletePlaceAlias(request, @@ -433,11 +562,21 @@ def DeletePlaceAlias(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/DeletePlaceAlias', + return grpc.experimental.unary_unary( + request, + target, + '/labgrid.Coordinator/DeletePlaceAlias', labgrid__coordinator__pb2.DeletePlaceAliasRequest.SerializeToString, labgrid__coordinator__pb2.DeletePlaceAliasResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def SetPlaceTags(request, @@ -450,11 +589,21 @@ def SetPlaceTags(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/SetPlaceTags', + return grpc.experimental.unary_unary( + request, + target, + '/labgrid.Coordinator/SetPlaceTags', labgrid__coordinator__pb2.SetPlaceTagsRequest.SerializeToString, labgrid__coordinator__pb2.SetPlaceTagsResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def SetPlaceComment(request, @@ -467,11 +616,21 @@ def SetPlaceComment(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/SetPlaceComment', + return grpc.experimental.unary_unary( + request, + target, + '/labgrid.Coordinator/SetPlaceComment', labgrid__coordinator__pb2.SetPlaceCommentRequest.SerializeToString, labgrid__coordinator__pb2.SetPlaceCommentResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def AddPlaceMatch(request, @@ -484,11 +643,21 @@ def AddPlaceMatch(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/AddPlaceMatch', + return grpc.experimental.unary_unary( + request, + target, + '/labgrid.Coordinator/AddPlaceMatch', labgrid__coordinator__pb2.AddPlaceMatchRequest.SerializeToString, labgrid__coordinator__pb2.AddPlaceMatchResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def DeletePlaceMatch(request, @@ -501,11 +670,21 @@ def DeletePlaceMatch(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/DeletePlaceMatch', + return grpc.experimental.unary_unary( + request, + target, + '/labgrid.Coordinator/DeletePlaceMatch', labgrid__coordinator__pb2.DeletePlaceMatchRequest.SerializeToString, labgrid__coordinator__pb2.DeletePlaceMatchResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def AcquirePlace(request, @@ -518,11 +697,75 @@ def AcquirePlace(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/AcquirePlace', + return grpc.experimental.unary_unary( + request, + target, + '/labgrid.Coordinator/AcquirePlace', labgrid__coordinator__pb2.AcquirePlaceRequest.SerializeToString, labgrid__coordinator__pb2.AcquirePlaceResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def LeasePlace(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/labgrid.Coordinator/LeasePlace', + labgrid__coordinator__pb2.LeasePlaceRequest.SerializeToString, + labgrid__coordinator__pb2.LeasePlaceResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def GetLeaseConfig(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/labgrid.Coordinator/GetLeaseConfig', + labgrid__coordinator__pb2.GetLeaseConfigRequest.SerializeToString, + labgrid__coordinator__pb2.GetLeaseConfigResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def ReleasePlace(request, @@ -535,11 +778,21 @@ def ReleasePlace(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/ReleasePlace', + return grpc.experimental.unary_unary( + request, + target, + '/labgrid.Coordinator/ReleasePlace', labgrid__coordinator__pb2.ReleasePlaceRequest.SerializeToString, labgrid__coordinator__pb2.ReleasePlaceResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def AllowPlace(request, @@ -552,11 +805,21 @@ def AllowPlace(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/AllowPlace', + return grpc.experimental.unary_unary( + request, + target, + '/labgrid.Coordinator/AllowPlace', labgrid__coordinator__pb2.AllowPlaceRequest.SerializeToString, labgrid__coordinator__pb2.AllowPlaceResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def CreateReservation(request, @@ -569,11 +832,21 @@ def CreateReservation(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/CreateReservation', + return grpc.experimental.unary_unary( + request, + target, + '/labgrid.Coordinator/CreateReservation', labgrid__coordinator__pb2.CreateReservationRequest.SerializeToString, labgrid__coordinator__pb2.CreateReservationResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def CancelReservation(request, @@ -586,11 +859,21 @@ def CancelReservation(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/CancelReservation', + return grpc.experimental.unary_unary( + request, + target, + '/labgrid.Coordinator/CancelReservation', labgrid__coordinator__pb2.CancelReservationRequest.SerializeToString, labgrid__coordinator__pb2.CancelReservationResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def PollReservation(request, @@ -603,11 +886,48 @@ def PollReservation(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/PollReservation', + return grpc.experimental.unary_unary( + request, + target, + '/labgrid.Coordinator/PollReservation', labgrid__coordinator__pb2.PollReservationRequest.SerializeToString, labgrid__coordinator__pb2.PollReservationResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def ExtendLease(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/labgrid.Coordinator/ExtendLease', + labgrid__coordinator__pb2.ExtendLeaseRequest.SerializeToString, + labgrid__coordinator__pb2.ExtendLeaseResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def GetReservations(request, @@ -620,8 +940,18 @@ def GetReservations(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/GetReservations', + return grpc.experimental.unary_unary( + request, + target, + '/labgrid.Coordinator/GetReservations', labgrid__coordinator__pb2.GetReservationsRequest.SerializeToString, labgrid__coordinator__pb2.GetReservationsResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) diff --git a/labgrid/remote/proto/labgrid-coordinator.proto b/labgrid/remote/proto/labgrid-coordinator.proto index e0585f7e1..780cb9107 100644 --- a/labgrid/remote/proto/labgrid-coordinator.proto +++ b/labgrid/remote/proto/labgrid-coordinator.proto @@ -1,5 +1,7 @@ syntax = "proto3"; +import "google/protobuf/timestamp.proto"; + package labgrid; service Coordinator { @@ -27,6 +29,10 @@ service Coordinator { rpc AcquirePlace(AcquirePlaceRequest) returns (AcquirePlaceResponse) {} + rpc LeasePlace(LeasePlaceRequest) returns (LeasePlaceResponse); + + rpc GetLeaseConfig(GetLeaseConfigRequest) returns (GetLeaseConfigResponse); + rpc ReleasePlace(ReleasePlaceRequest) returns (ReleasePlaceResponse) {} rpc AllowPlace(AllowPlaceRequest) returns (AllowPlaceResponse) {} @@ -37,6 +43,8 @@ service Coordinator { rpc PollReservation(PollReservationRequest) returns (PollReservationResponse) {} + rpc ExtendLease(ExtendLeaseRequest) returns (ExtendLeaseResponse); + rpc GetReservations(GetReservationsRequest) returns (GetReservationsResponse) {} } @@ -125,6 +133,7 @@ message ExporterOutMessage { oneof kind { Hello hello = 1; ExporterSetAcquiredRequest set_acquired_request = 2; + ExporterLeaseExtendedRequest lease_extended_request = 3; }; }; @@ -134,6 +143,13 @@ message ExporterSetAcquiredRequest { optional string place_name = 3; }; +message ExporterLeaseExtendedRequest { + string group_name = 1; + string resource_name = 2; + optional string place_name = 3; + uint64 duration = 4; +} + message AddPlaceRequest { string name = 1; }; @@ -234,6 +250,29 @@ message AcquirePlaceRequest { message AcquirePlaceResponse { }; +message LeasePlaceRequest { + string placename = 1; +}; + +message LeasePlaceResponse { +}; + +message ExtendLeaseRequest { + string token = 1; +}; + +message ExtendLeaseResponse { + Reservation reservation = 1; +}; + +message GetLeaseConfigRequest {} + +message GetLeaseConfigResponse { + uint32 default_lease_duration = 1; + uint32 default_extend_duration = 2; + uint32 max_lease_duration = 3; +} + message ReleasePlaceRequest { string placename = 1; optional string fromuser = 2; @@ -272,6 +311,7 @@ message Reservation { map allocations = 6; double created = 7; double timeout = 8; + google.protobuf.Timestamp lease_start_time = 9; }; message CancelReservationRequest { diff --git a/man/labgrid-client.1 b/man/labgrid-client.1 index dfc95b2e8..d34598424 100644 --- a/man/labgrid-client.1 +++ b/man/labgrid-client.1 @@ -377,6 +377,31 @@ output filename .B \-\-format {shell,shell\-export,json} output format (default: shell\-export) .UNINDENT +.SS labgrid\-client extend +.sp +extend a lease by the coordinator default duration +.INDENT 0.0 +.INDENT 3.5 +.sp +.EX +usage: labgrid\-client extend [\-\-keepalive] [\-q] [token] +.EE +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B token +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-keepalive +keep extending the lease automatically using coordinator policy +.UNINDENT +.INDENT 0.0 +.TP +.B \-q, \-\-quiet +do not print lease status on each extension +.UNINDENT .SS labgrid\-client fastboot .sp run fastboot @@ -476,6 +501,22 @@ action .B name optional resource name .UNINDENT +.SS labgrid\-client lease +.sp +lease a place (time\-limited, requires extension) +.INDENT 0.0 +.INDENT 3.5 +.sp +.EX +usage: labgrid\-client lease [\-\-allow\-unmatched] +.EE +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-allow\-unmatched +allow missing resources for matches when locking the place +.UNINDENT .SS labgrid\-client monitor .sp monitor events from the coordinator @@ -1177,6 +1218,22 @@ exporter/group/cls/name, exporter is the name of the exporting machine, group is a name defined within the exporter, cls is the class of the exported resource and name is its name. Wild cards in match patterns are explicitly allowed, * matches anything. +.SH LEASES +.sp +A lease is a time\-limited acquisition of a place. +.sp +Leases are always associated with a reservation. The reserved place is referenced +using \fB\-p +\fP\&. To keep a lease active, the reservation must be extended using +the \fBextend\fP command. +.sp +Use \fBlabgrid\-client extend\fP to refresh the lease once, or +\fBlabgrid\-client extend \-\-keepalive\fP to keep it alive automatically. +.sp +If a lease extension fails, the coordinator cancels the lease and releases the +place to avoid leaving the system in an inconsistent state. +.sp +If the reservation expires, the coordinator automatically releases the leased +place. .SH ADDING NAMED RESOURCES .sp If a target contains multiple Resources of the same type, named matches need to @@ -1221,6 +1278,36 @@ $ labgrid\-client \-p console .UNINDENT .UNINDENT .sp +Lease a place using a reservation: +.INDENT 0.0 +.INDENT 3.5 +.sp +.EX +$ labgrid\-client reserve board=imx8 \-\-shell +$ labgrid\-client wait +$ labgrid\-client \-p + lease +.EE +.UNINDENT +.UNINDENT +.sp +Extend the lease to keep it alive: +.INDENT 0.0 +.INDENT 3.5 +.sp +.EX +# refresh once by passing the token explicitly +$ labgrid\-client extend ABC123 + +# or take the token from the environment (LG_TOKEN) +$ export LG_TOKEN=ABC123 +$ labgrid\-client extend + +# keep the lease alive automatically +$ labgrid\-client extend \-\-keepalive +.EE +.UNINDENT +.UNINDENT +.sp Add all resources with the group \(dqexample\-group\(dq to the place example\-place: .INDENT 0.0 .INDENT 3.5 diff --git a/tests/conftest.py b/tests/conftest.py index 3bb2641f9..f22b018d0 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,7 +2,7 @@ from signal import SIGTERM import sys import threading - +import os import pytest import pexpect @@ -142,6 +142,9 @@ def start(self): class Coordinator(LabgridComponent): + def __init__(self, cwd, env=None): + super().__init__(cwd) + self.env = env def start(self): assert self.spawn is None assert self.reader is None @@ -149,7 +152,8 @@ def start(self): self.spawn = pexpect.spawn( 'python -m labgrid.remote.coordinator', logfile=Prefixer(sys.stdout.buffer, 'coordinator'), - cwd=self.cwd) + cwd=self.cwd, + env=self.env) try: self.spawn.expect('Coordinator ready') except Exception as e: @@ -197,7 +201,12 @@ def serial_driver_no_name(target, serial_port, mocker): @pytest.fixture(scope='function') def coordinator(tmpdir): - coordinator = Coordinator(tmpdir) + env = os.environ.copy() + env["LG_DEFAULT_LEASE_DURATION"] = "5" + env["LG_DEFAULT_EXTEND_DURATION"] = "2" + env["LG_MAX_LEASE_DURATION"] = "20" + env["LG_COORDINATOR_POLL_INTERVAL"] = "1" + coordinator = Coordinator(tmpdir, env=env) coordinator.start() yield coordinator diff --git a/tests/test_client.py b/tests/test_client.py index 8d2cc1c9f..c60bd12f3 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -5,6 +5,22 @@ import pytest import pexpect + +def reserve_and_get_token(args="board=123board name=test"): + with pexpect.spawn(f'python -m labgrid.remote.client reserve --shell {args}') as spawn: + spawn.expect(pexpect.EOF) + spawn.close() + assert spawn.exitstatus == 0, spawn.before.strip() + + m = re.search( + rb"^export LG_TOKEN=(\S+)$", + spawn.before.replace(b"\r\n", b"\n"), + re.MULTILINE, + ) + assert m is not None, spawn.before.strip() + return m.group(1) + + def test_startup(coordinator): pass @@ -357,13 +373,7 @@ def test_resource_conflict(place_acquire, tmpdir): assert spawn.exitstatus == 0, spawn.before.strip() def test_reservation(place_acquire, tmpdir): - with pexpect.spawn('python -m labgrid.remote.client reserve --shell board=123board name=test') as spawn: - spawn.expect(pexpect.EOF) - spawn.close() - assert spawn.exitstatus == 0, spawn.before.strip() - m = re.search(rb"^export LG_TOKEN=(\S+)$", spawn.before.replace(b'\r\n', b'\n'), re.MULTILINE) - assert m is not None, spawn.before.strip() - token = m.group(1) + token = reserve_and_get_token() env = os.environ.copy() env['LG_TOKEN'] = token.decode('ASCII') @@ -616,3 +626,173 @@ def test_same_name_resources(place, exporter, tmpdir): spawn.expect(pexpect.EOF) spawn.close() assert spawn.exitstatus == 0, spawn.before.strip() + + +def test_place_lease(place): + token = reserve_and_get_token() + + env = os.environ.copy() + env["LG_TOKEN"] = token.decode("ascii") + + with pexpect.spawn('python -m labgrid.remote.client -p + lease', env=env) as spawn: + spawn.expect("leased place test") + spawn.expect(pexpect.EOF) + spawn.close() + assert spawn.exitstatus == 0, spawn.before.strip() + + with pexpect.spawn('python -m labgrid.remote.client reservations') as spawn: + spawn.expect(pexpect.EOF) + spawn.close() + assert spawn.exitstatus == 0, spawn.before.strip() + assert token in spawn.before, spawn.before.strip() + assert b"leased" in spawn.before, spawn.before.strip() + + with pexpect.spawn('python -m labgrid.remote.client -p + show', env=env) as spawn: + spawn.expect(pexpect.EOF) + spawn.close() + assert spawn.exitstatus == 0, spawn.before.strip() + assert token in spawn.before, spawn.before.strip() + assert b"acquired: None" not in spawn.before + assert token in spawn.before + +def test_place_lease_timeout(place): + token = reserve_and_get_token() + + env = os.environ.copy() + env["LG_TOKEN"] = token.decode("ascii") + + with pexpect.spawn('python -m labgrid.remote.client -p + lease', env=env) as spawn: + spawn.expect("leased place test") + spawn.expect(pexpect.EOF) + spawn.close() + assert spawn.exitstatus == 0, spawn.before.strip() + + time.sleep(7) + + with pexpect.spawn('python -m labgrid.remote.client -p test show') as spawn: + spawn.expect(pexpect.EOF) + spawn.close() + assert spawn.exitstatus == 0, spawn.before.strip() + assert b"acquired: None" in spawn.before, spawn.before.strip() + + with pexpect.spawn('python -m labgrid.remote.client reservations') as spawn: + spawn.expect(pexpect.EOF) + spawn.close() + assert spawn.exitstatus == 0, spawn.before.strip() + assert token in spawn.before, spawn.before.strip() + assert b"expired" in spawn.before, spawn.before.strip() + +def test_place_lease_then_release(place): + token = reserve_and_get_token() + + env = os.environ.copy() + env["LG_TOKEN"] = token.decode("ascii") + + with pexpect.spawn('python -m labgrid.remote.client -p + lease', env=env) as spawn: + spawn.expect("leased place test") + spawn.expect(pexpect.EOF) + spawn.close() + assert spawn.exitstatus == 0, spawn.before.strip() + + with pexpect.spawn('python -m labgrid.remote.client -p + release', env=env) as spawn: + spawn.expect("released place test") + spawn.expect(pexpect.EOF) + spawn.close() + assert spawn.exitstatus == 0, spawn.before.strip() + + with pexpect.spawn('python -m labgrid.remote.client -p test show') as spawn: + spawn.expect(pexpect.EOF) + spawn.close() + assert spawn.exitstatus == 0, spawn.before.strip() + assert b"acquired: None" in spawn.before, spawn.before.strip() + + with pexpect.spawn('python -m labgrid.remote.client reservations') as spawn: + spawn.expect(pexpect.EOF) + spawn.close() + assert spawn.exitstatus == 0, spawn.before.strip() + assert token in spawn.before, spawn.before.strip() + assert b"expired" in spawn.before, spawn.before.strip() + +def test_place_lease_then_cancel_reservation(place): + token = reserve_and_get_token() + + env = os.environ.copy() + env["LG_TOKEN"] = token.decode("ascii") + + with pexpect.spawn('python -m labgrid.remote.client -p + lease', env=env) as spawn: + spawn.expect("leased place test") + spawn.expect(pexpect.EOF) + spawn.close() + assert spawn.exitstatus == 0, spawn.before.strip() + + with pexpect.spawn('python -m labgrid.remote.client cancel-reservation', env=env) as spawn: + spawn.expect(pexpect.EOF) + spawn.close() + assert spawn.exitstatus == 0, spawn.before.strip() + + with pexpect.spawn('python -m labgrid.remote.client -p test show') as spawn: + spawn.expect(pexpect.EOF) + spawn.close() + assert spawn.exitstatus == 0, spawn.before.strip() + assert b"acquired: None" in spawn.before, spawn.before.strip() + + with pexpect.spawn('python -m labgrid.remote.client reservations') as spawn: + spawn.expect(pexpect.EOF) + spawn.close() + assert spawn.exitstatus == 0, spawn.before.strip() + assert token not in spawn.before, spawn.before.strip() + +def test_place_lease_without_reservation_fails(place): + with pexpect.spawn('python -m labgrid.remote.client -p test lease') as spawn: + spawn.expect("not reserved") + spawn.expect(pexpect.EOF) + spawn.close() + assert spawn.exitstatus != 0, spawn.before.strip() + +def test_place_lease_extend_updates_timeout(place, exporter): + with pexpect.spawn( + 'python -m labgrid.remote.client -p test add-match testhost/Testport/NetworkSerialPort' + ) as spawn: + spawn.expect(pexpect.EOF) + spawn.close() + assert spawn.exitstatus == 0, spawn.before.strip() + + token = reserve_and_get_token() + + env = os.environ.copy() + env["LG_TOKEN"] = token.decode("ascii") + + with pexpect.spawn('python -m labgrid.remote.client -p + lease', env=env) as spawn: + spawn.expect("leased place test") + spawn.expect(pexpect.EOF) + spawn.close() + assert spawn.exitstatus == 0, spawn.before.strip() + + with pexpect.spawn('python -m labgrid.remote.client reservations') as spawn: + spawn.expect(pexpect.EOF) + spawn.close() + assert spawn.exitstatus == 0, spawn.before.strip() + assert token in spawn.before, spawn.before.strip() + assert b"leased" in spawn.before, spawn.before.strip() + m = re.search(rb"timeout: (.+)", spawn.before.replace(b'\r\n', b'\n')) + assert m is not None, spawn.before.strip() + timeout_before = m.group(1) + + with pexpect.spawn('python -m labgrid.remote.client extend', env=env) as spawn: + spawn.expect("extended lease") + spawn.expect(pexpect.EOF) + spawn.close() + assert spawn.exitstatus == 0, spawn.before.strip() + + with pexpect.spawn('python -m labgrid.remote.client reservations') as spawn: + spawn.expect(pexpect.EOF) + spawn.close() + assert spawn.exitstatus == 0, spawn.before.strip() + assert token in spawn.before, spawn.before.strip() + assert b"leased" in spawn.before, spawn.before.strip() + m = re.search(rb"timeout: (.+)", spawn.before.replace(b'\r\n', b'\n')) + assert m is not None, spawn.before.strip() + timeout_after = m.group(1) + + assert timeout_after != timeout_before + assert timeout_after > timeout_before From 357ceca29b0bc25d0f93a3ca075badbc0d701138 Mon Sep 17 00:00:00 2001 From: Asher Pemberton Date: Sun, 14 Jun 2026 21:03:33 +0300 Subject: [PATCH 2/3] remote/coordinator: add exporter notification for lease start Send a dedicated lease-start request to exporters when a place is leased, including the coordinator default lease duration. This keeps lease acquisition separate from normal acquire requests. Signed-off-by: Asher Pemberton Reviewed-by: Asher Pemberton # gatekeeper Co-authored-by: Idan Saadon --- labgrid/remote/coordinator.py | 102 ++++- labgrid/remote/exporter.py | 46 ++ .../generated/labgrid_coordinator_pb2.py | 242 +++++------ .../generated/labgrid_coordinator_pb2.pyi | 25 +- .../generated/labgrid_coordinator_pb2_grpc.py | 399 ++++-------------- .../remote/proto/labgrid-coordinator.proto | 8 + 6 files changed, 371 insertions(+), 451 deletions(-) diff --git a/labgrid/remote/coordinator.py b/labgrid/remote/coordinator.py index 6f098f5d9..c1730a537 100644 --- a/labgrid/remote/coordinator.py +++ b/labgrid/remote/coordinator.py @@ -206,7 +206,11 @@ async def wait(self): self.expired = True -class ExporterError(Exception): +class CoordinatorError(Exception): + pass + + +class ExporterError(CoordinatorError): pass @@ -504,6 +508,8 @@ async def request_task(): out_msg = labgrid_coordinator_pb2.ExporterOutMessage() if cmd.kind == "set_acquired_request": out_msg.set_acquired_request.CopyFrom(cmd.request) + elif cmd.kind == "lease_started_request": + out_msg.lease_started_request.CopyFrom(cmd.request) elif cmd.kind == "lease_extended_request": out_msg.lease_extended_request.CopyFrom(cmd.request) else: @@ -686,6 +692,27 @@ async def _acquire_resource(self, place, resource): if resource.acquired != place.name: logging.warning("resource %s not acquired by this place after acquire request", resource) + async def _lease_resource(self, place, resource, duration): + assert self.lock.locked() + + # this triggers an update from the exporter which is published + # to the clients + request = labgrid_coordinator_pb2.ExporterLeaseStartedRequest() + request.group_name = resource.path[1] + request.resource_name = resource.path[3] + request.place_name = place.name + request.duration = duration + cmd = ExporterCommand("lease_started_request", request) + self.get_exporter_by_name(resource.path[0]).queue.put_nowait(cmd) + try: + await cmd.wait() + except asyncio.TimeoutError as e: + raise ExporterError("timed out waiting for exporter while leasing resource") from e + if not cmd.response.success: + raise ExporterError(cmd.response.reason or "exporter returned failure without a reason") + if resource.acquired != place.name: + logging.warning("resource %s not acquired by this place after lease request", resource) + async def _acquire_resources(self, place, resources): assert self.lock.locked() @@ -720,6 +747,47 @@ async def _acquire_resources(self, place, resources): return True + async def _lease_resources(self, place, resources, duration): + assert self.lock.locked() + + resources = resources.copy() # we may modify the list + # all resources need to be free + for resource in resources: + if resource.acquired: + raise CoordinatorError(f"{resource} is already acquired by {resource.acquired}") + + for otherplace in self.places.values(): + for oldres in otherplace.acquired_resources: + if resource.path == oldres.path: + logging.info( + "Conflicting orphaned resource %s for lease request for place %s", oldres, place.name + ) + raise CoordinatorError( + f"conflicting orphaned resource {oldres} for lease request for place {place.name}" + ) + + # lease resources + leased = [] + try: + for resource in resources: + await self._lease_resource(place, resource, duration) + leased.append(resource) + except Exception as e: + logging.exception("failed to lease %s", resource) + # cleanup + try: + await self._release_resources(place, leased) + except CoordinatorError: + logging.exception("failed to release leased resources during lease cleanup") + if isinstance(e, CoordinatorError): + raise + raise CoordinatorError(f"failed to lease {resource}") from e + + for resource in resources: + place.acquired_resources.append(resource) + + return True + async def _notify_lease_extended_resource(self, place, resource, duration): assert self.lock.locked() @@ -917,6 +985,24 @@ async def _acquire_place_resources(self, place, owner): return False return True + async def _lease_place_resources(self, place, owner, duration): + assert self.lock.locked() + + place.acquired = owner + resources = [] + for _, session in sorted(self.exporters.items()): + for _, group in sorted(session.groups.items()): + for _, resource in sorted(group.items()): + if place.hasmatch(resource.path): + resources.append(resource) + + try: + await self._lease_resources(place, resources, duration) + except CoordinatorError: + place.acquired = None + raise + return True + @locked async def AcquirePlace(self, request, context): peer = context.peer() @@ -956,7 +1042,10 @@ async def AcquirePlace(self, request, context): @locked async def LeasePlace(self, request, context): peer = context.peer() - username = self.clients[peer].name + try: + username = self.clients[peer].name + except KeyError: + await context.abort(grpc.StatusCode.FAILED_PRECONDITION, f"Peer {peer} does not have a valid session") name = request.placename place = self.places.get(name) @@ -977,8 +1066,13 @@ async def LeasePlace(self, request, context): f"Place {name} is reserved by a different user", ) - if not await self._acquire_place_resources(place, username): - await context.abort(grpc.StatusCode.FAILED_PRECONDITION, f"Failed to lease resources for place {name}") + try: + await self._lease_place_resources(place, username, self.default_lease_duration) + except CoordinatorError as e: + message = f"Failed to lease resources for place {name}" + if str(e): + message += f": {e}" + await context.abort(grpc.StatusCode.FAILED_PRECONDITION, message) now = time.time() res.state = ReservationState.leased diff --git a/labgrid/remote/exporter.py b/labgrid/remote/exporter.py index b47d52469..94d9ff6eb 100755 --- a/labgrid/remote/exporter.py +++ b/labgrid/remote/exporter.py @@ -936,6 +936,29 @@ async def message_pump(self): logging.debug("queuing %s", in_message) self.out_queue.put_nowait(in_message) logging.debug("queued %s", in_message) + elif kind == "lease_started_request": + logging.debug("lease started request") + success = False + reason = None + try: + await self.lease_started( + out_message.lease_started_request.group_name, + out_message.lease_started_request.resource_name, + out_message.lease_started_request.place_name, + out_message.lease_started_request.duration, + ) + success = True + except (BrokenResourceError, InvalidResourceRequestError, UnknownResourceError) as e: + reason = e.args[0] + logging.warning("lease_started_request failed: %s", reason) + finally: + in_message = labgrid_coordinator_pb2.ExporterInMessage() + in_message.response.success = success + if reason: + in_message.response.reason = reason + logging.debug("queuing %s", in_message) + self.out_queue.put_nowait(in_message) + logging.debug("queued %s", in_message) elif kind == "lease_extended_request": logging.debug("lease extended request") success = False @@ -1000,6 +1023,29 @@ async def acquire(self, group_name, resource_name, place_name): finally: await self.update_resource(group_name, resource_name) + async def lease_started(self, group_name, resource_name, place_name, duration): + resource = self.groups.get(group_name, {}).get(resource_name) + if resource is None: + raise UnknownResourceError( + f"lease start request for unknown resource {group_name}/{resource_name} by {place_name}" + ) + + if resource.acquired: + raise InvalidResourceRequestError( + f"Resource {group_name}/{resource_name} is already acquired by {resource.acquired}" + ) + + logging.info( + "received lease start for %s/%s by %s seconds", + group_name, + resource_name, + duration, + ) + try: + resource.acquire(place_name) + finally: + await self.update_resource(group_name, resource_name) + async def release(self, group_name, resource_name): resource = self.groups.get(group_name, {}).get(resource_name) if resource is None: diff --git a/labgrid/remote/generated/labgrid_coordinator_pb2.py b/labgrid/remote/generated/labgrid_coordinator_pb2.py index 8b73871df..328810494 100644 --- a/labgrid/remote/generated/labgrid_coordinator_pb2.py +++ b/labgrid/remote/generated/labgrid_coordinator_pb2.py @@ -1,22 +1,12 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE # source: labgrid-coordinator.proto -# Protobuf Python Version: 6.31.1 +# Protobuf Python Version: 4.25.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 6, - 31, - 1, - '', - 'labgrid-coordinator.proto' -) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -25,28 +15,28 @@ from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19labgrid-coordinator.proto\x12\x07labgrid\x1a\x1fgoogle/protobuf/timestamp.proto\"\x8a\x01\n\x0f\x43lientInMessage\x12\x1d\n\x04sync\x18\x01 \x01(\x0b\x32\r.labgrid.SyncH\x00\x12\'\n\x07startup\x18\x02 \x01(\x0b\x32\x14.labgrid.StartupDoneH\x00\x12\'\n\tsubscribe\x18\x03 \x01(\x0b\x32\x12.labgrid.SubscribeH\x00\x42\x06\n\x04kind\"\x12\n\x04Sync\x12\n\n\x02id\x18\x01 \x01(\x04\",\n\x0bStartupDone\x12\x0f\n\x07version\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"r\n\tSubscribe\x12\x1b\n\x0eis_unsubscribe\x18\x01 \x01(\x08H\x01\x88\x01\x01\x12\x14\n\nall_places\x18\x02 \x01(\x08H\x00\x12\x17\n\rall_resources\x18\x03 \x01(\x08H\x00\x42\x06\n\x04kindB\x11\n\x0f_is_unsubscribe\"g\n\x10\x43lientOutMessage\x12 \n\x04sync\x18\x01 \x01(\x0b\x32\r.labgrid.SyncH\x00\x88\x01\x01\x12(\n\x07updates\x18\x02 \x03(\x0b\x32\x17.labgrid.UpdateResponseB\x07\n\x05_sync\"\xa5\x01\n\x0eUpdateResponse\x12%\n\x08resource\x18\x01 \x01(\x0b\x32\x11.labgrid.ResourceH\x00\x12.\n\x0c\x64\x65l_resource\x18\x02 \x01(\x0b\x32\x16.labgrid.Resource.PathH\x00\x12\x1f\n\x05place\x18\x03 \x01(\x0b\x32\x0e.labgrid.PlaceH\x00\x12\x13\n\tdel_place\x18\x04 \x01(\tH\x00\x42\x06\n\x04kind\"\x9a\x01\n\x11\x45xporterInMessage\x12%\n\x08resource\x18\x01 \x01(\x0b\x32\x11.labgrid.ResourceH\x00\x12\'\n\x07startup\x18\x02 \x01(\x0b\x32\x14.labgrid.StartupDoneH\x00\x12-\n\x08response\x18\x03 \x01(\x0b\x32\x19.labgrid.ExporterResponseH\x00\x42\x06\n\x04kind\"\x9e\x03\n\x08Resource\x12$\n\x04path\x18\x01 \x01(\x0b\x32\x16.labgrid.Resource.Path\x12\x0b\n\x03\x63ls\x18\x02 \x01(\t\x12-\n\x06params\x18\x03 \x03(\x0b\x32\x1d.labgrid.Resource.ParamsEntry\x12+\n\x05\x65xtra\x18\x04 \x03(\x0b\x32\x1c.labgrid.Resource.ExtraEntry\x12\x10\n\x08\x61\x63quired\x18\x05 \x01(\t\x12\r\n\x05\x61vail\x18\x06 \x01(\x08\x1a_\n\x04Path\x12\x1a\n\rexporter_name\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x12\n\ngroup_name\x18\x02 \x01(\t\x12\x15\n\rresource_name\x18\x03 \x01(\tB\x10\n\x0e_exporter_name\x1a@\n\x0bParamsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12 \n\x05value\x18\x02 \x01(\x0b\x32\x11.labgrid.MapValue:\x02\x38\x01\x1a?\n\nExtraEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12 \n\x05value\x18\x02 \x01(\x0b\x32\x11.labgrid.MapValue:\x02\x38\x01\"\x82\x01\n\x08MapValue\x12\x14\n\nbool_value\x18\x01 \x01(\x08H\x00\x12\x13\n\tint_value\x18\x02 \x01(\x03H\x00\x12\x14\n\nuint_value\x18\x03 \x01(\x04H\x00\x12\x15\n\x0b\x66loat_value\x18\x04 \x01(\x01H\x00\x12\x16\n\x0cstring_value\x18\x05 \x01(\tH\x00\x42\x06\n\x04kind\"C\n\x10\x45xporterResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x13\n\x06reason\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_reason\"\x18\n\x05Hello\x12\x0f\n\x07version\x18\x01 \x01(\t\"\xcb\x01\n\x12\x45xporterOutMessage\x12\x1f\n\x05hello\x18\x01 \x01(\x0b\x32\x0e.labgrid.HelloH\x00\x12\x43\n\x14set_acquired_request\x18\x02 \x01(\x0b\x32#.labgrid.ExporterSetAcquiredRequestH\x00\x12G\n\x16lease_extended_request\x18\x03 \x01(\x0b\x32%.labgrid.ExporterLeaseExtendedRequestH\x00\x42\x06\n\x04kind\"o\n\x1a\x45xporterSetAcquiredRequest\x12\x12\n\ngroup_name\x18\x01 \x01(\t\x12\x15\n\rresource_name\x18\x02 \x01(\t\x12\x17\n\nplace_name\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\r\n\x0b_place_name\"\x83\x01\n\x1c\x45xporterLeaseExtendedRequest\x12\x12\n\ngroup_name\x18\x01 \x01(\t\x12\x15\n\rresource_name\x18\x02 \x01(\t\x12\x17\n\nplace_name\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x10\n\x08\x64uration\x18\x04 \x01(\x04\x42\r\n\x0b_place_name\"\x1f\n\x0f\x41\x64\x64PlaceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x12\n\x10\x41\x64\x64PlaceResponse\"\"\n\x12\x44\x65letePlaceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x15\n\x13\x44\x65letePlaceResponse\"\x12\n\x10GetPlacesRequest\"3\n\x11GetPlacesResponse\x12\x1e\n\x06places\x18\x01 \x03(\x0b\x32\x0e.labgrid.Place\"\xd2\x02\n\x05Place\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07\x61liases\x18\x02 \x03(\t\x12\x0f\n\x07\x63omment\x18\x03 \x01(\t\x12&\n\x04tags\x18\x04 \x03(\x0b\x32\x18.labgrid.Place.TagsEntry\x12\'\n\x07matches\x18\x05 \x03(\x0b\x32\x16.labgrid.ResourceMatch\x12\x15\n\x08\x61\x63quired\x18\x06 \x01(\tH\x00\x88\x01\x01\x12\x1a\n\x12\x61\x63quired_resources\x18\x07 \x03(\t\x12\x0f\n\x07\x61llowed\x18\x08 \x03(\t\x12\x0f\n\x07\x63reated\x18\t \x01(\x01\x12\x0f\n\x07\x63hanged\x18\n \x01(\x01\x12\x18\n\x0breservation\x18\x0b \x01(\tH\x01\x88\x01\x01\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x0b\n\t_acquiredB\x0e\n\x0c_reservation\"y\n\rResourceMatch\x12\x10\n\x08\x65xporter\x18\x01 \x01(\t\x12\r\n\x05group\x18\x02 \x01(\t\x12\x0b\n\x03\x63ls\x18\x03 \x01(\t\x12\x11\n\x04name\x18\x04 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06rename\x18\x05 \x01(\tH\x01\x88\x01\x01\x42\x07\n\x05_nameB\t\n\x07_rename\"8\n\x14\x41\x64\x64PlaceAliasRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\r\n\x05\x61lias\x18\x02 \x01(\t\"\x17\n\x15\x41\x64\x64PlaceAliasResponse\";\n\x17\x44\x65letePlaceAliasRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\r\n\x05\x61lias\x18\x02 \x01(\t\"\x1a\n\x18\x44\x65letePlaceAliasResponse\"\x8b\x01\n\x13SetPlaceTagsRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\x34\n\x04tags\x18\x02 \x03(\x0b\x32&.labgrid.SetPlaceTagsRequest.TagsEntry\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x16\n\x14SetPlaceTagsResponse\"<\n\x16SetPlaceCommentRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\x0f\n\x07\x63omment\x18\x02 \x01(\t\"\x19\n\x17SetPlaceCommentResponse\"Z\n\x14\x41\x64\x64PlaceMatchRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\x0f\n\x07pattern\x18\x02 \x01(\t\x12\x13\n\x06rename\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_rename\"\x17\n\x15\x41\x64\x64PlaceMatchResponse\"]\n\x17\x44\x65letePlaceMatchRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\x0f\n\x07pattern\x18\x02 \x01(\t\x12\x13\n\x06rename\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_rename\"\x1a\n\x18\x44\x65letePlaceMatchResponse\"(\n\x13\x41\x63quirePlaceRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\"\x16\n\x14\x41\x63quirePlaceResponse\"&\n\x11LeasePlaceRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\"\x14\n\x12LeasePlaceResponse\"#\n\x12\x45xtendLeaseRequest\x12\r\n\x05token\x18\x01 \x01(\t\"@\n\x13\x45xtendLeaseResponse\x12)\n\x0breservation\x18\x01 \x01(\x0b\x32\x14.labgrid.Reservation\"\x17\n\x15GetLeaseConfigRequest\"u\n\x16GetLeaseConfigResponse\x12\x1e\n\x16\x64\x65\x66\x61ult_lease_duration\x18\x01 \x01(\r\x12\x1f\n\x17\x64\x65\x66\x61ult_extend_duration\x18\x02 \x01(\r\x12\x1a\n\x12max_lease_duration\x18\x03 \x01(\r\"L\n\x13ReleasePlaceRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\x15\n\x08\x66romuser\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0b\n\t_fromuser\"\x16\n\x14ReleasePlaceResponse\"4\n\x11\x41llowPlaceRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\x0c\n\x04user\x18\x02 \x01(\t\"\x14\n\x12\x41llowPlaceResponse\"\xb6\x01\n\x18\x43reateReservationRequest\x12?\n\x07\x66ilters\x18\x01 \x03(\x0b\x32..labgrid.CreateReservationRequest.FiltersEntry\x12\x0c\n\x04prio\x18\x02 \x01(\x01\x1aK\n\x0c\x46iltersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12*\n\x05value\x18\x02 \x01(\x0b\x32\x1b.labgrid.Reservation.Filter:\x02\x38\x01\"F\n\x19\x43reateReservationResponse\x12)\n\x0breservation\x18\x01 \x01(\x0b\x32\x14.labgrid.Reservation\"\x83\x04\n\x0bReservation\x12\r\n\x05owner\x18\x01 \x01(\t\x12\r\n\x05token\x18\x02 \x01(\t\x12\r\n\x05state\x18\x03 \x01(\x05\x12\x0c\n\x04prio\x18\x04 \x01(\x01\x12\x32\n\x07\x66ilters\x18\x05 \x03(\x0b\x32!.labgrid.Reservation.FiltersEntry\x12:\n\x0b\x61llocations\x18\x06 \x03(\x0b\x32%.labgrid.Reservation.AllocationsEntry\x12\x0f\n\x07\x63reated\x18\x07 \x01(\x01\x12\x0f\n\x07timeout\x18\x08 \x01(\x01\x12\x34\n\x10lease_start_time\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x1ap\n\x06\x46ilter\x12\x37\n\x06\x66ilter\x18\x01 \x03(\x0b\x32\'.labgrid.Reservation.Filter.FilterEntry\x1a-\n\x0b\x46ilterEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1aK\n\x0c\x46iltersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12*\n\x05value\x18\x02 \x01(\x0b\x32\x1b.labgrid.Reservation.Filter:\x02\x38\x01\x1a\x32\n\x10\x41llocationsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\")\n\x18\x43\x61ncelReservationRequest\x12\r\n\x05token\x18\x01 \x01(\t\"\x1b\n\x19\x43\x61ncelReservationResponse\"\'\n\x16PollReservationRequest\x12\r\n\x05token\x18\x01 \x01(\t\"D\n\x17PollReservationResponse\x12)\n\x0breservation\x18\x01 \x01(\x0b\x32\x14.labgrid.Reservation\"E\n\x17GetReservationsResponse\x12*\n\x0creservations\x18\x01 \x03(\x0b\x32\x14.labgrid.Reservation\"\x18\n\x16GetReservationsRequest2\xb6\r\n\x0b\x43oordinator\x12I\n\x0c\x43lientStream\x12\x18.labgrid.ClientInMessage\x1a\x19.labgrid.ClientOutMessage\"\x00(\x01\x30\x01\x12O\n\x0e\x45xporterStream\x12\x1a.labgrid.ExporterInMessage\x1a\x1b.labgrid.ExporterOutMessage\"\x00(\x01\x30\x01\x12\x41\n\x08\x41\x64\x64Place\x12\x18.labgrid.AddPlaceRequest\x1a\x19.labgrid.AddPlaceResponse\"\x00\x12J\n\x0b\x44\x65letePlace\x12\x1b.labgrid.DeletePlaceRequest\x1a\x1c.labgrid.DeletePlaceResponse\"\x00\x12\x44\n\tGetPlaces\x12\x19.labgrid.GetPlacesRequest\x1a\x1a.labgrid.GetPlacesResponse\"\x00\x12P\n\rAddPlaceAlias\x12\x1d.labgrid.AddPlaceAliasRequest\x1a\x1e.labgrid.AddPlaceAliasResponse\"\x00\x12Y\n\x10\x44\x65letePlaceAlias\x12 .labgrid.DeletePlaceAliasRequest\x1a!.labgrid.DeletePlaceAliasResponse\"\x00\x12M\n\x0cSetPlaceTags\x12\x1c.labgrid.SetPlaceTagsRequest\x1a\x1d.labgrid.SetPlaceTagsResponse\"\x00\x12V\n\x0fSetPlaceComment\x12\x1f.labgrid.SetPlaceCommentRequest\x1a .labgrid.SetPlaceCommentResponse\"\x00\x12P\n\rAddPlaceMatch\x12\x1d.labgrid.AddPlaceMatchRequest\x1a\x1e.labgrid.AddPlaceMatchResponse\"\x00\x12Y\n\x10\x44\x65letePlaceMatch\x12 .labgrid.DeletePlaceMatchRequest\x1a!.labgrid.DeletePlaceMatchResponse\"\x00\x12M\n\x0c\x41\x63quirePlace\x12\x1c.labgrid.AcquirePlaceRequest\x1a\x1d.labgrid.AcquirePlaceResponse\"\x00\x12\x45\n\nLeasePlace\x12\x1a.labgrid.LeasePlaceRequest\x1a\x1b.labgrid.LeasePlaceResponse\x12Q\n\x0eGetLeaseConfig\x12\x1e.labgrid.GetLeaseConfigRequest\x1a\x1f.labgrid.GetLeaseConfigResponse\x12M\n\x0cReleasePlace\x12\x1c.labgrid.ReleasePlaceRequest\x1a\x1d.labgrid.ReleasePlaceResponse\"\x00\x12G\n\nAllowPlace\x12\x1a.labgrid.AllowPlaceRequest\x1a\x1b.labgrid.AllowPlaceResponse\"\x00\x12\\\n\x11\x43reateReservation\x12!.labgrid.CreateReservationRequest\x1a\".labgrid.CreateReservationResponse\"\x00\x12\\\n\x11\x43\x61ncelReservation\x12!.labgrid.CancelReservationRequest\x1a\".labgrid.CancelReservationResponse\"\x00\x12V\n\x0fPollReservation\x12\x1f.labgrid.PollReservationRequest\x1a .labgrid.PollReservationResponse\"\x00\x12H\n\x0b\x45xtendLease\x12\x1b.labgrid.ExtendLeaseRequest\x1a\x1c.labgrid.ExtendLeaseResponse\x12V\n\x0fGetReservations\x12\x1f.labgrid.GetReservationsRequest\x1a .labgrid.GetReservationsResponse\"\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19labgrid-coordinator.proto\x12\x07labgrid\x1a\x1fgoogle/protobuf/timestamp.proto\"\x8a\x01\n\x0f\x43lientInMessage\x12\x1d\n\x04sync\x18\x01 \x01(\x0b\x32\r.labgrid.SyncH\x00\x12\'\n\x07startup\x18\x02 \x01(\x0b\x32\x14.labgrid.StartupDoneH\x00\x12\'\n\tsubscribe\x18\x03 \x01(\x0b\x32\x12.labgrid.SubscribeH\x00\x42\x06\n\x04kind\"\x12\n\x04Sync\x12\n\n\x02id\x18\x01 \x01(\x04\",\n\x0bStartupDone\x12\x0f\n\x07version\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"r\n\tSubscribe\x12\x1b\n\x0eis_unsubscribe\x18\x01 \x01(\x08H\x01\x88\x01\x01\x12\x14\n\nall_places\x18\x02 \x01(\x08H\x00\x12\x17\n\rall_resources\x18\x03 \x01(\x08H\x00\x42\x06\n\x04kindB\x11\n\x0f_is_unsubscribe\"g\n\x10\x43lientOutMessage\x12 \n\x04sync\x18\x01 \x01(\x0b\x32\r.labgrid.SyncH\x00\x88\x01\x01\x12(\n\x07updates\x18\x02 \x03(\x0b\x32\x17.labgrid.UpdateResponseB\x07\n\x05_sync\"\xa5\x01\n\x0eUpdateResponse\x12%\n\x08resource\x18\x01 \x01(\x0b\x32\x11.labgrid.ResourceH\x00\x12.\n\x0c\x64\x65l_resource\x18\x02 \x01(\x0b\x32\x16.labgrid.Resource.PathH\x00\x12\x1f\n\x05place\x18\x03 \x01(\x0b\x32\x0e.labgrid.PlaceH\x00\x12\x13\n\tdel_place\x18\x04 \x01(\tH\x00\x42\x06\n\x04kind\"\x9a\x01\n\x11\x45xporterInMessage\x12%\n\x08resource\x18\x01 \x01(\x0b\x32\x11.labgrid.ResourceH\x00\x12\'\n\x07startup\x18\x02 \x01(\x0b\x32\x14.labgrid.StartupDoneH\x00\x12-\n\x08response\x18\x03 \x01(\x0b\x32\x19.labgrid.ExporterResponseH\x00\x42\x06\n\x04kind\"\x9e\x03\n\x08Resource\x12$\n\x04path\x18\x01 \x01(\x0b\x32\x16.labgrid.Resource.Path\x12\x0b\n\x03\x63ls\x18\x02 \x01(\t\x12-\n\x06params\x18\x03 \x03(\x0b\x32\x1d.labgrid.Resource.ParamsEntry\x12+\n\x05\x65xtra\x18\x04 \x03(\x0b\x32\x1c.labgrid.Resource.ExtraEntry\x12\x10\n\x08\x61\x63quired\x18\x05 \x01(\t\x12\r\n\x05\x61vail\x18\x06 \x01(\x08\x1a_\n\x04Path\x12\x1a\n\rexporter_name\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x12\n\ngroup_name\x18\x02 \x01(\t\x12\x15\n\rresource_name\x18\x03 \x01(\tB\x10\n\x0e_exporter_name\x1a@\n\x0bParamsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12 \n\x05value\x18\x02 \x01(\x0b\x32\x11.labgrid.MapValue:\x02\x38\x01\x1a?\n\nExtraEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12 \n\x05value\x18\x02 \x01(\x0b\x32\x11.labgrid.MapValue:\x02\x38\x01\"\x82\x01\n\x08MapValue\x12\x14\n\nbool_value\x18\x01 \x01(\x08H\x00\x12\x13\n\tint_value\x18\x02 \x01(\x03H\x00\x12\x14\n\nuint_value\x18\x03 \x01(\x04H\x00\x12\x15\n\x0b\x66loat_value\x18\x04 \x01(\x01H\x00\x12\x16\n\x0cstring_value\x18\x05 \x01(\tH\x00\x42\x06\n\x04kind\"C\n\x10\x45xporterResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x13\n\x06reason\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_reason\"\x18\n\x05Hello\x12\x0f\n\x07version\x18\x01 \x01(\t\"\x92\x02\n\x12\x45xporterOutMessage\x12\x1f\n\x05hello\x18\x01 \x01(\x0b\x32\x0e.labgrid.HelloH\x00\x12\x43\n\x14set_acquired_request\x18\x02 \x01(\x0b\x32#.labgrid.ExporterSetAcquiredRequestH\x00\x12\x45\n\x15lease_started_request\x18\x03 \x01(\x0b\x32$.labgrid.ExporterLeaseStartedRequestH\x00\x12G\n\x16lease_extended_request\x18\x04 \x01(\x0b\x32%.labgrid.ExporterLeaseExtendedRequestH\x00\x42\x06\n\x04kind\"o\n\x1a\x45xporterSetAcquiredRequest\x12\x12\n\ngroup_name\x18\x01 \x01(\t\x12\x15\n\rresource_name\x18\x02 \x01(\t\x12\x17\n\nplace_name\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\r\n\x0b_place_name\"n\n\x1b\x45xporterLeaseStartedRequest\x12\x12\n\ngroup_name\x18\x01 \x01(\t\x12\x15\n\rresource_name\x18\x02 \x01(\t\x12\x12\n\nplace_name\x18\x03 \x01(\t\x12\x10\n\x08\x64uration\x18\x04 \x01(\x04\"\x83\x01\n\x1c\x45xporterLeaseExtendedRequest\x12\x12\n\ngroup_name\x18\x01 \x01(\t\x12\x15\n\rresource_name\x18\x02 \x01(\t\x12\x17\n\nplace_name\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x10\n\x08\x64uration\x18\x04 \x01(\x04\x42\r\n\x0b_place_name\"\x1f\n\x0f\x41\x64\x64PlaceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x12\n\x10\x41\x64\x64PlaceResponse\"\"\n\x12\x44\x65letePlaceRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x15\n\x13\x44\x65letePlaceResponse\"\x12\n\x10GetPlacesRequest\"3\n\x11GetPlacesResponse\x12\x1e\n\x06places\x18\x01 \x03(\x0b\x32\x0e.labgrid.Place\"\xd2\x02\n\x05Place\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07\x61liases\x18\x02 \x03(\t\x12\x0f\n\x07\x63omment\x18\x03 \x01(\t\x12&\n\x04tags\x18\x04 \x03(\x0b\x32\x18.labgrid.Place.TagsEntry\x12\'\n\x07matches\x18\x05 \x03(\x0b\x32\x16.labgrid.ResourceMatch\x12\x15\n\x08\x61\x63quired\x18\x06 \x01(\tH\x00\x88\x01\x01\x12\x1a\n\x12\x61\x63quired_resources\x18\x07 \x03(\t\x12\x0f\n\x07\x61llowed\x18\x08 \x03(\t\x12\x0f\n\x07\x63reated\x18\t \x01(\x01\x12\x0f\n\x07\x63hanged\x18\n \x01(\x01\x12\x18\n\x0breservation\x18\x0b \x01(\tH\x01\x88\x01\x01\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x0b\n\t_acquiredB\x0e\n\x0c_reservation\"y\n\rResourceMatch\x12\x10\n\x08\x65xporter\x18\x01 \x01(\t\x12\r\n\x05group\x18\x02 \x01(\t\x12\x0b\n\x03\x63ls\x18\x03 \x01(\t\x12\x11\n\x04name\x18\x04 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06rename\x18\x05 \x01(\tH\x01\x88\x01\x01\x42\x07\n\x05_nameB\t\n\x07_rename\"8\n\x14\x41\x64\x64PlaceAliasRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\r\n\x05\x61lias\x18\x02 \x01(\t\"\x17\n\x15\x41\x64\x64PlaceAliasResponse\";\n\x17\x44\x65letePlaceAliasRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\r\n\x05\x61lias\x18\x02 \x01(\t\"\x1a\n\x18\x44\x65letePlaceAliasResponse\"\x8b\x01\n\x13SetPlaceTagsRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\x34\n\x04tags\x18\x02 \x03(\x0b\x32&.labgrid.SetPlaceTagsRequest.TagsEntry\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x16\n\x14SetPlaceTagsResponse\"<\n\x16SetPlaceCommentRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\x0f\n\x07\x63omment\x18\x02 \x01(\t\"\x19\n\x17SetPlaceCommentResponse\"Z\n\x14\x41\x64\x64PlaceMatchRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\x0f\n\x07pattern\x18\x02 \x01(\t\x12\x13\n\x06rename\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_rename\"\x17\n\x15\x41\x64\x64PlaceMatchResponse\"]\n\x17\x44\x65letePlaceMatchRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\x0f\n\x07pattern\x18\x02 \x01(\t\x12\x13\n\x06rename\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_rename\"\x1a\n\x18\x44\x65letePlaceMatchResponse\"(\n\x13\x41\x63quirePlaceRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\"\x16\n\x14\x41\x63quirePlaceResponse\"&\n\x11LeasePlaceRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\"\x14\n\x12LeasePlaceResponse\"#\n\x12\x45xtendLeaseRequest\x12\r\n\x05token\x18\x01 \x01(\t\"@\n\x13\x45xtendLeaseResponse\x12)\n\x0breservation\x18\x01 \x01(\x0b\x32\x14.labgrid.Reservation\"\x17\n\x15GetLeaseConfigRequest\"u\n\x16GetLeaseConfigResponse\x12\x1e\n\x16\x64\x65\x66\x61ult_lease_duration\x18\x01 \x01(\r\x12\x1f\n\x17\x64\x65\x66\x61ult_extend_duration\x18\x02 \x01(\r\x12\x1a\n\x12max_lease_duration\x18\x03 \x01(\r\"L\n\x13ReleasePlaceRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\x15\n\x08\x66romuser\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0b\n\t_fromuser\"\x16\n\x14ReleasePlaceResponse\"4\n\x11\x41llowPlaceRequest\x12\x11\n\tplacename\x18\x01 \x01(\t\x12\x0c\n\x04user\x18\x02 \x01(\t\"\x14\n\x12\x41llowPlaceResponse\"\xb6\x01\n\x18\x43reateReservationRequest\x12?\n\x07\x66ilters\x18\x01 \x03(\x0b\x32..labgrid.CreateReservationRequest.FiltersEntry\x12\x0c\n\x04prio\x18\x02 \x01(\x01\x1aK\n\x0c\x46iltersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12*\n\x05value\x18\x02 \x01(\x0b\x32\x1b.labgrid.Reservation.Filter:\x02\x38\x01\"F\n\x19\x43reateReservationResponse\x12)\n\x0breservation\x18\x01 \x01(\x0b\x32\x14.labgrid.Reservation\"\x83\x04\n\x0bReservation\x12\r\n\x05owner\x18\x01 \x01(\t\x12\r\n\x05token\x18\x02 \x01(\t\x12\r\n\x05state\x18\x03 \x01(\x05\x12\x0c\n\x04prio\x18\x04 \x01(\x01\x12\x32\n\x07\x66ilters\x18\x05 \x03(\x0b\x32!.labgrid.Reservation.FiltersEntry\x12:\n\x0b\x61llocations\x18\x06 \x03(\x0b\x32%.labgrid.Reservation.AllocationsEntry\x12\x0f\n\x07\x63reated\x18\x07 \x01(\x01\x12\x0f\n\x07timeout\x18\x08 \x01(\x01\x12\x34\n\x10lease_start_time\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x1ap\n\x06\x46ilter\x12\x37\n\x06\x66ilter\x18\x01 \x03(\x0b\x32\'.labgrid.Reservation.Filter.FilterEntry\x1a-\n\x0b\x46ilterEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1aK\n\x0c\x46iltersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12*\n\x05value\x18\x02 \x01(\x0b\x32\x1b.labgrid.Reservation.Filter:\x02\x38\x01\x1a\x32\n\x10\x41llocationsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\")\n\x18\x43\x61ncelReservationRequest\x12\r\n\x05token\x18\x01 \x01(\t\"\x1b\n\x19\x43\x61ncelReservationResponse\"\'\n\x16PollReservationRequest\x12\r\n\x05token\x18\x01 \x01(\t\"D\n\x17PollReservationResponse\x12)\n\x0breservation\x18\x01 \x01(\x0b\x32\x14.labgrid.Reservation\"E\n\x17GetReservationsResponse\x12*\n\x0creservations\x18\x01 \x03(\x0b\x32\x14.labgrid.Reservation\"\x18\n\x16GetReservationsRequest2\xb6\r\n\x0b\x43oordinator\x12I\n\x0c\x43lientStream\x12\x18.labgrid.ClientInMessage\x1a\x19.labgrid.ClientOutMessage\"\x00(\x01\x30\x01\x12O\n\x0e\x45xporterStream\x12\x1a.labgrid.ExporterInMessage\x1a\x1b.labgrid.ExporterOutMessage\"\x00(\x01\x30\x01\x12\x41\n\x08\x41\x64\x64Place\x12\x18.labgrid.AddPlaceRequest\x1a\x19.labgrid.AddPlaceResponse\"\x00\x12J\n\x0b\x44\x65letePlace\x12\x1b.labgrid.DeletePlaceRequest\x1a\x1c.labgrid.DeletePlaceResponse\"\x00\x12\x44\n\tGetPlaces\x12\x19.labgrid.GetPlacesRequest\x1a\x1a.labgrid.GetPlacesResponse\"\x00\x12P\n\rAddPlaceAlias\x12\x1d.labgrid.AddPlaceAliasRequest\x1a\x1e.labgrid.AddPlaceAliasResponse\"\x00\x12Y\n\x10\x44\x65letePlaceAlias\x12 .labgrid.DeletePlaceAliasRequest\x1a!.labgrid.DeletePlaceAliasResponse\"\x00\x12M\n\x0cSetPlaceTags\x12\x1c.labgrid.SetPlaceTagsRequest\x1a\x1d.labgrid.SetPlaceTagsResponse\"\x00\x12V\n\x0fSetPlaceComment\x12\x1f.labgrid.SetPlaceCommentRequest\x1a .labgrid.SetPlaceCommentResponse\"\x00\x12P\n\rAddPlaceMatch\x12\x1d.labgrid.AddPlaceMatchRequest\x1a\x1e.labgrid.AddPlaceMatchResponse\"\x00\x12Y\n\x10\x44\x65letePlaceMatch\x12 .labgrid.DeletePlaceMatchRequest\x1a!.labgrid.DeletePlaceMatchResponse\"\x00\x12M\n\x0c\x41\x63quirePlace\x12\x1c.labgrid.AcquirePlaceRequest\x1a\x1d.labgrid.AcquirePlaceResponse\"\x00\x12\x45\n\nLeasePlace\x12\x1a.labgrid.LeasePlaceRequest\x1a\x1b.labgrid.LeasePlaceResponse\x12Q\n\x0eGetLeaseConfig\x12\x1e.labgrid.GetLeaseConfigRequest\x1a\x1f.labgrid.GetLeaseConfigResponse\x12M\n\x0cReleasePlace\x12\x1c.labgrid.ReleasePlaceRequest\x1a\x1d.labgrid.ReleasePlaceResponse\"\x00\x12G\n\nAllowPlace\x12\x1a.labgrid.AllowPlaceRequest\x1a\x1b.labgrid.AllowPlaceResponse\"\x00\x12\\\n\x11\x43reateReservation\x12!.labgrid.CreateReservationRequest\x1a\".labgrid.CreateReservationResponse\"\x00\x12\\\n\x11\x43\x61ncelReservation\x12!.labgrid.CancelReservationRequest\x1a\".labgrid.CancelReservationResponse\"\x00\x12V\n\x0fPollReservation\x12\x1f.labgrid.PollReservationRequest\x1a .labgrid.PollReservationResponse\"\x00\x12H\n\x0b\x45xtendLease\x12\x1b.labgrid.ExtendLeaseRequest\x1a\x1c.labgrid.ExtendLeaseResponse\x12V\n\x0fGetReservations\x12\x1f.labgrid.GetReservationsRequest\x1a .labgrid.GetReservationsResponse\"\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'labgrid_coordinator_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - DESCRIPTOR._loaded_options = None - _globals['_RESOURCE_PARAMSENTRY']._loaded_options = None +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + _globals['_RESOURCE_PARAMSENTRY']._options = None _globals['_RESOURCE_PARAMSENTRY']._serialized_options = b'8\001' - _globals['_RESOURCE_EXTRAENTRY']._loaded_options = None + _globals['_RESOURCE_EXTRAENTRY']._options = None _globals['_RESOURCE_EXTRAENTRY']._serialized_options = b'8\001' - _globals['_PLACE_TAGSENTRY']._loaded_options = None + _globals['_PLACE_TAGSENTRY']._options = None _globals['_PLACE_TAGSENTRY']._serialized_options = b'8\001' - _globals['_SETPLACETAGSREQUEST_TAGSENTRY']._loaded_options = None + _globals['_SETPLACETAGSREQUEST_TAGSENTRY']._options = None _globals['_SETPLACETAGSREQUEST_TAGSENTRY']._serialized_options = b'8\001' - _globals['_CREATERESERVATIONREQUEST_FILTERSENTRY']._loaded_options = None + _globals['_CREATERESERVATIONREQUEST_FILTERSENTRY']._options = None _globals['_CREATERESERVATIONREQUEST_FILTERSENTRY']._serialized_options = b'8\001' - _globals['_RESERVATION_FILTER_FILTERENTRY']._loaded_options = None + _globals['_RESERVATION_FILTER_FILTERENTRY']._options = None _globals['_RESERVATION_FILTER_FILTERENTRY']._serialized_options = b'8\001' - _globals['_RESERVATION_FILTERSENTRY']._loaded_options = None + _globals['_RESERVATION_FILTERSENTRY']._options = None _globals['_RESERVATION_FILTERSENTRY']._serialized_options = b'8\001' - _globals['_RESERVATION_ALLOCATIONSENTRY']._loaded_options = None + _globals['_RESERVATION_ALLOCATIONSENTRY']._options = None _globals['_RESERVATION_ALLOCATIONSENTRY']._serialized_options = b'8\001' _globals['_CLIENTINMESSAGE']._serialized_start=72 _globals['_CLIENTINMESSAGE']._serialized_end=210 @@ -77,107 +67,109 @@ _globals['_HELLO']._serialized_start=1443 _globals['_HELLO']._serialized_end=1467 _globals['_EXPORTEROUTMESSAGE']._serialized_start=1470 - _globals['_EXPORTEROUTMESSAGE']._serialized_end=1673 - _globals['_EXPORTERSETACQUIREDREQUEST']._serialized_start=1675 - _globals['_EXPORTERSETACQUIREDREQUEST']._serialized_end=1786 - _globals['_EXPORTERLEASEEXTENDEDREQUEST']._serialized_start=1789 - _globals['_EXPORTERLEASEEXTENDEDREQUEST']._serialized_end=1920 - _globals['_ADDPLACEREQUEST']._serialized_start=1922 - _globals['_ADDPLACEREQUEST']._serialized_end=1953 - _globals['_ADDPLACERESPONSE']._serialized_start=1955 - _globals['_ADDPLACERESPONSE']._serialized_end=1973 - _globals['_DELETEPLACEREQUEST']._serialized_start=1975 - _globals['_DELETEPLACEREQUEST']._serialized_end=2009 - _globals['_DELETEPLACERESPONSE']._serialized_start=2011 - _globals['_DELETEPLACERESPONSE']._serialized_end=2032 - _globals['_GETPLACESREQUEST']._serialized_start=2034 - _globals['_GETPLACESREQUEST']._serialized_end=2052 - _globals['_GETPLACESRESPONSE']._serialized_start=2054 - _globals['_GETPLACESRESPONSE']._serialized_end=2105 - _globals['_PLACE']._serialized_start=2108 - _globals['_PLACE']._serialized_end=2446 - _globals['_PLACE_TAGSENTRY']._serialized_start=2374 - _globals['_PLACE_TAGSENTRY']._serialized_end=2417 - _globals['_RESOURCEMATCH']._serialized_start=2448 - _globals['_RESOURCEMATCH']._serialized_end=2569 - _globals['_ADDPLACEALIASREQUEST']._serialized_start=2571 - _globals['_ADDPLACEALIASREQUEST']._serialized_end=2627 - _globals['_ADDPLACEALIASRESPONSE']._serialized_start=2629 - _globals['_ADDPLACEALIASRESPONSE']._serialized_end=2652 - _globals['_DELETEPLACEALIASREQUEST']._serialized_start=2654 - _globals['_DELETEPLACEALIASREQUEST']._serialized_end=2713 - _globals['_DELETEPLACEALIASRESPONSE']._serialized_start=2715 - _globals['_DELETEPLACEALIASRESPONSE']._serialized_end=2741 - _globals['_SETPLACETAGSREQUEST']._serialized_start=2744 - _globals['_SETPLACETAGSREQUEST']._serialized_end=2883 - _globals['_SETPLACETAGSREQUEST_TAGSENTRY']._serialized_start=2374 - _globals['_SETPLACETAGSREQUEST_TAGSENTRY']._serialized_end=2417 - _globals['_SETPLACETAGSRESPONSE']._serialized_start=2885 - _globals['_SETPLACETAGSRESPONSE']._serialized_end=2907 - _globals['_SETPLACECOMMENTREQUEST']._serialized_start=2909 - _globals['_SETPLACECOMMENTREQUEST']._serialized_end=2969 - _globals['_SETPLACECOMMENTRESPONSE']._serialized_start=2971 - _globals['_SETPLACECOMMENTRESPONSE']._serialized_end=2996 - _globals['_ADDPLACEMATCHREQUEST']._serialized_start=2998 - _globals['_ADDPLACEMATCHREQUEST']._serialized_end=3088 - _globals['_ADDPLACEMATCHRESPONSE']._serialized_start=3090 - _globals['_ADDPLACEMATCHRESPONSE']._serialized_end=3113 - _globals['_DELETEPLACEMATCHREQUEST']._serialized_start=3115 - _globals['_DELETEPLACEMATCHREQUEST']._serialized_end=3208 - _globals['_DELETEPLACEMATCHRESPONSE']._serialized_start=3210 - _globals['_DELETEPLACEMATCHRESPONSE']._serialized_end=3236 - _globals['_ACQUIREPLACEREQUEST']._serialized_start=3238 - _globals['_ACQUIREPLACEREQUEST']._serialized_end=3278 - _globals['_ACQUIREPLACERESPONSE']._serialized_start=3280 - _globals['_ACQUIREPLACERESPONSE']._serialized_end=3302 - _globals['_LEASEPLACEREQUEST']._serialized_start=3304 - _globals['_LEASEPLACEREQUEST']._serialized_end=3342 - _globals['_LEASEPLACERESPONSE']._serialized_start=3344 - _globals['_LEASEPLACERESPONSE']._serialized_end=3364 - _globals['_EXTENDLEASEREQUEST']._serialized_start=3366 - _globals['_EXTENDLEASEREQUEST']._serialized_end=3401 - _globals['_EXTENDLEASERESPONSE']._serialized_start=3403 - _globals['_EXTENDLEASERESPONSE']._serialized_end=3467 - _globals['_GETLEASECONFIGREQUEST']._serialized_start=3469 - _globals['_GETLEASECONFIGREQUEST']._serialized_end=3492 - _globals['_GETLEASECONFIGRESPONSE']._serialized_start=3494 - _globals['_GETLEASECONFIGRESPONSE']._serialized_end=3611 - _globals['_RELEASEPLACEREQUEST']._serialized_start=3613 - _globals['_RELEASEPLACEREQUEST']._serialized_end=3689 - _globals['_RELEASEPLACERESPONSE']._serialized_start=3691 - _globals['_RELEASEPLACERESPONSE']._serialized_end=3713 - _globals['_ALLOWPLACEREQUEST']._serialized_start=3715 - _globals['_ALLOWPLACEREQUEST']._serialized_end=3767 - _globals['_ALLOWPLACERESPONSE']._serialized_start=3769 - _globals['_ALLOWPLACERESPONSE']._serialized_end=3789 - _globals['_CREATERESERVATIONREQUEST']._serialized_start=3792 - _globals['_CREATERESERVATIONREQUEST']._serialized_end=3974 - _globals['_CREATERESERVATIONREQUEST_FILTERSENTRY']._serialized_start=3899 - _globals['_CREATERESERVATIONREQUEST_FILTERSENTRY']._serialized_end=3974 - _globals['_CREATERESERVATIONRESPONSE']._serialized_start=3976 - _globals['_CREATERESERVATIONRESPONSE']._serialized_end=4046 - _globals['_RESERVATION']._serialized_start=4049 - _globals['_RESERVATION']._serialized_end=4564 - _globals['_RESERVATION_FILTER']._serialized_start=4323 - _globals['_RESERVATION_FILTER']._serialized_end=4435 - _globals['_RESERVATION_FILTER_FILTERENTRY']._serialized_start=4390 - _globals['_RESERVATION_FILTER_FILTERENTRY']._serialized_end=4435 - _globals['_RESERVATION_FILTERSENTRY']._serialized_start=3899 - _globals['_RESERVATION_FILTERSENTRY']._serialized_end=3974 - _globals['_RESERVATION_ALLOCATIONSENTRY']._serialized_start=4514 - _globals['_RESERVATION_ALLOCATIONSENTRY']._serialized_end=4564 - _globals['_CANCELRESERVATIONREQUEST']._serialized_start=4566 - _globals['_CANCELRESERVATIONREQUEST']._serialized_end=4607 - _globals['_CANCELRESERVATIONRESPONSE']._serialized_start=4609 - _globals['_CANCELRESERVATIONRESPONSE']._serialized_end=4636 - _globals['_POLLRESERVATIONREQUEST']._serialized_start=4638 - _globals['_POLLRESERVATIONREQUEST']._serialized_end=4677 - _globals['_POLLRESERVATIONRESPONSE']._serialized_start=4679 - _globals['_POLLRESERVATIONRESPONSE']._serialized_end=4747 - _globals['_GETRESERVATIONSRESPONSE']._serialized_start=4749 - _globals['_GETRESERVATIONSRESPONSE']._serialized_end=4818 - _globals['_GETRESERVATIONSREQUEST']._serialized_start=4820 - _globals['_GETRESERVATIONSREQUEST']._serialized_end=4844 - _globals['_COORDINATOR']._serialized_start=4847 - _globals['_COORDINATOR']._serialized_end=6565 + _globals['_EXPORTEROUTMESSAGE']._serialized_end=1744 + _globals['_EXPORTERSETACQUIREDREQUEST']._serialized_start=1746 + _globals['_EXPORTERSETACQUIREDREQUEST']._serialized_end=1857 + _globals['_EXPORTERLEASESTARTEDREQUEST']._serialized_start=1859 + _globals['_EXPORTERLEASESTARTEDREQUEST']._serialized_end=1969 + _globals['_EXPORTERLEASEEXTENDEDREQUEST']._serialized_start=1972 + _globals['_EXPORTERLEASEEXTENDEDREQUEST']._serialized_end=2103 + _globals['_ADDPLACEREQUEST']._serialized_start=2105 + _globals['_ADDPLACEREQUEST']._serialized_end=2136 + _globals['_ADDPLACERESPONSE']._serialized_start=2138 + _globals['_ADDPLACERESPONSE']._serialized_end=2156 + _globals['_DELETEPLACEREQUEST']._serialized_start=2158 + _globals['_DELETEPLACEREQUEST']._serialized_end=2192 + _globals['_DELETEPLACERESPONSE']._serialized_start=2194 + _globals['_DELETEPLACERESPONSE']._serialized_end=2215 + _globals['_GETPLACESREQUEST']._serialized_start=2217 + _globals['_GETPLACESREQUEST']._serialized_end=2235 + _globals['_GETPLACESRESPONSE']._serialized_start=2237 + _globals['_GETPLACESRESPONSE']._serialized_end=2288 + _globals['_PLACE']._serialized_start=2291 + _globals['_PLACE']._serialized_end=2629 + _globals['_PLACE_TAGSENTRY']._serialized_start=2557 + _globals['_PLACE_TAGSENTRY']._serialized_end=2600 + _globals['_RESOURCEMATCH']._serialized_start=2631 + _globals['_RESOURCEMATCH']._serialized_end=2752 + _globals['_ADDPLACEALIASREQUEST']._serialized_start=2754 + _globals['_ADDPLACEALIASREQUEST']._serialized_end=2810 + _globals['_ADDPLACEALIASRESPONSE']._serialized_start=2812 + _globals['_ADDPLACEALIASRESPONSE']._serialized_end=2835 + _globals['_DELETEPLACEALIASREQUEST']._serialized_start=2837 + _globals['_DELETEPLACEALIASREQUEST']._serialized_end=2896 + _globals['_DELETEPLACEALIASRESPONSE']._serialized_start=2898 + _globals['_DELETEPLACEALIASRESPONSE']._serialized_end=2924 + _globals['_SETPLACETAGSREQUEST']._serialized_start=2927 + _globals['_SETPLACETAGSREQUEST']._serialized_end=3066 + _globals['_SETPLACETAGSREQUEST_TAGSENTRY']._serialized_start=2557 + _globals['_SETPLACETAGSREQUEST_TAGSENTRY']._serialized_end=2600 + _globals['_SETPLACETAGSRESPONSE']._serialized_start=3068 + _globals['_SETPLACETAGSRESPONSE']._serialized_end=3090 + _globals['_SETPLACECOMMENTREQUEST']._serialized_start=3092 + _globals['_SETPLACECOMMENTREQUEST']._serialized_end=3152 + _globals['_SETPLACECOMMENTRESPONSE']._serialized_start=3154 + _globals['_SETPLACECOMMENTRESPONSE']._serialized_end=3179 + _globals['_ADDPLACEMATCHREQUEST']._serialized_start=3181 + _globals['_ADDPLACEMATCHREQUEST']._serialized_end=3271 + _globals['_ADDPLACEMATCHRESPONSE']._serialized_start=3273 + _globals['_ADDPLACEMATCHRESPONSE']._serialized_end=3296 + _globals['_DELETEPLACEMATCHREQUEST']._serialized_start=3298 + _globals['_DELETEPLACEMATCHREQUEST']._serialized_end=3391 + _globals['_DELETEPLACEMATCHRESPONSE']._serialized_start=3393 + _globals['_DELETEPLACEMATCHRESPONSE']._serialized_end=3419 + _globals['_ACQUIREPLACEREQUEST']._serialized_start=3421 + _globals['_ACQUIREPLACEREQUEST']._serialized_end=3461 + _globals['_ACQUIREPLACERESPONSE']._serialized_start=3463 + _globals['_ACQUIREPLACERESPONSE']._serialized_end=3485 + _globals['_LEASEPLACEREQUEST']._serialized_start=3487 + _globals['_LEASEPLACEREQUEST']._serialized_end=3525 + _globals['_LEASEPLACERESPONSE']._serialized_start=3527 + _globals['_LEASEPLACERESPONSE']._serialized_end=3547 + _globals['_EXTENDLEASEREQUEST']._serialized_start=3549 + _globals['_EXTENDLEASEREQUEST']._serialized_end=3584 + _globals['_EXTENDLEASERESPONSE']._serialized_start=3586 + _globals['_EXTENDLEASERESPONSE']._serialized_end=3650 + _globals['_GETLEASECONFIGREQUEST']._serialized_start=3652 + _globals['_GETLEASECONFIGREQUEST']._serialized_end=3675 + _globals['_GETLEASECONFIGRESPONSE']._serialized_start=3677 + _globals['_GETLEASECONFIGRESPONSE']._serialized_end=3794 + _globals['_RELEASEPLACEREQUEST']._serialized_start=3796 + _globals['_RELEASEPLACEREQUEST']._serialized_end=3872 + _globals['_RELEASEPLACERESPONSE']._serialized_start=3874 + _globals['_RELEASEPLACERESPONSE']._serialized_end=3896 + _globals['_ALLOWPLACEREQUEST']._serialized_start=3898 + _globals['_ALLOWPLACEREQUEST']._serialized_end=3950 + _globals['_ALLOWPLACERESPONSE']._serialized_start=3952 + _globals['_ALLOWPLACERESPONSE']._serialized_end=3972 + _globals['_CREATERESERVATIONREQUEST']._serialized_start=3975 + _globals['_CREATERESERVATIONREQUEST']._serialized_end=4157 + _globals['_CREATERESERVATIONREQUEST_FILTERSENTRY']._serialized_start=4082 + _globals['_CREATERESERVATIONREQUEST_FILTERSENTRY']._serialized_end=4157 + _globals['_CREATERESERVATIONRESPONSE']._serialized_start=4159 + _globals['_CREATERESERVATIONRESPONSE']._serialized_end=4229 + _globals['_RESERVATION']._serialized_start=4232 + _globals['_RESERVATION']._serialized_end=4747 + _globals['_RESERVATION_FILTER']._serialized_start=4506 + _globals['_RESERVATION_FILTER']._serialized_end=4618 + _globals['_RESERVATION_FILTER_FILTERENTRY']._serialized_start=4573 + _globals['_RESERVATION_FILTER_FILTERENTRY']._serialized_end=4618 + _globals['_RESERVATION_FILTERSENTRY']._serialized_start=4082 + _globals['_RESERVATION_FILTERSENTRY']._serialized_end=4157 + _globals['_RESERVATION_ALLOCATIONSENTRY']._serialized_start=4697 + _globals['_RESERVATION_ALLOCATIONSENTRY']._serialized_end=4747 + _globals['_CANCELRESERVATIONREQUEST']._serialized_start=4749 + _globals['_CANCELRESERVATIONREQUEST']._serialized_end=4790 + _globals['_CANCELRESERVATIONRESPONSE']._serialized_start=4792 + _globals['_CANCELRESERVATIONRESPONSE']._serialized_end=4819 + _globals['_POLLRESERVATIONREQUEST']._serialized_start=4821 + _globals['_POLLRESERVATIONREQUEST']._serialized_end=4860 + _globals['_POLLRESERVATIONRESPONSE']._serialized_start=4862 + _globals['_POLLRESERVATIONRESPONSE']._serialized_end=4930 + _globals['_GETRESERVATIONSRESPONSE']._serialized_start=4932 + _globals['_GETRESERVATIONSRESPONSE']._serialized_end=5001 + _globals['_GETRESERVATIONSREQUEST']._serialized_start=5003 + _globals['_GETRESERVATIONSREQUEST']._serialized_end=5027 + _globals['_COORDINATOR']._serialized_start=5030 + _globals['_COORDINATOR']._serialized_end=6748 # @@protoc_insertion_point(module_scope) diff --git a/labgrid/remote/generated/labgrid_coordinator_pb2.pyi b/labgrid/remote/generated/labgrid_coordinator_pb2.pyi index 5e6e6f704..1be6e0091 100644 --- a/labgrid/remote/generated/labgrid_coordinator_pb2.pyi +++ b/labgrid/remote/generated/labgrid_coordinator_pb2.pyi @@ -1,11 +1,8 @@ -import datetime - from google.protobuf import timestamp_pb2 as _timestamp_pb2 from google.protobuf.internal import containers as _containers from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message -from collections.abc import Iterable as _Iterable, Mapping as _Mapping -from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union +from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union DESCRIPTOR: _descriptor.FileDescriptor @@ -141,14 +138,16 @@ class Hello(_message.Message): def __init__(self, version: _Optional[str] = ...) -> None: ... class ExporterOutMessage(_message.Message): - __slots__ = ("hello", "set_acquired_request", "lease_extended_request") + __slots__ = ("hello", "set_acquired_request", "lease_started_request", "lease_extended_request") HELLO_FIELD_NUMBER: _ClassVar[int] SET_ACQUIRED_REQUEST_FIELD_NUMBER: _ClassVar[int] + LEASE_STARTED_REQUEST_FIELD_NUMBER: _ClassVar[int] LEASE_EXTENDED_REQUEST_FIELD_NUMBER: _ClassVar[int] hello: Hello set_acquired_request: ExporterSetAcquiredRequest + lease_started_request: ExporterLeaseStartedRequest lease_extended_request: ExporterLeaseExtendedRequest - def __init__(self, hello: _Optional[_Union[Hello, _Mapping]] = ..., set_acquired_request: _Optional[_Union[ExporterSetAcquiredRequest, _Mapping]] = ..., lease_extended_request: _Optional[_Union[ExporterLeaseExtendedRequest, _Mapping]] = ...) -> None: ... + def __init__(self, hello: _Optional[_Union[Hello, _Mapping]] = ..., set_acquired_request: _Optional[_Union[ExporterSetAcquiredRequest, _Mapping]] = ..., lease_started_request: _Optional[_Union[ExporterLeaseStartedRequest, _Mapping]] = ..., lease_extended_request: _Optional[_Union[ExporterLeaseExtendedRequest, _Mapping]] = ...) -> None: ... class ExporterSetAcquiredRequest(_message.Message): __slots__ = ("group_name", "resource_name", "place_name") @@ -160,6 +159,18 @@ class ExporterSetAcquiredRequest(_message.Message): place_name: str def __init__(self, group_name: _Optional[str] = ..., resource_name: _Optional[str] = ..., place_name: _Optional[str] = ...) -> None: ... +class ExporterLeaseStartedRequest(_message.Message): + __slots__ = ("group_name", "resource_name", "place_name", "duration") + GROUP_NAME_FIELD_NUMBER: _ClassVar[int] + RESOURCE_NAME_FIELD_NUMBER: _ClassVar[int] + PLACE_NAME_FIELD_NUMBER: _ClassVar[int] + DURATION_FIELD_NUMBER: _ClassVar[int] + group_name: str + resource_name: str + place_name: str + duration: int + def __init__(self, group_name: _Optional[str] = ..., resource_name: _Optional[str] = ..., place_name: _Optional[str] = ..., duration: _Optional[int] = ...) -> None: ... + class ExporterLeaseExtendedRequest(_message.Message): __slots__ = ("group_name", "resource_name", "place_name", "duration") GROUP_NAME_FIELD_NUMBER: _ClassVar[int] @@ -469,7 +480,7 @@ class Reservation(_message.Message): created: float timeout: float lease_start_time: _timestamp_pb2.Timestamp - def __init__(self, owner: _Optional[str] = ..., token: _Optional[str] = ..., state: _Optional[int] = ..., prio: _Optional[float] = ..., filters: _Optional[_Mapping[str, Reservation.Filter]] = ..., allocations: _Optional[_Mapping[str, str]] = ..., created: _Optional[float] = ..., timeout: _Optional[float] = ..., lease_start_time: _Optional[_Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping]] = ...) -> None: ... + def __init__(self, owner: _Optional[str] = ..., token: _Optional[str] = ..., state: _Optional[int] = ..., prio: _Optional[float] = ..., filters: _Optional[_Mapping[str, Reservation.Filter]] = ..., allocations: _Optional[_Mapping[str, str]] = ..., created: _Optional[float] = ..., timeout: _Optional[float] = ..., lease_start_time: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ...) -> None: ... class CancelReservationRequest(_message.Message): __slots__ = ("token",) diff --git a/labgrid/remote/generated/labgrid_coordinator_pb2_grpc.py b/labgrid/remote/generated/labgrid_coordinator_pb2_grpc.py index 43bd47957..62d5cbfc0 100644 --- a/labgrid/remote/generated/labgrid_coordinator_pb2_grpc.py +++ b/labgrid/remote/generated/labgrid_coordinator_pb2_grpc.py @@ -1,29 +1,9 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! """Client and server classes corresponding to protobuf-defined services.""" import grpc -import warnings from . import labgrid_coordinator_pb2 as labgrid__coordinator__pb2 -GRPC_GENERATED_VERSION = '1.76.0' -GRPC_VERSION = grpc.__version__ -_version_not_supported = False - -try: - from grpc._utilities import first_version_is_lower - _version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION) -except ImportError: - _version_not_supported = True - -if _version_not_supported: - raise RuntimeError( - f'The grpc package installed is at version {GRPC_VERSION},' - + ' but the generated code in labgrid_coordinator_pb2_grpc.py depends on' - + f' grpcio>={GRPC_GENERATED_VERSION}.' - + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' - + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' - ) - class CoordinatorStub(object): """Missing associated documentation comment in .proto file.""" @@ -38,107 +18,107 @@ def __init__(self, channel): '/labgrid.Coordinator/ClientStream', request_serializer=labgrid__coordinator__pb2.ClientInMessage.SerializeToString, response_deserializer=labgrid__coordinator__pb2.ClientOutMessage.FromString, - _registered_method=True) + ) self.ExporterStream = channel.stream_stream( '/labgrid.Coordinator/ExporterStream', request_serializer=labgrid__coordinator__pb2.ExporterInMessage.SerializeToString, response_deserializer=labgrid__coordinator__pb2.ExporterOutMessage.FromString, - _registered_method=True) + ) self.AddPlace = channel.unary_unary( '/labgrid.Coordinator/AddPlace', request_serializer=labgrid__coordinator__pb2.AddPlaceRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.AddPlaceResponse.FromString, - _registered_method=True) + ) self.DeletePlace = channel.unary_unary( '/labgrid.Coordinator/DeletePlace', request_serializer=labgrid__coordinator__pb2.DeletePlaceRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.DeletePlaceResponse.FromString, - _registered_method=True) + ) self.GetPlaces = channel.unary_unary( '/labgrid.Coordinator/GetPlaces', request_serializer=labgrid__coordinator__pb2.GetPlacesRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.GetPlacesResponse.FromString, - _registered_method=True) + ) self.AddPlaceAlias = channel.unary_unary( '/labgrid.Coordinator/AddPlaceAlias', request_serializer=labgrid__coordinator__pb2.AddPlaceAliasRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.AddPlaceAliasResponse.FromString, - _registered_method=True) + ) self.DeletePlaceAlias = channel.unary_unary( '/labgrid.Coordinator/DeletePlaceAlias', request_serializer=labgrid__coordinator__pb2.DeletePlaceAliasRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.DeletePlaceAliasResponse.FromString, - _registered_method=True) + ) self.SetPlaceTags = channel.unary_unary( '/labgrid.Coordinator/SetPlaceTags', request_serializer=labgrid__coordinator__pb2.SetPlaceTagsRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.SetPlaceTagsResponse.FromString, - _registered_method=True) + ) self.SetPlaceComment = channel.unary_unary( '/labgrid.Coordinator/SetPlaceComment', request_serializer=labgrid__coordinator__pb2.SetPlaceCommentRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.SetPlaceCommentResponse.FromString, - _registered_method=True) + ) self.AddPlaceMatch = channel.unary_unary( '/labgrid.Coordinator/AddPlaceMatch', request_serializer=labgrid__coordinator__pb2.AddPlaceMatchRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.AddPlaceMatchResponse.FromString, - _registered_method=True) + ) self.DeletePlaceMatch = channel.unary_unary( '/labgrid.Coordinator/DeletePlaceMatch', request_serializer=labgrid__coordinator__pb2.DeletePlaceMatchRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.DeletePlaceMatchResponse.FromString, - _registered_method=True) + ) self.AcquirePlace = channel.unary_unary( '/labgrid.Coordinator/AcquirePlace', request_serializer=labgrid__coordinator__pb2.AcquirePlaceRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.AcquirePlaceResponse.FromString, - _registered_method=True) + ) self.LeasePlace = channel.unary_unary( '/labgrid.Coordinator/LeasePlace', request_serializer=labgrid__coordinator__pb2.LeasePlaceRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.LeasePlaceResponse.FromString, - _registered_method=True) + ) self.GetLeaseConfig = channel.unary_unary( '/labgrid.Coordinator/GetLeaseConfig', request_serializer=labgrid__coordinator__pb2.GetLeaseConfigRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.GetLeaseConfigResponse.FromString, - _registered_method=True) + ) self.ReleasePlace = channel.unary_unary( '/labgrid.Coordinator/ReleasePlace', request_serializer=labgrid__coordinator__pb2.ReleasePlaceRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.ReleasePlaceResponse.FromString, - _registered_method=True) + ) self.AllowPlace = channel.unary_unary( '/labgrid.Coordinator/AllowPlace', request_serializer=labgrid__coordinator__pb2.AllowPlaceRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.AllowPlaceResponse.FromString, - _registered_method=True) + ) self.CreateReservation = channel.unary_unary( '/labgrid.Coordinator/CreateReservation', request_serializer=labgrid__coordinator__pb2.CreateReservationRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.CreateReservationResponse.FromString, - _registered_method=True) + ) self.CancelReservation = channel.unary_unary( '/labgrid.Coordinator/CancelReservation', request_serializer=labgrid__coordinator__pb2.CancelReservationRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.CancelReservationResponse.FromString, - _registered_method=True) + ) self.PollReservation = channel.unary_unary( '/labgrid.Coordinator/PollReservation', request_serializer=labgrid__coordinator__pb2.PollReservationRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.PollReservationResponse.FromString, - _registered_method=True) + ) self.ExtendLease = channel.unary_unary( '/labgrid.Coordinator/ExtendLease', request_serializer=labgrid__coordinator__pb2.ExtendLeaseRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.ExtendLeaseResponse.FromString, - _registered_method=True) + ) self.GetReservations = channel.unary_unary( '/labgrid.Coordinator/GetReservations', request_serializer=labgrid__coordinator__pb2.GetReservationsRequest.SerializeToString, response_deserializer=labgrid__coordinator__pb2.GetReservationsResponse.FromString, - _registered_method=True) + ) class CoordinatorServicer(object): @@ -382,7 +362,6 @@ def add_CoordinatorServicer_to_server(servicer, server): generic_handler = grpc.method_handlers_generic_handler( 'labgrid.Coordinator', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) - server.add_registered_method_handlers('labgrid.Coordinator', rpc_method_handlers) # This class is part of an EXPERIMENTAL API. @@ -400,21 +379,11 @@ def ClientStream(request_iterator, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.stream_stream( - request_iterator, - target, - '/labgrid.Coordinator/ClientStream', + return grpc.experimental.stream_stream(request_iterator, target, '/labgrid.Coordinator/ClientStream', labgrid__coordinator__pb2.ClientInMessage.SerializeToString, labgrid__coordinator__pb2.ClientOutMessage.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def ExporterStream(request_iterator, @@ -427,21 +396,11 @@ def ExporterStream(request_iterator, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.stream_stream( - request_iterator, - target, - '/labgrid.Coordinator/ExporterStream', + return grpc.experimental.stream_stream(request_iterator, target, '/labgrid.Coordinator/ExporterStream', labgrid__coordinator__pb2.ExporterInMessage.SerializeToString, labgrid__coordinator__pb2.ExporterOutMessage.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def AddPlace(request, @@ -454,21 +413,11 @@ def AddPlace(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/labgrid.Coordinator/AddPlace', + return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/AddPlace', labgrid__coordinator__pb2.AddPlaceRequest.SerializeToString, labgrid__coordinator__pb2.AddPlaceResponse.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def DeletePlace(request, @@ -481,21 +430,11 @@ def DeletePlace(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/labgrid.Coordinator/DeletePlace', + return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/DeletePlace', labgrid__coordinator__pb2.DeletePlaceRequest.SerializeToString, labgrid__coordinator__pb2.DeletePlaceResponse.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def GetPlaces(request, @@ -508,21 +447,11 @@ def GetPlaces(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/labgrid.Coordinator/GetPlaces', + return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/GetPlaces', labgrid__coordinator__pb2.GetPlacesRequest.SerializeToString, labgrid__coordinator__pb2.GetPlacesResponse.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def AddPlaceAlias(request, @@ -535,21 +464,11 @@ def AddPlaceAlias(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/labgrid.Coordinator/AddPlaceAlias', + return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/AddPlaceAlias', labgrid__coordinator__pb2.AddPlaceAliasRequest.SerializeToString, labgrid__coordinator__pb2.AddPlaceAliasResponse.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def DeletePlaceAlias(request, @@ -562,21 +481,11 @@ def DeletePlaceAlias(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/labgrid.Coordinator/DeletePlaceAlias', + return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/DeletePlaceAlias', labgrid__coordinator__pb2.DeletePlaceAliasRequest.SerializeToString, labgrid__coordinator__pb2.DeletePlaceAliasResponse.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def SetPlaceTags(request, @@ -589,21 +498,11 @@ def SetPlaceTags(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/labgrid.Coordinator/SetPlaceTags', + return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/SetPlaceTags', labgrid__coordinator__pb2.SetPlaceTagsRequest.SerializeToString, labgrid__coordinator__pb2.SetPlaceTagsResponse.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def SetPlaceComment(request, @@ -616,21 +515,11 @@ def SetPlaceComment(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/labgrid.Coordinator/SetPlaceComment', + return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/SetPlaceComment', labgrid__coordinator__pb2.SetPlaceCommentRequest.SerializeToString, labgrid__coordinator__pb2.SetPlaceCommentResponse.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def AddPlaceMatch(request, @@ -643,21 +532,11 @@ def AddPlaceMatch(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/labgrid.Coordinator/AddPlaceMatch', + return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/AddPlaceMatch', labgrid__coordinator__pb2.AddPlaceMatchRequest.SerializeToString, labgrid__coordinator__pb2.AddPlaceMatchResponse.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def DeletePlaceMatch(request, @@ -670,21 +549,11 @@ def DeletePlaceMatch(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/labgrid.Coordinator/DeletePlaceMatch', + return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/DeletePlaceMatch', labgrid__coordinator__pb2.DeletePlaceMatchRequest.SerializeToString, labgrid__coordinator__pb2.DeletePlaceMatchResponse.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def AcquirePlace(request, @@ -697,21 +566,11 @@ def AcquirePlace(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/labgrid.Coordinator/AcquirePlace', + return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/AcquirePlace', labgrid__coordinator__pb2.AcquirePlaceRequest.SerializeToString, labgrid__coordinator__pb2.AcquirePlaceResponse.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def LeasePlace(request, @@ -724,21 +583,11 @@ def LeasePlace(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/labgrid.Coordinator/LeasePlace', + return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/LeasePlace', labgrid__coordinator__pb2.LeasePlaceRequest.SerializeToString, labgrid__coordinator__pb2.LeasePlaceResponse.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def GetLeaseConfig(request, @@ -751,21 +600,11 @@ def GetLeaseConfig(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/labgrid.Coordinator/GetLeaseConfig', + return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/GetLeaseConfig', labgrid__coordinator__pb2.GetLeaseConfigRequest.SerializeToString, labgrid__coordinator__pb2.GetLeaseConfigResponse.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def ReleasePlace(request, @@ -778,21 +617,11 @@ def ReleasePlace(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/labgrid.Coordinator/ReleasePlace', + return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/ReleasePlace', labgrid__coordinator__pb2.ReleasePlaceRequest.SerializeToString, labgrid__coordinator__pb2.ReleasePlaceResponse.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def AllowPlace(request, @@ -805,21 +634,11 @@ def AllowPlace(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/labgrid.Coordinator/AllowPlace', + return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/AllowPlace', labgrid__coordinator__pb2.AllowPlaceRequest.SerializeToString, labgrid__coordinator__pb2.AllowPlaceResponse.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def CreateReservation(request, @@ -832,21 +651,11 @@ def CreateReservation(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/labgrid.Coordinator/CreateReservation', + return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/CreateReservation', labgrid__coordinator__pb2.CreateReservationRequest.SerializeToString, labgrid__coordinator__pb2.CreateReservationResponse.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def CancelReservation(request, @@ -859,21 +668,11 @@ def CancelReservation(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/labgrid.Coordinator/CancelReservation', + return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/CancelReservation', labgrid__coordinator__pb2.CancelReservationRequest.SerializeToString, labgrid__coordinator__pb2.CancelReservationResponse.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def PollReservation(request, @@ -886,21 +685,11 @@ def PollReservation(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/labgrid.Coordinator/PollReservation', + return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/PollReservation', labgrid__coordinator__pb2.PollReservationRequest.SerializeToString, labgrid__coordinator__pb2.PollReservationResponse.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def ExtendLease(request, @@ -913,21 +702,11 @@ def ExtendLease(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/labgrid.Coordinator/ExtendLease', + return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/ExtendLease', labgrid__coordinator__pb2.ExtendLeaseRequest.SerializeToString, labgrid__coordinator__pb2.ExtendLeaseResponse.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def GetReservations(request, @@ -940,18 +719,8 @@ def GetReservations(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/labgrid.Coordinator/GetReservations', + return grpc.experimental.unary_unary(request, target, '/labgrid.Coordinator/GetReservations', labgrid__coordinator__pb2.GetReservationsRequest.SerializeToString, labgrid__coordinator__pb2.GetReservationsResponse.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/labgrid/remote/proto/labgrid-coordinator.proto b/labgrid/remote/proto/labgrid-coordinator.proto index 780cb9107..87b7a9d35 100644 --- a/labgrid/remote/proto/labgrid-coordinator.proto +++ b/labgrid/remote/proto/labgrid-coordinator.proto @@ -134,6 +134,7 @@ message ExporterOutMessage { Hello hello = 1; ExporterSetAcquiredRequest set_acquired_request = 2; ExporterLeaseExtendedRequest lease_extended_request = 3; + ExporterLeaseStartedRequest lease_started_request = 4; }; }; @@ -143,6 +144,13 @@ message ExporterSetAcquiredRequest { optional string place_name = 3; }; +message ExporterLeaseStartedRequest { + string group_name = 1; + string resource_name = 2; + string place_name = 3; + uint64 duration = 4; +} + message ExporterLeaseExtendedRequest { string group_name = 1; string resource_name = 2; From 5d480fb2f1552ce6db3cc7f2defc3aaa1ace1d3b Mon Sep 17 00:00:00 2001 From: Asher Pemberton Date: Sun, 26 Jul 2026 11:31:21 +0300 Subject: [PATCH 3/3] remote/coordinator: fail lease extension for orphaned resources Return FAILED_PRECONDITION when a leased place contains an orphaned acquired resource during lease extension. This keeps the existing lease alive until its current timeout instead of silently extending the reservation without notifying the exporter. Signed-off-by: Asher Pemberton Reviewed-by: Asher Pemberton # gatekeeper Co-authored-by: Idan Saadon --- labgrid/remote/coordinator.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/labgrid/remote/coordinator.py b/labgrid/remote/coordinator.py index c1730a537..1c3d2dbe8 100644 --- a/labgrid/remote/coordinator.py +++ b/labgrid/remote/coordinator.py @@ -214,6 +214,10 @@ class ExporterError(CoordinatorError): pass +class LeaseExtendPreconditionError(CoordinatorError): + pass + + class Coordinator(labgrid_coordinator_pb2_grpc.CoordinatorServicer): def __init__(self) -> None: self.places: dict[str, Place] = {} @@ -810,7 +814,11 @@ async def _notify_lease_extended(self, place, duration): for resource in place.acquired_resources: if getattr(resource, "orphaned", False): - continue + raise LeaseExtendPreconditionError( + f"cannot extend lease for {place.name}: resource {resource} is orphaned" + ) + + for resource in place.acquired_resources: await self._notify_lease_extended_resource(place, resource, duration) async def _release_resources(self, place, resources, callback=True): @@ -1426,6 +1434,11 @@ async def ExtendLease(self, request, context): try: await self._notify_lease_extended(leased_place, extend_duration) + except LeaseExtendPreconditionError as e: + await context.abort( + grpc.StatusCode.FAILED_PRECONDITION, + str(e), + ) except ExporterError as e: try: await self._release_place(leased_place)