version-handler: add version-handler, blob handler
Implement version-handler: a blob handler for retrieving version
information about a blob.
Problem: ipmi-flash(firmware-handler) provides a mechanism to transfer
firmware updates, verify them and perform updates but there is no
mechanism to interrogate the firmware for its version.
Solution: version-handler provides handlers for retrieving information
about firmware blobs. Adding "version" syntax to "/flash/blob" entries
in the json configuration file enables this feature.
The mechanism to retrieve version is identical to the mechanism used by
firmware-handler to perform preparation, verification and updates (kick
off systemd targets).
Signed-off-by: Jason Ling <jasonling@google.com>
Change-Id: I28868ca8dd76d63af668d2e46b9359401d45f0bc
diff --git a/bmc/version-handler/version_handler.hpp b/bmc/version-handler/version_handler.hpp
index aefd3c4..336a869 100644
--- a/bmc/version-handler/version_handler.hpp
+++ b/bmc/version-handler/version_handler.hpp
@@ -1,10 +1,18 @@
#pragma once
#include "buildjson.hpp"
+#include "image_handler.hpp"
#include "status.hpp"
+#include "util.hpp"
#include <blobs-ipmid/blobs.hpp>
+#include <algorithm>
+#include <cstdint>
+#include <map>
#include <memory>
+#include <string>
+#include <unordered_map>
+#include <vector>
namespace ipmi_flash
{
struct VersionActionPack
@@ -16,4 +24,95 @@
/** Only file operation action supported currently */
std::unique_ptr<TriggerableActionInterface> onOpen;
};
+
+/*
+ * All the information associated with a version blob
+ */
+struct VersionInfoPack
+{
+ public:
+ VersionInfoPack(const std::string& blobId,
+ std::unique_ptr<VersionActionPack> actionPackIn,
+ std::unique_ptr<ImageHandlerInterface> imageHandler) :
+ blobId(blobId),
+ actionPack(std::move(actionPackIn)),
+ imageHandler(std::move(imageHandler)),
+ blobState(static_cast<blobs::StateFlags>(0)){};
+ VersionInfoPack() = default;
+
+ std::string blobId;
+ std::unique_ptr<VersionActionPack> actionPack;
+ std::unique_ptr<ImageHandlerInterface> imageHandler;
+ blobs::StateFlags blobState;
+};
+
+/* convenience alias: the key (std::string) is blobId, same as
+ * VersionInfoPack.blobId */
+using VersionInfoMap = std::unordered_map<std::string, VersionInfoPack>;
+
+class VersionBlobHandler : public blobs::GenericBlobInterface
+{
+ public:
+ /**
+ * Factory to create a BlobHandler for use by phosphor-ipmi-blobs
+ *
+ * @param[in] versionMap - blob names to VersionInfoPack which contains
+ * triggers, file handlers, state and blobID.
+ *
+ * @returns a unique_ptr to a GenericBlobInterface which is used by
+ * phosphor-ipmi-blobs. The underlying implementation (VersionBlobHandler)
+ * implements all the blob operations for the blobs owned by
+ * VersionBlobHandler.
+ */
+ static std::unique_ptr<blobs::GenericBlobInterface>
+ create(VersionInfoMap&& versionMap);
+ /**
+ * Create a VersionBlobHandler.
+ *
+ * @param[in] blobs - list of blobs_ids to support
+ * @param[in] actions - a map of blobId to VersionInfoPack
+ */
+ VersionBlobHandler(std::vector<std::string>&& blobs,
+ VersionInfoMap&& handlerMap) :
+ blobIds(blobs),
+ versionInfoMap(std::move(handlerMap))
+ {}
+ ~VersionBlobHandler() = default;
+ VersionBlobHandler(const VersionBlobHandler&) = delete;
+ VersionBlobHandler& operator=(const VersionBlobHandler&) = delete;
+ VersionBlobHandler(VersionBlobHandler&&) = default;
+ VersionBlobHandler& operator=(VersionBlobHandler&&) = default;
+
+ bool canHandleBlob(const std::string& path) override;
+ std::vector<std::string> getBlobIds() override;
+ bool deleteBlob(const std::string& path) override;
+ bool stat(const std::string&, blobs::BlobMeta* meta) override;
+ bool open(uint16_t session, uint16_t flags,
+ const std::string& path) override;
+ std::vector<uint8_t> read(uint16_t session, uint32_t offset,
+ uint32_t requestedSize) override;
+ bool write(uint16_t session, uint32_t offset,
+ const std::vector<uint8_t>& data) override
+ {
+ return false; /* not supported */
+ };
+ bool writeMeta(uint16_t session, uint32_t offset,
+ const std::vector<uint8_t>& data) override
+ {
+ return false; /* not supported */
+ }
+ bool commit(uint16_t session, const std::vector<uint8_t>& data) override
+ {
+ return false; // not supported
+ }
+ bool close(uint16_t session) override;
+ bool stat(uint16_t session, blobs::BlobMeta* meta) override;
+ bool expire(uint16_t session) override;
+ bool cleanup(uint16_t session);
+
+ private:
+ std::vector<std::string> blobIds;
+ VersionInfoMap versionInfoMap;
+ std::unordered_map<uint16_t, std::string> sessionToBlob;
+};
} // namespace ipmi_flash