Archived

This forum has been archived. Please start a new discussion on GitHub.

Relative paths for IceGrid.Node.Output are not relative to the Node

I'm building an application which will be installed (from an SVN) on different machines. As the install location will vary between machines I'm avoiding the use of absolute paths. As I control the directory structure and thus know the relative paths between the Nodes and the sub-directories which contain the Servers this hasn't proved a problem until I tried to use the IceGrid.Node.Output option (see snippet from config file below). To my surprise "IceGrid.Node.Output = logs" is interpreted relative the to Servers' working directories and not the Node's working directory (I'm using "pwd" when the servers are launched).

I would like to collect all the logs in one directory rather than relative to each Server. Is there something that I can put in the below configuration file to achieve that other than the absolute path? For example something tha expands to the absolute path at runtime, e.g. "IceGrid.Node.Output = `cwd` <this doesn't actually work>".

Thanks,

Paul

#
# IceGrid Node configuration.
# (co-located with registry)
#
IceGrid.Node.Endpoints = tcp
IceGrid.Node.Name = Node1
IceGrid.Node.Data = node # local directory name for node data storage
IceGrid.Node.Output = logs # local directory for output from this node's servers
# NB relative directory paths for Node.Output are interpreted relative to the server
IceGrid.Node.CollocateRegistry = 1
Ice.Default.Locator = IceGrid/Locator:tcp -p 4061

Comments

  • bernard
    bernard Jupiter, FL
    Hi Paul,

    Welcome to our forums!

    If you look at the configuration files generated by IceGrid, you'll see that all IceGrid.Node.Output does it trigger the creation of Ice.StdOut and Ice.StdErr settings in this configuration file. And a relative IceGrid.Node.Output path becomes a relative path for Ice.StdOut/Ice.StdErr.

    I think the default working directory for a server is actually the working directory of the node that launches it, so by default, you could not tell the difference. Perhaps you're setting a non-default working directory for your servers?

    A solution here could be to set Ice.StdOut and Ice.StdErr in your server configuration (IceGrid descriptors), using a variable such as ${node.datadir}:
    <properties>
       <property name="Ice.StdOut" value="${node.datadir}/logs/${server}.out/>  
       <property name="Ice.StdErr" value="${node.datadir}/logs/${server}.err/>  
    </properties>
    

    Best regards,
    Bernard
  • bernard wrote: »
    Welcome to our forums!

    Thanks!
    bernard wrote: »
    I think the default working directory for a server is actually the working directory of the node that launches it, so by default, you could not tell the difference. Perhaps you're setting a non-default working directory for your servers?

    Yes, I'm using the 'pwd' option in <server ...>, in the IceGrid descriptor file, to change the working directory for each server.

    Okay I'll look at your suggestion,

    thanks,

    Paul
  • Hi Bernard,

    I just realised how cunning your suggestion is. As you obviously knew ${node.datadir} is one of "special descriptor variables" which points to the "absolute pathname of the enclosing node's data directory". Thus getting an absolute path without the need to hard code it. Genius!

    I've adapted your suggestion and used
    <property name="Ice.StdOut" value="${node.datadir}/../logs/${server}.out"/>
    <property name="Ice.StdErr" value="${node.datadir}/../logs/${server}.err"/>
    

    which I think (haven't tested it yet) should give me exactly what I want.

    Many thanks!

    Paul
  • Hmm,

    I've now got a problem with ${server} not being resolved when the application descriptor file is read. My application description looks something like:
    <icegrid>
        <application name="somename">
    
            <!-- Set of default configuration properties for all servers -->
            <properties id="DefaultParams_AllServers">
                <!-- Send std out and std err to a common 'logs' directory. -->
                <!-- {node.datadir} is the absolute path name of the enclosing node's -->
                <!-- data directory, e.g. "NodeX/node/" so ../logs is "NodeX/logs". -->  
                <property name="Ice.StdOut" value="${node.datadir}/../logs/${server}.out"/>
                <property name="Ice.StdErr" value="${node.datadir}/../logs/${server}.err"/>
            </properties>
    
            <!-- ============================================================== -->
    
            <!-- Template for servers. -->
            <server-template id="ServerTemplate">
                <parameter name="server-name"/>
                <server
                    id="${server-name}"
                    pwd="${server-name}"
                    exe="python"
                    activation="always">
                    <option>${server-name}_start.py</option>
                    <adapter
                        name="${server-name}Adapter"
                        endpoints="tcp"/>
                    <properties>
                        <!-- import default configuration properties for publish subscribe servers -->
                        <properties refid="DefaultParams_AllServers"/>
                    </properties>
                </server>
            </server-template>
    
            <!-- ============================================================== -->
    
            <!-- Define all the servers that run on Node 1.  -->
            <node name="Node1">
    
                <!-- create a server -->
                <server-instance
                    template    = "ServerTemplate"
                    server-name = "SomeServer">
                    <properties>
                        <!-- locally override one of the default publish/subscribe config settings -->
                        <property name="DebugLevel" value="2"/>
                        <!-- configuration settings local to this server -->
                        <property name="Topic.Subscribe" value="output-topic"/>
                        <property name="Topic.Publish"   value="publish-topic"/>
                    </properties>
                </server-instance>
    
            </node>
    
        </application>
    </icegrid>
    

    I'm guessing this is due to scoping. But as ${node.datadir} is being resolved I'm not clear why ${server} isn't.
  • bernard
    bernard Jupiter, FL
    Hi Paul,

    According to IceGrid Property Set Semantics:

    Named property sets are evaluated at the point of definition. If you reference other property sets or use variables in a named property set definition, you must make sure that the referenced property sets or variables are defined in the same scope. For example, the following is correct:
    <application name="App">
    
        <variable name="level" value="1"/>
    
        <properties id="DebugApp">
            <property name="DebugLevel value="${level}">
        </properties>
    
    </application>
    

    However, the following example is wrong because the ${level} variable is not defined at the application scope:
    <application name="App">
    
        <properties id="DebugApp">
            <property name="DebugLevel value="${level}">
        </properties>
    
        <node name="TheNode">
            <variable name="level" value="1"/>
        </node>
    
    </application>
    

    If both the application and the node define the ${level} variable, the value of the ${level} variable in the DebugApp property set will be the value of the variable defined in the application descriptor.

    So you shouldn't be able to use ${node.datadir} or ${server} in this application-level property set. Can you confirm ${node.datadir} is indeed resolved with your example? This could be a bug.

    Thanks,
    Bernard
  • Won't have time for at least a week to check on what's actually happening, but I thought they might be resolved as they are reserved names, i.e. from the Ice Grid Manual:
    The availability of a variable is easily determined in some cases, but may not be readily apparent in others. For example, the following example represents a valid use of the ${node} variable:
    <icegrid>
        <application name="App">
            <server&#8209;template id="T" ...>
                <parameter name="id"/>
                <server id="${id}" ...>
                    <property name="NodeName" value="${node}"/>
                    ...
                </server>
            </server&#8209;template>
            <node name="TheNode">
                <server&#8209;instance template="T" id="TheServer"/>
            </node>
        </application>
    </icegrid>
    
    Although the server template descriptor is defined as a child of an application descriptor, its variables are not evaluated until it is instantiated. Since a template instance is always enclosed within a node, it is able to use the ${node} variable.