diff --git a/OCIContainer/CMakeLists.txt b/OCIContainer/CMakeLists.txt index 2aff9fc947..80a5700e0a 100644 --- a/OCIContainer/CMakeLists.txt +++ b/OCIContainer/CMakeLists.txt @@ -2,6 +2,7 @@ set(PLUGIN_NAME OCIContainer) set(MODULE_NAME ${NAMESPACE}${PLUGIN_NAME}) set(PLUGIN_OCICONTAINER_STARTUPORDER "" CACHE STRING "To configure startup order of OCIContainer plugin") +option(PLUGIN_HIBERNATESUPPORT "Include hibernate support in the build." OFF) find_package(PkgConfig) find_package(${NAMESPACE}Plugins REQUIRED) @@ -45,6 +46,9 @@ find_package_handle_standard_args( SYSTEMD_LIBRARIES SYSTEMD_INCLUDE_DIRS ) +if(PLUGIN_HIBERNATESUPPORT) + target_compile_definitions(${MODULE_NAME} PRIVATE HIBERNATE_SUPPORT_ENABLED=1) +endif() target_include_directories(${MODULE_NAME} PRIVATE diff --git a/OCIContainer/OCIContainer.cpp b/OCIContainer/OCIContainer.cpp index 830ed328f1..87c7456561 100644 --- a/OCIContainer/OCIContainer.cpp +++ b/OCIContainer/OCIContainer.cpp @@ -49,6 +49,10 @@ OCIContainer::OCIContainer() Register("pauseContainer", &OCIContainer::pauseContainer, this); Register("resumeContainer", &OCIContainer::resumeContainer, this); Register("executeCommand", &OCIContainer::executeCommand, this); + #ifdef HIBERNATE_SUPPORT_ENABLED + Register("hibernateContainer", &OCIContainer::hibernateContainer, this); + Register("wakeupContainer", &OCIContainer::wakeupContainer, this); + #endif } OCIContainer::~OCIContainer() @@ -97,6 +101,10 @@ void OCIContainer::Deinitialize(PluginHost::IShell *service) Unregister("pauseContainer"); Unregister("resumeContainer"); Unregister("executeCommand"); + #ifdef HIBERNATE_SUPPORT_ENABLED + Unregister("hibernateContainer"); + Unregister("wakeupContainer"); + #endif } string OCIContainer::Information() const @@ -187,6 +195,17 @@ uint32_t OCIContainer::getContainerState(const JsonObject ¶meters, JsonObjec case IDobbyProxyEvents::ContainerState::Stopped: containerState = "Stopped"; break; + #ifdef HIBERNATE_SUPPORT_ENABLED + case IDobbyProxyEvents::ContainerState::Hibernating: + containerState = "Hibernating"; + break; + case IDobbyProxyEvents::ContainerState::Hibernated: + containerState = "Hibernated"; + break; + case IDobbyProxyEvents::ContainerState::Awakening: + containerState = "Awakening"; + break; + #endif default: containerState = "Unknown"; break; @@ -529,6 +548,76 @@ uint32_t OCIContainer::resumeContainer(const JsonObject ¶meters, JsonObject returnResponse(true); } +#ifdef HIBERNATE_SUPPORT_ENABLED +/** + * @brief Hibernate a container + * + * @param[in] parameters Must include 'containerId' of container to resume. + * @param[out] response Success. + * + * @return A code indicating success. + */ +uint32_t OCIContainer::hibernateContainer(const JsonObject ¶meters, JsonObject &response) +{ + LOGINFO("Hibernate container"); + + // Need to have an ID to hibernate + returnIfStringParamNotFound(parameters, "containerId"); + std::string id = parameters["containerId"].String(); + std::string options; + + int cd = GetContainerDescriptorFromId(id); + if (cd < 0) + { + returnResponse(false); + } + + bool offloadSuccessfully = mDobbyProxy->hibernateContainer(cd,options); + + if (!offloadSuccessfully) + { + LOGERR("Failed to Hibernate container - internal Dobby error."); + returnResponse(false); + } + + returnResponse(true); + +} +/** + * @brief Wakeup a container + * + * @param[in] parameters Must include 'containerId' of container to resume. + * @param[out] response Success. + * + * @return A code indicating success. + */ +uint32_t OCIContainer::wakeupContainer(const JsonObject ¶meters, JsonObject &response) +{ + LOGINFO("Wakeup Container"); + + // Need to have an ID to wakeup + returnIfStringParamNotFound(parameters, "containerId"); + std::string id = parameters["containerId"].String(); + + int cd = GetContainerDescriptorFromId(id); + if (cd < 0) + { + returnResponse(false); + } + + bool wokeSuccessfully = mDobbyProxy->wakeupContainer(cd); + + if (!wokeSuccessfully) + { + LOGERR("Failed to Wake up container - internal Dobby error."); + returnResponse(false); + } + + returnResponse(true); + +} +#endif + /** * @brief Execute a command in a container. * @@ -568,6 +657,36 @@ uint32_t OCIContainer::executeCommand(const JsonObject ¶meters, JsonObject & returnResponse(true); } +#ifdef HIBERNATE_SUPPORT_ENABLED +/** + * @brief Send an event notifying that a container has hibernated. + * + * @param descriptor Container descriptor. + * @param name Container name. + */ +void OCIContainer::onContainerHibernated(int32_t descriptor, const std::string& name) +{ + JsonObject params; + params["descriptor"] = std::to_string(descriptor); + params["name"] = name; + sendNotify("onContainerHibernated", params); +} + +/** + * @brief Send an event notifying that a container has Awoken. + * + * @param descriptor Container descriptor. + * @param name Container name. + */ +void OCIContainer::onContainerAwoken(int32_t descriptor, const std::string& name) +{ + JsonObject params; + params["descriptor"] = std::to_string(descriptor); + params["name"] = name; + sendNotify("onContainerAwoken", params); +} +#endif + /** * @brief Send an event notifying that a container has started. @@ -666,6 +785,16 @@ const void OCIContainer::stateListener(int32_t descriptor, const std::string& na { __this->onContainerStopped(descriptor, name); } + #ifdef HIBERNATE_SUPPORT_ENABLED + else if (state == IDobbyProxyEvents::ContainerState::Hibernated) + { + __this->onContainerHibernated(descriptor, name); + } + else if (state == IDobbyProxyEvents::ContainerState::Awakening) + { + __this->onContainerAwoken(descriptor, name); + } + #endif else { LOGINFO("Received an unknown state event for container '%s'.", name.c_str()); diff --git a/OCIContainer/OCIContainer.h b/OCIContainer/OCIContainer.h index f0291eea8f..2748207944 100644 --- a/OCIContainer/OCIContainer.h +++ b/OCIContainer/OCIContainer.h @@ -45,12 +45,20 @@ class OCIContainer : public PluginHost::IPlugin, public PluginHost::JSONRPC uint32_t pauseContainer(const JsonObject ¶meters, JsonObject &response); uint32_t resumeContainer(const JsonObject ¶meters, JsonObject &response); uint32_t executeCommand(const JsonObject ¶meters, JsonObject &response); + #ifdef HIBERNATE_SUPPORT_ENABLED + uint32_t hibernateContainer(const JsonObject ¶meters, JsonObject &response); + uint32_t wakeupContainer(const JsonObject ¶meters, JsonObject &response); + #endif //End methods //Begin events void onContainerStarted(int32_t descriptor, const std::string& name); void onContainerStopped(int32_t descriptor, const std::string& name); void onVerityFailed(const std::string& name); + #ifdef HIBERNATE_SUPPORT_ENABLED + void onContainerHibernated(int32_t descriptor, const std::string& name); + void onContainerAwoken(int32_t descriptor, const std::string& name); + #endif //End events //Build QueryInterface implementation, specifying all possible interfaces to be returned.