Specify environment variables to contract binary (#355)

This commit is contained in:
Chalith Desaman
2022-01-11 13:41:33 +05:30
committed by GitHub
parent 2d4cebb37e
commit 150df0eabb
5 changed files with 27 additions and 5 deletions

View File

@@ -158,6 +158,7 @@ struct hp_config
struct hp_unl_collection unl;
char *bin_path;
char *bin_args;
char *environment;
uint32_t roundtime;
uint32_t stage_slice;
char *consensus;
@@ -584,6 +585,7 @@ void hp_free_config(struct hp_config *config)
__HP_FREE(config->unl.list);
__HP_FREE(config->bin_path);
__HP_FREE(config->bin_args);
__HP_FREE(config->environment);
__HP_FREE(config->consensus);
__HP_FREE(config->npl);
__HP_FREE(config->appbill.mode);
@@ -737,7 +739,7 @@ int __hp_write_to_patch_file(const int fd, const struct hp_config *config)
// Top-level field values.
const char *json_string = " \"bin_path\": \"%s\",\n \"bin_args\": \"%s\",\n \"roundtime\": %s,\n \"stage_slice\": %s,\n"
const char *json_string = " \"bin_path\": \"%s\",\n \"bin_args\": \"%s\",\n \"environment\": \"%s\",\n \"roundtime\": %s,\n \"stage_slice\": %s,\n"
" \"consensus\": \"%s\",\n \"npl\": \"%s\",\n \"max_input_ledger_offset\": %s,\n";
char roundtime_str[16];
@@ -749,11 +751,11 @@ int __hp_write_to_patch_file(const int fd, const struct hp_config *config)
char max_input_ledger_offset_str[16];
sprintf(max_input_ledger_offset_str, "%d", config->max_input_ledger_offset);
const size_t json_string_len = 149 + strlen(config->bin_path) + strlen(config->bin_args) +
const size_t json_string_len = 172 + strlen(config->bin_path) + strlen(config->bin_args) + strlen(config->environment) +
strlen(roundtime_str) + strlen(stage_slice_str) +
strlen(config->consensus) + strlen(config->npl) + strlen(max_input_ledger_offset_str);
char json_buf[json_string_len];
sprintf(json_buf, json_string, config->bin_path, config->bin_args, roundtime_str, stage_slice_str, config->consensus, config->npl, max_input_ledger_offset_str);
sprintf(json_buf, json_string, config->bin_path, config->bin_args, config->environment, roundtime_str, stage_slice_str, config->consensus, config->npl, max_input_ledger_offset_str);
iov_vec[2].iov_base = json_buf;
iov_vec[2].iov_len = json_string_len;
@@ -844,6 +846,10 @@ void __hp_populate_patch_from_json_object(struct hp_config *config, const struct
{
__HP_ASSIGN_CHAR_PTR(config->bin_args, elem);
}
else if (strcmp(k->string, "environment") == 0)
{
__HP_ASSIGN_CHAR_PTR(config->environment, elem);
}
else if (strcmp(k->string, "roundtime") == 0)
{
const struct json_number_s *value = (struct json_number_s *)elem->value->payload;

View File

@@ -948,6 +948,7 @@ namespace conf
jdoc.insert_or_assign("unl", unl);
jdoc.insert_or_assign("bin_path", contract.bin_path);
jdoc.insert_or_assign("bin_args", contract.bin_args);
jdoc.insert_or_assign("environment", contract.environment);
jdoc.insert_or_assign("roundtime", contract.roundtime.load());
jdoc.insert_or_assign("stage_slice", contract.stage_slice.load());
jdoc.insert_or_assign("consensus", contract.is_consensus_public ? PUBLIC : PRIVATE);
@@ -1045,6 +1046,7 @@ namespace conf
contract.bin_path = jdoc["bin_path"].as<std::string>();
contract.bin_args = jdoc["bin_args"].as<std::string>();
contract.environment = jdoc["environment"].as<std::string>();
contract.roundtime = jdoc["roundtime"].as<uint32_t>();
if (contract.roundtime < 1 || contract.roundtime > MAX_ROUND_TIME)
@@ -1093,6 +1095,11 @@ namespace conf
return -1;
}
contract.runtime_env_args.clear();
// Populate runtime environment args.
if (!contract.environment.empty())
util::split_string(contract.runtime_env_args, contract.environment, " ");
contract.runtime_binexec_args.clear();
// Populate runtime contract execution args.
if (!contract.bin_args.empty())

View File

@@ -182,6 +182,7 @@ namespace conf
std::set<std::string> unl; // Unique node list (list of binary public keys).
std::string bin_path; // Full path to the contract binary.
std::string bin_args; // CLI arguments to pass to the contract binary.
std::string environment; // Environment variables to be passed into contract.
std::atomic<uint32_t> roundtime = 0; // Consensus round time in ms (max: 3,600,000).
std::atomic<uint32_t> stage_slice = 0; // Percentage slice of round time that stages 0,1,2 get (max: 33).
bool is_consensus_public = false; // If true, consensus are broadcasted to non-unl nodes as well.
@@ -192,6 +193,7 @@ namespace conf
// Config element which are initialized in memory (This is not directly loaded from the config file)
std::vector<std::string> runtime_binexec_args; // Contract binary execution args used during runtime.
std::vector<std::string> runtime_env_args; // Contract environment variables.
};
struct user_config

View File

@@ -210,6 +210,12 @@ namespace sc
execv_args[j] = conf::cfg.contract.runtime_binexec_args[i].data();
execv_args[len - 1] = NULL;
len = conf::cfg.contract.runtime_env_args.size() + 1;
char *env_args[len];
for (int i = 0; i < conf::cfg.contract.runtime_env_args.size(); i++)
env_args[i] = conf::cfg.contract.runtime_env_args[i].data();
env_args[len - 1] = NULL;
if (chdir(ctx.working_dir.c_str()) == -1)
{
std::cerr << errno << ": Contract process chdir failed." << (ctx.args.readonly ? " (rdonly)" : "") << "\n";
@@ -224,8 +230,8 @@ namespace sc
exit(1);
}
execv(execv_args[0], execv_args);
std::cerr << errno << ": Contract process execv failed." << (ctx.args.readonly ? " (rdonly)" : "") << "\n";
execve(execv_args[0], execv_args, env_args);
std::cerr << errno << ": Contract process execve failed." << (ctx.args.readonly ? " (rdonly)" : "") << "\n";
exit(1);
}
else

View File

@@ -111,6 +111,7 @@ do
id: '3c349abe-4d70-4f50-9fa6-018f1f2530ab', \
bin_path: '$binary', \
bin_args: '$binargs', \
environment: '', \
roundtime: $roundtime, \
consensus: 'public', \
npl: 'public', \