This is an automated email from the ASF dual-hosted git repository. maskit pushed a commit to branch quic-05 in repository https://gitbox.apache.org/repos/asf/trafficserver.git
commit 6d401d7246d3e47785a1f88ed92af3308c74dd25 Author: Leif Hedstrom <zw...@apache.org> AuthorDate: Thu Oct 5 11:41:40 2017 -0700 Merge branch 'master' into quic-latest * master: Change the include from .cc to .h, as Odin intended Fix mem leak related to do_os_response() function Runroot for traffic_layout Fixed typo in cachekey plugin documentation (cherry picked from commit f322f09d56ff4c9e956807f7a5754fe2274ad6be) --- cmd/traffic_cop/traffic_cop.cc | 2 +- cmd/traffic_crashlog/traffic_crashlog.cc | 2 +- cmd/traffic_ctl/traffic_ctl.cc | 2 +- cmd/traffic_layout/Makefile.am | 6 +- cmd/traffic_layout/engine.cc | 288 ++++++++++++++++++++++ cmd/traffic_layout/engine.h | 58 +++++ cmd/traffic_layout/file_system.cc | 186 ++++++++++++++ cmd/traffic_layout/file_system.h | 50 ++++ cmd/traffic_layout/traffic_layout.cc | 88 ++++++- cmd/traffic_manager/traffic_manager.cc | 2 +- doc/admin-guide/plugins/cachekey.en.rst | 2 +- doc/appendices/command-line/traffic_layout.en.rst | 73 ++++++ lib/ts/Makefile.am | 2 + lib/ts/runroot.cc | 10 +- lib/ts/runroot.h | 35 +++ mgmt/utils/MgmtSocket.cc | 2 +- plugins/experimental/ts_lua/ts_lua.c | 2 + proxy/Main.cc | 2 +- proxy/http2/Makefile.am | 2 +- proxy/logcat.cc | 2 +- proxy/logstats.cc | 2 +- tests/gold_tests/basic/runroot-layout.test.py | 69 ++++++ 22 files changed, 868 insertions(+), 19 deletions(-) diff --git a/cmd/traffic_cop/traffic_cop.cc b/cmd/traffic_cop/traffic_cop.cc index 56737e0..7fcb211 100644 --- a/cmd/traffic_cop/traffic_cop.cc +++ b/cmd/traffic_cop/traffic_cop.cc @@ -35,7 +35,7 @@ #include "RecordsConfig.h" #include "ts/ink_cap.h" #include "Cop.h" -#include "ts/runroot.cc" +#include "ts/runroot.h" #include <string> #include <map> diff --git a/cmd/traffic_crashlog/traffic_crashlog.cc b/cmd/traffic_crashlog/traffic_crashlog.cc index c64aded..cca4113 100644 --- a/cmd/traffic_crashlog/traffic_crashlog.cc +++ b/cmd/traffic_crashlog/traffic_crashlog.cc @@ -30,7 +30,7 @@ #include "I_RecProcess.h" #include "RecordsConfig.h" #include "ts/BaseLogFile.h" -#include "ts/runroot.cc" +#include "ts/runroot.h" static int syslog_mode = false; static int debug_mode = false; diff --git a/cmd/traffic_ctl/traffic_ctl.cc b/cmd/traffic_ctl/traffic_ctl.cc index f09f3b2..32f59d9 100644 --- a/cmd/traffic_ctl/traffic_ctl.cc +++ b/cmd/traffic_ctl/traffic_ctl.cc @@ -26,7 +26,7 @@ #include "ts/I_Layout.h" #include "I_RecProcess.h" #include "RecordsConfig.h" -#include "ts/runroot.cc" +#include "ts/runroot.h" AppVersionInfo CtrlVersionInfo; diff --git a/cmd/traffic_layout/Makefile.am b/cmd/traffic_layout/Makefile.am index eb20a0c..4bb3f2a 100644 --- a/cmd/traffic_layout/Makefile.am +++ b/cmd/traffic_layout/Makefile.am @@ -28,7 +28,11 @@ AM_LDFLAGS += \ @OPENSSL_LDFLAGS@ traffic_layout_SOURCES = \ - traffic_layout.cc + traffic_layout.cc \ + file_system.cc \ + file_system.h \ + engine.cc \ + engine.h traffic_layout_LDADD = \ $(top_builddir)/lib/records/librecords_p.a \ diff --git a/cmd/traffic_layout/engine.cc b/cmd/traffic_layout/engine.cc new file mode 100644 index 0000000..8cb2a32 --- /dev/null +++ b/cmd/traffic_layout/engine.cc @@ -0,0 +1,288 @@ +/** @file + + A brief file description + + @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. +*/ + +// for engine of traffic runroot +// function introduction in engine.h + +#include "ts/runroot.h" +#include "ts/I_Layout.h" +#include "ts/ink_error.h" +#include "ts/ink_args.h" +#include "ts/I_Version.h" +#include "ts/ink_file.h" + +#include "engine.h" +#include "file_system.h" + +#include <fstream> +#include <iostream> + +// check if user want to force create the ts_runroot +// return true if user replies Y +static bool +check_force() +{ + // check for Y/N 3 times + for (int i = 0; i < 3; i++) { + std::cout << "Are you sure to overwrite and force creating 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); +} + +// check if we can create the runroot using path +// return true if the path is good to use +static bool +check_run_path(const std::string &arg, const int forceflag) +{ + if (arg.empty() || arg[0] == '-') + return false; + if (arg[0] != '-' && arg[0] != '/') + ink_fatal("Please provide absolute path"); + + std::string path = arg; + // check force create + if (forceflag == 1) { + if (!check_force()) { + ink_notice("Force create failed"); + exit(0); + } + ink_notice("Forcing creating runroot ..."); + if (!remove_directory(path)) { + ink_warning("Failed removing(overwriting) existing directory - %s", strerror(errno)); + } + } + // if directory already exist + if (exists(path) && is_directory(path)) { + return true; + } else { + // try to create & remove + if (!create_directory(path)) { + return false; + } + remove_directory(path); + return true; + } +} + +// return true if the path is good to delete +static bool +check_delete_path(const std::string &arg) +{ + if (arg.empty() || arg[0] == '-') + return false; + if (arg[0] != '-' && arg[0] != '/') + ink_fatal("Please provide absolute path"); + + std::ifstream check_file(arg); + if (check_file) { + return true; + } + return false; +} + +// the help message for traffic_runroot +static void +help_message(const int versionflag, const int runflag, const int cleanflag, const int forceflag) +{ + std::cout << "if no path provided, please set Environment variable $TS_RUNROOT" << std::endl; + std::cout << "traffic_runroot usage: traffic_runroot [switch] [<path>]" << std::endl; + std::cout << " traffic_runroot -f [switch] [<path>]\n" << std::endl; + std::cout << "==option=====switch=====description=====================================" << std::endl; + std::cout << "Run: --init(-i) (Initialize the ts_runroot sandbox)" << std::endl; + std::cout << "Remove: --remove(-r) (remove the ts_runroot sandbox)\n" << std::endl; + std::cout << "==flag=======key=========description======================================" << std::endl; + std::cout << "Force: --force (force to create ts_runroot, only works with init)\n" << std::endl; + std::cout << "Program information: traffic_runroot [switch]" << std::endl; + + if (runflag) + std::cout << "\ninit example: traffic_runroot init /path/to/sandbox" << std::endl; + if (cleanflag) + std::cout << "\nremove example: traffic_runroot rm /path/to/sandbox" << std::endl; + if (forceflag) + std::cout << "\nforce example: traffic_runroot --force init /path/to/sandbox" << std::endl; +} + +// the parsing function for traffic runroot program +// set the flag & path appropriately +void +RunrootEngine::runroot_parse() +{ + int i = 0; + while (i < _argc) { + std::string argument = _argv[i]; + // set help, verion, force flag + if (argument == "-h" || argument == "--help") { + help_flag = 1; + } + if (argument == "-V" || argument == "--version") { + version_flag = 1; + } + if (argument == "-f" || argument == "--force") { + force_flag = 1; + } + // set init flag & sandbox path + if (argument == "--init" || argument == "-i") { + run_flag = 1; + if (i == _argc - 1) + break; + if (!check_run_path(_argv[i + 1], force_flag)) { + ++i; + continue; + } + run_path = _argv[i + 1]; + ++i; + } + // set remove flag & sandbox path + if (argument == "--remove" || argument == "-r") { + clean_flag = 1; + if (i == _argc - 1) + break; + if (!check_delete_path(_argv[i + 1])) { + ++i; + continue; + } + clean_path = _argv[i + 1]; + ++i; + } + ++i; + } + // check output help or not + if (help_flag == 1) { + help_message(version_flag, run_flag, clean_flag, force_flag); + exit(0); + } + if (version_flag == 1) { + // get version info + AppVersionInfo appVersionInfo; + appVersionInfo.setup(PACKAGE_NAME, "traffic_runroot", PACKAGE_VERSION, __DATE__, __TIME__, BUILD_MACHINE, BUILD_PERSON, ""); + ink_fputln(stdout, appVersionInfo.FullVersionInfoStr); + exit(0); + } + if (run_flag == 1 && clean_flag == 1) { + ink_fatal("Cannot run and clean in the same time"); + } + if (force_flag == 1 && run_flag == 0) { + ink_fatal("Nothing to force"); + } +} + +// for cleanning the parent of bin / cwd +// return the path if we can clean the bin / cwd +const static std::string +clean_parent(const std::string &bin_path) +{ + char cwd[MAX_CWD_LEN]; + getcwd(cwd, sizeof(cwd)); + std::string RealBinPath = realpath(bin_path.c_str(), nullptr); // bin path + + std::vector<std::string> TwoPath = {RealBinPath, cwd}; + for (auto it : TwoPath) { + std::string path = check_parent_path(it); + if (path.size() != 0) { + return path; + } + } + return ""; +} + +// the function for removing the runroot +bool +RunrootEngine::clean_runroot() +{ + if (clean_flag == 1) { + std::string clean_root; + if (!clean_path.empty()) { + clean_root = clean_path; + } else { + // no clean path provided get the environment + if (getenv("TS_RUNROOT") != nullptr) { + clean_root = getenv("TS_RUNROOT"); + } else { + // no path & environment, get parents of bin/cwd + clean_root = clean_parent(_argv[0]); + if (clean_root.empty()) + ink_fatal("Nothing to clean"); + } + } + append_slash(clean_root); + + // if we can find the yaml, then clean it + std::ifstream check_file(clean_root + "runroot_path.yaml"); + if (check_file.good()) { + if (!remove_directory(clean_root)) { + ink_fatal("Error cleaning directory - %s", strerror(errno)); + } + } else { + ink_fatal("invalid path to clean (no yaml file found)"); + } + return true; + } + + // no clean + return false; +} + +// 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 + std::unordered_map<std::string, std::string> original_map; + + original_map["exec_prefix"] = TS_BUILD_EXEC_PREFIX; + original_map["bindir"] = TS_BUILD_BINDIR; + original_map["sbindir"] = TS_BUILD_SBINDIR; + original_map["sysconfdir"] = TS_BUILD_SYSCONFDIR; + original_map["datadir"] = TS_BUILD_DATADIR; + original_map["includedir"] = TS_BUILD_INCLUDEDIR; + original_map["libdir"] = TS_BUILD_LIBDIR; + original_map["libexecdir"] = TS_BUILD_LIBEXECDIR; + original_map["localstatedir"] = TS_BUILD_LOCALSTATEDIR; + original_map["runtimedir"] = TS_BUILD_RUNTIMEDIR; + original_map["logdir"] = TS_BUILD_LOGDIR; + original_map["mandir"] = TS_BUILD_MANDIR; + original_map["infodir"] = TS_BUILD_INFODIR; + original_map["cachedir"] = TS_BUILD_CACHEDIR; + + // copy each directory to the runroot path + // symlink the executables + // set up path_map for yaml to emit key-value pairs + ink_notice("Copying from the original root..."); + for (auto it : original_map) { + std::string old_path = Layout::relative_to(original_root, it.second); + std::string new_path = ts_runroot + it.second; + if (!copy_directory(old_path, new_path)) { + ink_warning("Copy failed for %s - %s", it.first.c_str(), strerror(errno)); + } + path_map[it.first] = ts_runroot + it.second; + } + path_map["prefix"] = ts_runroot; +} diff --git a/cmd/traffic_layout/engine.h b/cmd/traffic_layout/engine.h new file mode 100644 index 0000000..c68ef51 --- /dev/null +++ b/cmd/traffic_layout/engine.h @@ -0,0 +1,58 @@ +/** @file + + A brief file description + + @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. +*/ + +#pragma once + +#include <vector> +#include <string> +#include <unordered_map> + +// structure for informaiton of the runroot passing around +struct RunrootEngine { + // the parsing function for traffic runroot program + void runroot_parse(); + + // the function for removing the runroot + // return true upon success, false upon failure + bool clean_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 pass in arguments + int _argc; + std::vector<std::string> _argv; + // the flag for command line parsing + int help_flag = 0; + int version_flag = 0; + int run_flag = 0; + int clean_flag = 0; + int force_flag = 0; + // the path for create & remove + std::string run_path; + std::string clean_path; + + // map for yaml file emit + std::unordered_map<std::string, std::string> path_map; +}; diff --git a/cmd/traffic_layout/file_system.cc b/cmd/traffic_layout/file_system.cc new file mode 100644 index 0000000..8730f93 --- /dev/null +++ b/cmd/traffic_layout/file_system.cc @@ -0,0 +1,186 @@ +/** @file + + A brief file description + + @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. +*/ + +// funciton for file system management +// including: make directory (with parents), copy directory (recursively), remove directory (recursively) + +#include "ts/ink_error.h" + +#include "file_system.h" + +#include <iostream> +#include <fstream> +#include <ftw.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <ts/I_Layout.h> + +// global variables for copy function +static std::string dst_root; +static std::string src_root; + +void +append_slash(std::string &path) +{ + if (path.back() != '/') + path.append("/"); +} + +void +remove_slash(std::string &path) +{ + if (path.back() == '/') + path.pop_back(); +} + +bool +exists(std::string const &dir) +{ + struct stat buffer; + int result = stat(dir.c_str(), &buffer); + return (!result) ? true : false; +} + +bool +is_directory(std::string const &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)) { + return true; + } + + int ret = 0, pos = 0, pos1 = 0; + if ((s[0] == '.') || (s[0] == '/')) { + pos1 = s.find("/") + 1; + } + pos = s.find("/", pos1); + + ret = mkdir(s.substr(0, pos).c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + pos1 = pos + 1; + // create directory one layer by one layer + while (1) { + pos = s.find("/", pos1); + if ((size_t)pos == s.npos) + break; + ret = mkdir(s.substr(0, pos).c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + pos1 = pos + 1; + } + if (ret) + return false; + else + return true; +} + +static int +remove_function(const char *path, const struct stat *s, int flag, struct FTW *f) +{ + int (*rm_func)(const char *); + + switch (flag) { + default: + rm_func = unlink; + break; + case FTW_DP: + rm_func = rmdir; + } + if (rm_func(path) == -1) { + ink_notice("Failed removing directory: %s\n", strerror(errno)); + return -1; + } + return 0; +} + +// remove directory recursively using nftw to iterate +bool +remove_directory(const std::string &dir) +{ + std::string path = dir; + remove_slash(path); + if (nftw(path.c_str(), remove_function, OPEN_MAX_FILE, FTW_DEPTH)) + return false; + else + return true; +} + +static int +copy_function(const char *src_path, const struct stat *sb, int flag) +{ + // src path no slash + std::string full_src_path = src_path; + if (full_src_path == src_root) { + if (!create_directory(dst_root)) + ink_fatal("create directory failed during copy"); + return 0; + } + std::string src_back = full_src_path.substr(src_root.size() + 1); + std::string dst_path = dst_root + src_back; + + switch (flag) { + case FTW_D: + // create directory for FTW_D type + if (!create_directory(dst_path)) + ink_fatal("create directory failed during copy"); + break; + case FTW_F: + // for files if bin executable mode, symlink + if (sb->st_mode == BIN_MODE) { + if (symlink(src_path, dst_path.c_str()) != 0) { + if (errno != EEXIST) + ink_warning("failed to create symbolic link - %s", strerror(errno)); + } + } else { + // for normal other files + std::ifstream src(src_path, std::ios::binary); + std::ofstream dst(dst_path, std::ios::binary); + dst << src.rdbuf(); + chmod(dst_path.c_str(), sb->st_mode); + } + } + return 0; +} + +// copy directory recursively using ftw to iterate +bool +copy_directory(const std::string &src, const std::string &dst) +{ + src_root = src; + dst_root = dst; + remove_slash(src_root); + append_slash(dst_root); + + if (ftw(src_root.c_str(), copy_function, OPEN_MAX_FILE)) + return false; + else + return true; +} diff --git a/cmd/traffic_layout/file_system.h b/cmd/traffic_layout/file_system.h new file mode 100644 index 0000000..093f60b --- /dev/null +++ b/cmd/traffic_layout/file_system.h @@ -0,0 +1,50 @@ +/** @file + + A brief file description + + @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. +*/ + +#pragma once + +#include <string> + +// binary executable mode (for symlink) +#define BIN_MODE 33261 + +// some system does not have OPEN_MAX defined +// size can be changed accordingly +#define OPEN_MAX_FILE 256 + +// 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(std::string const &dir); + +bool is_directory(std::string const &directory); + +// for file system +bool create_directory(const std::string &dir); + +bool remove_directory(const std::string &dir); + +bool copy_directory(const std::string &src, const std::string &dst); diff --git a/cmd/traffic_layout/traffic_layout.cc b/cmd/traffic_layout/traffic_layout.cc index b680145..36fdf2e 100644 --- a/cmd/traffic_layout/traffic_layout.cc +++ b/cmd/traffic_layout/traffic_layout.cc @@ -27,7 +27,12 @@ #include "ts/I_Layout.h" #include "I_RecProcess.h" #include "RecordsConfig.h" -#include "ts/runroot.cc" +#include "ts/runroot.h" +#include "engine.h" +#include "file_system.h" + +#include <iostream> +#include <fstream> // Command line arguments (parsing) struct CommandLineArgs { @@ -42,6 +47,9 @@ const ArgumentDescription argument_descriptions[] = { {"layout", 'l', "Show the layout (this is the default with no options given)", "T", &cl.layout, nullptr, nullptr}, {"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}, + {"init", 'i', "Initialize the ts_runroot sandbox (details in traffic_layout --init -h)", nullptr, nullptr, nullptr, nullptr}, + {"remove", 'r', "remove the ts_runroot sandbox (details in traffic_layout --remove -h)", nullptr, nullptr, nullptr, nullptr}, + {"force", '-', "force flag for init (details in traffic_layout --force -h)", nullptr, nullptr, nullptr, nullptr}, HELP_ARGUMENT_DESCRIPTION(), VERSION_ARGUMENT_DESCRIPTION(), @@ -175,9 +183,85 @@ produce_layout(bool json) } } +void +traffic_runroot(int argc, const char **argv) +{ + // runroot engine for operations + RunrootEngine engine; + engine._argc = argc; + int i = 0; + while (argv[i]) { + engine._argv.push_back(argv[i]); + ++i; + } + + // parse the command line & put into global variable + engine.runroot_parse(); + + // check to clean the runroot or not + if (engine.clean_runroot()) + return; + + // start the runroot creating stuff + std::string original_root = TS_BUILD_PREFIX; + append_slash(original_root); + + // setting up ts_runroot + // Use passed in parameter, else use ENV variable + std::string ts_runroot; + if (!engine.run_path.empty()) { + ts_runroot = engine.run_path; + } else { + if (getenv("TS_RUNROOT") != nullptr) { + ts_runroot = getenv("TS_RUNROOT"); + ink_notice("Using TS_RUNROOT Env variable"); + } else { + ink_fatal("Invalid ts_runroot path\n(please set command line path or Environment variable $TS_RUNROOT)"); + } + } + + // handle the ts_runroot + // ts runroot must be an accessible path + append_slash(ts_runroot); + std::ifstream check_file(ts_runroot + "runroot_path.yaml"); + if (check_file.good()) { + // if the path already ts_runroot, use it + ink_notice("Using existing TS_RUNROOT..."); + ink_notice("Please remove the old TS_RUNROOT if new runroot is needed \n(usage: traffic_runroot rm /path/...)"); + return; + } else if (exists(ts_runroot) && is_directory(ts_runroot)) { + ink_fatal("directory already exist"); + } + + // create new root & copy from original to new runroot. then fill in the map + engine.copy_runroot(original_root, ts_runroot); + + // create and emit to yaml file the key value pairs of path + std::ofstream yamlfile; + std::string yaml_path = ts_runroot + "runroot_path.yaml"; + yamlfile.open(yaml_path); + + for (auto it : engine.path_map) { + // out put key value pairs of path + yamlfile << it.first << ": " << it.second << std::endl; + } + ink_notice("\nTS runroot initialized"); + + return; +} + int -main(int /* argc ATS_UNUSED */, const char **argv) +main(int argc, const char **argv) { + // check for traffic_runroot operations + for (int i = 0; i < argc; i++) { + if (!strcmp(argv[i], "--init") || !strcmp(argv[i], "--remove") || !strcmp(argv[i], "-i") || !strcmp(argv[i], "-r") || + !strcmp(argv[i], "--force")) { + traffic_runroot(argc, argv); + exit(0); + } + } + // normal print out layout operation AppVersionInfo appVersionInfo; appVersionInfo.setup(PACKAGE_NAME, "traffic_layout", PACKAGE_VERSION, __DATE__, __TIME__, BUILD_MACHINE, BUILD_PERSON, ""); diff --git a/cmd/traffic_manager/traffic_manager.cc b/cmd/traffic_manager/traffic_manager.cc index b5e35fa..4080d37 100644 --- a/cmd/traffic_manager/traffic_manager.cc +++ b/cmd/traffic_manager/traffic_manager.cc @@ -27,7 +27,7 @@ #include "ts/ink_sock.h" #include "ts/ink_args.h" #include "ts/ink_syslog.h" -#include "ts/runroot.cc" +#include "ts/runroot.h" #include "WebMgmtUtils.h" #include "MgmtUtils.h" diff --git a/doc/admin-guide/plugins/cachekey.en.rst b/doc/admin-guide/plugins/cachekey.en.rst index 39f7c55..b36e6ee 100644 --- a/doc/admin-guide/plugins/cachekey.en.rst +++ b/doc/admin-guide/plugins/cachekey.en.rst @@ -167,7 +167,7 @@ All parameters are optional, and if not used, their default values are as mentio Cache key elements separator ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -* ``--separator=<string>`` - the cache key is constructed by extracting elements from HTTP URI and headers or by using the UA classifiers and they are appended during the key construction and separated by ``/`` (by default). This options allows to override the dafault separator to any string (including an empty string) +* ``--separator=<string>`` - the cache key is constructed by extracting elements from HTTP URI and headers or by using the UA classifiers and they are appended during the key construction and separated by ``/`` (by default). This options allows to override the default separator to any string (including an empty string). Detailed examples and troubleshooting diff --git a/doc/appendices/command-line/traffic_layout.en.rst b/doc/appendices/command-line/traffic_layout.en.rst new file mode 100644 index 0000000..bd790f1 --- /dev/null +++ b/doc/appendices/command-line/traffic_layout.en.rst @@ -0,0 +1,73 @@ +.. 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:: ../../common.defs + +.. _traffic_cop: + +traffic_layout +***************** + +Description +============= +Document for the special functionality of ``runroot`` inside ``traffic_layout`` program +This feature is for the setup of traffic server runroot. +It will create a runtime sandbox for any program of traffic server to run under. + +1. Use program traffic_layout to create sandbox. +2. Run any program use the sandbox with ``--run-root=/path`` or ``--run-root`` + +How it works: +-------------- + +1. Create a sandbox directory for programs to run under +2. Copy and symlink build time directories and files to sandbox, allowing users to modify freely. +3. Emit a yaml file that defines layout structure for other programs to use. + +Options: +============= +1. Initialize the runroot: :: + + traffic_layout --init /path/to/sandbox/ + + If no path is found, it will find the ENV variable $TS_RUNROOT + +2. Remove the runroot: :: + + traffic_layout --remove /path/to/sandbox/ + + Remove the sandbox we created(check yaml file). + If no path provided, it will find the ENV variable $TS_RUNROOT. + If $TS_RUNROOT not found, it will find bin executing path & current working directory. + +3. Force flag for creating: :: + + traffic_runroot --force --init /path/to/sandbox + + Force create sandbox and overwrite existing directory + +Usage for other programs: +============================================== +Use pass in path or use Environment variable $TS_RUNROOT. +If both not found, program will try to find bin path & current woring directory. :: + + trafficserver --run-root=/path/to/runroot + trafficserver --run-root + +Notes +========== +Path to sandbox must be an absolute path. diff --git a/lib/ts/Makefile.am b/lib/ts/Makefile.am index efd87d5..5880f5c 100644 --- a/lib/ts/Makefile.am +++ b/lib/ts/Makefile.am @@ -178,6 +178,8 @@ libtsutil_la_SOURCES = \ Regression.cc \ Regression.h \ Result.h \ + runroot.cc \ + runroot.h \ signals.cc \ signals.h \ SimpleTokenizer.h \ diff --git a/lib/ts/runroot.cc b/lib/ts/runroot.cc index ef49ce0..4586f79 100644 --- a/lib/ts/runroot.cc +++ b/lib/ts/runroot.cc @@ -38,19 +38,17 @@ datadir, libexecdir, libdir, runtimedir, infodir, cachedir. */ #include "ts/ink_error.h" +#include "runroot.h" #include <vector> -#include <string> #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, bool json = false) +std::string +check_parent_path(const std::string &path, bool json) { std::string whole_path = path; if (whole_path.back() == '/') @@ -81,7 +79,7 @@ is_directory(const char *directory) // handler for ts runroot void -runroot_handler(const char **argv, bool json = false) +runroot_handler(const char **argv, bool json) { std::string command = {}; std::string arg = {}; diff --git a/lib/ts/runroot.h b/lib/ts/runroot.h new file mode 100644 index 0000000..ee0118b --- /dev/null +++ b/lib/ts/runroot.h @@ -0,0 +1,35 @@ +/** @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. +*/ + +// runroot handler for TS_RUNROOT +// detailed information in runroot.cc + +#pragma once + +#include <string> + +#define MAX_CWD_LEN 1024 + +std::string check_parent_path(const std::string &path, bool json = false); + +void runroot_handler(const char **argv, bool json = false); diff --git a/mgmt/utils/MgmtSocket.cc b/mgmt/utils/MgmtSocket.cc index 9c372a8..bbb0c69 100644 --- a/mgmt/utils/MgmtSocket.cc +++ b/mgmt/utils/MgmtSocket.cc @@ -23,7 +23,7 @@ #include "ts/ink_platform.h" #include "ts/ink_assert.h" -#include <ts/ink_cap.cc> +#include "ts/ink_cap.h" #include "MgmtSocket.h" #if HAVE_UCRED_H diff --git a/plugins/experimental/ts_lua/ts_lua.c b/plugins/experimental/ts_lua/ts_lua.c index 59cfb9e..554a327 100644 --- a/plugins/experimental/ts_lua/ts_lua.c +++ b/plugins/experimental/ts_lua/ts_lua.c @@ -194,6 +194,8 @@ ts_lua_remap_plugin_init(void *ih, TSHttpTxn rh, TSRemapRequestInfo *rri) lua_getglobal(L, (remap ? TS_LUA_FUNCTION_REMAP : TS_LUA_FUNCTION_OS_RESPONSE)); if (lua_type(L, -1) != LUA_TFUNCTION) { + lua_pop(L, 1); + ts_lua_destroy_http_ctx(http_ctx); TSMutexUnlock(main_ctx->mutexp); return TSREMAP_NO_REMAP; } diff --git a/proxy/Main.cc b/proxy/Main.cc index 12f83df..32a8dd3 100644 --- a/proxy/Main.cc +++ b/proxy/Main.cc @@ -37,7 +37,7 @@ #include "ts/ink_stack_trace.h" #include "ts/ink_syslog.h" #include "ts/hugepages.h" -#include "ts/runroot.cc" +#include "ts/runroot.h" #include "api/ts/ts.h" // This is sadly needed because of us using TSThreadInit() for some reason. diff --git a/proxy/http2/Makefile.am b/proxy/http2/Makefile.am index 3124e46..848b71c 100644 --- a/proxy/http2/Makefile.am +++ b/proxy/http2/Makefile.am @@ -89,7 +89,7 @@ test_HPACK_LDADD = \ $(top_builddir)/mgmt/libmgmt_p.la \ $(top_builddir)/proxy/shared/libUglyLogStubs.a \ @LIBTCL@ \ - @HWLOC_LIBS@ @LIBCAP@ + @HWLOC_LIBS@ test_HPACK_SOURCES = \ test_HPACK.cc \ diff --git a/proxy/logcat.cc b/proxy/logcat.cc index 98f8c82..58144ca 100644 --- a/proxy/logcat.cc +++ b/proxy/logcat.cc @@ -24,7 +24,7 @@ #include "ts/ink_platform.h" #include "ts/ink_args.h" #include "ts/I_Layout.h" -#include "ts/runroot.cc" +#include "ts/runroot.h" #define PROGRAM_NAME "traffic_logcat" #define MAX_LOGBUFFER_SIZE 65536 diff --git a/proxy/logstats.cc b/proxy/logstats.cc index 8007a42..6ab7e93 100644 --- a/proxy/logstats.cc +++ b/proxy/logstats.cc @@ -29,7 +29,7 @@ #include "ts/HashFNV.h" #include "ts/ink_args.h" #include "ts/MatcherUtils.h" -#include "ts/runroot.cc" +#include "ts/runroot.h" // Includes and namespaces etc. #include "LogStandalone.cc" diff --git a/tests/gold_tests/basic/runroot-layout.test.py b/tests/gold_tests/basic/runroot-layout.test.py new file mode 100644 index 0000000..b1846c9 --- /dev/null +++ b/tests/gold_tests/basic/runroot-layout.test.py @@ -0,0 +1,69 @@ +''' +''' +# 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. + +import os +import sys +import time + +Test.Summary = ''' +Test that use for runroot from traffic_layout is all functional. +''' +Test.ContinueOnFail = True + +p = Test.MakeATSProcess("ts") +path = os.path.join(p.Env['TS_ROOT'], "runroot") + +# normal init from pass in path +tr = Test.AddTestRun("Test traffic_layout init") +tr.Processes.Default.Command = "$ATS_BIN/traffic_layout --init " + path +tr.Processes.Default.ReturnCode = 0 +d = tr.Disk.Directory(path) +d.Exists = True +f = tr.Disk.File(os.path.join(path, "runroot_path.yaml")) +f.Exists = True + +# remove from pass in path +tr = Test.AddTestRun("Test traffoc_layout remove") +tr.Processes.Default.Command = "$ATS_BIN/traffic_layout --remove " + path +tr.Processes.Default.ReturnCode = 0 +d = tr.Disk.Directory(path) +d.Exists = False +f = tr.Disk.File(os.path.join(path, "runroot_path.yaml")) +f.Exists = False + +path += '/' + +#use env variable to init +tr = Test.AddTestRun("Test traffic_layout ENV init") +tr.Processes.Default.Env["TS_RUNROOT"] = path +tr.Processes.Default.Command = "$ATS_BIN/traffic_layout --init" +tr.Processes.Default.ReturnCode = 0 +d = tr.Disk.Directory(path) +d.Exists = True +f = tr.Disk.File(os.path.join(path, "runroot_path.yaml")) +f.Exists = True + +#use env variable to remove +tr = Test.AddTestRun("Test traffic_layout ENV remove") +tr.Processes.Default.Env["TS_RUNROOT"] = path +tr.Processes.Default.Command = "$ATS_BIN/traffic_layout --remove" +tr.Processes.Default.ReturnCode = 0 +d = tr.Disk.Directory(path) +d.Exists = False +f = tr.Disk.File(os.path.join(path, "runroot_path.yaml")) +f.Exists = False \ No newline at end of file -- To stop receiving notification emails like this one, please contact "commits@trafficserver.apache.org" <commits@trafficserver.apache.org>.