Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 46 additions & 65 deletions OCIContainer/OCIContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -73,7 +72,6 @@ void OCIContainer::Deinitialize(PluginHost::IShell *service)
Unregister("getContainerState");
Unregister("getContainerInfo");
Unregister("startContainer");
Unregister("startContainerFromCryptedBundle");
Unregister("startContainerFromDobbySpec");
Unregister("stopContainer");
Unregister("pauseContainer");
Expand Down Expand Up @@ -226,109 +224,87 @@ uint32_t OCIContainer::getContainerInfo(const JsonObject &parameters, 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 &parameters, 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<int> 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 &parameters, JsonObject &response)
uint32_t OCIContainer::startContainer(const JsonObject &parameters, 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();

// Can be used to pass file descriptors to container construction.
// Currently unsupported, see DobbyProxy::startContainerFromBundle().
std::list<int> 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.");
response["error"] = "mount failed";
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
{
Expand All @@ -341,18 +317,23 @@ uint32_t OCIContainer::startContainerFromCryptedBundle(const JsonObject &paramet
{
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";
}

Expand Down Expand Up @@ -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<OCIContainer*>(reinterpret_cast<const OCIContainer*>(_this));

if (err == omi::IOmiProxy::ErrorType::verityFailed)
if (__this != nullptr && err == omi::IOmiProxy::ErrorType::verityFailed)
{
__this->onVerityFailed(id);
}
Expand Down
1 change: 0 additions & 1 deletion OCIContainer/OCIContainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ class OCIContainer : public PluginHost::IPlugin, public PluginHost::JSONRPC
uint32_t getContainerState(const JsonObject &parameters, JsonObject &response);
uint32_t getContainerInfo(const JsonObject &parameters, JsonObject &response);
uint32_t startContainer(const JsonObject &parameters, JsonObject &response);
uint32_t startContainerFromCryptedBundle(const JsonObject &parameters, JsonObject &response);
uint32_t startContainerFromDobbySpec(const JsonObject &parameters, JsonObject &response);
uint32_t stopContainer(const JsonObject &parameters, JsonObject &response);
uint32_t pauseContainer(const JsonObject &parameters, JsonObject &response);
Expand Down
62 changes: 0 additions & 62 deletions OCIContainer/OCIContainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
Expand Down