Commit graph

11 commits

Author SHA1 Message Date
Christian Kellner
58e9211d71 api: implement canonical setup_stdio method
The `api.API` provides a `setup-stdio` method, that is meant to
be used by clients to replace their stdio with the supplied fds
from the server. Provide a canonical `api.setup_stdio` method
that will do exactly that.
2020-07-27 12:50:38 +01:00
Christian Kellner
1ce517e595 api: extract base class
Split out the part of `api.API` that is responsible for providing
the server infrastructure for the API; i.e. setting up the server
and the corresponding context manager and asynchronous event
handling. This leaves `API` itself which just the implementation
of the high level protocol and makes the API-server part re-usable.

NB: pylint, for some reason, confuses `API` and `BaseAPI`, like in
`test_monitor`. Annotate that accordingly.
2020-07-27 12:50:38 +01:00
Christian Kellner
3e18d8118c api: introduce pipeline monitoring
Introduce the concept of pipeline monitoring: A new monitor class is
passed to the pipeline.run() function. The main idea is to separate
the monitoring from the code that builds pipeline. Through the build
process various methods will be called on that object, representing
the different steps and their targets during the build process. This
can be used to fully stream the output of the various stages or just
indicate the start and finish of the individual stages.

This replaces the 'interactive' argument throughout the pipeline
code. The old interactive behavior is replicated via the new
`LogMonitor` class that logs the beginning of stages/assembler,
but also streams all the output of them to stdout.
The non-interactive behavior of not reporting anything is done by
using the `NullMonitor` class, which in turn outputs nothing.
2020-07-21 13:25:04 +02:00
Christian Kellner
5d55bc9aca api: use io.StringIO as output data buffer
Instead of using plain python strings and appending to them, use
'io.StringIO' which is a data structure meant to be used for i/o.
This should increase performance compared to plain strings.
2020-07-21 13:25:04 +02:00
Christian Kellner
1e88ee62e3 api: use pipe for output
Instead of either using a text file, in non-interactive mode, or
directly stdout otherwise, create a pipe and always use that as
for stdout/stderr when preparing the output for 'setup_stdio'.
This streamlines the two cases (interactive, non-interactive) and
as a result 'API.output' will always contain the full output data.
2020-07-21 13:25:04 +02:00
Christian Kellner
4c6ca0b4a0 api: properly close the event loop
Close the event loop when the context is exited, which will clear
the internal queues and shut down the executor of the event loop.
Not doing this will create a warning when the object is garbage
collected.
2020-07-21 13:25:04 +02:00
David Rheinsberg
4ad4da4658 osbuild: convert to jsoncomm
Convert the hard-coded DGRAM communication to util.jsoncomm. This
avoids hard-coding any IPC-details and simplifies the callers quite a
bit.
2020-04-21 13:47:38 +02:00
Tom Gundersen
794ec97bf3 api: add barriers
Ensure that the api sockets are created before entering the with clause.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-02-06 19:01:12 +01:00
Lars Karlitski
b9b2f99123 osbuild: create API sockets in the thread they're used in
This might (hopefully) fix a race in destructing the asyncio.EventLoop
that's used in all API classes, which leads to warnings about unhandled
exceptions on CI.

This also puts their creation closer to where the client-side sockets
are created.
2019-12-25 17:48:26 +01:00
Lars Karlitski
e0bb65dd71 api and remoteloop: don't close the passed-in socket
The socket that the osbuild and loop apis should talk on are passed into
their `__init__` function. The caller should be responsible for closing
those sockets.

This already happens in all current callers.

This fixes a non-fatal error on RHEL's python 3.6, because it was
calling `socket.close` on an already-closed socket:

    Traceback (most recent call last):
      File "/usr/lib64/python3.6/asyncio/base_events.py", line 529, in __del__
        self.close()
      File "/usr/lib64/python3.6/asyncio/unix_events.py", line 63, in close
        super().close()
      File "/usr/lib64/python3.6/asyncio/selector_events.py", line 99, in close
        self._close_self_pipe()
      File "/usr/lib64/python3.6/asyncio/selector_events.py", line 109, in _close_self_pipe
        self._remove_reader(self._ssock.fileno())
      File "/usr/lib64/python3.6/asyncio/selector_events.py", line 268, in _remove_reader
        key = self._selector.get_key(fd)
      File "/usr/lib64/python3.6/selectors.py", line 189, in get_key
        return mapping[fileobj]
      File "/usr/lib64/python3.6/selectors.py", line 70, in __getitem__
        fd = self._selector._fileobj_lookup(fileobj)
      File "/usr/lib64/python3.6/selectors.py", line 224, in _fileobj_lookup
        return _fileobj_to_fd(fileobj)
      File "/usr/lib64/python3.6/selectors.py", line 41, in _fileobj_to_fd
        raise ValueError("Invalid file descriptor: {}".format(fd))
    ValueError: Invalid file descriptor: -1
2019-12-15 12:05:14 +01:00
Christian Kellner
93e1c60460 api: new host side API to be used by the container
Introduce an osbuild API that can be used by the container to talk
to the osbuild host. It currently supports one method 'setup-stdio'
which should be used by the container to setup its standard input/
output so the stages can transparently do i/o with the osbuild host
via stdio.
The input data (args) is written to a temp-file backed buffer. The
output is either the host's stdout directly or another temp-file
backed buffer; the latter is re-opened (via /proc/self/fd) to get
another file-descriptor for the container, so in theory the host
and the container could do i/o to the same buffer independently.
2019-10-30 18:44:55 +01:00