We based this on Twisted's own settings, which use hatchling as a
build system.
With these changes, the project is now published as RC on pypi, mostly
to secure the module name.
It has not been tested yet, but we should be able to install using pip
and run the project as a mdoule.
This mostly relates to timeouts.
We are using minutes because it is human-friendly, but some could
benefit in certain cases from using seconds.
We are open to changing this in the future.
We will want to issue configuration reloads with USR1 signals soon
enough, in order to achieve this we need to be able to reload each
object without losing state.
In this commit, we add reload methods to most objects, so we can
easily propagate the reload order.
We should look into upstreaming these fixes to twisted.
Twisted's RecvLine currently discards anything other than ascii
printable characters, which happens to include things like: àéñü or
l·l, which we use extensively.
Since RecvLine processes each 'keystroke' on its own, it only has
access to one byte at a time, which means we get to have "fun"
implementing our own simple Unicode-state parsing.
Python's documentation happened to be quite useful as a reminder:
https://docs.python.org/3/library/codecs.html#encodings-and-unicodeCloses#4
The strange bytes came from `setMode` in:
7697871b4d/src/twisted/conch/insults/insults.py (L726-L729)
```
def setModes(self, modes):
# XXX Support ANSI-Compatible private modes
modesBytes = b";".join(b"%d" % (mode,) for mode in modes)
self.write(b"\x1b[" + modesBytes + b"h")
```
Instead of calling this method, we now set the mode attribute of the
protocol directly and early.
Having a better detection of interactive mode simplifies our code and
makes it more reliable too.
Previously any command "ssh user@host CMD" would hang due to us not
handling the execCommand method.
While implementing that, we reliased that exit codes were not being
propagated and that overall handling of non-interactive sessions was
subpar.
This commit tries to address that and closes#2
While there, we get rid of annoying:
Failure: twisted.internet.defer.CancelledError
Whenever we would cancel a deferred (which we use a lot in this app)
It seems like we never deployed this long in production :-), so there
were some confusing things left to fix (this was originally written in
a weekend):
- Some constants were repeated throughout the code
- Naming was inconsistent, which meant that setting up the status page
was not an entirely easy feat, now the sample file can actually be
followed
- Due to naming being inconsistent, alert names were given an
importance that they should have never had
- Given that multiple alerts with different severity levels can be
triggered on Prometheus' side (e.g. warning probably always trigger
when critical triggers), we could have seen ourselves in the
position of receiving them in an undefined order, and switching from
"critical" to "warning" in a very flaky fashion.
- Similarly, when an alert had been *resolved*, this was not timely
reflected on AdlerManager, instead it waited until prometheus
stopped sending the alert, then for AdlerManager's timeout to occur
- We now filter received alerts by using an 'adlermanager' label,
whose value should match the domain on which the status page is
being served. This is due to a misinterpretation of Prometheus'
configuration for alertmanagers called 'relabel_configs'.
We expected it to apply to alerts sent to alertmanager, instead, it
seems to be a functionality to modify alertmanager's settings
themselves.
Since alert_relabel_configs applies globally, it also is not a good
fit to selectively drop certain alerts.
This does mean that, even if not published, AdlerManager potentially
receives all alerts produced by the Prometheus instance.
https://prometheus.io/docs/prometheus/latest/configuration/configuration/#alert_relabel_configs
- For the heartbeat alert, instead of relying on the funnily named
EverythingIsFine (insert meme here) alert, we now rely on a label
called 'heartbeat' being set.
- The text shown when there are alerts now uses annotations.summary
when available.