| 1364 | |
| 1365 | |
| 1366 | Try<VolumeInfo, StatusError> TestCSIPlugin::createVolume( |
| 1367 | const string& name, |
| 1368 | const Bytes& requiredBytes, |
| 1369 | const Bytes& limitBytes, |
| 1370 | const RepeatedPtrField<VolumeCapability>& capabilities, |
| 1371 | const Map<string, string> parameters) |
| 1372 | { |
| 1373 | // The volume ID is determined by `name`, with reserved characters escaped. |
| 1374 | const string volumeId = http::encode(name); |
| 1375 | |
| 1376 | foreach (const VolumeCapability& capability, capabilities) { |
| 1377 | if (capability != defaultVolumeCapability) { |
| 1378 | return StatusError(Status( |
| 1379 | grpc::INVALID_ARGUMENT, "Unsupported volume capabilities")); |
| 1380 | } |
| 1381 | } |
| 1382 | |
| 1383 | if (parameters != createParameters) { |
| 1384 | return StatusError(Status( |
| 1385 | grpc::INVALID_ARGUMENT, "Unsupported create parameters")); |
| 1386 | } |
| 1387 | |
| 1388 | Option<VolumeInfo> found = findVolumeByName(name); |
| 1389 | |
| 1390 | if (found.isSome()) { |
| 1391 | if (found->capacity > limitBytes) { |
| 1392 | return StatusError(Status( |
| 1393 | grpc::ALREADY_EXISTS, "Cannot satisfy limit bytes")); |
| 1394 | } |
| 1395 | |
| 1396 | if (found->capacity < requiredBytes) { |
| 1397 | return StatusError(Status( |
| 1398 | grpc::ALREADY_EXISTS, "Cannot satisfy required bytes")); |
| 1399 | } |
| 1400 | |
| 1401 | return *found; |
| 1402 | } else { |
| 1403 | if (availableCapacity < requiredBytes) { |
| 1404 | return StatusError(Status(grpc::OUT_OF_RANGE, "Insufficient capacity")); |
| 1405 | } |
| 1406 | |
| 1407 | |
| 1408 | // We assume that `requiredBytes <= limitBytes` has been verified. |
| 1409 | const Bytes defaultSize = min(availableCapacity, DEFAULT_VOLUME_CAPACITY); |
| 1410 | |
| 1411 | VolumeInfo volumeInfo = createVolumeInfo( |
| 1412 | min(max(defaultSize, requiredBytes), limitBytes), |
| 1413 | name, |
| 1414 | volumeMetadata); |
| 1415 | |
| 1416 | Try<Nothing> mkdir = os::mkdir(volumeInfo.path); |
| 1417 | if (mkdir.isError()) { |
| 1418 | return StatusError(Status( |
| 1419 | grpc::INTERNAL, |
| 1420 | "Failed to create volume '" + volumeInfo.id + "': " + mkdir.error())); |
| 1421 | } |
| 1422 | |
| 1423 | CHECK_GE(availableCapacity, volumeInfo.capacity); |