Alexander Hansen | cc37235 | 2025-01-14 14:15:39 +0100 | [diff] [blame] | 1 | #include "software.hpp" |
| 2 | |
| 3 | #include "device.hpp" |
| 4 | #include "software_update.hpp" |
| 5 | |
| 6 | #include <phosphor-logging/lg2.hpp> |
| 7 | #include <sdbusplus/async/context.hpp> |
| 8 | #include <xyz/openbmc_project/Association/Definitions/server.hpp> |
| 9 | #include <xyz/openbmc_project/Software/Activation/aserver.hpp> |
| 10 | #include <xyz/openbmc_project/Software/Update/aserver.hpp> |
| 11 | #include <xyz/openbmc_project/State/Host/client.hpp> |
| 12 | |
| 13 | PHOSPHOR_LOG2_USING; |
| 14 | |
| 15 | using namespace phosphor::software; |
| 16 | using namespace phosphor::software::device; |
| 17 | using namespace phosphor::software::config; |
| 18 | using namespace phosphor::software::update; |
| 19 | |
| 20 | const static std::string baseObjPathSoftware = "/xyz/openbmc_project/software/"; |
| 21 | |
Alexander Hansen | cc37235 | 2025-01-14 14:15:39 +0100 | [diff] [blame] | 22 | Software::Software(sdbusplus::async::context& ctx, Device& parent) : |
| 23 | Software(ctx, parent, getRandomSoftwareId(parent)) |
| 24 | {} |
| 25 | |
| 26 | Software::Software(sdbusplus::async::context& ctx, Device& parent, |
| 27 | const std::string& swid) : |
Alexander Hansen | df62819 | 2025-06-18 16:28:59 +0200 | [diff] [blame] | 28 | SoftwareActivation(ctx, (baseObjPathSoftware + swid).c_str(), |
| 29 | Activation::properties_t{Activations::NotReady, |
| 30 | RequestedActivations::None}), |
Alexander Hansen | cc37235 | 2025-01-14 14:15:39 +0100 | [diff] [blame] | 31 | objectPath(baseObjPathSoftware + swid), parentDevice(parent), swid(swid), |
| 32 | ctx(ctx) |
| 33 | { |
Alexander Hansen | cc37235 | 2025-01-14 14:15:39 +0100 | [diff] [blame] | 34 | std::string objPath = baseObjPathSoftware + swid; |
| 35 | |
| 36 | debug("{SWID}: created dbus interfaces on path {OBJPATH}", "SWID", swid, |
| 37 | "OBJPATH", objPath); |
| 38 | }; |
| 39 | |
Alexander Hansen | f2c95a0 | 2024-11-26 11:16:44 +0100 | [diff] [blame] | 40 | long int Software::getRandomId() |
Alexander Hansen | cc37235 | 2025-01-14 14:15:39 +0100 | [diff] [blame] | 41 | { |
| 42 | struct timespec ts; |
| 43 | clock_gettime(CLOCK_REALTIME, &ts); |
| 44 | unsigned int seed = ts.tv_nsec ^ getpid(); |
| 45 | srandom(seed); |
| 46 | return random() % 10000; |
| 47 | } |
| 48 | |
| 49 | std::string Software::getRandomSoftwareId(Device& parent) |
| 50 | { |
| 51 | return std::format("{}_{}", parent.config.configName, getRandomId()); |
| 52 | } |
| 53 | |
Alexander Hansen | cc37235 | 2025-01-14 14:15:39 +0100 | [diff] [blame] | 54 | sdbusplus::async::task<> Software::createInventoryAssociations(bool isRunning) |
Alexander Hansen | cc37235 | 2025-01-14 14:15:39 +0100 | [diff] [blame] | 55 | { |
| 56 | debug("{SWID}: setting association definitions", "SWID", swid); |
| 57 | |
| 58 | std::string endpoint = ""; |
| 59 | |
| 60 | try |
| 61 | { |
| 62 | endpoint = co_await parentDevice.config.getInventoryItemObjectPath(ctx); |
| 63 | } |
| 64 | catch (std::exception& e) |
| 65 | { |
| 66 | error(e.what()); |
| 67 | } |
| 68 | |
| 69 | if (!associationDefinitions) |
| 70 | { |
| 71 | std::string path = objectPath; |
| 72 | associationDefinitions = |
Alexander Hansen | df62819 | 2025-06-18 16:28:59 +0200 | [diff] [blame] | 73 | std::make_unique<SoftwareAssociationDefinitions>( |
| 74 | ctx, path.c_str(), |
| 75 | SoftwareAssociationDefinitions::properties_t{{}}); |
Alexander Hansen | cc37235 | 2025-01-14 14:15:39 +0100 | [diff] [blame] | 76 | } |
| 77 | |
Alexander Hansen | cc37235 | 2025-01-14 14:15:39 +0100 | [diff] [blame] | 78 | if (endpoint.empty()) |
| 79 | { |
Alexander Hansen | cc37235 | 2025-01-14 14:15:39 +0100 | [diff] [blame] | 80 | co_return; |
| 81 | } |
| 82 | |
Alexander Hansen | df62819 | 2025-06-18 16:28:59 +0200 | [diff] [blame] | 83 | std::vector<std::tuple<std::string, std::string, std::string>> assocs; |
| 84 | |
Alexander Hansen | cc37235 | 2025-01-14 14:15:39 +0100 | [diff] [blame] | 85 | if (isRunning) |
| 86 | { |
| 87 | debug("{SWID}: creating 'running' association to {OBJPATH}", "SWID", |
| 88 | swid, "OBJPATH", endpoint); |
| 89 | std::tuple<std::string, std::string, std::string> assocRunning = { |
| 90 | "running", "ran_on", endpoint}; |
| 91 | assocs.push_back(assocRunning); |
| 92 | } |
| 93 | else |
| 94 | { |
| 95 | debug("{SWID}: creating 'activating' association to {OBJPATH}", "SWID", |
| 96 | swid, "OBJPATH", endpoint); |
| 97 | std::tuple<std::string, std::string, std::string> assocActivating = { |
| 98 | "activating", "activated_on", endpoint}; |
| 99 | assocs.push_back(assocActivating); |
| 100 | } |
| 101 | |
| 102 | associationDefinitions->associations(assocs); |
| 103 | |
| 104 | co_return; |
| 105 | } |
| 106 | |
Alexander Hansen | de5e76f | 2025-02-20 16:30:11 +0100 | [diff] [blame] | 107 | void Software::setVersion(const std::string& versionStr, |
| 108 | SoftwareVersion::VersionPurpose versionPurpose) |
Alexander Hansen | cc37235 | 2025-01-14 14:15:39 +0100 | [diff] [blame] | 109 | { |
| 110 | debug("{SWID}: set version {VERSION}", "SWID", swid, "VERSION", versionStr); |
| 111 | |
Alexander Hansen | ccec7c6 | 2025-02-21 17:17:45 +0100 | [diff] [blame] | 112 | if (!version) |
Alexander Hansen | cc37235 | 2025-01-14 14:15:39 +0100 | [diff] [blame] | 113 | { |
Alexander Hansen | df62819 | 2025-06-18 16:28:59 +0200 | [diff] [blame] | 114 | version = std::make_unique<SoftwareVersion>( |
| 115 | ctx, objectPath.str.c_str(), |
| 116 | SoftwareVersion::properties_t{versionStr, versionPurpose}); |
| 117 | version->emit_added(); |
| 118 | return; |
Alexander Hansen | cc37235 | 2025-01-14 14:15:39 +0100 | [diff] [blame] | 119 | } |
| 120 | |
Alexander Hansen | cc37235 | 2025-01-14 14:15:39 +0100 | [diff] [blame] | 121 | version->version(versionStr); |
Alexander Hansen | de5e76f | 2025-02-20 16:30:11 +0100 | [diff] [blame] | 122 | version->purpose(versionPurpose); |
Alexander Hansen | de5e76f | 2025-02-20 16:30:11 +0100 | [diff] [blame] | 123 | } |
| 124 | |
| 125 | SoftwareVersion::VersionPurpose Software::getPurpose() |
| 126 | { |
| 127 | return version->purpose(); |
Alexander Hansen | cc37235 | 2025-01-14 14:15:39 +0100 | [diff] [blame] | 128 | } |
| 129 | |
| 130 | void Software::setActivationBlocksTransition(bool enabled) |
| 131 | { |
| 132 | if (!enabled) |
| 133 | { |
| 134 | activationBlocksTransition = nullptr; |
| 135 | return; |
| 136 | } |
| 137 | |
| 138 | std::string path = objectPath; |
| 139 | activationBlocksTransition = |
| 140 | std::make_unique<SoftwareActivationBlocksTransition>(ctx, path.c_str()); |
| 141 | } |
| 142 | |
| 143 | void Software::setActivation(SoftwareActivation::Activations act) |
| 144 | { |
| 145 | activation(act); |
| 146 | } |
| 147 | |
| 148 | void Software::enableUpdate( |
| 149 | const std::set<RequestedApplyTimes>& allowedApplyTimes) |
| 150 | { |
| 151 | if (updateIntf != nullptr) |
| 152 | { |
| 153 | error("[Software] update of {OBJPATH} has already been enabled", |
| 154 | "OBJPATH", objectPath); |
| 155 | return; |
| 156 | } |
| 157 | |
| 158 | debug( |
| 159 | "[Software] enabling update of {OBJPATH} (adding the update interface)", |
| 160 | "OBJPATH", objectPath); |
| 161 | |
| 162 | updateIntf = std::make_unique<SoftwareUpdate>(ctx, objectPath.str.c_str(), |
| 163 | *this, allowedApplyTimes); |
| 164 | } |