Esempio n. 1
0
Future<Option<ContainerLaunchInfo>> CgroupsNetClsIsolatorProcess::prepare(
    const ContainerID& containerId,
    const ContainerConfig& containerConfig)
{
  if (infos.contains(containerId)) {
    return Failure("Container has already been prepared");
  }

  // Use this info to create the cgroup, but do not insert it into
  // infos till the cgroup has been created successfully.
  Info info(path::join(flags.cgroups_root, containerId.value()));

  // Create a cgroup for this container.
  Try<bool> exists = cgroups::exists(hierarchy, info.cgroup);
  if (exists.isError()) {
    return Failure("Failed to check if the cgroup already exists: " +
                   exists.error());
  } else if (exists.get()) {
    return Failure("The cgroup already exists");
  }

  Try<Nothing> create = cgroups::create(hierarchy, info.cgroup);
  if (create.isError()) {
    return Failure("Failed to create the cgroup: " + create.error());
  }

  // 'chown' the cgroup so the executor can create nested cgroups. Do
  // not recurse so the control files are still owned by the slave
  // user and thus cannot be changed by the executor.
  if (containerConfig.has_user()) {
    Try<Nothing> chown = os::chown(
        containerConfig.user(),
        path::join(hierarchy, info.cgroup),
        false);

    if (chown.isError()) {
      return Failure("Failed to change ownership of cgroup hierarchy: " +
                     chown.error());
    }
  }

  infos.emplace(containerId, info);

  return update(containerId, containerConfig.executorinfo().resources())
    .then([]() -> Future<Option<ContainerLaunchInfo>> {
      return None();
    });
}
Esempio n. 2
0
Future<Option<ContainerLaunchInfo>> LinuxFilesystemIsolatorProcess::prepare(
    const ContainerID& containerId,
    const ContainerConfig& containerConfig)
{
  const string& directory = containerConfig.directory();

  Option<string> user;
  if (containerConfig.has_user()) {
    user = containerConfig.user();
  }

  if (infos.contains(containerId)) {
    return Failure("Container has already been prepared");
  }

  Owned<Info> info(new Info(
      directory,
      containerConfig.executor_info()));

  infos.put(containerId, info);

  ContainerLaunchInfo launchInfo;
  launchInfo.set_namespaces(CLONE_NEWNS);

  // Prepare the commands that will be run in the container's mount
  // namespace right after forking the executor process. We use these
  // commands to mount those volumes specified in the container info
  // so that they don't pollute the host mount namespace.
  Try<string> _script = script(containerId, containerConfig);
  if (_script.isError()) {
    return Failure("Failed to generate isolation script: " + _script.error());
  }

  CommandInfo* command = launchInfo.add_commands();
  command->set_value(_script.get());

  return update(containerId, containerConfig.executor_info().resources())
    .then([launchInfo]() -> Future<Option<ContainerLaunchInfo>> {
      return launchInfo;
    });
}