| 782 | |
| 783 | |
| 784 | void CheckerProcess::___nestedCommandCheck( |
| 785 | shared_ptr<Promise<int>> promise, |
| 786 | const ContainerID& checkContainerId, |
| 787 | const http::Response& launchResponse, |
| 788 | runtime::Nested nested) |
| 789 | { |
| 790 | if (launchResponse.code != http::Status::OK) { |
| 791 | // The agent was unable to launch the check container, |
| 792 | // we treat this as a transient failure. |
| 793 | LOG(WARNING) << "Received '" << launchResponse.status << "' (" |
| 794 | << launchResponse.body << ") while launching " << name |
| 795 | << " for task '" << taskId << "'"; |
| 796 | |
| 797 | // We'll try to remove the container created for the check at the |
| 798 | // beginning of the next check. In order to prevent a failure, the |
| 799 | // promise should only be completed once we're sure that the |
| 800 | // container has terminated. |
| 801 | waitNestedContainer(checkContainerId, nested) |
| 802 | .onAny([promise](const Future<Option<int>>&) { |
| 803 | // We assume that once `WaitNestedContainer` returns, |
| 804 | // irrespective of whether the response contains a failure, the |
| 805 | // container will be in a terminal state, and that it will be |
| 806 | // possible to remove it. |
| 807 | promise->discard(); |
| 808 | }); |
| 809 | |
| 810 | return; |
| 811 | } |
| 812 | |
| 813 | Try<tuple<string, string>> checkOutput = |
| 814 | decodeProcessIOData(launchResponse.body); |
| 815 | |
| 816 | if (checkOutput.isError()) { |
| 817 | LOG(WARNING) << "Failed to decode the output of the " << name |
| 818 | << " for task '" << taskId << "': " << checkOutput.error(); |
| 819 | } else { |
| 820 | string stdoutReceived; |
| 821 | string stderrReceived; |
| 822 | |
| 823 | tie(stdoutReceived, stderrReceived) = checkOutput.get(); |
| 824 | |
| 825 | LOG(INFO) << "Output of the " << name << " for task '" << taskId |
| 826 | << "' (stdout):" << std::endl << stdoutReceived; |
| 827 | |
| 828 | LOG(INFO) << "Output of the " << name << " for task '" << taskId |
| 829 | << "' (stderr):" << std::endl << stderrReceived; |
| 830 | } |
| 831 | |
| 832 | waitNestedContainer(checkContainerId, nested) |
| 833 | .onFailed([promise](const string& failure) { |
| 834 | promise->fail( |
| 835 | "Unable to get the exit code: " + failure); |
| 836 | }) |
| 837 | .onReady([promise](const Option<int>& status) -> void { |
| 838 | if (status.isNone()) { |
| 839 | promise->fail("Unable to get the exit code"); |
| 840 | #ifndef __WINDOWS__ |
| 841 | // TODO(akagup): Implement this for Windows. The `WaitNestedContainer` |