6656 Commits

Author SHA1 Message Date
Julian Brost
30f7d74c7c JsonEncoder: wrap writer for flushing
This commit introduces intruduces a small helper class that wraps any writer
and provides a flush operation that performs the corresponding action if the
writer is an AsyncJsonWriter and does nothing otherwise.
2025-07-11 13:33:02 +02:00
Yonas Habteab
89418f38ee JsonEncoder: let the serializer replace invalid UTF-8 characters
Replacing invalid UTF-8 characters beforehand by our selves doesn't make
any sense, the serializer can literally perform the same replacement ops
with the exact same Unicode replacement character (U+FFFD) on its own.
So, why not just use it directly? Instead of wasting memory on a temporary
`String` object to always UTF-8 validate every and each value, we just
use the serializer to directly to dump the replaced char (if any) into
the output writer. No memory waste, no fuss!
2025-07-10 18:09:21 +02:00
Yonas Habteab
dad4c0889f JsonEncoder: lock olock conditionally & flush output regularly 2025-07-10 18:09:21 +02:00
Yonas Habteab
398b5e3193 Implement LockIfRequired() method for Namespace, Dictionary & Array 2025-07-10 18:09:21 +02:00
Yonas Habteab
57726fbb66 Do not require olock on frozen Namespace, Dictionary & Array 2025-07-10 18:09:21 +02:00
Yonas Habteab
2461e0415d Introduce JsonEncode helper function
It's just a wrapper around the `JsonEncoder` class to simplify its usage.
2025-07-10 18:09:21 +02:00
Yonas Habteab
9dd2e2a3ec Introduce JsonEncoder class 2025-07-10 18:09:21 +02:00
Yonas Habteab
1c61bced03 Introduce AsyncJsonWriter output adapter interface 2025-07-09 13:41:15 +02:00
Yonas Habteab
8ef921aa5e Implement bool operator for ObjectLock 2025-07-08 18:24:16 +02:00
Yonas Habteab
4c0628c24d Allow to defer lock on ObjectLock 2025-07-08 18:24:16 +02:00
Yonas Habteab
455d6fcde1 Introduce ValueGenerator class 2025-07-08 18:24:16 +02:00
Julian Brost
0ebcd2662d No longer allow overriding the frozen attribute of containers
The Array, Dictionary, and Namespace types provide a Freeze() method that makes
them read-only. So far, there was the possibility to call some methods with
`overrideFrozen=true` which would then bypass the corresponding check and allow
modification of the data structures nonetheless.

With 24b57f0d3a222835178e88489eabd595755ed883, this possibility was already
removed from the Namespace type. However, for interface compatibility, it kept
the parameter and just ignores it, throwing an exception on any modification on
a frozen instance.

The only place using `overrideFrozen` was processing of the `-D`/`--define`
command line flag that allows setting additional variables in the DSL. At the
time it is evaluated, there are no user-created data structures yet that could
be frozen, so the only frozen objects that could be encountered are Namespaces
(Icinga doesn't freeze other types by itself) and for these, `overrideFrozen`
already has no effect.

Hence, there is no harm in removing `overrideFrozen` altogether. This
simplifies the code and also means that frozen objects are now indeed read-only
without exceptions, allowing further optimizations regarding locking in the
future.
2025-07-08 14:16:20 +02:00
Chris Malton
ec48dae331 Correct a problem with expiry times not being passed through to AcknowledgeProblem 2025-06-23 11:57:29 +02:00
Julian Brost
1aa62d4bb9
Merge pull request #10420 from Icinga/bundled-perfdata-writers-fix
Serialize fields before queueing them to the workqueue
2025-06-17 10:17:27 +02:00
Johannes Schmidt
82bb636d2b Use WaitGroup to wait for or abort HTTP requests
The wait group gets passed to HttpServerConnection, then down to the
HttpHandlers. For those handlers that modify the program state, the
wait group is locked so ApiListener will wait on Stop() for the
request to complete. If the request iterates over config objects,
a further check on the state of the wait group is added to abort early
and not delay program shutdown. In that case, 503 responses will be
sent to the client.

Additionally, in HttpServerConnection, no further requests than the
one already started will be allowed once the wait group is joining.
2025-06-13 14:48:15 +02:00
Johannes Schmidt
33777f6f3f Disconnect JSON-RPC clients on ApiListner::Stop() 2025-06-13 14:48:15 +02:00
Johannes Schmidt
00802ed9fa Stop ApiListener::ListenerCoroutineProc() when Stop() is called 2025-06-13 14:48:11 +02:00
Johannes Schmidt
157e3750e3 Add IsLockable method to WaitGroup 2025-06-13 14:48:07 +02:00
Julian Brost
b27310fb6c
Merge pull request #10467 from Icinga/icingadb-calceventid-no-double-timestamptomilliseconds
IcingaDB::CalcEventID: No milliseconds as eventTime
2025-06-10 17:09:16 +02:00
Julian Brost
dcd9a2dd41
Merge pull request #10457 from Icinga/remove-superfluous-dsl-functions
Drop superfluous (broken) DSL functions
2025-06-10 16:33:37 +02:00
Julian Brost
c41fe682c5
Merge pull request #10452 from Icinga/streamline-redis-and-db-values
IcingaDB: Make Redis & DB values consistent
2025-06-10 11:30:07 +02:00
Julian Brost
a15b706ee3
Merge pull request #10372 from WuerthPhoenix/10364-race-condition-while-calculating-object-state
Keep object locked until events are dispatched.
2025-06-06 17:19:21 +02:00
Alvar Penning
9cdbbf4ede
IcingaDB::CalcEventID: No milliseconds as eventTime
CalcEventID's internal logic uses the TimestampToMilliseconds function
to convert the given eventTime to milliseconds. Within this function,
the timestamp is capped to prevent an overflow.

On three occasions, the input timestamp given to CalcEventID had already
been converted using TimestampToMilliseconds. The second
TimestampToMilliseconds function then checked the value and always
returned the capped maximum value. Consequently, CalcEventID returned
the same hash value for different timestamps.

This affected SendFlappingChange, SendAcknowledgementSet, and
SendAcknowledgementCleared. For example, when two acknowledgments were
created for the same service, the calculated event_id representing the
history table row would be identical.

Fixes #10465
2025-06-06 16:50:01 +02:00
Julian Brost
4d9e9e7ed6
Merge pull request #9924 from ymartin-ovh/pr-9916
Fix `/v1/actions/` deadlock & nullptr dereference
2025-06-06 15:15:51 +02:00
Julian Brost
4e08adc532
Merge pull request #10161 from Icinga/authBYhost-10157
ApiListener::UpdateObjectAuthority(): distribute auth. by object's host
2025-06-06 15:03:32 +02:00
Yonas Habteab
9e65a8b63b Fix compiler warnings of missing NotificationTypeAll case 2025-06-06 13:31:44 +02:00
Yonas Habteab
186571ec99 Refresh the states & types bitsets whenever states & types attrs change
Since the types and states attributes are user configurable and allowed to change at
runtime, we need to update the actual filter bitsets whenever these attributes change.
Otherwise, the filter bitsets would be stale and not reflect their current state.
2025-06-06 13:31:44 +02:00
Yonas Habteab
fd1927115a IcingaDB: Make is_acknowledged a bool & add is_sticky_acknowledgement field 2025-06-06 13:31:44 +02:00
Yonas Habteab
76d5915b3f IcingaDB: Set notification_histor#type to its string representation
So that Icinga DB (Go) daemon doesn't have to make the mappings again.
2025-06-06 13:31:44 +02:00
Yonas Habteab
7037b18b34 IcingaDB: Send the int representation of states & types filter 2025-06-06 13:31:44 +02:00
Yonas Habteab
ef1c0eb9b3 IcingaDB: Set state_type to hard or soft and not int 2025-06-06 13:31:44 +02:00
Yonas Habteab
953a2e2e96 Merge {host,service}::StateTypeToString() & drop unused StateTypeFromString() 2025-06-06 13:31:44 +02:00
Yonas Habteab
5d11df1abf IcingaDB: Send the string representation of comment#entry_type to Redis 2025-06-06 13:31:44 +02:00
Yonas Habteab
bc5db9834f Drop System#track_parents DSL function
No external user needs to manipulate the actual object dependency
graphs. This was maybe introduced for debugging purposes at that time
but if someone messes with this in prod - good luck with that. Oh, apart
from that it's broken :( and doesn't track parents as its implies but
children.
2025-06-03 17:09:57 +02:00
Yonas Habteab
9577af8e6d Drop Checkable#process_check_result() DSL function
Not sure why it's introduced in the first place, maybe for debugging
purposes at the early stage of Icinga 2 dev but I failed to see an
actual useful use case for it that's worth its maintenance burden. So,
this commit dropped it entirely from the DSL language.
2025-06-03 17:09:57 +02:00
Yannick Martin
e6fc1b91a7
AddComment: return Comment::Ptr instead of String containing the name
Mimic 88e5744d54f79ab6a84260bd4a8d2cc0ffd43465 and address nullptr on concurrent
  add-comment / remove-comment actions.
2025-06-03 17:00:07 +02:00
Yonas Habteab
3d04eb456a
Merge pull request #10415 from Icinga/abort-no-endpoint-conns
Abort connections with no valid endpoint
2025-06-02 16:21:46 +02:00
William Calliari
9d40de78eb
Address comments from review 2025-05-29 09:16:46 +02:00
William Calliari
abf2fb392b
Keep object locked until events are dispatched. 2025-05-29 09:16:44 +02:00
Julian Brost
c253e7eb6e
Merge pull request #10397 from Icinga/activation-priority-10179
Checkable#ProcessCheckResult(): discard🗑️ CR or delay its producers shutdown
2025-05-28 12:30:40 +02:00
Yonas Habteab
7d2f1c2030 Drop Windows VISTA from the supported platform
Boost `1.88.0` introduced a feature [^1] that makes use of the Windows API, but it
uses API functions that are only available with `PSAPI_VERSION >= 2` and
Windows VISTA only supports `PSAPI_VERSION == 1`. Actually, that new feature
can also be disabled by setting the `BOOST_STACKTRACE_DISABLE_OFFSET_ADDR_BASE`
macro, but since it seems to be a useful feature and isn't even disabled by default,
we can just drop it that ancient Windows version instead of disabling it.

[^1]: https://github.com/boostorg/stacktrace/pull/200
2025-05-28 09:39:03 +02:00
Yonas Habteab
d265329a17
Merge commit from fork
Fix for master
2025-05-27 13:50:26 +02:00
Yannick Martin
ab58ff2928
fix api deadlock that can appears on two simultaneous actions
With this mutex, we can have deadlock in the following case:
    1/ Thread A processes a /v1/actions/acknowledge-problem request and locks the checkable
    2/ Thread B processes a /v1/actions/add-comment and enters first the ConfigItem::ActivateItems() method and locks the static mutex there and starts the just created comment object, which triggers the OnCommentAdded() event.
    3/ Thread A wants to activate the just created ack comment as well but since the mutex is already locked by TB, it blocks.
    4/ Thread B's OnCommentAdded() even dispatch causes the IcingaDB::CommentAddedHandler() to be called and implicitly triggers full state update for the checkable. Now, the state serialization of that checkable (remember that's the same checkable currently locked by TA) also includes computing its severity, thus it calls either service->GetSeverity() or host->GetSeverity(). However, since computing the checkable severity (as of now) requires acquiring the object lock, and boom - they deadlock each other.
2025-05-26 15:05:42 +02:00
Alexander Aleksandrovič Klimov
56d9f38b35
Merge pull request #10456 from Icinga/SharedObject-delete
SharedObject: delete unused methods
2025-05-26 10:00:52 +02:00
Alexander A. Klimov
4f351f625f SharedObject: delete unused methods
None of the derived classes use them, none shall have to explicitly delete them.
2025-05-23 15:47:02 +02:00
Alexander A. Klimov
36743f3100 Checkable#ProcessCheckResult(): discard CR or delay its producers shutdown 2025-05-23 14:53:58 +02:00
Alexander A. Klimov
f4691dd054 Require to pass WaitGroup::Ptr to several methods
Namely:

Checkable#ProcessCheckResult()
ClusterCheckTask::ScriptFunc()
ClusterZoneCheckTask::ScriptFunc()
DummyCheckTask::ScriptFunc()
ExceptionCheckTask::ScriptFunc()
IcingaCheckTask::ScriptFunc()
IfwApiCheckTask::ScriptFunc()
NullCheckTask::ScriptFunc()
PluginCheckTask::ScriptFunc()
RandomCheckTask::ScriptFunc()
SleepCheckTask::ScriptFunc()
IdoCheckTask::ScriptFunc()
IcingadbCheck::ScriptFunc()
CheckCommand#Execute()
Checkable#ExecuteCheck()
ClusterEvents::ExecuteCheckFromQueue()
ExternalCommandProcessor::Process*CheckResult()
ExternalCommandCallback
ExternalCommandProcessor::Execute()
ExternalCommandProcessor::ExecuteFromFile()
ExternalCommandProcessor::ProcessFile()
LivestatusQuery#ExecuteCommandHelper()
LivestatusQuery#Execute()
2025-05-23 14:53:58 +02:00
Alexander A. Klimov
c7cca7b460 Add a StoppableWaitGroup, and join it on #Stop(), to:
ApiListener
CheckerComponent
ExternalCommandListener
LivestatusListener
2025-05-23 14:53:58 +02:00
Alexander A. Klimov
18fb93fc11 Introduce WaitGroup and StoppableWaitGroup 2025-05-23 14:53:58 +02:00
Alexander A. Klimov
77b86bba52 Move l_MyCapabilities -> ApiCapabilities::MyCapabilities 2025-05-23 10:44:16 +02:00