Future<Option<ContainerPrepareInfo>> PosixFilesystemIsolatorProcess::prepare( const ContainerID& containerId, const ExecutorInfo& executorInfo, const ContainerConfig& containerConfig) { if (infos.contains(containerId)) { return Failure("Container has already been prepared"); } if (executorInfo.has_container()) { CHECK_EQ(executorInfo.container().type(), ContainerInfo::MESOS); // Return failure if the container change the filesystem root // because the symlinks will become invalid in the new root. if (executorInfo.container().mesos().has_image()) { return Failure("Container root filesystems not supported"); } if (executorInfo.container().volumes().size() > 0) { return Failure("Volumes in ContainerInfo is not supported"); } } infos.put(containerId, Owned<Info>(new Info(containerConfig.directory()))); return update(containerId, executorInfo.resources()) .then([]() -> Future<Option<ContainerPrepareInfo>> { return None(); }); }
process::Future<Option<ContainerPrepareInfo>> NetworkIsolatorProcess::prepare( const ContainerID& containerId, const ExecutorInfo& executorInfo, const std::string& directory, const Option<std::string>& user) { LOG(INFO) << "NetworkIsolator::prepare for container: " << containerId; if (!executorInfo.has_container()) { LOG(INFO) << "NetworkIsolator::prepare Ignoring request as " << "executorInfo.container is missing for container: " << containerId; return None(); } if (executorInfo.container().network_infos().size() == 0) { LOG(INFO) << "NetworkIsolator::prepare Ignoring request as " << "executorInfo.container.network_infos is missing for " << "container: " << containerId; return None(); } if (executorInfo.container().network_infos().size() > 1) { return Failure( "NetworkIsolator:: multiple NetworkInfos are not supported."); } NetworkInfo networkInfo = executorInfo.container().network_infos(0); if (networkInfo.has_protocol()) { return Failure( "NetworkIsolator: NetworkInfo.protocol is deprecated and unsupported."); } if (networkInfo.has_ip_address()) { return Failure( "NetworkIsolator: NetworkInfo.ip_address is deprecated and" " unsupported."); } string uid = UUID::random().toString(); // Two IPAM commands: // 1) reserve for IPs the user has specifically asked for. // 2) auto-assign IPs. // Spin through all IPAddress messages once to get info for each command. // Then we'll issue each command if needed. IPAMReserveIPMessage reserveMessage; IPAMReserveIPMessage::Args* reserveArgs = reserveMessage.mutable_args(); // Counter of IPs to auto assign. int numIPv4 = 0; foreach (const NetworkInfo::IPAddress& ipAddress, networkInfo.ip_addresses()) { if (ipAddress.has_ip_address() && ipAddress.has_protocol()) { return Failure("NetworkIsolator: Cannot include both ip_address and " "protocol in a request."); } if (ipAddress.has_ip_address()) { // Store IP to attempt to reserve. reserveArgs->add_ipv4_addrs(ipAddress.ip_address()); } else if (ipAddress.has_protocol() && ipAddress.protocol() == NetworkInfo::IPv6){ return Failure("NetworkIsolator: IPv6 is not supported at this time."); } else { // Either protocol is IPv4, or not included (in which case we default to // IPv4 anyway). numIPv4++; } } if (!(reserveArgs->ipv4_addrs_size() + numIPv4)) { return Failure( "NetworkIsolator: Container requires at least one IP address."); } // All the IP addresses, both reserved and allocated. vector<string> allAddresses; // Reserve provided IPs first. if (reserveArgs->ipv4_addrs_size()) { reserveArgs->set_hostname(slaveInfo.hostname()); reserveArgs->set_uid(uid); reserveArgs->mutable_netgroups()->CopyFrom(networkInfo.groups()); LOG(INFO) << "Sending IP reserve command to IPAM"; Try<IPAMResponse> response = runCommand<IPAMReserveIPMessage, IPAMResponse>( ipamClientPath, reserveMessage); if (response.isError()) { return Failure("Error reserving IPs with IPAM: " + response.error()); } string addresses = ""; foreach (const string& addr, reserveArgs->ipv4_addrs()) { addresses = addresses + addr + " "; allAddresses.push_back(addr); } LOG(INFO) << "IP(s) " << addresses << "reserved with IPAM"; }