support run in container

This commit is contained in:
ruanshudong 2022-02-21 20:40:17 +08:00
parent c8f541fcce
commit 26ce453b08
16 changed files with 2021 additions and 1989 deletions

View File

@ -717,6 +717,9 @@ void Application::main(const TC_Option &option)
string config = TC_File::load2str(ServerConfig::ConfigFile);
__out__.debug() << "config:" << ServerConfig::ConfigFile << endl;
__out__.debug() << "config:" << config << endl;
main(config);
}

View File

@ -239,52 +239,52 @@ void QueryEpBase::setObjName(const string & sObjName)
notifyEndpoints(_activeEndpoints,_inactiveEndpoints,true);
}
}
vector<string> QueryEpBase::sepEndpoint(const string& sEndpoints)
{
vector<string> vEndpoints;
bool flag = false;
string::size_type startPos = 0;
string::size_type sepPos = 0;
for(string::size_type pos = 0; pos < sEndpoints.size(); pos++)
{
if(sEndpoints[pos] == ':' && !flag )
{
sepPos = pos;
flag = true;
}
else if(flag)
{
if(sEndpoints[pos] == ' ')
{
continue;
}
if(TC_Port::strncasecmp("tcp", (sEndpoints.c_str() + pos), 3) == 0
|| TC_Port::strncasecmp("udp", (sEndpoints.c_str() + pos), 3) == 0
|| TC_Port::strncasecmp("ssl", (sEndpoints.c_str() + pos), 3) == 0)
{
string ep = TC_Common::trim(string(sEndpoints.c_str() + startPos, sepPos - startPos));
if(!ep.empty()) {
vEndpoints.push_back(ep);
}
startPos = pos;
}
flag = false;
}
}
string ep = sEndpoints.substr(startPos);
if(!ep.empty()) {
vEndpoints.push_back(ep);
}
// vEndpoints.push_back(sEndpoints.substr(startPos));
return vEndpoints;
}
//
//vector<string> QueryEpBase::sepEndpoint(const string& sEndpoints)
//{
// vector<string> vEndpoints;
// bool flag = false;
// string::size_type startPos = 0;
// string::size_type sepPos = 0;
// for(string::size_type pos = 0; pos < sEndpoints.size(); pos++)
// {
// if(sEndpoints[pos] == ':' && !flag )
// {
// sepPos = pos;
// flag = true;
// }
// else if(flag)
// {
// if(sEndpoints[pos] == ' ')
// {
// continue;
// }
//
// if(TC_Port::strncasecmp("tcp", (sEndpoints.c_str() + pos), 3) == 0
// || TC_Port::strncasecmp("udp", (sEndpoints.c_str() + pos), 3) == 0
// || TC_Port::strncasecmp("ssl", (sEndpoints.c_str() + pos), 3) == 0)
// {
// string ep = TC_Common::trim(string(sEndpoints.c_str() + startPos, sepPos - startPos));
// if(!ep.empty()) {
// vEndpoints.push_back(ep);
// }
// startPos = pos;
// }
//
// flag = false;
// }
// }
//
// string ep = sEndpoints.substr(startPos);
//
// if(!ep.empty()) {
// vEndpoints.push_back(ep);
// }
//
//// vEndpoints.push_back(sEndpoints.substr(startPos));
//
// return vEndpoints;
//}
void QueryEpBase::setEndpoints(const string & sEndpoints, set<EndpointInfo> & setEndpoints)
{
@ -297,7 +297,7 @@ void QueryEpBase::setEndpoints(const string & sEndpoints, set<EndpointInfo> & se
bool bFirstWeightType = true;
unsigned int iWeightType = 0;
vector<string> vEndpoints = sepEndpoint(sEndpoints);
vector<string> vEndpoints = TC_Endpoint::sepEndpoint(sEndpoints);
for (size_t i = 0; i < vEndpoints.size(); ++i)
{

@ -1 +1 @@
Subproject commit 39c6f87733710a28eb5e57e42558c7e016d84eba
Subproject commit 9d299a769d9f827670b726984e40ae9f52b3189c

View File

@ -155,10 +155,10 @@ private:
*/
void setObjName(const string & sObjName);
/*
* endpoint
*/
vector<string> sepEndpoint(const string& sEndpoints);
// /*
// * 解析endpoint
// */
// vector<string> sepEndpoint(const string& sEndpoints);
/*
* sEndpoints提取ip列表信息

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,14 @@
/* A Bison parser, made by GNU Bison 2.7. */
/* A Bison parser, made by GNU Bison 2.3. */
/* Bison interface for Yacc-like parsers in C
/* Skeleton interface for Bison's Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc.
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -15,7 +16,9 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@ -30,16 +33,6 @@
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
#ifndef YY_YY_TARS_TAB_HPP_INCLUDED
# define YY_YY_TARS_TAB_HPP_INCLUDED
/* Enabling traces. */
#ifndef YYDEBUG
# define YYDEBUG 1
#endif
#if YYDEBUG
extern int yydebug;
#endif
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
@ -79,29 +72,48 @@ extern int yydebug;
BAD_CHAR = 288
};
#endif
/* Tokens. */
#define TARS_VOID 258
#define TARS_STRUCT 259
#define TARS_BOOL 260
#define TARS_BYTE 261
#define TARS_SHORT 262
#define TARS_INT 263
#define TARS_DOUBLE 264
#define TARS_FLOAT 265
#define TARS_LONG 266
#define TARS_STRING 267
#define TARS_VECTOR 268
#define TARS_MAP 269
#define TARS_NAMESPACE 270
#define TARS_INTERFACE 271
#define TARS_IDENTIFIER 272
#define TARS_OUT 273
#define TARS_OP 274
#define TARS_KEY 275
#define TARS_ROUTE_KEY 276
#define TARS_REQUIRE 277
#define TARS_OPTIONAL 278
#define TARS_CONST_INTEGER 279
#define TARS_CONST_FLOAT 280
#define TARS_FALSE 281
#define TARS_TRUE 282
#define TARS_STRING_LITERAL 283
#define TARS_SCOPE_DELIMITER 284
#define TARS_CONST 285
#define TARS_ENUM 286
#define TARS_UNSIGNED 287
#define BAD_CHAR 288
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef int YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif
extern YYSTYPE yylval;
#ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus
int yyparse (void *YYPARSE_PARAM);
#else
int yyparse ();
#endif
#else /* ! YYPARSE_PARAM */
#if defined __STDC__ || defined __cplusplus
int yyparse (void);
#else
int yyparse ();
#endif
#endif /* ! YYPARSE_PARAM */
#endif /* !YY_YY_TARS_TAB_HPP_INCLUDED */

View File

@ -1,6 +1,6 @@
// **********************************************************************
// This file was generated by a TARS parser!
// TARS version 3.0.3.
// TARS version 3.0.4.
// **********************************************************************
#ifndef __HELLO_H_

View File

@ -111,7 +111,7 @@ TEST_F(UtilEpollServerTest, RunTcp)
TEST_F(UtilEpollServerTest, RunEnableManualListen)
{
int i = 0;
// int i = 0;
for(int i = 0; i <= TC_EpollServer::NET_THREAD_MERGE_HANDLES_CO; i++)
{
MyTcpServer server;

35
unit-test/util/test_tc_port.cpp Executable file
View File

@ -0,0 +1,35 @@
#include "util/tc_port.h"
#include "util/tc_common.h"
#include <cmath>
#include "gtest/gtest.h"
#include <iostream>
#include <vector>
using namespace std;
using namespace tars;
class UtilPortTest : public testing::Test
{
public:
//添加日志
static void SetUpTestCase()
{
}
static void TearDownTestCase()
{
}
virtual void SetUp() //TEST跑之前会执行SetUp
{
}
virtual void TearDown() //TEST跑完之后会执行TearDown
{
}
};
TEST_F(UtilPortTest, testExec)
{
string err;
string result = TC_Port::exec("ls '*.txt'", err);
cout << result << endl;
}

View File

@ -369,6 +369,12 @@ public:
*/
void parse(const string &desc);
/*
* endpoint(tcp -h xxx -p yyy:udp -h xxx -p yyy:ssl -h xxx -p xxx)
* ipv6地址
*/
static vector<string> sepEndpoint(const string& sEndpoints);
private:
void init(const string& host, int port, int timeout, EType type, int grid, int qos, int weight, unsigned int weighttype, AUTH_TYPE authType);

View File

@ -2,6 +2,7 @@
#define __TC_PORT_H
#include "util/tc_platform.h"
#include "util/tc_ex.h"
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
@ -36,6 +37,15 @@ using namespace std;
namespace tars
{
/**
* @brief port异常类
*/
struct TC_Port_Exception : public TC_Exception
{
TC_Port_Exception(const string &buffer) : TC_Exception(buffer){};
~TC_Port_Exception() throw() {};
};
class TC_Port
{
public:
@ -81,14 +91,47 @@ public:
static int64_t getpid();
/**
*
* @param name
* @return
*/
static std::string getEnv(const std::string &name);
/**
*
* @param name
* @param value
*/
static void setEnv(const std::string &name, const std::string &value);
/**
*
* @param cmd
* @param err
* @return
*/
static std::string exec(const char* cmd);
/**
* (+)
* @param cmd
* @param err
* @return:
*/
static std::string exec(const char* cmd, std::string &err);
/**
* fork子进程并运行程序
* @param sExe:
* @param sPwdPath:
* @param sRollLogPath: (stdout会重定向到滚动日志),
* @param vOptions:
* @return id: ==0: , >0: (pid), TC_Port_Exception
*/
static int64_t forkExec(const string& sExe, const string& sPwdPath, const string& sRollLogPath, const vector<string>& vOptions);
/**
* ctrl+c回调事件(SIGINT/CTRL_C_EVENT)
* @param callback
* @return size_t, id,

View File

@ -250,7 +250,6 @@ public:
*/
void init(size_t num);
/**
* @brief 线, 线
*/

View File

@ -256,6 +256,51 @@ void TC_Endpoint::parse(const string &str)
// _authType = 1;
}
vector<string> TC_Endpoint::sepEndpoint(const string& sEndpoints)
{
vector<string> vEndpoints;
bool flag = false;
string::size_type startPos = 0;
string::size_type sepPos = 0;
for(string::size_type pos = 0; pos < sEndpoints.size(); pos++)
{
if(sEndpoints[pos] == ':' && !flag )
{
sepPos = pos;
flag = true;
}
else if(flag)
{
if(sEndpoints[pos] == ' ')
{
continue;
}
if(TC_Port::strncasecmp("tcp", (sEndpoints.c_str() + pos), 3) == 0
|| TC_Port::strncasecmp("udp", (sEndpoints.c_str() + pos), 3) == 0
|| TC_Port::strncasecmp("ssl", (sEndpoints.c_str() + pos), 3) == 0)
{
string ep = TC_Common::trim(string(sEndpoints.c_str() + startPos, sepPos - startPos));
if(!ep.empty()) {
vEndpoints.push_back(ep);
}
startPos = pos;
}
flag = false;
}
}
string ep = sEndpoints.substr(startPos);
if(!ep.empty()) {
vEndpoints.push_back(ep);
}
return vEndpoints;
}
/*************************************TC_TCPClient**************************************/
TC_ClientSocket::TC_ClientSocket() : _port(0),_timeout(3000)

View File

@ -272,6 +272,155 @@ std::string TC_Port::exec(const char* cmd, std::string &err)
return fileData;
}
int64_t TC_Port::forkExec(const string& sExePath, const string& sPwdPath, const string& sRollLogPath, const vector<string>& vOptions)
{
vector<string> vEnvs;
if (sExePath.empty())
{
throw TC_Port_Exception("[TC_Port::forkExec] server exe: " + sExePath + " is empty.");
}
#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
if (TC_File::isFileExistEx(sExePath) && !TC_File::canExecutable(sExePath))
{
TC_File::setExecutable(sExePath, true);
}
#endif
//
// Current directory
//
const char *pwdCStr = sPwdPath.c_str();
#if TARGET_PLATFORM_WINDOWS
vector<string> vArgs;
vArgs.insert(vArgs.end(), vOptions.begin(), vOptions.end());
string path;
for (vector<string>::const_iterator p = vArgs.begin(); p != vArgs.end(); ++p)
{
path += " " + *p;
}
string command = sExePath + " " + path;
TCHAR p[1024];
strncpy_s(p, sizeof(p) / sizeof(TCHAR), command.c_str(), command.length());
STARTUPINFO si;
memset(&si, 0, sizeof(si));
PROCESS_INFORMATION pi;
memset(&pi, 0, sizeof(pi));
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE; //TRUE表示显示创建的进程的窗口
if (!CreateProcessA(
NULL, // 指向一个NULL结尾的、用来指定可执行模块的宽字节字符串
p, // 命令行字符串
NULL, // 指向一个SECURITY_ATTRIBUTES结构体这个结构体决定是否返回的句柄可以被子进程继承。
NULL, // 如果lpProcessAttributes参数为空NULL那么句柄不能被继承。<同上>
false, // 指示新进程是否从调用进程处继承了句柄。
CREATE_NEW_CONSOLE|CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, // 指定附加的、用来控制优先类和进程的创建的标
NULL, // 指向一个新进程的环境块。如果此参数为空,新进程使用调用进程的环境
pwdCStr, // 指定子进程的工作路径
&si, // 决定新进程的主窗体如何显示的STARTUPINFO结构体
&pi // 接收新进程的识别信息的PROCESS_INFORMATION结构体
))
{
string err = TC_Exception::parseError(TC_Exception::getSystemCode());
throw TC_Port_Exception("[TC_Port::forkExec] CreateProcessA exception:" + err);
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return pi.dwProcessId;
#else
vector<string> vArgs;
vArgs.push_back(sExePath);
vArgs.insert(vArgs.end(), vOptions.begin(), vOptions.end());
int argc = static_cast<int>(vArgs.size());
char **argv = static_cast<char **>(malloc((argc + 1) * sizeof(char *)));
int i = 0;
for (vector<string>::const_iterator p = vArgs.begin(); p != vArgs.end(); ++p, ++i)
{
assert(i < argc);
argv[i] = strdup(p->c_str());
}
assert(i == argc);
argv[argc] = 0;
pid_t pid = fork();
if (pid == -1)
{
throw TC_Port_Exception("[TC_Port::forkExec] fork exception");
}
if (pid == 0)
{
int maxFd = static_cast<int>(sysconf(_SC_OPEN_MAX));
for (int fd = 3; fd < maxFd; ++fd)
{
close(fd);
}
//server stdcout 日志在滚动日志显示
if (!sRollLogPath.empty())
{
TC_File::makeDirRecursive(TC_File::extractFilePath(sRollLogPath));
#if TARGET_PLATFORM_IOS
if ((freopen(sRollLogPath.c_str(), "ab", stdout)) != NULL && (freopen(sRollLogPath.c_str(), "ab", stderr)) != NULL)
#else
if ((freopen64(sRollLogPath.c_str(), "ab", stdout)) != NULL && (freopen64(sRollLogPath.c_str(), "ab", stderr)) != NULL)
#endif
{
cout << argv[0] << " redirect stdout and stderr to " << sRollLogPath << endl;
}
else
{
//重定向失败 直接退出
exit(0);
}
}
else
{
cout << argv[0] << " cannot redirect stdout and stderr to log file sRollLogPath is empty" << endl;
}
// for_each(vEnvs.begin(), vEnvs.end(), EnvVal());
if (strlen(pwdCStr) != 0)
{
if (chdir(pwdCStr) == -1)
{
cerr << argv[0] << " cannot change working directory to " << pwdCStr << "|errno=" << errno << endl;
}
}
if (execvp(argv[0], argv) == -1)
{
cerr << "cannot execute " << argv[0] << "|errno=" << strerror(errno) << endl;
}
exit(0);
}
else
{
for (i = 0; argv[i]; i++)
{
free(argv[i]);
}
free(argv);
}
return pid;
#endif
}
shared_ptr<TC_Port::SigInfo> TC_Port::_sigInfo = std::make_shared<TC_Port::SigInfo>();