Unable to use variable in <Role> tag in Installer manifest?
I have a variable set up for the name of the namespace (in my code it's called PMGNAMESPACE), and I create a variable for the resource name, called PMGDbResource ( this == %DB_ABC)
The installer manifest is not evaluating the variable PMGDbResource int he <Role> tag, and I get this error:
017-10-12 08:56:57 0 RHS.Installer: ERROR #892: Resource ${PMGDbResource} does not exist.
2017-10-12 08:56:57 0 RHS.Installer: Installation failed at 2017-10-12 08:56:57
Is this typical or is there any work around? If I can't evaluate the variable for the %DB_namespace resource name, then I can't add the Role for a different namespace. I'm stuck with one name.
<Var Name="PMGDbResource" Value="%DB_${PMGNAMESPACE}"/> <!-- %DB_PMG -->
<Resource
Name="${PMGNAMESPACE}"
Description="Namespace Resource for ${PMGNAMESPACE}"
Permission=""
Type="Application" />
<Log Level="2" Text="Creating ${PMGNAMESPACE} Role" />
<!-- Attempting to use PMGDbResource variable here -->
<Role
Name="${PMGNAMESPACE}"
Description="Works User Role for ${PMGNAMESPACE} Namespace"
Resources="${PMGDbResource}:RW,PMG:RWU" <-- I'd like to use ${PMGNAMESPACE} here too, but variables aren't evaluated in this part of the Role tag :( -->
RolesGranted="" />
Comments
Resources property is not evaluated. You can see that in %Installer.Role class, %OnGenerateCode method.
/// Generate code for this document. Method %OnGenerateCode(pTargetClass As %Dictionary.CompiledClass, pCode As %Stream.TmpCharacter, pDocument As %Installer.Manifest) As %Status [ Internal ] { Do pCode.WriteLine(..%Indent()_"Do tInstaller.CreateRole($$$EVAL("_..Target_"),$$$EVAL("_..Description_"),"""_..Resources_""","""_..RolesGranted_""")") Quit $$$OK }
You can get around that with this hacky solution:
<Role Name="${PMGNAMESPACE}" Description="Works User Role for ${PMGNAMESPACE} Namespace" Resources='"_tInstaller.Evaluate("${PMGDbResource}:RW,PMG:RWU")_"' RolesGranted="" />
Which would be compiled into the following code:
Do tInstaller.CreateRole(tInstaller.Evaluate("${PMGNAMESPACE}"),tInstaller.Evaluate("Works User Role for ${PMGNAMESPACE} Namespace"),""_tInstaller.Evaluate("${PMGDbResource}:RW,PMG:RWU")_"","")
I guess if you need to do that once, it's okay. But if it's a regular occurrence writing a method and calling it from installer might be a better solution.
Hi Eduard,
Interesting hack, and a good point. There's enough going back and forth between namespaces, importing new code, and running new methods in the newly created namespace already, so I'd prefer to keep my manifest simple. If I find that it needs to be done in, say, 5 places, I'll just say it needs to be the one value ("ABC") and I can create a copy of the installer if it needs to be a new value ("XYZ"). If it needs to be a new value, then we're probably moving toward replacing the old value anyway.
Thanks.