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

mendersoftware / mender / 1019451413

28 Sep 2023 10:09AM UTC coverage: 78.477%. Remained the same
1019451413

push

gitlab-ci

kacf
chore: Make our `optional` use compatible with C++17.

If the standard is pre-C++17, we use the `optional-lite` library, else
we use the one in `std`.

Signed-off-by: Kristian Amlie <kristian.amlie@northern.tech>

17 of 17 new or added lines in 6 files covered. (100.0%)

5546 of 7067 relevant lines covered (78.48%)

11103.41 hits per line

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

85.71
/mender-update/update_module/v3/update_module.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_UPDATE_MODULE_HPP
16
#define MENDER_UPDATE_UPDATE_MODULE_HPP
17

18
#include <vector>
19
#include <string>
20

21
#include <common/conf.hpp>
22
#include <common/error.hpp>
23
#include <common/expected.hpp>
24
#include <common/optional.hpp>
25
#include <common/processes.hpp>
26

27
#include <mender-update/context.hpp>
28

29
#include <artifact/artifact.hpp>
30

31
class UpdateModuleTests;
32

33
namespace mender {
34
namespace update {
35
namespace update_module {
36
namespace v3 {
37

38
using namespace std;
39

40
namespace conf = mender::common::conf;
41
namespace context = mender::update::context;
42
namespace error = mender::common::error;
43
namespace events = mender::common::events;
44
namespace expected = mender::common::expected;
45
namespace io = mender::common::io;
46
namespace procs = mender::common::processes;
47

48
using context::MenderContext;
49
using expected::ExpectedBool;
50
using expected::ExpectedStringVector;
51
using mender::artifact::Artifact;
52

53
enum class RebootAction { No, Automatic, Yes };
54
enum class State {
55
        ProvidePayloadFileSizes,
56
        Download,
57
        DownloadWithFileSizes,
58
        ArtifactInstall,
59
        NeedsReboot,
60
        ArtifactReboot,
61
        ArtifactCommit,
62
        SupportsRollback,
63
        ArtifactRollback,
64
        ArtifactVerifyReboot,
65
        ArtifactRollbackReboot,
66
        ArtifactVerifyRollbackReboot,
67
        ArtifactFailure,
68
        Cleanup,
69

70
        LastState
71
};
72

73
std::string StateToString(State state);
74

75
using ExpectedRebootAction = expected::expected<RebootAction, error::Error>;
76

77
using ExpectedWriterHandler = function<void(io::ExpectedAsyncWriterPtr)>;
78

79
class UpdateModule {
80
public:
81
        UpdateModule(MenderContext &ctx, const string &payload_type);
82

83
        string GetUpdateModulePath() {
84
                return update_module_path_;
1✔
85
        }
86
        string GetUpdateModuleWorkDir() {
87
                return update_module_workdir_;
1✔
88
        }
89
        void SetUpdateModulePath(const string &path) {
90
                update_module_path_ = path;
40✔
91
        }
40✔
92
        void SetUpdateModuleWorkDir(const string &path) {
93
                update_module_workdir_ = path;
40✔
94
        }
40✔
95

96
        error::Error PrepareFileTreeDeviceParts(const string &path);
97
        error::Error CleanAndPrepareFileTree(
98
                const string &path, artifact::PayloadHeaderView &payload_meta_data);
99
        error::Error EnsureRootfsImageFileTree(const string &path);
100
        error::Error DeleteFileTree(const string &path);
101

102
        using ProvidePayloadFileSizesFinishedHandler = function<void(ExpectedBool)>;
103
        using StateFinishedHandler = function<void(error::Error)>;
104
        using NeedsRebootFinishedHandler = function<void(ExpectedRebootAction)>;
105
        using SupportsRollbackFinishedHandler = function<void(ExpectedBool)>;
106

107
        // Use same names as in Update Module specification.
108
        ExpectedBool ProvidePayloadFileSizes();
109
        error::Error AsyncProvidePayloadFileSizes(
110
                events::EventLoop &event_loop, ProvidePayloadFileSizesFinishedHandler handler);
111
        error::Error Download(artifact::Payload &payload);
112
        void AsyncDownload(
113
                events::EventLoop &event_loop, artifact::Payload &payload, StateFinishedHandler handler);
114
        error::Error DownloadWithFileSizes(artifact::Payload &payload);
115
        void AsyncDownloadWithFileSizes(
116
                events::EventLoop &event_loop, artifact::Payload &payload, StateFinishedHandler handler);
117
        error::Error ArtifactInstall();
118
        error::Error AsyncArtifactInstall(events::EventLoop &event_loop, StateFinishedHandler handler);
119
        ExpectedRebootAction NeedsReboot();
120
        error::Error AsyncNeedsReboot(
121
                events::EventLoop &event_loop, NeedsRebootFinishedHandler handler);
122
        error::Error ArtifactReboot();
123
        error::Error AsyncArtifactReboot(events::EventLoop &event_loop, StateFinishedHandler handler);
124
        error::Error ArtifactCommit();
125
        error::Error AsyncArtifactCommit(events::EventLoop &event_loop, StateFinishedHandler handler);
126
        ExpectedBool SupportsRollback();
127
        error::Error AsyncSupportsRollback(
128
                events::EventLoop &event_loop, SupportsRollbackFinishedHandler handler);
129
        error::Error ArtifactRollback();
130
        error::Error AsyncArtifactRollback(events::EventLoop &event_loop, StateFinishedHandler handler);
131
        error::Error ArtifactVerifyReboot();
132
        error::Error AsyncArtifactVerifyReboot(
133
                events::EventLoop &event_loop, StateFinishedHandler handler);
134
        error::Error ArtifactRollbackReboot();
135
        error::Error AsyncArtifactRollbackReboot(
136
                events::EventLoop &event_loop, StateFinishedHandler handler);
137
        error::Error ArtifactVerifyRollbackReboot();
138
        error::Error AsyncArtifactVerifyRollbackReboot(
139
                events::EventLoop &event_loop, StateFinishedHandler handler);
140
        error::Error ArtifactFailure();
141
        error::Error AsyncArtifactFailure(events::EventLoop &event_loop, StateFinishedHandler handler);
142
        error::Error Cleanup();
143
        error::Error AsyncCleanup(events::EventLoop &event_loop, StateFinishedHandler handler);
144

145
        error::Error AsyncSystemReboot(events::EventLoop &event_loop, StateFinishedHandler handler);
146

147
        static error::Error GetProcessError(const error::Error &err);
148

149
private:
150
        error::Error AsyncCallStateCapture(
151
                events::EventLoop &loop, State state, function<void(expected::ExpectedString)> handler);
152
        expected::ExpectedString CallStateCapture(State state);
153

154
        error::Error AsyncCallStateNoCapture(
155
                events::EventLoop &loop, State state, function<void(error::Error)> handler);
156
        error::Error CallStateNoCapture(State state);
157

158
        string GetModulePath() const;
159
        string GetModulesWorkPath() const;
160

161
        error::Error PrepareStreamNextPipe();
162
        error::Error OpenStreamNextPipe(ExpectedWriterHandler open_handler);
163
        error::Error PrepareAndOpenStreamPipe(const string &path, ExpectedWriterHandler open_handler);
164
        error::Error PrepareDownloadDirectory(const string &path);
165
        error::Error DeleteStreamsFiles();
166

167
        void StartDownloadProcess();
168

169
        void StreamNextOpenHandler(io::ExpectedAsyncWriterPtr writer);
170
        void StreamOpenHandler(io::ExpectedAsyncWriterPtr writer);
171

172
        void StreamNextWriteHandler(size_t expected_n, io::ExpectedSize result);
173
        void PayloadReadHandler(io::ExpectedSize result);
174
        void StreamWriteHandler(size_t expected_n, io::ExpectedSize result);
175

176
        void EndStreamNext();
177

178
        void DownloadErrorHandler(const error::Error &err);
179
        void EndDownloadLoop(const error::Error &err);
180
        void DownloadTimeoutHandler();
181

182
        void ProcessEndedHandler(error::Error err);
183

184
        void StartDownloadToFile();
185

186
        context::MenderContext &ctx_;
187
        string update_module_path_;
188
        string update_module_workdir_;
189

190
        struct DownloadData {
191
                DownloadData(events::EventLoop &event_loop, artifact::Payload &payload);
192

193
                artifact::Payload &payload_;
194
                events::EventLoop &event_loop_;
195
                StateFinishedHandler download_finished_handler_;
196
                vector<uint8_t> buffer_;
197

198
                shared_ptr<procs::Process> proc_;
199

200
                string stream_next_path_;
201
                shared_ptr<io::Canceller> stream_next_opener_;
202
                io::AsyncWriterPtr stream_next_writer_;
203

204
                string current_payload_name_;
205
                size_t current_payload_size_;
206
                io::AsyncReaderPtr current_payload_reader_;
207
                shared_ptr<io::Canceller> current_stream_opener_;
208
                io::AsyncWriterPtr current_stream_writer_;
209
                size_t written_ {0};
210

211
                bool module_has_started_download_ {false};
212
                bool module_has_finished_download_ {false};
213
                bool downloading_to_files_ {false};
214
                bool downloading_with_sizes_ {false};
215
        };
216
        unique_ptr<DownloadData> download_;
217

218
        // Used for all states except Download.
219
        class StateRunner {
220
        public:
221
                StateRunner(
222
                        events::EventLoop &loop,
223
                        State state,
224
                        const string &module_path,
225
                        const string &module_work_path);
226

227
                using HandlerFunction = function<void(expected::expected<optional<string>, error::Error>)>;
228

229
                error::Error AsyncCallState(
230
                        State state, bool procOut, chrono::seconds timeout_seconds, HandlerFunction handler);
231

232
        private:
233
                void ProcessFinishedHandler(State state, error::Error err);
234

235
                events::EventLoop &loop;
236
                bool first_line_captured {false};
237
                bool too_many_lines {false};
238
                string module_work_path;
239
                procs::Process proc;
240
                optional<string> output;
241
                HandlerFunction handler;
242
        };
243
        unique_ptr<StateRunner> state_runner_;
244

245
        struct SystemRebootRunner {
×
246
                procs::Process proc;
247
                events::Timer timeout;
248
        };
249
        unique_ptr<SystemRebootRunner> system_reboot_;
250

251
        friend class ::UpdateModuleTests;
252
};
253

254
ExpectedStringVector DiscoverUpdateModules(const conf::MenderConfig &config);
255

256
class AsyncFifoOpener : virtual public io::Canceller {
257
public:
258
        AsyncFifoOpener(events::EventLoop &loop);
259
        ~AsyncFifoOpener();
260

261
        error::Error AsyncOpen(const string &path, ExpectedWriterHandler handler);
262

263
        void Cancel() override;
264

265
private:
266
        events::EventLoop &event_loop_;
267
        string path_;
268
        ExpectedWriterHandler handler_;
269
        thread thread_;
270
        shared_ptr<bool> cancelled_;
271
        shared_ptr<bool> destroying_;
272
};
273

274
} // namespace v3
275
} // namespace update_module
276
} // namespace update
277
} // namespace mender
278

279
#endif // MENDER_UPDATE_UPDATE_MODULE_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

© 2025 Coveralls, Inc