factJunction.job

Demonstrates using fact junctions to retrieve information about objects in the grid relative to another object.

Detail

Each object in the grid has a set of facts which can be read and modified. Some of these facts are special in the sense that their value contains the name of another object that must exist in the grid. These special facts are called fact junctions.

Fact junctions provide a way to reference the facts of one object, using another object as a starting point. For example, all jobs in the grid have a fact named job.accountinggroup. The value for job.accountinggroup must be the name of a job group currently existing in the grid (the default being the group named all). The following JDL code prints the ID of the accounting group for the job named myJob without using fact junctions:

job = getMatrix().getGridObject(TYPE_JOB, “myJob”)
groupName = job.getFact(“job.accountinggroup”)
group = getMatrix().getGridObject(TYPE_JOBGROUP, groupName)
print “Group ID: “ + group.getFact(“group.id”)

Using fact junctions, you can obtain the ID of the accounting group without having to retrieve a reference to the group object first, as follows:

job = getMatrix().getGridObject(TYPE_JOB, “myJob”)
print “Group ID: “ + job.getFact(“job.accountinggroup.id”)

Notice the job myJob does not have a fact named job.accountinggroup.id. However, it does have a fact named “job.accountinggroup”, which contains the name of an existing job group. This job group has the fact “group.id”, and using fact junctions you can obtain the value of this fact without explicitly reading it off of the job group object itself.

Usage

> zosadmin login --user zosadmin Login to server: skate
Please enter current password for 'zosadmin':
Logged into grid on server 'skate'

> cd /opt/novell/zenworks/zos/server/examples
> zosadmin deploy factJunction.job
factJunction successfully deployed

> zos login --user zenuser
Please enter current password for 'zenuser':
 Logged into grid as zenuser

> zos jobinfo --detail factJunction
Jobname/Parameters    Attributes
------------------    ----------
factJunction       Desc: This is a test job to exercise fact junctions.

No parameters defined for this job.

Description

The files that make up the factJunction job include:

factJunction                                     # Total: 205 lines
|-- factJunction.jdl                             #  179 lines
`-- factJunction.policy                          #   26 lines

factJunction.jdl

  1  # -----------------------------------------------------------------------------
  2  #  Copyright  2008 Novell, Inc. All Rights Reserved.
  3  #
  4  #  NOVELL PROVIDES THE SOFTWARE "AS IS," WITHOUT ANY EXPRESS OR IMPLIED
  5  #  WARRANTY, INCLUDING WITHOUT THE IMPLIED WARRANTIES OF MERCHANTABILITY,
  6  #  FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGMENT.  NOVELL, THE AUTHORS
  7  #  OF THE SOFTWARE, AND THE OWNERS OF COPYRIGHT IN THE SOFTWARE ARE NOT LIABLE
  8  #  FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  9  #  TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE
 10  #  OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 11  # -----------------------------------------------------------------------------
 12  #  $Id: factJunction.jdl,v 1.3 2008/02/27 20:49:39 john Exp $
 13  # -----------------------------------------------------------------------------
 14
 15  #
 16  # This is a test job, but also illustrates all the implemented fact junctions.
 17  # A fact junction is a way to access facts on a 'referenced' object.
 18  # E.g. vmhost.resource.***  redirects from the vmhost object through the
 19  #      juction onto the underlying physical resource object.
 20  #
 21  # To setup for test, copy job into the 'provisionAdapter' job group.
 22  #
 23
 24  #
 25  # Add to the 'examples' group on deployment
 26  #
 27  if __mode__ == "deploy":
 28      try:
 29          jobgroupname = "examples"
 30          jobgroup = getMatrix().getGroup(TYPE_JOB, jobgroupname)
 31          if jobgroup == None:
 32              jobgroup = getMatrix().createGroup(TYPE_JOB, jobgroupname)
 33          jobgroup.addMember(__jobname__)
 34      except:
 35          exc_type, exc_value, exc_traceback = sys.exc_info()
 36          print "Error adding %s to %s group: %s %s" % (__jobname__, jobgroupname, exc_type, exc_value)
 37
 38
 39  class factJunctionJob(Job):
 40
 41      def job_started_event(self):
 42          m = getMatrix()
 43          nptt = "<Not Possible To Test>"
 44
 45          # Setup test environment
 46          user = m.getGridObject(TYPE_USER, "test")
 47          if (user == None):
 48              user = m.createGridObject(TYPE_USER, "test")
 49          user.setArrayFact("user.privilegedjobgroups", ["all"])
 50
 51          repository = m.getGridObject(TYPE_REPOSITORY, "test")
 52          if (repository == None):
 53              repository = m.createGridObject(TYPE_REPOSITORY, "test")
 54          repository.setArrayFact("repository.provisioner.jobs", ["factJunction"])
 55
 56          node = m.getGridObject(TYPE_RESOURCE, "test")
 57          if (node == None):
 58              node = m.createGridObject(TYPE_RESOURCE, "test")
 59
 60          vm = m.getGridObject(TYPE_RESOURCE, "vmtest")
 61          if (vm == None):
 62              vm = m.createResource("vmtest", ResourceInfo.TYPE_VM_INSTANCE)
 63          vm.setFact("resource.provisioner.job", "factJunction")
 64          vm.setFact("resource.vm.repository", "test")
 65          vm.setFact("resource.provisioner.recommendedhost", "test_test")
 66
 67          vmt = m.getGridObject(TYPE_RESOURCE, "vmttest")
 68          if (vmt == None):
 69              vmt = m.createResource("vmttest", ResourceInfo.TYPE_VM_TEMPLATE)
 70          vmt.setFact("resource.provisioner.job", "factJunction")
 71          vmt.setFact("resource.vm.repository", "test")
 72
 73          try:
 74              vmhost = node.getVmHost("test")
 75          except:
 76              vmhost = node.createVmHost("test")
 77          vmhost.setFact("vmhost.provisioner.job", "factJunction")
 78          vmhost.setArrayFact("vmhost.repositories", ["test"])
 79          vmhost.setArrayFact("vmhost.vm.available.groups", ["all"])
 80
 81          job = m.getGridObject(TYPE_JOB, "factJunction")
 82
 83          # Test junctions
 84
 85          print
 86          print "Testing User fact junctions (3):"
 87          r = user.getFact("user.accountinggroup.id")
 88          print "1. user.accountinggroup.id = %s" % r
 89          # Array junctions
 90          r = user.getFact("user.privilegedjobgroups[all].id")
 91          print "2. user.privilegedjobgroups[all].id = %s" % r
 92          r = user.getFact("user.groups[all].jobcount")
 93          print "3. user.groups[all].jobcount = %s" % r
 94
 95
 96          print
 97          print "Testing Job fact junctions (3):"
 98          r = job.getFact("job.accountinggroup.id")
 99          print "1. job.accountinggroup.id = %s" % r
100          r = job.getFact("job.resourcegroup.id")
101          print "2. job.resourcegroup.id = %s" % r
102          # Array junctions
103          r = job.getFact("job.groups[all].jobinstances.total")
104          print "3. job.groups[all].jobinstances.total = %s" % r
105
106
107          print
108          print "Testing VmHost fact junctions (7):"
109          r = vmhost.getFact("vmhost.resource.id")
110          print "1. vmhost.resource.id = %s" % r
111          r = vmhost.getFact("vmhost.accountinggroup.id")
112          print "2. vmhost.accountinggroup.id = %s" % r
113          r = vmhost.getFact("vmhost.provisioner.job.id")
114          print "3. vmhost.provisioner.job.id = %s" % r
115          # Array junctions
116          r = vmhost.getFact("vmhost.groups[all].vmcount")
117          print "4. vmhost.groups[all].vmcount = %s" % r
118          r = vmhost.getFact("vmhost.repositories[test].id")
119          print "5. vmhost.repositories[test].id = %s" % r
120          r = vmhost.getFact("vmhost.vm.available.groups[all].id")
121          print "6. vmhost.vm.available.groups[all].id = %s" % r
122          #r = vmhost.getFact("vmhost.vm.instanceids[vmtest].id")
123          r = nptt
124          print "7. vmhost.vm.instanceids.[vmtest].id = %s" % r
125
126
127          print
128          print "Testing Resource fact junctions (9):"
129          r = vm.getFact("resource.provisioner.job.id")
130          print "1. resource.provisioner.job.id = %s" % r
131          r = vm.getFact("resource.vm.repository.id")
132          print "2. resource.vm.repository.id = %s" % r
133          r = vm.getFact("resource.provisioner.recommendedhost.id")
134          print "3. resource.provisioner.recommendedhost.id = %s" % r
135          #r = vm.getFact("resource.provision.vmhost.id")
136          r = nptt
137          print "4. resource.provision.vmhost.id = %s" % r
138          #r = vm.getFact("resource.provision.template.id")
139          r = nptt
140          print "5. resource.provision.template.id = %s" % r
141          # Array junctions
142          r = vm.getFact("resource.groups[all].loadaverage")
143          print "6. resource.groups[all].loadaverage = %s" % r
144          r = node.getFact("resource.vmhosts[test_test].id")
145          print "7. resource.vmhosts[test_test].id = %s" % r
146          r = node.getFact("resource.repositories[test].id")
147          print "8. resource.repositories[test].id = %s" % r
148          #r = vmt.getFact("resource.provisioner.instances[vmttest_2].id")
149          r = nptt
150          print "9. resource.provisioner.instances[vmtest_2].id = %s" % r
151
152
153          print
154          print "Testing Repository fact junctions (4):"
155          r = repository.getFact("repository.groups[all].id")
156          print "1. repository.groups[all].id = %s" % r
157          r = repository.getFact("repository.vmimages[vmtest].id")
158          print "2. repository.vmimages[vmtest].id = %s" % r
159          r = repository.getFact("repository.vmhosts[test_test].id")
160          print "3. repository.vmhosts[test_test].id = %s" % r
161          r = repository.getFact("repository.provisioner.jobs[factJunction].id")
162          print "4. repository.provisioner.jobs[factJunction].id = %s" % r
163
164
165          print
166          print "Testing multiple junctions (1):"
167          r = repository.getFact("repository.vmhosts[test_test].resource.repositories[test].vmhosts[test_test].groups[all].id")
168          print "1. repository.vmhosts[test_test].resource.repositories[test].vmhosts[test_test].groups[all].id = %s" % r
169
170          # Now make sure they are all accessable by the joblet...
171          #self.schedule(factJunctionJoblet, {})
172
173
174  class factJunctionJoblet(Joblet):
175
176      def joblet_started_event(self):
177          # TODO
178          time.sleep(sleeptime)
179

factJunction.policy

The description fact displays the commands x, y, z ...

 1  <!--
 2   *=============================================================================
 3   * Copyright © 2008 Novell, Inc. All Rights Reserved.
 4   *
 5   * NOVELL PROVIDES THE SOFTWARE "AS IS," WITHOUT ANY EXPRESS OR IMPLIED
 6   * WARRANTY, INCLUDING WITHOUT THE IMPLIED WARRANTIES OF MERCHANTABILITY,
 7   * FITNESS FOR A PARTICULAR PURPOSE, AND NON INFRINGMENT.  NOVELL, THE AUTHORS
 8   * OF THE SOFTWARE, AND THE OWNERS OF COPYRIGHT IN THE SOFTWARE ARE NOT LIABLE
 9   * FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
10   * TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE
11   * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12   *=============================================================================
13   * $Id: factJunction.policy,v 1.2 2008/02/27 20:49:39 john Exp $
14   *=============================================================================
15   -->
16
17  <policy>
18
19    <job>
20      <fact name="description"
21            type="String"
22            value="This is a test job to exercise fact junctions." />
23    </job>
24
25  </policy>
26

Classes and Methods

Definitions:

Job

A representation of a running job instance.

Joblet

Defines execution on the resource.

MatrixInfo

A representation of the matrix grid object, which provides operations for retrieving and creating grid objects in the system. MatrixInfo is retrieved using the built-in getMatrix() function. Write capability is dependent on the context in which getMatrix() is called. For example, in a joblet process on a resource, creating new grid objects is not supported.

GroupInfo

A representation of Group grid objects. Operations include retrieving the group member lists and adding/removing from the group member lists, and retrieving and setting facts on the group.

UserInfo

A representation of a User grid object. This class provides accessors and setters for User facts.

RepositoryInfo

A representation of a Repository grid object. This class provides accessors and setters for Repository facts. To script the creation of Repository objects, see MatrixInfo.

ResourceInfo

A representation of a Resource Grid Object. This class inherits the base fact operations from GridObjectInfo and adds the provisioning operations for provisionable resources such as virtual machines. See MatrixInfo for how to script creation of Resource objects.

JobInfo

A representation of a deployed Job. The factset available on the JobInfo class is the aggregation of the Job's policy and policies on the groups the Job is a member of. This includes the job.* and jobargs.* fact namespaces.

Job Details

The FactJunction job performs its work by handling the following events:

zosadmin deploy

Deploying FactJunction job is performed by lines 10-22 of factJunction.jdl. When jobs are deployed into the grid, they can optionally be placed in groups for organization and easy reference. In this case, the FactJunction job will be added to the group named “examples”, and will show up in the ZENworks Orchestrator Console in the Explorer view at the location:

/ZOS/YOUR_GRID/Jobs/examples

For a general overview of how jobs are added to groups during deployment, see Walkthrough: Deploy a Sample Job in the Novell ZENworks Orchestrator 1.3 Installation and Getting Started Guide.

job_started_event

When the FactJunction job receives a job_started_event, it gets a reference to the MatrixInfo object, which allows it to obtain references to other objects in the grid, such as Users, Resources, Jobs, etc. (see lines 28, 32, 37, 42, 46, and 53 in factJunction.jdl). If these objects don't exist in the grid, they are immediately created so they can be used later on (see lines 34, 39, 44, 48, 55, and 62).

After references exist for the various objects in the grid, values for other objects are printed out using the fact junctions that exist on each object (see lines 69-154 in factJunction.jdl).

There are several instances where the FactJunction job uses “array notation” to handle fact junctions that contain multiple values (see lines 76, 78, 89, 102, 104, 106, 108, 128, 130, 132, 142, 144, 146, and 153 in factJunction.jdl). As previously explained, fact junctions are special facts because their value contains the name of another object that must exist in the grid. However, fact junctions don't always contain a single name. Some fact junctions allow for an array of names to be specified. For example, the value for the fact “job.groups” is supplied as a String array.

In this case, the fact junction can be refined using array notation, which allows for the selection of one of the values. For example, the following code retrieves the ID of the group named “myGroup”, which is one of the groups the given job is a member of:

job.getFact(“job.groups[myGroup].id”)

joblet_started_event

The FactJunction job only illustrates using fact junctions to retrieve information about objects in the grid. Therefore, no work is performed on the resource by the FactJunction joblet.

Configure and Run

To run this example, you must have ZENworks Orchestrator installed and configured properly. No agents on separate resources are required. You also must be logged into your Orchestrator server before you run zosadmin or zos commands.

Execute the following commands to deploy and run factJunction.job:

  1. Deploy factJunction.job into the grid:

    > zosadmin deploy factJunction.job
    
  2. Display the list of deployed jobs:

    > zos joblist
    

    factJunction should appear in this list.

  3. Run the FactJunction job, and view the results:

    > zos run factJunction
    JobID: zenuser.factJunction.421
    > zos log factJunction
    > zos status zenuser.factJunction.421
    Completed
    
    > zos log factJunction
    
  4. Testing User fact junctions:

    1. user.accountinggroup.id = all

    2. user.privilegedjobgroups[all].id = all

    3. user.groups[all].jobcount = 147

  5. Testing Job fact junctions:

    1. job.accountinggroup.id = all

    2. job.resourcegroup.id = all

    3. job.groups[all].jobinstances.total = 1

  6. Testing VmHost fact junctions:

    1. vmhost.resource.id = test

    2. vmhost.accountinggroup.id = all

    3. vmhost.provisioner.job.id = factJunction

    4. vmhost.groups[all].vmcount = 0

    5. vmhost.repositories[test].id = test

    6. vmhost.vm.available.groups[all].id = all

    7. vmhost.vm.instanceids.[vmtest].id = <Not Possible To Test>

  7. Testing Resource fact junctions:

    1. resource.provisioner.job.id = factJunction

    2. resource.vm.repository.id = test

    3. resource.provisioner.recommendedhost.id = test_test

    4. resource.provision.vmhost.id = <Not Possible To Test

    5. resource.provision.template.id = <Not Possible To Test>

    6. resource.groups[all].loadaverage = 0.03666666666666667

    7. resource.vmhosts[test_test].id = test_test

    8. resource.repositories[test].id = test

    9. resource.provisioner.instances[vmtest_2].id = <Not Possible To Test>

  8. Testing Repository fact junctions:

    1. repository.groups[all].id = all

    2. repository.vmimages[vmtest].id = vmtest

    3. repository.vmhosts[test_test].id = test_test

    4. repository.provisioner.jobs[factJunction].id = factJunction

  9. Testing multiple junctions

    1. repository.vmhosts[test_test].resource.repositories[test].vmhosts[test_test].groups[all].id = all

See Also

  • Adding jobs to groups during deployment (see how the JDL code can print the ID of group of jobs in factJunction.job).

  • View the list of fact junctions available for each object type in a ZENworks Orchestrator grid

  • Using array notation to refine multi-valued fact junctions

  • Using ZENworks Orchestrator (How Do I Interact with ZENworks Orchestrator?)