blob: efff65f13334ab7bd0da8ea1b43b21f787ffdeb1 [file] [log] [blame]
Saqib Khan35e83f32017-05-22 11:37:32 -05001#include <fstream>
Gunnar Millsec1b41c2017-05-02 12:20:36 -05002#include <string>
Gunnar Mills2ce7da22017-05-04 15:37:56 -05003#include <phosphor-logging/log.hpp>
Gunnar Millsec1b41c2017-05-02 12:20:36 -05004#include "config.h"
Gunnar Mills2ce7da22017-05-04 15:37:56 -05005#include "item_updater.hpp"
6#include "xyz/openbmc_project/Software/Version/server.hpp"
Saqib Khan35e83f32017-05-22 11:37:32 -05007#include <experimental/filesystem>
Saqib Khan705f1bf2017-06-09 23:58:38 -05008#include "version.hpp"
Gunnar Millsec1b41c2017-05-02 12:20:36 -05009
10namespace phosphor
11{
12namespace software
13{
14namespace updater
15{
16
Gunnar Mills2ce7da22017-05-04 15:37:56 -050017// When you see server:: you know we're referencing our base class
18namespace server = sdbusplus::xyz::openbmc_project::Software::server;
19
20using namespace phosphor::logging;
Saqib Khan35e83f32017-05-22 11:37:32 -050021namespace fs = std::experimental::filesystem;
22
23constexpr auto bmcImage = "image-rofs";
Gunnar Mills2ce7da22017-05-04 15:37:56 -050024
Patrick Williamse75d10f2017-05-30 16:56:32 -050025void ItemUpdater::createActivation(sdbusplus::message::message& msg)
Gunnar Millsec1b41c2017-05-02 12:20:36 -050026{
Gunnar Mills2ce7da22017-05-04 15:37:56 -050027 sdbusplus::message::object_path objPath;
Saqib Khan705f1bf2017-06-09 23:58:38 -050028 auto purpose = server::Version::VersionPurpose::Unknown;
29 std::string version;
Gunnar Mills2ce7da22017-05-04 15:37:56 -050030 std::map<std::string,
Patrick Williamse75d10f2017-05-30 16:56:32 -050031 std::map<std::string,
32 sdbusplus::message::variant<std::string>>> interfaces;
33 msg.read(objPath, interfaces);
Gunnar Mills2ce7da22017-05-04 15:37:56 -050034 std::string path(std::move(objPath));
35
36 for (const auto& intf : interfaces)
37 {
Saqib Khan705f1bf2017-06-09 23:58:38 -050038 if (intf.first == VERSION_IFACE)
Gunnar Mills2ce7da22017-05-04 15:37:56 -050039 {
Saqib Khan705f1bf2017-06-09 23:58:38 -050040 for (const auto& property : intf.second)
Gunnar Mills2ce7da22017-05-04 15:37:56 -050041 {
Saqib Khan705f1bf2017-06-09 23:58:38 -050042 if (property.first == "Purpose")
Gunnar Mills2ce7da22017-05-04 15:37:56 -050043 {
Saqib Khan705f1bf2017-06-09 23:58:38 -050044 std::string str = sdbusplus::message::variant_ns::
45 get<std::string>(property.second);
46 purpose = server::Version::
47 convertVersionPurposeFromString(str);
48 }
49 else if (property.first == "Version")
50 {
51 version = sdbusplus::message::variant_ns::
52 get<std::string>(property.second);
Gunnar Mills2ce7da22017-05-04 15:37:56 -050053 }
54 }
55 }
56 }
Saqib Khan705f1bf2017-06-09 23:58:38 -050057 if (version.empty() ||
58 (purpose != server::Version::VersionPurpose::BMC &&
59 purpose != server::Version::VersionPurpose::System))
60 {
61 return;
62 }
Gunnar Mills2ce7da22017-05-04 15:37:56 -050063
64 // Version id is the last item in the path
65 auto pos = path.rfind("/");
66 if (pos == std::string::npos)
67 {
68 log<level::ERR>("No version id found in object path",
69 entry("OBJPATH=%s", path));
Patrick Williamse75d10f2017-05-30 16:56:32 -050070 return;
Gunnar Mills2ce7da22017-05-04 15:37:56 -050071 }
72
73 auto versionId = path.substr(pos + 1);
74
Patrick Williamse75d10f2017-05-30 16:56:32 -050075 if (activations.find(versionId) == activations.end())
Gunnar Mills2ce7da22017-05-04 15:37:56 -050076 {
Saqib Khan35e83f32017-05-22 11:37:32 -050077 // Determine the Activation state by processing the given image dir.
78 auto activationState = server::Activation::Activations::Invalid;
79 ItemUpdater::ActivationStatus result = ItemUpdater::
80 validateSquashFSImage(versionId);
81 if (result == ItemUpdater::ActivationStatus::ready)
82 {
83 activationState = server::Activation::Activations::Ready;
84 }
85 else if (result == ItemUpdater::ActivationStatus::active)
86 {
87 activationState = server::Activation::Activations::Active;
88 }
89 activations.insert(std::make_pair(
Saqib Khan705f1bf2017-06-09 23:58:38 -050090 versionId,
91 std::make_unique<Activation>(
92 bus,
93 path,
Saqib Khan35e83f32017-05-22 11:37:32 -050094 versionId,
Saqib Khan705f1bf2017-06-09 23:58:38 -050095 activationState)));
96 versions.insert(std::make_pair(
97 versionId,
98 std::make_unique<phosphor::software::
99 manager::Version>(
100 bus,
101 path,
102 version,
103 purpose,
104 "")));
Gunnar Mills2ce7da22017-05-04 15:37:56 -0500105 }
Patrick Williamse75d10f2017-05-30 16:56:32 -0500106 return;
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500107}
108
Saqib Khanba239882017-05-26 08:41:54 -0500109void ItemUpdater::processBMCImage()
110{
111 auto purpose = server::Version::VersionPurpose::BMC;
112 auto version = phosphor::software::manager::Version::getBMCVersion();
113 auto id = phosphor::software::manager::Version::getId(version);
114 auto path = std::string{SOFTWARE_OBJPATH} + '/' + id;
115 activations.insert(std::make_pair(
116 id,
117 std::make_unique<Activation>(
118 bus,
119 path,
120 id,
121 server::Activation::Activations::Active)));
122 versions.insert(std::make_pair(
123 id,
124 std::make_unique<phosphor::software::
125 manager::Version>(
126 bus,
127 path,
128 version,
129 purpose,
130 "")));
131 return;
132}
133
Saqib Khan35e83f32017-05-22 11:37:32 -0500134ItemUpdater::ActivationStatus ItemUpdater::validateSquashFSImage(
135 const std::string& versionId)
136{
137
138 // TODO openbmc/openbmc#1715 Check the Common.FilePath to
139 // determine the active image.
140 fs::path imageDirPath(IMG_UPLOAD_DIR);
141 imageDirPath /= versionId;
142 if (!fs::is_directory(imageDirPath))
143 {
144 return ItemUpdater::ActivationStatus::active;
145 }
146
147 fs::path file(imageDirPath);
148 file /= bmcImage;
149 std::ifstream efile(file.c_str());
150
151 if (efile.good() == 1)
152 {
153 return ItemUpdater::ActivationStatus::ready;
154 }
155 else
156 {
157 log<level::ERR>("Failed to find the SquashFS image.");
158 return ItemUpdater::ActivationStatus::invalid;
159 }
160}
161
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500162} // namespace updater
163} // namespace software
164} // namespace phosphor