| 376 | |
| 377 | |
| 378 | Try<vector<ContainerID>> getContainerIds(const string& runtimeDir) |
| 379 | { |
| 380 | lambda::function<Try<vector<ContainerID>>(const Option<ContainerID>&)> helper; |
| 381 | |
| 382 | helper = [&helper, &runtimeDir](const Option<ContainerID>& parentContainerId) |
| 383 | -> Try<vector<ContainerID>> { |
| 384 | // Loop through each container at the path, if it exists. |
| 385 | const string path = path::join( |
| 386 | parentContainerId.isSome() |
| 387 | ? getRuntimePath(runtimeDir, parentContainerId.get()) |
| 388 | : runtimeDir, |
| 389 | CONTAINER_DIRECTORY); |
| 390 | |
| 391 | if (!os::exists(path)) { |
| 392 | return vector<ContainerID>(); |
| 393 | } |
| 394 | |
| 395 | Try<list<string>> entries = os::ls(path); |
| 396 | if (entries.isError()) { |
| 397 | return Error("Failed to list '" + path + "': " + entries.error()); |
| 398 | } |
| 399 | |
| 400 | // The order always guarantee that a parent container is inserted |
| 401 | // before its child containers. This is necessary for constructing |
| 402 | // the hashmap 'containers_' in 'Containerizer::recover()'. |
| 403 | vector<ContainerID> containers; |
| 404 | |
| 405 | foreach (const string& entry, entries.get()) { |
| 406 | // We're not expecting anything else but directories here |
| 407 | // representing each container. |
| 408 | CHECK(os::stat::isdir(path::join(path, entry))); |
| 409 | |
| 410 | // TODO(benh): Validate that the entry looks like a ContainerID? |
| 411 | ContainerID container; |
| 412 | container.set_value(entry); |
| 413 | |
| 414 | if (parentContainerId.isSome()) { |
| 415 | container.mutable_parent()->CopyFrom(parentContainerId.get()); |
| 416 | } |
| 417 | |
| 418 | containers.push_back(container); |
| 419 | |
| 420 | // Now recursively build the list of nested containers. |
| 421 | Try<vector<ContainerID>> children = helper(container); |
| 422 | if (children.isError()) { |
| 423 | return Error(children.error()); |
| 424 | } |
| 425 | |
| 426 | if (!children->empty()) { |
| 427 | containers.insert(containers.end(), children->begin(), children->end()); |
| 428 | } |
| 429 | } |
| 430 | |
| 431 | return containers; |
| 432 | }; |
| 433 | |
| 434 | return helper(None()); |
| 435 | } |