blob: 9e909d91652929dfbff54df143c11a6dfe0e702f [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 Khan35e83f32017-05-22 11:37:32 -0500109ItemUpdater::ActivationStatus ItemUpdater::validateSquashFSImage(
110 const std::string& versionId)
111{
112
113 // TODO openbmc/openbmc#1715 Check the Common.FilePath to
114 // determine the active image.
115 fs::path imageDirPath(IMG_UPLOAD_DIR);
116 imageDirPath /= versionId;
117 if (!fs::is_directory(imageDirPath))
118 {
119 return ItemUpdater::ActivationStatus::active;
120 }
121
122 fs::path file(imageDirPath);
123 file /= bmcImage;
124 std::ifstream efile(file.c_str());
125
126 if (efile.good() == 1)
127 {
128 return ItemUpdater::ActivationStatus::ready;
129 }
130 else
131 {
132 log<level::ERR>("Failed to find the SquashFS image.");
133 return ItemUpdater::ActivationStatus::invalid;
134 }
135}
136
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500137} // namespace updater
138} // namespace software
139} // namespace phosphor