| 282 | |
| 283 | |
| 284 | Future<Nothing> ServiceManagerProcess::recover() |
| 285 | { |
| 286 | // For the unmanaged CSI plugin, we do not need to recover anything. |
| 287 | if (!serviceEndpoints.empty()) { |
| 288 | return Nothing(); |
| 289 | } |
| 290 | |
| 291 | CHECK(!serviceContainers.empty()); |
| 292 | |
| 293 | return getContainers() |
| 294 | .then(process::defer(self(), [=]( |
| 295 | const hashmap<ContainerID, Option<ContainerStatus>>& containers) |
| 296 | -> Future<Nothing> { |
| 297 | Try<list<string>> containerPaths = |
| 298 | paths::getContainerPaths(rootDir, info.type(), info.name()); |
| 299 | |
| 300 | if (containerPaths.isError()) { |
| 301 | return Failure( |
| 302 | "Failed to find service container paths for CSI plugin type '" + |
| 303 | info.type() + "' and name '" + info.name() + |
| 304 | "': " + containerPaths.error()); |
| 305 | } |
| 306 | |
| 307 | vector<Future<Nothing>> futures; |
| 308 | |
| 309 | foreach (const string& path, containerPaths.get()) { |
| 310 | Try<paths::ContainerPath> containerPath = |
| 311 | paths::parseContainerPath(rootDir, path); |
| 312 | |
| 313 | if (containerPath.isError()) { |
| 314 | return Failure( |
| 315 | "Failed to parse service container path '" + path + |
| 316 | "': " + containerPath.error()); |
| 317 | } |
| 318 | |
| 319 | CHECK_EQ(info.type(), containerPath->type); |
| 320 | CHECK_EQ(info.name(), containerPath->name); |
| 321 | |
| 322 | const ContainerID& containerId = containerPath->containerId; |
| 323 | |
| 324 | // NOTE: Since `GET_CONTAINERS` might return containers that are being |
| 325 | // destroyed, to identify if the container is actually running, we check |
| 326 | // if the `executor_pid` field is set as a workaround. |
| 327 | bool isRunningContainer = |
| 328 | containers.contains(containerId) && |
| 329 | containers.at(containerId).isSome() && |
| 330 | containers.at(containerId)->has_executor_pid(); |
| 331 | |
| 332 | // Do not kill the up-to-date running controller or node container. |
| 333 | if (serviceContainers.contains_value(containerId) && |
| 334 | isRunningContainer) { |
| 335 | const string configPath = paths::getContainerInfoPath( |
| 336 | rootDir, info.type(), info.name(), containerId); |
| 337 | |
| 338 | if (os::exists(configPath)) { |
| 339 | Result<CSIPluginContainerInfo> config = |
| 340 | slave::state::read<CSIPluginContainerInfo>(configPath); |
| 341 | |