Caché Installation Guide
Creating and Using an Installation Manifest
[Home] [Back] 
InterSystems: The power behind what matters   
Class Reference   
Search:    

This chapter describes how to use the %Installer utility to create an installation manifest describing a specific Caché configuration and use it to generate code to configure a Caché instance. The chapter discusses the following topics:

Overview of an Installation Manifest
The %Installer utility lets you define an installation manifest that describes a specific Caché configuration, rather than a step-by-step installation process. To do so, you create a class that contains an XData block describing the configuration you want, using variables that contain information usually provided during installation (superserver port, operating system, and so on). You also include in the class a method that uses the XData block to generate code to configure the instance. (You can copy and paste this method from this book.)
Once you have defined the manifest, you can call it during installation, from a Terminal session, or from code. The manifest must be run in the %SYS namespace.
Creating a Class That Defines a Manifest
To create a class that defines an installation manifest, create a class as follows:
The following is an example:
Include %occInclude
Class MyPackage.MyInstaller
{
XData MyInstall [ XMLNamespace = INSTALLER ]
   {
   <Manifest>
      <Var/>
      <If/>
      <Log/>
      <User/>
      <Resource/>
      <Role/>
      <SystemSetting/>
      <ForEach>
         <!--Code for each iteration of named Index key while looping through values-->
      </ForEach>
      <CopyDir/>
      <CopyFile/>
      <Namespace>
         <Configuration>
            <Database/>
            <ForEach>
               <!--Code for each iteration of named Index key while looping through values-->
            </ForEach>
            <Log/>
            <GlobalMapping/>
            <RoutineMapping/>
            <ClassMapping/>
         </Configuration>
         <Compile/>
         <CopyClass/>
         <CSPApplication/>
         <ForEach>
            <!--Code for each iteration of named Index key while looping through values-->
         </ForEach>
         <If/>
         <Import/>
         <Invoke/>
      </Namespace>
   </Manifest>
   }

ClassMethod setup(ByRef pVars, pLogLevel As %Integer = 3, 
   pInstaller As %Installer.Installer, 
   pLogger As %Installer.AbstractLogger) 
   As %Status [ CodeMode = objectgenerator, Internal ]
   {
   #; Let XGL document generate code for this method. 
   Quit ##class(%Installer.Manifest).%Generate(%compiledclass,
      %code, "MyInstall")
   }
}
Key Options
The outermost XML tag, <Manifest>, contains all the information for code generation. There can be as many <Namespace> tags as needed within the <Manifest> tag to define namespaces in the manifest.
A <Configuration> tag, which is located inside a <Namespace> tag, is required only if databases and/or mappings are being defined. There must be as many <Database> tags within the <Configuration> tag as are needed to define the namespace. In addition, following each <Database> tag, you can add <GlobalMapping>, <RoutineMapping>, and <ClassMapping> tags as required. The </Configuration> tag activates the defined mappings.
Within the context of a <Namespace> tag — after the databases and their mappings have been defined — globals can be loaded, and routines and classes can be loaded and compiled using <Import> tag. Class methods can be invoked using the <Invoke> tag. Invoked class methods can execute routines and access globals that have been imported.
Optionally, you can define variable pairs with the <Var> tag; each variable must specify a name and value. When the value for the <Var> is needed, the name is referenced by the ${NameAssigned} syntax.
For an example, see Example later in this chapter.
Adding Users and Passwords
There are several ways to add users (including their roles and passwords) to the installed instance, as follows:
Adding Messages
You can define messages to be added to the log by incorporating <Log> tags in your class, in the following format:
<Log Level="<level>" Text="<text>"/>
The log level must be in the range of 0 to 3, where 0 is “none” and 3 is “verbose”; if the log level specified in the setup() method is equal to or greater than the Level property in the <Log> tag, the message is logged. The text is limited to 32,000 characters.
You set the log level via the second argument of the setup() method (for more information, see Using the Manifest later in this chapter). Since this cannot be passed to the manifest from the install, you must set it in the class as follows:
ClassMethod setup(ByRef pVars, pLogLevel As %Integer = 3, 
   pInstaller As %Installer.Installer, 
   pLogger As %Installer.AbstractLogger) 
   As %Status [ CodeMode = objectgenerator, Internal ]
You can direct where messages are displayed via the fourth argument (%Installer.AbstractLogger) of the setup() method; for example, if you instantiate a %Installer.FileLogger object referencing an operating system file, all %Installer and log messages are directed to that file. (Without this argument, all messages are written to the primary device if setup() is called directly, and are ignored if it is executed by the installer.)
<Manifest> Tags
Following are descriptions of the tags (in alphabetical order) you can use within the XData block of your manifest class.
Some tags can contain expressions (strings) that are expanded when the manifest is executed. There are three types of expressions that can be expanded, as follows:
Parameter expressions are expanded at compile time, which means they can be nested within variable and COS expressions. Addtionally, variable expressions are expanded before COS expressions and thus can be nested within the latter.
Important:
Null arguments cannot be passed in tags in a manifest class. The <Arg/> tag passes an empty string, equivalent to <Arg=""/>, not null.
Note:
The value shown in square brackets ([]) is the default used for a property if it is not specified explicitly.
<Arg>
Parent tags: <Invoke>, <Error>
Passes an argument into a method called via <Invoke> or <Error>.
<Error Status="$$$NamespaceDoesNotExist">
        <Arg Value="${NAMESPACE}"/>
/>
<ClassMapping>
Parent tag: <Configuration>
Creates a class mapping from a database to the namespace which contains this <Configuration> item.
<ClassMapping Package="MYAPP"
     From="MYDB"/>
<Compile>
Parent tag: <Namespace>
Compiles the specified class name by calling %SYSTEM.OBJ.Compile(Class, Flags).
<Compile  
    Class="MyPackage.MyClass"
    Flags="ck"
    IgnoreErrors=0/>
<Configuration>
Parent tag: <Namespace>
Child tags: <ClassMapping>, <Database>, <GlobalMapping>, <RoutineMapping>
Required as parent tag of configuration tags within <Namespace>. The closing tag (</Configuration>) activates the mappings for the databases in the namespace and updates the .cpf file.
No properties.
<Configuration>
    <Database> . . . />
    <ClassMapping> . . . />
/>
<CopyClass>
Parent tag: <Namespace>
Copies or moves the source class definition to the target.
<CopyClass  
    Src="MyPackage.MyClass"
    Target="NewPackage.NewClass"
    Replace="0"/>
<CopyDir>
Parent tag: <Manifest>
Copies the source directory to a target.
<CopyDir  
    Src="${MGRDIR}"
    Target="F:\MyTargetDir"
    IgnoreErrors="0"/>
<CopyFile>
Parent tag: <Manifest>
Copies the source file to a target.
<CopyDir  
    Src="${MGRDIR}\cconsole.log"
    Target="F:\${INSTANCE}_log"
    IgnoreErrors="0"/>
<Credential>
Parent tag: <Production>
Creates or overrides the access credentials
<Credential  
    Name="Admin"
    Username="administrator"
    Password="123jUgT540!f3B$#"
    Overwrite="0"/>
<CSPApplication>
Parent tag: <Namespace>
Defines one or more CSP applications, as defined within the Security.Applications class.
<CSPApplication 
    Url="/csp/foo/bar"
    Description=""
    Directory="C\InterSystems\Cache\CSP\Democode1"
    Resource=""
    Grant="%DB_%DEFAULT"
    Recurse="1"
    LoginClass=""
    CookiePath="/csp/demo1"
    AuthenticationMethods="64"/>
<Database>
Parent tag: <Configuration>
Defines a database within a namespace.
See Configuring Databases in the “Configuring Caché” chapter of the Caché System Administration Guide for information about the database settings controlled by the following properties.
<Database Name="${DBNAME}" 
    Dir="${MGRDIR}/${DBNAME}"  
    Create="yes"
    Resource="${DBRESOURCE}"
    Blocksize="8192"
    ClusterMountMode="0"
    Collation="5"
    Encrypted="0"
    EncryptionKeyID=
    ExpansionSize="0"
    InitialSize="1"
    MaximumSize="0"
    MountAtStartup="0"
    MountRequired="0"
    StreamLocation=
    PublicPermissions=""/>
<Database Name="MYAPP" 
    Dir="${MYAPPDIR}/db"  
    Create="no"
    Resource="${MYAPPRESOURCE}"
    Blocksize="8192"
    ClusterMountMode="0"
    Collation="5"
    Encrypted="0"
    EncryptionKeyID=
    ExpansionSize="0"
    InitialSize="1"
    MaximumSize="0"
    MountAtStartup="0"
    MountRequired="0"
    StreamLocation=
    PublicPermissions=""/>
<Default>
Parent tag: <Manifest>
Sets the variable value if it is not already set.
<Default Name="blksiz"
    Value=8192" />
<Else>
Parent tags: <Manifest>, <Namespace>
Executed when the conditional defined by the preceding <If> statement is false.
No properties.
<Error>
Parent tag: <Manifest>
Child tag: <arg>
Generates an error.
<Error Status="$$$NamespaceDoesNotExist" Source=>
    <Arg Value="${NAMESPACE}"/>
</Error>
<ForEach>
Parent tag: <Manifest>
Defines values for iterations of the specified index key.
<ForEach 
    Index="TargetNameSpace"
    Values="%SYS,Samples,User">
    <!--Code for each iteration of TargetNameSpace-->
</ForEach>
<GlobalMapping>
Parent tag: <Configuration>
Maps a global to the current namespace.
<GlobalMapping Global="MyAppData.*"
    From="MYAPP" Collation="30"/> 
<GlobalMapping Global="cspRule" 
    From="MYAPP"/>
<If>
Parent tags: <Manifest>, <Namespace>
Specifies a conditional action.
<If Condition='$L("${NAMESPACE}")=0'>
    <Error Status="$$$NamespaceDoesNotExist" Source=>
        <Arg Value="${NAMESPACE}"/>
    </Error>
</If>
<IfDef>
Parent tags: <Manifest>, <Namespace>
Specifies a conditional action if a variable has been set.
<IfDef Var="DBCreateName>
   <Database Name="${DBNAME}" 
       Dir="${MGRDIR}/${DBNAME}"  
       Create="yes"
       ...
</IfDef>
<IfNotDef>
Parent tags: <Manifest>, <Namespace>
Specifies a conditional action if a variable has not been set.
<Import>
Parent tag: <Namespace>
Imports files by calling %SYSTEM.OBJ.ImportDir(File,Flags,Recurse) or %SYSTEM.OBJ.Load(File,Flags).
<Invoke>
Parent tag: <Namespace>
Child tag: <arg>
Calls a class method and returns the execution result as the value of a variable.
<Invoke Class="SECURITY.SSLConfigs" Method="GetCertificate" CheckStatus="1" Return="CertContents"> 
    <Arg Value="Cache.cer"/>
</Invoke>
<LoadPage>
Parent tag: <Namespace>
Loads a CSP page by calling %SYSTEM.CSP.LoadPage(PageURL,Flags) or %SYSTEM.CSP.LoadPageDir(DirURL,Flags).
<Log>
Parent tag: <Manifest>
Writes a message to the log specified by the setup() method if the log level specified by the setup() method is greater or equal to the level property provided.
See Adding Messages for more information.
<Manifest>
Parent tag: n/a (Root tag, containing all other tags.)
Child tags: <CopyDir>, <CopyFile>, <Default>, <Else>, <Error>, <ForEach>, <If>, <IfDef>, <IfNotDef>, <Log>, <Namespace>, <Resource>, <Role>, <SystemSetting>, <User>, <Var>
No properties.
<Manifest>
    <Namespace ... >
        <Configuration>
            <Database .../>
            <Database .../>
        </Configuration>
    </Namespace>
</Manifest>
<Namespace>
Parent tag: <Manifest>
Child tags: <Compile>, <Configuration>, <CopyClass>, <CSPApplication>, <Else>, <If>, <IfDef>, <IfNotDef>, <Import>, <Invoke>, <LoadPage>, <Production>
Defines a namespace.
(Other properties are applicable to Ensemble web applications.)
<Namespace Name="${NAMESPACE}" 
     Create="yes" 
     Code="${NAMESPACE}"
     Data="${NAMESPACE}"> 
          <Configuration> 
               <Database Name="${NAMESPACE}" . . . />
          </Configuration>
</Namespace>
<Production>
Parent tag: <Namespace>
Child tags: <Credential>, <Setting>
Defines an Ensemble production.
<Production Name="${NAMESPACE}" 
     AutoStart="1" />
<Resource>
Parent tag: <Manifest>
Defines a resource.
<Resource
    Name="%accounting_user" 
    Description="Accounting"
    Permission="RW"/>
<Role>
Parent tag: <Manifest>
Defines a role.
<Role 
    Name="%DB_USER"
    Description="Database user"
    Resources="MyResource:RW,MyResource1:RWU"
    RolesGranted= />
<RoutineMapping>
Parent tag: <Configuration>
Defines a routing mapping.
<RoutineMapping Name="MyRoutine"
    Type="ALL" From="${NAMESPACE}" /> 
<Setting>
Parent tag: <Production>
Configures an item in the Ensemble production by calling the Ens.Production.ApplySettings() method.
<Production Name="Demo.ComplexMap.SemesterProduction">
    <Setting Item="Semester_Data_FileService"
        Target=“Item"
        Setting=“PoolSize"
        Value=“1”/>
    <Setting Item="Semester_Data_FileService"
        Target=“Host"
        Setting="ComplexMap"
        Value="Demo.ComplexMap.Semester.SemesterData"/>
    <Setting Item="Semester_Data_FileService"
        Target="Adapter"
        Setting="FilePath"
        Value="C:\Practice\in\”/>
</Production>
<SystemSetting>
Parent tag: <Manifest>
Sets the value for a property of any Config class that implements the Modify method.
<SystemSetting 
    Name="Config.Miscellaneous.EnableLongStrings"
    Value="1"/>
<User>
Parent tag: <Manifest>
Defines a user; if PasswordVar is included, the user’s password must be provided in the specified variable name.
<User 
    Username="Clerk1"
    PasswordVar="clerk1pw"
    Roles="Dataentry"
    Fullname="Data Entry Clerk"
    Namespace=
    Routine=
    ExpirationDate=
    ChangePassword=
    Enabled=
    Comment=""/>
<Var>
Parent tag: <Manifest>
Defines and sets variables that can be used in the manifest/
<Var Name="Namespace" Value="MUSIC"/> 
<Var Name="GlobalDatabase" Value="${Namespace}G"/> 
<Var Name="RoutineDatabase" Value="${Namespace}R"/> 
<Var Name="AppDir" Value="C:\MyApp\${CFGNAME}"/> 
<Var Name="GlobalDatabaseDir" Value="${AppDir}\${GlobalDatabase}"/> 
<Var Name="RoutineDatabaseDir" Value="${AppDir}\${RoutineDatabase}"/> 
<Var Name="Resource" Value="%DB_${Namespace}"/> 
<Var Name="Role" Value="${Namespace}"/> 
<Var Name="CSPResource" Value="CSP_${Namespace}"/> 
For a comprehensive example of a user-defined installer class, see Sample.Installer in the SAMPLES namespace.
For an up-to-date list of tags and attributes, see the %Installer class reference documentation.
Variables Available within <Manifest>
The following table lists the predefined variables that you can use in the manifest:
Variable Name Description
SourceDir (Available only when the installer is run) Directory from which the installation (setup_cache.exe or cinstall) is running.
ISCUpgrade (Available only when the installer is run) Indicates whether this is a new installation or an upgrade. This variable is either 0 (new installation) or 1 (upgrade).
CFGDIR See INSTALLDIR.
CFGNAME Instance name.
CPUCOUNT Number of operating system CPUs.
CSPDIR CSP directory.
HOSTNAME Name of the host server.
HTTPPORT Web server port.
INSTALLDIR Directory into which Caché is installed.
MGRDIR Manager (mgr) directory.
PLATFORM Operating system.
PORT Caché superserver port.
PROCESSOR Processor chip.
VERSION Caché version number.
Using the Manifest
You can use the manifest as follows:
Example
The following class creates a namespace (MyNamespace) and three databases; two of the databases are defined as the default databases for globals (MyDataDB) and routines (MyRoutinesDB), while the third database (MyMappingDB) is a globals database that overrides the default database mapping for t* globals in the MyNamespace namespace.
Note:
For a more comprehensive example, see the Sample.Installer class in the SAMPLES namespace.
Include %occInclude

/// Simple example of installation instructions (Manifest)
Class MyInstallerPackage.SimpleManifest
{

XData SimpleManifest [ XMLNamespace = INSTALLER ]
{
<Manifest>
    <Namespace Name="MyNamespace" Create="yes" 
        Code="MyRoutinesDB" Data="MyDataDB">
      <Configuration>
        <Database Name="MyRoutinesDB" Create="yes" 
            Dir="C:\MyInstallerDir\MyRoutinesDB"/>
        <Database Name="MyDataDB" Create="yes" 
            Dir="C:\MyInstallerDir\MyDataDB"/>
        <Database Name="MyMappingDB" Create="yes" 
            Dir="C:\MyInstallerDir\MyMappingDB"/>
        <GlobalMapping Global="t*" From="MyMappingDB"/>
      </Configuration>
    </Namespace>
</Manifest>
}

/// This is a method generator whose code is generated by XGL.
ClassMethod setup(ByRef pVars, pLogLevel As %Integer = 3, 
   pInstaller As %Installer.Installer, 
   pLogger As %Installer.AbstractLogger) 
   As %Status [ CodeMode = objectgenerator, Internal ]
{
    #; Let our XGL document generate code for this method. 
    Quit ##class(%Installer.Manifest).%Generate(%compiledclass, 
    %code, "SimpleManifest")
}

}
After the class is compiled, you can invoke it in the Terminal as shown below (assuming you created the class in the USER namespace):
%SYS>znspace "USER"
USER>do ##class(MyInstallerPackage.SimpleManifest).setup()