• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mendersoftware / mender / 2281564137

23 Jan 2026 10:59AM UTC coverage: 81.48% (+1.7%) from 79.764%
2281564137

push

gitlab-ci

michalkopczan
fix: Schedule next deployment poll if current one failed early causing no handler to be called

Ticket: MEN-9144
Changelog: Fix a hang when polling for deployment failed early causing no handler of API response
to be called. Added handler call for this case, causing the deployment polling
to continue.

Signed-off-by: Michal Kopczan <michal.kopczan@northern.tech>

1 of 1 new or added line in 1 file covered. (100.0%)

327 existing lines in 44 files now uncovered.

8839 of 10848 relevant lines covered (81.48%)

20226.53 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.3
/src/mender-update/daemon/state_machine.hpp
1
// Copyright 2023 Northern.tech AS
2
//
3
//    Licensed under the Apache License, Version 2.0 (the "License");
4
//    you may not use this file except in compliance with the License.
5
//    You may obtain a copy of the License at
6
//
7
//        http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//    Unless required by applicable law or agreed to in writing, software
10
//    distributed under the License is distributed on an "AS IS" BASIS,
11
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//    See the License for the specific language governing permissions and
13
//    limitations under the License.
14

15
#ifndef MENDER_UPDATE_STATE_MACHINE_HPP
16
#define MENDER_UPDATE_STATE_MACHINE_HPP
17

18
#include <common/error.hpp>
19
#include <common/events.hpp>
20
#include <common/state_machine.hpp>
21

22
#include <mender-update/context.hpp>
23

24
#include <mender-update/daemon/context.hpp>
25
#include <mender-update/daemon/state_events.hpp>
26
#include <mender-update/daemon/states.hpp>
27

28
namespace mender {
29
namespace update {
30
namespace daemon {
31

32
namespace error = mender::common::error;
33
namespace events = mender::common::events;
34
namespace sm = mender::common::state_machine;
35

36
namespace context = mender::update::context;
37

38
class StateMachine {
39
public:
40
        StateMachine(Context &ctx, events::EventLoop &event_loop);
41
        // For tests: Use a state machine with custom minimum wait times.
42
        StateMachine(
43
                Context &ctx, events::EventLoop &event_loop, chrono::milliseconds minimum_wait_time);
44

45
        void LoadStateFromDb();
46

47
        error::Error Run();
48

49
        // Mainly for tests.
50
        void StopAfterDeployment();
51
#ifndef NDEBUG
52
        void StopAfterDeployments(int number);
53
#endif
54

55
private:
56
        Context &ctx_;
57
        events::EventLoop &event_loop_;
58
        events::SignalHandler check_update_handler_;
59
        events::SignalHandler inventory_update_handler_;
60
        events::SignalHandler termination_handler_;
61

62
        error::Error RegisterSignalHandlers();
63

64
        ///////////////////////////////////////////////////////////////////////////////////////////
65
        // Main states
66
        ///////////////////////////////////////////////////////////////////////////////////////////
67

68
        InitState init_state_;
69

70
        IdleState idle_state_;
71
        ScheduleNextPollState schedule_submit_inventory_state_;
72
        ScheduleNextPollState schedule_poll_for_deployment_state_;
73
        SubmitInventoryState submit_inventory_state_;
74
        PollForDeploymentState poll_for_deployment_state_;
75
        SendStatusUpdateState send_download_status_state_;
76
        UpdateDownloadState update_download_state_;
77
        UpdateDownloadCancelState update_download_cancel_state_;
78
        SendStatusUpdateState send_install_status_state_;
79
        UpdateInstallState update_install_state_;
80

81
        // Currently used same state code for checking NeedsReboot both before normal reboot, and
82
        // before rollback reboot, since currently they have the same behavior, only different state
83
        // transitions.
84
        UpdateCheckRebootState update_check_reboot_state_;
85
        UpdateCheckRebootState update_check_rollback_reboot_state_;
86

87
        SendStatusUpdateState send_reboot_status_state_;
88
        UpdateRebootState update_reboot_state_;
89
        UpdateVerifyRebootState update_verify_reboot_state_;
90
        SendStatusUpdateState send_commit_status_state_;
91
        UpdateBeforeCommitState update_before_commit_state_;
92
        UpdateCommitState update_commit_state_;
93
        UpdateAfterCommitState update_after_commit_state_;
94
        UpdateCheckRollbackState update_check_rollback_state_;
95
        UpdateRollbackState update_rollback_state_;
96
        UpdateRollbackRebootState update_rollback_reboot_state_;
97
        UpdateVerifyRollbackRebootState update_verify_rollback_reboot_state_;
98
        UpdateRollbackSuccessfulState update_rollback_successful_state_;
99
        UpdateFailureState update_failure_state_;
100
        UpdateSaveProvidesState update_save_provides_state_;
101
        UpdateRollbackSuccessfulState update_rollback_not_needed_state_;
102
        UpdateCleanupState update_cleanup_state_;
103
        SendStatusUpdateState send_final_status_state_;
104
        ClearArtifactDataState clear_artifact_data_state_;
105

106
        StateLoopState state_loop_state_;
107

108
        EndOfDeploymentState end_of_deployment_state_;
109

110
        ExitState exit_state_;
111

112
        sm::StateMachine<Context, StateEvent> main_states_;
113

114
        class StateScripts {
115
        public:
116
                StateScripts(
96✔
117
                        events::EventLoop &loop,
118
                        chrono::seconds script_timeout,
119
                        chrono::seconds retry_interval,
120
                        chrono::seconds retry_timeout,
121
                        const string &artifact_script_path,
122
                        const string &rootfs_script_path) :
96✔
123
                        idle_enter_(
96✔
124
                                loop,
125
                                script_executor::State::Idle,
126
                                script_executor::Action::Enter,
127
                                script_timeout,
128
                                retry_interval,
129
                                retry_timeout,
130
                                artifact_script_path,
131
                                rootfs_script_path,
132
                                script_executor::OnError::Ignore),
133
                        idle_leave_deploy_(
96✔
134
                                loop,
135
                                script_executor::State::Idle,
136
                                script_executor::Action::Leave,
137
                                script_timeout,
138
                                retry_interval,
139
                                retry_timeout,
140
                                artifact_script_path,
141
                                rootfs_script_path,
142
                                script_executor::OnError::Ignore),
143
                        idle_leave_inv_(
96✔
144
                                loop,
145
                                script_executor::State::Idle,
146
                                script_executor::Action::Leave,
147
                                script_timeout,
148
                                retry_interval,
149
                                retry_timeout,
150
                                artifact_script_path,
151
                                rootfs_script_path,
152
                                script_executor::OnError::Ignore),
153
                        sync_enter_deployment_(
96✔
154
                                loop,
155
                                script_executor::State::Sync,
156
                                script_executor::Action::Enter,
157
                                script_timeout,
158
                                retry_interval,
159
                                retry_timeout,
160
                                artifact_script_path,
161
                                rootfs_script_path,
162
                                script_executor::OnError::Fail),
163
                        sync_enter_inventory_(
96✔
164
                                loop,
165
                                script_executor::State::Sync,
166
                                script_executor::Action::Enter,
167
                                script_timeout,
168
                                retry_interval,
169
                                retry_timeout,
170
                                artifact_script_path,
171
                                rootfs_script_path,
172
                                script_executor::OnError::Fail),
173
                        sync_leave_(
96✔
174
                                loop,
175
                                script_executor::State::Sync,
176
                                script_executor::Action::Leave,
177
                                script_timeout,
178
                                retry_interval,
179
                                retry_timeout,
180
                                artifact_script_path,
181
                                rootfs_script_path,
182
                                script_executor::OnError::Fail),
183
                        sync_leave_download_(
96✔
184
                                loop,
185
                                script_executor::State::Sync,
186
                                script_executor::Action::Leave,
187
                                script_timeout,
188
                                retry_interval,
189
                                retry_timeout,
190
                                artifact_script_path,
191
                                rootfs_script_path,
192
                                script_executor::OnError::Fail),
193
                        sync_error_(
96✔
194
                                loop,
195
                                script_executor::State::Sync,
196
                                script_executor::Action::Error,
197
                                script_timeout,
198
                                retry_interval,
199
                                retry_timeout,
200
                                artifact_script_path,
201
                                rootfs_script_path,
202
                                script_executor::OnError::Ignore),
203
                        sync_error_download_(
96✔
204
                                loop,
205
                                script_executor::State::Sync,
206
                                script_executor::Action::Error,
207
                                script_timeout,
208
                                retry_interval,
209
                                retry_timeout,
210
                                artifact_script_path,
211
                                rootfs_script_path,
212
                                script_executor::OnError::Ignore),
213
                        download_enter_(
96✔
214
                                loop,
215
                                script_executor::State::Download,
216
                                script_executor::Action::Enter,
217
                                script_timeout,
218
                                retry_interval,
219
                                retry_timeout,
220
                                artifact_script_path,
221
                                rootfs_script_path,
222
                                Context::kUpdateStateDownload,
223
                                script_executor::OnError::Fail),
224
                        download_leave_(
96✔
225
                                loop,
226
                                script_executor::State::Download,
227
                                script_executor::Action::Leave,
228
                                script_timeout,
229
                                retry_interval,
230
                                retry_timeout,
231
                                artifact_script_path,
232
                                rootfs_script_path,
233
                                script_executor::OnError::Fail),
234
                        download_leave_save_provides(
96✔
235
                                loop,
236
                                script_executor::State::Download,
237
                                script_executor::Action::Leave,
238
                                script_timeout,
239
                                retry_interval,
240
                                retry_timeout,
241
                                artifact_script_path,
242
                                rootfs_script_path,
243
                                script_executor::OnError::Fail),
244
                        download_error_(
96✔
245
                                loop,
246
                                script_executor::State::Download,
247
                                script_executor::Action::Error,
248
                                script_timeout,
249
                                retry_interval,
250
                                retry_timeout,
251
                                artifact_script_path,
252
                                rootfs_script_path,
253
                                script_executor::OnError::Ignore),
254
                        install_enter_(
96✔
255
                                loop,
256
                                script_executor::State::ArtifactInstall,
257
                                script_executor::Action::Enter,
258
                                script_timeout,
259
                                retry_interval,
260
                                retry_timeout,
261
                                artifact_script_path,
262
                                rootfs_script_path,
263
                                Context::kUpdateStateArtifactInstall,
264
                                script_executor::OnError::Fail),
265
                        install_leave_(
96✔
266
                                loop,
267
                                script_executor::State::ArtifactInstall,
268
                                script_executor::Action::Leave,
269
                                script_timeout,
270
                                retry_interval,
271
                                retry_timeout,
272
                                artifact_script_path,
273
                                rootfs_script_path,
274
                                script_executor::OnError::Fail),
275
                        install_error_(
96✔
276
                                loop,
277
                                script_executor::State::ArtifactInstall,
278
                                script_executor::Action::Error,
279
                                script_timeout,
280
                                retry_interval,
281
                                retry_timeout,
282
                                artifact_script_path,
283
                                rootfs_script_path,
284
                                script_executor::OnError::Ignore),
285
                        install_error_rollback_(
96✔
286
                                loop,
287
                                script_executor::State::ArtifactInstall,
288
                                script_executor::Action::Error,
289
                                script_timeout,
290
                                retry_interval,
291
                                retry_timeout,
292
                                artifact_script_path,
293
                                rootfs_script_path,
294
                                script_executor::OnError::Fail),
295
                        reboot_enter_(
96✔
296
                                loop,
297
                                script_executor::State::ArtifactReboot,
298
                                script_executor::Action::Enter,
299
                                script_timeout,
300
                                retry_interval,
301
                                retry_timeout,
302
                                artifact_script_path,
303
                                rootfs_script_path,
304
                                Context::kUpdateStateArtifactReboot,
305
                                script_executor::OnError::Fail),
306
                        reboot_leave_(
96✔
307
                                loop,
308
                                script_executor::State::ArtifactReboot,
309
                                script_executor::Action::Leave,
310
                                script_timeout,
311
                                retry_interval,
312
                                retry_timeout,
313
                                artifact_script_path,
314
                                rootfs_script_path,
315
                                script_executor::OnError::Fail),
316
                        reboot_error_(
96✔
317
                                loop,
318
                                script_executor::State::ArtifactReboot,
319
                                script_executor::Action::Error,
320
                                script_timeout,
321
                                retry_interval,
322
                                retry_timeout,
323
                                artifact_script_path,
324
                                rootfs_script_path,
325
                                script_executor::OnError::Ignore),
326
                        rollback_enter_(
96✔
327
                                loop,
328
                                script_executor::State::ArtifactRollback,
329
                                script_executor::Action::Enter,
330
                                script_timeout,
331
                                retry_interval,
332
                                retry_timeout,
333
                                artifact_script_path,
334
                                rootfs_script_path,
335
                                Context::kUpdateStateArtifactRollback,
336
                                script_executor::OnError::Fail,
337
                                true),
338
                        rollback_leave_(
96✔
339
                                loop,
340
                                script_executor::State::ArtifactRollback,
341
                                script_executor::Action::Leave,
342
                                script_timeout,
343
                                retry_interval,
344
                                retry_timeout,
345
                                artifact_script_path,
346
                                rootfs_script_path,
347
                                script_executor::OnError::Fail),
348
                        rollback_leave_error_(
96✔
349
                                loop,
350
                                script_executor::State::ArtifactRollback,
351
                                script_executor::Action::Leave,
352
                                script_timeout,
353
                                retry_interval,
354
                                retry_timeout,
355
                                artifact_script_path,
356
                                rootfs_script_path,
357
                                script_executor::OnError::Ignore),
358
                        commit_enter_(
96✔
359
                                loop,
360
                                script_executor::State::ArtifactCommit,
361
                                script_executor::Action::Enter,
362
                                script_timeout,
363
                                retry_interval,
364
                                retry_timeout,
365
                                artifact_script_path,
366
                                rootfs_script_path,
367
                                Context::kUpdateStateArtifactCommit,
368
                                script_executor::OnError::Fail),
369
                        commit_leave_(
96✔
370
                                loop,
371
                                script_executor::State::ArtifactCommit,
372
                                script_executor::Action::Leave,
373
                                script_timeout,
374
                                retry_interval,
375
                                retry_timeout,
376
                                artifact_script_path,
377
                                rootfs_script_path,
378
                                script_executor::OnError::Fail),
379
                        commit_error_(
96✔
380
                                loop,
381
                                script_executor::State::ArtifactCommit,
382
                                script_executor::Action::Error,
383
                                script_timeout,
384
                                retry_interval,
385
                                retry_timeout,
386
                                artifact_script_path,
387
                                rootfs_script_path,
388
                                script_executor::OnError::Ignore),
389
                        commit_error_save_provides_(
96✔
390
                                loop,
391
                                script_executor::State::ArtifactCommit,
392
                                script_executor::Action::Error,
393
                                script_timeout,
394
                                retry_interval,
395
                                retry_timeout,
396
                                artifact_script_path,
397
                                rootfs_script_path,
398
                                script_executor::OnError::Fail),
399
                        failure_enter_(
96✔
400
                                loop,
401
                                script_executor::State::ArtifactFailure,
402
                                script_executor::Action::Enter,
403
                                script_timeout,
404
                                retry_interval,
405
                                retry_timeout,
406
                                artifact_script_path,
407
                                rootfs_script_path,
408
                                Context::kUpdateStateArtifactFailure,
409
                                script_executor::OnError::Fail,
410
                                true), // IsFailureState
411
                        failure_leave_update_save_provides_(
96✔
412
                                loop,
413
                                script_executor::State::ArtifactFailure,
414
                                script_executor::Action::Leave,
415
                                script_timeout,
416
                                retry_interval,
417
                                retry_timeout,
418
                                artifact_script_path,
419
                                rootfs_script_path,
420
                                script_executor::OnError::Fail),
421
                        failure_leave_state_loop_state_(
96✔
422
                                loop,
423
                                script_executor::State::ArtifactFailure,
424
                                script_executor::Action::Leave,
425
                                script_timeout,
426
                                retry_interval,
427
                                retry_timeout,
428
                                artifact_script_path,
429
                                rootfs_script_path,
430
                                script_executor::OnError::Fail),
431
                        rollback_reboot_enter_(
96✔
432
                                loop,
433
                                script_executor::State::ArtifactRollbackReboot,
434
                                script_executor::Action::Enter,
435
                                script_timeout,
436
                                retry_interval,
437
                                retry_timeout,
438
                                artifact_script_path,
439
                                rootfs_script_path,
440
                                Context::kUpdateStateArtifactRollbackReboot,
441
                                script_executor::OnError::Fail,
442
                                true),
443
                        rollback_reboot_leave_(
96✔
444
                                loop,
445
                                script_executor::State::ArtifactRollbackReboot,
446
                                script_executor::Action::Leave,
447
                                script_timeout,
448
                                retry_interval,
449
                                retry_timeout,
450
                                artifact_script_path,
451
                                rootfs_script_path,
452
                                script_executor::OnError::Fail),
453
                        rollback_reboot_error_(
96✔
454
                                loop,
455
                                script_executor::State::ArtifactRollbackReboot,
456
                                script_executor::Action::Error,
457
                                script_timeout,
458
                                retry_interval,
459
                                retry_timeout,
460
                                artifact_script_path,
461
                                rootfs_script_path,
462
                                script_executor::OnError::Ignore) {};
96✔
463

464
                StateScriptState idle_enter_;
465
                StateScriptState idle_leave_deploy_;
466
                StateScriptState idle_leave_inv_;
467

468
                StateScriptState sync_enter_deployment_;
469
                StateScriptState sync_enter_inventory_;
470
                StateScriptState sync_leave_;
471
                StateScriptState sync_leave_download_;
472
                StateScriptState sync_error_;
473
                StateScriptState sync_error_download_;
474

475
                SaveStateScriptState download_enter_;
476
                StateScriptState download_leave_;
477
                StateScriptState download_leave_save_provides;
478
                StateScriptState download_error_;
479

480
                SaveStateScriptState install_enter_;
481
                StateScriptState install_leave_;
482
                StateScriptState install_error_;
483
                StateScriptState install_error_rollback_;
484

485
                SaveStateScriptState reboot_enter_;
486
                StateScriptState reboot_leave_;
487
                StateScriptState reboot_error_;
488

489
                SaveStateScriptState rollback_enter_;
490
                StateScriptState rollback_leave_;
491
                StateScriptState rollback_leave_error_;
492

493
                SaveStateScriptState commit_enter_;
494
                StateScriptState commit_leave_;
495
                StateScriptState commit_error_;
496
                StateScriptState commit_error_save_provides_;
497

498
                SaveStateScriptState failure_enter_;
499
                StateScriptState failure_leave_update_save_provides_;
500
                StateScriptState failure_leave_state_loop_state_;
501

502
                SaveStateScriptState rollback_reboot_enter_;
503
                StateScriptState rollback_reboot_leave_;
504
                StateScriptState rollback_reboot_error_;
505

506
        } state_scripts_;
507

508
        ///////////////////////////////////////////////////////////////////////////////////////////
509
        // Deployment tracking states
510
        ///////////////////////////////////////////////////////////////////////////////////////////
511

UNCOV
512
        class DeploymentTracking {
×
513
        public:
514
                DeploymentTracking();
515

516
                EmptyState idle_state_;
517
                deployment_tracking::NoFailuresState no_failures_state_;
518
                deployment_tracking::FailureState failure_state_;
519
                deployment_tracking::RollbackAttemptedState rollback_attempted_state_;
520
                deployment_tracking::RollbackFailedState rollback_failed_state_;
521

522
                // Not used for actual deployment work (that's main states), but for tracking the failure
523
                // and rollback events. This is used to automatically update the running context so that the
524
                // correct database entries are saved at the end of the update. The alternative to this
525
                // state machine would be to update the context in every state that can fail, but this state
526
                // machine does it automatically based on the submitted events.
527
                sm::StateMachine<Context, StateEvent> states_;
528
        } deployment_tracking_;
529

530
        sm::StateMachineRunner<Context, StateEvent> runner_;
531
};
532

533
} // namespace daemon
534
} // namespace update
535
} // namespace mender
536

537
#endif // MENDER_UPDATE_STATE_MACHINE_HPP
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc