From b5e1e15c192cf98f709ff96572f05fd72d35fffb Mon Sep 17 00:00:00 2001 From: Damian Wrobel Date: Wed, 19 Jul 2023 10:23:50 +0200 Subject: [PATCH] ONEM-30706 OMI upstreaming (backports) - Backports upstreamed version of startContainer()[1] which can start both plain and dm-verity encrypted applications transparently. - Removes startContainerFromCryptedBundle() LGi proprietary method. [1] https://github.com/rdkcentral/rdkservices/pull/4185 no_jenkins --- OCIContainer/OCIContainer.cpp | 111 ++++++++++++++------------------- OCIContainer/OCIContainer.h | 1 - OCIContainer/OCIContainer.json | 62 ------------------ 3 files changed, 46 insertions(+), 128 deletions(-) diff --git a/OCIContainer/OCIContainer.cpp b/OCIContainer/OCIContainer.cpp index 0ce060f532..cf35dd6efa 100644 --- a/OCIContainer/OCIContainer.cpp +++ b/OCIContainer/OCIContainer.cpp @@ -23,7 +23,6 @@ OCIContainer::OCIContainer() Register("getContainerState", &OCIContainer::getContainerState, this); Register("getContainerInfo", &OCIContainer::getContainerInfo, this); Register("startContainer", &OCIContainer::startContainer, this); - Register("startContainerFromCryptedBundle", &OCIContainer::startContainerFromCryptedBundle, this); Register("startContainerFromDobbySpec", &OCIContainer::startContainerFromDobbySpec, this); Register("stopContainer", &OCIContainer::stopContainer, this); Register("pauseContainer", &OCIContainer::pauseContainer, this); @@ -73,7 +72,6 @@ void OCIContainer::Deinitialize(PluginHost::IShell *service) Unregister("getContainerState"); Unregister("getContainerInfo"); Unregister("startContainer"); - Unregister("startContainerFromCryptedBundle"); Unregister("startContainerFromDobbySpec"); Unregister("stopContainer"); Unregister("pauseContainer"); @@ -226,82 +224,54 @@ uint32_t OCIContainer::getContainerInfo(const JsonObject ¶meters, JsonObject returnResponse(true); } -/** - * @brief Starts a container from an OCI bundle - * - * @param[in] parameters - Must include 'containerId' and 'bundlePath'. - * @param[out] response - Dobby descriptor of the started container. - * - * @return A code indicating success. - */ -uint32_t OCIContainer::startContainer(const JsonObject ¶meters, JsonObject &response) -{ - LOGINFO("Start container from OCI bundle"); - - // To start a container, we need a path to an OCI bundle and an ID for the container - returnIfStringParamNotFound(parameters, "containerId"); - returnIfStringParamNotFound(parameters, "bundlePath"); +static bool is_encrypted(const std::string &bundlePath) { + struct stat st; - std::string id = parameters["containerId"].String(); - std::string bundlePath = parameters["bundlePath"].String(); - std::string command = parameters["command"].String(); - std::string westerosSocket = parameters["westerosSocket"].String(); + std::string str = bundlePath + "rootfs.img"; - // Can be used to pass file descriptors to container construction. - // Currently unsupported, see DobbyProxy::startContainerFromBundle(). - std::list emptyList; + if (stat(str.c_str(), &st)) + { + return false; + } - int descriptor; - // If no additional arguments, start the container - if ((command == "null" || command.empty()) && (westerosSocket == "null" || westerosSocket.empty())) + if (!(st.st_mode & S_IFREG || st.st_mode & S_IFLNK)) { - descriptor = mDobbyProxy->startContainerFromBundle(id, bundlePath, emptyList); + return false; } - else + + str = bundlePath + "config.json.jwt"; + + if (stat(str.c_str(), &st)) { - // Dobby expects empty strings if values not set - if (command == "null" || command.empty()) - { - command = ""; - } - if (westerosSocket == "null" || westerosSocket.empty()) - { - westerosSocket = ""; - } - descriptor = mDobbyProxy->startContainerFromBundle(id, bundlePath, emptyList, command, westerosSocket); + return false; } - // startContainer returns -1 on failure - if (descriptor <= 0) + if (!(st.st_mode & S_IFREG || st.st_mode & S_IFLNK)) { - LOGERR("Failed to start container - internal Dobby error."); - returnResponse(false); + return false; } - response["descriptor"] = descriptor; - returnResponse(true); + return true; } /** - * @brief Starts a container from a crypted OCI bundle + * @brief Starts a container from an OCI bundle * - * @param[in] parameters - Must include 'containerId', 'rootFSPath' and 'configFilePath'. + * @param[in] parameters - Must include 'containerId' and 'bundlePath'. * @param[out] response - Dobby descriptor of the started container. * * @return A code indicating success. */ -uint32_t OCIContainer::startContainerFromCryptedBundle(const JsonObject ¶meters, JsonObject &response) +uint32_t OCIContainer::startContainer(const JsonObject ¶meters, JsonObject &response) { - LOGINFO("Start container from crypted OCI bundle"); + LOGINFO("Start container from OCI bundle"); // To start a container, we need a path to an OCI bundle and an ID for the container returnIfStringParamNotFound(parameters, "containerId"); - returnIfStringParamNotFound(parameters, "rootFSPath"); - returnIfStringParamNotFound(parameters, "configFilePath"); + returnIfStringParamNotFound(parameters, "bundlePath"); std::string id = parameters["containerId"].String(); - std::string rootfsPath = parameters["rootFSPath"].String(); - std::string configPath = parameters["configFilePath"].String(); + std::string bundlePath = parameters["bundlePath"].String(); std::string command = parameters["command"].String(); std::string westerosSocket = parameters["westerosSocket"].String(); @@ -309,13 +279,13 @@ uint32_t OCIContainer::startContainerFromCryptedBundle(const JsonObject ¶met // Currently unsupported, see DobbyProxy::startContainerFromBundle(). std::list emptyList; - int descriptor; - std::string containerPath; - if (!mOmiProxy->mountCryptedBundle(id, - rootfsPath, - configPath, + const bool encrypted = is_encrypted(bundlePath); + + if (encrypted && !mOmiProxy->mountCryptedBundle(id, + bundlePath + "rootfs.img", + bundlePath + "config.json.jwt", containerPath)) { LOGERR("Failed to start container - sync mount request to omi failed."); @@ -323,12 +293,18 @@ uint32_t OCIContainer::startContainerFromCryptedBundle(const JsonObject ¶met returnResponse(false); } - LOGINFO("Mount request to omi succeeded, contenerPath: %s", containerPath.c_str()); + if (encrypted) + { + LOGINFO("Mount request to omi succeeded, contenerPath: %s", containerPath.c_str()); + } + + int descriptor; // If no additional arguments, start the container if ((command == "null" || command.empty()) && (westerosSocket == "null" || westerosSocket.empty())) { - descriptor = mDobbyProxy->startContainerFromBundle(id, containerPath, emptyList); + LOGINFO("startContainerFromBundle: id: %s, containerPath: %s", id.c_str(), encrypted ? containerPath.c_str() : bundlePath.c_str()); + descriptor = mDobbyProxy->startContainerFromBundle(id, encrypted ? containerPath : bundlePath, emptyList); } else { @@ -341,18 +317,23 @@ uint32_t OCIContainer::startContainerFromCryptedBundle(const JsonObject ¶met { westerosSocket = ""; } - descriptor = mDobbyProxy->startContainerFromBundle(id, containerPath, emptyList, command, westerosSocket); + + LOGINFO("startContainerFromBundle: id: %s, containerPath: %s, command: %s, westerosSocket: %s", id.c_str(), encrypted ? containerPath.c_str() : bundlePath.c_str(), command.c_str(), westerosSocket.c_str()); + descriptor = mDobbyProxy->startContainerFromBundle(id, encrypted ? containerPath : bundlePath, emptyList, command, westerosSocket); } // startContainer returns -1 on failure if (descriptor <= 0) { - LOGERR("Failed to start container - internal Dobby error. Unmounting container."); + LOGERR("Failed to start container - internal Dobby error."); - if (!mOmiProxy->umountCryptedBundle(id.c_str())) { + if (encrypted && !mOmiProxy->umountCryptedBundle(id.c_str())) + { LOGERR("Failed to umount container %s - sync unmount request to omi failed.", id.c_str()); response["error"] = "dobby start failed, unmount failed"; - } else { + } + else + { response["error"] = "dobby start failed"; } @@ -696,7 +677,7 @@ const void OCIContainer::omiErrorListener(const std::string& id, omi::IOmiProxy: // Cast const void* back to OCIContainer* type to get 'this' OCIContainer* __this = const_cast(reinterpret_cast(_this)); - if (err == omi::IOmiProxy::ErrorType::verityFailed) + if (__this != nullptr && err == omi::IOmiProxy::ErrorType::verityFailed) { __this->onVerityFailed(id); } diff --git a/OCIContainer/OCIContainer.h b/OCIContainer/OCIContainer.h index a77f6cee2a..0b88f107bd 100644 --- a/OCIContainer/OCIContainer.h +++ b/OCIContainer/OCIContainer.h @@ -40,7 +40,6 @@ class OCIContainer : public PluginHost::IPlugin, public PluginHost::JSONRPC uint32_t getContainerState(const JsonObject ¶meters, JsonObject &response); uint32_t getContainerInfo(const JsonObject ¶meters, JsonObject &response); uint32_t startContainer(const JsonObject ¶meters, JsonObject &response); - uint32_t startContainerFromCryptedBundle(const JsonObject ¶meters, JsonObject &response); uint32_t startContainerFromDobbySpec(const JsonObject ¶meters, JsonObject &response); uint32_t stopContainer(const JsonObject ¶meters, JsonObject &response); uint32_t pauseContainer(const JsonObject ¶meters, JsonObject &response); diff --git a/OCIContainer/OCIContainer.json b/OCIContainer/OCIContainer.json index f7b92c4678..2d86f130d8 100644 --- a/OCIContainer/OCIContainer.json +++ b/OCIContainer/OCIContainer.json @@ -401,68 +401,6 @@ ] } }, - "startContainerFromCryptedBundle":{ - "summary": "Starts a new container from an existing encrypted OCI bundle", - "params": { - "type": "object", - "properties": { - "containerId": { - "$ref": "#/definitions/containerId" - }, - "rootFSPath": { - "summary": "Path to the enrypted OCI bundle containing the rootfs to use to create the container", - "type": "string", - "example": "/containers/rootfs/myBundle" - }, - "configFilePath": { - "summary": "Path to the enrypted OCI bundle containing the config file to use to create the container", - "type": "string", - "example": "/containers/var/myBundle" - }, - "command": { - "$ref": "#/definitions/command" - }, - "westerosSocket":{ - "summary": "Path to a Westeros socket to mount inside the container", - "type": "string", - "example": "/usr/mySocket" - }, - "envvar": { - "summary": "A list of environment variables to add to the container", - "type": "array", - "items": { - "type": "string", - "example": "FOO=BAR" - } - } - }, - "required": [ - "containerId", - "rootFSPath", - "configFilePath" - ] - }, - "result": { - "type": "object", - "properties": { - "descriptor": { - "$ref": "#/definitions/Descriptor" - }, - "success":{ - "$ref": "#/definitions/success" - }, - "error":{ - "summary": "An error message in case of a failure", - "type": "string", - "example": "internal dobby error" - } - }, - "required": [ - "descriptor", - "success" - ] - } - }, "startContainerFromDobbySpec":{ "summary": "Starts a new container from a legacy Dobby JSON specification.\n \n### Events \n| Event | Description | \n| :----------- | :----------- | \n| `onContainerStarted` | Triggers when a new container starts running.|", "events": [