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 30c2c35  Added traffic_runroot feature to generate sandbox for 
programs to run
30c2c35 is described below

commit 30c2c35e5ed1daadcf8a8db5e46760e3d7ae5325
Author: Xavier Chi <chitianha...@gmail.com>
AuthorDate: Fri Aug 11 16:22:32 2017 -0500

    Added traffic_runroot feature to generate sandbox for programs to run
---
 cmd/traffic_cop/traffic_cop.cc           |   5 +-
 cmd/traffic_crashlog/traffic_crashlog.cc |   5 +-
 cmd/traffic_ctl/traffic_ctl.cc           |   3 +
 cmd/traffic_layout/traffic_layout.cc     |   8 +-
 cmd/traffic_manager/traffic_manager.cc   |   6 +-
 cmd/traffic_top/traffic_top.cc           |   1 +
 lib/ts/I_Layout.h                        |   6 ++
 lib/ts/Layout.cc                         |  80 ++++++++++++++++++-
 lib/ts/ink_args.cc                       |   3 +
 lib/ts/ink_args.h                        |   4 +
 lib/ts/runroot.cc                        | 132 +++++++++++++++++++++++++++++++
 proxy/Main.cc                            |   3 +
 proxy/logcat.cc                          |   5 +-
 proxy/logstats.cc                        |   5 +-
 14 files changed, 257 insertions(+), 9 deletions(-)

diff --git a/cmd/traffic_cop/traffic_cop.cc b/cmd/traffic_cop/traffic_cop.cc
index 4536e25..56737e0 100644
--- a/cmd/traffic_cop/traffic_cop.cc
+++ b/cmd/traffic_cop/traffic_cop.cc
@@ -35,6 +35,7 @@
 #include "RecordsConfig.h"
 #include "ts/ink_cap.h"
 #include "Cop.h"
+#include "ts/runroot.cc"
 
 #include <string>
 #include <map>
@@ -1685,7 +1686,8 @@ static const ArgumentDescription argument_descriptions[] 
= {
   {"stdout", 'o', "Print log messages to standard output", "F", &stdout_flag, 
nullptr, nullptr},
   {"stop", 's', "Send child processes SIGSTOP instead of SIGKILL", "F", 
&stop_flag, nullptr, nullptr},
   HELP_ARGUMENT_DESCRIPTION(),
-  VERSION_ARGUMENT_DESCRIPTION()};
+  VERSION_ARGUMENT_DESCRIPTION(),
+  RUNROOT_ARGUMENT_DESCRIPTION()};
 
 int
 main(int /* argc */, const char *argv[])
@@ -1693,6 +1695,7 @@ main(int /* argc */, const char *argv[])
   int fd;
   appVersionInfo.setup(PACKAGE_NAME, "traffic_cop", PACKAGE_VERSION, __DATE__, 
__TIME__, BUILD_MACHINE, BUILD_PERSON, "");
 
+  runroot_handler(argv);
   // Before accessing file system initialize Layout engine
   Layout::create();
 
diff --git a/cmd/traffic_crashlog/traffic_crashlog.cc 
b/cmd/traffic_crashlog/traffic_crashlog.cc
index 54b4755..c64aded 100644
--- a/cmd/traffic_crashlog/traffic_crashlog.cc
+++ b/cmd/traffic_crashlog/traffic_crashlog.cc
@@ -30,6 +30,7 @@
 #include "I_RecProcess.h"
 #include "RecordsConfig.h"
 #include "ts/BaseLogFile.h"
+#include "ts/runroot.cc"
 
 static int syslog_mode    = false;
 static int debug_mode     = false;
@@ -48,7 +49,8 @@ static const ArgumentDescription argument_descriptions[] = {
   {"syslog", '-', "Syslog after writing a crash log", "F", &syslog_mode, 
nullptr, nullptr},
   {"debug", '-', "Enable debugging mode", "F", &debug_mode, nullptr, nullptr},
   HELP_ARGUMENT_DESCRIPTION(),
-  VERSION_ARGUMENT_DESCRIPTION()};
+  VERSION_ARGUMENT_DESCRIPTION(),
+  RUNROOT_ARGUMENT_DESCRIPTION()};
 
 static struct tm
 timestamp()
@@ -117,6 +119,7 @@ main(int /* argc ATS_UNUSED */, const char **argv)
     ATS_UNUSED_RETURN(seteuid(0));
   }
 
+  runroot_handler(argv);
   Layout::create();
   RecProcessInit(RECM_STAND_ALONE, nullptr /* diags */);
   LibRecordsConfigInit();
diff --git a/cmd/traffic_ctl/traffic_ctl.cc b/cmd/traffic_ctl/traffic_ctl.cc
index 88a0bc0..f09f3b2 100644
--- a/cmd/traffic_ctl/traffic_ctl.cc
+++ b/cmd/traffic_ctl/traffic_ctl.cc
@@ -26,6 +26,7 @@
 #include "ts/I_Layout.h"
 #include "I_RecProcess.h"
 #include "RecordsConfig.h"
+#include "ts/runroot.cc"
 
 AppVersionInfo CtrlVersionInfo;
 
@@ -223,6 +224,7 @@ main(int argc, const char **argv)
     {"debug", '-', "Enable debugging output", "F", &debug, nullptr, nullptr},
     HELP_ARGUMENT_DESCRIPTION(),
     VERSION_ARGUMENT_DESCRIPTION(),
+    RUNROOT_ARGUMENT_DESCRIPTION(),
   };
 
   const subcommand commands[] = {
@@ -252,6 +254,7 @@ main(int argc, const char **argv)
     return CtrlSubcommandUsage(nullptr, commands, countof(commands), 
argument_descriptions, countof(argument_descriptions));
   }
 
+  runroot_handler(argv);
   Layout::create();
   RecProcessInit(RECM_STAND_ALONE, diags);
   LibRecordsConfigInit();
diff --git a/cmd/traffic_layout/traffic_layout.cc 
b/cmd/traffic_layout/traffic_layout.cc
index ec984f6..3ba483e 100644
--- a/cmd/traffic_layout/traffic_layout.cc
+++ b/cmd/traffic_layout/traffic_layout.cc
@@ -27,8 +27,7 @@
 #include "ts/I_Layout.h"
 #include "I_RecProcess.h"
 #include "RecordsConfig.h"
-
-#include <iostream>
+#include "ts/runroot.cc"
 
 // Command line arguments (parsing)
 struct CommandLineArgs {
@@ -45,7 +44,8 @@ const ArgumentDescription argument_descriptions[] = {
   {"json", 'j', "Produce output in JSON format (when supported)", "T", 
&cl.json, nullptr, nullptr},
 
   HELP_ARGUMENT_DESCRIPTION(),
-  VERSION_ARGUMENT_DESCRIPTION()};
+  VERSION_ARGUMENT_DESCRIPTION(),
+  RUNROOT_ARGUMENT_DESCRIPTION()};
 
 // Produce output about compile time features, useful for checking how things 
were built, as well
 // as for our TSQA test harness.
@@ -184,6 +184,8 @@ main(int /* argc ATS_UNUSED */, const char **argv)
   // Process command line arguments and dump into variables
   process_args(&appVersionInfo, argument_descriptions, 
countof(argument_descriptions), argv);
 
+  runroot_handler(argv);
+
   if (cl.features) {
     produce_features(0 != cl.json);
   } else {
diff --git a/cmd/traffic_manager/traffic_manager.cc 
b/cmd/traffic_manager/traffic_manager.cc
index c3d23e2..7a6c98e 100644
--- a/cmd/traffic_manager/traffic_manager.cc
+++ b/cmd/traffic_manager/traffic_manager.cc
@@ -27,6 +27,7 @@
 #include "ts/ink_sock.h"
 #include "ts/ink_args.h"
 #include "ts/ink_syslog.h"
+#include "ts/runroot.cc"
 
 #include "WebMgmtUtils.h"
 #include "MgmtUtils.h"
@@ -416,6 +417,8 @@ main(int argc, const char **argv)
 {
   const long MAX_LOGIN = ink_login_name_max();
 
+  runroot_handler(argv);
+
   // Before accessing file system initialize Layout engine
   Layout::create();
   mgmt_path = Layout::get()->sysconfdir.c_str();
@@ -454,7 +457,8 @@ main(int argc, const char **argv)
 #endif
     {"nosyslog", '-', "Do not log to syslog", "F", &disable_syslog, nullptr, 
nullptr},
     HELP_ARGUMENT_DESCRIPTION(),
-    VERSION_ARGUMENT_DESCRIPTION()
+    VERSION_ARGUMENT_DESCRIPTION(),
+    RUNROOT_ARGUMENT_DESCRIPTION()
   };
 
   // Process command line arguments and dump into variables
diff --git a/cmd/traffic_top/traffic_top.cc b/cmd/traffic_top/traffic_top.cc
index 982983a..99996ff 100644
--- a/cmd/traffic_top/traffic_top.cc
+++ b/cmd/traffic_top/traffic_top.cc
@@ -404,6 +404,7 @@ main(int argc, const char **argv)
     {"sleep", 's', "Enable debugging output", "I", &sleep_time, nullptr, 
nullptr},
     HELP_ARGUMENT_DESCRIPTION(),
     VERSION_ARGUMENT_DESCRIPTION(),
+    RUNROOT_ARGUMENT_DESCRIPTION(),
   };
 
   process_args(&version, argument_descriptions, 
countof(argument_descriptions), argv, USAGE);
diff --git a/lib/ts/I_Layout.h b/lib/ts/I_Layout.h
index d23b07a..b742340 100644
--- a/lib/ts/I_Layout.h
+++ b/lib/ts/I_Layout.h
@@ -44,6 +44,12 @@ struct Layout {
   ~Layout();
 
   /**
+   return use runroot or not
+
+  */
+  bool check_runroot();
+
+  /**
    Return file path relative to Layout->prefix
 
   */
diff --git a/lib/ts/Layout.cc b/lib/ts/Layout.cc
index cb3c7d8..5abbffc 100644
--- a/lib/ts/Layout.cc
+++ b/lib/ts/Layout.cc
@@ -28,6 +28,10 @@
 #include "ts/ink_string.h"
 #include "ts/I_Layout.h"
 
+#include <fstream>
+#include <iostream>
+#include <unordered_map>
+
 static Layout *layout = nullptr;
 
 Layout *
@@ -108,13 +112,87 @@ Layout::relative_to(char *buf, size_t bufsz, 
ts::string_view dir, ts::string_vie
   }
 }
 
+bool
+Layout::check_runroot()
+{
+  std::string yaml_path = {};
+
+  if (getenv("USING_RUNROOT") == nullptr) {
+    return false;
+  } else {
+    std::string env_path = getenv("USING_RUNROOT");
+    int len              = env_path.size();
+    if ((len + 1) > PATH_NAME_MAX) {
+      ink_fatal("TS_RUNROOT environment variable is too big: %d, max %d\n", 
len, PATH_NAME_MAX - 1);
+    }
+    std::cout << "TS_RUNROOT initiated..." << std::endl;
+    std::ifstream file;
+    if (env_path.back() != '/') {
+      env_path.append("/");
+    }
+    yaml_path = env_path + "runroot_path.yaml";
+
+    file.open(yaml_path);
+    if (!file.good()) {
+      ink_warning("Bad env path, continue with default value");
+      return false;
+    }
+  }
+  std::ifstream yamlfile(yaml_path);
+  std::unordered_map<std::string, std::string> runroot_map;
+  std::string str;
+  while (std::getline(yamlfile, str)) {
+    int pos = str.find(':');
+    runroot_map[str.substr(0, pos)] = str.substr(pos + 2);
+  }
+  for (auto it : runroot_map) {
+    prefix        = runroot_map["prefix"];
+    exec_prefix   = runroot_map["exec_prefix"];
+    bindir        = runroot_map["bindir"];
+    sbindir       = runroot_map["sbindir"];
+    sysconfdir    = runroot_map["sysconfdir"];
+    datadir       = runroot_map["datadir"];
+    includedir    = runroot_map["includedir"];
+    libdir        = runroot_map["libdir"];
+    libexecdir    = runroot_map["libexecdir"];
+    localstatedir = runroot_map["localstatedir"];
+    runtimedir    = runroot_map["runtimedir"];
+    logdir        = runroot_map["logdir"];
+    mandir        = runroot_map["mandir"];
+    infodir       = runroot_map["infodir"];
+    cachedir      = runroot_map["cachedir"];
+  }
+
+  // // for yaml lib operations
+  // YAML::Node yamlfile = YAML::LoadFile(yaml_path);
+  // prefix              = yamlfile["prefix"].as<string>();
+  // exec_prefix         = yamlfile["exec_prefix"].as<string>();
+  // bindir              = yamlfile["bindir"].as<string>();
+  // sbindir             = yamlfile["sbindir"].as<string>();
+  // sysconfdir          = yamlfile["sysconfdir"].as<string>();
+  // datadir             = yamlfile["datadir"].as<string>();
+  // includedir          = yamlfile["includedir"].as<string>();
+  // libdir              = yamlfile["libdir"].as<string>();
+  // libexecdir          = yamlfile["libexecdir"].as<string>();
+  // localstatedir       = yamlfile["localstatedir"].as<string>();
+  // runtimedir          = yamlfile["runtimedir"].as<string>();
+  // logdir              = yamlfile["logdir"].as<string>();
+  // mandir              = yamlfile["mandir"].as<string>();
+  // infodir             = yamlfile["infodir"].as<string>();
+  // cachedir            = yamlfile["cachedir"].as<string>();
+  return true;
+}
+
 Layout::Layout(ts::string_view const _prefix)
 {
-  if (_prefix.size() != 0) {
+  if (!_prefix.empty()) {
     prefix.assign(_prefix.data(), _prefix.size());
   } else {
     std::string path;
     int len;
+    if (check_runroot()) {
+      return;
+    }
     if (getenv("TS_ROOT") != nullptr) {
       std::string env_path(getenv("TS_ROOT"));
       len = env_path.size();
diff --git a/lib/ts/ink_args.cc b/lib/ts/ink_args.cc
index b2a61c1..4954bff 100644
--- a/lib/ts/ink_args.cc
+++ b/lib/ts/ink_args.cc
@@ -221,6 +221,9 @@ process_args_ex(const AppVersionInfo *appinfo, const 
ArgumentDescription *argume
     if ((*argv)[1] == '-') {
       // Deal with long options ...
       for (i = 0; i < n_argument_descriptions; i++) {
+        if (!strcmp(argument_descriptions[i].name, "run-root")) {
+          break;
+        }
         if (!strcmp(argument_descriptions[i].name, (*argv) + 2)) {
           *argv += strlen(*argv) - 1;
           if (!process_arg(appinfo, argument_descriptions, 
n_argument_descriptions, i, &argv)) {
diff --git a/lib/ts/ink_args.h b/lib/ts/ink_args.h
index ad7ecd4..549fcdd 100644
--- a/lib/ts/ink_args.h
+++ b/lib/ts/ink_args.h
@@ -75,6 +75,10 @@ struct ArgumentDescription {
   {                                                                          \
     "help", 'h', "Print usage information", nullptr, nullptr, nullptr, usage \
   }
+#define RUNROOT_ARGUMENT_DESCRIPTION()                                         
        \
+  {                                                                            
        \
+    "run-root", '-', "using TS_RUNROOT as sandbox", nullptr, nullptr, nullptr, 
nullptr \
+  }
 
 /* Global Data
 */
diff --git a/lib/ts/runroot.cc b/lib/ts/runroot.cc
new file mode 100644
index 0000000..785e7e5
--- /dev/null
+++ b/lib/ts/runroot.cc
@@ -0,0 +1,132 @@
+/** @file
+
+  A brief file prefix
+
+  @section license License
+
+  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.
+*/
+
+/*
+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, mandir, 
sbindir, sysconfdir,
+datadir, libexecdir, libdir, runtimedir, infodir, cachedir.
+*/
+
+#include "ts/ink_error.h"
+
+#include <vector>
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <set>
+#include <unistd.h>
+
+#define MAX_CWD_LEN 1024
+
+// the function for the checking of the yaml file in parent path
+// if found return the parent path containing the yaml file
+static std::string
+check_parent_path(const std::string &path)
+{
+  std::string whole_path = path;
+  if (whole_path.back() == '/')
+    whole_path.pop_back();
+
+  while (whole_path != "") {
+    whole_path                   = whole_path.substr(0, 
whole_path.find_last_of("/"));
+    std::string parent_yaml_path = whole_path + "/runroot_path.yaml";
+    std::ifstream parent_check_file;
+    parent_check_file.open(parent_yaml_path);
+    if (parent_check_file.good()) {
+      std::cout << "using parent of bin/current working dir" << std::endl;
+      return whole_path;
+    }
+  }
+  return {};
+}
+
+// handler for ts runroot
+void
+runroot_handler(const char **argv)
+{
+  std::string command = {};
+  std::string arg     = {};
+  std::string prefix  = "--run-root";
+
+  int i = 0;
+  while (argv[i]) {
+    command = argv[i];
+    if (command.substr(0, prefix.size()) == prefix) {
+      arg = command;
+      break;
+    }
+    i++;
+  }
+  if (arg.empty())
+    return;
+
+  // 1. check pass in path
+  prefix += "=";
+  if (arg.substr(0, prefix.size()) == prefix) {
+    std::ifstream yaml_checkfile;
+    std::string path = arg.substr(prefix.size(), arg.size() - 1);
+
+    if (path.back() != '/')
+      path.append("/");
+
+    std::string yaml_path = path + "runroot_path.yaml";
+    yaml_checkfile.open(yaml_path);
+    if (yaml_checkfile.good()) {
+      std::cout << "using command line path as RUNROOT" << std::endl;
+      setenv("USING_RUNROOT", path.c_str(), true);
+      return;
+    } else {
+      ink_warning("bad RUNROOT");
+    }
+  }
+  // 2. argv provided invalid/no yaml file, then check env variable
+  if (getenv("TS_RUNROOT") != nullptr) {
+    setenv("USING_RUNROOT", getenv("TS_RUNROOT"), true);
+    std::cout << "using the environment variable TS_RUNROOT" << std::endl;
+    return;
+  }
+  // 3. find parent path of bin/pwd to check
+  char cwd[MAX_CWD_LEN];
+  getcwd(cwd, sizeof(cwd));
+  std::string RealBinPath = realpath(argv[0], nullptr); // bin path
+
+  std::vector<std::string> TwoPath = {RealBinPath, cwd};
+  for (auto it : TwoPath) {
+    std::string path = check_parent_path(it);
+    if (!path.empty()) {
+      setenv("USING_RUNROOT", path.c_str(), true);
+      return;
+    }
+  }
+  std::cout << "Failed to initialize TS_RUNROOT, using default path..." << 
std::endl;
+}
diff --git a/proxy/Main.cc b/proxy/Main.cc
index 5be69e4..92916d3 100644
--- a/proxy/Main.cc
+++ b/proxy/Main.cc
@@ -37,6 +37,7 @@
 #include "ts/ink_stack_trace.h"
 #include "ts/ink_syslog.h"
 #include "ts/hugepages.h"
+#include "ts/runroot.cc"
 
 #include "api/ts/ts.h" // This is sadly needed because of us using 
TSThreadInit() for some reason.
 
@@ -211,6 +212,7 @@ static ArgumentDescription argument_descriptions[] = {
   {"poll_timeout", 't', "poll timeout in milliseconds", "I", &poll_timeout, 
nullptr, nullptr},
   HELP_ARGUMENT_DESCRIPTION(),
   VERSION_ARGUMENT_DESCRIPTION(),
+  RUNROOT_ARGUMENT_DESCRIPTION(),
 };
 
 struct AutoStopCont : public Continuation {
@@ -1521,6 +1523,7 @@ main(int /* argc ATS_UNUSED */, const char **argv)
   // Define the version info
   appVersionInfo.setup(PACKAGE_NAME, "traffic_server", PACKAGE_VERSION, 
__DATE__, __TIME__, BUILD_MACHINE, BUILD_PERSON, "");
 
+  runroot_handler(argv);
   // Before accessing file system initialize Layout engine
   Layout::create();
   chdir_root(); // change directory to the install root of traffic server.
diff --git a/proxy/logcat.cc b/proxy/logcat.cc
index 590804e..98f8c82 100644
--- a/proxy/logcat.cc
+++ b/proxy/logcat.cc
@@ -24,6 +24,7 @@
 #include "ts/ink_platform.h"
 #include "ts/ink_args.h"
 #include "ts/I_Layout.h"
+#include "ts/runroot.cc"
 
 #define PROGRAM_NAME "traffic_logcat"
 #define MAX_LOGBUFFER_SIZE 65536
@@ -68,7 +69,8 @@ static const ArgumentDescription argument_descriptions[] = {
   {"overwrite_output", 'w', "Overwrite existing output file(s)", "T", 
&overwrite_existing_file, NULL, NULL},
   {"elf2", '2', "Convert to Extended2 Logging Format", "T", &elf2_flag, NULL, 
NULL},
   HELP_ARGUMENT_DESCRIPTION(),
-  VERSION_ARGUMENT_DESCRIPTION()};
+  VERSION_ARGUMENT_DESCRIPTION(),
+  RUNROOT_ARGUMENT_DESCRIPTION()};
 
 /*
  * Gets the inode number of a given file
@@ -256,6 +258,7 @@ main(int /* argc ATS_UNUSED */, const char *argv[])
   //
   appVersionInfo.setup(PACKAGE_NAME, PROGRAM_NAME, PACKAGE_VERSION, __DATE__, 
__TIME__, BUILD_MACHINE, BUILD_PERSON, "");
 
+  runroot_handler(argv);
   // Before accessing file system initialize Layout engine
   Layout::create();
   // process command-line arguments
diff --git a/proxy/logstats.cc b/proxy/logstats.cc
index 18c914e..8007a42 100644
--- a/proxy/logstats.cc
+++ b/proxy/logstats.cc
@@ -29,6 +29,7 @@
 #include "ts/HashFNV.h"
 #include "ts/ink_args.h"
 #include "ts/MatcherUtils.h"
+#include "ts/runroot.cc"
 
 // Includes and namespaces etc.
 #include "LogStandalone.cc"
@@ -653,7 +654,8 @@ static ArgumentDescription argument_descriptions[] = {
   {"debug_tags", 'T', "Colon-Separated Debug Tags", "S1023", &error_tags, 
nullptr, nullptr},
   {"report_per_user", 'r', "Report stats per user instead of host", "T", 
&cl.report_per_user, nullptr, nullptr},
   HELP_ARGUMENT_DESCRIPTION(),
-  VERSION_ARGUMENT_DESCRIPTION()};
+  VERSION_ARGUMENT_DESCRIPTION(),
+  RUNROOT_ARGUMENT_DESCRIPTION()};
 
 static const char *USAGE_LINE = "Usage: " PROGRAM_NAME " [-f logfile] [-o 
origin[,...]] [-O originfile] [-m minhits] [-binshv]";
 
@@ -2380,6 +2382,7 @@ main(int /* argc ATS_UNUSED */, const char *argv[])
   // build the application information structure
   appVersionInfo.setup(PACKAGE_NAME, PROGRAM_NAME, PACKAGE_VERSION, __DATE__, 
__TIME__, BUILD_MACHINE, BUILD_PERSON, "");
 
+  runroot_handler(argv);
   // Before accessing file system initialize Layout engine
   Layout::create();
 

-- 
To stop receiving notification emails like this one, please contact
['"commits@trafficserver.apache.org" <commits@trafficserver.apache.org>'].

Reply via email to