示例#1
0
	TaskInfo buildTask (string hostname, string id, const SlaveID& slave)  {
		hostProfile profile = hostList[hostname];
	// Define the Docker container.
		/*  Since there is no "executor" to manage the tasks, the
			container will be built and attached directly into the task below */
		ContainerInfo container;
		container.set_type(container.DOCKER);
		ContainerInfo::DockerInfo docker;
		docker.set_image(DOCKER_IMAGE);
		container.mutable_docker()->MergeFrom(docker);

		// Mount local volume inside Container
		Volume * volume = container.add_volumes();
		volume->set_container_path("/mnt");
		volume->set_host_path("/local/mesos");
		volume->set_mode(Volume_Mode_RW);

		// Define the task
		TaskInfo task;
		task.set_name("K3-" + k3binary);
		task.mutable_task_id()->set_value(id);
		task.mutable_slave_id()->MergeFrom(slave);
		task.mutable_container()->MergeFrom(container);
		//task.set_data(stringify(localTasks));

		// Define include files for the command
		CommandInfo command;

		CommandInfo_URI * k3_bin = command.add_uris();
		k3_bin->set_value(fileServer + "/" + k3binary);
		k3_bin->set_executable(true);
		k3_bin->set_extract(false);

//		CommandInfo_URI * k3_args = command.add_uris();
//		k3_args->set_value(runpath + "/k3input.yaml");
		
//		command.set_value("$MESOS_SANDBOX/" + k3binary + " -l INFO -p " +
//				"$MESOS_SANDBOX/k3input.yaml");
		task.mutable_command()->MergeFrom(command);

		// Option A for doing resources management (see scheduler for option B)
		Resource* resource;

		resource = task.add_resources();
		resource->set_name("cpus");
		resource->set_type(Value::SCALAR);
		resource->mutable_scalar()->set_value(profile.cpu);

		resource = task.add_resources();
		resource->set_name("mem");
		resource->set_type(Value::SCALAR);
		resource->mutable_scalar()->set_value(profile.mem);
		
		return task;
	}
示例#2
0
// This test verifies mounting in an absolute path when running a
// docker container works.
TEST_F(DockerTest, ROOT_DOCKER_MountAbsolute)
{
  Owned<Docker> docker = Docker::create(
      tests::flags.docker,
      tests::flags.docker_socket,
      false).get();

  ContainerInfo containerInfo;
  containerInfo.set_type(ContainerInfo::DOCKER);

  Try<string> directory = environment->mkdtemp();
  CHECK_SOME(directory) << "Failed to create temporary directory";

  const string testFile = path::join(directory.get(), "test_file");
  EXPECT_SOME(os::write(testFile, "data"));

  Volume* volume = containerInfo.add_volumes();
  volume->set_host_path(testFile);
  volume->set_container_path("/tmp/test_file");
  volume->set_mode(Volume::RO);

  ContainerInfo::DockerInfo dockerInfo;
  dockerInfo.set_image("busybox");

  containerInfo.mutable_docker()->CopyFrom(dockerInfo);

  CommandInfo commandInfo;
  commandInfo.set_shell(true);
  commandInfo.set_value("ls /tmp/test_file");

  Future<Nothing> run = docker->run(
      containerInfo,
      commandInfo,
      NAME_PREFIX + "-mount-absolute-test",
      directory.get(),
      directory.get());

  AWAIT_READY(run);
}
示例#3
0
TEST_F(SharedFilesystemIsolatorTest, ROOT_AbsoluteVolume)
{
    slave::Flags flags = CreateSlaveFlags();
    flags.isolation = "filesystem/shared";

    Try<Isolator*> isolator = SharedFilesystemIsolatorProcess::create(flags);
    CHECK_SOME(isolator);

    Try<Launcher*> launcher = LinuxLauncher::create(flags);
    CHECK_SOME(launcher);

    // We'll mount the absolute test work directory as /var/tmp in the
    // container.
    const string hostPath = flags.work_dir;
    const string containerPath = "/var/tmp";

    ContainerInfo containerInfo;
    containerInfo.set_type(ContainerInfo::MESOS);
    containerInfo.add_volumes()->CopyFrom(
        CREATE_VOLUME(containerPath, hostPath, Volume::RW));

    ExecutorInfo executorInfo;
    executorInfo.mutable_container()->CopyFrom(containerInfo);

    ContainerID containerId;
    containerId.set_value(UUID::random().toString());

    Future<Option<CommandInfo> > prepare =
        isolator.get()->prepare(containerId, executorInfo, flags.work_dir, None());
    AWAIT_READY(prepare);
    ASSERT_SOME(prepare.get());

    // Test the volume mounting by touching a file in the container's
    // /tmp, which should then be in flags.work_dir.
    const string filename = UUID::random().toString();
    ASSERT_FALSE(os::exists(path::join(containerPath, filename)));

    vector<string> args;
    args.push_back("/bin/sh");
    args.push_back("-x");
    args.push_back("-c");
    args.push_back(prepare.get().get().value() +
                   " && touch " +
                   path::join(containerPath, filename));

    Try<pid_t> pid = launcher.get()->fork(
                         containerId,
                         "/bin/sh",
                         args,
                         Subprocess::FD(STDIN_FILENO),
                         Subprocess::FD(STDOUT_FILENO),
                         Subprocess::FD(STDERR_FILENO),
                         None(),
                         None(),
                         None());
    ASSERT_SOME(pid);

    // Set up the reaper to wait on the forked child.
    Future<Option<int> > status = process::reap(pid.get());

    AWAIT_READY(status);
    EXPECT_SOME_EQ(0, status.get());

    // Check the file was created in flags.work_dir.
    EXPECT_TRUE(os::exists(path::join(hostPath, filename)));

    // Check it didn't get created in the host's view of containerPath.
    EXPECT_FALSE(os::exists(path::join(containerPath, filename)));

    delete launcher.get();
    delete isolator.get();
}
示例#4
0
// Test that a container can create a private view of a system
// directory (/var/tmp). Check that a file written by a process inside
// the container doesn't appear on the host filesystem but does appear
// under the container's work directory.
TEST_F(SharedFilesystemIsolatorTest, ROOT_RelativeVolume)
{
    slave::Flags flags = CreateSlaveFlags();
    flags.isolation = "filesystem/shared";

    Try<Isolator*> isolator = SharedFilesystemIsolatorProcess::create(flags);
    CHECK_SOME(isolator);

    Try<Launcher*> launcher = LinuxLauncher::create(flags);
    CHECK_SOME(launcher);

    // Use /var/tmp so we don't mask the work directory (under /tmp).
    const string containerPath = "/var/tmp";
    ASSERT_TRUE(os::isdir(containerPath));

    // Use a host path relative to the container work directory.
    const string hostPath = strings::remove(containerPath, "/", strings::PREFIX);

    ContainerInfo containerInfo;
    containerInfo.set_type(ContainerInfo::MESOS);
    containerInfo.add_volumes()->CopyFrom(
        CREATE_VOLUME(containerPath, hostPath, Volume::RW));

    ExecutorInfo executorInfo;
    executorInfo.mutable_container()->CopyFrom(containerInfo);

    ContainerID containerId;
    containerId.set_value(UUID::random().toString());

    Future<Option<CommandInfo> > prepare =
        isolator.get()->prepare(containerId, executorInfo, flags.work_dir, None());
    AWAIT_READY(prepare);
    ASSERT_SOME(prepare.get());

    // The test will touch a file in container path.
    const string file = path::join(containerPath, UUID::random().toString());
    ASSERT_FALSE(os::exists(file));

    // Manually run the isolator's preparation command first, then touch
    // the file.
    vector<string> args;
    args.push_back("/bin/sh");
    args.push_back("-x");
    args.push_back("-c");
    args.push_back(prepare.get().get().value() + " && touch " + file);

    Try<pid_t> pid = launcher.get()->fork(
                         containerId,
                         "/bin/sh",
                         args,
                         Subprocess::FD(STDIN_FILENO),
                         Subprocess::FD(STDOUT_FILENO),
                         Subprocess::FD(STDERR_FILENO),
                         None(),
                         None(),
                         None());
    ASSERT_SOME(pid);

    // Set up the reaper to wait on the forked child.
    Future<Option<int> > status = process::reap(pid.get());

    AWAIT_READY(status);
    EXPECT_SOME_EQ(0, status.get());

    // Check the correct hierarchy was created under the container work
    // directory.
    string dir = "/";
    foreach (const string& subdir, strings::tokenize(containerPath, "/")) {
        dir = path::join(dir, subdir);

        struct stat hostStat;
        EXPECT_EQ(0, ::stat(dir.c_str(), &hostStat));

        struct stat containerStat;
        EXPECT_EQ(0,
                  ::stat(path::join(flags.work_dir, dir).c_str(), &containerStat));

        EXPECT_EQ(hostStat.st_mode, containerStat.st_mode);
        EXPECT_EQ(hostStat.st_uid, containerStat.st_uid);
        EXPECT_EQ(hostStat.st_gid, containerStat.st_gid);
    }

    // Check it did *not* create a file in the host namespace.
    EXPECT_FALSE(os::exists(file));

    // Check it did create the file under the container's work directory
    // on the host.
    EXPECT_TRUE(os::exists(path::join(flags.work_dir, file)));

    delete launcher.get();
    delete isolator.get();
}
// This test verifies that sandbox path volume allows two containers
// nested under the same parent container to share data.
// TODO(jieyu): Parameterize this test to test both linux and posix
// launcher and filesystem isolator.
TEST_F(VolumeSandboxPathIsolatorTest, SharedVolume)
{
  slave::Flags flags = CreateSlaveFlags();
  flags.isolation = "volume/sandbox_path";

  Fetcher fetcher;

  Try<MesosContainerizer*> create = MesosContainerizer::create(
      flags,
      true,
      &fetcher);

  ASSERT_SOME(create);

  Owned<MesosContainerizer> containerizer(create.get());

  SlaveState state;
  state.id = SlaveID();

  AWAIT_READY(containerizer->recover(state));

  ContainerID containerId;
  containerId.set_value(UUID::random().toString());

  ExecutorInfo executor = createExecutorInfo("executor", "sleep 99", "cpus:1");

  Try<string> directory = environment->mkdtemp();
  ASSERT_SOME(directory);

  Future<bool> launch = containerizer->launch(
      containerId,
      None(),
      executor,
      directory.get(),
      None(),
      state.id,
      map<string, string>(),
      true); // TODO(benh): Ever want to check not-checkpointing?

  AWAIT_ASSERT_TRUE(launch);

  ContainerID nestedContainerId1;
  nestedContainerId1.mutable_parent()->CopyFrom(containerId);
  nestedContainerId1.set_value(UUID::random().toString());

  ContainerInfo containerInfo;
  containerInfo.set_type(ContainerInfo::MESOS);

  Volume* volume = containerInfo.add_volumes();
  volume->set_mode(Volume::RW);
  volume->set_container_path("parent");

  Volume::Source* source = volume->mutable_source();
  source->set_type(Volume::Source::SANDBOX_PATH);

  Volume::Source::SandboxPath* sandboxPath = source->mutable_sandbox_path();
  sandboxPath->set_type(Volume::Source::SandboxPath::PARENT);
  sandboxPath->set_path("shared");

  launch = containerizer->launch(
      nestedContainerId1,
      createCommandInfo("touch parent/file; sleep 1000"),
      containerInfo,
      None(),
      state.id);

  AWAIT_ASSERT_TRUE(launch);

  ContainerID nestedContainerId2;
  nestedContainerId2.mutable_parent()->CopyFrom(containerId);
  nestedContainerId2.set_value(UUID::random().toString());

  launch = containerizer->launch(
      nestedContainerId2,
      createCommandInfo(
        "while true; do if [ -f parent/file ]; then exit 0; fi; done"),
      containerInfo,
      None(),
      state.id);

  AWAIT_ASSERT_TRUE(launch);

  Future<Option<ContainerTermination>> wait =
    containerizer->wait(nestedContainerId2);

  AWAIT_READY(wait);
  ASSERT_SOME(wait.get());
  ASSERT_TRUE(wait.get()->has_status());
  EXPECT_WEXITSTATUS_EQ(0, wait.get()->status());

  wait = containerizer->wait(containerId);

  containerizer->destroy(containerId);

  AWAIT_READY(wait);
  ASSERT_SOME(wait.get());
  ASSERT_TRUE(wait.get()->has_status());
  EXPECT_WTERMSIG_EQ(SIGKILL, wait.get()->status());
}