You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ch...@apache.org on 2018/04/13 03:39:21 UTC
[3/3] mesos git commit: Added `STAGE_UNSTAGE_VOLUME` capability to
the test CSI plugin.
Added `STAGE_UNSTAGE_VOLUME` capability to the test CSI plugin.
Now it is required to call `NodeStageVolume` before `NodePublishVolume`
for the test CSI plugin. `NodeStageVolume` would bind-mount the volume
directory to the specified staging path, and then `NodePublishVolume`
would bind-mount the staging path to the target path.
Review: https://reviews.apache.org/r/66576/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/5a105893
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/5a105893
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/5a105893
Branch: refs/heads/master
Commit: 5a105893acbae841f68fe95c109a6ff3c3fd63a9
Parents: a9aa3ad
Author: Chun-Hung Hsiao <ch...@apache.org>
Authored: Thu Apr 12 19:42:29 2018 -0700
Committer: Chun-Hung Hsiao <ch...@mesosphere.io>
Committed: Thu Apr 12 19:42:29 2018 -0700
----------------------------------------------------------------------
src/examples/test_csi_plugin.cpp | 144 +++++++++++++++++++++++++++++++++-
1 file changed, 140 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/5a105893/src/examples/test_csi_plugin.cpp
----------------------------------------------------------------------
diff --git a/src/examples/test_csi_plugin.cpp b/src/examples/test_csi_plugin.cpp
index 357e022..9c4da88 100644
--- a/src/examples/test_csi_plugin.cpp
+++ b/src/examples/test_csi_plugin.cpp
@@ -216,6 +216,16 @@ public:
const csi::v0::ControllerGetCapabilitiesRequest* request,
csi::v0::ControllerGetCapabilitiesResponse* response) override;
+ virtual Status NodeStageVolume(
+ ServerContext* context,
+ const csi::v0::NodeStageVolumeRequest* request,
+ csi::v0::NodeStageVolumeResponse* response) override;
+
+ virtual Status NodeUnstageVolume(
+ ServerContext* context,
+ const csi::v0::NodeUnstageVolumeRequest* request,
+ csi::v0::NodeUnstageVolumeResponse* response) override;
+
virtual Status NodePublishVolume(
ServerContext* context,
const csi::v0::NodePublishVolumeRequest* request,
@@ -594,6 +604,112 @@ Status TestCSIPlugin::ControllerGetCapabilities(
}
+Status TestCSIPlugin::NodeStageVolume(
+ ServerContext* context,
+ const csi::v0::NodeStageVolumeRequest* request,
+ csi::v0::NodeStageVolumeResponse* response)
+{
+ LOG(INFO) << request->GetDescriptor()->name() << " '" << *request << "'";
+
+ // TODO(chhsiao): Validate required fields.
+
+ if (!volumes.contains(request->volume_id())) {
+ return Status(
+ grpc::NOT_FOUND,
+ "Volume '" + request->volume_id() + "' is not found");
+ }
+
+ const VolumeInfo& volumeInfo = volumes.at(request->volume_id());
+ const string path = getVolumePath(volumeInfo);
+
+ auto it = request->volume_attributes().find("path");
+ if (it == request->volume_attributes().end() || it->second != path) {
+ return Status(grpc::INVALID_ARGUMENT, "Invalid volume attributes");
+ }
+
+ if (!os::exists(request->staging_target_path())) {
+ return Status(
+ grpc::INVALID_ARGUMENT,
+ "Target path '" + request->staging_target_path() + "' is not found");
+ }
+
+ Try<fs::MountInfoTable> table = fs::MountInfoTable::read();
+ if (table.isError()) {
+ return Status(
+ grpc::INTERNAL,
+ "Failed to get mount table: " + table.error());
+ }
+
+ foreach (const fs::MountInfoTable::Entry& entry, table->entries) {
+ if (entry.target == request->staging_target_path()) {
+ return Status::OK;
+ }
+ }
+
+ Try<Nothing> mount = fs::mount(
+ path,
+ request->staging_target_path(),
+ None(),
+ MS_BIND,
+ None());
+
+ if (mount.isError()) {
+ return Status(
+ grpc::INTERNAL,
+ "Failed to mount from '" + path + "' to '" +
+ request->staging_target_path() + "': " + mount.error());
+ }
+
+ return Status::OK;
+}
+
+
+Status TestCSIPlugin::NodeUnstageVolume(
+ ServerContext* context,
+ const csi::v0::NodeUnstageVolumeRequest* request,
+ csi::v0::NodeUnstageVolumeResponse* response)
+{
+ LOG(INFO) << request->GetDescriptor()->name() << " '" << *request << "'";
+
+ // TODO(chhsiao): Validate required fields.
+
+ if (!volumes.contains(request->volume_id())) {
+ return Status(
+ grpc::NOT_FOUND,
+ "Volume '" + request->volume_id() + "' is not found");
+ }
+
+ Try<fs::MountInfoTable> table = fs::MountInfoTable::read();
+ if (table.isError()) {
+ return Status(
+ grpc::INTERNAL,
+ "Failed to get mount table: " + table.error());
+ }
+
+ bool found = false;
+ foreach (const fs::MountInfoTable::Entry& entry, table->entries) {
+ if (entry.target == request->staging_target_path()) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ return Status::OK;
+ }
+
+ Try<Nothing> unmount = fs::unmount(request->staging_target_path());
+ if (unmount.isError()) {
+ return Status(
+ grpc::INTERNAL,
+ "Failed to unmount '" + request->staging_target_path() +
+ "': " + unmount.error());
+ }
+
+ return Status::OK;
+}
+
+
Status TestCSIPlugin::NodePublishVolume(
ServerContext* context,
const csi::v0::NodePublishVolumeRequest* request,
@@ -623,6 +739,12 @@ Status TestCSIPlugin::NodePublishVolume(
"Target path '" + request->target_path() + "' is not found");
}
+ if (request->staging_target_path().empty()) {
+ return Status(
+ grpc::FAILED_PRECONDITION,
+ "Expecting 'staging_target_path' to be set");
+ }
+
Try<fs::MountInfoTable> table = fs::MountInfoTable::read();
if (table.isError()) {
return Status(
@@ -630,6 +752,20 @@ Status TestCSIPlugin::NodePublishVolume(
"Failed to get mount table: " + table.error());
}
+ bool found = false;
+ foreach (const fs::MountInfoTable::Entry& entry, table->entries) {
+ if (entry.target == request->staging_target_path()) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ return Status(
+ grpc::FAILED_PRECONDITION,
+ "Volume '" + request->volume_id() + "' has not been staged yet");
+ }
+
foreach (const fs::MountInfoTable::Entry& entry, table->entries) {
if (entry.target == request->target_path()) {
return Status::OK;
@@ -637,7 +773,7 @@ Status TestCSIPlugin::NodePublishVolume(
}
Try<Nothing> mount = fs::mount(
- path,
+ request->staging_target_path(),
request->target_path(),
None(),
MS_BIND,
@@ -700,9 +836,6 @@ Status TestCSIPlugin::NodeUnpublishVolume(
return Status::OK;
}
- const VolumeInfo& volumeInfo = volumes.at(request->volume_id());
- const string path = getVolumePath(volumeInfo);
-
Try<Nothing> unmount = fs::unmount(request->target_path());
if (unmount.isError()) {
return Status(
@@ -735,6 +868,9 @@ Status TestCSIPlugin::NodeGetCapabilities(
{
LOG(INFO) << request->GetDescriptor()->name() << " '" << *request << "'";
+ response->add_capabilities()->mutable_rpc()->set_type(
+ csi::v0::NodeServiceCapability::RPC::STAGE_UNSTAGE_VOLUME);
+
return Status::OK;
}