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/01/12 16:03:41 UTC

[trafficserver] branch 7.1.x updated (8595196 -> 2d1159e)

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

zwoop pushed a change to branch 7.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git.


    from 8595196  Bump version to v7.1.3
     new 10c22e0  Switch traffic_top to standard argument processing.
     new fe826e7  Add records configuration support to traffic_top.
     new c6a741e  Add records configuration support to traffic_ctl.
     new 08a5dcc  New layout structure with std string & basic string view
     new b2b5f45  Added traffic_runroot feature to generate sandbox for programs to run
     new 0f1bfdd  Fix traffic_layout to not add messages to --json
     new 4ba94ef  Add check on Environment input to validate it exists
     new 7131096  add openssh flags that we need to build plugins with custom SSL correctly
     new 2d1159e  Manual update to APIs that changed

The 9 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .gitignore                                         |   4 +
 cmd/traffic_cop/traffic_cop.cc                     |  51 ++---
 cmd/traffic_crashlog/traffic_crashlog.cc           |   7 +-
 cmd/traffic_ctl/Makefile.am                        |   7 +-
 cmd/traffic_ctl/traffic_ctl.cc                     |  17 +-
 cmd/traffic_layout/traffic_layout.cc               |  34 ++--
 cmd/traffic_manager/metrics.cc                     |   2 +-
 cmd/traffic_manager/traffic_manager.cc             |  45 ++---
 cmd/traffic_top/Makefile.am                        |   6 +
 cmd/traffic_top/stats.h                            |   4 +-
 cmd/traffic_top/traffic_top.cc                     |  81 ++++----
 iocore/cache/Store.cc                              |  13 +-
 iocore/net/SSLConfig.cc                            |  10 +-
 lib/cppapi/Transaction.cc                          |   4 +-
 lib/records/I_RecCore.h                            |  27 ++-
 lib/records/RecCore.cc                             |  63 ++++---
 lib/ts/I_Layout.h                                  |  65 ++++---
 lib/ts/Layout.cc                                   | 206 ++++++++++++---------
 lib/ts/Ptr.h                                       |   2 -
 lib/ts/ink_args.cc                                 |   6 +-
 lib/ts/ink_args.h                                  |   4 +
 lib/ts/ink_memory.h                                |  10 +
 lib/ts/runroot.cc                                  | 144 ++++++++++++++
 lib/ts/unit-tests/test_layout.cpp                  |  89 +++++++++
 mgmt/Alarms.cc                                     |   2 +-
 mgmt/FileManager.cc                                |   2 +-
 mgmt/LocalManager.cc                               |  24 +--
 mgmt/ProcessManager.cc                             |   9 +-
 mgmt/Rollback.cc                                   |   4 +-
 mgmt/api/CoreAPIRemote.cc                          |   2 +-
 mgmt/api/NetworkUtilsRemote.cc                     |   4 +-
 proxy/Crash.cc                                     |   2 +-
 proxy/InkAPI.cc                                    |  15 +-
 proxy/Main.cc                                      |  42 +++--
 proxy/Plugin.cc                                    |   3 +-
 proxy/http/remap/RemapConfig.cc                    |   2 +-
 proxy/logcat.cc                                    |   5 +-
 proxy/logging/LogConfig.cc                         |   2 +-
 proxy/logging/LogStandalone.cc                     |   6 +-
 proxy/logstats.cc                                  |  13 +-
 tests/gold_tests/autest-site/build.test.ext        |  53 ++++++
 tests/gold_tests/autest-site/conditions.test.ext   |  65 +++++++
 .../autest-site/httpbin.test.ext}                  |  39 ++--
 tests/gold_tests/autest-site/init.cli.ext          |  15 +-
 tests/gold_tests/autest-site/microserver.test.ext  | 150 ++++++++++-----
 tests/gold_tests/autest-site/ports.py              |  21 ++-
 tests/gold_tests/autest-site/setup.cli.ext         |  53 +++++-
 .../gold_tests/autest-site/trafficserver.test.ext  |   6 +-
 .../autest-site/trafficserver_plugins.test.ext     |  13 +-
 tests/tools/microServer/uWServer.py                | 100 +++++++---
 tools/tsxs.in                                      |  12 +-
 51 files changed, 1095 insertions(+), 470 deletions(-)
 create mode 100644 lib/ts/runroot.cc
 create mode 100644 lib/ts/unit-tests/test_layout.cpp
 create mode 100644 tests/gold_tests/autest-site/build.test.ext
 create mode 100644 tests/gold_tests/autest-site/conditions.test.ext
 copy tests/{tools/sessionvalidation/response.py => gold_tests/autest-site/httpbin.test.ext} (50%)

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

[trafficserver] 09/09: Manual update to APIs that changed

Posted by zw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch 7.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit 2d1159ea6d10392ae8fc3a6d2a713a7521694138
Author: Jason Kenny <dr...@live.com>
AuthorDate: Tue Jan 9 17:09:38 2018 -0600

    Manual update to APIs that changed
    
    Cherry picks broke the code. Fixes to stuff that did not merge correctly or are part of other cherry picks that bring in other code we don't want in 7.1
    manual fixes and addition to test extensions to allow tests to work
    manual updates traffic_top
---
 .gitignore                                         |   4 +
 cmd/traffic_top/traffic_top.cc                     |  22 +--
 lib/records/RecCore.cc                             |   2 +-
 lib/ts/Ptr.h                                       |   2 -
 lib/ts/ink_args.cc                                 |   1 +
 mgmt/ProcessManager.cc                             |   3 +-
 tests/gold_tests/autest-site/build.test.ext        |  53 ++++++++
 tests/gold_tests/autest-site/conditions.test.ext   |  65 +++++++++
 .../autest-site/{init.cli.ext => httpbin.test.ext} |  34 ++++-
 tests/gold_tests/autest-site/init.cli.ext          |  15 ++-
 tests/gold_tests/autest-site/microserver.test.ext  | 150 ++++++++++++++-------
 tests/gold_tests/autest-site/ports.py              |  21 ++-
 tests/gold_tests/autest-site/setup.cli.ext         |  53 ++++++--
 .../gold_tests/autest-site/trafficserver.test.ext  |   6 +-
 .../autest-site/trafficserver_plugins.test.ext     |  13 +-
 tests/tools/microServer/uWServer.py                | 100 ++++++++++----
 16 files changed, 418 insertions(+), 126 deletions(-)

diff --git a/.gitignore b/.gitignore
index d9bd7bd..f3b6201 100644
--- a/.gitignore
+++ b/.gitignore
@@ -164,3 +164,7 @@ tools/trafficserver.pc
 BUILDS
 DEBUG
 RELEASE
+
+# autest
+tests/env-test/
+tests/_sandbox/
diff --git a/cmd/traffic_top/traffic_top.cc b/cmd/traffic_top/traffic_top.cc
index e217cee..99996ff 100644
--- a/cmd/traffic_top/traffic_top.cc
+++ b/cmd/traffic_top/traffic_top.cc
@@ -54,6 +54,7 @@
 #include "stats.h"
 
 #include "ts/I_Layout.h"
+#include "ts/ink_args.h"
 #include "I_RecProcess.h"
 #include "RecordsConfig.h"
 
@@ -424,29 +425,16 @@ main(int argc, const char **argv)
     break;
   }
 
-  Layout::create();
-  RecProcessInit(RECM_STAND_ALONE, nullptr /* diags */);
-  LibRecordsConfigInit();
-
-  string url = "";
+  case 1:
 #if HAS_CURL
     url = file_arguments[0];
 #else
     usage(argument_descriptions, countof(argument_descriptions), USAGE);
 #endif
+    break;
 
-    ats_scoped_str rundir(RecConfigReadRuntimeDir());
-
-    if (TS_ERR_OKAY != TSInit(rundir, static_cast<TSInitOptionT>(TS_MGMT_OPT_NO_EVENTS | TS_MGMT_OPT_NO_SOCK_TESTS))) {
-#if HAS_CURL
-      fprintf(stderr, "Error: missing URL on command line or error connecting to the local manager\n");
-#else
-      fprintf(stderr, "Error: error connecting to the local manager\n");
-#endif
-      usage();
-    }
-  } else {
-    url = argv[optind];
+  default:
+    usage(argument_descriptions, countof(argument_descriptions), USAGE);
   }
 
   Stats stats(url);
diff --git a/lib/records/RecCore.cc b/lib/records/RecCore.cc
index 0d5cea2..4fa9593 100644
--- a/lib/records/RecCore.cc
+++ b/lib/records/RecCore.cc
@@ -212,7 +212,7 @@ RecCoreInit(RecModeT mode_type, Diags *_diags)
   if ((mode_type == RECM_SERVER) || (mode_type == RECM_STAND_ALONE)) {
     bool file_exists = true;
 
-    ink_mutex_init(&g_rec_config_lock);
+    ink_mutex_init(&g_rec_config_lock, "");
 
     g_rec_config_fpath = ats_stringdup(RecConfigReadConfigPath(nullptr, REC_CONFIG_FILE REC_SHADOW_EXT));
     if (RecFileExists(g_rec_config_fpath) == REC_ERR_FAIL) {
diff --git a/lib/ts/Ptr.h b/lib/ts/Ptr.h
index fdae759..d3ac27a 100644
--- a/lib/ts/Ptr.h
+++ b/lib/ts/Ptr.h
@@ -111,10 +111,8 @@ public:
 
   T *operator->() const { return (m_ptr); }
   T &operator*() const { return (*m_ptr); }
-
   // Making this explicit avoids unwanted conversions.  See https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Safe_bool .
   explicit operator bool() const { return m_ptr != nullptr; }
-
   int
   operator==(const T *p)
   {
diff --git a/lib/ts/ink_args.cc b/lib/ts/ink_args.cc
index bd973e3..37b4be3 100644
--- a/lib/ts/ink_args.cc
+++ b/lib/ts/ink_args.cc
@@ -229,6 +229,7 @@ process_args_ex(const AppVersionInfo *appinfo, const ArgumentDescription *argume
           }
           break;
         }
+      }
       if (i >= n_argument_descriptions) {
         return false;
       }
diff --git a/mgmt/ProcessManager.cc b/mgmt/ProcessManager.cc
index 3addf5b..b0c9be0 100644
--- a/mgmt/ProcessManager.cc
+++ b/mgmt/ProcessManager.cc
@@ -206,7 +206,8 @@ ProcessManager::initLMConnection()
   }
 
   if ((connect(local_manager_sockfd, (struct sockaddr *)&serv_addr, servlen)) < 0) {
-    mgmt_fatal(errno, "[ProcessManager::initLMConnection] failed to connect management socket '%s'\n", (const char *)sockpath);
+    mgmt_fatal(errno, "[ProcessManager::initLMConnection] failed to connect management socket '%s'\n",
+               (const char *)sockpath.c_str());
   }
 
   data_len          = sizeof(pid_t);
diff --git a/tests/gold_tests/autest-site/build.test.ext b/tests/gold_tests/autest-site/build.test.ext
new file mode 100644
index 0000000..ef8aa42
--- /dev/null
+++ b/tests/gold_tests/autest-site/build.test.ext
@@ -0,0 +1,53 @@
+'''
+Build random code for running as part of a test
+'''
+#  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 re
+import autest.common.is_a as is_a
+
+
+def Build(Test, target, sources, CPPFLAGS='', LDFLAGS='', LIBS='', CC=None):
+    if is_a.OrderedSequence(sources):
+        sources = " ".join(sources)
+    tr = Test.AddTestRun("Build", "Build test files: {0}".format(sources))
+    vars = Test.ComposeVariables()
+    if CC is None:
+        cc = vars.CXX
+    else:
+        cc = CC
+
+    tr.Processes.Default.Command = '{cc} -o {target} {cppflags} {sources} {ldflags} {libs}'.format(
+        cppflags="{0} {1}".format(vars.CPPFLAGS, CPPFLAGS),
+        ldflags="{0} {1}".format(vars.LDFLAGS, LDFLAGS),
+        libs="{0} {1}".format(vars.LIBS, LIBS),
+        target=target,
+        sources=sources,
+        cc=cc
+    )
+    tr.Processes.Default.ForceUseShell = True
+    tr.ReturnCode = 0
+    tr.Streams.All = Testers.ExcludesExpression(
+        r'(\A|\s)error?\s?(([?!: ])|(\.\s))\D',
+        "Build should not contain errors",
+        reflags=re.IGNORECASE
+    )
+
+    return tr
+
+
+ExtendTest(Build, name="Build")
diff --git a/tests/gold_tests/autest-site/conditions.test.ext b/tests/gold_tests/autest-site/conditions.test.ext
new file mode 100644
index 0000000..9cac02f
--- /dev/null
+++ b/tests/gold_tests/autest-site/conditions.test.ext
@@ -0,0 +1,65 @@
+'''
+'''
+#  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.
+
+def HasOpenSSLVersion(self, version):
+    return self.EnsureVersion(["openssl","version"],min_version=version)
+
+def HasCurlFeature(self, feature):
+
+    def default(output):
+        FEATURE_TAG = 'Features:'
+        tag = feature.lower()
+        for line in output.splitlines():
+            # look for line with starting with the Features
+            if line.startswith(FEATURE_TAG):
+                # get a features and lower case then for safety
+                line = line[len(FEATURE_TAG):].lower()
+                tokens = line.split()
+                for t in tokens:
+                    if t == tag:
+                        return True
+        return False
+
+    return self.CheckOutput(
+        ['curl', '--version'],
+        default,
+        "Curl needs to support feature: {feature}".format(feature=feature)
+    )
+
+
+def HasATSFeature(self, feature):
+
+    val = self.Variables.get(feature, None)
+
+    return self.Condition(
+        lambda: val == True,
+        "ATS feature not enabled: {feature}".format(feature=feature)
+    )
+
+#test if a plugin exists in the libexec folder
+def PluginExists(self, pluginname):
+
+    path = os.path.join(self.Variables.PLUGINDIR, pluginname)
+    return self.Condition(lambda: os.path.isfile(path) == True, path + " not found." )
+
+
+ExtendCondition(HasOpenSSLVersion)
+ExtendCondition(HasATSFeature)
+ExtendCondition(HasCurlFeature)
+ExtendCondition(PluginExists)
+
diff --git a/tests/gold_tests/autest-site/init.cli.ext b/tests/gold_tests/autest-site/httpbin.test.ext
similarity index 50%
copy from tests/gold_tests/autest-site/init.cli.ext
copy to tests/gold_tests/autest-site/httpbin.test.ext
index cc3a1a6..6e2dd86 100644
--- a/tests/gold_tests/autest-site/init.cli.ext
+++ b/tests/gold_tests/autest-site/httpbin.test.ext
@@ -16,12 +16,32 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 
-import os
+from ports import get_port
 
-import sys
-if sys.version_info<(3,5,0):
-  host.WriteError("You need python 3.5 or later to run these tests\n",show_stack=False)
 
-Settings.path_argument(["--ats-bin"],
-                        required=True,
-                        help="A user provided directory to ATS bin")
\ No newline at end of file
+def MakeHttpBinServer(obj, name, port=False, ip=False, delay=False, public_ip=False, ssl=False, options={}):
+    data_dir = os.path.join(obj.RunDirectory, name)
+    # create Process
+    p = obj.Processes.Process(name)
+    if (port == False):
+        port = get_port(p, "Port")
+    if (ip == False):
+        ip = '127.0.0.1'
+    if (delay == False):
+        delay = 0
+
+    command = "gunicorn -b {0}:{1} httpbin:app".format(ip, port)
+    for flag, value in options.items():
+        command += " {} {}".format(flag, value)
+
+    # create process
+    p.Command = command
+    p.Setup.MakeDir(data_dir)
+    p.Variables.DataDir = data_dir
+    p.Ready = When.PortOpen(port, ip)
+    p.ReturnCode = Any(None, 0)
+
+    return p
+
+
+ExtendTest(MakeHttpBinServer, name="MakeHttpBinServer")
diff --git a/tests/gold_tests/autest-site/init.cli.ext b/tests/gold_tests/autest-site/init.cli.ext
index cc3a1a6..903f12f 100644
--- a/tests/gold_tests/autest-site/init.cli.ext
+++ b/tests/gold_tests/autest-site/init.cli.ext
@@ -19,9 +19,16 @@
 import os
 
 import sys
-if sys.version_info<(3,5,0):
-  host.WriteError("You need python 3.5 or later to run these tests\n",show_stack=False)
+if sys.version_info < (3, 5, 0):
+    host.WriteError(
+        "You need python 3.5 or later to run these tests\n", show_stack=False)
+
+autest_version ="1.4.2"
+if AuTestVersion() < autest_version:
+    host.WriteError(
+        "Tests need AuTest version {ver} or better\n Please update AuTest:\n  pip install --upgrade autest\n".format(ver=autest_version), show_stack=False)
+
 
 Settings.path_argument(["--ats-bin"],
-                        required=True,
-                        help="A user provided directory to ATS bin")
\ No newline at end of file
+                       required=True,
+                       help="A user provided directory to ATS bin")
diff --git a/tests/gold_tests/autest-site/microserver.test.ext b/tests/gold_tests/autest-site/microserver.test.ext
index 4c39843..4ab6783 100644
--- a/tests/gold_tests/autest-site/microserver.test.ext
+++ b/tests/gold_tests/autest-site/microserver.test.ext
@@ -19,103 +19,157 @@
 from ports import get_port
 import json
 
-def addMethod(self,testName, request_header, functionName):
+
+def addMethod(self, testName, request_header, functionName):
     return
 
 # creates the full request or response block using headers and message data
-def httpObject(self,header,data):
-    r=dict()
-    r["timestamp"]=""
-    r["headers"]=header
-    r["body"]=data
+
+
+def httpObject(self, header, data):
+    r = dict()
+    r["timestamp"] = ""
+    r["headers"] = header
+    r["body"] = data
     return r
 
 # addResponse adds customized response with respect to request_header. request_header and response_header are both dictionaries
-def addResponse(self,filename, testName, request_header, response_header):
+
+
+def addResponse(self, filename, testName, request_header, response_header):
 
     txn = dict()
     txn["timestamp"] = ""
     txn["uuid"] = testName
     txn["request"] = request_header
     txn["response"] = response_header
-    print("data dir",self.Variables.DataDir)
-    addTransactionToSession(txn,filename)
-    absFilepath=os.path.abspath(filename)
-    self.Setup.CopyAs(absFilepath,self.Variables.DataDir)
-    return
 
+    addTransactionToSession(txn, filename)
+    absFilepath = os.path.abspath(filename)
+    self.Setup.CopyAs(absFilepath, self.Variables.DataDir)
+    return
 
+def getHeaderFieldVal(request_header, field):
+    requestline = request_header["headers"].split("\r\n")[0]
+    requestline = requestline.split(" ")[1]
+    field = field+':'
+    valField = request_header["headers"].split(field,1);
+    val=""
+    if len(valField)>1:
+            field_v = valField[1].split("\r\n",1)
+            if len(field_v)>0:
+                val = field_v[0].strip()
+    return val
 
 # addResponse adds customized response with respect to request_header. request_header and response_header are both dictionaries
-def addResponse(self,filename, request_header, response_header):
+def addResponse(self, filename, request_header, response_header):
     requestline = request_header["headers"].split("\r\n")[0]
-    requestline = requestline.split(" ")[1]
-    resourceLocation = requestline.split("/",1)
-    if len(resourceLocation)>1:
-        rl = resourceLocation[1]
-    else:
-        rl = ""
+    host_ = ""
+    path_ = ""
+    if requestline:
+        url_part = requestline.split(" ")
+        if len(url_part)>1:
+            if url_part[1].startswith("http"):
+                path_ = url_part[1].split("/",2)[2]
+                host_,path_ = path_.split("/",1)
+            else:
+                path_ = url_part[1].split("/",1)[1]
+
+    kpath = ""
+    #print("Format of lookup key",self.Variables.lookup_key)
+    
+    argsList = []
+    keyslist = self.Variables.lookup_key.split("}")
+    for keystr in keyslist:
+        if keystr == '{PATH':
+            kpath = kpath+path_
+            continue
+        if keystr == '{HOST':
+            kpath = kpath + host_
+            continue
+        if keystr == '': #empty
+            continue
+        stringk = keystr.replace("{%","")
+        argsList.append(stringk)
+    KeyList = []
+    for argsL in argsList:
+        field_val = getHeaderFieldVal(request_header,argsL)
+        if field_val!=None:
+            KeyList.append(field_val)
+    rl = "".join(KeyList)+kpath
     txn = dict()
     txn["timestamp"] = ""
     txn["uuid"] = rl
     txn["request"] = request_header
     txn["response"] = response_header
     absFilepath = os.path.join(self.Variables.DataDir, filename)
-    addTransactionToSession(txn,absFilepath)
-    #absFilepath=os.path.abspath(filename)
-    #self.Setup.CopyAs(absFilepath,self.Variables.DataDir)
+    addTransactionToSession(txn, absFilepath)
+    # absFilepath=os.path.abspath(filename)
+    # self.Setup.CopyAs(absFilepath,self.Variables.DataDir)
     return
 
-#adds transaction in json format to the specified file
-def addTransactionToSession(txn,JFile):
-    jsondata=None
+# adds transaction in json format to the specified file
+
+
+def addTransactionToSession(txn, JFile):
+    jsondata = None
     if not os.path.exists(os.path.dirname(JFile)):
         os.makedirs(os.path.dirname(JFile))
     if os.path.exists(JFile):
-        jf = open(JFile,'r')
+        jf = open(JFile, 'r')
         jsondata = json.load(jf)
 
     if jsondata == None:
         jsondata = dict()
-        jsondata["version"]='0.1'
-        jsondata["timestamp"]="1234567890.098"
-        jsondata["encoding"]="url_encoded"
-        jsondata["txns"]=list()
+        jsondata["version"] = '0.1'
+        jsondata["timestamp"] = "1234567890.098"
+        jsondata["encoding"] = "url_encoded"
+        jsondata["txns"] = list()
         jsondata["txns"].append(txn)
     else:
         jsondata["txns"].append(txn)
-    with open(JFile,'w+') as jf:
+    with open(JFile, 'w+') as jf:
         jf.write(json.dumps(jsondata))
 
 
-#make headers with the key and values provided
-def makeHeader(self,requestString, **kwargs):
-    headerStr = requestString+'\r\n'
-    for k,v in kwargs.iteritems():
-        headerStr += k+': '+v+'\r\n'
-    headerStr = headerStr+'\r\n'
+# make headers with the key and values provided
+def makeHeader(self, requestString, **kwargs):
+    headerStr = requestString + '\r\n'
+    for k, v in kwargs.iteritems():
+        headerStr += k + ': ' + v + '\r\n'
+    headerStr = headerStr + '\r\n'
     return headerStr
 
 
-def MakeOriginServer(obj, name,public_ip=False,options={}):
-    server_path= os.path.join(obj.Variables.AtsTestToolsDir,'microServer/uWServer.py')
+def MakeOriginServer(obj, name, port=False, ip=False, delay=False, ssl=False, lookup_key='{PATH}', options={}):
+    server_path = os.path.join(obj.Variables.AtsTestToolsDir, 'microServer/uWServer.py')
     data_dir = os.path.join(obj.RunDirectory, name)
     # create Process
     p = obj.Processes.Process(name)
-    port=get_port(p,"Port")
-    command = "python3 {0} --data-dir {1} --port {2} --public {3} -m test".format(server_path, data_dir, port, public_ip)
-    for flag,value in options.items() :
-        command += " {} {}".format(flag,value)
+    if (port == False):
+        port = get_port(p, "Port")
+    if (ip == False):
+        ip = '127.0.0.1'
+    if (delay == False):
+        delay = 0
+    command = "python3 {0} --data-dir {1} --port {2} --ip_address {3} --delay {4} -m test --ssl {5} --lookupkey '{6}'".format(
+        server_path, data_dir, port, ip, delay, ssl,lookup_key)
+    for flag, value in options.items():
+        command += " {} {}".format(flag, value)
 
     # create process
     p.Command = command
     p.Setup.MakeDir(data_dir)
     p.Variables.DataDir = data_dir
-    p.Ready = When.PortOpen(port)
-    AddMethodToInstance(p,addResponse)
-    AddMethodToInstance(p,addTransactionToSession)
+    p.Variables.lookup_key = lookup_key
+    p.Ready = When.PortOpen(port, ip)
+    p.ReturnCode = Any(None,0)
+    AddMethodToInstance(p, addResponse)
+    AddMethodToInstance(p, addTransactionToSession)
 
     return p
 
-AddTestRunSet(MakeOriginServer,name="MakeOriginServer")
-AddTestRunSet(MakeOriginServer,name="MakeOrigin")
+
+ExtendTest(MakeOriginServer, name="MakeOriginServer")
+ExtendTest(MakeOriginServer, name="MakeOrigin")
+
diff --git a/tests/gold_tests/autest-site/ports.py b/tests/gold_tests/autest-site/ports.py
index 1f26e7e..7932be8 100644
--- a/tests/gold_tests/autest-site/ports.py
+++ b/tests/gold_tests/autest-site/ports.py
@@ -19,6 +19,7 @@
 import socket
 import subprocess
 import os
+import platform
 
 import hosts.output as host
 
@@ -59,11 +60,21 @@ def setup_port_queue(amount=1000):
         return
     try:
         # some docker setups don't have sbin setup correctly
-        new_env= os.environ.copy()
-        new_env['PATH']="/sbin:/usr/sbin:"+new_env['PATH']
-        dmin, dmax = subprocess.check_output(
-            ["sysctl", "net.ipv4.ip_local_port_range"],
-            env=new_env
+        new_env = os.environ.copy()
+        new_env['PATH'] = "/sbin:/usr/sbin:" + new_env['PATH']
+        if 'Darwin' == platform.system():
+            dmin = subprocess.check_output(
+                ["sysctl", "net.inet.ip.portrange.first"],
+                env=new_env
+            ).decode().split(":")[1].split()[0]
+            dmax = subprocess.check_output(
+                ["sysctl", "net.inet.ip.portrange.last"],
+                env=new_env
+            ).decode().split(":")[1].split()[0]
+        else:
+            dmin, dmax = subprocess.check_output(
+                ["sysctl", "net.ipv4.ip_local_port_range"],
+                env=new_env
             ).decode().split("=")[1].split()
         dmin = int(dmin)
         dmax = int(dmax)
diff --git a/tests/gold_tests/autest-site/setup.cli.ext b/tests/gold_tests/autest-site/setup.cli.ext
index 6f38a87..7fe26f7 100644
--- a/tests/gold_tests/autest-site/setup.cli.ext
+++ b/tests/gold_tests/autest-site/setup.cli.ext
@@ -16,34 +16,67 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 
-import json, subprocess
+import json
+import subprocess
 import pprint
 
 if Arguments.ats_bin is not None:
     # Add environment variables
     ENV['ATS_BIN'] = Arguments.ats_bin
-    #if Arguments.ats_bin not in ENV['PATH']:
-        #ENV['PATH'] = Arguments.ats_bin + ':' + ENV['PATH']
-    
+
 if ENV['ATS_BIN'] is not None:
     # Add variables for Tests
     traffic_layout = os.path.join(ENV['ATS_BIN'], "traffic_layout")
+    tsxs = os.path.join(ENV['ATS_BIN'], "tsxs")
     if not os.path.isdir(ENV['ATS_BIN']):
         host.WriteError("--ats-bin requires a directory", show_stack=False)
+    # setting up data from traffic_layout
+    # this is getting layout structure
     if not os.path.isfile(traffic_layout):
         host.WriteError("traffic_layout is not found. Aborting tests - Bad build or install.", show_stack=False)
     try:
         out = subprocess.check_output([traffic_layout, "--json"])
     except subprocess.CalledProcessError:
-        host.WriteError("traffic_layout is broken. Aborting tests - The build of traffic server is bad.", show_stack=False) 
+        host.WriteError("traffic_layout is broken. Aborting tests - The build of traffic server is bad.", show_stack=False)
+    out = json.loads(out.decode("utf-8"))
+    for k, v in out.items():
+        out[k] = v[:-1] if v.endswith('/') else v
+    Variables.update(out)
+    host.WriteVerbose(['ats'], "Traffic server layout Data:\n", pprint.pformat(out))
+    # if the above worked this should as well
+    # this gets feature data
+    out = subprocess.check_output([traffic_layout, "-f", "--json"])
     out = json.loads(out.decode("utf-8"))
-    for k,v in out.items():
-        out[k]=v[:-1] if v.endswith('/') else v
     Variables.update(out)
-    host.WriteVerbose(['ats'],"Traffic server layout Data:\n",pprint.pformat(out))
+    host.WriteVerbose(['ats'], "Traffic server feature data:\n", pprint.pformat(out))
 
-Variables.AtsTestToolsDir = os.path.join(AutestSitePath,'../../tools')
+    # update version number 
+    out = subprocess.check_output([traffic_layout, "--version"]) 
+    out = Version(out.decode("utf-8").split("-")[2].strip()) 
+    Variables.trafficserver_version = out
+    host.WriteVerbose(['ats'], "Traffic server version:", out) 
+
+    # this querys tsxs for build flags so we can build code for the tests and get certain
+    # useful flags as which openssl to use when we don't use the system version
+    out = {
+        'CPPFLAGS': '',
+        'LIBS': '',
+        'LDFLAGS': '',
+        'CXX': ''
+    }
+    if os.path.isfile(tsxs):
+        for flag in out.keys():
+            try:
+                data = subprocess.check_output([tsxs, "-q", flag])
+                out[flag] = data.decode("utf-8")[:-1]
+            except subprocess.CalledProcessError:
+                # error if something goes wrong as the test will break if this exists and is broken
+                host.WriteError("tsxs is broken. Aborting tests", show_stack=False)
+    host.WriteVerbose(['ats'], "Traffic server build flags:\n", pprint.pformat(out))
+    Variables.update(out)
+Variables.AtsTestToolsDir = os.path.join(AutestSitePath, '../../tools')
 
 # modify delay times as we always have to kill Trafficserver
 # no need to wait
-Variables.Autest.StopProcessLongDelaySeconds=0
+Variables.Autest.StopProcessLongDelaySeconds = 0
+Variables.Autest.KillDelaySecond = 30
diff --git a/tests/gold_tests/autest-site/trafficserver.test.ext b/tests/gold_tests/autest-site/trafficserver.test.ext
index 1090ae2..35c13d7 100644
--- a/tests/gold_tests/autest-site/trafficserver.test.ext
+++ b/tests/gold_tests/autest-site/trafficserver.test.ext
@@ -269,8 +269,10 @@ def MakeATSProcess(obj, name, command='traffic_server', select_ports=True):
     p.Env['PROXY_CONFIG_ADMIN_AUTOCONF_PORT'] = str(
         p.Variables.admin_port)  # support pre ATS 6.x
 
-    # since we always kill this
-    p.ReturnCode = None
+    if command == "traffic_manager":
+        p.ReturnCode = 2
+    else:
+        p.ReturnCode = 0
 
     return p
 
diff --git a/tests/gold_tests/autest-site/trafficserver_plugins.test.ext b/tests/gold_tests/autest-site/trafficserver_plugins.test.ext
index 9ba2718..0efe6a3 100644
--- a/tests/gold_tests/autest-site/trafficserver_plugins.test.ext
+++ b/tests/gold_tests/autest-site/trafficserver_plugins.test.ext
@@ -31,14 +31,25 @@ def prepare_plugin(self, path, tsproc, plugin_args = ""):
     plugin_dir = tsproc.Env['PROXY_CONFIG_PLUGIN_PLUGIN_DIR']
     tsproc.Setup.Copy(path, plugin_dir)
 
+    tsxs = os.path.join(self.Variables.BINDIR,'tsxs')
+    # get the top level object ( ie Test) to add a condition
+    # need to change this API in AuTest to be a better name as it now has value 
+    # to be called by user API - dragon512
+    self._RootRunable.SkipUnless(
+        Condition.HasProgram(tsxs, "tsxs needs be installed with trafficserver package for this test to run")
+        )
+
     # Compile the plugin.
     in_basename = os.path.basename(path)
     in_path = os.path.join(plugin_dir, in_basename)
     out_basename = os.path.splitext(in_basename)[0] + '.so'
     out_path = os.path.join(plugin_dir, out_basename)
-    tsproc.Setup.RunCommand("tsxs -c {0} -o {1}".format(in_path, out_path))
+    tsproc.Setup.RunCommand("{tsxs} -c {0} -o {1}".format(in_path, out_path, tsxs=tsxs))
 
     # Add an entry to plugin.config.
     tsproc.Disk.plugin_config.AddLine("{0} {1}".format(out_basename,plugin_args))
 
+# remove this later
 ExtendTest(prepare_plugin, name="prepare_plugin")
+
+ExtendTest(prepare_plugin, name="PreparePlugin")
diff --git a/tests/tools/microServer/uWServer.py b/tests/tools/microServer/uWServer.py
index 0ee4ac6..b646608 100644
--- a/tests/tools/microServer/uWServer.py
+++ b/tests/tools/microServer/uWServer.py
@@ -33,8 +33,9 @@ import argparse
 import ssl
 import socket
 import importlib.util
-
+import time
 test_mode_enabled = True
+lookup_key_ = "{PATH}"
 __version__ = "1.0"
 
 
@@ -51,6 +52,7 @@ import sessionvalidation.sessionvalidation as sv
 
 
 SERVER_PORT = 5005  # default port
+SERVER_DELAY = 0 # default delay
 HTTP_VERSION = 'HTTP/1.1'
 G_replay_dict = {}
 
@@ -151,6 +153,7 @@ class SSLServer(ThreadingMixIn, HTTPServer):
 
         self.server_bind()
         self.server_activate()
+        print("Port Configured for SSL communication")
 
 
 class MyHandler(BaseHTTPRequestHandler):
@@ -166,17 +169,43 @@ class MyHandler(BaseHTTPRequestHandler):
         else:
             readChunks()
 
-    def getTestName(self, requestline):
-        key = None
-        keys = requestline.split(" ")
-        # print(keys)
-        if keys:
-            rkey = keys[1]
-        key = rkey.split("/", 1)[1]
-        if key + "/" in G_replay_dict:
-            key = key + "/"
-        elif len(key) > 1 and key[:-1] in G_replay_dict:
-            key = key[:-1]
+    def getLookupKey(self, requestline):
+        global lookup_key_
+        kpath= ""
+        path = ""
+        url_part = requestline.split(" ")
+        if url_part:
+            if url_part[1].startswith("http"):
+                path = url_part[1].split("/",2)[2]
+                host_, path = path.split("/",1)
+            else:
+                path = url_part[1].split("/",1)[1]
+        argsList = []
+        keyslist = lookup_key_.split("}")
+        for keystr in keyslist:            
+            if keystr == '{PATH':
+                kpath = kpath+path
+                continue # do not include path in the list of header fields
+            if keystr == '{HOST':
+                kpath = kpath+host_
+                continue
+            stringk = keystr.replace("{%","")
+            argsList.append(stringk)
+        KeyList = []
+        for argsL in argsList:
+            print("args",argsL,len(argsL))
+            if len(argsL)>0:
+                val = self.headers.get(argsL)
+                if val:
+                    field_val,__ = cgi.parse_header(val)
+                else:
+                    field_val=None
+                if field_val!=None:
+                    KeyList.append(field_val)
+        key = "".join(KeyList)+kpath
+        print("lookup key",key, len(key))
+
+
         return key
 
     def parseRequestline(self, requestline):
@@ -196,8 +225,11 @@ class MyHandler(BaseHTTPRequestHandler):
         return int(header.split(' ')[1])
 
     def generator(self):
-        yield 'microserver'
-        yield 'yahoo'
+        yield 'micro'
+        yield 'server'
+        yield 'apache'
+        yield 'traffic'
+        yield 'server'
 
     def send_response(self, code, message=None):
         ''' Override `send_response()`'s tacking on of server and date header lines. '''
@@ -364,7 +396,8 @@ class MyHandler(BaseHTTPRequestHandler):
     def do_GET(self):
         global G_replay_dict, test_mode_enabled
         if test_mode_enabled:
-            request_hash = self.getTestName(self.requestline)
+            time.sleep(time_delay)
+            request_hash = self.getLookupKey(self.requestline)
         else:
             request_hash, __ = cgi.parse_header(self.headers.get('Content-MD5'))
         # print("key:",request_hash)
@@ -439,7 +472,7 @@ class MyHandler(BaseHTTPRequestHandler):
     def do_HEAD(self):
         global G_replay_dict, test_mode_enabled
         if test_mode_enabled:
-            request_hash = self.getTestName(self.requestline)
+            request_hash = self.getLookupKey(self.requestline)
         else:
             request_hash, __ = cgi.parse_header(self.headers.get('Content-MD5'))
 
@@ -477,7 +510,7 @@ class MyHandler(BaseHTTPRequestHandler):
         chunkedResponse = False
         global G_replay_dict, test_mode_enabled
         if test_mode_enabled:
-            request_hash = self.getTestName(self.requestline)
+            request_hash = self.getLookupKey(self.requestline)
         else:
             request_hash, __ = cgi.parse_header(self.headers.get('Content-MD5'))
         try:
@@ -599,12 +632,6 @@ def main():
                         help="Directory with data file"
                         )
 
-    parser.add_argument("--public", "-P",
-                        type=_bool,
-                        default=False,
-                        help="Bind server to public IP 0.0.0.0 vs private IP of 127.0.0.1"
-                        )
-
     parser.add_argument("--ip_address", "-ip",
                         type=str,
                         default='',
@@ -616,6 +643,11 @@ def main():
                         default=SERVER_PORT,
                         help="Port to use")
 
+    parser.add_argument("--delay", "-dy",
+                        type=float,
+                        default=SERVER_DELAY,
+                        help="Response delay")
+
     parser.add_argument("--timeout", "-t",
                         type=float,
                         default=None,
@@ -627,10 +659,10 @@ def main():
                         type=str,
                         default="test",
                         help="Mode of operation")
-    parser.add_argument("--connection", "-c",
+    parser.add_argument("--ssl", "-ssl",
                         type=str,
-                        default="nonSSL",
-                        help="use SSL")
+                        default="False",
+                        help="SSL port")
     parser.add_argument("--key", "-k",
                         type=str,
                         default="ssl/server.pem",
@@ -648,9 +680,20 @@ def main():
                         type=str,
                         default='',
                         help="A file which will install observers on hooks")
+    parser.add_argument("--lookupkey",
+                        type=str,
+                        default="{PATH}",
+                        help="format string used as a key for response lookup: \
+                        example: \"{%Host}{%Server}{PATH}\", \"{HOST}{PATH}\", \"{PATH}\"\
+                        All the args preceded by % are header fields in the request\
+                        The only two acceptable arguments which are not header fields are : fqdn (represented by HOST) and the url path (represented by PATH) in a request line.\
+                        Example: given a client request as  << GET /some/resource/location HTTP/1.1\nHost: hahaha.com\n\n >>, if the user wishes the host field and the path to be used for the response lookup\
+                        then the required format will be {%Host}{PATH}")
 
     args = parser.parse_args()
     options = args
+    global time_delay
+    time_delay = options.delay
 
     # set up global dictionary of {uuid (string): response (Response object)}
     s = sv.SessionValidator(args.data_dir)
@@ -661,9 +704,10 @@ def main():
     try:
         socket_timeout = args.timeout
         test_mode_enabled = args.mode == "test"
-
+        global lookup_key_
+        lookup_key_ = args.lookupkey
         MyHandler.protocol_version = HTTP_VERSION
-        if options.connection == 'ssl':
+        if options.ssl == "True" or options.ssl == "true":
             server = SSLServer((options.ip_address, options.port), MyHandler, options)
         else:
             server = ThreadingServer((options.ip_address, options.port), MyHandler, options)

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

[trafficserver] 07/09: Add check on Environment input to validate it exists

Posted by zw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch 7.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit 4ba94efa85689ac86c19e3659c939bb93a2b2305
Author: Jason Kenny <dr...@live.com>
AuthorDate: Tue Aug 15 17:14:22 2017 -0500

    Add check on Environment input to validate it exists
    
    (cherry picked from commit ee9477d13f659e27ca6525ebdd084d91d50a00a1)
---
 lib/ts/runroot.cc | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/lib/ts/runroot.cc b/lib/ts/runroot.cc
index c6261c4..ef49ce0 100644
--- a/lib/ts/runroot.cc
+++ b/lib/ts/runroot.cc
@@ -70,6 +70,15 @@ check_parent_path(const std::string &path, bool json = false)
   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
 void
 runroot_handler(const char **argv, bool json = false)
@@ -112,8 +121,9 @@ runroot_handler(const char **argv, bool json = false)
     }
   }
   // 2. argv provided invalid/no yaml file, then check env variable
-  if (getenv("TS_RUNROOT") != nullptr) {
-    setenv("USING_RUNROOT", getenv("TS_RUNROOT"), true);
+  char *env_val = getenv("TS_RUNROOT");
+  if ((env_val != nullptr) && is_directory(env_val)) {
+    setenv("USING_RUNROOT", env_val, true);
     if (!json)
       ink_notice("using the environment variable TS_RUNROOT");
     return;

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

[trafficserver] 03/09: Add records configuration support to traffic_ctl.

Posted by zw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch 7.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit c6a741ea535597a1e50264d9b7311bd0c25cb87c
Author: James Peach <jp...@apache.org>
AuthorDate: Fri Jun 9 21:25:44 2017 -0700

    Add records configuration support to traffic_ctl.
    
    (cherry picked from commit ab19da39ce31d046b2d6da0299aeb30a106f7f34)
    
     Conflicts:
    	cmd/traffic_ctl/Makefile.am
---
 cmd/traffic_ctl/Makefile.am    |  7 ++++++-
 cmd/traffic_ctl/traffic_ctl.cc | 14 +++++++++++---
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/cmd/traffic_ctl/Makefile.am b/cmd/traffic_ctl/Makefile.am
index 4b4fb78..2d8b80b 100644
--- a/cmd/traffic_ctl/Makefile.am
+++ b/cmd/traffic_ctl/Makefile.am
@@ -21,6 +21,7 @@ AM_CPPFLAGS += \
   $(iocore_include_dirs) \
   -I$(abs_top_srcdir)/lib \
   -I$(abs_top_srcdir)/lib/records \
+  -I$(abs_top_srcdir)/mgmt \
   -I$(abs_top_srcdir)/mgmt/api/include
 
 bin_PROGRAMS = traffic_ctl
@@ -35,9 +36,13 @@ traffic_ctl_SOURCES = \
   traffic_ctl.cc
 
 traffic_ctl_LDADD = \
+  $(top_builddir)/lib/records/librecords_p.a \
+  $(top_builddir)/mgmt/libmgmt_p.la \
+  $(top_builddir)/iocore/eventsystem/libinkevent.a \
+  $(top_builddir)/proxy/shared/libUglyLogStubs.a \
   $(top_builddir)/mgmt/api/libtsmgmt.la \
   $(top_builddir)/lib/ts/libtsutil.la \
-  @LIBRESOLV@ @LIBTCL@
+  @LIBTCL@ @HWLOC_LIBS@
 
 include $(top_srcdir)/build/tidy.mk
 
diff --git a/cmd/traffic_ctl/traffic_ctl.cc b/cmd/traffic_ctl/traffic_ctl.cc
index c67c0f8..59ad001 100644
--- a/cmd/traffic_ctl/traffic_ctl.cc
+++ b/cmd/traffic_ctl/traffic_ctl.cc
@@ -23,6 +23,10 @@
 
 #include "traffic_ctl.h"
 
+#include "ts/I_Layout.h"
+#include "I_RecProcess.h"
+#include "RecordsConfig.h"
+
 AppVersionInfo CtrlVersionInfo;
 
 const char *
@@ -245,16 +249,20 @@ main(int argc, const char **argv)
     diags->show_location                      = SHOW_LOCATION_DEBUG;
   }
 
-  CtrlDebug("debug logging active");
-
   if (n_file_arguments < 1) {
     return CtrlSubcommandUsage(nullptr, commands, countof(commands), argument_descriptions, countof(argument_descriptions));
   }
 
+  Layout::create();
+  RecProcessInit(RECM_STAND_ALONE, diags);
+  LibRecordsConfigInit();
+
+  ats_scoped_str rundir(RecConfigReadRuntimeDir());
+
   // Make a best effort to connect the control socket. If it turns out we are just displaying help or something then it
   // doesn't matter that we failed. If we end up performing some operation then that operation will fail and display the
   // error.
-  TSInit(nullptr, static_cast<TSInitOptionT>(TS_MGMT_OPT_NO_EVENTS | TS_MGMT_OPT_NO_SOCK_TESTS));
+  TSInit(rundir, static_cast<TSInitOptionT>(TS_MGMT_OPT_NO_EVENTS | TS_MGMT_OPT_NO_SOCK_TESTS));
 
   for (unsigned i = 0; i < countof(commands); ++i) {
     if (strcmp(file_arguments[0], commands[i].name) == 0) {

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

[trafficserver] 02/09: Add records configuration support to traffic_top.

Posted by zw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch 7.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit fe826e7c51c633f6fce4d9704759e38a74b94f3c
Author: James Peach <jp...@apache.org>
AuthorDate: Fri Jun 9 21:26:08 2017 -0700

    Add records configuration support to traffic_top.
    
    (cherry picked from commit 9cc421218921b322fbadf085cc3ccd2b9a9fff4f)
    
     Conflicts:
    	cmd/traffic_top/traffic_top.cc
---
 cmd/traffic_top/Makefile.am    |  6 ++++++
 cmd/traffic_top/traffic_top.cc | 23 ++++++++++++++++++-----
 2 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/cmd/traffic_top/Makefile.am b/cmd/traffic_top/Makefile.am
index d9c66ba..f9079b1 100644
--- a/cmd/traffic_top/Makefile.am
+++ b/cmd/traffic_top/Makefile.am
@@ -21,6 +21,8 @@ if BUILD_TRAFFIC_TOP
 AM_CPPFLAGS += \
   $(iocore_include_dirs) \
   -I$(abs_top_srcdir)/lib \
+  -I$(abs_top_srcdir)/lib/records \
+  -I$(abs_top_srcdir)/mgmt \
   -I$(abs_top_srcdir)/mgmt/api/include \
   @CURL_CFLAGS@ \
   @CURSES_CFLAGS@
@@ -33,6 +35,10 @@ bin_PROGRAMS = traffic_top
 traffic_top_SOURCES = traffic_top.cc
 
 traffic_top_LDADD = \
+  $(top_builddir)/lib/records/librecords_p.a \
+  $(top_builddir)/mgmt/libmgmt_p.la \
+  $(top_builddir)/iocore/eventsystem/libinkevent.a \
+  $(top_builddir)/proxy/shared/libUglyLogStubs.a \
   $(top_builddir)/mgmt/api/libtsmgmt.la \
   $(top_builddir)/lib/ts/libtsutil.la \
   @CURL_LIBS@ \
diff --git a/cmd/traffic_top/traffic_top.cc b/cmd/traffic_top/traffic_top.cc
index 16ad488..ad289fe 100644
--- a/cmd/traffic_top/traffic_top.cc
+++ b/cmd/traffic_top/traffic_top.cc
@@ -54,11 +54,11 @@
 #include "stats.h"
 
 #include "ts/I_Layout.h"
-#include "ts/ink_args.h"
 #include "I_RecProcess.h"
 #include "RecordsConfig.h"
 
 using namespace std;
+
 #if HAS_CURL
 char curl_error[CURL_ERROR_SIZE];
 #endif
@@ -423,16 +423,29 @@ main(int argc, const char **argv)
     break;
   }
 
-  case 1:
+  Layout::create();
+  RecProcessInit(RECM_STAND_ALONE, nullptr /* diags */);
+  LibRecordsConfigInit();
+
+  string url = "";
 #if HAS_CURL
     url = file_arguments[0];
 #else
     usage(argument_descriptions, countof(argument_descriptions), USAGE);
 #endif
-    break;
 
-  default:
-    usage(argument_descriptions, countof(argument_descriptions), USAGE);
+    ats_scoped_str rundir(RecConfigReadRuntimeDir());
+
+    if (TS_ERR_OKAY != TSInit(rundir, static_cast<TSInitOptionT>(TS_MGMT_OPT_NO_EVENTS | TS_MGMT_OPT_NO_SOCK_TESTS))) {
+#if HAS_CURL
+      fprintf(stderr, "Error: missing URL on command line or error connecting to the local manager\n");
+#else
+      fprintf(stderr, "Error: error connecting to the local manager\n");
+#endif
+      usage();
+    }
+  } else {
+    url = argv[optind];
   }
 
   Stats stats(url);

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

[trafficserver] 08/09: add openssh flags that we need to build plugins with custom SSL correctly

Posted by zw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch 7.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit 71310969dc7cb987b2999b9efffdea9073cec577
Author: Jason Kenny <dr...@live.com>
AuthorDate: Mon Jan 8 10:46:11 2018 -0600

    add openssh flags that we need to build plugins with custom SSL correctly
    
    fix flags used
    
    (cherry picked from commit e779edbaf4a825ef7044a42b0691abfa80c8ef10)
---
 tools/tsxs.in | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/tools/tsxs.in b/tools/tsxs.in
index 8d529af..405589f 100755
--- a/tools/tsxs.in
+++ b/tools/tsxs.in
@@ -24,9 +24,10 @@ localstatedir="@localstatedir@"
 
 INSTALLDIR=`eval echo "@libexecdir@"`
 INCLUDEDIR=`eval echo "@includedir@"`
-CPPFLAGS="$CPPFLAGS -I$INCLUDEDIR"
+CPPFLAGS="$CPPFLAGS -I$INCLUDEDIR @OPENSSL_INCLUDES@"
 CFLAGS="$CFLAGS @AM_CFLAGS@"
 CXXFLAGS="$CXXFLAGS @AM_CXXFLAGS@"
+LIBS="$LIBS @LIBS@ @OPENSSL_LIBS@"
 BUILD=
 DEBUGECHO=
 LDFLAGS="$LDFLAGS @LDFLAGS@"
@@ -77,8 +78,11 @@ query() {
   case $1 in
     CC) echo @CC@ ;;
     CXX) echo @CXX@ ;;
-    CFLAGS) echo @AM_CFLAGS@ ;;
-    CXXFLAGS) echo @AM_CXXFLAGS@ ;;
+    CFLAGS) echo $CFLAGS ;;
+    CXXFLAGS) echo $CXXFLAGS ;;
+	CPPFLAGS) echo $CPPFLAGS ;;
+	LIBS) echo $LIBS ;;
+	LDFLAGS) echo $LDFLAGS ;;
     PREFIX) echo @prefix@ ;;
     SYSCONFDIR) echo @sysconfdir@ ;;
     INCLUDEDIR) echo @includedir@ ;;
@@ -144,7 +148,7 @@ case $host in
         NOWHOLE_ARCHIVE="-Wl,-z -Wl,defaultextract"
         ;;
 *-*-linux*)
-        LDFLAGS="$LDFLAGS -Wl,-E"
+        LDFLAGS="$LDFLAGS @OPENSSL_LDFLAGS@ -Wl,-E"
         CPPFLAGS="$CPPFLAGS"
         PICFLAGS="-fpic"
         MODULELD="$CC -shared"

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

[trafficserver] 04/09: New layout structure with std string & basic string view

Posted by zw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch 7.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit 08a5dccbc7d8ced37fc9cd0ccfaa8ec4b1b55618
Author: Xavier Chi <ch...@gmail.com>
AuthorDate: Tue Aug 8 15:15:45 2017 -0500

    New layout structure with std string & basic string view
    
    (cherry picked from commit 27cec04b9bd345a5fadb3bd505336c41785b7e1b)
    
     Conflicts:
    	cmd/traffic_layout/traffic_layout.cc
    	iocore/cache/Store.cc
    	lib/records/I_RecCore.h
    	lib/records/RecCore.cc
    	lib/ts/I_Layout.h
    	lib/ts/Makefile.am
    	mgmt/ProcessManager.cc
    	proxy/InkAPI.cc
    	proxy/Plugin.cc
    	proxy/logstats.cc
---
 cmd/traffic_cop/traffic_cop.cc           |  46 +++++------
 cmd/traffic_crashlog/traffic_crashlog.cc |   2 +-
 cmd/traffic_layout/traffic_layout.cc     |  30 ++++---
 cmd/traffic_manager/metrics.cc           |   2 +-
 cmd/traffic_manager/traffic_manager.cc   |  39 +++++-----
 iocore/cache/Store.cc                    |  13 ++--
 iocore/net/SSLConfig.cc                  |  10 +--
 lib/cppapi/Transaction.cc                |   4 +-
 lib/records/I_RecCore.h                  |  27 +++----
 lib/records/RecCore.cc                   |  63 ++++++++-------
 lib/ts/I_Layout.h                        |  59 +++++++-------
 lib/ts/Layout.cc                         | 130 +++++++++----------------------
 lib/ts/ink_memory.h                      |  10 +++
 lib/ts/unit-tests/test_layout.cpp        |  89 +++++++++++++++++++++
 mgmt/Alarms.cc                           |   2 +-
 mgmt/FileManager.cc                      |   2 +-
 mgmt/LocalManager.cc                     |  24 +++---
 mgmt/ProcessManager.cc                   |   6 +-
 mgmt/Rollback.cc                         |   4 +-
 mgmt/api/CoreAPIRemote.cc                |   2 +-
 mgmt/api/NetworkUtilsRemote.cc           |   4 +-
 proxy/Crash.cc                           |   2 +-
 proxy/InkAPI.cc                          |  15 ++--
 proxy/Main.cc                            |  36 ++++-----
 proxy/Plugin.cc                          |   3 +-
 proxy/http/remap/RemapConfig.cc          |   2 +-
 proxy/logging/LogConfig.cc               |   2 +-
 proxy/logging/LogStandalone.cc           |   6 +-
 proxy/logstats.cc                        |   8 +-
 29 files changed, 340 insertions(+), 302 deletions(-)

diff --git a/cmd/traffic_cop/traffic_cop.cc b/cmd/traffic_cop/traffic_cop.cc
index 871c7f6..10b9f4f 100644
--- a/cmd/traffic_cop/traffic_cop.cc
+++ b/cmd/traffic_cop/traffic_cop.cc
@@ -546,7 +546,7 @@ ConfigIntFatalError:
   exit(1);
 }
 
-static char *
+static std::string
 config_read_runtime_dir()
 {
   char state_dir[PATH_NAME_MAX];
@@ -556,11 +556,11 @@ config_read_runtime_dir()
   if (strlen(state_dir) > 0) {
     return Layout::get()->relative(state_dir);
   } else {
-    return ats_strdup(Layout::get()->runtimedir);
+    return Layout::get()->runtimedir;
   }
 }
 
-static char *
+static std::string
 config_read_sysconfig_dir()
 {
   char sysconfig_dir[PATH_NAME_MAX];
@@ -570,11 +570,11 @@ config_read_sysconfig_dir()
   if (strlen(sysconfig_dir) > 0) {
     return Layout::get()->relative(sysconfig_dir);
   } else {
-    return ats_strdup(Layout::get()->sysconfdir);
+    return Layout::get()->sysconfdir;
   }
 }
 
-static char *
+static std::string
 config_read_bin_dir()
 {
   char bindir[PATH_NAME_MAX];
@@ -585,11 +585,11 @@ config_read_bin_dir()
   if (strlen(bindir) > 0) {
     return Layout::get()->relative(bindir);
   } else {
-    return ats_strdup(Layout::get()->bindir);
+    return Layout::get()->bindir;
   }
 }
 
-static char *
+static std::string
 config_read_log_dir()
 {
   char logdir[PATH_NAME_MAX];
@@ -599,7 +599,7 @@ config_read_log_dir()
   if (strlen(logdir) > 0) {
     return Layout::get()->relative(logdir);
   } else {
-    return ats_strdup(Layout::get()->logdir);
+    return Layout::get()->logdir;
   }
 }
 
@@ -611,8 +611,8 @@ config_reload_records()
   char log_filename[PATH_NAME_MAX];
   int tmp_int = 3;
 
-  ats_scoped_str bindir;
-  ats_scoped_str logdir;
+  std::string bindir;
+  std::string logdir;
 
   cop_log_trace("Entering %s()\n", __func__);
   // coverity[fs_check_call]
@@ -640,15 +640,15 @@ config_reload_records()
   get_admin_user();
 
   bindir = config_read_bin_dir();
-  if (access(bindir, R_OK) == -1) {
-    cop_log(COP_FATAL, "could not access() \"%s\"\n", (const char *)bindir);
+  if (access(bindir.c_str(), R_OK) == -1) {
+    cop_log(COP_FATAL, "could not access() \"%s\"\n", bindir.c_str());
     cop_log(COP_FATAL, "please set 'proxy.config.bin_path' \n");
     exit(1);
   }
 
   logdir = config_read_log_dir();
-  if (access(logdir, W_OK) == -1) {
-    cop_log(COP_FATAL, "could not access() \"%s\"\n", (const char *)logdir);
+  if (access(logdir.c_str(), W_OK) == -1) {
+    cop_log(COP_FATAL, "could not access() \"%s\"\n", logdir.c_str());
     cop_log(COP_FATAL, "please set 'proxy.config.log.logfile_dir' \n");
     exit(1);
   }
@@ -745,7 +745,7 @@ static void
 spawn_manager()
 {
   char prog[PATH_NAME_MAX];
-  ats_scoped_str bindir(config_read_bin_dir());
+  std::string bindir(config_read_bin_dir());
 
   cop_log_trace("Entering spawn_manager()\n");
 
@@ -1638,8 +1638,8 @@ check(void *arg)
 
     // We do this after the first round of checks, since the first "check" will spawn traffic_manager
     if (!mgmt_init) {
-      ats_scoped_str runtimedir(config_read_runtime_dir());
-      TSInit(runtimedir, static_cast<TSInitOptionT>(TS_MGMT_OPT_NO_EVENTS));
+      std::string runtimedir(config_read_runtime_dir());
+      TSInit(runtimedir.c_str(), static_cast<TSInitOptionT>(TS_MGMT_OPT_NO_EVENTS));
       mgmt_init = true;
 
       // Allow a configurable longer sleep init time
@@ -1762,13 +1762,13 @@ static void
 init_config_file()
 {
   struct stat info;
-  ats_scoped_str config_dir;
+  std::string config_dir;
 
   cop_log_trace("Entering init_config_file()\n");
 
   config_dir = config_read_sysconfig_dir();
-  if (stat(config_dir, &info) < 0) {
-    cop_log(COP_FATAL, "unable to locate config directory '%s'\n", (const char *)config_dir);
+  if (stat(config_dir.c_str(), &info) < 0) {
+    cop_log(COP_FATAL, "unable to locate config directory '%s'\n", config_dir.c_str());
     cop_log(COP_FATAL, " please try setting correct root path in env variable TS_ROOT \n");
     exit(1);
   }
@@ -1777,8 +1777,8 @@ init_config_file()
   if (stat(config_file, &info) < 0) {
     Layout::relative_to(config_file, sizeof(config_file), config_dir, "records.config");
     if (stat(config_file, &info) < 0) {
-      cop_log(COP_FATAL, "unable to locate \"%s/records.config\" or \"%s/records.config.shadow\"\n", (const char *)config_dir,
-              (const char *)config_dir);
+      cop_log(COP_FATAL, "unable to locate \"%s/records.config\" or \"%s/records.config.shadow\"\n", config_dir.c_str(),
+              config_dir.c_str());
       exit(1);
     }
   }
@@ -1802,7 +1802,7 @@ init()
   init_config_file();
   config_reload_records();
 
-  runtime_dir = config_read_runtime_dir();
+  runtime_dir = ats_stringdup(config_read_runtime_dir());
   if (stat(runtime_dir, &info) < 0) {
     cop_log(COP_FATAL, "unable to locate local state directory '%s'\n", runtime_dir);
     cop_log(COP_FATAL, " please try setting correct root path in either env variable TS_ROOT \n");
diff --git a/cmd/traffic_crashlog/traffic_crashlog.cc b/cmd/traffic_crashlog/traffic_crashlog.cc
index faf98dc..54b4755 100644
--- a/cmd/traffic_crashlog/traffic_crashlog.cc
+++ b/cmd/traffic_crashlog/traffic_crashlog.cc
@@ -65,7 +65,7 @@ crashlog_name()
 {
   char filename[64];
   struct tm now = timestamp();
-  ats_scoped_str logdir(RecConfigReadLogDir());
+  std::string logdir(RecConfigReadLogDir());
   ats_scoped_str pathname;
 
   strftime(filename, sizeof(filename), "crash-%Y-%m-%d-%H%M%S.log", &now);
diff --git a/cmd/traffic_layout/traffic_layout.cc b/cmd/traffic_layout/traffic_layout.cc
index cce710b..f48befb 100644
--- a/cmd/traffic_layout/traffic_layout.cc
+++ b/cmd/traffic_layout/traffic_layout.cc
@@ -28,6 +28,8 @@
 #include "I_RecProcess.h"
 #include "RecordsConfig.h"
 
+#include <iostream>
+
 // Command line arguments (parsing)
 struct CommandLineArgs {
   int layout;
@@ -122,18 +124,14 @@ produce_features(bool json)
   }
 }
 
-static void
-print_var(const char *name, char *value, bool json, bool free = true, bool last = false)
+void
+print_var(ts::string_view const &name, ts::string_view const &value, bool json, bool last = false)
 {
-  if (json) {
-    printf(R"(    "%s": "%s"%s)", name, value, last ? "\n" : ",\n");
-  } else {
-    printf("%s: %s\n", name, value);
-  }
-
-  if (free) {
-    ats_free(value);
-  }
+  if (json)
+    printf(R"(    "%.*s": "%.*s"%s)", static_cast<int>(name.size()), name.data(), static_cast<int>(value.size()), value.data(),
+           last ? "\n" : ",\n");
+  else
+    printf("%.*s: %.*s\n", static_cast<int>(name.size()), name.data(), static_cast<int>(value.size()), value.data());
 }
 
 static void
@@ -147,14 +145,14 @@ produce_layout(bool json)
   if (json) {
     printf("{\n");
   }
-  print_var("PREFIX", Layout::get()->prefix, json, false); // Don't free this
+  print_var("PREFIX", Layout::get()->prefix, json);
   print_var("BINDIR", RecConfigReadBinDir(), json);
   print_var("SYSCONFDIR", RecConfigReadConfigDir(), json);
-  print_var("LIBDIR", Layout::get()->libdir, json, false); // Don't free this
+  print_var("LIBDIR", Layout::get()->libdir, json);
   print_var("LOGDIR", RecConfigReadLogDir(), json);
   print_var("RUNTIMEDIR", RecConfigReadRuntimeDir(), json);
-  print_var("PLUGINDIR", RecConfigReadPrefixPath("proxy.config.plugin.plugin_dir"), json);
-  print_var("INCLUDEDIR", Layout::get()->includedir, json, false); // Dont' free this
+  print_var("PLUGINDIR", RecConfigReadPluginDir(), json);
+  print_var("INCLUDEDIR", Layout::get()->includedir, json);
   print_var("SNAPSHOTDIR", RecConfigReadSnapshotDir(), json);
 
   print_var("records.config", RecConfigReadConfigPath(nullptr, REC_CONFIG_FILE), json);
@@ -164,7 +162,7 @@ produce_layout(bool json)
   print_var("storage.config", RecConfigReadConfigPath("proxy.config.cache.storage_filename"), json);
   print_var("hosting.config", RecConfigReadConfigPath("proxy.config.cache.hosting_filename"), json);
   print_var("volume.config", RecConfigReadConfigPath("proxy.config.cache.volume_filename"), json);
-  print_var("ip_allow.config", RecConfigReadConfigPath("proxy.config.cache.ip_allow.filename"), json, true, true);
+  print_var("ip_allow.config", RecConfigReadConfigPath("proxy.config.cache.ip_allow.filename"), json, true);
   if (json) {
     printf("}\n");
   }
diff --git a/cmd/traffic_manager/metrics.cc b/cmd/traffic_manager/metrics.cc
index 88a296f..bdb7e8e 100644
--- a/cmd/traffic_manager/metrics.cc
+++ b/cmd/traffic_manager/metrics.cc
@@ -387,7 +387,7 @@ bool
 metrics_binding_configure(BindingInstance &binding)
 {
   ats_scoped_str sysconfdir(RecConfigReadConfigDir());
-  ats_scoped_str config(Layout::get()->relative_to(sysconfdir, "metrics.config"));
+  ats_scoped_str config(Layout::get()->relative_to(sysconfdir.get(), "metrics.config"));
 
   return binding.require(config.get());
 }
diff --git a/cmd/traffic_manager/traffic_manager.cc b/cmd/traffic_manager/traffic_manager.cc
index d9964f5..f0afcaf 100644
--- a/cmd/traffic_manager/traffic_manager.cc
+++ b/cmd/traffic_manager/traffic_manager.cc
@@ -166,7 +166,7 @@ is_server_idle()
 static void
 check_lockfile()
 {
-  ats_scoped_str rundir(RecConfigReadRuntimeDir());
+  std::string rundir(RecConfigReadRuntimeDir());
   char lockfile[PATH_NAME_MAX];
   int err;
   pid_t holding_pid;
@@ -302,17 +302,17 @@ initSignalHandlers()
 static void
 init_dirs()
 {
-  ats_scoped_str rundir(RecConfigReadRuntimeDir());
-  ats_scoped_str sysconfdir(RecConfigReadConfigDir());
+  std::string rundir(RecConfigReadRuntimeDir());
+  std::string sysconfdir(RecConfigReadConfigDir());
 
-  if (access(sysconfdir, R_OK) == -1) {
-    mgmt_elog(0, "unable to access() config directory '%s': %d, %s\n", (const char *)sysconfdir, errno, strerror(errno));
+  if (access(sysconfdir.c_str(), R_OK) == -1) {
+    mgmt_elog(0, "unable to access() config directory '%s': %d, %s\n", sysconfdir.c_str(), errno, strerror(errno));
     mgmt_elog(0, "please set the 'TS_ROOT' environment variable\n");
     ::exit(1);
   }
 
-  if (access(rundir, R_OK) == -1) {
-    mgmt_elog(0, "unable to access() local state directory '%s': %d, %s\n", (const char *)rundir, errno, strerror(errno));
+  if (access(rundir.c_str(), R_OK) == -1) {
+    mgmt_elog(0, "unable to access() local state directory '%s': %d, %s\n", rundir.c_str(), errno, strerror(errno));
     mgmt_elog(0, "please set 'proxy.config.local_state_dir'\n");
     ::exit(1);
   }
@@ -321,14 +321,14 @@ init_dirs()
 static void
 chdir_root()
 {
-  const char *prefix = Layout::get()->prefix;
+  std::string prefix = Layout::get()->prefix;
 
-  if (chdir(prefix) < 0) {
-    mgmt_elog(0, "unable to change to root directory \"%s\" [%d '%s']\n", prefix, errno, strerror(errno));
+  if (chdir(prefix.c_str()) < 0) {
+    mgmt_elog(0, "unable to change to root directory \"%s\" [%d '%s']\n", prefix.c_str(), errno, strerror(errno));
     mgmt_elog(0, " please set correct path in env variable TS_ROOT \n");
     exit(1);
   } else {
-    mgmt_log("[TrafficManager] using root directory '%s'\n", prefix);
+    mgmt_log("[TrafficManager] using root directory '%s'\n", prefix.c_str());
   }
 }
 
@@ -421,7 +421,7 @@ main(int argc, const char **argv)
 
   // Before accessing file system initialize Layout engine
   Layout::create();
-  mgmt_path = Layout::get()->sysconfdir;
+  mgmt_path = Layout::get()->sysconfdir.c_str();
 
   // Set up the application version info
   appVersionInfo.setup(PACKAGE_NAME, "traffic_manager", PACKAGE_VERSION, __DATE__, __TIME__, BUILD_MACHINE, BUILD_PERSON, "");
@@ -681,9 +681,9 @@ main(int argc, const char **argv)
   Debug("lm", "Created Web Agent thread (%" PRId64 ")", (int64_t)synthThrId);
 
   // Setup the API and event sockets
-  ats_scoped_str rundir(RecConfigReadRuntimeDir());
-  ats_scoped_str apisock(Layout::relative_to(rundir, MGMTAPI_MGMT_SOCKET_NAME));
-  ats_scoped_str eventsock(Layout::relative_to(rundir, MGMTAPI_EVENT_SOCKET_NAME));
+  std::string rundir(RecConfigReadRuntimeDir());
+  std::string apisock(Layout::relative_to(rundir, MGMTAPI_MGMT_SOCKET_NAME));
+  std::string eventsock(Layout::relative_to(rundir, MGMTAPI_EVENT_SOCKET_NAME));
 
   mode_t oldmask = umask(0);
   mode_t newmode = api_socket_is_restricted() ? 00700 : 00777;
@@ -692,17 +692,16 @@ main(int argc, const char **argv)
   int eventapiFD        = -1; // FD for the api and clients to handle event callbacks
   char mgmtapiFailMsg[] = "Traffic server management API service Interface Failed to Initialize.";
 
-  mgmtapiFD = bind_unix_domain_socket(apisock, newmode);
+  mgmtapiFD = bind_unix_domain_socket(apisock.c_str(), newmode);
   if (mgmtapiFD == -1) {
-    mgmt_log("[WebIntrMain] Unable to set up socket for handling management API calls. API socket path = %s\n",
-             (const char *)apisock);
+    mgmt_log("[WebIntrMain] Unable to set up socket for handling management API calls. API socket path = %s\n", apisock.c_str());
     lmgmt->alarm_keeper->signalAlarm(MGMT_ALARM_WEB_ERROR, mgmtapiFailMsg);
   }
 
-  eventapiFD = bind_unix_domain_socket(eventsock, newmode);
+  eventapiFD = bind_unix_domain_socket(eventsock.c_str(), newmode);
   if (eventapiFD == -1) {
     mgmt_log("[WebIntrMain] Unable to set up so for handling management API event calls. Event Socket path: %s\n",
-             (const char *)eventsock);
+             eventsock.c_str());
   }
 
   umask(oldmask);
diff --git a/iocore/cache/Store.cc b/iocore/cache/Store.cc
index 06068ad..16e873c 100644
--- a/iocore/cache/Store.cc
+++ b/iocore/cache/Store.cc
@@ -378,19 +378,18 @@ Store::read_config()
       }
     }
 
-    char *pp = Layout::get()->relative(path);
+    std::string pp = Layout::get()->relative(path);
 
     ns = new Span;
-    Debug("cache_init", "Store::read_config - ns = new Span; ns->init(\"%s\",%" PRId64 "), forced volume=%d%s%s", pp, size,
+    Debug("cache_init", "Store::read_config - ns = new Span; ns->init(\"%s\",%" PRId64 "), forced volume=%d%s%s", pp.c_str(), size,
           volume_num, seed ? " id=" : "", seed ? seed : "");
-    if ((err = ns->init(pp, size))) {
-      RecSignalWarning(REC_SIGNAL_SYSTEM_ERROR, "could not initialize storage \"%s\" [%s]", pp, err);
-      Debug("cache_init", "Store::read_config - could not initialize storage \"%s\" [%s]", pp, err);
+    if ((err = ns->init(pp.c_str(), size))) {
+      RecSignalWarning(REC_SIGNAL_SYSTEM_ERROR, "could not initialize storage \"%s\" [%s]", pp.c_str(), err);
+      Debug("cache_init", "Store::read_config - could not initialize storage \"%s\" [%s]", pp.c_str(), err);
       delete ns;
-      ats_free(pp);
       continue;
     }
-    ats_free(pp);
+
     n_dsstore++;
 
     // Set side values if present.
diff --git a/iocore/net/SSLConfig.cc b/iocore/net/SSLConfig.cc
index 01cc1ba..731e351 100644
--- a/iocore/net/SSLConfig.cc
+++ b/iocore/net/SSLConfig.cc
@@ -141,16 +141,16 @@ set_paths_helper(const char *path, const char *filename, char **final_path, char
 {
   if (final_path) {
     if (path && path[0] != '/') {
-      *final_path = RecConfigReadPrefixPath(nullptr, path);
+      *final_path = ats_stringdup(RecConfigReadPrefixPath(nullptr, path));
     } else if (!path || path[0] == '\0') {
-      *final_path = RecConfigReadConfigDir();
+      *final_path = ats_stringdup(RecConfigReadConfigDir());
     } else {
       *final_path = ats_strdup(path);
     }
   }
 
   if (final_filename) {
-    *final_filename = filename ? Layout::get()->relative_to(path, filename) : nullptr;
+    *final_filename = filename ? ats_stringdup(Layout::get()->relative_to(path, filename)) : nullptr;
   }
 }
 
@@ -176,7 +176,7 @@ SSLConfigParams::initialize()
   REC_ReadConfigInt32(clientCertLevel, "proxy.config.ssl.client.certification_level");
   REC_ReadConfigStringAlloc(cipherSuite, "proxy.config.ssl.server.cipher_suite");
   REC_ReadConfigStringAlloc(client_cipherSuite, "proxy.config.ssl.client.cipher_suite");
-  dhparamsFile = RecConfigReadConfigPath("proxy.config.ssl.server.dhparams_file");
+  dhparamsFile = ats_stringdup(RecConfigReadConfigPath("proxy.config.ssl.server.dhparams_file"));
 
   int options;
   int client_ssl_options = 0;
@@ -249,7 +249,7 @@ SSLConfigParams::initialize()
   set_paths_helper(serverCertRelativePath, nullptr, &serverCertPathOnly, nullptr);
   ats_free(serverCertRelativePath);
 
-  configFilePath = RecConfigReadConfigPath("proxy.config.ssl.server.multicert.filename");
+  configFilePath = ats_stringdup(RecConfigReadConfigPath("proxy.config.ssl.server.multicert.filename"));
   REC_ReadConfigInteger(configExitOnLoadError, "proxy.config.ssl.server.multicert.exit_on_load_fail");
 
   REC_ReadConfigStringAlloc(ssl_server_private_key_path, "proxy.config.ssl.server.private_key.path");
diff --git a/lib/cppapi/Transaction.cc b/lib/cppapi/Transaction.cc
index b7a2703..261bfce 100644
--- a/lib/cppapi/Transaction.cc
+++ b/lib/cppapi/Transaction.cc
@@ -395,9 +395,9 @@ Transaction::getCacheStatus()
 void
 Transaction::redirectTo(std::string const &url)
 {
-  char *s = ats_strdup(url.c_str());
+  std::string s = url;
   // Must re-alloc the string locally because ownership is transferred to the transaction.
-  TSHttpTxnRedirectUrlSet(state_->txn_, s, url.length());
+  TSHttpTxnRedirectUrlSet(state_->txn_, s.c_str(), url.length());
 }
 
 namespace
diff --git a/lib/records/I_RecCore.h b/lib/records/I_RecCore.h
index 52d8d48..ff39339 100644
--- a/lib/records/I_RecCore.h
+++ b/lib/records/I_RecCore.h
@@ -49,36 +49,33 @@ void RecConfigFileInit(void);
 int RecConfigFileParse(const char *path, RecConfigEntryCallback handler, bool inc_version);
 
 // Return a copy of the system's configuration directory, taking proxy.config.config_dir into account. The
-// caller MUST release the result with ats_free().
-char *RecConfigReadConfigDir();
+std::string RecConfigReadConfigDir();
 
 // Return a copy of the system's local state directory, taking proxy.config.local_state_dir into account. The
-// caller MUST release the result with ats_free().
-char *RecConfigReadRuntimeDir();
+std::string RecConfigReadRuntimeDir();
 
 // Return a copy of the system's snapshot directory, taking proxy.config.snapshot_dir into account. The caller
-// MUST release the result with ats_free().
-char *RecConfigReadSnapshotDir();
+std::string RecConfigReadSnapshotDir();
 
 // Return a copy of the system's log directory, taking proxy.config.log.logfile_dir into account. The caller
-// MUST release the result with ats_free().
-char *RecConfigReadLogDir();
+std::string RecConfigReadLogDir();
 
 // Return a copy of the system's bin directory, taking proxy.config.bin_path into account. The caller MUST
-// release the result with ats_free().
-char *RecConfigReadBinDir();
+std::string RecConfigReadBinDir();
+
+// Return a copy of the system's plugin directory, taking proxy.config.plugin.plugin_dir into account. The caller MUST
+std::string RecConfigReadPluginDir();
 
 // Return a copy of a configuration file that is relative to sysconfdir. The relative path to the configuration
 // file is specified in the configuration variable named by "file_variable". If the configuration variable has no
-// value, nullptr is returned. The caller MUST release the result with ats_free().
-char *RecConfigReadConfigPath(const char *file_variable, const char *default_value = nullptr);
+// value, nullptr is returned.
+std::string RecConfigReadConfigPath(const char *file_variable, const char *default_value = nullptr);
 
 // This is the same as RecConfigReadConfigPath, except it makes the paths relative to $PREFIX.
-char *RecConfigReadPrefixPath(const char *file_variable, const char *default_value = nullptr);
+std::string RecConfigReadPrefixPath(const char *file_variable, const char *default_value = nullptr);
 
 // Return a copy of the persistent stats file. This is $RUNTIMEDIR/records.snap.
-// The caller MUST release the result with ats_free().
-char *RecConfigReadPersistentStatsPath();
+std::string RecConfigReadPersistentStatsPath();
 
 // Test whether the named configuration value is overridden by an environment variable. Return either
 // the overridden value, or the original value. Caller MUST NOT free the result.
diff --git a/lib/records/RecCore.cc b/lib/records/RecCore.cc
index 71e5fda..0d5cea2 100644
--- a/lib/records/RecCore.cc
+++ b/lib/records/RecCore.cc
@@ -210,17 +210,14 @@ RecCoreInit(RecModeT mode_type, Diags *_diags)
   }
   // read configs
   if ((mode_type == RECM_SERVER) || (mode_type == RECM_STAND_ALONE)) {
-    ink_mutex_init(&g_rec_config_lock, nullptr);
-    // Import the file into memory; try the following in this order:
-    // ./etc/trafficserver/records.config.shadow
-    // ./records.config.shadow
-    // ./etc/trafficserver/records.config
-    // ./records.config
-    bool file_exists   = true;
-    g_rec_config_fpath = RecConfigReadConfigPath(nullptr, REC_CONFIG_FILE REC_SHADOW_EXT);
+    bool file_exists = true;
+
+    ink_mutex_init(&g_rec_config_lock);
+
+    g_rec_config_fpath = ats_stringdup(RecConfigReadConfigPath(nullptr, REC_CONFIG_FILE REC_SHADOW_EXT));
     if (RecFileExists(g_rec_config_fpath) == REC_ERR_FAIL) {
       ats_free((char *)g_rec_config_fpath);
-      g_rec_config_fpath = RecConfigReadConfigPath(nullptr, REC_CONFIG_FILE);
+      g_rec_config_fpath = ats_stringdup(RecConfigReadConfigPath(nullptr, REC_CONFIG_FILE));
       if (RecFileExists(g_rec_config_fpath) == REC_ERR_FAIL) {
         RecLog(DL_Warning, "Could not find '%s', system will run with defaults\n", REC_CONFIG_FILE);
         file_exists = false;
@@ -1120,10 +1117,11 @@ REC_readString(const char *name, bool *found, bool lock)
   return _tmp;
 }
 
-//-------------------------------------------------------------------------
-// RecConfigReadConfigDir
-//-------------------------------------------------------------------------
-char *
+// RecConfigReadConfigDir. Note that we handle environmental configuration
+// overrides specially here. Normally we would override the configuration
+// variable when we read records.config but to avoid the bootstrapping
+// problem, we make an explicit check here.
+std::string
 RecConfigReadConfigDir()
 {
   char buf[PATH_NAME_MAX];
@@ -1133,14 +1131,14 @@ RecConfigReadConfigDir()
   if (strlen(buf) > 0) {
     return Layout::get()->relative(buf);
   } else {
-    return ats_strdup(Layout::get()->sysconfdir);
+    return Layout::get()->sysconfdir;
   }
 }
 
 //-------------------------------------------------------------------------
 // RecConfigReadRuntimeDir
 //-------------------------------------------------------------------------
-char *
+std::string
 RecConfigReadRuntimeDir()
 {
   char buf[PATH_NAME_MAX];
@@ -1150,14 +1148,14 @@ RecConfigReadRuntimeDir()
   if (strlen(buf) > 0) {
     return Layout::get()->relative(buf);
   } else {
-    return ats_strdup(Layout::get()->runtimedir);
+    return Layout::get()->runtimedir;
   }
 }
 
 //-------------------------------------------------------------------------
 // RecConfigReadLogDir
 //-------------------------------------------------------------------------
-char *
+std::string
 RecConfigReadLogDir()
 {
   char buf[PATH_NAME_MAX];
@@ -1167,14 +1165,14 @@ RecConfigReadLogDir()
   if (strlen(buf) > 0) {
     return Layout::get()->relative(buf);
   } else {
-    return ats_strdup(Layout::get()->logdir);
+    return Layout::get()->logdir;
   }
 }
 
 //-------------------------------------------------------------------------
 // RecConfigReadBinDir
 //-------------------------------------------------------------------------
-char *
+std::string
 RecConfigReadBinDir()
 {
   char buf[PATH_NAME_MAX];
@@ -1184,14 +1182,23 @@ RecConfigReadBinDir()
   if (strlen(buf) > 0) {
     return Layout::get()->relative(buf);
   } else {
-    return ats_strdup(Layout::get()->bindir);
+    return Layout::get()->bindir;
   }
 }
 
 //-------------------------------------------------------------------------
+// RecConfigReadPluginDir
+//-------------------------------------------------------------------------
+std::string
+RecConfigReadPluginDir()
+{
+  return RecConfigReadPrefixPath("proxy.config.plugin.plugin_dir");
+}
+
+//-------------------------------------------------------------------------
 // RecConfigReadSnapshotDir.
 //-------------------------------------------------------------------------
-char *
+std::string
 RecConfigReadSnapshotDir()
 {
   return RecConfigReadConfigPath("proxy.config.snapshot_dir", "snapshots");
@@ -1200,10 +1207,10 @@ RecConfigReadSnapshotDir()
 //-------------------------------------------------------------------------
 // RecConfigReadConfigPath
 //-------------------------------------------------------------------------
-char *
+std::string
 RecConfigReadConfigPath(const char *file_variable, const char *default_value)
 {
-  ats_scoped_str sysconfdir(RecConfigReadConfigDir());
+  std::string sysconfdir(RecConfigReadConfigDir());
 
   // If the file name is in a configuration variable, look it up first ...
   if (file_variable) {
@@ -1221,13 +1228,13 @@ RecConfigReadConfigPath(const char *file_variable, const char *default_value)
     return Layout::get()->relative_to(sysconfdir, default_value);
   }
 
-  return nullptr;
+  return {};
 }
 
 //-------------------------------------------------------------------------
 // RecConfigReadPrefixPath
 //-------------------------------------------------------------------------
-char *
+std::string
 RecConfigReadPrefixPath(const char *file_variable, const char *default_value)
 {
   char buf[PATH_NAME_MAX];
@@ -1246,16 +1253,16 @@ RecConfigReadPrefixPath(const char *file_variable, const char *default_value)
     return Layout::get()->relative_to(Layout::get()->prefix, default_value);
   }
 
-  return nullptr;
+  return {};
 }
 
 //-------------------------------------------------------------------------
 // RecConfigReadPersistentStatsPath
 //-------------------------------------------------------------------------
-char *
+std::string
 RecConfigReadPersistentStatsPath()
 {
-  ats_scoped_str rundir(RecConfigReadRuntimeDir());
+  std::string rundir(RecConfigReadRuntimeDir());
   return Layout::relative_to(rundir, REC_RAW_STATS_FILE);
 }
 
diff --git a/lib/ts/I_Layout.h b/lib/ts/I_Layout.h
index 2be9b19..d23b07a 100644
--- a/lib/ts/I_Layout.h
+++ b/lib/ts/I_Layout.h
@@ -31,67 +31,44 @@
 #ifndef _I_Layout_h
 #define _I_Layout_h
 
+// use std string and string view for layout
+#include <string>
+#include "ts/string_view.h"
+
 /**
   The Layout is a simple place holder for the distribution layout.
 
  */
 struct Layout {
-  char *prefix;
-  char *exec_prefix;
-  char *bindir;
-  char *sbindir;
-  char *sysconfdir;
-  char *datadir;
-  char *includedir;
-  char *libdir;
-  char *libexecdir;
-  char *localstatedir;
-  char *sharedstatedir;
-  char *runtimedir;
-  char *logdir;
-  char *mandir;
-  char *infodir;
-  char *cachedir;
-
-  Layout(const char *prefix = 0);
+  Layout(ts::string_view const _prefix = {});
   ~Layout();
 
   /**
    Return file path relative to Layout->prefix
-   Memory is allocated, so use ats_free() when no longer needed
 
   */
-  char *relative(const char *file);
+  std::string relative(ts::string_view file);
 
   /**
    update the sysconfdir to a test conf dir
-   */
-  void update_sysconfdir(const char *dir);
-
-  /**
-   Return file path relative to Layout->prefix
-   Store the path to buf. The buf should be large eough to store
-   PATH_NAME_MAX characters
 
    */
-  void relative(char *buf, size_t bufsz, const char *file);
+  void update_sysconfdir(ts::string_view dir);
 
   /**
    Return file path relative to dir
-   Memory is allocated, so use ats_free() when no longer needed
    Example usage: Layout::relative_to(default_layout()->sysconfdir, "foo.bar");
 
   */
-  static char *relative_to(const char *dir, const char *file);
+  static std::string relative_to(ts::string_view dir, ts::string_view file);
 
   /**
    Return file path relative to dir
    Store the path to buf. The buf should be large eough to store
-   PATH_NAME_MAX characters
    Example usage: Layout::relative_to(default_layout()->sysconfdir, "foo.bar");
 
   */
-  static void relative_to(char *buf, size_t bufsz, const char *dir, const char *file);
+  static void relative_to(char *buf, size_t bufsz, ts::string_view dir, ts::string_view file);
 
   /**
    Creates a Layout Object with the given prefix.  If no
@@ -99,13 +76,29 @@ struct Layout {
    at the compile time.
 
   */
-  static void create(const char *prefix = 0);
+  static void create(ts::string_view const prefix = {});
 
   /**
    Returns the Layout object created by create_default_layout().
 
   */
   static Layout *get();
+
+  std::string prefix;
+  std::string exec_prefix;
+  std::string bindir;
+  std::string sbindir;
+  std::string sysconfdir;
+  std::string datadir;
+  std::string includedir;
+  std::string libdir;
+  std::string libexecdir;
+  std::string localstatedir;
+  std::string runtimedir;
+  std::string logdir;
+  std::string mandir;
+  std::string infodir;
+  std::string cachedir;
 };
 
 #endif
diff --git a/lib/ts/Layout.cc b/lib/ts/Layout.cc
index 483dcf1..cb3c7d8 100644
--- a/lib/ts/Layout.cc
+++ b/lib/ts/Layout.cc
@@ -41,134 +41,95 @@ Layout::get()
 }
 
 void
-Layout::create(const char *prefix)
+Layout::create(ts::string_view const prefix)
 {
   if (layout == nullptr) {
     layout = new Layout(prefix);
   }
 }
 
-static char *
-layout_relative(const char *root, const char *file)
+static void
+_relative(char *path, size_t buffsz, ts::string_view root, ts::string_view file)
 {
-  char path[PATH_NAME_MAX];
-
-  if (ink_filepath_merge(path, PATH_NAME_MAX, root, file, INK_FILEPATH_TRUENAME)) {
+  if (ink_filepath_merge(path, buffsz, root.data(), file.data(), INK_FILEPATH_TRUENAME)) {
     int err = errno;
     // Log error
     if (err == EACCES) {
-      ink_error("Cannot merge path '%s' above the root '%s'\n", file, root);
+      ink_fatal("Cannot merge path '%s' above the root '%s'\n", file.data(), root.data());
     } else if (err == E2BIG) {
-      ink_error("Exceeding file name length limit of %d characters\n", PATH_NAME_MAX);
+      ink_fatal("Exceeding file name length limit of %d characters\n", PATH_NAME_MAX);
     } else {
       // TODO: Make some pretty errors.
-      ink_error("Cannot merge '%s' with '%s' error=%d\n", file, root, err);
+      ink_fatal("Cannot merge '%s' with '%s' error=%d\n", file.data(), root.data(), err);
     }
-    return nullptr;
   }
-  return ats_strdup(path);
 }
 
-char *
-Layout::relative(const char *file)
+static std::string
+layout_relative(ts::string_view root, ts::string_view file)
 {
-  return layout_relative(prefix, file);
+  char path[PATH_NAME_MAX];
+  std::string ret;
+  _relative(path, PATH_NAME_MAX, root, file);
+  ret = path;
+  return ret;
 }
 
-void
-Layout::relative(char *buf, size_t bufsz, const char *file)
+std::string
+Layout::relative(ts::string_view file)
 {
-  char path[PATH_NAME_MAX];
-
-  if (ink_filepath_merge(path, PATH_NAME_MAX, prefix, file, INK_FILEPATH_TRUENAME)) {
-    int err = errno;
-    // Log error
-    if (err == EACCES) {
-      ink_error("Cannot merge path '%s' above the root '%s'\n", file, prefix);
-    } else if (err == E2BIG) {
-      ink_error("Exceeding file name length limit of %d characters\n", PATH_NAME_MAX);
-    } else {
-      // TODO: Make some pretty errors.
-      ink_error("Cannot merge '%s' with '%s' error=%d\n", file, prefix, err);
-    }
-    return;
-  }
-  size_t path_len = strlen(path) + 1;
-  if (path_len > bufsz) {
-    ink_error("Provided buffer is too small: %zu, required %zu\n", bufsz, path_len);
-  } else {
-    ink_strlcpy(buf, path, bufsz);
-  }
+  return layout_relative(prefix, file);
 }
 
+// for updating the structure sysconfdir
 void
-Layout::update_sysconfdir(const char *dir)
+Layout::update_sysconfdir(ts::string_view dir)
 {
-  if (sysconfdir) {
-    ats_free(sysconfdir);
-  }
-
-  sysconfdir = ats_strdup(dir);
+  sysconfdir.assign(dir.data(), dir.size());
 }
 
-char *
-Layout::relative_to(const char *dir, const char *file)
+std::string
+Layout::relative_to(ts::string_view dir, ts::string_view file)
 {
   return layout_relative(dir, file);
 }
 
 void
-Layout::relative_to(char *buf, size_t bufsz, const char *dir, const char *file)
+Layout::relative_to(char *buf, size_t bufsz, ts::string_view dir, ts::string_view file)
 {
   char path[PATH_NAME_MAX];
 
-  if (ink_filepath_merge(path, PATH_NAME_MAX, dir, file, INK_FILEPATH_TRUENAME)) {
-    int err = errno;
-    // Log error
-    if (err == EACCES) {
-      ink_error("Cannot merge path '%s' above the root '%s'\n", file, dir);
-    } else if (err == E2BIG) {
-      ink_error("Exceeding file name length limit of %d characters\n", PATH_NAME_MAX);
-    } else {
-      // TODO: Make some pretty errors.
-      ink_error("Cannot merge '%s' with '%s' error=%d\n", file, dir, err);
-    }
-    return;
-  }
+  _relative(path, PATH_NAME_MAX, dir, file);
   size_t path_len = strlen(path) + 1;
   if (path_len > bufsz) {
-    ink_error("Provided buffer is too small: %zu, required %zu\n", bufsz, path_len);
+    ink_fatal("Provided buffer is too small: %zu, required %zu\n", bufsz, path_len);
   } else {
     ink_strlcpy(buf, path, bufsz);
   }
 }
 
-Layout::Layout(const char *_prefix)
+Layout::Layout(ts::string_view const _prefix)
 {
-  if (_prefix) {
-    prefix = ats_strdup(_prefix);
+  if (_prefix.size() != 0) {
+    prefix.assign(_prefix.data(), _prefix.size());
   } else {
-    char *env_path;
-    char path[PATH_NAME_MAX];
+    std::string path;
     int len;
-
-    if ((env_path = getenv("TS_ROOT"))) {
-      len = strlen(env_path);
+    if (getenv("TS_ROOT") != nullptr) {
+      std::string env_path(getenv("TS_ROOT"));
+      len = env_path.size();
       if ((len + 1) > PATH_NAME_MAX) {
-        ink_error("TS_ROOT environment variable is too big: %d, max %d\n", len, PATH_NAME_MAX - 1);
-        return;
+        ink_fatal("TS_ROOT environment variable is too big: %d, max %d\n", len, PATH_NAME_MAX - 1);
       }
-      ink_strlcpy(path, env_path, sizeof(path));
-      while (len > 1 && path[len - 1] == '/') {
-        path[len - 1] = '\0';
-        --len;
+      path = env_path;
+      while (path.back() == '/') {
+        path.pop_back();
       }
     } else {
       // Use compile time --prefix
-      ink_strlcpy(path, TS_BUILD_PREFIX, sizeof(path));
+      path = TS_BUILD_PREFIX;
     }
-
-    prefix = ats_strdup(path);
+    prefix = path;
   }
   exec_prefix   = layout_relative(prefix, TS_BUILD_EXEC_PREFIX);
   bindir        = layout_relative(prefix, TS_BUILD_BINDIR);
@@ -188,19 +149,4 @@ Layout::Layout(const char *_prefix)
 
 Layout::~Layout()
 {
-  ats_free(prefix);
-  ats_free(exec_prefix);
-  ats_free(bindir);
-  ats_free(sbindir);
-  ats_free(sysconfdir);
-  ats_free(datadir);
-  ats_free(includedir);
-  ats_free(libdir);
-  ats_free(libexecdir);
-  ats_free(localstatedir);
-  ats_free(runtimedir);
-  ats_free(logdir);
-  ats_free(mandir);
-  ats_free(infodir);
-  ats_free(cachedir);
 }
diff --git a/lib/ts/ink_memory.h b/lib/ts/ink_memory.h
index 4276b2f..b659025 100644
--- a/lib/ts/ink_memory.h
+++ b/lib/ts/ink_memory.h
@@ -122,6 +122,16 @@ static inline size_t __attribute__((const)) ats_pagesize(void)
 char *_xstrdup(const char *str, int length, const char *path);
 
 #define ats_strdup(p) _xstrdup((p), -1, nullptr)
+
+// this is to help with migration to a std::string issue with older code that
+// expects char* being copied. As more code moves to std::string, this can be
+// removed to avoid these extra copies.
+inline char *
+ats_stringdup(std::string const &p)
+{
+  return p.empty() ? nullptr : _xstrdup(p.c_str(), p.size(), nullptr);
+}
+
 #define ats_strndup(p, n) _xstrdup((p), n, nullptr)
 
 #ifdef __cplusplus
diff --git a/lib/ts/unit-tests/test_layout.cpp b/lib/ts/unit-tests/test_layout.cpp
new file mode 100644
index 0000000..59facae
--- /dev/null
+++ b/lib/ts/unit-tests/test_layout.cpp
@@ -0,0 +1,89 @@
+/** @file
+  Test file for layout structure
+  @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.
+ */
+
+#include "catch.hpp"
+
+#include "ts/I_Layout.h"
+#include "ts/ink_platform.h"
+
+std::string
+append_slash(const char *path)
+{
+  std::string ret(path);
+  if (ret.back() != '/')
+    ret.append("/");
+  return ret;
+}
+
+// test cases: [constructor], [env_constructor], [create], [relative], [relative_to], [update_sysconfdir]
+// ======= test for layout ========
+
+TEST_CASE("constructor test", "[constructor]")
+{
+  Layout layout;
+  // test for constructor
+  REQUIRE(layout.prefix == TS_BUILD_PREFIX);
+  REQUIRE(layout.sysconfdir == layout.relative(TS_BUILD_SYSCONFDIR));
+}
+
+TEST_CASE("environment variable constructor test", "[env_constructor]")
+{
+  std::string newpath = append_slash(TS_BUILD_PREFIX) + "env";
+  setenv("TS_ROOT", newpath.c_str(), true);
+
+  Layout layout;
+  REQUIRE(layout.prefix == newpath);
+  REQUIRE(layout.sysconfdir == layout.relative_to(newpath, TS_BUILD_SYSCONFDIR));
+  unsetenv("TS_ROOT");
+}
+
+TEST_CASE("layout create test", "[create]")
+{
+  Layout::create();
+  REQUIRE(Layout::get()->prefix == TS_BUILD_PREFIX);
+  REQUIRE(Layout::get()->sysconfdir == Layout::get()->relative(TS_BUILD_SYSCONFDIR));
+}
+
+// tests below based on the created layout
+TEST_CASE("relative test", "[relative]")
+{
+  // relative (1 argument)
+  ts::string_view sv("file");
+  std::string str1 = append_slash(TS_BUILD_PREFIX) + "file";
+  REQUIRE(Layout::get()->relative(sv) == str1);
+}
+
+TEST_CASE("relative to test", "[relative_to]")
+{
+  // relative to (2 parameters)
+  std::string str1 = append_slash(TS_BUILD_PREFIX) + "file";
+  REQUIRE(Layout::relative_to(Layout::get()->prefix, "file") == str1);
+
+  // relative to (4 parameters)
+  char config_file[PATH_NAME_MAX];
+  Layout::relative_to(config_file, sizeof(config_file), Layout::get()->sysconfdir, "records.config");
+  std::string a = Layout::relative_to(Layout::get()->sysconfdir, "records.config");
+  std::string b = config_file;
+  REQUIRE(a == b);
+}
+
+TEST_CASE("update_sysconfdir test", "[update_sysconfdir]")
+{
+  Layout::get()->update_sysconfdir("/abc");
+  REQUIRE(Layout::get()->sysconfdir == "/abc");
+}
diff --git a/mgmt/Alarms.cc b/mgmt/Alarms.cc
index bf549c0..4cdc2ec 100644
--- a/mgmt/Alarms.cc
+++ b/mgmt/Alarms.cc
@@ -73,7 +73,7 @@ alarm_script_dir()
     return path;
   }
 
-  return RecConfigReadBinDir();
+  return ats_stringdup(RecConfigReadBinDir());
 }
 
 Alarms::Alarms()
diff --git a/mgmt/FileManager.cc b/mgmt/FileManager.cc
index bdbd23c..df92f1b 100644
--- a/mgmt/FileManager.cc
+++ b/mgmt/FileManager.cc
@@ -593,7 +593,7 @@ FileManager::WalkSnaps(ExpandingArray *snapList)
   MFresult r;
 
   // Make sure managedDir is the latest from proxy.config.snapshot_dir.
-  this->managedDir = RecConfigReadSnapshotDir();
+  this->managedDir = ats_stringdup(RecConfigReadSnapshotDir());
 
   ink_mutex_acquire(&accessLock);
 
diff --git a/mgmt/LocalManager.cc b/mgmt/LocalManager.cc
index b27dd7b..7ff715c 100644
--- a/mgmt/LocalManager.cc
+++ b/mgmt/LocalManager.cc
@@ -179,9 +179,9 @@ LocalManager::processRunning()
 LocalManager::LocalManager(bool proxy_on) : BaseManager(), run_proxy(proxy_on), configFiles(nullptr)
 {
   bool found;
-  ats_scoped_str rundir(RecConfigReadRuntimeDir());
-  ats_scoped_str bindir(RecConfigReadBinDir());
-  ats_scoped_str sysconfdir(RecConfigReadConfigDir());
+  std::string rundir(RecConfigReadRuntimeDir());
+  std::string bindir(RecConfigReadBinDir());
+  std::string sysconfdir(RecConfigReadConfigDir());
 
   syslog_facility = 0;
 
@@ -208,8 +208,8 @@ LocalManager::LocalManager(bool proxy_on) : BaseManager(), run_proxy(proxy_on),
   // Get the default IP binding values.
   RecHttpLoadIp("proxy.local.incoming_ip_to_bind", m_inbound_ip4, m_inbound_ip6);
 
-  if (access(sysconfdir, R_OK) == -1) {
-    mgmt_log("[LocalManager::LocalManager] unable to access() directory '%s': %d, %s\n", (const char *)sysconfdir, errno,
+  if (access(sysconfdir.c_str(), R_OK) == -1) {
+    mgmt_log("[LocalManager::LocalManager] unable to access() directory '%s': %d, %s\n", sysconfdir.c_str(), errno,
              strerror(errno));
     mgmt_fatal(0, "[LocalManager::LocalManager] please set the 'TS_ROOT' environment variable\n");
   }
@@ -247,7 +247,7 @@ LocalManager::LocalManager(bool proxy_on) : BaseManager(), run_proxy(proxy_on),
   proxy_options                = nullptr;
 
   // Calculate proxy_binary from the absolute bin_path
-  absolute_proxy_binary = Layout::relative_to(bindir, proxy_binary);
+  absolute_proxy_binary = ats_stringdup(Layout::relative_to(bindir, proxy_binary));
 
   // coverity[fs_check_call]
   if (access(absolute_proxy_binary, R_OK | X_OK) == -1) {
@@ -357,8 +357,8 @@ LocalManager::initCCom(const AppVersionInfo &version, FileManager *configFiles,
 void
 LocalManager::initMgmtProcessServer()
 {
-  ats_scoped_str rundir(RecConfigReadRuntimeDir());
-  ats_scoped_str sockpath(Layout::relative_to(rundir, LM_CONNECTION_SERVER));
+  std::string rundir(RecConfigReadRuntimeDir());
+  std::string sockpath(Layout::relative_to(rundir, LM_CONNECTION_SERVER));
   mode_t oldmask = umask(0);
 
 #if TS_HAS_WCCP
@@ -368,9 +368,9 @@ LocalManager::initMgmtProcessServer()
   }
 #endif
 
-  process_server_sockfd = bind_unix_domain_socket(sockpath, 00700);
+  process_server_sockfd = bind_unix_domain_socket(sockpath.c_str(), 00700);
   if (process_server_sockfd == -1) {
-    mgmt_fatal(errno, "[LocalManager::initMgmtProcessServer] failed to bind socket at %s\n", (const char *)sockpath);
+    mgmt_fatal(errno, "[LocalManager::initMgmtProcessServer] failed to bind socket at %s\n", sockpath.c_str());
   }
 
   umask(oldmask);
@@ -913,9 +913,9 @@ LocalManager::startProxy(const char *onetime_options)
       int res;
 
       char env_prep_bin[MAXPATHLEN];
-      ats_scoped_str bindir(RecConfigReadBinDir());
+      std::string bindir(RecConfigReadBinDir());
 
-      ink_filepath_make(env_prep_bin, sizeof(env_prep_bin), bindir, env_prep);
+      ink_filepath_make(env_prep_bin, sizeof(env_prep_bin), bindir.c_str(), env_prep);
       res = execl(env_prep_bin, env_prep_bin, (char *)nullptr);
       _exit(res);
     }
diff --git a/mgmt/ProcessManager.cc b/mgmt/ProcessManager.cc
index cd7c714..3addf5b 100644
--- a/mgmt/ProcessManager.cc
+++ b/mgmt/ProcessManager.cc
@@ -178,8 +178,8 @@ ProcessManager::processSignalQueue()
 void
 ProcessManager::initLMConnection()
 {
-  ats_scoped_str rundir(RecConfigReadRuntimeDir());
-  ats_scoped_str sockpath(Layout::relative_to(rundir, LM_CONNECTION_SERVER));
+  std::string rundir(RecConfigReadRuntimeDir());
+  std::string sockpath(Layout::relative_to(rundir, LM_CONNECTION_SERVER));
 
   MgmtMessageHdr *mh_full;
   int data_len;
@@ -191,7 +191,7 @@ ProcessManager::initLMConnection()
   memset((char *)&serv_addr, 0, sizeof(serv_addr));
   serv_addr.sun_family = AF_UNIX;
 
-  ink_strlcpy(serv_addr.sun_path, sockpath, sizeof(serv_addr.sun_path));
+  ink_strlcpy(serv_addr.sun_path, sockpath.c_str(), sizeof(serv_addr.sun_path));
 #if defined(darwin) || defined(freebsd)
   servlen = sizeof(sockaddr_un);
 #else
diff --git a/mgmt/Rollback.cc b/mgmt/Rollback.cc
index 31d3f75..17dfc3c 100644
--- a/mgmt/Rollback.cc
+++ b/mgmt/Rollback.cc
@@ -233,8 +233,8 @@ Rollback::createPathStr(version_t version)
 {
   int bufSize  = 0;
   char *buffer = nullptr;
-  ats_scoped_str sysconfdir(RecConfigReadConfigDir());
-  bufSize = strlen(sysconfdir) + fileNameLen + MAX_VERSION_DIGITS + 1;
+  std::string sysconfdir(RecConfigReadConfigDir());
+  bufSize = sysconfdir.size() + fileNameLen + MAX_VERSION_DIGITS + 1;
   buffer  = (char *)ats_malloc(bufSize);
   Layout::get()->relative_to(buffer, bufSize, sysconfdir, fileName);
   if (version != ACTIVE_VERSION) {
diff --git a/mgmt/api/CoreAPIRemote.cc b/mgmt/api/CoreAPIRemote.cc
index 32e7ac1..caf57ad 100644
--- a/mgmt/api/CoreAPIRemote.cc
+++ b/mgmt/api/CoreAPIRemote.cc
@@ -196,7 +196,7 @@ Init(const char *socket_path, TSInitOptionT options)
   // libraries. The caller has to pass down the right socket path :(
   if (!socket_path) {
     Layout::create();
-    socket_path = Layout::get()->runtimedir;
+    socket_path = Layout::get()->runtimedir.c_str();
   }
 
   // store socket_path
diff --git a/mgmt/api/NetworkUtilsRemote.cc b/mgmt/api/NetworkUtilsRemote.cc
index 740ae46..d0c7152 100644
--- a/mgmt/api/NetworkUtilsRemote.cc
+++ b/mgmt/api/NetworkUtilsRemote.cc
@@ -57,8 +57,8 @@ set_socket_paths(const char *path)
   // construct paths based on user input
   // form by replacing "mgmtapi.sock" with "eventapi.sock"
   if (path) {
-    main_socket_path  = Layout::relative_to(path, MGMTAPI_MGMT_SOCKET_NAME);
-    event_socket_path = Layout::relative_to(path, MGMTAPI_EVENT_SOCKET_NAME);
+    main_socket_path  = ats_stringdup(Layout::relative_to(path, MGMTAPI_MGMT_SOCKET_NAME));
+    event_socket_path = ats_stringdup(Layout::relative_to(path, MGMTAPI_EVENT_SOCKET_NAME));
   } else {
     main_socket_path  = nullptr;
     event_socket_path = nullptr;
diff --git a/proxy/Crash.cc b/proxy/Crash.cc
index b99abde..366d5fd 100644
--- a/proxy/Crash.cc
+++ b/proxy/Crash.cc
@@ -40,7 +40,7 @@ static char *
 create_logger_path()
 {
   RecString name;
-  ats_scoped_str bindir;
+  std::string bindir;
   ats_scoped_str fullpath;
 
   if (RecGetRecordString_Xmalloc("proxy.config.crash_log_helper", &name) != REC_ERR_OKAY) {
diff --git a/proxy/InkAPI.cc b/proxy/InkAPI.cc
index 15fbe00..a23427f 100644
--- a/proxy/InkAPI.cc
+++ b/proxy/InkAPI.cc
@@ -1763,21 +1763,22 @@ TShrtime()
 const char *
 TSInstallDirGet(void)
 {
-  return Layout::get()->prefix;
+  static std::string prefix = Layout::get()->prefix;
+  return prefix.c_str();
 }
 
 const char *
 TSConfigDirGet(void)
 {
-  static const char *sysconfdir = RecConfigReadConfigDir();
-  return sysconfdir;
+  static std::string sysconfdir = RecConfigReadConfigDir();
+  return sysconfdir.c_str();
 }
 
 const char *
 TSRuntimeDirGet(void)
 {
-  static const char *runtimedir = RecConfigReadRuntimeDir();
-  return runtimedir;
+  static std::string runtimedir = RecConfigReadRuntimeDir();
+  return runtimedir.c_str();
 }
 
 const char *
@@ -1805,8 +1806,8 @@ TSTrafficServerVersionGetPatch()
 const char *
 TSPluginDirGet(void)
 {
-  static const char *path = RecConfigReadPrefixPath("proxy.config.plugin.plugin_dir");
-  return path;
+  static std::string path = RecConfigReadPluginDir();
+  return path.c_str();
 }
 
 ////////////////////////////////////////////////////////////////////
diff --git a/proxy/Main.cc b/proxy/Main.cc
index 8d13f26..eae8db0 100644
--- a/proxy/Main.cc
+++ b/proxy/Main.cc
@@ -485,19 +485,19 @@ init_system()
 static void
 check_lockfile()
 {
-  ats_scoped_str rundir(RecConfigReadRuntimeDir());
-  ats_scoped_str lockfile;
+  std::string rundir(RecConfigReadRuntimeDir());
+  std::string lockfile;
   pid_t holding_pid;
   int err;
 
   lockfile = Layout::relative_to(rundir, SERVER_LOCK);
 
-  Lockfile server_lockfile(lockfile);
+  Lockfile server_lockfile(lockfile.c_str());
   err = server_lockfile.Get(&holding_pid);
 
   if (err != 1) {
     char *reason = strerror(-err);
-    fprintf(stderr, "WARNING: Can't acquire lockfile '%s'", (const char *)lockfile);
+    fprintf(stderr, "WARNING: Can't acquire lockfile '%s'", lockfile.c_str());
 
     if ((err == 0) && (holding_pid != -1)) {
       fprintf(stderr, " (Lock file held by process ID %ld)\n", (long)holding_pid);
@@ -515,17 +515,17 @@ check_lockfile()
 static void
 check_config_directories()
 {
-  ats_scoped_str rundir(RecConfigReadRuntimeDir());
-  ats_scoped_str sysconfdir(RecConfigReadConfigDir());
+  std::string rundir(RecConfigReadRuntimeDir());
+  std::string sysconfdir(RecConfigReadConfigDir());
 
-  if (access(sysconfdir, R_OK) == -1) {
-    fprintf(stderr, "unable to access() config dir '%s': %d, %s\n", (const char *)sysconfdir, errno, strerror(errno));
+  if (access(sysconfdir.c_str(), R_OK) == -1) {
+    fprintf(stderr, "unable to access() config dir '%s': %d, %s\n", sysconfdir.c_str(), errno, strerror(errno));
     fprintf(stderr, "please set the 'TS_ROOT' environment variable\n");
     ::exit(1);
   }
 
-  if (access(rundir, R_OK | W_OK) == -1) {
-    fprintf(stderr, "unable to access() local state dir '%s': %d, %s\n", (const char *)rundir, errno, strerror(errno));
+  if (access(rundir.c_str(), R_OK | W_OK) == -1) {
+    fprintf(stderr, "unable to access() local state dir '%s': %d, %s\n", rundir.c_str(), errno, strerror(errno));
     fprintf(stderr, "please set 'proxy.config.local_state_dir'\n");
     ::exit(1);
   }
@@ -742,12 +742,12 @@ cmd_clear(char *cmd)
   bool c_cache = !strcmp(cmd, "clear_cache");
 
   if (c_all || c_hdb) {
-    ats_scoped_str rundir(RecConfigReadRuntimeDir());
-    ats_scoped_str config(Layout::relative_to(rundir, "hostdb.config"));
+    std::string rundir(RecConfigReadRuntimeDir());
+    std::string config(Layout::relative_to(rundir, "hostdb.config"));
 
     Note("Clearing HostDB Configuration");
-    if (unlink(config) < 0) {
-      Note("unable to unlink %s", (const char *)config);
+    if (unlink(config.c_str()) < 0) {
+      Note("unable to unlink %s", config.c_str());
     }
   }
 
@@ -1357,15 +1357,15 @@ run_RegressionTest()
 static void
 chdir_root()
 {
-  const char *prefix = Layout::get()->prefix;
+  std::string prefix = Layout::get()->prefix;
 
-  if (chdir(prefix) < 0) {
-    fprintf(stderr, "%s: unable to change to root directory \"%s\" [%d '%s']\n", appVersionInfo.AppStr, prefix, errno,
+  if (chdir(prefix.c_str()) < 0) {
+    fprintf(stderr, "%s: unable to change to root directory \"%s\" [%d '%s']\n", appVersionInfo.AppStr, prefix.c_str(), errno,
             strerror(errno));
     fprintf(stderr, "%s: please correct the path or set the TS_ROOT environment variable\n", appVersionInfo.AppStr);
     ::exit(1);
   } else {
-    printf("%s: using root directory '%s'\n", appVersionInfo.AppStr, prefix);
+    printf("%s: using root directory '%s'\n", appVersionInfo.AppStr, prefix.c_str());
   }
 }
 
diff --git a/proxy/Plugin.cc b/proxy/Plugin.cc
index c8b9107..250edf1 100644
--- a/proxy/Plugin.cc
+++ b/proxy/Plugin.cc
@@ -231,8 +231,7 @@ plugin_init(bool validateOnly)
 
   if (INIT_ONCE) {
     api_init();
-    TSConfigDirGet();
-    plugin_dir = TSPluginDirGet();
+    plugin_dir = ats_stringdup(RecConfigReadPluginDir());
     INIT_ONCE  = false;
   }
 
diff --git a/proxy/http/remap/RemapConfig.cc b/proxy/http/remap/RemapConfig.cc
index 1f43d4a..d528c1f 100644
--- a/proxy/http/remap/RemapConfig.cc
+++ b/proxy/http/remap/RemapConfig.cc
@@ -337,7 +337,7 @@ parse_include_directive(const char *directive, BUILD_TABLE_INFO *bti, char *errb
           continue;
         }
 
-        subpath = Layout::relative_to(path, entrylist[j]->d_name);
+        subpath = Layout::relative_to(path.get(), entrylist[j]->d_name);
 
         if (ink_file_is_directory(subpath)) {
           continue;
diff --git a/proxy/logging/LogConfig.cc b/proxy/logging/LogConfig.cc
index 1461599..86ed11b 100644
--- a/proxy/logging/LogConfig.cc
+++ b/proxy/logging/LogConfig.cc
@@ -163,7 +163,7 @@ LogConfig::read_configuration_variables()
   }
 
   ats_free(logfile_dir);
-  logfile_dir = RecConfigReadLogDir();
+  logfile_dir = ats_stringdup(RecConfigReadLogDir());
 
   if (access(logfile_dir, R_OK | W_OK | X_OK) == -1) {
     // Try 'system_root_dir/var/log/trafficserver' directory
diff --git a/proxy/logging/LogStandalone.cc b/proxy/logging/LogStandalone.cc
index 1102c59..d2091b3 100644
--- a/proxy/logging/LogStandalone.cc
+++ b/proxy/logging/LogStandalone.cc
@@ -148,12 +148,12 @@ check_lockfile()
   pid_t holding_pid;
   char *lockfile = nullptr;
 
-  if (access(Layout::get()->runtimedir, R_OK | W_OK) == -1) {
-    fprintf(stderr, "unable to access() dir'%s': %d, %s\n", Layout::get()->runtimedir, errno, strerror(errno));
+  if (access(Layout::get()->runtimedir.c_str(), R_OK | W_OK) == -1) {
+    fprintf(stderr, "unable to access() dir'%s': %d, %s\n", Layout::get()->runtimedir.c_str(), errno, strerror(errno));
     fprintf(stderr, " please set correct path in env variable TS_ROOT \n");
     ::exit(1);
   }
-  lockfile = Layout::relative_to(Layout::get()->runtimedir, SERVER_LOCK);
+  lockfile = ats_stringdup(Layout::relative_to(Layout::get()->runtimedir, SERVER_LOCK));
 
   Lockfile server_lockfile(lockfile);
   err = server_lockfile.Get(&holding_pid);
diff --git a/proxy/logstats.cc b/proxy/logstats.cc
index ff1ea11..8d9a1fa 100644
--- a/proxy/logstats.cc
+++ b/proxy/logstats.cc
@@ -2471,7 +2471,7 @@ main(int /* argc ATS_UNUSED */, const char *argv[])
         if (end > start) {
           char *buf;
 
-          buf = ats_strdup(line.substr(start, end).c_str());
+          buf = ats_stringdup(line.substr(start, end));
           if (buf) {
             origin_set->insert(buf);
           }
@@ -2499,7 +2499,7 @@ main(int /* argc ATS_UNUSED */, const char *argv[])
   // Do the incremental parse of the default squid log.
   if (cl.incremental) {
     // Change directory to the log dir
-    if (chdir(Layout::get()->logdir) < 0) {
+    if (chdir(Layout::get()->logdir.c_str()) < 0) {
       exit_status.set(EXIT_CRITICAL, " can't chdir to ");
       exit_status.append(Layout::get()->logdir);
       my_exit(exit_status);
@@ -2602,8 +2602,8 @@ main(int /* argc ATS_UNUSED */, const char *argv[])
       last_state.st_ino = stat_buf.st_ino;
 
       // Find the old log file.
-      dirp = opendir(Layout::get()->logdir);
-      if (NULL == dirp) {
+      dirp = opendir(Layout::get()->logdir.c_str());
+      if (nullptr == dirp) {
         exit_status.set(EXIT_WARNING, " can't read log directory");
       } else {
         while ((dp = readdir(dirp)) != NULL) {

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

[trafficserver] 05/09: Added traffic_runroot feature to generate sandbox for programs to run

Posted by zw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch 7.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

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

    Added traffic_runroot feature to generate sandbox for programs to run
    
    (cherry picked from commit 30c2c35e5ed1daadcf8a8db5e46760e3d7ae5325)
    
     Conflicts:
    	lib/ts/ink_args.cc
    	proxy/Main.cc
---
 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                       |   5 +-
 lib/ts/ink_args.h                        |   4 +
 lib/ts/runroot.cc                        | 132 +++++++++++++++++++++++++++++++
 proxy/Main.cc                            |   6 +-
 proxy/logcat.cc                          |   5 +-
 proxy/logstats.cc                        |   5 +-
 14 files changed, 260 insertions(+), 11 deletions(-)

diff --git a/cmd/traffic_cop/traffic_cop.cc b/cmd/traffic_cop/traffic_cop.cc
index 10b9f4f..420702c 100644
--- a/cmd/traffic_cop/traffic_cop.cc
+++ b/cmd/traffic_cop/traffic_cop.cc
@@ -36,6 +36,7 @@
 #include "ClusterCom.h"
 #include "ts/ink_cap.h"
 #include "Cop.h"
+#include "ts/runroot.cc"
 
 #include <string>
 #include <map>
@@ -1820,7 +1821,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[])
@@ -1828,6 +1830,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 59ad001..bf69fc6 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[] = {
@@ -253,6 +255,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 f48befb..f22fb57 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.
@@ -178,6 +178,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 f0afcaf..d447692 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 "WebOverview.h"
@@ -419,6 +420,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();
@@ -462,7 +465,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 ad289fe..e217cee 100644
--- a/cmd/traffic_top/traffic_top.cc
+++ b/cmd/traffic_top/traffic_top.cc
@@ -403,6 +403,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 7c58592..bd973e3 100644
--- a/lib/ts/ink_args.cc
+++ b/lib/ts/ink_args.cc
@@ -218,7 +218,10 @@ process_args_ex(const AppVersionInfo *appinfo, const ArgumentDescription *argume
 
     if ((*argv)[1] == '-') {
       // Deal with long options ...
-      for (i = 0; i < n_argument_descriptions; i++)
+      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 eae8db0..b28441e 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 <syslog.h>
 
@@ -219,7 +220,9 @@ static const ArgumentDescription argument_descriptions[] = {
   {"accept_mss", '-', "MSS for client connections", "I", &accept_mss, nullptr, nullptr},
   {"poll_timeout", 't', "poll timeout in milliseconds", "I", &poll_timeout, nullptr, nullptr},
   HELP_ARGUMENT_DESCRIPTION(),
-  VERSION_ARGUMENT_DESCRIPTION()};
+  VERSION_ARGUMENT_DESCRIPTION(),
+  RUNROOT_ARGUMENT_DESCRIPTION(),
+};
 
 class SignalContinuation : public Continuation
 {
@@ -1523,6 +1526,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 8d9a1fa..35967dc 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"
@@ -658,7 +659,8 @@ static ArgumentDescription argument_descriptions[] = {
   {"debug_tags", 'T', "Colon-Separated Debug Tags", "S1023", &error_tags, NULL, NULL},
   {"report_per_user", 'r', "Report stats per user instead of host", "T", &cl.report_per_user, NULL, NULL},
   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]";
 
@@ -2409,6 +2411,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" <co...@trafficserver.apache.org>.

[trafficserver] 01/09: Switch traffic_top to standard argument processing.

Posted by zw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch 7.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit 10c22e0e43fa0e8da66f313cf6c0741196cb7126
Author: James Peach <jp...@apache.org>
AuthorDate: Fri Jun 9 21:38:43 2017 -0700

    Switch traffic_top to standard argument processing.
    
    (cherry picked from commit e4ee12c005f90231e9ea6038266314f2b372eb7f)
    
     Conflicts:
    	cmd/traffic_top/traffic_top.cc
---
 cmd/traffic_top/stats.h        |  4 +--
 cmd/traffic_top/traffic_top.cc | 79 ++++++++++++++++++++++++------------------
 2 files changed, 48 insertions(+), 35 deletions(-)

diff --git a/cmd/traffic_top/stats.h b/cmd/traffic_top/stats.h
index ffb1c1e..f35c163 100644
--- a/cmd/traffic_top/stats.h
+++ b/cmd/traffic_top/stats.h
@@ -326,8 +326,8 @@ public:
           _now       = now;
           _time_diff = _now - _old_time;
         } else {
-          fprintf(stderr, "Can't fetch url %s", _url.c_str());
-          abort();
+          fprintf(stderr, "Can't fetch url %s\n", _url.c_str());
+          exit(1);
         }
 
         /* always cleanup */
diff --git a/cmd/traffic_top/traffic_top.cc b/cmd/traffic_top/traffic_top.cc
index 32441ae..16ad488 100644
--- a/cmd/traffic_top/traffic_top.cc
+++ b/cmd/traffic_top/traffic_top.cc
@@ -53,6 +53,11 @@
 
 #include "stats.h"
 
+#include "ts/I_Layout.h"
+#include "ts/ink_args.h"
+#include "I_RecProcess.h"
+#include "RecordsConfig.h"
+
 using namespace std;
 #if HAS_CURL
 char curl_error[CURL_ERROR_SIZE];
@@ -262,17 +267,6 @@ help(const string &host, const string &version)
   }
 }
 
-static void
-usage()
-{
-#if HAS_CURL
-  fprintf(stderr, "Usage: traffic_top [-s seconds] [URL|hostname|hostname:port]\n");
-#else
-  fprintf(stderr, "Usage: traffic_top [-s seconds]\n");
-#endif
-  exit(1);
-}
-
 //----------------------------------------------------------------------------
 void
 main_stats_page(Stats &stats)
@@ -390,38 +384,57 @@ main_stats_page(Stats &stats)
 
 //----------------------------------------------------------------------------
 int
-main(int argc, char **argv)
+main(int argc, const char **argv)
 {
+#if HAS_CURL
+  static const char USAGE[] = "Usage: traffic_top [-s seconds] [URL|hostname|hostname:port]";
+#else
+  static const char USAGE[] = "Usage: traffic_top [-s seconds]";
+#endif
+
   int sleep_time = 6000;
   bool absolute  = false;
-  int opt;
-  while ((opt = getopt(argc, argv, "s:")) != -1) {
-    switch (opt) {
-    case 's':
-      sleep_time = atoi(optarg) * 1000;
-      break;
-    default:
-      usage();
+  string url;
+
+  AppVersionInfo version;
+  version.setup(PACKAGE_NAME, "traffic_top", PACKAGE_VERSION, __DATE__, __TIME__, BUILD_MACHINE, BUILD_PERSON, "");
+
+  const ArgumentDescription argument_descriptions[] = {
+    {"sleep", 's', "Enable debugging output", "I", &sleep_time, nullptr, nullptr},
+    HELP_ARGUMENT_DESCRIPTION(),
+    VERSION_ARGUMENT_DESCRIPTION(),
+  };
+
+  process_args(&version, argument_descriptions, countof(argument_descriptions), argv, USAGE);
+
+  Layout::create();
+  RecProcessInit(RECM_STAND_ALONE, nullptr /* diags */);
+  LibRecordsConfigInit();
+
+  switch (n_file_arguments) {
+  case 0: {
+    ats_scoped_str rundir(RecConfigReadRuntimeDir());
+
+    TSMgmtError err = TSInit(rundir, static_cast<TSInitOptionT>(TS_MGMT_OPT_NO_EVENTS | TS_MGMT_OPT_NO_SOCK_TESTS));
+    if (err != TS_ERR_OKAY) {
+      fprintf(stderr, "Error: connecting to local manager: %s\n", TSGetErrorMessage(err));
+      exit(1);
     }
+    break;
   }
 
-  string url = "";
+  case 1:
 #if HAS_CURL
-  if (optind >= argc) {
+    url = file_arguments[0];
 #else
-  if (1) {
+    usage(argument_descriptions, countof(argument_descriptions), USAGE);
 #endif
-    if (TS_ERR_OKAY != TSInit(nullptr, static_cast<TSInitOptionT>(TS_MGMT_OPT_NO_EVENTS | TS_MGMT_OPT_NO_SOCK_TESTS))) {
-#if HAS_CURL
-      fprintf(stderr, "Error: missing URL on command line or error connecting to the local manager\n");
-#else
-      fprintf(stderr, "Error: error connecting to the local manager\n");
-#endif
-      usage();
-    }
-  } else {
-    url = argv[optind];
+    break;
+
+  default:
+    usage(argument_descriptions, countof(argument_descriptions), USAGE);
   }
+
   Stats stats(url);
   stats.getStats();
   const string &host = stats.getHost();

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

[trafficserver] 06/09: Fix traffic_layout to not add messages to --json

Posted by zw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch 7.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit 0f1bfdd45acc139e52e4c5dff950ef4116c3daf7
Author: Jason Kenny <dr...@live.com>
AuthorDate: Mon Aug 14 11:21:17 2017 -0500

    Fix traffic_layout to not add messages to --json
    
    Fix issues with possible memory leak with realpath
    fix issue with realpath returning NULL
    Fix issue #2367 realpath error could cause crash
    coverity issues 1379612 1379613 1379614 1379615 1379616 1379617 1379618 1379619
    Clang format
    
    (cherry picked from commit c746df2d6936e670caf0ffb8a450a548ee1de9bb)
---
 cmd/traffic_layout/traffic_layout.cc |  2 +-
 lib/ts/Layout.cc                     |  2 --
 lib/ts/runroot.cc                    | 38 +++++++++++++++++++-----------------
 3 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/cmd/traffic_layout/traffic_layout.cc b/cmd/traffic_layout/traffic_layout.cc
index f22fb57..eb7a452 100644
--- a/cmd/traffic_layout/traffic_layout.cc
+++ b/cmd/traffic_layout/traffic_layout.cc
@@ -178,7 +178,7 @@ 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);
+  runroot_handler(argv, 0 != cl.json);
 
   if (cl.features) {
     produce_features(0 != cl.json);
diff --git a/lib/ts/Layout.cc b/lib/ts/Layout.cc
index 5abbffc..da52989 100644
--- a/lib/ts/Layout.cc
+++ b/lib/ts/Layout.cc
@@ -29,7 +29,6 @@
 #include "ts/I_Layout.h"
 
 #include <fstream>
-#include <iostream>
 #include <unordered_map>
 
 static Layout *layout = nullptr;
@@ -125,7 +124,6 @@ Layout::check_runroot()
     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("/");
diff --git a/lib/ts/runroot.cc b/lib/ts/runroot.cc
index 785e7e5..c6261c4 100644
--- a/lib/ts/runroot.cc
+++ b/lib/ts/runroot.cc
@@ -41,7 +41,6 @@ datadir, libexecdir, libdir, runtimedir, infodir, cachedir.
 
 #include <vector>
 #include <string>
-#include <iostream>
 #include <fstream>
 #include <set>
 #include <unistd.h>
@@ -51,7 +50,7 @@ datadir, libexecdir, libdir, runtimedir, infodir, cachedir.
 // 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)
+check_parent_path(const std::string &path, bool json = false)
 {
   std::string whole_path = path;
   if (whole_path.back() == '/')
@@ -63,7 +62,8 @@ check_parent_path(const std::string &path)
     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;
+      if (!json)
+        ink_notice("using parent of bin/current working dir");
       return whole_path;
     }
   }
@@ -72,7 +72,7 @@ check_parent_path(const std::string &path)
 
 // handler for ts runroot
 void
-runroot_handler(const char **argv)
+runroot_handler(const char **argv, bool json = false)
 {
   std::string command = {};
   std::string arg     = {};
@@ -102,31 +102,33 @@ runroot_handler(const char **argv)
     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;
+      if (!json)
+        ink_notice("using command line path as RUNROOT");
       setenv("USING_RUNROOT", path.c_str(), true);
       return;
     } else {
-      ink_warning("bad RUNROOT");
+      if (!json)
+        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;
+    if (!json)
+      ink_notice("using the environment variable TS_RUNROOT");
     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;
+  char cwd[MAX_CWD_LEN]      = {0};
+  char RealBinPath[PATH_MAX] = {0};
+  if ((argv[0] != nullptr) && (getcwd(cwd, sizeof(cwd)) != nullptr) && (realpath(argv[0], RealBinPath) != nullptr)) {
+    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;
 }

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