You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by dr...@apache.org on 2018/09/26 18:55:43 UTC

[trafficserver] branch master updated: Rewrite traffic_layout with ArgParser

This is an automated email from the ASF dual-hosted git repository.

dragon pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new 7dc16b1  Rewrite traffic_layout with ArgParser
7dc16b1 is described below

commit 7dc16b13bdb368f051dc604a6c81164ccb01bc7f
Author: Xavier Chi <ch...@gmail.com>
AuthorDate: Tue Sep 25 17:21:08 2018 -0500

    Rewrite traffic_layout with ArgParser
---
 doc/admin-guide/files/storage.config.en.rst       |   2 +-
 doc/appendices/command-line/traffic_layout.en.rst |   5 +-
 include/tscore/runroot.h                          |  10 +-
 src/traffic_layout/engine.cc                      | 480 ++++++++--------------
 src/traffic_layout/engine.h                       |  65 +--
 src/traffic_layout/file_system.cc                 |  31 +-
 src/traffic_layout/file_system.h                  |   7 -
 src/traffic_layout/info.cc                        |   2 -
 src/traffic_layout/info.h                         |   2 +-
 src/traffic_layout/traffic_layout.cc              | 171 ++------
 src/tscore/runroot.cc                             |  92 +++--
 tests/gold_tests/runroot/runroot_error.test.py    |  13 +-
 tests/gold_tests/runroot/runroot_init.test.py     |  10 +-
 tests/gold_tests/runroot/runroot_manager.test.py  |   6 +-
 tests/gold_tests/runroot/runroot_remove.test.py   |  12 +-
 tests/gold_tests/runroot/runroot_use.test.py      |   4 +-
 tests/gold_tests/runroot/runroot_verify.test.py   |   2 +-
 17 files changed, 310 insertions(+), 604 deletions(-)

diff --git a/doc/admin-guide/files/storage.config.en.rst b/doc/admin-guide/files/storage.config.en.rst
index aa41736..943dc94 100644
--- a/doc/admin-guide/files/storage.config.en.rst
+++ b/doc/admin-guide/files/storage.config.en.rst
@@ -189,5 +189,5 @@ Advanced
 --------
 
 Because relative paths in :file:`storage.config` are relative to the base prefix, when using customized runroot
-it may be necessary to adjust such paths in :file:`storage.config` or adjust ``runroot_path.yml`` itself.
+it may be necessary to adjust such paths in :file:`storage.config` or adjust ``runroot.yaml`` itself.
 Despite the name, the cachedir value is not used for this file.
diff --git a/doc/appendices/command-line/traffic_layout.en.rst b/doc/appendices/command-line/traffic_layout.en.rst
index 8e54d93..99c480e 100644
--- a/doc/appendices/command-line/traffic_layout.en.rst
+++ b/doc/appendices/command-line/traffic_layout.en.rst
@@ -57,7 +57,7 @@ If the path is not specified, the current working directory will be used.
 To run traffic_manager, for example, using the runroot, there are several ways:
     #. ``/path/to/runroot/bin/traffic_manager``
     #. ``traffic_manager --run-root=/path/to/runroot``
-    #. ``traffic_manager --run-root=/path/to/runroot/runroot_path.yml``
+    #. ``traffic_manager --run-root=/path/to/runroot/runroot.yaml``
     #. Set :envvar:`TS_RUNROOT` to ``/path/to/runroot`` and run ``traffic_manager``
     #. Run ``traffic_manager`` with ``/path/to/runroot`` as current working directory
 
@@ -72,7 +72,7 @@ Subcommands
 init
 ----
 Use the current working directory or the specific path to create runroot. 
-The path can be absolute, relative or set up in :envvar:`TS_RUNROOT`.
+The path can be absolute or relative.
 
 workflow: 
     #. Create a sandbox directory for programs to run under.
@@ -111,7 +111,6 @@ remove
 ------
 Find the sandbox to remove in following order:
     #. specified in --path as absolute or relative.
-    #. ENV variable: :envvar:`TS_RUNROOT`.
     #. current working directory.
     #. installed directory.
 
diff --git a/include/tscore/runroot.h b/include/tscore/runroot.h
index 2d3459e..1dd391e 100644
--- a/include/tscore/runroot.h
+++ b/include/tscore/runroot.h
@@ -21,8 +21,9 @@
   limitations under the License.
 */
 
-// runroot handler for TS_RUNROOT
-// detailed information in runroot.cc
+/*
+  Please refer to traffic_layout document for the runroot usage
+*/
 
 #pragma once
 
@@ -48,6 +49,11 @@ const std::string LAYOUT_CACHEDIR      = "cachedir";
 
 typedef std::unordered_map<std::string, std::string> RunrootMapType;
 
+// some checks for directory exist or is it a directory
+// this is a temporary approach and will be replaced
+bool exists(const std::string &dir);
+bool is_directory(const std::string &directory);
+
 void runroot_handler(const char **argv, bool json = false);
 
 // get a map from default layout
diff --git a/src/traffic_layout/engine.cc b/src/traffic_layout/engine.cc
index c7e21ca..d9511da 100644
--- a/src/traffic_layout/engine.cc
+++ b/src/traffic_layout/engine.cc
@@ -27,20 +27,13 @@
 #include "tscore/runroot.h"
 #include "tscore/I_Layout.h"
 #include "tscore/ink_error.h"
-#include "tscore/ink_args.h"
-#include "tscore/I_Version.h"
-#include "records/I_RecCore.h"
-#include "tscore/ink_config.h"
-
 #include "engine.h"
 #include "file_system.h"
-#include "tscore/runroot.h"
+#include "info.h"
 
-#include <cctype>
 #include <fstream>
 #include <iostream>
 #include <ftw.h>
-#include <pwd.h>
 #include <yaml-cpp/yaml.h>
 
 // for nftw check_directory
@@ -51,10 +44,8 @@ std::string directory_check;
 std::string
 check_path(const std::string &path)
 {
-  std::ifstream check_file;
-  std::string yaml_file = Layout::relative_to(path, "runroot_path.yml");
-  check_file.open(yaml_file);
-  if (!check_file.good()) {
+  std::string yaml_file = Layout::relative_to(path, "runroot.yaml");
+  if (!exists(yaml_file)) {
     ink_warning("Unable to access runroot: '%s' - %s", yaml_file.c_str(), strerror(errno));
     return {};
   }
@@ -75,9 +66,7 @@ check_parent_path(const std::string &path)
     if (yaml_path.empty()) {
       return {};
     }
-    std::ifstream check_file;
-    check_file.open(Layout::relative_to(yaml_path, "runroot_path.yml"));
-    if (check_file.good()) {
+    if (exists(Layout::relative_to(yaml_path, "runroot.yaml"))) {
       return yaml_path;
     }
     yaml_path = yaml_path.substr(0, yaml_path.find_last_of("/"));
@@ -94,13 +83,13 @@ check_run_path(const std::string &arg, const bool forceflag)
     return false;
   }
   // the condition of force create
-  if (exists(arg) && is_directory(arg) && forceflag) {
+  if (is_directory(arg) && forceflag) {
     std::cout << "Forcing creating runroot ..." << std::endl;
     return true;
   }
 
   // if directory already exist
-  if (exists(arg) && is_directory(arg)) {
+  if (is_directory(arg)) {
     return true;
   } else {
     // try to create & remove
@@ -147,22 +136,13 @@ path_handler(const std::string &path, bool run_flag, const std::string &command)
     }
   }
 
-  // 2. check Environment variable
-  char *env_val = getenv("TS_RUNROOT");
-  if (env_val != nullptr) {
-    std::string envpath = check_path(env_val);
-    if (!envpath.empty()) {
-      return envpath;
-    }
-  }
-
-  // 3. find cwd or parent path of cwd to check
+  // 2. find cwd or parent path of cwd to check
   std::string cwdpath = check_parent_path(cwd);
   if (!cwdpath.empty()) {
     return cwdpath;
   }
 
-  // 4. installed executable
+  // 3. installed executable
   char RealBinPath[PATH_MAX] = {0};
   if (!command.empty() && realpath(command.c_str(), RealBinPath) != nullptr) {
     std::string bindir = RealBinPath;
@@ -176,247 +156,13 @@ path_handler(const std::string &path, bool run_flag, const std::string &command)
   return path;
 }
 
-// the help message for traffic_layout runroot
-void
-RunrootEngine::runroot_help_message(const bool runflag, const bool cleanflag, const bool verifyflag)
-{
-  if (runflag) {
-    std::cout << "\ninit Usage: traffic_layout init ([switch]) (--path /path/to/sandbox)\n" << std::endl;
-    std::cout << "Sub-switches:\n"
-                 "--path    Specify the path of the runroot to create (the path should be the next argument)\n"
-                 "--force   Force to create ts_runroot even directory already exists\n"
-                 "--absolute    Produce absolute path in the yaml file\n"
-                 "--run-root(=/path)  Using specified TS_RUNROOT as sandbox\n"
-                 "--copy-style=[STYLE] Specify style (FULL, HARD, SOFT) when copying executable\n"
-                 "--layout=[/path] Use specific layout (providing yaml file) to create runroot\n"
-              << std::endl;
-  }
-  if (cleanflag) {
-    std::cout << "\nremove Usage: traffic_layout remove ([switch]) (--path /path/to/sandbox)\n" << std::endl;
-    std::cout << "Sub-switches:\n"
-                 "--path   Specify the path of the runroot to remove (the path should be the next argument)\n"
-                 "--force  Force to remove ts_runroot even with other unknown files\n"
-              << std::endl;
-  }
-  if (verifyflag) {
-    std::cout << "\nverify Usage: traffic_layout verify (--fix) (--path /path/to/sandbox)\n" << std::endl;
-    std::cout << "Sub-switches:\n"
-                 "--path   Specify the path of the runroot to verify (the path should be the next argument)\n"
-                 "--fix    Fix the premission issues that verify found"
-              << std::endl;
-  }
-  return;
-}
-
-// the parsing function for traffic runroot program
-// set the flag & path appropriately
-bool
-RunrootEngine::runroot_parse()
-{
-  for (unsigned int i = 1; i < _argv.size(); ++i) {
-    std::string argument = _argv[i];
-    // set the help, version, force and absolute flags
-    if (argument == "-h" || argument == "--help") {
-      help_flag = true;
-      continue;
-    }
-    if (argument == "-V" || argument == "--version") {
-      version_flag = true;
-      continue;
-    }
-    if (argument == "--force") {
-      force_flag = true;
-      continue;
-    }
-    if (argument == "--absolute") {
-      abs_flag = true;
-      continue;
-    }
-    if (argument.substr(0, RUNROOT_WORD.size()) == RUNROOT_WORD) {
-      continue;
-    }
-    // set init flag
-    if (argument == "init") {
-      run_flag = true;
-      command_num++;
-      continue;
-    }
-    // set remove flag
-    if (argument == "remove") {
-      clean_flag = true;
-      command_num++;
-      continue;
-    }
-    // set verify flag
-    if (argument == "verify") {
-      verify_flag = true;
-      command_num++;
-      continue;
-    }
-    // set fix flag
-    if (argument == "--fix") {
-      fix_flag = true;
-      continue;
-    }
-    if (argument.substr(0, COPYSTYLE_WORD.size()) == COPYSTYLE_WORD) {
-      std::string style = argument.substr(COPYSTYLE_WORD.size() + 1);
-      transform(style.begin(), style.end(), style.begin(), ::tolower);
-      if (style == "full") {
-        copy_style = FULL;
-      } else if (style == "soft") {
-        copy_style = SOFT;
-      } else {
-        copy_style = HARD;
-      }
-      continue;
-    }
-    if (argument.substr(0, LAYOUT_WORD.size()) == LAYOUT_WORD) {
-      if (argument.size() <= LAYOUT_WORD.size() + 1) {
-        layout_file = "";
-      } else {
-        layout_file = argument.substr(LAYOUT_WORD.size() + 1);
-      }
-      continue;
-    }
-    if (argument == "--path") {
-      if (i + 1 >= _argv.size() || _argv[i + 1][0] == '-') {
-        // invalid path
-        return false;
-      }
-      path = _argv[i + 1];
-      ++i;
-      continue;
-    }
-    return false;
-  }
-  return true;
-}
-
-// check the logic and see if everthing is fine
-void
-RunrootEngine::sanity_check()
-{
-  // check output help or not
-  if (help_flag) {
-    runroot_help_message(run_flag, clean_flag, verify_flag);
-    exit(0);
-  }
-  if (version_flag) {
-    // get version info
-    AppVersionInfo appVersionInfo;
-    appVersionInfo.setup(PACKAGE_NAME, "traffic_layout", PACKAGE_VERSION, __DATE__, __TIME__, BUILD_MACHINE, BUILD_PERSON, "");
-    ink_fputln(stdout, appVersionInfo.FullVersionInfoStr);
-    exit(0);
-  }
-  if (command_num > 1) {
-    ink_fatal("Cannot run multiple command at the same time");
-  }
-  if (command_num < 1) {
-    ink_fatal("No command specified");
-  }
-  if ((force_flag && !run_flag) && (force_flag && !clean_flag)) {
-    ink_fatal("Nothing to force");
-  }
-
-  path = path_handler(path, run_flag, _argv[0]);
-
-  if (path.empty()) {
-    if (!verify_flag) {
-      ink_fatal("Path not valid (runroot_path.yml not found)");
-    } else {
-      verify_default = true;
-    }
-  }
-
-  if (run_flag) {
-    if (!check_run_path(path, force_flag)) {
-      ink_fatal("Failed to create runroot with path '%s'", path.c_str());
-    }
-  }
-}
-
-// check if user want to force remove the ts_runroot
-// return true if user replies Y
-static bool
-check_remove_force()
-{
-  // check for Y/N 3 times
-  for (int i = 0; i < 3; i++) {
-    std::cout << "Are you sure to force removing runroot? (irreversible) Y/N: ";
-    std::string input;
-    std::cin >> input;
-    if (input == "Y" || input == "y")
-      return true;
-    if (input == "N" || input == "n")
-      return false;
-  }
-  ink_error("Invalid input Y/N");
-  exit(70);
-}
-
-// the function for removing the runroot
-void
-RunrootEngine::clean_runroot()
-{
-  std::string clean_root = path;
-  append_slash(clean_root);
-
-  char cwd[PATH_MAX];
-  if (getcwd(cwd, sizeof(cwd)) == nullptr) {
-    ink_fatal("unexcepted failure from getcwd() code=%d", errno);
-  }
-  std::string cur_working_dir = cwd;
-
-  if (force_flag) {
-    // the force clean
-    if (!check_remove_force()) {
-      exit(0);
-    }
-    std::cout << "Forcing removing runroot ..." << std::endl;
-
-    if (!remove_directory(clean_root)) {
-      ink_warning("Failed force removing runroot '%s' - %s", clean_root.c_str(), strerror(errno));
-    }
-  } else {
-    // handle the map and deleting of each directories specified in the yml file
-    RunrootMapType map = runroot_map(Layout::relative_to(clean_root, "runroot_path.yml"));
-    map.erase(LAYOUT_PREFIX);
-    map.erase(LAYOUT_EXEC_PREFIX);
-    for (auto it : map) {
-      std::string dir = it.second;
-      append_slash(dir);
-      std::string later_dir = dir.substr(clean_root.size());
-      dir                   = Layout::relative_to(clean_root, later_dir.substr(0, later_dir.find_first_of("/")));
-      if (cur_working_dir != dir) {
-        remove_directory(dir);
-      } else {
-        // if we are at this directory, remove files inside
-        remove_inside_directory(dir);
-      }
-    }
-    // remove yaml file
-    std::string yaml_file = Layout::relative_to(clean_root, "runroot_path.yml");
-    if (remove(yaml_file.c_str()) != 0) {
-      ink_notice("unable to delete runroot_path.yml - %s", strerror(errno));
-    }
-
-    append_slash(cur_working_dir);
-    if (cur_working_dir.find(clean_root) != 0) {
-      // if cwd is not runroot and runroot is empty, remove it
-      if (remove(clean_root.c_str()) != 0) {
-        ink_notice("unable to delete %s - %s", clean_root.c_str(), strerror(errno));
-      }
-    }
-  }
-}
-
 // if directory is not empty, ask input from user Y/N
 static int
 check_directory(const char *path, const struct stat *s, int flag, struct FTW *f)
 {
   std::string checkpath = path;
   if (checkpath != directory_check) {
-    // check for Y/N 3 times
+    // check for valid Y/N
     for (int i = 0; i < 3; i++) {
       std::cout << "Are you sure to create runroot inside a non-empty directory Y/N: ";
       std::string input;
@@ -435,18 +181,48 @@ check_directory(const char *path, const struct stat *s, int flag, struct FTW *f)
   return 0;
 }
 
-// the function for creating the runroot
 void
-RunrootEngine::create_runroot()
+LayoutEngine::info()
 {
-  std::string original_root = Layout::get()->prefix;
-  std::string ts_runroot    = path;
+  bool json = arguments.get("json");
 
-  std::ifstream check_file(Layout::relative_to(ts_runroot, "runroot_path.yml"));
-  std::cout << "creating runroot - " + ts_runroot << std::endl;
+  if (arguments.get("features")) {
+    produce_features(json);
+  } else {
+    produce_layout(json);
+  }
+}
 
+void
+LayoutEngine::create_runroot()
+{
+  // set up options
+  std::string path = path_handler(arguments.get("path").value(), true, _argv[0]);
+  bool force_flag  = arguments.get("force");
+  bool abs_flag    = arguments.get("absolute");
+  // deal with the copy style
+  CopyStyle copy_style;
+  std::string style = arguments.get("copy-style").value();
+  if (!style.empty()) {
+    transform(style.begin(), style.end(), style.begin(), ::tolower);
+    if (style == "full") {
+      copy_style = FULL;
+    } else if (style == "soft") {
+      copy_style = SOFT;
+    } else {
+      copy_style = HARD;
+    }
+  } else {
+    copy_style = HARD;
+  }
+  // check validity of the path
+  if (!check_run_path(path, force_flag)) {
+    ink_fatal("Failed to create runroot with path '%s'", path.c_str());
+  }
+  std::string original_root = Layout::get()->prefix;
+  std::string ts_runroot    = path;
   // check for existing runroot to use rather than create new one
-  if (!force_flag && check_file.good()) {
+  if (!force_flag && exists(Layout::relative_to(ts_runroot, "runroot.yaml"))) {
     std::cout << "Using existing runroot...\n"
                  "Please remove the old runroot if new runroot is needed"
               << std::endl;
@@ -456,36 +232,16 @@ RunrootEngine::create_runroot()
     ink_fatal("Cannot create runroot inside another runroot");
   }
 
+  std::cout << "creating runroot - " + ts_runroot << std::endl;
+
   // check if directory is empty when --force is not used
-  if (exists(ts_runroot) && is_directory(ts_runroot) && !force_flag) {
+  if (is_directory(ts_runroot) && !force_flag) {
     directory_check = ts_runroot;
     nftw(ts_runroot.c_str(), check_directory, OPEN_MAX_FILE, FTW_DEPTH);
   }
 
   // create new root & copy from original to new runroot. then fill in the map
-  copy_runroot(original_root, ts_runroot);
-
-  YAML::Emitter yamlfile;
-  // emit key value pairs to the yaml file
-  yamlfile << YAML::BeginMap;
-  for (uint i = 0; i < dir_vector.size(); i++) {
-    yamlfile << YAML::Key << dir_vector[i];
-    yamlfile << YAML::Value << path_map[dir_vector[i]];
-  }
-  yamlfile << YAML::EndMap;
-
-  // create the file
-  std::ofstream f(Layout::relative_to(ts_runroot, "runroot_path.yml"));
-  f << yamlfile.c_str();
-}
-
-// copy the stuff from original_root to ts_runroot
-// fill in the global map for yaml file emitting later
-void
-RunrootEngine::copy_runroot(const std::string &original_root, const std::string &ts_runroot)
-{
-  // map the original build time directory
-  RunrootMapType original_map;
+  RunrootMapType original_map; // map the original build time directory
 
   original_map[LAYOUT_EXEC_PREFIX]   = TS_BUILD_EXEC_PREFIX;
   original_map[LAYOUT_BINDIR]        = TS_BUILD_BINDIR;
@@ -504,13 +260,14 @@ RunrootEngine::copy_runroot(const std::string &original_root, const std::string
 
   RunrootMapType new_map = original_map;
   // use the user provided layout: layout_file
+  std::string layout_file = arguments.get("layout").value();
   if (layout_file.size() != 0) {
     try {
       YAML::Node yamlfile = YAML::LoadFile(layout_file);
-      for (auto it : yamlfile) {
+      for (auto &&it : yamlfile) {
         std::string key   = it.first.as<std::string>();
         std::string value = it.second.as<std::string>();
-        auto iter         = new_map.find(key);
+        auto &&iter       = new_map.find(key);
         if (iter != new_map.end()) {
           iter->second = value;
         } else {
@@ -528,7 +285,8 @@ RunrootEngine::copy_runroot(const std::string &original_root, const std::string
   // copy each directory to the runroot path
   // symlink the executables
   // set up path_map for yaml to emit key-value pairs
-  for (auto it : original_map) {
+  RunrootMapType path_map;
+  for (auto &&it : original_map) {
     // path handle
     std::string join_path;
     if (it.second[0] && it.second[0] == '/') {
@@ -566,6 +324,118 @@ RunrootEngine::copy_runroot(const std::string &original_root, const std::string
   } else {
     path_map[LAYOUT_PREFIX] = ".";
   }
+
+  YAML::Emitter yamlfile;
+  // emit key value pairs to the yaml file
+  yamlfile << YAML::BeginMap;
+  for (auto &&it : dir_vector) {
+    yamlfile << YAML::Key << it;
+    yamlfile << YAML::Value << path_map[it];
+  }
+  yamlfile << YAML::EndMap;
+
+  // create the file
+  std::ofstream f(Layout::relative_to(ts_runroot, "runroot.yaml"));
+  if (f.bad()) {
+    ink_warning("Writing to YAML file failed\n");
+  } else {
+    f << yamlfile.c_str();
+  }
+}
+static bool
+check_remove_force_second()
+{
+  for (int i = 0; i < 3; i++) {
+    std::cout << "This is irreversible. Are you really sure to forcibly remove the runroot Y/N: ";
+    std::string input;
+    std::cin >> input;
+    if (input == "Y" || input == "y")
+      return true;
+    if (input == "N" || input == "n")
+      return false;
+  }
+  ink_error("Invalid input Y/N");
+  exit(70);
+}
+
+// check if user want to force remove the ts_runroot
+// return true if user replies Y
+static bool
+check_remove_force()
+{
+  // check for valid Y/N
+  for (int i = 0; i < 3; i++) {
+    std::cout << "Are you sure to force removing runroot? (irreversible) Y/N: ";
+    std::string input;
+    std::cin >> input;
+    if (input == "Y" || input == "y")
+      return check_remove_force_second();
+    if (input == "N" || input == "n")
+      return false;
+  }
+  ink_error("Invalid input Y/N");
+  exit(70);
+}
+
+// the function for removing the runroot
+void
+LayoutEngine::remove_runroot()
+{
+  std::string path = path_handler(arguments.get("path").value(), false, _argv[0]);
+  // check validity of the path
+  if (path.empty()) {
+    ink_fatal("Path not valid (runroot.yaml not found)");
+  }
+
+  std::string clean_root = path;
+  append_slash(clean_root);
+
+  char cwd[PATH_MAX];
+  if (getcwd(cwd, sizeof(cwd)) == nullptr) {
+    ink_fatal("unexcepted failure from getcwd() code=%d", errno);
+  }
+  std::string cur_working_dir = cwd;
+
+  if (arguments.get("force")) {
+    // the force clean
+    if (!check_remove_force()) {
+      exit(0);
+    }
+    std::cout << "Forcing removing runroot ..." << std::endl;
+    if (!remove_directory(clean_root)) {
+      ink_warning("Failed force removing runroot '%s' - %s", clean_root.c_str(), strerror(errno));
+    }
+  } else {
+    // handle the map and deleting of each directories specified in the yml file
+    RunrootMapType map = runroot_map(Layout::relative_to(clean_root, "runroot.yaml"));
+    map.erase(LAYOUT_PREFIX);
+    map.erase(LAYOUT_EXEC_PREFIX);
+    for (auto &&it : map) {
+      std::string dir = it.second;
+      append_slash(dir);
+      // get the directory to remove: prefix/etc/trafficserver -> prefix/etc
+      dir = dir.substr(0, dir.substr(clean_root.size()).find_first_of("/") + clean_root.size());
+      if (cur_working_dir != dir) {
+        remove_directory(dir);
+      } else {
+        // if we are at this directory, remove files inside
+        remove_inside_directory(dir);
+      }
+    }
+    // remove yaml file
+    std::string yaml_file = Layout::relative_to(clean_root, "runroot.yaml");
+    if (remove(yaml_file.c_str()) != 0) {
+      ink_notice("unable to delete runroot.yaml - %s", strerror(errno));
+    }
+
+    append_slash(cur_working_dir);
+    if (cur_working_dir.find(clean_root) != 0) {
+      // if cwd is not runroot and runroot is empty, remove it
+      if (remove(clean_root.c_str()) != 0) {
+        ink_notice("unable to delete %s - %s", clean_root.c_str(), strerror(errno));
+      }
+    }
+  }
 }
 
 // return an array containing gid and uid of provided user
@@ -629,7 +499,7 @@ fix_runroot(RunrootMapType &path_map, RunrootMapType &permission_map, RunrootMap
     ink_error("To fix permission issues, root privileges are required.\nPlease run with sudo.");
     exit(70);
   }
-  for (auto it : permission_map) {
+  for (auto &&it : permission_map) {
     std::string name       = it.first;
     std::string permission = it.second;
     std::string usergroup  = usergroup_map[name];
@@ -700,8 +570,8 @@ set_permission(std::vector<std::string> const &dir_vector, RunrootMapType &path_
   struct stat stat_buffer;
 
   // set up permission map for all permissions
-  for (uint i = 0; i < dir_vector.size(); i++) {
-    std::string name  = dir_vector[i];
+  for (auto &&it : dir_vector) {
+    std::string name  = it;
     std::string value = path_map[name];
 
     if (name == LAYOUT_PREFIX || name == LAYOUT_EXEC_PREFIX) {
@@ -757,17 +627,19 @@ set_permission(std::vector<std::string> const &dir_vector, RunrootMapType &path_
 }
 
 void
-RunrootEngine::verify_runroot()
+LayoutEngine::verify_runroot()
 {
+  std::string path = path_handler(arguments.get("path").value(), false, _argv[0]);
+
   std::cout << "trafficserver user: " << TS_PKGSYSUSER << std::endl << std::endl;
 
   // put paths from yaml file or default paths to path_map
   RunrootMapType path_map;
-  if (verify_default) {
+  if (path.empty()) {
     path_map = runroot_map_default();
     std::cout << "Verifying default build ..." << std::endl;
   } else {
-    path_map = runroot_map(Layout::relative_to(path, "runroot_path.yml"));
+    path_map = runroot_map(Layout::relative_to(path, "runroot.yaml"));
   }
 
   RunrootMapType permission_map; // contains rwx bits
@@ -776,7 +648,7 @@ RunrootEngine::verify_runroot()
   set_permission(dir_vector, path_map, permission_map, usergroup_map);
 
   // if --fix is used
-  if (fix_flag) {
+  if (arguments.get("fix")) {
     fix_runroot(path_map, permission_map, usergroup_map);
     set_permission(dir_vector, path_map, permission_map, usergroup_map);
   }
diff --git a/src/traffic_layout/engine.h b/src/traffic_layout/engine.h
index 857877d..9154f1b 100644
--- a/src/traffic_layout/engine.h
+++ b/src/traffic_layout/engine.h
@@ -23,71 +23,30 @@
 
 #pragma once
 
-#include "file_system.h"
-
-#include <vector>
-#include <string>
+#include "tscore/ArgParser.h"
 #include <unordered_map>
 
-static const std::string_view RUNROOT_WORD{"--run-root"};
-static const std::string_view COPYSTYLE_WORD{"--copy-style"};
-static const std::string_view LAYOUT_WORD{"--layout"};
-
 typedef std::unordered_map<std::string, std::string> RunrootMapType;
 
 // structure for informaiton of the runroot passing around
-struct RunrootEngine {
-  // the parsing function for traffic runroot program
-  bool runroot_parse();
-
-  // check the logic and see if everthing is fine
-  void sanity_check();
-
-  // the function for removing the runroot
-  void clean_runroot();
-
+struct LayoutEngine {
+  // default output of all layouts
+  void info();
   // the function of creating runroot
   void create_runroot();
-
+  // the function for removing the runroot
+  void remove_runroot();
   // the function of verifying runroot (including fix)
   void verify_runroot();
-
-  // copy the stuff from original_root to ts_runroot
-  // fill in the global map for yaml file emitting later
-  void copy_runroot(const std::string &original_root, const std::string &ts_runroot);
-
-  // the help message for runroot
-  void runroot_help_message(const bool runflag, const bool cleanflag, const bool verifyflag);
-
-  // the pass in arguments
-  std::vector<std::string> _argv;
-  // flags for command line parsing
-  bool help_flag    = false;
-  bool version_flag = false;
-  bool run_flag     = false;
-  bool clean_flag   = false;
-  bool force_flag   = false;
-  bool abs_flag     = false;
-  bool verify_flag  = false;
-  bool fix_flag     = false;
-  // verify the default layout or not
-  bool verify_default = false;
-  // for parsing
-  int command_num = 0;
-
-  std::string layout_file;
-
-  CopyStyle copy_style = HARD;
-
-  // the path for create & remove
-  std::string path;
-
   // vector containing all directory names
   std::vector<std::string> const dir_vector = {LAYOUT_PREFIX,     LAYOUT_EXEC_PREFIX,   LAYOUT_BINDIR,     LAYOUT_SBINDIR,
                                                LAYOUT_SYSCONFDIR, LAYOUT_DATADIR,       LAYOUT_INCLUDEDIR, LAYOUT_LIBDIR,
                                                LAYOUT_LIBEXECDIR, LAYOUT_LOCALSTATEDIR, LAYOUT_RUNTIMEDIR, LAYOUT_LOGDIR,
                                                LAYOUT_CACHEDIR};
-
-  // map for yaml file emit
-  RunrootMapType path_map;
+  // parser
+  ts::ArgParser parser;
+  // parsed arguments
+  ts::Arguments arguments;
+  // mordern argv
+  std::vector<std::string> _argv;
 };
diff --git a/src/traffic_layout/file_system.cc b/src/traffic_layout/file_system.cc
index 6b94034..54e273b 100644
--- a/src/traffic_layout/file_system.cc
+++ b/src/traffic_layout/file_system.cc
@@ -21,21 +21,16 @@
   limitations under the License.
 */
 
-// funciton for file system management
-// including: make directory (with parents), copy directory (recursively), remove directory (recursively), remove all directories
-// inside
+// file for file system management for runroot including:
+// create directory (with parents), copy directory (recursively),
+// remove directory (recursively), remove everything inside certain directory (recursively)
 
 #include "tscore/ink_error.h"
-#include "tscore/I_Layout.h"
 #include "tscore/runroot.h"
 #include "file_system.h"
 
-#include <iostream>
 #include <fstream>
 #include <ftw.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
 #include <set>
 
 // global variables for copy function
@@ -58,7 +53,7 @@ append_slash(std::string &path)
   }
 }
 
-void
+static void
 remove_slash(std::string &path)
 {
   if (path.back() == '/') {
@@ -67,28 +62,12 @@ remove_slash(std::string &path)
 }
 
 bool
-exists(const std::string &dir)
-{
-  struct stat buffer;
-  int result = stat(dir.c_str(), &buffer);
-  return (!result) ? true : false;
-}
-
-bool
-is_directory(const std::string &directory)
-{
-  struct stat buffer;
-  int result = stat(directory.c_str(), &buffer);
-  return (!result && (S_IFDIR & buffer.st_mode)) ? true : false;
-}
-
-bool
 create_directory(const std::string &dir)
 {
   std::string s = dir;
   append_slash(s);
 
-  if (exists(dir) && is_directory(dir)) {
+  if (is_directory(dir)) {
     return true;
   }
 
diff --git a/src/traffic_layout/file_system.h b/src/traffic_layout/file_system.h
index b6d450e..147b51a 100644
--- a/src/traffic_layout/file_system.h
+++ b/src/traffic_layout/file_system.h
@@ -35,13 +35,6 @@ enum CopyStyle { FULL, HARD, SOFT };
 // append slash & remove slash of path for convinient use
 void append_slash(std::string &path);
 
-void remove_slash(std::string &path);
-
-// some checks for directory exist or is it a directory
-bool exists(const std::string &dir);
-
-bool is_directory(const std::string &directory);
-
 // for file system
 bool create_directory(const std::string &dir);
 
diff --git a/src/traffic_layout/info.cc b/src/traffic_layout/info.cc
index 1be0d37..f67a737 100644
--- a/src/traffic_layout/info.cc
+++ b/src/traffic_layout/info.cc
@@ -129,8 +129,6 @@ print_var(std::string_view const &name, std::string_view const &value, bool json
 void
 produce_layout(bool json)
 {
-  Layout::create();
-
   RecProcessInit(RECM_STAND_ALONE, nullptr /* diags */);
   LibRecordsConfigInit();
 
diff --git a/src/traffic_layout/info.h b/src/traffic_layout/info.h
index 2230b88..c70f0ec 100644
--- a/src/traffic_layout/info.h
+++ b/src/traffic_layout/info.h
@@ -21,7 +21,7 @@
   limitations under the License.
  */
 
-// header file for traffic layout info
+// the original traffic_layout
 
 void produce_features(bool json);
 
diff --git a/src/traffic_layout/traffic_layout.cc b/src/traffic_layout/traffic_layout.cc
index f3cd448..bbcf43a 100644
--- a/src/traffic_layout/traffic_layout.cc
+++ b/src/traffic_layout/traffic_layout.cc
@@ -21,158 +21,59 @@
   limitations under the License.
  */
 
-#include "tscore/ink_platform.h"
-#include "tscore/ink_args.h"
-#include "tscore/I_Version.h"
 #include "tscore/I_Layout.h"
-#include "records/I_RecProcess.h"
-#include "RecordsConfig.h"
 #include "tscore/runroot.h"
 #include "engine.h"
-#include "file_system.h"
-#include "info.h"
-
-#include <iostream>
-#include <fstream>
-#include <set>
 
 using namespace std::literals;
 
-struct subcommand {
-  int (*handler)(int, const char **);
-  const std::string name;
-  const std::string help;
-};
-
-// Command line arguments (parsing)
-struct CommandLineArgs {
-  int features;
-  int json;
-};
-
-static CommandLineArgs cl;
-
-const ArgumentDescription argument_descriptions[] = {
-  {"features", 'f', "Show the compiled features", "T", &cl.features, nullptr, nullptr},
-  {"json", 'j', "Produce output in JSON format (when supported)", "T", &cl.json, nullptr, nullptr},
-  VERSION_ARGUMENT_DESCRIPTION(),
-  RUNROOT_ARGUMENT_DESCRIPTION()};
-
-// the usage help message for subcommand
-static void
-help_usage()
-{
-  std::cout << "\nSubcommands:\n"
-               "info         Show the layout as default\n"
-               "init         Initialize the ts_runroot sandbox\n"
-               "remove       Remove the ts_runroot sandbox\n"
-               "verify       Verify the ts_runroot paths\n"
-            << std::endl;
-  std::cout << "Switches of runroot:\n"
-               "--path:      Specify the path of the runroot\n"
-               "--force:     Force to create or remove ts_runroot\n"
-               "--absolute:  Produce absolute path in the yaml file during init\n"
-               "--run-root(=/path):  Using specified TS_RUNROOT as sandbox\n"
-               "--fix:       fix the premission issues that verify found"
-            << std::endl;
-  printf("Detailed usage and description in traffic_layout.en.rst\n");
-  printf("\nGeneral Usage:\n");
-  usage(argument_descriptions, countof(argument_descriptions), nullptr);
-}
-
 int
-info(int argc, const char **argv)
-{
-  // take the "info" out from command line
-  if (argv[1] && argv[1] == "info"sv) {
-    for (int i = 1; i < argc; i++) {
-      argv[i] = argv[i + 1];
-    }
-  }
-  // detect help command
-  int i = 1;
-  while (argv[i]) {
-    if (argv[i] == "--help"sv || argv[i] == "-h"sv) {
-      help_usage();
-    }
-    ++i;
-  }
-
-  AppVersionInfo appVersionInfo;
-  appVersionInfo.setup(PACKAGE_NAME, "traffic_layout", PACKAGE_VERSION, __DATE__, __TIME__, BUILD_MACHINE, BUILD_PERSON, "");
-  // Process command line arguments and dump into variables
-  if (!process_args_ex(&appVersionInfo, argument_descriptions, countof(argument_descriptions), argv) ||
-      file_arguments[0] != nullptr) {
-    help_usage();
-  }
-
-  runroot_handler(argv, 0 != cl.json);
-
-  if (cl.features) {
-    produce_features(0 != cl.json);
-  } else {
-    produce_layout(0 != cl.json);
-  }
-  return 0;
-}
-
-// handle everything with runroot using engine
-int
-traffic_runroot(int argc, const char **argv)
+main(int argc, const char **argv)
 {
-  // runroot engine for operations
-  RunrootEngine engine;
+  LayoutEngine engine;
 
   int i = 0;
   while (argv[i]) {
     engine._argv.push_back(argv[i]);
     ++i;
   }
-  // parse the command line & put into global variable
-  if (!engine.runroot_parse()) {
-    engine.runroot_help_message(true, true, true);
-    return 0;
-  }
-  // check sanity of the command about the runroot program
-  engine.sanity_check();
-
-  // create layout for runroot handling
-  runroot_handler(argv);
+  engine.parser.add_global_usage("traffic_layout CMD [OPTIONS]");
+
+  // global options
+  engine.parser.add_option("--features", "-f", "Show the compiled features");
+  engine.parser.add_option("--json", "-j", "Produce output in JSON format (when supported)");
+  engine.parser.add_option("--version", "-V", "Print version string");
+  engine.parser.add_option("--help", "-h", "Print usage information");
+  engine.parser.add_option("--run-root", "", "using TS_RUNROOT as sandbox", "", 1);
+
+  // info command
+  engine.parser.add_command("info", "Show the layout as default", [&]() { engine.info(); });
+  // init command
+  engine.parser.add_command("init", "Initialize(create) the runroot sandbox", [&]() { engine.create_runroot(); })
+    .add_option("--absolute", "", "Produce absolute path in the runroot.yaml")
+    .add_option("--force", "", "Create runroot even if the directory is not empty")
+    .add_option("--path", "", "Specify the path of the runroot", "", 1)
+    .add_option("--copy-style", "", "Specify the way of copying (FULL/HARD/SOFT)", "", 1)
+    .add_option("--layout", "", "Use specific layout (providing YAML file) to create runroot", "", 1);
+  // remove command
+  engine.parser.add_command("remove", "Remove the runroot sandbox", [&]() { engine.remove_runroot(); })
+    .add_option("--force", "", "Remove runroot even if runroot.yaml is not found")
+    .add_option("--path", "", "Specify the path of the runroot", "", 1);
+  // verify command
+  engine.parser.add_command("verify", "Verify the runroot permissions", [&]() { engine.verify_runroot(); })
+    .add_option("--fix", "", "Fix the permission issues of runroot")
+    .add_option("--path", "", "Specify the path of the runroot", "", 1);
+
+  engine.arguments = engine.parser.parse(argv);
+
+  runroot_handler(argv, engine.arguments.get("json"));
   Layout::create();
 
-  // check the command to execute
-  if (engine.run_flag) {
-    engine.create_runroot();
-  } else if (engine.clean_flag) {
-    engine.clean_runroot();
-  } else if (engine.verify_flag) {
-    engine.verify_runroot();
+  if (engine.arguments.has_action()) {
+    engine.arguments.invoke();
+  } else {
+    engine.info();
   }
 
   return 0;
 }
-
-int
-main(int argc, const char **argv)
-{
-  const subcommand commands[] = {
-    {info, "info", "Show the layout"},
-    {traffic_runroot, "init", "Initialize the ts_runroot sandbox"},
-    {traffic_runroot, "remove", "Remove the ts_runroot sandbox"},
-    {traffic_runroot, "verify", "verify the ts_runroot paths"},
-    {traffic_runroot, "fix", "fix permmision issue of the ts_runroot"},
-  };
-
-  // with command (info, init, remove)
-  for (unsigned i = 0; i < countof(commands); ++i) {
-    if (!argv[1]) {
-      break;
-    }
-    if (strcmp(argv[1], commands[i].name.c_str()) == 0) {
-      return commands[i].handler(argc, argv);
-    }
-  }
-
-  // without command (info, init, remove), default behavior
-  return info(argc, argv);
-}
diff --git a/src/tscore/runroot.cc b/src/tscore/runroot.cc
index eb22ed6..e18e991 100644
--- a/src/tscore/runroot.cc
+++ b/src/tscore/runroot.cc
@@ -1,6 +1,6 @@
 /** @file
 
-  A brief file prefix
+  runroot.cc
 
   @section license License
 
@@ -22,56 +22,60 @@
 */
 
 /*
-This file contains the function of the runroot handler for TS_RUNROOT
-handle the --run-root for every command or program
-
-Goal: set up an ENV variable for Layout.cc to use as TS_RUNROOT sandbox
-easy & clean
-
-Example: ./traffic_server --run-root=/path/to/sandbox
-
-Need a yaml file in the sandbox with key value pairs of all directory locations for other programs to use
-
-Directories needed in the yaml file:
-prefix, exec_prefix, includedir, localstatedir, bindir, logdir, sbindir, sysconfdir,
-datadir, libexecdir, libdir, runtimedir, cachedir.
+  Please refer to traffic_layout document for the usage
 */
 
 #include "tscore/ink_error.h"
-#include "tscore/ink_file.h"
 #include "tscore/I_Layout.h"
 #include "tscore/runroot.h"
-
-#include <vector>
-#include <fstream>
-#include <set>
-#include <unistd.h>
 #include <yaml-cpp/yaml.h>
 
 static std::string runroot_file = {};
 
+// this is a temporary approach and will be replaced when std::filesystem is in
+bool
+exists(const std::string &dir)
+{
+  struct stat buffer;
+  int result = stat(dir.c_str(), &buffer);
+  return (!result) ? true : false;
+}
+
+bool
+is_directory(const std::string &directory)
+{
+  struct stat buffer;
+  int result = stat(directory.c_str(), &buffer);
+  return (!result && (S_IFDIR & buffer.st_mode)) ? true : false;
+}
+
 // the function for the checking of the yaml file in the passed in path
 // if found return the path to the yaml file, if not return empty string.
 static std::string
-get_yaml_path(const std::string &path, bool json)
+get_yaml_path(const std::string &path)
 {
+  // yaml_file 2 and 3 are for temporary use in case the change may break for people using runroot already
+  // this can be removed in the future.
   std::string yaml_file;
-  if (ink_file_is_directory(path.c_str())) {
-    yaml_file = Layout::relative_to(path, "runroot_path.yml");
-  } else {
-    if (path.substr(path.find_last_of("/") + 1) == "runroot_path.yml") {
-      yaml_file = path;
+  std::string yaml_file2;
+  std::string yaml_file3;
+  if (is_directory(path.c_str())) {
+    std::string yaml_file(Layout::relative_to(path, "runroot.yaml"));
+    if (exists(yaml_file)) {
+      return yaml_file;
     }
-  }
-  std::ifstream check_file;
-  check_file.open(yaml_file);
-  if (!check_file.good()) {
-    if (!json) {
-      ink_warning("Unable to access runroot: '%s' - %s", yaml_file.c_str(), strerror(errno));
+    std::string yaml_file2(Layout::relative_to(path, "runroot.yml"));
+    if (exists(yaml_file2)) {
+      return yaml_file2;
+    }
+    std::string yaml_file3(Layout::relative_to(path, "runroot_path.yml"));
+    if (exists(yaml_file3)) {
+      return yaml_file3;
     }
-    return {};
+  } else if (exists(path)) {
+    return path;
   }
-  return yaml_file;
+  return {};
 }
 
 // the function for the checking of the yaml file in passed in directory or parent directory
@@ -83,16 +87,13 @@ get_parent_yaml_path(const std::string &path)
   if (whole_path.back() == '/') {
     whole_path.pop_back();
   }
-
   // go up to 4 level of parent directories
   for (int i = 0; i < 4; i++) {
     if (whole_path.empty()) {
       return {};
     }
-    std::ifstream check_file;
-    std::string yaml_file = Layout::relative_to(whole_path, "runroot_path.yml");
-    check_file.open(yaml_file);
-    if (check_file.good()) {
+    std::string yaml_file = get_yaml_path(whole_path);
+    if (!yaml_file.empty()) {
       return yaml_file;
     }
     whole_path = whole_path.substr(0, whole_path.find_last_of("/"));
@@ -121,30 +122,35 @@ runroot_handler(const char **argv, bool json)
     i++;
   }
 
-  // if --run-root is provided arg is not just --run-root
+  // if --run-root is provided
   if (!arg.empty() && arg != prefix) {
     // 1. pass in path
     prefix += "=";
-    path = get_yaml_path(arg.substr(prefix.size(), arg.size() - 1), json);
+    std::string value = arg.substr(prefix.size(), arg.size() - 1);
+    path              = get_yaml_path(value);
     if (!path.empty()) {
       if (!json) {
         ink_notice("using command line path as RUNROOT");
       }
       runroot_file = path;
       return;
+    } else if (!json) {
+      ink_warning("Unable to access runroot: '%s'", value.c_str());
     }
   }
 
   // 2. check Environment variable
   char *env_val = getenv("TS_RUNROOT");
   if (env_val) {
-    path = get_yaml_path(env_val, json);
+    path = get_yaml_path(env_val);
     if (!path.empty()) {
       runroot_file = path;
       if (!json) {
         ink_notice("using the environment variable TS_RUNROOT");
       }
       return;
+    } else if (!json) {
+      ink_warning("Unable to access runroot: '%s' from $TS_RUNROOT", env_val);
     }
   }
 
@@ -203,7 +209,7 @@ runroot_map_default()
   return map;
 }
 
-// return a map of all path in runroot_path.yml
+// return a map of all path in runroot.yaml
 RunrootMapType
 runroot_map(const std::string &file)
 {
diff --git a/tests/gold_tests/runroot/runroot_error.test.py b/tests/gold_tests/runroot/runroot_error.test.py
index ce8dcf7..1fc7ca7 100644
--- a/tests/gold_tests/runroot/runroot_error.test.py
+++ b/tests/gold_tests/runroot/runroot_error.test.py
@@ -29,21 +29,14 @@ Test.ContinueOnFail = True
 path = os.path.join(Test.RunDirectory, "runroot")
 tr = Test.AddTestRun()
 tr.Processes.Default.Command = "$ATS_BIN/traffic_layout init --path " + path
-f = tr.Disk.File(os.path.join(path, "runroot_path.yml"))
+f = tr.Disk.File(os.path.join(path, "runroot.yaml"))
 f.Exists = True
 
-# bad command line args
-tr = Test.AddTestRun("wrong usage")
-tr.Processes.Default.Command = "$ATS_BIN/traffic_layout init --path"
-tr.Processes.Default.Streams.All = Testers.ContainsExpression("init Usage", "init incorrect usage")
-tr.Processes.Default.Streams.All = Testers.ContainsExpression("remove Usage", "init incorrect usage")
-tr.Processes.Default.Streams.All = Testers.ContainsExpression("verify Usage", "init incorrect usage")
-
 # use existing runroot
 tr = Test.AddTestRun("using existing runroot")
 tr.Processes.Default.Command = "$ATS_BIN/traffic_layout init --path " + path
 tr.Processes.Default.Streams.All = Testers.ContainsExpression("Using existing runroot", "init incorrect usage")
-f = tr.Disk.File(os.path.join(path, "runroot_path.yml"))
+f = tr.Disk.File(os.path.join(path, "runroot.yaml"))
 f.Exists = True
 
 # create runroot inside another
@@ -52,7 +45,7 @@ tr = Test.AddTestRun("create runroot inside runroot")
 tr.Processes.Default.Command = "$ATS_BIN/traffic_layout init --path " + path_inside
 tr.Processes.Default.Streams.All = Testers.ContainsExpression(
     "Cannot create runroot inside another runroot", "init incorrect usage")
-f = tr.Disk.File(os.path.join(path_inside, "runroot_path.yml"))
+f = tr.Disk.File(os.path.join(path_inside, "runroot.yaml"))
 f.Exists = False
 
 # remove invalid runroot
diff --git a/tests/gold_tests/runroot/runroot_init.test.py b/tests/gold_tests/runroot/runroot_init.test.py
index e031e73..ec8a2f6 100644
--- a/tests/gold_tests/runroot/runroot_init.test.py
+++ b/tests/gold_tests/runroot/runroot_init.test.py
@@ -32,7 +32,7 @@ path1 = os.path.join(Test.RunDirectory, "runroot1")
 tr = Test.AddTestRun("Test traffic_layout init #1")
 tr.Processes.Default.Command = "$ATS_BIN/traffic_layout init --path " + path1
 tr.Processes.Default.ReturnCode = 0
-f = tr.Disk.File(os.path.join(path1, "runroot_path.yml"))
+f = tr.Disk.File(os.path.join(path1, "runroot.yaml"))
 f.Exists = True
 
 # init to relative directory
@@ -40,7 +40,7 @@ path2 = os.path.join(Test.RunDirectory, "runroot2")
 tr = Test.AddTestRun("Test traffic_layout init #2")
 tr.Processes.Default.Command = "cd " + Test.RunDirectory + ";$ATS_BIN/traffic_layout init --path runroot2"
 tr.Processes.Default.ReturnCode = 0
-f = tr.Disk.File(os.path.join(path2, "runroot_path.yml"))
+f = tr.Disk.File(os.path.join(path2, "runroot.yaml"))
 f.Exists = True
 
 # init to cwd
@@ -48,7 +48,7 @@ path3 = os.path.join(Test.RunDirectory, "runroot3")
 tr = Test.AddTestRun("Test traffic_layout init #3")
 tr.Processes.Default.Command = "mkdir " + path3 + ";cd " + path3 + ";$ATS_BIN/traffic_layout init"
 tr.Processes.Default.ReturnCode = 0
-f = tr.Disk.File(os.path.join(path3, "runroot_path.yml"))
+f = tr.Disk.File(os.path.join(path3, "runroot.yaml"))
 f.Exists = True
 
 # --force init to an non-empty directory
@@ -57,7 +57,7 @@ tr = Test.AddTestRun("Test traffic_layout init #4")
 randomfile = os.path.join(path4, "foo")
 tr.Processes.Default.Command = "mkdir " + path4 + ";touch " + randomfile + ";$ATS_BIN/traffic_layout init --force --path " + path4
 tr.Processes.Default.ReturnCode = 0
-f = tr.Disk.File(os.path.join(path4, "runroot_path.yml"))
+f = tr.Disk.File(os.path.join(path4, "runroot.yaml"))
 f.Exists = True
 tr.Processes.Default.Streams.All = Testers.ContainsExpression("Forcing creating runroot", "force message")
 
@@ -72,7 +72,7 @@ tr = Test.AddTestRun("Test traffic_layout init #5")
 # create the junk files in runroot1 and create(init and copy) runroot5 from runroot 1
 tr.Processes.Default.Command = "touch " + junk + ";" + os.path.join(path1, exe_path) + " init --path " + path5
 tr.Processes.Default.ReturnCode = 0
-f = tr.Disk.File(os.path.join(path5, "runroot_path.yml"))
+f = tr.Disk.File(os.path.join(path5, "runroot.yaml"))
 f.Exists = True
 # check if the junk file is created and not copied to the new runroot
 f = tr.Disk.File(junk)
diff --git a/tests/gold_tests/runroot/runroot_manager.test.py b/tests/gold_tests/runroot/runroot_manager.test.py
index 8ad3515..0954cdb 100644
--- a/tests/gold_tests/runroot/runroot_manager.test.py
+++ b/tests/gold_tests/runroot/runroot_manager.test.py
@@ -32,9 +32,9 @@ rr_file = os.path.join(Test.RunDirectory, "rr_tmp")
 tr = Test.AddTestRun("create runroot and deal with it")
 tr.Processes.Default.Command = "$ATS_BIN/traffic_layout init --path " + path + " --absolute; " + \
     "mkdir " + rr_file + "; mv " + \
-    os.path.join(path, "runroot_path.yml") + " " + \
-    os.path.join(rr_file, "runroot_path.yml")
-f = tr.Disk.File(os.path.join(rr_file, "runroot_path.yml"))
+    os.path.join(path, "runroot.yaml") + " " + \
+    os.path.join(rr_file, "runroot.yaml")
+f = tr.Disk.File(os.path.join(rr_file, "runroot.yaml"))
 f.Exists = True
 
 
diff --git a/tests/gold_tests/runroot/runroot_remove.test.py b/tests/gold_tests/runroot/runroot_remove.test.py
index 314c56a..c2349eb 100644
--- a/tests/gold_tests/runroot/runroot_remove.test.py
+++ b/tests/gold_tests/runroot/runroot_remove.test.py
@@ -29,26 +29,26 @@ Test.ContinueOnFail = True
 path1 = os.path.join(Test.RunDirectory, "runroot1")
 tr = Test.AddTestRun()
 tr.Processes.Default.Command = "$ATS_BIN/traffic_layout init --path " + path1
-f = tr.Disk.File(os.path.join(path1, "runroot_path.yml"))
+f = tr.Disk.File(os.path.join(path1, "runroot.yaml"))
 f.Exists = True
 
 path2 = os.path.join(Test.RunDirectory, "runroot2")
 tr = Test.AddTestRun()
 tr.Processes.Default.Command = "$ATS_BIN/traffic_layout init --path " + path2
-f = tr.Disk.File(os.path.join(path2, "runroot_path.yml"))
+f = tr.Disk.File(os.path.join(path2, "runroot.yaml"))
 f.Exists = True
 
 path3 = os.path.join(Test.RunDirectory, "runroot3")
 tr = Test.AddTestRun()
 tr.Processes.Default.Command = "$ATS_BIN/traffic_layout init --path " + path3
-f = tr.Disk.File(os.path.join(path3, "runroot_path.yml"))
+f = tr.Disk.File(os.path.join(path3, "runroot.yaml"))
 f.Exists = True
 
 # normal remove from pass in path
 tr = Test.AddTestRun("Test traffic_layout remove #1")
 tr.Processes.Default.Command = "$ATS_BIN/traffic_layout remove --path " + path1
 tr.Processes.Default.ReturnCode = 0
-f = tr.Disk.File(os.path.join(path1, "runroot_path.yml"))
+f = tr.Disk.File(os.path.join(path1, "runroot.yaml"))
 f.Exists = False
 d = tr.Disk.Directory(path1)
 d.Exists = False
@@ -57,7 +57,7 @@ d.Exists = False
 tr = Test.AddTestRun("Test traffic_layout remove #2")
 tr.Processes.Default.Command = "cd " + Test.RunDirectory + ";$ATS_BIN/traffic_layout remove --path runroot2"
 tr.Processes.Default.ReturnCode = 0
-f = tr.Disk.File(os.path.join(path2, "runroot_path.yml"))
+f = tr.Disk.File(os.path.join(path2, "runroot.yaml"))
 f.Exists = False
 d = tr.Disk.Directory(path2)
 d.Exists = False
@@ -66,7 +66,7 @@ d.Exists = False
 tr = Test.AddTestRun("Test traffic_layout remove #3")
 tr.Processes.Default.Command = "mkdir " + path3 + ";cd " + path3 + ";$ATS_BIN/traffic_layout remove"
 tr.Processes.Default.ReturnCode = 0
-f = tr.Disk.File(os.path.join(path3, "runroot_path.yml"))
+f = tr.Disk.File(os.path.join(path3, "runroot.yaml"))
 f.Exists = False
 d = tr.Disk.Directory(path3)
 d.Exists = True
diff --git a/tests/gold_tests/runroot/runroot_use.test.py b/tests/gold_tests/runroot/runroot_use.test.py
index 1c0ef10..0ef2aef 100644
--- a/tests/gold_tests/runroot/runroot_use.test.py
+++ b/tests/gold_tests/runroot/runroot_use.test.py
@@ -31,13 +31,13 @@ Test.SkipUnless(Test.Variables.BINDIR.startswith(Test.Variables.PREFIX),
 path = os.path.join(Test.RunDirectory, "runroot")
 tr = Test.AddTestRun()
 tr.Processes.Default.Command = "$ATS_BIN/traffic_layout init --path " + path
-f = tr.Disk.File(os.path.join(path, "runroot_path.yml"))
+f = tr.Disk.File(os.path.join(path, "runroot.yaml"))
 f.Exists = True
 
 path2 = os.path.join(Test.RunDirectory, "runroot2")
 tr = Test.AddTestRun()
 tr.Processes.Default.Command = "$ATS_BIN/traffic_layout init --path " + path2
-f = tr.Disk.File(os.path.join(path2, "runroot_path.yml"))
+f = tr.Disk.File(os.path.join(path2, "runroot.yaml"))
 f.Exists = True
 
 # 1. --run-root use path cmd
diff --git a/tests/gold_tests/runroot/runroot_verify.test.py b/tests/gold_tests/runroot/runroot_verify.test.py
index ce201c0..a9253b4 100644
--- a/tests/gold_tests/runroot/runroot_verify.test.py
+++ b/tests/gold_tests/runroot/runroot_verify.test.py
@@ -31,7 +31,7 @@ Test.SkipUnless(Test.Variables.BINDIR.startswith(Test.Variables.PREFIX),
 path = os.path.join(Test.RunDirectory, "runroot")
 tr = Test.AddTestRun()
 tr.Processes.Default.Command = "$ATS_BIN/traffic_layout init --path " + path
-f = tr.Disk.File(os.path.join(path, "runroot_path.yml"))
+f = tr.Disk.File(os.path.join(path, "runroot.yaml"))
 f.Exists = True
 
 # verify test #1