// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <list>
#include <string>
#include <vector>

#include <mesos/mesos.hpp>
#include <mesos/resources.hpp>
#include <mesos/roles.hpp>
#include <mesos/type_utils.hpp>

#include <stout/check.hpp>
#include <stout/fs.hpp>
#include <stout/nothing.hpp>
#include <stout/os.hpp>
#include <stout/path.hpp>
#include <stout/strings.hpp>
#include <stout/try.hpp>
#include <stout/unreachable.hpp>

#include <glog/logging.h>

#include "common/validation.hpp"

#include "csi/paths.hpp"

#include "messages/messages.hpp"

#include "slave/paths.hpp"
#include "slave/validation.hpp"

using std::list;
using std::string;
using std::vector;

namespace mesos {
namespace internal {
namespace slave {
namespace paths {

// File names.
const char BOOT_ID_FILE[] = "boot_id";
const char SLAVE_INFO_FILE[] = "slave.info";
const char DRAIN_CONFIG_FILE[] = "drain.config";
const char FRAMEWORK_PID_FILE[] = "framework.pid";
const char FRAMEWORK_INFO_FILE[] = "framework.info";
const char LIBPROCESS_PID_FILE[] = "libprocess.pid";
const char EXECUTOR_INFO_FILE[] = "executor.info";
const char EXECUTOR_SENTINEL_FILE[] = "executor.sentinel";
const char HTTP_MARKER_FILE[] = "http.marker";
const char FORKED_PID_FILE[] = "forked.pid";
const char TASK_INFO_FILE[] = "task.info";
const char TASK_UPDATES_FILE[] = "task.updates";
const char RESOURCE_STATE_FILE[] = "resources_and_operations.state";
const char RESOURCE_STATE_TARGET_FILE[] = "resources_and_operations.target";
const char RESOURCES_INFO_FILE[] = "resources.info";
const char RESOURCES_TARGET_FILE[] = "resources.target";
const char RESOURCE_PROVIDER_STATE_FILE[] = "resource_provider.state";
const char OPERATION_UPDATES_FILE[] = "operation.updates";
const char VOLUME_GIDS_FILE[] = "volume_gids";
const char DEVICE_STATE_FILE[] = "device.state";


const char CONTAINERS_DIR[] = "containers";
const char CSI_DIR[] = "csi";
const char SLAVES_DIR[] = "slaves";
const char FRAMEWORKS_DIR[] = "frameworks";
const char EXECUTORS_DIR[] = "executors";
const char EXECUTOR_RUNS_DIR[] = "runs";
const char RESOURCE_PROVIDER_REGISTRY[] = "resource_provider_registry";
const char RESOURCE_PROVIDERS_DIR[] = "resource_providers";
const char OPERATIONS_DIR[] = "operations";


Try<ExecutorRunPath> parseExecutorRunPath(
    const string& _rootDir,
    const string& dir)
{
  // TODO(josephw): Consider using `<regex>` here, which requires GCC 4.9+.

  // Make sure there's a separator at the end of the `rootdir` so that
  // we don't accidentally slice off part of a directory.
  const string rootDir = path::join(_rootDir, "");

  if (!strings::startsWith(dir, rootDir)) {
    return Error(
        "Directory '" + dir + "' does not fall under "
        "the root directory: " + rootDir);
  }

  vector<string> tokens = strings::tokenize(
      dir.substr(rootDir.size()), stringify(os::PATH_SEPARATOR));

  // A complete executor run path consists of at least 8 tokens, which
  // includes the four named directories and the four IDs.
  if (tokens.size() < 8) {
    return Error(
        "Path after root directory is not long enough to be an "
        "executor run path: " + path::join(tokens));
  }

  // All four named directories much match.
  if (tokens[0] == SLAVES_DIR &&
      tokens[2] == FRAMEWORKS_DIR &&
      tokens[4] == EXECUTORS_DIR &&
      tokens[6] == EXECUTOR_RUNS_DIR) {
    ExecutorRunPath path;

    path.slaveId.set_value(tokens[1]);
    path.frameworkId.set_value(tokens[3]);
    path.executorId.set_value(tokens[5]);
    path.containerId.set_value(tokens[7]);

    return path;
  }

  return Error("Could not parse executor run path from directory: " + dir);
}


string getMetaRootDir(const string& rootDir)
{
  return path::join(rootDir, "meta");
}


string getSandboxRootDir(const string& rootDir)
{
  return path::join(rootDir, SLAVES_DIR);
}


string getProvisionerDir(const string& rootDir)
{
  return path::join(rootDir, "provisioner");
}


string getCsiRootDir(const string& workDir)
{
  return path::join(workDir, CSI_DIR);
}


string getBootIdPath(const string& rootDir)
{
  return path::join(rootDir, BOOT_ID_FILE);
}


string getLatestSlavePath(const string& rootDir)
{
  return path::join(rootDir, SLAVES_DIR, LATEST_SYMLINK);
}


string getSlavePath(
    const string& rootDir,
    const SlaveID& slaveId)
{
  return path::join(rootDir, SLAVES_DIR, stringify(slaveId));
}


Try<list<string>> getContainerPaths(
    const string& rootDir)
{
  return fs::list(path::join(rootDir, CONTAINERS_DIR, "*"));
}


string getContainerPath(
    const string& rootDir,
    const ContainerID& containerId)
{
  return path::join(rootDir, CONTAINERS_DIR, stringify(containerId));
}


string getSlaveInfoPath(
    const string& rootDir,
    const SlaveID& slaveId)
{
  return path::join(getSlavePath(rootDir, slaveId), SLAVE_INFO_FILE);
}


Try<list<string>> getFrameworkPaths(
    const string& rootDir,
    const SlaveID& slaveId)
{
  return fs::list(
      path::join(getSlavePath(rootDir, slaveId), FRAMEWORKS_DIR, "*"));
}


string getFrameworkPath(
    const string& rootDir,
    const SlaveID& slaveId,
    const FrameworkID& frameworkId)
{
  return path::join(
      getSlavePath(rootDir, slaveId), FRAMEWORKS_DIR, stringify(frameworkId));
}


string getFrameworkPidPath(
    const string& rootDir,
    const SlaveID& slaveId,
    const FrameworkID& frameworkId)
{
  return path::join(
      getFrameworkPath(rootDir, slaveId, frameworkId), FRAMEWORK_PID_FILE);
}


string getFrameworkInfoPath(
    const string& rootDir,
    const SlaveID& slaveId,
    const FrameworkID& frameworkId)
{
  return path::join(
      getFrameworkPath(rootDir, slaveId, frameworkId), FRAMEWORK_INFO_FILE);
}


Try<list<string>> getExecutorPaths(
    const string& rootDir,
    const SlaveID& slaveId,
    const FrameworkID& frameworkId)
{
  return fs::list(path::join(
      getFrameworkPath(rootDir, slaveId, frameworkId),
      EXECUTORS_DIR,
      "*"));
}


string getExecutorPath(
    const string& rootDir,
    const SlaveID& slaveId,
    const FrameworkID& frameworkId,
    const ExecutorID& executorId)
{
  return path::join(
        getFrameworkPath(rootDir, slaveId, frameworkId),
        EXECUTORS_DIR,
        stringify(executorId));
}


string getExecutorInfoPath(
    const string& rootDir,
    const SlaveID& slaveId,
    const FrameworkID& frameworkId,
    const ExecutorID& executorId)
{
  return path::join(
      getExecutorPath(rootDir, slaveId, frameworkId, executorId),
      EXECUTOR_INFO_FILE);
}


Try<list<string>> getExecutorRunPaths(
    const string& rootDir,
    const SlaveID& slaveId,
    const FrameworkID& frameworkId,
    const ExecutorID& executorId)
{
  return fs::list(path::join(
      getExecutorPath(rootDir, slaveId, frameworkId, executorId),
      EXECUTOR_RUNS_DIR,
      "*"));
}


string getExecutorRunPath(
    const string& rootDir,
    const SlaveID& slaveId,
    const FrameworkID& frameworkId,
    const ExecutorID& executorId,
    const ContainerID& containerId)
{
  return path::join(
      getExecutorPath(rootDir, slaveId, frameworkId, executorId),
      EXECUTOR_RUNS_DIR,
      stringify(containerId));
}


string getExecutorGeneratedForCommandTaskPath(
  const string& rootDir,
  const SlaveID& slaveId,
  const FrameworkID& frameworkId,
  const ExecutorID& executorId)
{
  constexpr char EXECUTOR_GENERATED_FOR_COMMAND_TASK_PATH[] =
    "executor_generated_for_command_task";

  return path::join(
    getExecutorPath(rootDir, slaveId, frameworkId, executorId),
    EXECUTOR_GENERATED_FOR_COMMAND_TASK_PATH);
}


string getExecutorHttpMarkerPath(
    const string& rootDir,
    const SlaveID& slaveId,
    const FrameworkID& frameworkId,
    const ExecutorID& executorId,
    const ContainerID& containerId)
{
  return path::join(
      getExecutorRunPath(
          rootDir,
          slaveId,
          frameworkId,
          executorId,
          containerId),
          HTTP_MARKER_FILE);
}


string getExecutorSentinelPath(
    const string& rootDir,
    const SlaveID& slaveId,
    const FrameworkID& frameworkId,
    const ExecutorID& executorId,
    const ContainerID& containerId)
{
  return path::join(
      getExecutorRunPath(
          rootDir,
          slaveId,
          frameworkId,
          executorId,
          containerId),
      EXECUTOR_SENTINEL_FILE);
}


string getExecutorVirtualPath(
    const FrameworkID& frameworkId,
    const ExecutorID& executorId)
{
  return path::join(
      stringify(os::PATH_SEPARATOR) + FRAMEWORKS_DIR,
      stringify(frameworkId),
      EXECUTORS_DIR,
      stringify(executorId),
      EXECUTOR_RUNS_DIR,
      LATEST_SYMLINK);
}


string getExecutorLatestRunPath(
    const string& rootDir,
    const SlaveID& slaveId,
    const FrameworkID& frameworkId,
    const ExecutorID& executorId)
{
  return path::join(
      getExecutorPath(rootDir, slaveId, frameworkId, executorId),
      EXECUTOR_RUNS_DIR,
      LATEST_SYMLINK);
}


string getLibprocessPidPath(
    const string& rootDir,
    const SlaveID& slaveId,
    const FrameworkID& frameworkId,
    const ExecutorID& executorId,
    const ContainerID& containerId)
{
  return path::join(
      getExecutorRunPath(
          rootDir,
          slaveId,
          frameworkId,
          executorId,
          containerId),
      "pids",
      LIBPROCESS_PID_FILE);
}


string getForkedPidPath(
    const string& rootDir,
    const SlaveID& slaveId,
    const FrameworkID& frameworkId,
    const ExecutorID& executorId,
    const ContainerID& containerId)
{
  return path::join(
      getExecutorRunPath(
          rootDir,
          slaveId,
          frameworkId,
          executorId,
          containerId),
      "pids",
      FORKED_PID_FILE);
}


Try<list<string>> getTaskPaths(
    const string& rootDir,
    const SlaveID& slaveId,
    const FrameworkID& frameworkId,
    const ExecutorID& executorId,
    const ContainerID& containerId)
{
  return fs::list(path::join(
      getExecutorRunPath(
          rootDir,
          slaveId,
          frameworkId,
          executorId,
          containerId),
      "tasks",
      "*"));
}


string getTaskPath(
    const string& rootDir,
    const SlaveID& slaveId,
    const FrameworkID& frameworkId,
    const ExecutorID& executorId,
    const ContainerID& containerId,
    const TaskID& taskId)
{
  return path::join(
      getExecutorRunPath(
          rootDir,
          slaveId,
          frameworkId,
          executorId,
          containerId),
      "tasks",
      stringify(taskId));
}


string getTaskInfoPath(
    const string& rootDir,
    const SlaveID& slaveId,
    const FrameworkID& frameworkId,
    const ExecutorID& executorId,
    const ContainerID& containerId,
    const TaskID& taskId)
{
  return path::join(
      getTaskPath(
          rootDir,
          slaveId,
          frameworkId,
          executorId,
          containerId,
          taskId),
      TASK_INFO_FILE);
}


string getTaskUpdatesPath(
    const string& rootDir,
    const SlaveID& slaveId,
    const FrameworkID& frameworkId,
    const ExecutorID& executorId,
    const ContainerID& containerId,
    const TaskID& taskId)
{
  return path::join(
      getTaskPath(
          rootDir,
          slaveId,
          frameworkId,
          executorId,
          containerId,
          taskId),
      TASK_UPDATES_FILE);
}


string getResourceProviderRegistryPath(
    const string& rootDir,
    const SlaveID& slaveId)
{
  return path::join(
      getSlavePath(getMetaRootDir(rootDir), slaveId),
      RESOURCE_PROVIDER_REGISTRY);
}


Try<list<string>> getResourceProviderPaths(
    const string& metaDir,
    const SlaveID& slaveId)
{
  return fs::list(path::join(
      getSlavePath(metaDir, slaveId),
      RESOURCE_PROVIDERS_DIR,
      "*", // Resource provider type.
      "*", // Resource provider name.
      "*"));
}


string getResourceProviderPath(
    const string& metaDir,
    const SlaveID& slaveId,
    const string& resourceProviderType,
    const string& resourceProviderName,
    const ResourceProviderID& resourceProviderId)
{
  return path::join(
      getSlavePath(metaDir, slaveId),
      RESOURCE_PROVIDERS_DIR,
      resourceProviderType,
      resourceProviderName,
      stringify(resourceProviderId));
}


string getResourceProviderStatePath(
    const string& metaDir,
    const SlaveID& slaveId,
    const string& resourceProviderType,
    const string& resourceProviderName,
    const ResourceProviderID& resourceProviderId)
{
  return path::join(
      getResourceProviderPath(
          metaDir,
          slaveId,
          resourceProviderType,
          resourceProviderName,
          resourceProviderId),
      RESOURCE_PROVIDER_STATE_FILE);
}


string getLatestResourceProviderPath(
    const string& metaDir,
    const SlaveID& slaveId,
    const string& resourceProviderType,
    const string& resourceProviderName)
{
  return path::join(
      getSlavePath(metaDir, slaveId),
      RESOURCE_PROVIDERS_DIR,
      resourceProviderType,
      resourceProviderName,
      LATEST_SYMLINK);
}


Try<list<string>> getOperationPaths(
    const string& rootDir)
{
  return fs::list(path::join(rootDir, OPERATIONS_DIR, "*"));
}


Try<list<string>> getSlaveOperationPaths(
    const string& metaDir,
    const SlaveID& slaveId)
{
  return getOperationPaths(getSlavePath(metaDir, slaveId));
}


string getOperationPath(
    const string& rootDir,
    const id::UUID& operationUuid)
{
  return path::join(rootDir, OPERATIONS_DIR, operationUuid.toString());
}


string getSlaveOperationPath(
    const string& metaDir,
    const SlaveID& slaveId,
    const id::UUID& operationUuid)
{
  return getOperationPath(getSlavePath(metaDir, slaveId), operationUuid);
}


Try<id::UUID> parseOperationPath(
    const string& rootDir,
    const string& dir)
{
  // TODO(chhsiao): Consider using `<regex>`, which requires GCC 4.9+.

  // Make sure there's a separator at the end of the prefix so that we
  // don't accidently slice off part of a directory.
  const string prefix = path::join(rootDir, OPERATIONS_DIR, "");

  if (!strings::startsWith(dir, prefix)) {
    return Error(
        "Directory '" + dir + "' does not fall under operations directory '" +
        prefix + "'");
  }

  Try<id::UUID> operationUuid = id::UUID::fromString(Path(dir).basename());
  if (operationUuid.isError()) {
    return Error(
        "Could not decode operation UUID from string '" +
        Path(dir).basename() + "': " + operationUuid.error());
  }

  return operationUuid.get();
}


Try<id::UUID> parseSlaveOperationPath(
    const string& metaDir,
    const SlaveID& slaveId,
    const string& dir)
{
  return parseOperationPath(getSlavePath(metaDir, slaveId), dir);
}


string getOperationUpdatesPath(
    const string& rootDir,
    const id::UUID& operationUuid)
{
  return path::join(
      getOperationPath(rootDir, operationUuid),
      OPERATION_UPDATES_FILE);
}


string getSlaveOperationUpdatesPath(
    const string& metaDir,
    const SlaveID& slaveId,
    const id::UUID& operationUuid)
{
  return getOperationUpdatesPath(getSlavePath(metaDir, slaveId), operationUuid);
}


string getResourceStatePath(const string& rootDir)
{
  return path::join(rootDir, "resources", RESOURCE_STATE_FILE);
}


string getResourceStateTargetPath(const string& rootDir)
{
  return path::join(rootDir, "resources", RESOURCE_STATE_TARGET_FILE);
}


string getResourcesInfoPath(
    const string& rootDir)
{
  return path::join(rootDir, "resources", RESOURCES_INFO_FILE);
}


string getResourcesTargetPath(
    const string& rootDir)
{
  return path::join(rootDir, "resources", RESOURCES_TARGET_FILE);
}


string getDrainConfigPath(
    const string& metaDir,
    const SlaveID& slaveId)
{
  return path::join(getSlavePath(metaDir, slaveId), DRAIN_CONFIG_FILE);
}


Try<list<string>> getPersistentVolumePaths(
    const std::string& workDir)
{
  return fs::list(path::join(workDir, "volumes", "roles", "*", "*"));
}


string getPersistentVolumePath(
    const string& workDir,
    const string& role,
    const string& persistenceId)
{
  // Role names might contain literal `/` if the role is part of a
  // role hierarchy. Since `/` is not allowed in a directory name
  // under Linux, we could either represent such sub-roles with
  // sub-directories, or encode the `/` with some other identifier.
  // To clearly distinguish artifacts in a volume from subroles we
  // choose to encode `/` in role names as ` ` (literal space) as
  // opposed to using subdirectories. Whitespace is not allowed as
  // part of a role name. Also, practically all modern filesystems can
  // use ` ` in filenames. There are some limitations in auxilary
  // tooling which are not relevant here, e.g., many shell constructs
  // require quotes around filesnames containing ` `; containers using
  // persistent volumes would not see the ` ` as the role-related part
  // of the path would not be part of a mapping into the container
  // sandbox.
  string serializableRole = strings::replace(role, "/", " ");

  return path::join(
      workDir, "volumes", "roles", serializableRole, persistenceId);
}


string getPersistentVolumePath(
    const string& workDir,
    const Resource& volume)
{
  CHECK_GT(volume.reservations_size(), 0);
  CHECK(volume.has_disk());
  CHECK(volume.disk().has_persistence());

  const string& role = Resources::reservationRole(volume);

  // Additionally check that the role and the persistent ID are valid
  // before using them to construct a directory path.
  CHECK_NONE(roles::validate(role));
  CHECK_NONE(common::validation::validateID(volume.disk().persistence().id()));


  // If no `source` is provided in `DiskInfo` volumes are mapped into
  // the `workDir`.
  if (!volume.disk().has_source()) {
    return getPersistentVolumePath(
        workDir,
        role,
        volume.disk().persistence().id());
  }

  // If a `source` was provided for the volume, we map it according
  // to the `type` of disk. Currently only the `PATH` and 'MOUNT'
  // types are supported.
  switch (volume.disk().source().type()) {
    case Resource::DiskInfo::Source::PATH: {
      // For `PATH` we mount a directory inside the `root`.
      CHECK(volume.disk().source().has_path());
      CHECK(volume.disk().source().path().has_root());
      string root = volume.disk().source().path().root();

      if (!path::is_absolute(root)) {
        // A relative path in `root` is relative to agent work dir.
        root = path::join(workDir, root);
      }

      if (volume.disk().source().has_id()) {
        // For a CSI volume the mount point is derived from `root` and `id`.
        root =
          csi::paths::getMountTargetPath(root, volume.disk().source().id());
      }

      return getPersistentVolumePath(
          root,
          role,
          volume.disk().persistence().id());
    }
    case Resource::DiskInfo::Source::MOUNT: {
      // For `MOUNT` we map straight onto the root of the mount.
      CHECK(volume.disk().source().has_mount());
      CHECK(volume.disk().source().mount().has_root());
      string root = volume.disk().source().mount().root();

      if (!path::is_absolute(root)) {
        // A relative path in `root` is relative to agent work dir.
        root = path::join(workDir, root);
      }

      if (volume.disk().source().has_id()) {
        // For a CSI volume the mount point is derived from `root` and `id`.
        root =
          csi::paths::getMountTargetPath(root, volume.disk().source().id());
      }

      return root;
    }
    case Resource::DiskInfo::Source::BLOCK:
    case Resource::DiskInfo::Source::RAW:
    case Resource::DiskInfo::Source::UNKNOWN:
      LOG(FATAL) << "Unsupported DiskInfo.Source.type";
      break;
  }

  UNREACHABLE();
}


string getVolumeGidsPath(const string& rootDir)
{
  return path::join(rootDir, "volume_gid_manager", VOLUME_GIDS_FILE);
}


string getDevicesStatePath(const string& rootDir)
{
  return path::join(rootDir, "device_manager", DEVICE_STATE_FILE);
}


Try<string> createExecutorDirectory(
    const string& rootDir,
    const SlaveID& slaveId,
    const FrameworkID& frameworkId,
    const ExecutorID& executorId,
    const ContainerID& containerId,
    const Option<string>& user)
{
  // These IDs should be valid as they are either assigned by the
  // master/agent or validated by the master but we do a sanity check
  // here before using them to create a directory.
  CHECK_NONE(common::validation::validateSlaveID(slaveId));
  CHECK_NONE(common::validation::validateFrameworkID(frameworkId));
  CHECK_NONE(common::validation::validateExecutorID(executorId));
  CHECK_NONE(slave::validation::container::validateContainerId(containerId));

  const string directory =
    getExecutorRunPath(rootDir, slaveId, frameworkId, executorId, containerId);

  if (user.isSome()) {
    LOG(INFO) << "Creating sandbox '" << directory << "'"
              << " for user '" << user.get() << "'";
  } else {
    LOG(INFO) << "Creating sandbox '" << directory << "'";
  }

  Try<Nothing> mkdir = createSandboxDirectory(directory, user);
  if (mkdir.isError()) {
    return Error(
        "Failed to create executor directory '" + directory + "': " +
        mkdir.error());
  }

  // Remove the previous "latest" symlink.
  const string latest =
    getExecutorLatestRunPath(rootDir, slaveId, frameworkId, executorId);

  if (os::exists(latest)) {
    CHECK_SOME(os::rm(latest))
      << "Failed to remove latest symlink '" << latest << "'";
  }

  // Symlink the new executor directory to "latest".
  Try<Nothing> symlink = ::fs::symlink(directory, latest);
  if (symlink.isError()) {
    return Error(
        "Failed to symlink '" + directory + "' to '" + latest + "': " +
        symlink.error());
  }

  return directory;
}


// Given a directory path and an optional user, create a directory
// suitable for use as a task sandbox. A task sandbox must be owned
// by the task user (if present) and have restricted permissions.
Try<Nothing> createSandboxDirectory(
    const string& directory,
    const Option<string>& user)
{
  Try<Nothing> mkdir = os::mkdir(directory);
  if (mkdir.isError()) {
    return Error("Failed to create directory: " + mkdir.error());
  }

#ifndef __WINDOWS__
  // Since this is a sandbox directory containing private task data,
  // we want to ensure that it is not accessible to "others".
  Try<Nothing> chmod = os::chmod(directory, 0750);
  if (chmod.isError()) {
    return Error("Failed to chmod directory: " + chmod.error());
  }

  if (user.isSome()) {
    Try<Nothing> chown = os::chown(user.get(), directory);
    if (chown.isError()) {
      // Attempt to clean up, but since we've already failed to chown,
      // we don't check the return value here.
      os::rmdir(directory);

      return Error(
          "Failed to chown directory to '" +
          user.get() + "': " + chown.error());
    }
  }
#endif // __WINDOWS__

  return Nothing();
}


string createSlaveDirectory(
    const string& rootDir,
    const SlaveID& slaveId)
{
  // `slaveId` should be valid because it's assigned by the master but
  // we do a sanity check here before using it to create a directory.
  CHECK_NONE(common::validation::validateSlaveID(slaveId));

  const string directory = getSlavePath(rootDir, slaveId);

  Try<Nothing> mkdir = os::mkdir(directory);

  CHECK_SOME(mkdir)
    << "Failed to create agent directory '" << directory << "'";

  // Remove the previous "latest" symlink.
  const string latest = getLatestSlavePath(rootDir);

  if (os::exists(latest)) {
    CHECK_SOME(os::rm(latest))
      << "Failed to remove latest symlink '" << latest << "'";
  }

  // Symlink the new slave directory to "latest".
  Try<Nothing> symlink = ::fs::symlink(directory, latest);

  CHECK_SOME(symlink)
    << "Failed to symlink directory '" << directory
    << "' to '" << latest << "'";

  return directory;
}


string createResourceProviderDirectory(
    const string& rootDir,
    const SlaveID& slaveId,
    const string& resourceProviderType,
    const string& resourceProviderName,
    const ResourceProviderID& resourceProviderId)
{
  const string directory = getResourceProviderPath(
      rootDir,
      slaveId,
      resourceProviderType,
      resourceProviderName,
      resourceProviderId);

  Try<Nothing> mkdir = os::mkdir(directory);

  CHECK_SOME(mkdir)
    << "Failed to create resource provider directory '" << directory << "'";

  // Remove the previous "latest" symlink.
  const string latest = getLatestResourceProviderPath(
      rootDir,
      slaveId,
      resourceProviderType,
      resourceProviderName);

  if (os::exists(latest)) {
    CHECK_SOME(os::rm(latest))
      << "Failed to remove latest symlink '" << latest << "'";
  }

  // Symlink the new resource provider directory to "latest".
  Try<Nothing> symlink = ::fs::symlink(directory, latest);

  CHECK_SOME(symlink)
    << "Failed to symlink directory '" << directory
    << "' to '" << latest << "'";

  return directory;
}

} // namespace paths {
} // namespace slave {
} // namespace internal {
} // namespace mesos {
