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

Merge staging into Master #119

Merged
merged 10 commits into from
Jul 3, 2024
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
All notable changes to the Zowe Launcher package will be documented in this file.
This repo is part of the app-server Zowe Component, and the change logs here may appear on Zowe.org in that section.

## 2.17.0
- Using configmgr to create the component list rather than zwe. (#117)

## 2.13.0
- Bugfix: Changed timestamp to UTC to match the server timestamps (#103)
- Bugfix: Removed server timestamps from syslog to avoid duplicate logging of time (#103)
Expand Down
203 changes: 178 additions & 25 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "logging.h"
#include "stcbase.h"
#include "zos.h"
#include "yaml2json.h"

extern char ** environ;
/*
Expand Down Expand Up @@ -73,6 +74,8 @@ extern char ** environ;
#define PATH_MAX _POSIX_PATH_MAX
#endif

#define YAML_ERROR_MAX 1024

// Progressive restart internals in seconds
static int restart_intervals_default[] = {1, 1, 1, 5, 5, 10, 20, 60, 120, 240};

Expand Down Expand Up @@ -460,7 +463,7 @@ static void set_shared_uss_env(ConfigManager *configmgr) {
object = jsonAsObject(env);
}

int maxRecords = 2;
int maxRecords = 5;

for (char **env = environ; *env != 0; env++) {
maxRecords++;
Expand All @@ -471,6 +474,12 @@ static void set_shared_uss_env(ConfigManager *configmgr) {
// _BPX_SHAREAS is set on component level
arrayListAdd(list, "_BPX_SHAREAS");


//These are all properties that should not be changed by zowe.environments
arrayListAdd(list, "ZWE_CLI_PARAMETER_CONFIG");
arrayListAdd(list, "ZWE_CLI_PARAMETER_HA_INSTANCE");
arrayListAdd(list, "ZWE_zowe_runtimeDirectory");

if (object) { // environments block is defined in zowe.yaml
for (JsonProperty *property = jsonObjectGetFirstProperty(object); property != NULL; property = jsonObjectGetNextProperty(property)) {
maxRecords++;
Expand All @@ -480,6 +489,16 @@ static void set_shared_uss_env(ConfigManager *configmgr) {
shared_uss_env = malloc(maxRecords * sizeof(char*));
memset(shared_uss_env, 0, maxRecords * sizeof(char*));

char *configEnv = malloc(PATH_MAX+32);
char *runtimeEnv = malloc(PATH_MAX+32);
char *haEnv = malloc(256);
snprintf(configEnv, PATH_MAX+32, "ZWE_CLI_PARAMETER_CONFIG=%s", zl_context.config_path);
shared_uss_env[idx++] = configEnv;
snprintf(runtimeEnv, PATH_MAX+32, "ZWE_zowe_runtimeDirectory=%s", zl_context.root_dir);
shared_uss_env[idx++] = runtimeEnv;
snprintf(haEnv, 256, "ZWE_CLI_PARAMETER_HA_INSTANCE=%s", zl_context.ha_instance_id);
shared_uss_env[idx++] = haEnv;

if (object) {
// Get all environment variables defined in zowe.yaml and put them in the output as they are
for (JsonProperty *property = jsonObjectGetFirstProperty(object); property != NULL; property = jsonObjectGetNextProperty(property)) {
Expand Down Expand Up @@ -513,6 +532,7 @@ static void set_shared_uss_env(ConfigManager *configmgr) {
}
}


// Get all environment variables defined in the system and put them in output if they were not already defined in zowe.yaml
for (char **env = environ; *env != 0; env++) {
char *thisEnv = *env;
Expand Down Expand Up @@ -540,6 +560,7 @@ static void set_shared_uss_env(ConfigManager *configmgr) {
shared_uss_env[idx++] = new_env;
}
}

shared_uss_env[idx] = NULL;
arrayListFree(list);
}
Expand Down Expand Up @@ -865,14 +886,20 @@ static const char **env_comp(zl_comp_t *comp) {
env_records++;
}

const char **env_comp = malloc((env_records + 2) * sizeof(char*));
const char **env_comp = malloc((env_records + 3) * sizeof(char*));

char *componentEnv = malloc(256);
snprintf(componentEnv, 256, "ZWE_CLI_PARAMETER_COMPONENT=%s", comp->name);


int i = 0;
env_comp[i++] = shareas;
env_comp[i++] = componentEnv;
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));
aux[strlen(thisEnv)] = '\0';
trimRight(aux, strlen(aux));
env_comp[i] = aux;
i++;
Expand Down Expand Up @@ -912,8 +939,11 @@ static int start_component(zl_comp_t *comp) {
int fd_count = 3;
int fd_map[3];
char bin[PATH_MAX];
char js_path[PATH_MAX];
snprintf(bin, sizeof(bin), "%s/bin/utils/configmgr", zl_context.root_dir);
snprintf(js_path, sizeof(js_path), "%s/bin/commands/internal/start/component/cli.js", zl_context.root_dir);


snprintf(bin, sizeof(bin), "%s/bin/zwe", zl_context.root_dir);
script = fopen(bin, "r");
if (script == NULL) {
DEBUG("script not open for %s - %s\n", comp->name, strerror(errno));
Expand All @@ -929,12 +959,8 @@ static int start_component(zl_comp_t *comp) {

const char *c_args[] = {
bin,
"internal",
"start",
"component",
"--config", zl_context.config_path,
"--ha-instance", zl_context.ha_instance_id,
"--component", comp->name,
"-script",
js_path,
NULL
};

Expand Down Expand Up @@ -1419,13 +1445,12 @@ 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 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;
const char basecmd[] = "%s ZWE_CLI_PARAMETER_CONFIG=\"%s\" %s/bin/utils/configmgr -script %s/bin/commands/internal/get-launch-components/cli.js 2>&1";
int size = (strlen(zl_context.root_dir) * 2) + strlen(zl_context.config_path) + 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);

sharedenv, zl_context.config_path, zl_context.root_dir, zl_context.root_dir);
return command;
}

Expand Down Expand Up @@ -1473,23 +1498,151 @@ static char* get_sharedenv(void) {
return output;
}

static int get_component_list(char *buf, size_t buf_size) {
char *sharedenv = get_sharedenv();
char *command = get_launch_components_cmd(sharedenv);
static int check_if_yaml_exists(const char *yaml, const char *name) {
struct stat s;
if (stat(yaml, &s) != 0) {
DEBUG("failed to get properties for file %s='%s' - %s\n", name, yaml, strerror(errno));
return -1;
}
return 0;
}

free(sharedenv);
static void get_yaml_pair_key(yaml_document_t *document, yaml_node_pair_t *pair, char *buf, size_t buf_size) {
yaml_node_t *node = yaml_document_get_node(document, pair->key);
if (node) {
snprintf(buf, buf_size, "%.*s", (int)node->data.scalar.length, (const char *)node->data.scalar.value);
#ifdef __MVS__
__atoe(buf);
#endif
} else {
snprintf(buf, buf_size, "");
DEBUG ("key node not found\n");
}
}

DEBUG("about to get component list\n");
static yaml_node_t *get_child_node(yaml_document_t *doc, yaml_node_t *node, const char *name) {
char key[ZL_YAML_KEY_LEN + 1];
yaml_node_t *value_node = NULL;
for (yaml_node_pair_t *pair = node->data.mapping.pairs.start; pair != node->data.mapping.pairs.top; pair++) {
get_yaml_pair_key(doc, pair, key, sizeof(key));
if (0 == strcmp(key, name)) {
value_node = yaml_document_get_node(doc, pair->value);
break;
}
}
return value_node;
}

static void get_yaml_scalar(yaml_document_t *doc, yaml_node_t *node, char *buf, size_t buf_size) {
char *value = (char *)node->data.scalar.value;
snprintf(buf, buf_size, "%s", value);
#ifdef __MVS__
__atoe(buf);
#endif
}

static yaml_node_t *get_node_by_path(yaml_document_t *doc, yaml_node_t *node, const char **path, size_t path_len) {
for (size_t i = 0; i < path_len; i++) {
node = get_child_node(doc, node, path[i]);
if (!node) {
break;
}
}
return node;
}

static int get_string_by_yaml_path(yaml_document_t *doc, yaml_node_t *root, const char **path, size_t path_len, char *buf, int buf_size) {
yaml_node_t *node = get_node_by_path(doc, root, path, path_len);
if (node && node->type == YAML_SCALAR_NODE) {
get_yaml_scalar(doc, node, buf, buf_size);
return 0;
}
return -1;
}

static int get_component_list(char *buf, size_t buf_size,ConfigManager *configmgr) {
char comp_list[COMP_LIST_SIZE] = {0};
if (run_command(command, handle_get_component_line, (void*)comp_list)) {
ERROR(MSG_COMP_LIST_ERR);
Json *result = NULL;
char manifestPath[PATH_MAX]={0};
char *runtimeDirectory=NULL;
char *extensionDirectory=NULL;
char item[128] = {0};
const char *start_path[] = {"commands", "start"};
int len = 0;
char errorBuffer[YAML_ERROR_MAX];
bool yamlExists;
bool startScript;
bool enabled;
bool wasMissing = false;

DEBUG("about to get component list\n");
int rc = cfgGetAnyC(configmgr, ZOWE_CONFIG_NAME, &result, 1, "components");
if (jsonIsObject(result)) {
JsonObject *resultObj = jsonAsObject(result);
JsonProperty *prop = resultObj->firstProperty;
int getStatus = cfgGetStringC(configmgr, ZOWE_CONFIG_NAME, &runtimeDirectory, 2, "zowe", "runtimeDirectory");
if (getStatus) {
getStatus = cfgGetStringC(configmgr, ZOWE_CONFIG_NAME, &extensionDirectory, 2, "zowe", "extensionDirectory");
if (getStatus) {
ERROR(" failed to get runtimeDirectory and extensionDirectory");
return -1;
}
}

while (prop!=NULL) {
enabled = false;
// check if component is enabled
getStatus = cfgGetBooleanC(configmgr, ZOWE_CONFIG_NAME, &enabled,3, "components", prop->key, "enabled");
if (getStatus) { // failed to get enabled value of the component
DEBUG("failed to get enabled value of the component %s\n", prop->key);
prop = prop->next;
continue;
}
snprintf(manifestPath, PATH_MAX, "%s/components/%s/manifest.yaml", runtimeDirectory, prop->key);
DEBUG("manifest path for component %s is %s\n", prop->key, manifestPath);

// check if manifest.yaml is in instance/components/component-name/manifest.yaml
yamlExists = true;
if (check_if_yaml_exists(manifestPath, "MANIFEST.YAML")) {
yamlExists = false;
// if not check instance/extensions/component/manifest.yaml
snprintf(manifestPath, PATH_MAX, "%s/components/%s/manifest.yaml", extensionDirectory, prop->key);
DEBUG("manifest path for component %s is %s\n", prop->key, manifestPath);
if(!check_if_yaml_exists(manifestPath, "MANIFEST.YAML"))
yamlExists = true;
}

// read the yaml and check for item 'commands.start', if present then add enabled component to component list
startScript = false;
if(enabled && yamlExists) {
yaml_document_t *document = readYAML2(manifestPath, errorBuffer, YAML_ERROR_MAX, &wasMissing);
yaml_node_t *root = yaml_document_get_root_node(document);
if (root) {
getStatus = get_string_by_yaml_path(document, root, start_path, sizeof(start_path)/sizeof(start_path[0]), item, sizeof(item));
memset(item, 0, sizeof(item));
if(!getStatus)
startScript = true;
}
if (startScript) {
strncpy(comp_list + len, prop->key, strlen(prop->key));
strncpy(comp_list + len + strlen(prop->key), ",", 1);
len += (strlen(prop->key)+1);
}
}
prop = prop->next;
}
if (len)
comp_list[len-1] = '\0';
}

if (strlen(comp_list) == 0) {
ERROR(MSG_COMP_LIST_EMPTY);
return -1;
}

snprintf(buf, buf_size, "%s", comp_list);
INFO(MSG_START_COMP_LIST, buf);

return 0;
}

Expand Down Expand Up @@ -1581,13 +1734,12 @@ static void print_line(void *data, const char *line) {
}

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;
const char basecmd[] = "%s ZWE_CLI_PARAMETER_CONFIG=\"%s\" %s/bin/utils/configmgr -script %s/bin/commands/internal/start/prepare/cli.js 2>&1";
int size = (strlen(zl_context.root_dir) * 2) + strlen(zl_context.config_path) + 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);

sharedenv, zl_context.config_path, zl_context.root_dir, zl_context.root_dir);
return command;
}

Expand Down Expand Up @@ -1676,6 +1828,7 @@ int main(int argc, char **argv) {
exit(EXIT_FAILURE);
}

setenv("_BPXK_AUTOCVT", "ON", 1);
INFO(MSG_LAUNCHER_START);
INFO(MSG_LINE_LENGTH);
printf_wto(MSG_LAUNCHER_START); // Manual sys log print (messages not set here yet)
Expand Down Expand Up @@ -1751,7 +1904,7 @@ int main(int argc, char **argv) {
if (prepare_instance()) {
exit(EXIT_FAILURE);
}
if (get_component_list(comp_buf, sizeof(comp_buf))) {
if (get_component_list(comp_buf, sizeof(comp_buf), configmgr)) {
exit(EXIT_FAILURE);
}
component_list = comp_buf;
Expand Down
Loading