blob: 33bf03bf38bfb74111707a576c68cb8e88eb2075 [file] [log] [blame]
Alexander Hansen0119cd72025-01-14 14:15:39 +01001#include "software_update.hpp"
2
3#include "device.hpp"
4#include "software.hpp"
5
6#include <phosphor-logging/lg2.hpp>
7#include <sdbusplus/async/context.hpp>
8#include <xyz/openbmc_project/Software/Update/aserver.hpp>
9
10SoftwareUpdate::SoftwareUpdate(
11 sdbusplus::async::context& ctx, const char* path, Software& software,
12 const std::set<RequestedApplyTimes>& allowedApplyTimes) :
13 sdbusplus::aserver::xyz::openbmc_project::software::Update<SoftwareUpdate>(
14 ctx, path),
15 software(software), allowedApplyTimes(allowedApplyTimes)
16{}
17
18auto SoftwareUpdate::method_call(start_update_t /*unused*/, auto image,
19 auto applyTime)
20 -> sdbusplus::async::task<start_update_t::return_type>
21{
22 lg2::info("requesting Device update");
23
24 // check if the apply time is allowed by our device
25
26 if (!this->allowedApplyTimes.contains(applyTime))
27 {
28 lg2::error(
29 "the selected apply time {APPLYTIME} is not allowed by the device",
30 "APPLYTIME", applyTime);
31 co_return this->software.getObjectPath();
32 }
33
34 lg2::info("started asynchronous update with fd {FD}", "FD", image.fd);
35
36 Device& device = this->software.getParentDevice();
37
38 int imageDup = dup(image.fd);
39
40 if (imageDup < 0)
41 {
42 lg2::error("ERROR calling dup on fd: {ERR}", "ERR", strerror(errno));
43 co_return this->software.getObjectPath();
44 }
45
46 lg2::debug("starting async update with FD: {FD}\n", "FD", imageDup);
47
48 const std::string newSwid = Software::getRandomSoftwareId(device);
49
50 // Swid = <DeviceX>_<RandomId>
51 // This new swid will then be used for the object path for the new image.
52 std::unique_ptr<Software> softwareUpdate =
53 std::make_unique<Software>(ctx, newSwid, device);
54
55 softwareUpdate->setActivation(ActivationInterface::Activations::NotReady);
56
57 // NOLINTBEGIN
58 ctx.spawn(
59 [](Device& device, int imageDup, RequestedApplyTimes applyTime,
60 std::unique_ptr<Software> swupdate) -> sdbusplus::async::task<> {
61 co_await device.startUpdateAsync(imageDup, applyTime,
62 std::move(swupdate));
63 co_return;
64 }(device, imageDup, applyTime, std::move(softwareUpdate)));
65 // NOLINTEND
66
67 // We need the object path for the new software here.
68 // It must be the same as constructed during the update process.
69 // This is so that bmcweb and redfish clients can keep track of the update
70 // process.
71 co_return Software::getObjPathFromSwid(newSwid);
72}
73
74auto SoftwareUpdate::set_property(allowed_apply_times_t /*unused*/,
75 auto /*unused*/) -> bool
76{
77 // we do not implement this since the allowed apply times are
78 // defined by the device type and cannot be changed via dbus.
79 return false;
80}
81
82auto SoftwareUpdate::get_property(allowed_apply_times_t /*unused*/) const
83{
84 return this->allowedApplyTimes;
85}