From 55327eea013b9110b501fd5ed9c2052b5c78a5aa Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Wed, 13 Dec 2023 12:10:56 +0100 Subject: [PATCH] Revert src to 36877c352f733e --- src/client/cockpit-client | 13 +----------- src/cockpit/bridge.py | 27 ++---------------------- src/cockpit/packages.py | 23 +++------------------ src/cockpit/protocol.py | 14 +++++++++++++ src/cockpit/router.py | 43 ++++----------------------------------- src/cockpit/samples.py | 8 ++------ 6 files changed, 26 insertions(+), 102 deletions(-) diff --git a/src/client/cockpit-client b/src/client/cockpit-client index f4604d8b295a..84b6deb77ed2 100755 --- a/src/client/cockpit-client +++ b/src/client/cockpit-client @@ -55,17 +55,6 @@ def prctl(*args): raise Exception('prctl() failed') -def get_user_state_dir(): - try: - # GLib ≥ 2.72 - return GLib.get_user_state_dir() - except AttributeError: - try: - return os.environ["XDG_STATE_HOME"] - except KeyError: - return os.path.expanduser("~/.local/share") - - SET_PDEATHSIG = 1 @@ -233,7 +222,7 @@ class CockpitClient(Gtk.Application): context.set_sandbox_enabled(enabled=True) context.set_cache_model(WebKit2.CacheModel.DOCUMENT_VIEWER) - cookiesFile = os.path.join(get_user_state_dir(), "cockpit-client", "cookies.txt") + cookiesFile = os.path.join(GLib.get_user_state_dir(), "cockpit-client", "cookies.txt") cookies = context.get_cookie_manager() cookies.set_persistent_storage(cookiesFile, WebKit2.CookiePersistentStorage.TEXT) diff --git a/src/cockpit/bridge.py b/src/cockpit/bridge.py index 22517653e871..139db92f90ce 100644 --- a/src/cockpit/bridge.py +++ b/src/cockpit/bridge.py @@ -24,7 +24,6 @@ import pwd import shlex import socket -import stat import subprocess from typing import Iterable, List, Optional, Sequence, Tuple, Type @@ -203,33 +202,11 @@ def try_to_receive_stderr(): os.close(fd) -def setup_journald() -> bool: - # If stderr is a socket, prefer systemd-journal logging. This covers the - # case we're already connected to the journal but also the case where we're - # talking to the ferny agent, while leaving logging to file or terminal - # unaffected. - if not stat.S_ISSOCK(os.fstat(2).st_mode): - # not a socket? Don't redirect. - return False - - try: - import systemd.journal # type: ignore[import] - except ImportError: - # No python3-systemd? Don't redirect. - return False - - logging.root.addHandler(systemd.journal.JournalHandler()) - return True - - -def setup_logging(*, debug: bool) -> None: +def setup_logging(*, debug: bool): """Setup our logger with optional filtering of modules if COCKPIT_DEBUG env is set""" modules = os.getenv('COCKPIT_DEBUG', '') - - # Either setup logging via journal or via formatted messages to stderr - if not setup_journald(): - logging.basicConfig(format='%(name)s-%(levelname)s: %(message)s') + logging.basicConfig(format='%(name)s-%(levelname)s: %(message)s') if debug or modules == 'all': logging.getLogger().setLevel(level=logging.DEBUG) diff --git a/src/cockpit/packages.py b/src/cockpit/packages.py index 66c7ac970b0e..0d648db3fe13 100644 --- a/src/cockpit/packages.py +++ b/src/cockpit/packages.py @@ -20,7 +20,6 @@ import functools import gzip import io -import itertools import json import logging import mimetypes @@ -266,22 +265,11 @@ def ensure_scanned(self) -> None: # Accept-Language is case-insensitive and uses '-' to separate variants lower_locale = locale.lower().replace('_', '-') - logger.debug('Adding translation %r %r -> %r', basename, lower_locale, name) self.translations[f'{basename}.js'][lower_locale] = name else: - # strip out trailing '.gz' components - basename = re.sub('.gz$', '', name) - logger.debug('Adding content %r -> %r', basename, name) + basename = name[:-3] if name.endswith('.gz') else name self.files[basename] = name - # If we see a filename like `x.min.js` we want to also offer it - # at `x.js`, but only if `x.js(.gz)` itself is not present. - # Note: this works for both the case where we found the `x.js` - # first (it's already in the map) and also if we find it second - # (it will be replaced in the map by the line just above). - # See https://github.com/cockpit-project/cockpit/pull/19716 - self.files.setdefault(basename.replace('.min.', '.'), name) - # support old cockpit-po-plugin which didn't write po.manifest.??.js if not self.translations['po.manifest.js']: self.translations['po.manifest.js'] = self.translations['po.js'] @@ -502,13 +490,8 @@ def load(self) -> None: def show(self): for name in sorted(self.packages): package = self.packages[name] - menuitems = [] - for entry in itertools.chain( - package.manifest.get('menu', {}).values(), - package.manifest.get('tools', {}).values()): - with contextlib.suppress(KeyError): - menuitems.append(entry['label']) - print(f'{name:20} {", ".join(menuitems):40} {package.path}') + menuitems = '' + print(f'{name:20} {menuitems:40} {package.path}') def get_bridge_configs(self) -> Sequence[BridgeConfig]: def yield_configs(): diff --git a/src/cockpit/protocol.py b/src/cockpit/protocol.py index 9ed09e75f187..734e29385893 100644 --- a/src/cockpit/protocol.py +++ b/src/cockpit/protocol.py @@ -60,6 +60,7 @@ class CockpitProtocol(asyncio.Protocol): transport: Optional[asyncio.Transport] = None buffer = b'' _closed: bool = False + _communication_done: Optional[asyncio.Future] = None def do_ready(self) -> None: pass @@ -172,6 +173,12 @@ def close(self, exc: Optional[Exception] = None) -> None: self.do_closed(exc) + if self._communication_done is not None: + if exc is None: + self._communication_done.set_result(None) + else: + self._communication_done.set_exception(exc) + def write_channel_data(self, channel, payload): """Send a given payload (bytes) on channel (string)""" # Channel is certainly ascii (as enforced by .encode() below) @@ -203,6 +210,13 @@ def data_received(self, data): def eof_received(self) -> Optional[bool]: return False + async def communicate(self) -> None: + """Wait until communication is complete on this protocol.""" + assert self._communication_done is None + self._communication_done = asyncio.get_running_loop().create_future() + await self._communication_done + self._communication_done = None + # Helpful functionality for "server"-side protocol implementations class CockpitProtocolServer(CockpitProtocol): diff --git a/src/cockpit/router.py b/src/cockpit/router.py index 73449492a24f..526910b7437c 100644 --- a/src/cockpit/router.py +++ b/src/cockpit/router.py @@ -15,7 +15,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import asyncio import collections import logging from typing import Dict, List, Optional @@ -62,7 +61,7 @@ class Endpoint: __endpoint_frozen_queue: Optional[ExecutionQueue] = None def __init__(self, router: 'Router'): - router.add_endpoint(self) + router.endpoints[self] = set() self.router = router def freeze_endpoint(self): @@ -134,7 +133,6 @@ class Router(CockpitProtocolServer): routing_rules: List[RoutingRule] open_channels: Dict[str, Endpoint] endpoints: 'dict[Endpoint, set[str]]' - no_endpoints: asyncio.Event # set if endpoints dict is empty _eof: bool = False def __init__(self, routing_rules: List[RoutingRule]): @@ -143,8 +141,6 @@ def __init__(self, routing_rules: List[RoutingRule]): self.routing_rules = routing_rules self.open_channels = {} self.endpoints = {} - self.no_endpoints = asyncio.Event() - self.no_endpoints.set() # at first there are no endpoints def check_rules(self, options: JsonObject) -> Endpoint: for rule in self.routing_rules: @@ -164,10 +160,6 @@ def drop_channel(self, channel: str) -> None: except KeyError: logger.error('trying to drop non-existent channel %s from %s', channel, self.open_channels) - def add_endpoint(self, endpoint: Endpoint) -> None: - self.endpoints[endpoint] = set() - self.no_endpoints.clear() - def shutdown_endpoint(self, endpoint: Endpoint, _msg: 'JsonObject | None' = None, **kwargs: JsonDocument) -> None: channels = self.endpoints.pop(endpoint) logger.debug('shutdown_endpoint(%s, %s) will close %s', endpoint, kwargs, channels) @@ -175,12 +167,9 @@ def shutdown_endpoint(self, endpoint: Endpoint, _msg: 'JsonObject | None' = None self.write_control(_msg, command='close', channel=channel, **kwargs) self.drop_channel(channel) - if not self.endpoints: - self.no_endpoints.set() - # were we waiting to exit? if self._eof: - logger.debug(' endpoints remaining: %r', self.endpoints) + logger.debug(' %d endpoints remaining', len(self.endpoints)) if not self.endpoints and self.transport: logger.debug(' close transport') self.transport.close() @@ -237,30 +226,6 @@ def eof_received(self) -> bool: logger.debug(' endpoints remaining: %r', self.endpoints) return bool(self.endpoints) - _communication_done: Optional[asyncio.Future] = None - def do_closed(self, exc: Optional[Exception]) -> None: - # If we didn't send EOF yet, do it now. - if not self._eof: - self.eof_received() - - if self._communication_done is not None: - if exc is None: - self._communication_done.set_result(None) - else: - self._communication_done.set_exception(exc) - - async def communicate(self) -> None: - """Wait until communication is complete on the router and all endpoints are done.""" - assert self._communication_done is None - self._communication_done = asyncio.get_running_loop().create_future() - try: - await self._communication_done - except (BrokenPipeError, ConnectionResetError): - pass # these are normal occurrences when closed from the other side - finally: - self._communication_done = None - - # In an orderly exit, this is already done, but in case it wasn't - # orderly, we need to make sure the endpoints shut down anyway... - await self.no_endpoints.wait() + for rule in self.routing_rules: + rule.shutdown() diff --git a/src/cockpit/samples.py b/src/cockpit/samples.py index b821ad70005b..e2820d95214e 100644 --- a/src/cockpit/samples.py +++ b/src/cockpit/samples.py @@ -228,12 +228,8 @@ def sample(self, samples: Samples) -> None: num_sectors_read = fields[5] num_sectors_written = fields[9] - # ignore mdraid - if dev_major == '9': - continue - - # ignore device-mapper - if dev_name.startswith('dm-'): + # ignore device-mapper and md + if dev_major in ['9', '253']: continue # Skip partitions