| 104 | typename TResourceConversion, |
| 105 | typename TOperation> |
| 106 | Try<vector<TResourceConversion>> getResourceConversions( |
| 107 | const TOperation& operation) |
| 108 | { |
| 109 | vector<TResourceConversion> conversions; |
| 110 | |
| 111 | switch (operation.type()) { |
| 112 | case TOperation::UNKNOWN: |
| 113 | return Error("Unknown operation"); |
| 114 | |
| 115 | case TOperation::LAUNCH: |
| 116 | case TOperation::LAUNCH_GROUP: |
| 117 | case TOperation::CREATE_DISK: |
| 118 | case TOperation::DESTROY_DISK: |
| 119 | return Error("Operation not supported"); |
| 120 | |
| 121 | case TOperation::RESERVE: { |
| 122 | TResources reserved(operation.reserve().resources()); |
| 123 | |
| 124 | // If the operation explicitly specifies a `source` we use that, |
| 125 | // otherwise we assume that the operation is "pushing" a single |
| 126 | // reservation. At this point, the resources in the operation |
| 127 | // should have been already sanity checked, so we don't have to |
| 128 | // repeat that here. |
| 129 | TResources consumed; |
| 130 | if (operation.reserve().source_size() > 0) { |
| 131 | consumed = TResources(operation.reserve().source()); |
| 132 | } else { |
| 133 | consumed = reserved.popReservation(); |
| 134 | } |
| 135 | conversions.emplace_back(consumed, reserved); |
| 136 | break; |
| 137 | } |
| 138 | |
| 139 | case TOperation::UNRESERVE: { |
| 140 | foreach (const TResource& reserved, operation.unreserve().resources()) { |
| 141 | // Note that we only allow "popping" a single reservation at time. |
| 142 | TResources converted = TResources(reserved).popReservation(); |
| 143 | conversions.emplace_back(reserved, converted); |
| 144 | } |
| 145 | break; |
| 146 | } |
| 147 | |
| 148 | case TOperation::CREATE: { |
| 149 | foreach (const TResource& volume, operation.create().volumes()) { |
| 150 | // Strip persistence and volume from the disk info so that we |
| 151 | // can subtract it from the original resources. |
| 152 | // TODO(jieyu): Non-persistent volumes are not supported for |
| 153 | // now. Persistent volumes can only be be created from regular |
| 154 | // disk resources. Revisit this once we start to support |
| 155 | // non-persistent volumes. |
| 156 | TResource stripped = volume; |
| 157 | |
| 158 | if (stripped.disk().has_source()) { |
| 159 | stripped.mutable_disk()->clear_persistence(); |
| 160 | stripped.mutable_disk()->clear_volume(); |
| 161 | } else { |
| 162 | stripped.clear_disk(); |
| 163 | } |