You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2018/08/13 18:29:18 UTC
[trafficserver] 03/03: Runroot: Add feature to use runroot by
providing yaml file
This is an automated email from the ASF dual-hosted git repository.
zwoop pushed a commit to branch 8.0.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
commit ea89d097086392e684034d95e2e74cad9b3c1f50
Author: Xavier Chi <ch...@gmail.com>
AuthorDate: Fri Jul 20 15:14:18 2018 -0500
Runroot: Add feature to use runroot by providing yaml file
(cherry picked from commit 37aa9fefc729ab320b2acffca480ce37ea3f21c6)
---
lib/ts/runroot.cc | 81 +++++++++++++-------------
lib/ts/runroot.h | 4 --
src/traffic_layout/engine.cc | 39 ++++++++++++-
tests/gold_tests/runroot/runroot_error.test.py | 4 +-
4 files changed, 80 insertions(+), 48 deletions(-)
diff --git a/lib/ts/runroot.cc b/lib/ts/runroot.cc
index 38edaa4..8e5f0f4 100644
--- a/lib/ts/runroot.cc
+++ b/lib/ts/runroot.cc
@@ -38,6 +38,7 @@ datadir, libexecdir, libdir, runtimedir, cachedir.
*/
#include "ts/ink_error.h"
+#include "ts/ink_file.h"
#include "ts/I_Layout.h"
#include "runroot.h"
@@ -47,27 +48,33 @@ datadir, libexecdir, libdir, runtimedir, cachedir.
#include <unistd.h>
#include <yaml-cpp/yaml.h>
-static std::string using_runroot = {};
+static std::string runroot_file = {};
// the function for the checking of the yaml file in the passed in path
-// if found return the path, if not return empty string
-std::string
-check_path(const std::string &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)
{
- std::string whole_path = path;
- std::string yaml_path = Layout::relative_to(whole_path, "runroot_path.yml");
std::ifstream check_file;
- check_file.open(yaml_path);
- if (check_file.good()) {
- return whole_path;
+ if (ink_file_is_directory(path.c_str())) {
+ std::string yaml_path = Layout::relative_to(path, "runroot_path.yml");
+ check_file.open(yaml_path);
+ if (check_file.good()) {
+ return yaml_path;
+ }
+ } else {
+ check_file.open(path);
+ if (check_file.good() && path.substr(path.find_last_of("/") + 1) == "runroot_path.yml") {
+ return path;
+ }
}
return {};
}
// the function for the checking of the yaml file in passed in directory or parent directory
-// if found return the parent path containing the yaml file
-std::string
-check_parent_path(const std::string &path)
+// if found return the parent path to the yaml file
+static std::string
+get_parent_yaml_path(const std::string &path)
{
std::string whole_path = path;
if (whole_path.back() == '/') {
@@ -79,25 +86,17 @@ check_parent_path(const std::string &path)
if (whole_path.empty()) {
return {};
}
- if (!check_path(whole_path).empty()) {
- return whole_path;
+ 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("/"));
}
return {};
}
-// until I get a <filesystem> impl in
-bool
-is_directory(const char *directory)
-{
- struct stat buffer;
- int result = stat(directory, &buffer);
- return (!result && (S_IFDIR & buffer.st_mode)) ? true : false;
-}
-
// handler for ts runroot
-// this function set up using_runroot
+// this function set up runroot_file
void
runroot_handler(const char **argv, bool json)
{
@@ -121,12 +120,12 @@ runroot_handler(const char **argv, bool json)
if (!arg.empty() && arg != prefix) {
// 1. pass in path
prefix += "=";
- path = check_path(arg.substr(prefix.size(), arg.size() - 1));
+ path = get_yaml_path(arg.substr(prefix.size(), arg.size() - 1));
if (!path.empty()) {
if (!json) {
ink_notice("using command line path as RUNROOT");
}
- using_runroot = path;
+ runroot_file = path;
return;
} else {
if (!json) {
@@ -137,10 +136,10 @@ runroot_handler(const char **argv, bool json)
// 2. check Environment variable
char *env_val = getenv("TS_RUNROOT");
- if ((env_val != nullptr) && is_directory(env_val)) {
- path = check_path(env_val);
+ if (env_val) {
+ path = get_yaml_path(env_val);
if (!path.empty()) {
- using_runroot = env_val;
+ runroot_file = path;
if (!json) {
ink_notice("using the environment variable TS_RUNROOT");
}
@@ -155,9 +154,9 @@ runroot_handler(const char **argv, bool json)
// 3. find cwd or parent path of cwd to check
char cwd[PATH_MAX] = {0};
if (getcwd(cwd, sizeof(cwd)) != nullptr) {
- path = check_parent_path(cwd);
+ path = get_parent_yaml_path(cwd);
if (!path.empty()) {
- using_runroot = path;
+ runroot_file = path;
if (!json) {
ink_notice("using cwd as TS_RUNROOT");
}
@@ -170,9 +169,9 @@ runroot_handler(const char **argv, bool json)
if ((argv[0] != nullptr) && realpath(argv[0], RealBinPath) != nullptr) {
std::string bindir = RealBinPath;
bindir = bindir.substr(0, bindir.find_last_of("/")); // getting the bin dir not executable path
- path = check_parent_path(bindir);
+ path = get_parent_yaml_path(bindir);
if (!path.empty()) {
- using_runroot = path;
+ runroot_file = path;
if (!json) {
ink_notice("using the installed dir as TS_RUNROOT");
}
@@ -209,11 +208,13 @@ runroot_map_default()
// return a map of all path in runroot_path.yml
RunrootMapType
-runroot_map(const std::string &prefix)
+runroot_map(const std::string &file)
{
RunrootMapType map;
try {
- YAML::Node yamlfile = YAML::LoadFile(Layout::relative_to(prefix, "runroot_path.yml"));
+ YAML::Node yamlfile = YAML::LoadFile(file);
+ std::string prefix = file.substr(0, file.find_last_of("/"));
+
for (auto it : yamlfile) {
// key value pairs of dirs
std::string value = it.second.as<std::string>();
@@ -223,7 +224,7 @@ runroot_map(const std::string &prefix)
map[it.first.as<std::string>()] = value;
}
} catch (YAML::Exception &e) {
- ink_warning("Unable to read runroot_path.yml from '%s': %s", prefix.c_str(), e.what());
+ ink_warning("Unable to read '%s': %s", file.c_str(), e.what());
ink_notice("Continuing with default value");
return RunrootMapType{};
}
@@ -236,19 +237,19 @@ runroot_map(const std::string &prefix)
RunrootMapType
check_runroot()
{
- if (using_runroot.empty()) {
+ if (runroot_file.empty()) {
return RunrootMapType{};
}
- int len = using_runroot.size();
+ int len = runroot_file.size();
if ((len + 1) > PATH_NAME_MAX) {
ink_fatal("runroot path is too big: %d, max %d\n", len, PATH_NAME_MAX - 1);
}
- return runroot_map(using_runroot);
+ return runroot_map(runroot_file);
}
bool
use_runroot()
{
- return !using_runroot.empty();
+ return !runroot_file.empty();
}
diff --git a/lib/ts/runroot.h b/lib/ts/runroot.h
index a06636f..fcb44e4 100644
--- a/lib/ts/runroot.h
+++ b/lib/ts/runroot.h
@@ -48,10 +48,6 @@ const std::string LAYOUT_CACHEDIR = "cachedir";
typedef std::unordered_map<std::string, std::string> RunrootMapType;
-std::string check_path(const std::string &path);
-
-std::string check_parent_path(const std::string &path);
-
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 764514d..36c21e9 100644
--- a/src/traffic_layout/engine.cc
+++ b/src/traffic_layout/engine.cc
@@ -46,6 +46,41 @@
// for nftw check_directory
std::string directory_check;
+// the function for the checking of the yaml file in the passed in path
+// if found return the path, if not return empty string
+std::string
+check_path(const std::string &path)
+{
+ std::ifstream check_file;
+ check_file.open(Layout::relative_to(path, "runroot_path.yml"));
+ if (check_file.good()) {
+ return path;
+ }
+ return {};
+}
+
+// the function for the checking of the yaml file in passed in directory or parent directory
+// if found return the parent path containing the yaml file
+std::string
+check_parent_path(const std::string &path)
+{
+ std::string yaml_path = path;
+ if (yaml_path.back() == '/') {
+ yaml_path.pop_back();
+ }
+ // go up to 4 level of parent directories
+ for (int i = 0; i < 4; i++) {
+ if (yaml_path.empty()) {
+ return {};
+ }
+ if (!check_path(yaml_path).empty()) {
+ return yaml_path;
+ }
+ yaml_path = yaml_path.substr(0, yaml_path.find_last_of("/"));
+ }
+ return {};
+}
+
// check if we can create the runroot using path
// return true if the path is good to use
static bool
@@ -340,7 +375,7 @@ RunrootEngine::clean_runroot()
}
} else {
// handle the map and deleting of each directories specified in the yml file
- RunrootMapType map = runroot_map(clean_root);
+ 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) {
@@ -728,7 +763,7 @@ RunrootEngine::verify_runroot()
path_map = runroot_map_default();
std::cout << "Verifying default build ..." << std::endl;
} else {
- path_map = runroot_map(path);
+ path_map = runroot_map(Layout::relative_to(path, "runroot_path.yml"));
}
RunrootMapType permission_map; // contains rwx bits
diff --git a/tests/gold_tests/runroot/runroot_error.test.py b/tests/gold_tests/runroot/runroot_error.test.py
index 2776243..e32df98 100644
--- a/tests/gold_tests/runroot/runroot_error.test.py
+++ b/tests/gold_tests/runroot/runroot_error.test.py
@@ -62,9 +62,9 @@ f.Exists = False
path_invalid = os.path.join(ts_root, "tmp")
tr = Test.AddTestRun("remove invalid runroot")
tr.Processes.Default.Command = "$ATS_BIN/traffic_layout remove --path " + path_invalid
-tr.Processes.Default.Streams.All = Testers.ContainsExpression("Unable to read runroot_path.yml", "remove incorrect usage")
+tr.Processes.Default.Streams.All = Testers.ContainsExpression("Unable to read", "remove incorrect usage")
# verify invalid runroot
tr = Test.AddTestRun("verify invalid runroot")
tr.Processes.Default.Command = "$ATS_BIN/traffic_layout verify --path " + path_invalid
-tr.Processes.Default.Streams.All = Testers.ContainsExpression("Unable to read runroot_path.yml", "verify incorrect usage")
+tr.Processes.Default.Streams.All = Testers.ContainsExpression("Unable to read", "verify incorrect usage")