!32 sync with openeuler stable 2.0.0

Merge pull request !32 from lifeng_isula/lts
This commit is contained in:
haozi007 2020-05-25 12:55:14 +08:00 committed by Gitee
commit 321f0ab677
30 changed files with 781 additions and 335 deletions

View File

@ -9,7 +9,7 @@ include(cmake/set_build_flags.cmake)
#set(CMAKE_C_COMPILER "gcc" CACHE PATH "c compiler")
set(GIT_COMMIT_HASH "d03048c03e5f83d8de4e6f164f354a9cb8316362")
set(GIT_COMMIT_HASH "237e7cb8572b23cde98864077c5ea89ea19bfec1")
message("-- commit id: " ${GIT_COMMIT_HASH})
add_definitions(-DISULAD_GIT_COMMIT="${GIT_COMMIT_HASH}")

View File

@ -1,5 +1,5 @@
%global _version 2.0.0
%global _release 20200406.224614.gitd03048c0
%global _release 20200428.173159.git237e7cb8
%global is_systemd 1
%global debug_package %{nil}

View File

@ -231,18 +231,27 @@ static int request_pack_custom_env(struct client_arguments *args, isula_containe
{
int ret = 0;
char *pe = NULL;
char *new_env = NULL;
if (args->custom_conf.env != NULL) {
size_t i;
for (i = 0; i < util_array_len((const char **)(args->custom_conf.env)); i++) {
if (util_array_append(&conf->env, args->custom_conf.env[i]) != 0) {
COMMAND_ERROR("Failed to append custom config env list");
if (util_validate_env(args->custom_conf.env[i], &new_env) != 0) {
COMMAND_ERROR("Invalid environment %s", args->custom_conf.env[i]);
ret = -1;
goto out;
}
if (new_env == NULL) {
continue;
}
if (util_array_append(&conf->env, new_env) != 0) {
COMMAND_ERROR("Failed to append custom config env list %s", new_env);
ret = -1;
goto out;
}
free(new_env);
new_env = NULL;
}
util_free_array(args->custom_conf.env);
args->custom_conf.env = conf->env; /* make sure args->custom_conf.env point to valid memory. */
conf->env_len = util_array_len((const char **)(conf->env));
}
@ -255,9 +264,7 @@ static int request_pack_custom_env(struct client_arguments *args, isula_containe
goto out;
}
}
args->custom_conf.env = conf->env; /* make sure args->custom_conf.env point to valid memory. */
conf->env_len = util_array_len((const char **)(conf->env));
conf->accel = args->custom_conf.accel;
conf->accel_len = util_array_len((const char **)(args->custom_conf.accel));
if (util_env_set_isulad_enable_plugins(&conf->env, &conf->env_len, ISULAD_ISULA_ADAPTER)) {
@ -269,52 +276,7 @@ static int request_pack_custom_env(struct client_arguments *args, isula_containe
out:
free(pe);
return ret;
}
static int validate_env(const char *env, char **dst)
{
int ret = 0;
char *value = NULL;
char **arr = util_string_split_multi(env, '=');
if (arr == NULL) {
ERROR("Failed to split env string");
return -1;
}
if (strlen(arr[0]) == 0) {
ERROR("Invalid environment variable: %s", env);
ret = -1;
goto out;
}
if (util_array_len((const char **)arr) > 1) {
*dst = util_strdup_s(env);
goto out;
}
value = getenv(env);
if (value == NULL) {
*dst = util_strdup_s(env);
goto out;
} else {
int sret;
size_t len = strlen(env) + 1 + strlen(value) + 1;
*dst = (char *)util_common_calloc_s(len);
if (*dst == NULL) {
ERROR("Out of memory");
ret = -1;
goto out;
}
sret = snprintf(*dst, len, "%s=%s", env, value);
if (sret < 0 || (size_t)sret >= len) {
ERROR("Failed to compose env string");
ret = -1;
goto out;
}
}
out:
util_free_array(arr);
free(new_env);
return ret;
}
@ -345,7 +307,7 @@ static int read_env_from_file(const char *path, size_t file_size, isula_containe
continue;
}
buf[len - 1] = '\0';
if (validate_env(buf, &new_env) != 0) {
if (util_validate_env(buf, &new_env) != 0) {
ret = -1;
goto out;
}

View File

@ -38,11 +38,64 @@ sem_t g_command_waitexit_sem;
struct client_arguments g_cmd_exec_args = {};
static int fill_exec_request(const struct client_arguments *args, const struct command_fifo_config *fifos,
struct isula_exec_request *request)
{
int ret = 0;
size_t i = 0;
char *new_env = NULL;
request->name = util_strdup_s(args->name);
request->suffix = util_strdup_s(args->exec_suffix);
request->tty = args->custom_conf.tty;
request->open_stdin = args->custom_conf.open_stdin;
request->attach_stdin = args->custom_conf.attach_stdin;
request->attach_stdout = args->custom_conf.attach_stdout;
request->attach_stderr = args->custom_conf.attach_stderr;
if (fifos != NULL) {
request->stdin = util_strdup_s(fifos->stdin_name);
request->stdout = util_strdup_s(fifos->stdout_name);
request->stderr = util_strdup_s(fifos->stderr_name);
}
request->user = util_strdup_s(args->custom_conf.user);
if (dup_array_of_strings((const char **)args->argv, args->argc, &(request->argv), (size_t *) & (request->argc)) != 0) {
ERROR("Failed to dup args");
ret = -1;
goto out;
}
/* environment variables */
for (i = 0; i < util_array_len((const char **)(args->extra_env)); i++) {
if (util_validate_env(args->extra_env[i], &new_env) != 0) {
ERROR("Invalid environment %s", args->extra_env[i]);
ret = -1;
goto out;
}
if (new_env == NULL) {
continue;
}
if (util_array_append(&request->env, new_env) != 0) {
ERROR("Failed to append custom config env list %s", new_env);
ret = -1;
goto out;
}
request->env_len++;
free(new_env);
new_env = NULL;
}
out:
free(new_env);
return ret;
}
static int client_exec(const struct client_arguments *args, const struct command_fifo_config *fifos,
uint32_t *exit_code)
{
isula_connect_ops *ops = NULL;
struct isula_exec_request request = { 0 };
struct isula_exec_request *request = NULL;
struct isula_exec_response *response = NULL;
client_connect_config_t config = { 0 };
int ret = 0;
@ -53,26 +106,18 @@ static int client_exec(const struct client_arguments *args, const struct command
return ECOMMON;
}
request.name = args->name;
request.suffix = args->exec_suffix;
request.tty = args->custom_conf.tty;
request.open_stdin = args->custom_conf.open_stdin;
request.attach_stdin = args->custom_conf.attach_stdin;
request.attach_stdout = args->custom_conf.attach_stdout;
request.attach_stderr = args->custom_conf.attach_stderr;
if (fifos != NULL) {
request.stdin = fifos->stdin_name;
request.stdout = fifos->stdout_name;
request.stderr = fifos->stderr_name;
request = util_common_calloc_s(sizeof(struct isula_exec_request));
if (request == NULL) {
ERROR("Out of memory");
ret = ECOMMON;
goto out;
}
request.user = args->custom_conf.user;
request.argc = args->argc;
request.argv = (char **)args->argv;
/* environment variables */
request.env_len = util_array_len((const char **)(args->extra_env));
request.env = args->extra_env;
if (fill_exec_request(args, fifos, request) != 0) {
ERROR("Failed to fill exec request");
ret = ECOMMON;
goto out;
}
ops = get_connect_client_ops();
if (ops == NULL || !ops->container.exec) {
@ -82,7 +127,7 @@ static int client_exec(const struct client_arguments *args, const struct command
}
config = get_connect_config(args);
ret = ops->container.exec(&request, response, &config);
ret = ops->container.exec(request, response, &config);
if (ret) {
client_print_error(response->cc, response->server_errono, response->errmsg);
ret = ECOMMON;
@ -94,6 +139,7 @@ out:
}
isula_exec_response_free(response);
isula_exec_request_free(request);
return ret;
}

View File

@ -48,6 +48,8 @@
#define NETWORK_MOUNT_FILE_MODE 0644
#define ETC_FILE_MODE 0755
#define ISULAD_CONFIG "/etc/isulad"
#define ISULAD_DAEMON_JSON_CONF_FILE ISULAD_CONFIG "/daemon.json"

View File

@ -1294,6 +1294,41 @@ out:
return bret;
}
bool util_deal_with_mount_info(mount_info_call_back_t cb, const char *pattern)
{
FILE *fp = NULL;
char *line = NULL;
char *mountpoint = NULL;
size_t length = 0;
bool bret = true;
int nret = 0;
fp = util_fopen("/proc/self/mountinfo", "r");
if (fp == NULL) {
ERROR("Failed opening /proc/self/mountinfo");
return false;
}
while (getline(&line, &length, fp) != -1) {
mountpoint = get_mtpoint(line);
if (mountpoint == NULL) {
INFO("Error reading mountinfo: bad line '%s'", line);
continue;
}
nret = cb(mountpoint, pattern);
free(mountpoint);
if (nret != 0) {
bret = false;
goto out;
}
}
out:
fclose(fp);
free(line);
return bret;
}
static int set_echo_back(bool echo_back)
{
struct termios old, new;
@ -1474,3 +1509,49 @@ void add_array_kv(char **array, size_t total, size_t *pos, const char *k, const
add_array_elem(array, total, pos, v);
}
int util_validate_env(const char *env, char **dst)
{
int ret = 0;
char *value = NULL;
char **arr = util_string_split_multi(env, '=');
if (arr == NULL) {
ERROR("Failed to split env string");
return -1;
}
if (strlen(arr[0]) == 0) {
ERROR("Invalid environment variable: %s", env);
ret = -1;
goto out;
}
if (util_array_len((const char **)arr) > 1) {
*dst = util_strdup_s(env);
goto out;
}
value = getenv(env);
if (value == NULL) {
*dst = NULL;
goto out;
} else {
int sret;
size_t len = strlen(env) + 1 + strlen(value) + 1;
*dst = (char *)util_common_calloc_s(len);
if (*dst == NULL) {
ERROR("Out of memory");
ret = -1;
goto out;
}
sret = snprintf(*dst, len, "%s=%s", env, value);
if (sret < 0 || (size_t)sret >= len) {
ERROR("Failed to compose env string");
ret = -1;
goto out;
}
}
out:
util_free_array(arr);
return ret;
}

View File

@ -428,6 +428,11 @@ void add_array_elem(char **array, size_t total, size_t *pos, const char *elem);
void add_array_kv(char **array, size_t total, size_t *pos, const char *k, const char *v);
typedef int (*mount_info_call_back_t)(const char *, const char *);
bool util_deal_with_mount_info(mount_info_call_back_t cb, const char *);
int util_validate_env(const char *env, char **dst);
#ifdef __cplusplus
}
#endif

View File

@ -23,6 +23,8 @@
#include <sys/mman.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <regex.h>
#include <dirent.h>
@ -182,6 +184,39 @@ static bool check_dir_valid(const char *dirpath, int recursive_depth, int *failu
return true;
}
static int mark_file_mutable(const char *fname)
{
int ret = 0;
int fd = -EBADF;
int attributes = 0;
fd = open(fname, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
if (fd < 0) {
ERROR("Failed to open file to modify flags:%s, %s", fname, strerror(errno));
return -1;
}
if (ioctl(fd, FS_IOC_GETFLAGS, &attributes) < 0) {
ERROR("Failed to retrieve file flags");
ret = -1;
goto out;
}
attributes &= ~FS_IMMUTABLE_FL;
if (ioctl(fd, FS_IOC_SETFLAGS, &attributes) < 0) {
ERROR("Failed to set file flags");
ret = -1;
goto out;
}
out:
if (fd >= 0) {
close(fd);
}
return ret;
}
static int recursive_rmdir_next_depth(struct stat fstat, const char *fname, int recursive_depth, int *saved_errno,
int failure)
{
@ -191,11 +226,19 @@ static int recursive_rmdir_next_depth(struct stat fstat, const char *fname, int
}
} else {
if (unlink(fname) < 0) {
ERROR("Failed to delete %s: %s", fname, strerror(errno));
ERROR("Failed to delete \"%s\": %s", fname, strerror(errno));
if (*saved_errno == 0) {
*saved_errno = errno;
}
failure = 1;
if (mark_file_mutable(fname) != 0) {
ERROR("Failed to mark file mutable");
}
if (unlink(fname) < 0) {
ERROR("Failed to delete \"%s\": %s", fname, strerror(errno));
failure = 1;
}
}
}
@ -934,3 +977,133 @@ free_out:
return ret;
}
char *util_path_base(const char *path)
{
char *dir = NULL;
int len = 0;
int i = 0;
if (path == NULL) {
ERROR("invalid NULL param");
return NULL;
}
len = (int)strlen(path);
if (len == 0) {
return util_strdup_s(".");
}
dir = util_strdup_s(path);
// strip last slashes
for (i = len - 1; i >= 0; i--) {
if (dir[i] != '/') {
break;
}
dir[i] = '\0';
}
len = (int)strlen(dir);
if (len == 0) {
free(dir);
return util_strdup_s("/");
}
for (i = len - 1; i >= 0; i--) {
if (dir[i] == '/') {
break;
}
}
if (i < 0) {
return dir;
}
char *result = util_strdup_s(&dir[i + 1]);
free(dir);
return result;
}
static char *get_random_tmp_file(const char *fname)
{
#define RANDOM_TMP_PATH 10
int nret = 0;
char *result = NULL;
char *base = NULL;
char *dir = NULL;
char rpath[PATH_MAX] = { 0x00 };
char random_tmp[RANDOM_TMP_PATH + 1] = { 0x00 };
base = util_path_base(fname);
if (base == NULL) {
ERROR("Failed to get base of %s", fname);
goto out;
}
dir = util_path_dir(fname);
if (dir == NULL) {
ERROR("Failed to get dir of %s", fname);
goto out;
}
if (util_generate_random_str(random_tmp, (size_t)RANDOM_TMP_PATH)) {
ERROR("Failed to generate random str for random path");
goto out;
}
nret = snprintf(rpath, PATH_MAX, ".tmp-%s-%s", base, random_tmp);
if (nret < 0 || nret >= PATH_MAX) {
ERROR("Failed to generate tmp base file");
goto out;
}
result = util_path_join(dir, rpath);
out:
free(base);
free(dir);
return result;
}
int util_atomic_write_file(const char *fname, const char *content, size_t content_len, mode_t mode)
{
int ret = 0;
char *tmp_file = NULL;
char rpath[PATH_MAX] = { 0x00 };
if (fname == NULL) {
return -1;
}
if (content == NULL || content_len == 0) {
return 0;
}
if (cleanpath(fname, rpath, sizeof(rpath)) == NULL) {
return -1;
}
tmp_file = get_random_tmp_file(fname);
if (tmp_file == NULL) {
ERROR("Failed to get tmp file for %s", fname);
ret = -1;
goto free_out;
}
ret = util_write_file(tmp_file, content, content_len, mode);
if (ret != 0) {
ERROR("Failed to write content to tmp file for %s", tmp_file);
ret = -1;
goto free_out;
}
ret = rename(tmp_file, rpath);
if (ret != 0) {
ERROR("Failed to rename old file %s to target %s", tmp_file, rpath);
ret = -1;
goto free_out;
}
free_out:
free(tmp_file);
return ret;
}

View File

@ -75,6 +75,10 @@ char *verify_file_and_get_real_path(const char *file);
int util_copy_file(const char *src_file, const char *dst_file, mode_t mode);
char *util_path_base(const char *path);
int util_atomic_write_file(const char *fname, const char *content, size_t content_len, mode_t mode);
#ifdef __cplusplus
}
#endif

View File

@ -667,26 +667,17 @@ void isula_exec_request_free(struct isula_exec_request *request)
free(request->stderr);
request->stderr = NULL;
if (request->argc && request->argv != NULL) {
int i;
for (i = 0; i < request->argc; i++) {
free(request->argv[i]);
request->argv[i] = NULL;
}
free(request->argv);
request->argv = NULL;
request->argc = 0;
}
if (request->env_len && request->env != NULL) {
size_t j;
for (j = 0; j < request->env_len; j++) {
free(request->env[j]);
request->env[j] = NULL;
}
free(request->env);
request->env = NULL;
request->env_len = 0;
}
free(request->user);
request->user = NULL;
util_free_array_by_len(request->argv, request->argc);
request->argv = NULL;
request->argc = 0;
util_free_array_by_len(request->env, request->env_len);
request->env = NULL;
request->env_len = 0;
free(request);
}

View File

@ -606,6 +606,12 @@ static int shim_create(bool fg, const char *id, const char *workdir,
goto realexec;
}
// clear NOTIFY_SOCKET from the env to adapt runc create
if (unsetenv("NOTIFY_SOCKET") != 0) {
(void)dprintf(exec_fd[1], "%s: unset env NOTIFY_SOCKET failed %s", id, strerror(errno));
exit(EXIT_FAILURE);
}
pid = fork();
if (pid < 0) {
(void)dprintf(exec_fd[1], "%s: fork shim-process failed %s", id, strerror(errno));

View File

@ -19,21 +19,18 @@
#include <vector>
#include <utility>
#include <set>
#include <chrono>
#include "cxxutils.h"
#include "log.h"
#include "utils.h"
#include "cri_helpers.h"
namespace Network {
static std::string VendorCNIDir(const std::string &prefix, const std::string &pluginType)
{
return prefix + "/opt/" + pluginType + "/bin";
}
static std::unique_ptr<CNINetwork> GetLoNetwork(const std::string &binDir, const std::string &vendorDirPrefix)
static std::unique_ptr<CNINetwork> GetLoNetwork(std::vector<std::string> binDirs, const std::string &vendorDirPrefix)
{
const std::string loNetConfListJson { "{\"cniVersion\": \"0.3.0\", \"name\": \"cni-loopback\","
"\"plugins\":[{\"type\": \"loopback\" }]}" };
"\"plugins\":[{\"type\": \"loopback\" }]}" };
char *cerr { nullptr };
struct cni_network_list_conf *loConf {
@ -62,8 +59,7 @@ static std::unique_ptr<CNINetwork> GetLoNetwork(const std::string &binDir, const
return nullptr;
}
result->InsertPath(VendorCNIDir(vendorDirPrefix, "loopback"));
result->InsertPath(binDir);
result->SetPaths(binDirs);
return result;
}
@ -92,8 +88,9 @@ void ProbeNetworkPlugins(const std::string &pluginDir, const std::string &binDir
std::vector<std::shared_ptr<NetworkPlugin>> *plugins)
{
const std::string useBinDir = binDir.empty() ? DEFAULT_CNI_DIR : binDir;
auto plugin = std::make_shared<CniNetworkPlugin>(useBinDir, pluginDir);
plugin->SetLoNetwork(GetLoNetwork(useBinDir, ""));
std::vector<std::string> binDirs = CXXUtils::Split(useBinDir, ',');
auto plugin = std::make_shared<CniNetworkPlugin>(binDirs, pluginDir);
plugin->SetLoNetwork(GetLoNetwork(binDirs, ""));
plugins->push_back(plugin);
}
@ -104,17 +101,43 @@ void CniNetworkPlugin::SetLoNetwork(std::unique_ptr<CNINetwork> lo)
}
}
CniNetworkPlugin::CniNetworkPlugin(const std::string &binDir, const std::string &pluginDir,
const std::string &vendorCNIDirPrefix)
: m_pluginDir(pluginDir)
, m_vendorCNIDirPrefix(vendorCNIDirPrefix)
, m_binDir(binDir)
void CniNetworkPlugin::SetDefaultNetwork(std::unique_ptr<CNINetwork> network,
std::vector<std::string> &binDirs, Errors &err)
{
if (network == nullptr) {
return;
}
WLockNetworkMap(err);
if (err.NotEmpty()) {
ERROR("%s", err.GetCMessage());
return;
}
m_defaultNetwork = std::move(network);
m_defaultNetwork->SetPaths(binDirs);
DEBUG("Update new cni network: \"%s\"", m_defaultNetwork->GetName().c_str());
UnlockNetworkMap(err);
if (err.NotEmpty()) {
ERROR("%s", err.GetCMessage());
}
}
CniNetworkPlugin::CniNetworkPlugin(std::vector<std::string> &binDirs, const std::string &confDir,
const std::string &podCidr)
: m_confDir(confDir)
, m_binDirs(binDirs)
, m_podCidr(podCidr)
, m_needFinish(false)
{
}
CniNetworkPlugin::~CniNetworkPlugin()
{
m_networks.clear();
m_needFinish = true;
if (m_syncThread.joinable()) {
m_syncThread.join();
}
}
void CniNetworkPlugin::PlatformInit(Errors &error)
@ -232,65 +255,16 @@ out:
return ret;
}
int CniNetworkPlugin::InsertNewNetwork(struct cni_network_list_conf *n_list,
std::map<std::string, std::unique_ptr<CNINetwork>> &newNets,
const std::string &binDir, const std::string &vendorCNIDirPrefix, Errors &err)
{
std::string confType { "" };
if (n_list == nullptr) {
err.Errorf("Invalid arguments");
return -1;
}
if (n_list->first_plugin_type != nullptr) {
confType = n_list->first_plugin_type;
}
std::string tpath = VendorCNIDir(vendorCNIDirPrefix, confType);
if (tpath.empty()) {
free_cni_network_list_conf(n_list);
err.SetError("Out of memory");
return -1;
}
std::unique_ptr<CNINetwork> network(new (std::nothrow) CNINetwork(n_list->name, n_list));
if (network == nullptr) {
free_cni_network_list_conf(n_list);
err.SetError("Out of memory");
return -1;
}
network->InsertPath(tpath);
network->InsertPath(binDir);
std::string n_key(network->GetName());
newNets.insert(std::pair<std::string, std::unique_ptr<CNINetwork>>(n_key, std::move(network)));
DEBUG("---parse cni network: %s finish ----", n_key.c_str());
return 0;
}
void CniNetworkPlugin::ResetCNINetwork(std::map<std::string, std::unique_ptr<CNINetwork>> &newNets, Errors &err)
{
std::string pluginNames { "map[" };
m_networks.clear();
for (auto iter = newNets.begin(); iter != newNets.end(); iter++) {
m_networks[iter->first] = std::move(iter->second);
pluginNames += (iter->first + " ");
}
INFO("Loaded cni plugins successfully, all plugins: %s]", pluginNames.substr(0, pluginNames.length() - 1).c_str());
}
void CniNetworkPlugin::GetCNINetwork(const std::string &pluginDir, const std::string &binDir,
const std::string &vendorCNIDirPrefix, Errors &err)
void CniNetworkPlugin::GetDefaultCNINetwork(const std::string &confDir, std::vector<std::string> &binDirs, Errors &err)
{
std::vector<std::string> files;
std::set<std::string> allPanes;
std::map<std::string, std::unique_ptr<CNINetwork>> newNets;
bool found = false;
if (GetCNIConfFiles(pluginDir, files, err) != 0) {
if (GetCNIConfFiles(confDir, files, err) != 0) {
goto free_out;
}
sort(files.begin(), files.end());
for (auto elem : files) {
struct cni_network_list_conf *n_list = nullptr;
@ -305,23 +279,15 @@ void CniNetworkPlugin::GetCNINetwork(const std::string &pluginDir, const std::st
continue;
}
if (InsertConfNameToAllPanes(n_list, allPanes, err) != 0) {
goto free_out;
}
if (InsertNewNetwork(n_list, newNets, binDir, vendorCNIDirPrefix, err) != 0) {
goto free_out;
}
SetDefaultNetwork(std::unique_ptr<CNINetwork>(new (std::nothrow) CNINetwork(n_list->name, n_list)), binDirs, err);
found = true;
break;
}
if (newNets.size() == 0) {
err.Errorf("No valid networks found in %s", pluginDir.c_str());
goto free_out;
if (!found) {
err.Errorf("No valid networks found in %s", confDir.c_str());
}
ResetCNINetwork(newNets, err);
free_out:
newNets.clear();
return;
}
@ -332,9 +298,9 @@ void CniNetworkPlugin::CheckInitialized(Errors &err)
ERROR("%s", err.GetCMessage());
return;
}
size_t len = m_networks.size();
bool inited = (m_defaultNetwork != nullptr);
UnlockNetworkMap(err);
if (len == 0) {
if (!inited) {
err.AppendError("cni config uninitialized");
}
}
@ -342,19 +308,10 @@ void CniNetworkPlugin::CheckInitialized(Errors &err)
void CniNetworkPlugin::SyncNetworkConfig()
{
Errors err;
WLockNetworkMap(err);
if (err.NotEmpty()) {
ERROR("%s", err.GetCMessage());
return;
}
GetCNINetwork(m_pluginDir, m_binDir, m_vendorCNIDirPrefix, err);
GetDefaultCNINetwork(m_confDir, m_binDirs, err);
if (err.NotEmpty()) {
WARN("Unable to update cni config: %s", err.GetCMessage());
}
UnlockNetworkMap(err);
if (err.NotEmpty()) {
ERROR("%s", err.GetCMessage());
}
}
void CniNetworkPlugin::Init(CRIRuntimeServiceImpl *criImpl, const std::string &hairpinMode,
@ -375,6 +332,10 @@ void CniNetworkPlugin::Init(CRIRuntimeServiceImpl *criImpl, const std::string &h
m_criImpl = criImpl;
SyncNetworkConfig();
// start a thread to sync network config from confDir periodically to detect network config updates in every 5 seconds
m_syncThread = std::thread([&]() {
UpdateDefaultNetwork();
});
return;
}
@ -385,14 +346,13 @@ const std::string &CniNetworkPlugin::Name() const
void CniNetworkPlugin::Status(Errors &err)
{
SyncNetworkConfig();
CheckInitialized(err);
}
void CniNetworkPlugin::SetUpPod(const std::string &ns, const std::string &name, const std::string &networkPlane,
void CniNetworkPlugin::SetUpPod(const std::string &ns, const std::string &name,
const std::string &interfaceName, const std::string &id,
const std::map<std::string, std::string> &annotations, Errors &err)
const std::map<std::string, std::string> &annotations,
const std::map<std::string, std::string> &options, Errors &err)
{
CheckInitialized(err);
if (err.NotEmpty()) {
@ -403,16 +363,10 @@ void CniNetworkPlugin::SetUpPod(const std::string &ns, const std::string &name,
ERROR("CNI failed to retrieve network namespace path: %s", err.GetCMessage());
return;
}
auto iter = annotations.find(CRIHelpers::Constants::POD_CHECKPOINT_KEY);
std::string jsonCheckpoint { "" };
if (iter != annotations.end()) {
jsonCheckpoint = iter->second;
}
DEBUG("add checkpoint: ", jsonCheckpoint.c_str());
struct result *preResult = nullptr;
if (m_loNetwork != nullptr) {
AddToNetwork(m_loNetwork.get(), jsonCheckpoint, name, ns, interfaceName, id, netnsPath, &preResult, err);
AddToNetwork(m_loNetwork.get(), name, ns, interfaceName, id, netnsPath, annotations, options, &preResult, err);
free_result(preResult);
preResult = nullptr;
if (err.NotEmpty()) {
@ -426,26 +380,20 @@ void CniNetworkPlugin::SetUpPod(const std::string &ns, const std::string &name,
ERROR("%s", err.GetCMessage());
return;
}
auto netIter = m_networks.find(networkPlane);
if (netIter == m_networks.end()) {
ERROR("Can't find cni plugin for network plane %s.", networkPlane.c_str());
err.Errorf("Can't find cni plugin for network plane %s.", networkPlane.c_str());
goto unlock_out;
}
AddToNetwork((netIter->second).get(), jsonCheckpoint, name, ns, interfaceName, id, netnsPath, &preResult, err);
AddToNetwork(m_defaultNetwork.get(), name, ns, interfaceName, id, netnsPath, annotations, options, &preResult, err);
free_result(preResult);
preResult = nullptr;
if (err.NotEmpty()) {
ERROR("Error while adding to cni network: %s", err.GetCMessage());
}
unlock_out:
UnlockNetworkMap(err);
}
void CniNetworkPlugin::TearDownPod(const std::string &ns, const std::string &name, const std::string &networkPlane,
const std::string &interfaceName, const std::string &id,
void CniNetworkPlugin::TearDownPod(const std::string &ns, const std::string &name, const std::string &interfaceName,
const std::string &id,
const std::map<std::string, std::string> &annotations, Errors &err)
{
CheckInitialized(err);
@ -459,27 +407,14 @@ void CniNetworkPlugin::TearDownPod(const std::string &ns, const std::string &nam
err.Clear();
}
auto iter = annotations.find(CRIHelpers::Constants::POD_CHECKPOINT_KEY);
std::string jsonCheckpoint = "";
if (iter != annotations.end()) {
jsonCheckpoint = iter->second;
}
DEBUG("delete checkpoint: ", jsonCheckpoint.c_str());
RLockNetworkMap(err);
if (err.NotEmpty()) {
ERROR("%s", err.GetCMessage());
return;
}
auto netIter = m_networks.find(networkPlane);
if (netIter == m_networks.end()) {
ERROR("Can't find cni plugin for network plane %s.", networkPlane.c_str());
err.Errorf("Can't find cni plugin for network plane %s.", networkPlane.c_str());
goto unlock_out;
}
DeleteFromNetwork((netIter->second).get(), jsonCheckpoint, name, ns, interfaceName, id, netnsPath, err);
DeleteFromNetwork(m_defaultNetwork.get(), name, ns, interfaceName, id, netnsPath, annotations, err);
unlock_out:
UnlockNetworkMap(err);
}
@ -488,9 +423,40 @@ std::map<int, bool> *CniNetworkPlugin::Capabilities()
return m_noop.Capabilities();
}
void CniNetworkPlugin::SetPodCidr(const std::string &podCidr)
{
Errors err;
WLockNetworkMap(err);
if (err.NotEmpty()) {
ERROR("%s", err.GetCMessage());
return;
}
if (!m_podCidr.empty()) {
WARN("Ignoring subsequent pod CIDR update to %s", podCidr.c_str());
goto unlock_out;
}
m_podCidr = podCidr;
unlock_out:
UnlockNetworkMap(err);
}
void CniNetworkPlugin::Event(const std::string &name, std::map<std::string, std::string> &details)
{
m_noop.Event(name, details);
if (name != CRIHelpers::Constants::NET_PLUGIN_EVENT_POD_CIDR_CHANGE) {
return;
}
auto iter = details.find(CRIHelpers::Constants::NET_PLUGIN_EVENT_POD_CIDR_CHANGE_DETAIL_CIDR);
if (iter == details.end()) {
WARN("%s event didn't contain pod CIDR", CRIHelpers::Constants::NET_PLUGIN_EVENT_POD_CIDR_CHANGE.c_str());
return;
}
SetPodCidr(iter->second);
}
void CniNetworkPlugin::GetPodNetworkStatus(const std::string &ns, const std::string &name,
@ -526,9 +492,11 @@ out:
INFO("get_pod_network_status: %s", podSandboxID.c_str());
}
void CniNetworkPlugin::AddToNetwork(CNINetwork *snetwork, const std::string &jsonCheckpoint, const std::string &podName,
void CniNetworkPlugin::AddToNetwork(CNINetwork *snetwork, const std::string &podName,
const std::string &podNamespace, const std::string &interfaceName,
const std::string &podSandboxID, const std::string &podNetnsPath,
const std::map<std::string, std::string> &annotations,
const std::map<std::string, std::string> &options,
struct result **presult, Errors &err)
{
struct runtime_conf *rc {
@ -540,7 +508,8 @@ void CniNetworkPlugin::AddToNetwork(CNINetwork *snetwork, const std::string &jso
ERROR("Invalid arguments");
return;
}
BuildCNIRuntimeConf(podName, jsonCheckpoint, podNamespace, interfaceName, podSandboxID, podNetnsPath, &rc, err);
BuildCNIRuntimeConf(podName, podNamespace, interfaceName, podSandboxID, podNetnsPath, annotations, options, &rc, err);
if (err.NotEmpty()) {
ERROR("Error adding network when building cni runtime conf: %s", err.GetCMessage());
return;
@ -566,10 +535,12 @@ void CniNetworkPlugin::AddToNetwork(CNINetwork *snetwork, const std::string &jso
free(serr);
}
void CniNetworkPlugin::DeleteFromNetwork(CNINetwork *network, const std::string &jsonCheckpoint,
void CniNetworkPlugin::DeleteFromNetwork(CNINetwork *network,
const std::string &podName, const std::string &podNamespace,
const std::string &interfaceName, const std::string &podSandboxID,
const std::string &podNetnsPath, Errors &err)
const std::string &podNetnsPath,
const std::map<std::string, std::string> &annotations,
Errors &err)
{
struct runtime_conf *rc {
nullptr
@ -580,7 +551,8 @@ void CniNetworkPlugin::DeleteFromNetwork(CNINetwork *network, const std::string
ERROR("Invalid arguments");
return;
}
BuildCNIRuntimeConf(podName, jsonCheckpoint, podNamespace, interfaceName, podSandboxID, podNetnsPath, &rc, err);
std::map<std::string, std::string> options;
BuildCNIRuntimeConf(podName, podNamespace, interfaceName, podSandboxID, podNetnsPath, annotations, options, &rc, err);
if (err.NotEmpty()) {
ERROR("Error deleting network when building cni runtime conf: %s", err.GetCMessage());
return;
@ -606,20 +578,25 @@ void CniNetworkPlugin::DeleteFromNetwork(CNINetwork *network, const std::string
free(serr);
}
void CniNetworkPlugin::BuildCNIRuntimeConf(const std::string &podName, const std::string &jsonCheckpoint,
const std::string &podNs, const std::string &interfaceName,
const std::string &podSandboxID, const std::string &podNetnsPath,
struct runtime_conf **cni_rc, Errors &err)
static void PrepareRuntimeConf(const std::string &podName,
const std::string &podNs, const std::string &interfaceName,
const std::string &podSandboxID, const std::string &podNetnsPath,
const std::map<std::string, std::string> &options,
struct runtime_conf **cni_rc, Errors &err)
{
std::vector<cri::PortMapping> portMappings;
INFO("Got netns path %s", podNetnsPath.c_str());
INFO("Using podns path %s", podNs.c_str());
const size_t defaultLen = 5;
if (cni_rc == nullptr) {
err.Errorf("Invalid arguments");
ERROR("Invalid arguments");
return;
}
auto iter = options.find("UID");
std::string podUID {""};
if (iter != options.end()) {
podUID = iter->second;
}
struct runtime_conf *rt = (struct runtime_conf *)util_common_calloc_s(sizeof(struct runtime_conf));
if (rt == nullptr) {
ERROR("Out of memory");
@ -631,13 +608,13 @@ void CniNetworkPlugin::BuildCNIRuntimeConf(const std::string &podName, const std
rt->netns = util_strdup_s(podNetnsPath.c_str());
rt->ifname = util_strdup_s(interfaceName.c_str());
rt->args = (char *(*)[2])util_common_calloc_s(sizeof(char *) * 2 * 4);
rt->args = (char *(*)[2])util_common_calloc_s(sizeof(char *) * 2 * defaultLen);
if (rt->args == nullptr) {
ERROR("Out of memory");
err.SetError("Out of memory");
goto free_out;
}
rt->args_len = 4;
rt->args_len = defaultLen;
rt->args[0][0] = util_strdup_s("IgnoreUnknown");
rt->args[0][1] = util_strdup_s("1");
rt->args[1][0] = util_strdup_s("K8S_POD_NAMESPACE");
@ -646,6 +623,39 @@ void CniNetworkPlugin::BuildCNIRuntimeConf(const std::string &podName, const std
rt->args[2][1] = util_strdup_s(podName.c_str());
rt->args[3][0] = util_strdup_s("K8S_POD_INFRA_CONTAINER_ID");
rt->args[3][1] = util_strdup_s(podSandboxID.c_str());
rt->args[4][0] = util_strdup_s("K8S_POD_UID");
rt->args[4][1] = util_strdup_s(podUID.c_str());
*cni_rc = rt;
return;
free_out:
free_runtime_conf(rt);
}
void CniNetworkPlugin::BuildCNIRuntimeConf(const std::string &podName,
const std::string &podNs, const std::string &interfaceName,
const std::string &podSandboxID, const std::string &podNetnsPath,
const std::map<std::string, std::string> &annotations,
const std::map<std::string, std::string> &options,
struct runtime_conf **cni_rc, Errors &err)
{
PrepareRuntimeConf(podName, podNs, interfaceName, podSandboxID, podNetnsPath, options, cni_rc, err);
if (err.NotEmpty()) {
return;
}
struct runtime_conf *rt = *cni_rc;
*cni_rc = nullptr;
auto iter = annotations.find(CRIHelpers::Constants::POD_CHECKPOINT_KEY);
std::string jsonCheckpoint { "" };
if (iter != annotations.end()) {
jsonCheckpoint = iter->second;
}
DEBUG("add checkpoint: ", jsonCheckpoint.c_str());
std::vector<cri::PortMapping> portMappings;
INFO("Got netns path %s", podNetnsPath.c_str());
INFO("Using podns path %s", podNs.c_str());
if (!jsonCheckpoint.empty()) {
cri::PodSandboxCheckpoint checkpoint;
@ -723,4 +733,22 @@ void CniNetworkPlugin::UnlockNetworkMap(Errors &error)
}
}
void CniNetworkPlugin::UpdateDefaultNetwork()
{
const int defaultSyncConfigCnt = 5;
const int defaultSyncConfigPeriod = 1000;
pthread_setname_np(pthread_self(), "CNIUpdater");
while (true) {
for (int i = 0; i < defaultSyncConfigCnt; i++) {
std::this_thread::sleep_for(std::chrono::milliseconds(defaultSyncConfigPeriod));
if (m_needFinish) {
return;
}
}
SyncNetworkConfig();
}
}
} // namespace Network

View File

@ -20,6 +20,8 @@
#include <map>
#include <vector>
#include <set>
#include <thread>
#include <clibcni/api.h>
#include "network_plugin.h"
@ -48,9 +50,9 @@ public:
{
m_name = name;
}
void InsertPath(const std::string &path)
void SetPaths(std::vector<std::string> &binDirs)
{
m_path.push_back(path);
m_path = binDirs;
}
std::string GetNetworkConfigJsonStr()
{
@ -64,6 +66,13 @@ public:
{
return m_networkConfig->first_plugin_name ? m_networkConfig->first_plugin_name : "";
}
struct cni_network_list_conf *UpdateCNIConfList(struct cni_network_list_conf *newConf)
{
struct cni_network_list_conf *result = m_networkConfig;
m_networkConfig = newConf;
return result;
}
char **GetPaths(Errors &err);
private:
@ -76,8 +85,8 @@ private:
class CniNetworkPlugin : public NetworkPlugin {
public:
CniNetworkPlugin(const std::string &binDir, const std::string &pluginDir,
const std::string &vendorCNIDirPrefix = "");
CniNetworkPlugin(std::vector<std::string> &binDirs, const std::string &confDir,
const std::string &podCidr = "");
virtual ~CniNetworkPlugin();
@ -90,12 +99,13 @@ public:
std::map<int, bool> *Capabilities() override;
void SetUpPod(const std::string &ns, const std::string &name, const std::string &networkPlane,
void SetUpPod(const std::string &ns, const std::string &name,
const std::string &interfaceName, const std::string &podSandboxID,
const std::map<std::string, std::string> &annotations, Errors &error) override;
const std::map<std::string, std::string> &annotations,
const std::map<std::string, std::string> &options, Errors &error) override;
void TearDownPod(const std::string &ns, const std::string &name, const std::string &networkPlane,
const std::string &interfaceName, const std::string &podSandboxID,
void TearDownPod(const std::string &ns, const std::string &name,
const std::string &networkPlane, const std::string &podSandboxID,
const std::map<std::string, std::string> &annotations, Errors &error) override;
void GetPodNetworkStatus(const std::string &ns, const std::string &name, const std::string &interfaceName,
@ -109,47 +119,56 @@ private:
virtual void PlatformInit(Errors &error);
virtual void SyncNetworkConfig();
virtual void GetCNINetwork(const std::string &pluginDir, const std::string &binDir,
const std::string &vendorCNIDirPrefix, Errors &error);
virtual void GetDefaultCNINetwork(const std::string &pluginDir, std::vector<std::string> &binDirs, Errors &error);
virtual void CheckInitialized(Errors &error);
virtual void AddToNetwork(CNINetwork *network, const std::string &jsonCheckpoint, const std::string &podName,
virtual void AddToNetwork(CNINetwork *network, const std::string &podName,
const std::string &podNamespace, const std::string &interfaceName,
const std::string &podSandboxID, const std::string &podNetnsPath, struct result **presult,
Errors &error);
const std::string &podSandboxID, const std::string &podNetnsPath,
const std::map<std::string, std::string> &annotations,
const std::map<std::string, std::string> &options,
struct result **presult, Errors &error);
virtual void DeleteFromNetwork(CNINetwork *network, const std::string &jsonCheckpoint, const std::string &podName,
virtual void DeleteFromNetwork(CNINetwork *network, const std::string &podName,
const std::string &podNamespace, const std::string &interfaceName,
const std::string &podSandboxID, const std::string &podNetnsPath, Errors &error);
const std::string &podSandboxID, const std::string &podNetnsPath,
const std::map<std::string, std::string> &annotations,
Errors &error);
virtual void BuildCNIRuntimeConf(const std::string &podName, const std::string &jsonCheckpoint,
virtual void BuildCNIRuntimeConf(const std::string &podName,
const std::string &podNs, const std::string &interfaceName,
const std::string &podSandboxID, const std::string &podNetnsPath,
const std::map<std::string, std::string> &annotations,
const std::map<std::string, std::string> &options,
struct runtime_conf **cni_rc, Errors &error);
private:
void RLockNetworkMap(Errors &error);
void WLockNetworkMap(Errors &error);
void UnlockNetworkMap(Errors &error);
void SetDefaultNetwork(std::unique_ptr<CNINetwork> network, std::vector<std::string> &binDirs, Errors &err);
void SetPodCidr(const std::string &podCidr);
int GetCNIConfFiles(const std::string &pluginDir, std::vector<std::string> &vect_files, Errors &err);
int LoadCNIConfigFileList(const std::string &elem, struct cni_network_list_conf **n_list);
int InsertConfNameToAllPanes(struct cni_network_list_conf *n_list, std::set<std::string> &allPanes, Errors &err);
int InsertNewNetwork(struct cni_network_list_conf *n_list,
std::map<std::string, std::unique_ptr<CNINetwork>> &newNets, const std::string &binDir,
const std::string &vendorCNIDirPrefix, Errors &err);
void ResetCNINetwork(std::map<std::string, std::unique_ptr<CNINetwork>> &newNets, Errors &err);
void UpdateDefaultNetwork();
NoopNetworkPlugin m_noop;
std::unique_ptr<CNINetwork> m_loNetwork { nullptr };
std::unique_ptr<CNINetwork> m_defaultNetwork { nullptr };
CRIRuntimeServiceImpl *m_criImpl { nullptr };
std::string m_nsenterPath;
std::string m_pluginDir;
std::string m_vendorCNIDirPrefix;
std::string m_binDir;
std::string m_confDir;
std::vector<std::string> m_binDirs;
std::string m_podCidr;
pthread_rwlock_t m_netsLock = PTHREAD_RWLOCK_INITIALIZER;
std::map<std::string, std::unique_ptr<CNINetwork>> m_networks;
std::thread m_syncThread;
bool m_needFinish;
};
} // namespace Network

View File

@ -49,6 +49,8 @@ const std::string Constants::CONTAINER_TYPE_ANNOTATION_KEY { "io.kubernetes.cri.
const std::string Constants::CONTAINER_TYPE_ANNOTATION_CONTAINER { "container" };
const std::string Constants::CONTAINER_TYPE_ANNOTATION_SANDBOX { "sandbox" };
const std::string Constants::SANDBOX_ID_ANNOTATION_KEY { "io.kubernetes.cri.sandbox-id" };
const std::string Constants::NET_PLUGIN_EVENT_POD_CIDR_CHANGE { "pod-cidr-change" };
const std::string Constants::NET_PLUGIN_EVENT_POD_CIDR_CHANGE_DETAIL_CIDR { "pod-cidr" };
const char *InternalLabelKeys[] = {
CRIHelpers::Constants::CONTAINER_TYPE_LABEL_KEY.c_str(),
@ -565,7 +567,7 @@ std::vector<iSuladOpt> GetSeccompiSuladOpts(const std::string &seccompProfile, E
if (seccompProfile.empty() || seccompProfile == "unconfined") {
return std::vector<iSuladOpt> { { "seccomp", "unconfined", "" } };
}
if (seccompProfile == "iSulad/default" || seccompProfile == "docker/default") {
if (seccompProfile == "iSulad/default" || seccompProfile == "docker/default" || seccompProfile == "runtime/default") {
// return nil so docker will load the default seccomp profile
return std::vector<iSuladOpt> {};
}

View File

@ -53,7 +53,11 @@ public:
static const std::string CONTAINER_TYPE_ANNOTATION_CONTAINER;
static const std::string CONTAINER_TYPE_ANNOTATION_SANDBOX;
static const std::string SANDBOX_ID_ANNOTATION_KEY;
static const std::string NET_PLUGIN_EVENT_POD_CIDR_CHANGE;
static const std::string NET_PLUGIN_EVENT_POD_CIDR_CHANGE_DETAIL_CIDR;
};
std::string GetDefaultSandboxImage(Errors &err);
json_map_string_string *MakeLabels(const google::protobuf::Map<std::string, std::string> &mapLabels, Errors &error);

View File

@ -109,14 +109,11 @@ cleanup:
void CRIRuntimeServiceImpl::UpdateRuntimeConfig(const runtime::v1alpha2::RuntimeConfig &config, Errors &error)
{
const std::string NET_PLUGIN_EVENT_POD_CIDR_CHANGE { "pod-cidr-change" };
const std::string NET_PLUGIN_EVENT_POD_CIDR_CHANGE_DETAIL_CIDR { "pod-cidr" };
INFO("iSulad cri received runtime config: %s", config.network_config().pod_cidr().c_str());
if (m_pluginManager != nullptr && config.has_network_config() && !(config.network_config().pod_cidr().empty())) {
std::map<std::string, std::string> events;
events[NET_PLUGIN_EVENT_POD_CIDR_CHANGE_DETAIL_CIDR] = config.network_config().pod_cidr();
m_pluginManager->Event(NET_PLUGIN_EVENT_POD_CIDR_CHANGE, events);
events[CRIHelpers::Constants::NET_PLUGIN_EVENT_POD_CIDR_CHANGE_DETAIL_CIDR] = config.network_config().pod_cidr();
m_pluginManager->Event(CRIHelpers::Constants::NET_PLUGIN_EVENT_POD_CIDR_CHANGE, events);
}
return;
}

View File

@ -247,7 +247,7 @@ private:
const std::string &jsonCheckpoint, Errors &error);
void SetupUserDefinedNetworkPlane(const runtime::v1alpha2::PodSandboxConfig &config, const std::string &response_id,
container_inspect *inspect_data, std::map<std::string, std::string> &stdAnnos,
Errors &error);
std::map<std::string, std::string> &options, Errors &error);
void StartSandboxContainer(const std::string &response_id, Errors &error);
std::string CreateSandboxContainer(const runtime::v1alpha2::PodSandboxConfig &config, const std::string &image,
std::string &jsonCheckpoint, const std::string &runtimeHandler, Errors &error);

View File

@ -469,7 +469,8 @@ void CRIRuntimeServiceImpl::StartSandboxContainer(const std::string &response_id
void CRIRuntimeServiceImpl::SetupUserDefinedNetworkPlane(const runtime::v1alpha2::PodSandboxConfig &config,
const std::string &response_id,
container_inspect *inspect_data,
std::map<std::string, std::string> &stdAnnos, Errors &error)
std::map<std::string, std::string> &stdAnnos,
std::map<std::string, std::string> &options, Errors &error)
{
google::protobuf::Map<std::string, std::string> annotations;
CRIHelpers::ExtractAnnotations(inspect_data->config->annotations, annotations);
@ -485,8 +486,8 @@ void CRIRuntimeServiceImpl::SetupUserDefinedNetworkPlane(const runtime::v1alpha2
if (networks[i] && networks[i]->name && networks[i]->interface &&
strcmp(networks[i]->name, Network::DEFAULT_NETWORK_PLANE_NAME.c_str()) != 0) {
INFO("SetupPod net: %s", networks[i]->name);
m_pluginManager->SetUpPod(config.metadata().namespace_(), config.metadata().name(), networks[i]->name,
networks[i]->interface, response_id, stdAnnos, error);
m_pluginManager->SetUpPod(config.metadata().namespace_(), config.metadata().name(), networks[i]->interface, response_id,
stdAnnos, options, error);
if (error.Empty()) {
continue;
}
@ -508,6 +509,8 @@ void CRIRuntimeServiceImpl::SetupSandboxNetwork(const runtime::v1alpha2::PodSand
Errors &error)
{
std::map<std::string, std::string> stdAnnos;
std::map<std::string, std::string> networkOptions;
container_inspect *inspect_data = InspectContainer(response_id, error);
if (error.NotEmpty()) {
return;
@ -530,22 +533,16 @@ void CRIRuntimeServiceImpl::SetupSandboxNetwork(const runtime::v1alpha2::PodSand
// Setup networking for the sandbox.
CRIHelpers::ProtobufAnnoMapToStd(config.annotations(), stdAnnos);
stdAnnos[CRIHelpers::Constants::POD_CHECKPOINT_KEY] = jsonCheckpoint;
networkOptions["UID"] = config.metadata().uid();
m_pluginManager->SetUpPod(config.metadata().namespace_(), config.metadata().name(),
Network::DEFAULT_NETWORK_PLANE_NAME, Network::DEFAULT_NETWORK_INTERFACE_NAME, response_id,
stdAnnos, error);
Network::DEFAULT_NETWORK_INTERFACE_NAME, response_id, stdAnnos, networkOptions, error);
if (error.NotEmpty()) {
ERROR("SetupPod failed: %s", error.GetCMessage());
StopContainerHelper(response_id, error);
goto cleanup;
}
// Multi network plane featrue
// Set up user defined network plane
SetupUserDefinedNetworkPlane(config, response_id, inspect_data, stdAnnos, error);
if (error.NotEmpty()) {
ERROR("failed to user defined network plane");
goto cleanup;
}
cleanup:
free_container_inspect(inspect_data);
}
@ -723,8 +720,7 @@ int CRIRuntimeServiceImpl::TearDownPodCniNetwork(const std::string &realSandboxI
if (networks[i] && networks[i]->name && networks[i]->interface &&
strcmp(networks[i]->name, Network::DEFAULT_NETWORK_PLANE_NAME.c_str()) != 0) {
Errors tmpErr;
m_pluginManager->TearDownPod(ns, name, networks[i]->name, networks[i]->interface, inspect_data->id,
stdAnnos, tmpErr);
m_pluginManager->TearDownPod(ns, name, networks[i]->interface, inspect_data->id, stdAnnos, tmpErr);
if (tmpErr.NotEmpty()) {
WARN("TearDownPod cni network failed: %s", tmpErr.GetCMessage());
errlist.push_back(tmpErr.GetMessage());
@ -746,22 +742,17 @@ int CRIRuntimeServiceImpl::ClearCniNetwork(const std::string &realSandboxID, boo
bool ready = GetNetworkReady(realSandboxID, networkErr);
if (!hostNetwork && (ready || networkErr.NotEmpty())) {
Errors pluginErr;
m_pluginManager->TearDownPod(ns, name, Network::DEFAULT_NETWORK_PLANE_NAME,
Network::DEFAULT_NETWORK_INTERFACE_NAME, realSandboxID, stdAnnos, pluginErr);
m_pluginManager->TearDownPod(ns, name, Network::DEFAULT_NETWORK_INTERFACE_NAME, realSandboxID, stdAnnos, pluginErr);
if (pluginErr.NotEmpty()) {
WARN("TearDownPod cni network: %s failed: %s", Network::DEFAULT_NETWORK_PLANE_NAME.c_str(),
pluginErr.GetCMessage());
WARN("TearDownPod cni network failed: %s", pluginErr.GetCMessage());
errlist.push_back(pluginErr.GetMessage());
} else {
INFO("TearDownPod cni network: %s success", Network::DEFAULT_NETWORK_PLANE_NAME.c_str());
INFO("TearDownPod cni network: success");
SetNetworkReady(realSandboxID, false, pluginErr);
if (pluginErr.NotEmpty()) {
WARN("set network ready: %s", pluginErr.GetCMessage());
}
}
if (TearDownPodCniNetwork(realSandboxID, errlist, stdAnnos, ns, name, error)) {
return -1;
}
}
return 0;
}

View File

@ -401,9 +401,10 @@ void PluginManager::GetPodNetworkStatus(const std::string &ns, const std::string
Unlock(fullName, error);
}
void PluginManager::SetUpPod(const std::string &ns, const std::string &name, const std::string &networkPlane,
void PluginManager::SetUpPod(const std::string &ns, const std::string &name,
const std::string &interfaceName, const std::string &podSandboxID,
std::map<std::string, std::string> &annotations, Errors &error)
std::map<std::string, std::string> &annotations,
const std::map<std::string, std::string> &options, Errors &error)
{
if (m_plugin == nullptr) {
return;
@ -417,7 +418,7 @@ void PluginManager::SetUpPod(const std::string &ns, const std::string &name, con
INFO("Calling network plugin %s to set up pod %s", m_plugin->Name().c_str(), fullName.c_str());
Errors tmpErr;
m_plugin->SetUpPod(ns, name, networkPlane, interfaceName, podSandboxID, annotations, tmpErr);
m_plugin->SetUpPod(ns, name, interfaceName, podSandboxID, annotations, options, tmpErr);
if (tmpErr.NotEmpty()) {
error.Errorf("NetworkPlugin %s failed to set up pod %s network: %s", m_plugin->Name().c_str(), fullName.c_str(),
tmpErr.GetCMessage());
@ -425,8 +426,8 @@ void PluginManager::SetUpPod(const std::string &ns, const std::string &name, con
Unlock(fullName, error);
}
void PluginManager::TearDownPod(const std::string &ns, const std::string &name, const std::string &networkPlane,
const std::string &interfaceName, const std::string &podSandboxID,
void PluginManager::TearDownPod(const std::string &ns, const std::string &name, const std::string &interfaceName,
const std::string &podSandboxID,
std::map<std::string, std::string> &annotations, Errors &error)
{
Errors tmpErr;
@ -440,7 +441,7 @@ void PluginManager::TearDownPod(const std::string &ns, const std::string &name,
}
INFO("Calling network plugin %s to tear down pod %s", m_plugin->Name().c_str(), fullName.c_str());
m_plugin->TearDownPod(ns, name, networkPlane, interfaceName, podSandboxID, annotations, tmpErr);
m_plugin->TearDownPod(ns, name, Network::DEFAULT_NETWORK_INTERFACE_NAME, podSandboxID, annotations, tmpErr);
if (tmpErr.NotEmpty()) {
error.Errorf("NetworkPlugin %s failed to teardown pod %s network: %s", m_plugin->Name().c_str(),
fullName.c_str(), tmpErr.GetCMessage());
@ -499,15 +500,16 @@ std::map<int, bool> *NoopNetworkPlugin::Capabilities()
return ret;
}
void NoopNetworkPlugin::SetUpPod(const std::string &ns, const std::string &name, const std::string &networkPlane,
void NoopNetworkPlugin::SetUpPod(const std::string &ns, const std::string &name,
const std::string &interfaceName, const std::string &podSandboxID,
const std::map<std::string, std::string> &annotations, Errors &error)
const std::map<std::string, std::string> &annotations,
const std::map<std::string, std::string> &options, Errors &error)
{
return;
}
void NoopNetworkPlugin::TearDownPod(const std::string &ns, const std::string &name, const std::string &networkPlane,
const std::string &interfaceName, const std::string &podSandboxID,
void NoopNetworkPlugin::TearDownPod(const std::string &ns, const std::string &name, const std::string &interfaceName,
const std::string &podSandboxID,
const std::map<std::string, std::string> &annotations, Errors &error)
{
return;

View File

@ -102,12 +102,13 @@ public:
virtual std::map<int, bool> *Capabilities() = 0;
virtual void SetUpPod(const std::string &ns, const std::string &name, const std::string &networkPlane,
virtual void SetUpPod(const std::string &ns, const std::string &name,
const std::string &interfaceName, const std::string &podSandboxID,
const std::map<std::string, std::string> &annotations, Errors &error) = 0;
const std::map<std::string, std::string> &annotations,
const std::map<std::string, std::string> &options, Errors &error) = 0;
virtual void TearDownPod(const std::string &ns, const std::string &name, const std::string &networkPlane,
const std::string &interfaceName, const std::string &podSandboxID,
const std::string &podSandboxID,
const std::map<std::string, std::string> &annotations, Errors &error) = 0;
virtual void GetPodNetworkStatus(const std::string &ns, const std::string &name, const std::string &interfaceName,
@ -136,12 +137,13 @@ public:
std::map<int, bool> *Capabilities() override;
void SetUpPod(const std::string &ns, const std::string &name, const std::string &networkPlane,
void SetUpPod(const std::string &ns, const std::string &name,
const std::string &interfaceName, const std::string &podSandboxID,
const std::map<std::string, std::string> &annotations, Errors &error) override;
const std::map<std::string, std::string> &annotations,
const std::map<std::string, std::string> &options, Errors &error) override;
void TearDownPod(const std::string &ns, const std::string &name, const std::string &networkPlane,
const std::string &interfaceName, const std::string &podSandboxID,
const std::string &podSandboxID,
const std::map<std::string, std::string> &annotations, Errors &error) override;
void GetPodNetworkStatus(const std::string &ns, const std::string &name, const std::string &interfaceName,
@ -201,11 +203,12 @@ public:
void Status(Errors &error);
void GetPodNetworkStatus(const std::string &ns, const std::string &name, const std::string &interfaceName,
const std::string &podSandboxID, PodNetworkStatus &status, Errors &error);
void SetUpPod(const std::string &ns, const std::string &name, const std::string &networkPlane,
void SetUpPod(const std::string &ns, const std::string &name,
const std::string &interfaceName, const std::string &podSandboxID,
std::map<std::string, std::string> &annotations, Errors &error);
std::map<std::string, std::string> &annotations,
const std::map<std::string, std::string> &options, Errors &error);
void TearDownPod(const std::string &ns, const std::string &name, const std::string &networkPlane,
const std::string &interfaceName, const std::string &podSandboxID,
const std::string &podSandboxID,
std::map<std::string, std::string> &annotations, Errors &error);
private:

View File

@ -792,6 +792,63 @@ out:
return ret;
}
static int create_mtab_link(const oci_runtime_spec *oci_spec)
{
char *pathname = "/proc/mounts";
char *slink = NULL;
char *dir = NULL;
int ret = 0;
if (oci_spec->root == NULL || oci_spec->root->path == NULL) {
ERROR("Root path is NULL, can not create link /etc/mtab for target /proc/mounts");
return -1;
}
slink = util_path_join(oci_spec->root->path, "/etc/mtab");
if (slink == NULL) {
ERROR("Failed to join path:%s with /etc/mtab", oci_spec->root->path);
ret = -1;
goto out;
}
dir = util_path_dir(slink);
if (dir == NULL) {
ERROR("Failed to get dir %s", slink);
ret = -1;
goto out;
}
if (!util_dir_exists(dir)) {
ret = util_mkdir_p(dir, ETC_FILE_MODE);
if (ret != 0) {
ERROR("Unable to create mtab directory %s.", dir);
goto out;
}
}
if (util_file_exists(slink)) {
goto out;
}
ret = symlink(pathname, slink);
if (ret < 0 && errno != EEXIST) {
if (errno == EROFS) {
WARN("Failed to create link %s for target %s. Read-only filesystem", slink, pathname);
} else {
SYSERROR("Failed to create \"%s\"", slink);
ret = -1;
goto out;
}
}
ret = 0;
out:
free(slink);
free(dir);
return ret;
}
static int do_start_container(container_t *cont, const char *console_fifos[], bool reset_rm,
container_pid_t *pid_info)
{
@ -867,6 +924,13 @@ static int do_start_container(container_t *cont, const char *console_fifos[], bo
goto close_exit_fd;
}
nret = create_mtab_link(oci_spec);
if (nret != 0) {
ERROR("Failed to create link /etc/mtab for target /proc/mounts");
ret = -1;
goto close_exit_fd;
}
if (renew_oci_config(cont, oci_spec) != 0) {
ret = -1;
goto close_exit_fd;
@ -1745,6 +1809,39 @@ out:
return ret;
}
int umount_residual_shm(const char *mount_info, const char *target)
{
if (strncmp(mount_info, target, strlen(target)) != 0) {
return 0;
}
DEBUG("Try to umount: %s", mount_info);
if (umount2(mount_info, MNT_DETACH)) {
SYSERROR("Failed to umount residual mount: %s", mount_info);
}
return 0;
}
int cleanup_mounts_by_id(const char *id, const char *engine_root_path)
{
char target[PATH_MAX] = {0};
int nret = 0;
nret = snprintf(target, PATH_MAX, "%s/%s", engine_root_path, id);
if (nret < 0 || nret >= PATH_MAX) {
ERROR("Sprintf failed");
return -1;
}
if (!util_deal_with_mount_info(umount_residual_shm, target)) {
ERROR("Cleanup mounts failed");
return -1;
}
return 0;
}
static int do_cleanup_container_resources(container_t *cont)
{
int ret = 0;
@ -1804,6 +1901,9 @@ static int do_cleanup_container_resources(container_t *cont)
umount_host_channel(cont->hostconfig->host_channel);
// clean residual mount points
cleanup_mounts_by_id(id, rootpath);
if (do_runtime_rm_helper(id, runtime, rootpath) != 0) {
ret = -1;
goto out;

View File

@ -35,6 +35,7 @@ int stop_container(container_t *cont, int timeout, bool force, bool restart);
int set_container_to_removal(const container_t *cont);
int cleanup_mounts_by_id(const char *id, const char *engine_root_path);
#ifdef __cplusplus
}

View File

@ -454,8 +454,6 @@ static int save_json_config_file(const char *id, const char *rootpath,
{
int ret = 0;
int nret;
int fd = -1;
ssize_t len = 0;
char filename[PATH_MAX] = { 0 };
if (json_data == NULL || strlen(json_data) == 0) {
@ -468,21 +466,12 @@ static int save_json_config_file(const char *id, const char *rootpath,
goto out;
}
fd = util_open(filename, O_CREAT | O_TRUNC | O_CLOEXEC | O_WRONLY, CONFIG_FILE_MODE);
if (fd == -1) {
ERROR("Create file %s failed: %s", filename, strerror(errno));
isulad_set_error_message("Create file '%s' failed: %s", filename, strerror(errno));
ret = -1;
goto out;
}
len = util_write_nointr(fd, json_data, strlen(json_data));
if (len < 0 || ((size_t)len) != strlen(json_data)) {
nret = util_atomic_write_file(filename, json_data, strlen(json_data), CONFIG_FILE_MODE);
if (nret != 0) {
ERROR("Write file %s failed: %s", filename, strerror(errno));
isulad_set_error_message("Write file '%s' failed: %s", filename, strerror(errno));
ret = -1;
}
close(fd);
out:
return ret;

View File

@ -371,6 +371,13 @@ static int remove_invalid_container(const container_t *cont, const char *runtime
goto out;
}
ret = cleanup_mounts_by_id(id, root);
if (ret != 0) {
ERROR("Failed to clean container's mounts");
ret = -1;
goto out;
}
ret = snprintf(container_root, sizeof(container_root), "%s/%s", root, id);
if (ret < 0 || (size_t)ret >= sizeof(container_root)) {
ERROR("Failed to sprintf invalid root directory %s/%s", root, id);

View File

@ -2191,7 +2191,7 @@ int save_oci_config(const char *id, const char *rootpath, const oci_runtime_spec
goto out_free;
}
if (util_write_file(file_path, json_container, strlen(json_container), DEFAULT_SECURE_FILE_MODE) != 0) {
if (util_atomic_write_file(file_path, json_container, strlen(json_container), DEFAULT_SECURE_FILE_MODE) != 0) {
ERROR("write json container failed: %s", strerror(errno));
ret = -1;
goto out_free;

View File

@ -2125,8 +2125,8 @@ static char *get_prepare_share_shm_path(const char *truntime, const char *cid)
goto err_out;
}
nret = sprintf(spath, "%s/%s/mounts/shm/", c_root_path, cid);
if (nret < 0) {
nret = snprintf(spath, slen, "%s/%s/mounts/shm/", c_root_path, cid);
if (nret < 0 || nret >= slen) {
ERROR("Sprintf failed");
goto err_out;
}
@ -2187,8 +2187,8 @@ static int prepare_share_shm(oci_runtime_spec *oci_spec, host_config *host_spec,
ERROR("Build shm dir failed");
goto out;
}
nret = sprintf(shmproperty, "mode=1777,size=%"PRId64, host_spec->shm_size);
if (nret < 0) {
nret = snprintf(shmproperty, MAX_PROPERTY_LEN, "mode=1777,size=%"PRId64, host_spec->shm_size);
if (nret < 0 || nret >= MAX_PROPERTY_LEN) {
ERROR("Sprintf failed");
goto out;
}

View File

@ -1482,6 +1482,29 @@ out:
return ret;
}
/* verify oci linux */
static int verify_process_env(const defs_process *process)
{
int ret = 0;
size_t i = 0;
char *new_env = NULL;
for (i = 0; i < process->env_len; i++) {
if (util_validate_env(process->env[i], &new_env) != 0) {
ERROR("Invalid environment %s", process->env[i]);
isulad_set_error_message("Invalid environment %s", process->env[i]);
ret = -1;
goto out;
}
free(new_env);
new_env = NULL;
}
out:
free(new_env);
return ret;
}
static int verify_container_linux(const oci_runtime_spec *container, const sysinfo_t *sysinfo)
{
int ret = 0;
@ -1498,6 +1521,14 @@ static int verify_container_linux(const oci_runtime_spec *container, const sysin
}
}
/* verify oci spec process settings */
if (container->process != NULL) {
ret = verify_process_env(container->process);
if (ret != 0) {
goto out;
}
}
out:
return ret;
}

View File

@ -52,7 +52,9 @@ int ExecServe::Execute(struct lws *wsi, const std::string &token,
StderrstringWriter.context = (void *)wsi;
StderrstringWriter.write_func = WsWriteStderrToClient;
int ret = cb->container.exec(container_req, &container_res,
container_req->attach_stdin ? read_pipe_fd : -1, &StdoutstringWriter, &StderrstringWriter);
container_req->attach_stdin ? read_pipe_fd : -1,
container_req->attach_stdout ? &StdoutstringWriter : nullptr,
container_req->attach_stderr ? &StderrstringWriter : nullptr);
if (ret != 0) {
std::string message;
if (container_res != nullptr && container_res->errmsg != nullptr) {

View File

@ -56,7 +56,7 @@ TEST_F(SELinuxGetEnableUnitTest, test_selinux_get_enable_normal)
const uint32_t selinuxfsMagic = 0xf97cff8c;
struct statfs sfbuf {
.f_type = selinuxfsMagic,
.f_flags = 0
.f_flags = 0
};
EXPECT_CALL(m_syscall, Statfs(_, _))

View File

@ -16,7 +16,7 @@
#set -xe
usage()
function usage()
{
echo "Usage: sh llt.sh [OPTIONS]"
echo "Use llt.sh to control llt operation"