Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for environment variables sent to components #74

Merged
merged 8 commits into from
Mar 30, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 106 additions & 46 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ extern char ** environ;

#define COMP_ID "ZWELNCH"

#define CEE_ENVFILE_PREFIX "_CEE_ENVFILE"

#define MIN_UPTIME_SECS 90

#define SHUTDOWN_GRACEFUL_PERIOD (20 * 1000)
Expand Down Expand Up @@ -343,7 +345,7 @@ static void set_shared_uss_env(ConfigManager *configmgr) {
object = jsonAsObject(env);
}

int maxRecords = 2;
int maxRecords = 3;

for (char **env = environ; *env != 0; env++) {
maxRecords++;
Expand Down Expand Up @@ -372,6 +374,11 @@ static void set_shared_uss_env(ConfigManager *configmgr) {
continue;
}

if (strncmp(key, CEE_ENVFILE_PREFIX, strlen(CEE_ENVFILE_PREFIX)) == 0) {
DEBUG("Ignoring environment variable: %s, conflict\n", key);
continue;
}

if (!arrayListContains(list, key)) {
arrayListAdd(list, key);

Expand All @@ -383,6 +390,7 @@ static void set_shared_uss_env(ConfigManager *configmgr) {
}

char *entry = malloc(strlen(key) + strlen(value) + 2);

sprintf(entry, "%s=%s", key, value);
shared_uss_env[idx++] = entry;
}
Expand All @@ -396,6 +404,10 @@ static void set_shared_uss_env(ConfigManager *configmgr) {
if (!index) {
continue;
}
if (strncmp(thisEnv, CEE_ENVFILE_PREFIX, strlen(CEE_ENVFILE_PREFIX)) == 0) {
DEBUG("Ignoring environment variable: %s, conflict\n", thisEnv);
continue;
}

int length = index - thisEnv;
char *key = malloc(length + 1);
Expand All @@ -406,6 +418,7 @@ static void set_shared_uss_env(ConfigManager *configmgr) {
shared_uss_env[idx++] = thisEnv;
}
}
shared_uss_env[idx] = NULL;
arrayListFree(list);
}

Expand Down Expand Up @@ -715,6 +728,35 @@ static void *handle_comp_comm(void *args) {
return NULL;
}

/**
* @brief Copy environment variables + _BPX_SHAREAS for the specified component
*
* @param comp The component
* @return const char** environment strings list
*/
static const char **env_comp(zl_comp_t *comp) {
shared_uss_env[0] = (char *)get_shareas_env(comp);

int env_records = 0;
for (char **env = shared_uss_env; *env != 0; env++) {
env_records++;
}

const char **env_comp = malloc(env_records + 1);

int i = 0;
for (char **env = shared_uss_env; *env != 0 && i < env_records; env++) {
char *thisEnv = *env;
char *aux = malloc(strlen(thisEnv) + 1);
strncpy(aux, thisEnv, strlen(thisEnv));
trimRight(aux, strlen(aux));
env_comp[i] = aux;
i++;
}
env_comp[i] = NULL;
return env_comp;
}

static int start_component(zl_comp_t *comp) {

if (comp->pid != -1) {
Expand Down Expand Up @@ -772,8 +814,9 @@ static int start_component(zl_comp_t *comp) {
NULL
};

shared_uss_env[0] = (char *)get_shareas_env(comp);
comp->pid = spawn(bin, fd_count, fd_map, &inherit, c_args, (const char **)shared_uss_env);
const char **c_envp = env_comp(comp);

comp->pid = spawn(bin, fd_count, fd_map, &inherit, c_args, c_envp);
if (comp->pid == -1) {
DEBUG("spawn() failed for %s - %s\n", comp->name, strerror(errno));
return -1;
Expand Down Expand Up @@ -1237,10 +1280,67 @@ static void handle_get_component_line(void *data, const char *line) {
}
}

static char* get_launch_components_cmd(char* sharedenv) {
const char basecmd[] = "%s %s/bin/zwe internal get-launch-components --config \"%s\" --ha-instance %s";
int size = strlen(zl_context.root_dir) + strlen(zl_context.config_path) + strlen(zl_context.ha_instance_id) + strlen(sharedenv) + sizeof(basecmd) + 1;
char *command = malloc(size);

snprintf(command, size, basecmd,
sharedenv, zl_context.root_dir, zl_context.config_path, zl_context.ha_instance_id);

return command;
}

/**
* @brief Get the sharedenv. The function contemplates enclosing in quotes the values of the variables.
*
* @return char* string representation of the shared_uss_env variable, e.g. VAR1="sample" VAR2=12345
*/
static char* get_sharedenv(void) {
char *output = NULL;
char *aux = NULL;

int required = 0;
for (char **env = shared_uss_env + 1; *env != 0; env++) { // First element is NULL, reserved to _BPX_SHAREAS
char *thisEnv = *env;
required += (strlen(thisEnv) + 3); // space + quotes
}

required++;
output = malloc(required);
aux = malloc(required);
for (char **env = shared_uss_env + 1; *env != 0; env++) { // First element is NULL, reserved to _BPX_SHAREAS
char *thisEnv = *env;
strcat(aux, thisEnv);
pablocarle marked this conversation as resolved.
Show resolved Hide resolved
char *envName = strtok(aux, "=");
if (envName) {
strcat(output, envName);
char *envValue = &thisEnv[strlen(envName) + 1];
if (*envValue == '"') { // Env value is already enclosed in quotes
strcat(output, "=");
strcat(output, envValue);
trimRight(output, strlen(output));
strcat(output, " ");
} else {
strcat(output, "=\"");
strcat(output, envValue);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quetos are not escaped

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what you mean here, this code is from the previous version, just moved it up

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JSON content is solved by jsonToString. The potential issue could come from shared_uss_env[idx++] = thisEnv;.

The proper solution there should probably be like this:

if (*thisEnv != '\"') {
 newstr = malloc(?);
 newstr[0] = 0; 
 strcat(newstr, key);
 strcat(newstr, "=");
 strcat(newstr, escapeString(thisEnv + length);
 length = newstr;
}

...anyway, I guess it is a bug, that could be solved in an issue. The workaround could be to use a different form in STC. And from another hand, it is pretty rear to set especially in this way string value with a quote.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

opened an issue based on testing done with these scenarios #76

trimRight(output, strlen(output));
strcat(output, "\" ");
}
}
aux[0] = 0;
}
trimRight(output, strlen(output));
free(aux);
return output;
}

static int get_component_list(char *buf, size_t buf_size) {
char command[4*PATH_MAX];
snprintf (command, sizeof(command), "%s/bin/zwe internal get-launch-components --config \"%s\" --ha-instance %s",
zl_context.root_dir, zl_context.config_path, zl_context.ha_instance_id);
char *sharedenv = get_sharedenv();
char *command = get_launch_components_cmd(sharedenv);

free(sharedenv);

DEBUG("about to get component list\n");
char comp_list[COMP_LIST_SIZE] = {0};
if (run_command(command, handle_get_component_line, (void*)comp_list)) {
Expand Down Expand Up @@ -1341,45 +1441,6 @@ static void print_line(void *data, const char *line) {
printf("%s", line);
}

static char* get_sharedenv(void) {
char *output = NULL;
char *aux = NULL;

int required = 0;
for (char **env = shared_uss_env + 1; *env != 0; env++) { // First element is NULL, reserved to _BPX_SHAREAS
char *thisEnv = *env;
required += (strlen(thisEnv) + 3); // space + quotes
}

required++;
output = malloc(required);
aux = malloc(required);
for (char **env = shared_uss_env + 1; *env != 0; env++) { // First element is NULL, reserved to _BPX_SHAREAS
char *thisEnv = *env;
strcat(aux, thisEnv);
char *envName = strtok(aux, "=");
if (envName) {
strcat(output, envName);
char *envValue = &thisEnv[strlen(envName) + 1];
if (*envValue == '"') { // Env value is already enclosed in quotes
strcat(output, "=");
strcat(output, envValue);
trimRight(output, strlen(output));
strcat(output, " ");
} else {
strcat(output, "=\"");
strcat(output, envValue);
trimRight(output, strlen(output));
strcat(output, "\" ");
}
}
aux[0] = 0;
}
trimRight(output, strlen(output));
free(aux);
return output;
}

static char* get_start_prepare_cmd(char *sharedenv) {
const char basecmd[] = "%s %s/bin/zwe internal start prepare --config \"%s\" --ha-instance %s 2>&1";
int size = strlen(zl_context.root_dir) + strlen(zl_context.config_path) + strlen(zl_context.ha_instance_id) + strlen(sharedenv) + sizeof(basecmd) + 1;
Expand All @@ -1391,7 +1452,6 @@ static char* get_start_prepare_cmd(char *sharedenv) {
return command;
}


static int prepare_instance() {
char *sharedenv = get_sharedenv();
char *command = get_start_prepare_cmd(sharedenv);
Expand Down