bool ArgList::InsertArgsIntoClassAd(ClassAd *ad,CondorVersionInfo *condor_version,MyString *error_msg) { bool has_args1 = ad->LookupExpr(ATTR_JOB_ARGUMENTS1) != NULL; bool has_args2 = ad->LookupExpr(ATTR_JOB_ARGUMENTS2) != NULL; bool requires_v1 = false; bool condor_version_requires_v1 = false; if(condor_version) { requires_v1 = CondorVersionRequiresV1(*condor_version); condor_version_requires_v1 = true; } else if(input_was_unknown_platform_v1) { requires_v1 = true; } if( !requires_v1 ) { MyString args2; if(!GetArgsStringV2Raw(&args2,error_msg)) return false; ad->Assign(ATTR_JOB_ARGUMENTS2,args2.Value()); } else if(has_args2) { ad->Delete(ATTR_JOB_ARGUMENTS2); } if(requires_v1) { MyString args1; if(GetArgsStringV1Raw(&args1,error_msg)) { ad->Assign(ATTR_JOB_ARGUMENTS1,args1.Value()); } else { if(condor_version_requires_v1 && !input_was_unknown_platform_v1) { // We failed to convert to V1 syntax, but otherwise we could // have converted to V2 syntax. // Rather than failing outright, simply remove // all arguments from the ClassAd, which will // cause failures in older versions of Condor. // We get here, for example, when the schedd is // generating the expanded ad to send to an older // starter that does not understand V2 syntax. // The end result in this case is to fail when the // starter tries to read the arguments, and then // we go back and get a new match, which hopefully // is a machine that understands V2 syntax. A more // direct mechanism would be nice, but this one should // at least prevent incorrect behavior. ad->Delete(ATTR_JOB_ARGUMENTS1); ad->Delete(ATTR_JOB_ARGUMENTS2); if(error_msg) { dprintf(D_FULLDEBUG,"Failed to convert arguments to V1 syntax: %s\n",error_msg->Value()); } } else { // Failed to convert to V1 syntax, and the ad does not // already contain V2 syntax, so we should assume the // worst. AddErrorMessage("Failed to convert arguments to V1 syntax.",error_msg); return false; } } } else if(has_args1) { ad->Delete(ATTR_JOB_ARGUMENTS1); } return true; }
bool Env::InsertEnvIntoClassAd( ClassAd *ad, MyString *error_msg, char const *opsys, CondorVersionInfo *condor_version) const { bool has_env1 = ad->LookupExpr(ATTR_JOB_ENVIRONMENT1) != NULL; bool has_env2 = ad->LookupExpr(ATTR_JOB_ENVIRONMENT2) != NULL; bool requires_env1 = false; if(condor_version) { requires_env1 = CondorVersionRequiresV1(*condor_version); } if(requires_env1) { if(has_env2) { ad->Delete(ATTR_JOB_ENVIRONMENT2); } } if( (has_env2 || !has_env1) && !requires_env1) { MyString env2; if(!getDelimitedStringV2Raw(&env2,error_msg)) { return false; } ad->Assign(ATTR_JOB_ENVIRONMENT2,env2.Value()); } if(has_env1 || requires_env1) { // Record the OPSYS that is being used to delimit the environment. char *lookup_delim = NULL; char delim = '\0'; if(opsys) { // Use delimiter for target opsys. delim = GetEnvV1Delimiter(opsys); } else if(ad->LookupString(ATTR_JOB_ENVIRONMENT1_DELIM,&lookup_delim)) { // Use delimiter that was used previously in this ad. delim = *lookup_delim; } else { // Use delimiter for the opsys we are currently running under. delim = env_delimiter; } if(!lookup_delim) { // Save the delimiter that we have chosen, in case the ad // is read by somebody on a platform that is not the same // as opsys. Example: we are writing the expanded ad in // the schedd for a starter on a different opsys, but we // want shadows to be able to still parse the environment. char delim_str[2]; delim_str[0] = delim; delim_str[1] = '\0'; ad->Assign(ATTR_JOB_ENVIRONMENT1_DELIM,delim_str); } MyString env1; bool env1_success = getDelimitedStringV1Raw(&env1,error_msg,delim); if(lookup_delim) { free(lookup_delim); lookup_delim = NULL; } if(env1_success) { ad->Assign(ATTR_JOB_ENVIRONMENT1,env1.Value()); } else { if(has_env2) { // We failed to convert to V1 syntax, but we started // with V2, so this is a special kind of failure. // Rather than failing outright, simply stick // an invalid environment value in the V1 attribute. // This happens, for example, when the schedd is // generating the expanded ad to send to an older // starter that does not understand V2 syntax. // The end result in this case is to fail when the // starter tries to read the environment, and then // we go back and get a new match, which hopefully // is a machine that understands V2 syntax. A more // direct mechanism would be nice, but this one should // at least prevent incorrect behavior. ad->Assign(ATTR_JOB_ENVIRONMENT1,"ENVIRONMENT_CONVERSION_ERROR"); dprintf(D_FULLDEBUG,"Failed to convert environment to V1 syntax: %s\n",error_msg ? error_msg->Value() : ""); } else { // Failed to convert to V1 syntax, and the ad does not // already contain V2 syntax, so we should assume the // worst. AddErrorMessage("Failed to convert to target environment syntax.",error_msg); return false; } } } return true; }