Demonstrates using fact junctions to retrieve information about objects in the grid relative to another object.
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.
> 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.
The files that make up the factJunction job include:
factJunction # Total: 205 lines |-- factJunction.jdl # 179 lines `-- factJunction.policy # 26 lines
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
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
A representation of a running job instance.
Defines execution on the resource.
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.
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.
A representation of a User grid object. This class provides accessors and setters for User facts.
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.
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.
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.
The FactJunction job performs its work by handling the following events:
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.
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”)
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.
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:
Deploy factJunction.job into the grid:
> zosadmin deploy factJunction.job
Display the list of deployed jobs:
> zos joblist
factJunction should appear in this list.
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
Testing User fact junctions:
user.accountinggroup.id = all
user.privilegedjobgroups[all].id = all
user.groups[all].jobcount = 147
Testing Job fact junctions:
job.accountinggroup.id = all
job.resourcegroup.id = all
job.groups[all].jobinstances.total = 1
Testing VmHost fact junctions:
vmhost.resource.id = test
vmhost.accountinggroup.id = all
vmhost.provisioner.job.id = factJunction
vmhost.groups[all].vmcount = 0
vmhost.repositories[test].id = test
vmhost.vm.available.groups[all].id = all
vmhost.vm.instanceids.[vmtest].id = <Not Possible To Test>
Testing Resource fact junctions:
resource.provisioner.job.id = factJunction
resource.vm.repository.id = test
resource.provisioner.recommendedhost.id = test_test
resource.provision.vmhost.id = <Not Possible To Test
resource.provision.template.id = <Not Possible To Test>
resource.groups[all].loadaverage = 0.03666666666666667
resource.vmhosts[test_test].id = test_test
resource.repositories[test].id = test
resource.provisioner.instances[vmtest_2].id = <Not Possible To Test>
Testing Repository fact junctions:
repository.groups[all].id = all
repository.vmimages[vmtest].id = vmtest
repository.vmhosts[test_test].id = test_test
repository.provisioner.jobs[factJunction].id = factJunction
Testing multiple junctions
repository.vmhosts[test_test].resource.repositories[test].vmhosts[test_test].groups[all].id = all
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?
)