tools: split out the update handler
Signed-off-by: Patrick Venture <venture@google.com>
Change-Id: I367ea961c98ec822d3200d101c4f5977d77e7402
diff --git a/tools/Makefile.am b/tools/Makefile.am
index c85ffeb..4fefe6e 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -10,6 +10,8 @@
libupdater_la_SOURCES = \
$(top_srcdir)/util.cpp \
updater.cpp \
+ handler.cpp \
+ helper.cpp \
bt.cpp \
lpc.cpp \
io.cpp \
diff --git a/tools/handler.cpp b/tools/handler.cpp
new file mode 100644
index 0000000..25bb48d
--- /dev/null
+++ b/tools/handler.cpp
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "handler.hpp"
+
+#include "helper.hpp"
+#include "status.hpp"
+#include "tool_errors.hpp"
+#include "util.hpp"
+
+#include <algorithm>
+#include <blobs-ipmid/blobs.hpp>
+#include <cstdint>
+#include <cstring>
+#include <ipmiblob/blob_errors.hpp>
+#include <string>
+#include <vector>
+
+namespace host_tool
+{
+
+bool UpdateHandler::checkAvailable(const std::string& goalFirmware)
+{
+ std::vector<std::string> blobs = blob->getBlobList();
+
+ auto blobInst = std::find_if(
+ blobs.begin(), blobs.end(), [&goalFirmware](const std::string& iter) {
+ /* Running into weird scenarios where the string comparison doesn't
+ * work. TODO: revisit.
+ */
+ return (0 == std::memcmp(goalFirmware.c_str(), iter.c_str(),
+ goalFirmware.length()));
+ // return (goalFirmware.compare(iter));
+ });
+ if (blobInst == blobs.end())
+ {
+ std::fprintf(stderr, "%s not found\n", goalFirmware.c_str());
+ return false;
+ }
+
+ /* Call stat on /flash/image (or /flash/tarball) and check if data interface
+ * is supported.
+ */
+ ipmiblob::StatResponse stat;
+
+ try
+ {
+ stat = blob->getStat(goalFirmware);
+ }
+ catch (const ipmiblob::BlobException& b)
+ {
+ std::fprintf(stderr, "Received exception '%s' on getStat\n", b.what());
+ return false;
+ }
+
+ auto supported = handler->supportedType();
+ if ((stat.blob_state & supported) == 0)
+ {
+ std::fprintf(stderr, "data interface selected not supported.\n");
+ return false;
+ }
+
+ return true;
+}
+
+void UpdateHandler::sendFile(const std::string& target, const std::string& path)
+{
+ std::uint16_t session;
+ auto supported = handler->supportedType();
+
+ try
+ {
+ session = blob->openBlob(
+ target, static_cast<std::uint16_t>(supported) |
+ static_cast<std::uint16_t>(blobs::OpenFlags::write));
+ }
+ catch (const ipmiblob::BlobException& b)
+ {
+ throw ToolException("blob exception received: " +
+ std::string(b.what()));
+ }
+
+ if (!handler->sendContents(path, session))
+ {
+ /* Need to close the session on failure, or it's stuck open (until the
+ * blob handler timeout is implemented, and even then, why make it wait.
+ */
+ blob->closeBlob(session);
+ throw ToolException("Failed to send contents of " + path);
+ }
+
+ blob->closeBlob(session);
+}
+
+bool UpdateHandler::verifyFile(const std::string& target)
+{
+ std::uint16_t session;
+ bool success = false;
+
+ try
+ {
+ session = blob->openBlob(
+ target, static_cast<std::uint16_t>(blobs::OpenFlags::write));
+ }
+ catch (const ipmiblob::BlobException& b)
+ {
+ throw ToolException("blob exception received: " +
+ std::string(b.what()));
+ }
+
+ std::fprintf(stderr, "Committing to %s to trigger service\n",
+ target.c_str());
+
+ try
+ {
+ blob->commit(session, {});
+ }
+ catch (const ipmiblob::BlobException& b)
+ {
+ throw ToolException("blob exception received: " +
+ std::string(b.what()));
+ }
+
+ std::fprintf(stderr, "Calling stat on %s session to check status\n",
+ target.c_str());
+
+ if (pollStatus(session, blob))
+ {
+ std::fprintf(stderr, "Returned success\n");
+ success = true;
+ }
+ else
+ {
+ std::fprintf(stderr, "Returned non-success (could still "
+ "be running (unlikely))\n");
+ }
+
+ blob->closeBlob(session);
+ return (success == true);
+}
+
+void UpdateHandler::cleanArtifacts()
+{
+ /* open(), commit(), close() */
+ std::uint16_t session;
+
+ /* Errors aren't important for this call. */
+ try
+ {
+ std::fprintf(stderr, "Opening the cleanup blob\n");
+ session =
+ blob->openBlob(ipmi_flash::cleanupBlobId,
+ static_cast<std::uint16_t>(blobs::OpenFlags::write));
+ std::fprintf(stderr, "Committing to the cleanup blob\n");
+ blob->commit(session, {});
+ std::fprintf(stderr, "Closing cleanup blob\n");
+ blob->closeBlob(session);
+ }
+ catch (...)
+ {
+ }
+}
+
+} // namespace host_tool
diff --git a/tools/handler.hpp b/tools/handler.hpp
new file mode 100644
index 0000000..2335977
--- /dev/null
+++ b/tools/handler.hpp
@@ -0,0 +1,79 @@
+#pragma once
+
+#include "interface.hpp"
+
+#include <ipmiblob/blob_interface.hpp>
+#include <string>
+
+namespace host_tool
+{
+
+class UpdateHandlerInterface
+{
+ public:
+ virtual ~UpdateHandlerInterface() = default;
+
+ /**
+ * Check if the goal firmware is listed in the blob_list and that the
+ * handler's supported data type is available.
+ *
+ * @param[in] goalFirmware - the firmware to check /flash/image
+ * /flash/tarball, etc.
+ */
+ virtual bool checkAvailable(const std::string& goalFirmware) = 0;
+
+ /**
+ * Send the file contents at path to the blob id, target.
+ *
+ * @param[in] target - the blob id
+ * @param[in] path - the source file path
+ */
+ virtual void sendFile(const std::string& target,
+ const std::string& path) = 0;
+
+ /**
+ * Trigger verification.
+ *
+ * @param[in] target - the verification blob id (may support multiple in the
+ * future.
+ * @return true if verified, false if verification errors.
+ */
+ virtual bool verifyFile(const std::string& target) = 0;
+
+ /**
+ * Cleanup the artifacts by triggering this action.
+ */
+ virtual void cleanArtifacts() = 0;
+};
+
+/** Object that actually handles the update itself. */
+class UpdateHandler : public UpdateHandlerInterface
+{
+ public:
+ UpdateHandler(ipmiblob::BlobInterface* blob, DataInterface* handler) :
+ blob(blob), handler(handler)
+ {
+ }
+
+ ~UpdateHandler() = default;
+
+ bool checkAvailable(const std::string& goalFirmware) override;
+
+ /**
+ * @throw ToolException on failure.
+ */
+ void sendFile(const std::string& target, const std::string& path) override;
+
+ /**
+ * @throw ToolException on failure (TODO: throw on timeout.)
+ */
+ bool verifyFile(const std::string& target) override;
+
+ void cleanArtifacts() override;
+
+ private:
+ ipmiblob::BlobInterface* blob;
+ DataInterface* handler;
+};
+
+} // namespace host_tool
diff --git a/tools/helper.cpp b/tools/helper.cpp
new file mode 100644
index 0000000..ad2c60d
--- /dev/null
+++ b/tools/helper.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2019 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "helper.hpp"
+
+#include "status.hpp"
+#include "tool_errors.hpp"
+
+#include <chrono>
+#include <ipmiblob/blob_errors.hpp>
+#include <thread>
+
+namespace host_tool
+{
+
+/* Poll an open verification session. Handling closing the session is not yet
+ * owned by this method.
+ */
+bool pollStatus(std::uint16_t session, ipmiblob::BlobInterface* blob)
+{
+ using namespace std::chrono_literals;
+
+ static constexpr auto verificationSleep = 5s;
+ ipmi_flash::ActionStatus result = ipmi_flash::ActionStatus::unknown;
+
+ try
+ {
+ static constexpr int commandAttempts = 20;
+ int attempts = 0;
+ bool exitLoop = false;
+
+ /* Reach back the current status from the verification service output.
+ */
+ while (attempts++ < commandAttempts)
+ {
+ ipmiblob::StatResponse resp = blob->getStat(session);
+
+ if (resp.metadata.size() != sizeof(std::uint8_t))
+ {
+ /* TODO: How do we want to handle the verification failures,
+ * because closing the session to the verify blob has a special
+ * as-of-yet not fully defined behavior.
+ */
+ std::fprintf(stderr, "Received invalid metadata response!!!\n");
+ }
+
+ result = static_cast<ipmi_flash::ActionStatus>(resp.metadata[0]);
+
+ switch (result)
+ {
+ case ipmi_flash::ActionStatus::failed:
+ std::fprintf(stderr, "failed\n");
+ exitLoop = true;
+ break;
+ case ipmi_flash::ActionStatus::unknown:
+ std::fprintf(stderr, "other\n");
+ break;
+ case ipmi_flash::ActionStatus::running:
+ std::fprintf(stderr, "running\n");
+ break;
+ case ipmi_flash::ActionStatus::success:
+ std::fprintf(stderr, "success\n");
+ exitLoop = true;
+ break;
+ default:
+ std::fprintf(stderr, "wat\n");
+ }
+
+ if (exitLoop)
+ {
+ break;
+ }
+ std::this_thread::sleep_for(verificationSleep);
+ }
+ }
+ catch (const ipmiblob::BlobException& b)
+ {
+ throw ToolException("blob exception received: " +
+ std::string(b.what()));
+ }
+
+ /* TODO: If this is reached and it's not success, it may be worth just
+ * throwing a ToolException with a timeout message specifying the final
+ * read's value.
+ *
+ * TODO: Given that excepting from certain points leaves the BMC update
+ * state machine in an inconsistent state, we need to carefully evaluate
+ * which exceptions from the lower layers allow one to try and delete the
+ * blobs to rollback the state and progress.
+ */
+ return (result == ipmi_flash::ActionStatus::success);
+}
+
+} // namespace host_tool
diff --git a/tools/helper.hpp b/tools/helper.hpp
new file mode 100644
index 0000000..8004cbf
--- /dev/null
+++ b/tools/helper.hpp
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <cstdint>
+#include <ipmiblob/blob_interface.hpp>
+
+namespace host_tool
+{
+
+/**
+ * Poll an open verification session.
+ *
+ * @param[in] session - the open verification session
+ * @param[in] blob - pointer to blob interface implementation object.
+ * @return true if the verification was successul.
+ */
+bool pollStatus(std::uint16_t session, ipmiblob::BlobInterface* blob);
+
+} // namespace host_tool
diff --git a/tools/test/Makefile.am b/tools/test/Makefile.am
index 26de6c5..c05654b 100644
--- a/tools/test/Makefile.am
+++ b/tools/test/Makefile.am
@@ -18,7 +18,8 @@
check_PROGRAMS = \
tools_bt_unittest \
tools_lpc_unittest \
- tools_updater_unittest
+ tools_updater_unittest \
+ tools_helper_unittest
TESTS = $(check_PROGRAMS)
@@ -30,3 +31,6 @@
tools_updater_unittest_SOURCES = tools_updater_unittest.cpp
tools_updater_unittest_LDADD = $(top_builddir)/tools/libupdater.la
+
+tools_helper_unittest_SOURCES = tools_helper_unittest.cpp
+tools_helper_unittest_LDADD = $(top_builddir)/tools/libupdater.la
diff --git a/tools/test/tools_helper_unittest.cpp b/tools/test/tools_helper_unittest.cpp
new file mode 100644
index 0000000..931c59f
--- /dev/null
+++ b/tools/test/tools_helper_unittest.cpp
@@ -0,0 +1,47 @@
+#include "helper.hpp"
+#include "status.hpp"
+
+#include <cstdint>
+#include <ipmiblob/test/blob_interface_mock.hpp>
+
+#include <gtest/gtest.h>
+
+namespace host_tool
+{
+using ::testing::Return;
+using ::testing::TypedEq;
+
+class UpdaterTest : public ::testing::Test
+{
+ protected:
+ ipmiblob::BlobInterfaceMock blobMock;
+ std::uint16_t session = 0xbeef;
+};
+
+TEST_F(UpdaterTest, PollStatusReturnsAfterSuccess)
+{
+ ipmiblob::StatResponse verificationResponse = {};
+ /* the other details of the response are ignored, and should be. */
+ verificationResponse.metadata.push_back(
+ static_cast<std::uint8_t>(ipmi_flash::ActionStatus::success));
+
+ EXPECT_CALL(blobMock, getStat(TypedEq<std::uint16_t>(session)))
+ .WillOnce(Return(verificationResponse));
+
+ EXPECT_TRUE(pollStatus(session, &blobMock));
+}
+
+TEST_F(UpdaterTest, PollStatusReturnsAfterFailure)
+{
+ ipmiblob::StatResponse verificationResponse = {};
+ /* the other details of the response are ignored, and should be. */
+ verificationResponse.metadata.push_back(
+ static_cast<std::uint8_t>(ipmi_flash::ActionStatus::failed));
+
+ EXPECT_CALL(blobMock, getStat(TypedEq<std::uint16_t>(session)))
+ .WillOnce(Return(verificationResponse));
+
+ EXPECT_FALSE(pollStatus(session, &blobMock));
+}
+
+} // namespace host_tool
diff --git a/tools/test/tools_updater_unittest.cpp b/tools/test/tools_updater_unittest.cpp
index 5b3cb5b..a2ba2df 100644
--- a/tools/test/tools_updater_unittest.cpp
+++ b/tools/test/tools_updater_unittest.cpp
@@ -96,32 +96,6 @@
std::uint16_t session = 0xbeef;
};
-TEST_F(UpdaterTest, PollStatusReturnsAfterSuccess)
-{
- ipmiblob::StatResponse verificationResponse = {};
- /* the other details of the response are ignored, and should be. */
- verificationResponse.metadata.push_back(
- static_cast<std::uint8_t>(ipmi_flash::ActionStatus::success));
-
- EXPECT_CALL(blobMock, getStat(TypedEq<std::uint16_t>(session)))
- .WillOnce(Return(verificationResponse));
-
- EXPECT_TRUE(pollStatus(session, &blobMock));
-}
-
-TEST_F(UpdaterTest, PollStatusReturnsAfterFailure)
-{
- ipmiblob::StatResponse verificationResponse = {};
- /* the other details of the response are ignored, and should be. */
- verificationResponse.metadata.push_back(
- static_cast<std::uint8_t>(ipmi_flash::ActionStatus::failed));
-
- EXPECT_CALL(blobMock, getStat(TypedEq<std::uint16_t>(session)))
- .WillOnce(Return(verificationResponse));
-
- EXPECT_FALSE(pollStatus(session, &blobMock));
-}
-
TEST_F(UpdaterTest, UpdateMainReturnsSuccessIfAllSuccess)
{
const std::string image = "image.bin";
diff --git a/tools/updater.cpp b/tools/updater.cpp
index 0c4b740..a364a4b 100644
--- a/tools/updater.cpp
+++ b/tools/updater.cpp
@@ -17,6 +17,7 @@
#include "updater.hpp"
#include "firmware_handler.hpp"
+#include "handler.hpp"
#include "status.hpp"
#include "tool_errors.hpp"
#include "util.hpp"
@@ -33,226 +34,6 @@
namespace host_tool
{
-bool UpdateHandler::checkAvailable(const std::string& goalFirmware)
-{
- std::vector<std::string> blobs = blob->getBlobList();
-
- auto blobInst = std::find_if(
- blobs.begin(), blobs.end(), [&goalFirmware](const std::string& iter) {
- /* Running into weird scenarios where the string comparison doesn't
- * work. TODO: revisit.
- */
- return (0 == std::memcmp(goalFirmware.c_str(), iter.c_str(),
- goalFirmware.length()));
- // return (goalFirmware.compare(iter));
- });
- if (blobInst == blobs.end())
- {
- std::fprintf(stderr, "%s not found\n", goalFirmware.c_str());
- return false;
- }
-
- /* Call stat on /flash/image (or /flash/tarball) and check if data interface
- * is supported.
- */
- ipmiblob::StatResponse stat;
-
- try
- {
- stat = blob->getStat(goalFirmware);
- }
- catch (const ipmiblob::BlobException& b)
- {
- std::fprintf(stderr, "Received exception '%s' on getStat\n", b.what());
- return false;
- }
-
- auto supported = handler->supportedType();
- if ((stat.blob_state & supported) == 0)
- {
- std::fprintf(stderr, "data interface selected not supported.\n");
- return false;
- }
-
- return true;
-}
-
-void UpdateHandler::sendFile(const std::string& target, const std::string& path)
-{
- std::uint16_t session;
- auto supported = handler->supportedType();
-
- try
- {
- session = blob->openBlob(
- target, static_cast<std::uint16_t>(supported) |
- static_cast<std::uint16_t>(blobs::OpenFlags::write));
- }
- catch (const ipmiblob::BlobException& b)
- {
- throw ToolException("blob exception received: " +
- std::string(b.what()));
- }
-
- if (!handler->sendContents(path, session))
- {
- /* Need to close the session on failure, or it's stuck open (until the
- * blob handler timeout is implemented, and even then, why make it wait.
- */
- blob->closeBlob(session);
- throw ToolException("Failed to send contents of " + path);
- }
-
- blob->closeBlob(session);
-}
-
-/* Poll an open verification session. Handling closing the session is not yet
- * owned by this method.
- */
-bool pollStatus(std::uint16_t session, ipmiblob::BlobInterface* blob)
-{
- using namespace std::chrono_literals;
-
- static constexpr auto verificationSleep = 5s;
- ipmi_flash::ActionStatus result = ipmi_flash::ActionStatus::unknown;
-
- try
- {
- static constexpr int commandAttempts = 20;
- int attempts = 0;
- bool exitLoop = false;
-
- /* Reach back the current status from the verification service output.
- */
- while (attempts++ < commandAttempts)
- {
- ipmiblob::StatResponse resp = blob->getStat(session);
-
- if (resp.metadata.size() != sizeof(std::uint8_t))
- {
- /* TODO: How do we want to handle the verification failures,
- * because closing the session to the verify blob has a special
- * as-of-yet not fully defined behavior.
- */
- std::fprintf(stderr, "Received invalid metadata response!!!\n");
- }
-
- result = static_cast<ipmi_flash::ActionStatus>(resp.metadata[0]);
-
- switch (result)
- {
- case ipmi_flash::ActionStatus::failed:
- std::fprintf(stderr, "failed\n");
- exitLoop = true;
- break;
- case ipmi_flash::ActionStatus::unknown:
- std::fprintf(stderr, "other\n");
- break;
- case ipmi_flash::ActionStatus::running:
- std::fprintf(stderr, "running\n");
- break;
- case ipmi_flash::ActionStatus::success:
- std::fprintf(stderr, "success\n");
- exitLoop = true;
- break;
- default:
- std::fprintf(stderr, "wat\n");
- }
-
- if (exitLoop)
- {
- break;
- }
- std::this_thread::sleep_for(verificationSleep);
- }
- }
- catch (const ipmiblob::BlobException& b)
- {
- throw ToolException("blob exception received: " +
- std::string(b.what()));
- }
-
- /* TODO: If this is reached and it's not success, it may be worth just
- * throwing a ToolException with a timeout message specifying the final
- * read's value.
- *
- * TODO: Given that excepting from certain points leaves the BMC update
- * state machine in an inconsistent state, we need to carefully evaluate
- * which exceptions from the lower layers allow one to try and delete the
- * blobs to rollback the state and progress.
- */
- return (result == ipmi_flash::ActionStatus::success);
-}
-
-bool UpdateHandler::verifyFile(const std::string& target)
-{
- std::uint16_t session;
- bool success = false;
-
- try
- {
- session = blob->openBlob(
- target, static_cast<std::uint16_t>(blobs::OpenFlags::write));
- }
- catch (const ipmiblob::BlobException& b)
- {
- throw ToolException("blob exception received: " +
- std::string(b.what()));
- }
-
- std::fprintf(stderr, "Committing to %s to trigger service\n",
- target.c_str());
-
- try
- {
- blob->commit(session, {});
- }
- catch (const ipmiblob::BlobException& b)
- {
- throw ToolException("blob exception received: " +
- std::string(b.what()));
- }
-
- std::fprintf(stderr, "Calling stat on %s session to check status\n",
- target.c_str());
-
- if (pollStatus(session, blob))
- {
- std::fprintf(stderr, "Returned success\n");
- success = true;
- }
- else
- {
- std::fprintf(stderr, "Returned non-success (could still "
- "be running (unlikely))\n");
- }
-
- blob->closeBlob(session);
- return (success == true);
-}
-
-void UpdateHandler::cleanArtifacts()
-{
- /* open(), commit(), close() */
- std::uint16_t session;
-
- /* Errors aren't important for this call. */
- try
- {
- std::fprintf(stderr, "Opening the cleanup blob\n");
- session =
- blob->openBlob(ipmi_flash::cleanupBlobId,
- static_cast<std::uint16_t>(blobs::OpenFlags::write));
- std::fprintf(stderr, "Committing to the cleanup blob\n");
- blob->commit(session, {});
- std::fprintf(stderr, "Closing cleanup blob\n");
- blob->closeBlob(session);
- }
- catch (...)
- {
- }
-}
-
void updaterMain(UpdateHandlerInterface* updater, const std::string& imagePath,
const std::string& signaturePath)
{
diff --git a/tools/updater.hpp b/tools/updater.hpp
index 4352c82..b3ab947 100644
--- a/tools/updater.hpp
+++ b/tools/updater.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "interface.hpp"
+#include "handler.hpp"
#include <ipmiblob/blob_interface.hpp>
#include <string>
@@ -8,83 +8,6 @@
namespace host_tool
{
-class UpdateHandlerInterface
-{
- public:
- virtual ~UpdateHandlerInterface() = default;
-
- /**
- * Check if the goal firmware is listed in the blob_list and that the
- * handler's supported data type is available.
- *
- * @param[in] goalFirmware - the firmware to check /flash/image
- * /flash/tarball, etc.
- */
- virtual bool checkAvailable(const std::string& goalFirmware) = 0;
-
- /**
- * Send the file contents at path to the blob id, target.
- *
- * @param[in] target - the blob id
- * @param[in] path - the source file path
- */
- virtual void sendFile(const std::string& target,
- const std::string& path) = 0;
-
- /**
- * Trigger verification.
- *
- * @param[in] target - the verification blob id (may support multiple in the
- * future.
- * @return true if verified, false if verification errors.
- */
- virtual bool verifyFile(const std::string& target) = 0;
-
- /**
- * Cleanup the artifacts by triggering this action.
- */
- virtual void cleanArtifacts() = 0;
-};
-
-/** Object that actually handles the update itself. */
-class UpdateHandler : public UpdateHandlerInterface
-{
- public:
- UpdateHandler(ipmiblob::BlobInterface* blob, DataInterface* handler) :
- blob(blob), handler(handler)
- {
- }
-
- ~UpdateHandler() = default;
-
- bool checkAvailable(const std::string& goalFirmware) override;
-
- /**
- * @throw ToolException on failure.
- */
- void sendFile(const std::string& target, const std::string& path) override;
-
- /**
- * @throw ToolException on failure (TODO: throw on timeout.)
- */
- bool verifyFile(const std::string& target) override;
-
- void cleanArtifacts() override;
-
- private:
- ipmiblob::BlobInterface* blob;
- DataInterface* handler;
-};
-
-/**
- * Poll an open verification session.
- *
- * @param[in] session - the open verification session
- * @param[in] blob - pointer to blob interface implementation object.
- * @return true if the verification was successul.
- */
-bool pollStatus(std::uint16_t session, ipmiblob::BlobInterface* blob);
-
/**
* Attempt to update the BMC's firmware using the interface provided.
*