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 vmmanager Please enter current password for 'vmmanager': Logged into grid as vmmanager > 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: 174 lines |-- factJunction.jdl # 165 lines `-- factJunction.policy # 9 lines
1 # 2 # This is a test job, but also illustrates all the implemented fact junctions. 3 # A fact junction is a way to access facts on a 'referenced' object. 4 # E.g. vmhost.resource.*** redirects from the vmhost object through the 5 # juction onto the underlying physical resource object. 6 # 7 # To setup for test, copy job into the 'provisionAdapter' job group. 8 # 9 10 # 11 # Add to the 'examples' group on deployment 12 # 13 if __mode__ == "deploy": 14 try: 15 jobgroupname = "examples" 16 jobgroup = getMatrix().getGroup(TYPE_JOB, jobgroupname) 17 if jobgroup == None: 18 jobgroup = getMatrix().createGroup(TYPE_JOB, jobgroupname) 19 jobgroup.addMember(__jobname__) 20 except: 21 exc_type, exc_value, exc_traceback = sys.exc_info() 22 print "Error adding %s to %s group: %s %s" % (__jobname__, jobgroupname, exc_type, exc_value) 23 24 25 class factJunctionJob(Job): 26 27 def job_started_event(self): 28 m = getMatrix() 29 nptt = "<Not Possible To Test>" 30 31 # Setup test environment 32 user = m.getGridObject(TYPE_USER, "test") 33 if (user == None): 34 user = m.createGridObject(TYPE_USER, "test") 35 user.setArrayFact("user.privilegedjobgroups", ["all"]) 36 37 repository = m.getGridObject(TYPE_REPOSITORY, "test") 38 if (repository == None): 39 repository = m.createGridObject(TYPE_REPOSITORY, "test") 40 repository.setArrayFact("repository.provisioner.jobs", ["factJunction"]) 41 42 node = m.getGridObject(TYPE_RESOURCE, "test") 43 if (node == None): 44 node = m.createGridObject(TYPE_RESOURCE, "test") 45 46 vm = m.getGridObject(TYPE_RESOURCE, "vmtest") 47 if (vm == None): 48 vm = m.createResource("vmtest", ResourceInfo.TYPE_VM_INSTANCE) 49 vm.setFact("resource.provisioner.job", "factJunction") 50 vm.setFact("resource.vm.repository", "test") 51 vm.setFact("resource.provisioner.recommendedhost", "test_test") 52 53 vmt = m.getGridObject(TYPE_RESOURCE, "vmttest") 54 if (vmt == None): 55 vmt = m.createResource("vmttest", ResourceInfo.TYPE_VM_TEMPLATE) 56 vmt.setFact("resource.provisioner.job", "factJunction") 57 vmt.setFact("resource.vm.repository", "test") 58 59 try: 60 vmhost = node.getVmHost("test") 61 except: 62 vmhost = node.createVmHost("test") 63 vmhost.setFact("vmhost.provisioner.job", "factJunction") 64 vmhost.setArrayFact("vmhost.repositories", ["test"]) 65 vmhost.setArrayFact("vmhost.vm.available.groups", ["all"]) 66 67 job = m.getGridObject(TYPE_JOB, "factJunction") 68 69 # Test junctions 70 71 print 72 print "Testing User fact junctions (3):" 73 r = user.getFact("user.accountinggroup.id") 74 print "1. user.accountinggroup.id = %s" % r 75 # Array junctions 76 r = user.getFact("user.privilegedjobgroups[all].id") 77 print "2. user.privilegedjobgroups[all].id = %s" % r 78 r = user.getFact("user.groups[all].jobcount") 79 print "3. user.groups[all].jobcount = %s" % r 80 81 82 print 83 print "Testing Job fact junctions (3):" 84 r = job.getFact("job.accountinggroup.id") 85 print "1. job.accountinggroup.id = %s" % r 86 r = job.getFact("job.resourcegroup.id") 87 print "2. job.resourcegroup.id = %s" % r 88 # Array junctions 89 r = job.getFact("job.groups[all].jobinstances.total") 90 print "3. job.groups[all].jobinstances.total = %s" % r 91 92 93 print 94 print "Testing VmHost fact junctions (7):" 95 r = vmhost.getFact("vmhost.resource.id") 96 print "1. vmhost.resource.id = %s" % r 97 r = vmhost.getFact("vmhost.accountinggroup.id") 98 print "2. vmhost.accountinggroup.id = %s" % r 99 r = vmhost.getFact("vmhost.provisioner.job.id") 100 print "3. vmhost.provisioner.job.id = %s" % r 101 # Array junctions 102 r = vmhost.getFact("vmhost.groups[all].vmcount") 103 print "4. vmhost.groups[all].vmcount = %s" % r 104 r = vmhost.getFact("vmhost.repositories[test].id") 105 print "5. vmhost.repositories[test].id = %s" % r 106 r = vmhost.getFact("vmhost.vm.available.groups[all].id") 107 print "6. vmhost.vm.available.groups[all].id = %s" % r 108 #r = vmhost.getFact("vmhost.vm.instanceids[vmtest].id") 109 r = nptt 110 print "7. vmhost.vm.instanceids.[vmtest].id = %s" % r 111 112 113 print 114 print "Testing Resource fact junctions (9):" 115 r = vm.getFact("resource.provisioner.job.id") 116 print "1. resource.provisioner.job.id = %s" % r 117 r = vm.getFact("resource.vm.repository.id") 118 print "2. resource.vm.repository.id = %s" % r 119 r = vm.getFact("resource.provisioner.recommendedhost.id") 120 print "3. resource.provisioner.recommendedhost.id = %s" % r 121 #r = vm.getFact("resource.provision.vmhost.id") 122 r = nptt 123 print "4. resource.provision.vmhost.id = %s" % r 124 #r = vm.getFact("resource.provision.template.id") 125 r = nptt 126 print "5. resource.provision.template.id = %s" % r 127 # Array junctions 128 r = vm.getFact("resource.groups[all].loadaverage") 129 print "6. resource.groups[all].loadaverage = %s" % r 130 r = node.getFact("resource.vmhosts[test_test].id") 131 print "7. resource.vmhosts[test_test].id = %s" % r 132 r = node.getFact("resource.repositories[test].id") 133 print "8. resource.repositories[test].id = %s" % r 134 #r = vmt.getFact("resource.provisioner.instances[vmttest_2].id") 135 r = nptt 136 print "9. resource.provisioner.instances[vmtest_2].id = %s" % r 137 138 139 print 140 print "Testing Repository fact junctions (4):" 141 r = repository.getFact("repository.groups[all].id") 142 print "1. repository.groups[all].id = %s" % r 143 r = repository.getFact("repository.vmimages[vmtest].id") 144 print "2. repository.vmimages[vmtest].id = %s" % r 145 r = repository.getFact("repository.vmhosts[test_test].id") 146 print "3. repository.vmhosts[test_test].id = %s" % r 147 r = repository.getFact("repository.provisioner.jobs[factJunction].id") 148 print "4. repository.provisioner.jobs[factJunction].id = %s" % r 149 150 151 print 152 print "Testing multiple junctions (1):" 153 r = repository.getFact("repository.vmhosts[test_test].resource.repositories[test].vmhosts[test_test].groups[all].id") 154 print "1. repository.vmhosts[test_test].resource.repositories[test].vmhosts[test_test].groups[all].id = %s" % r 155 156 # Now make sure they are all accessable by the joblet... 157 #self.schedule(factJunctionJoblet, {}) 158 159 class factJunctionJoblet(Joblet): 160 161 def joblet_started_event(self): 162 # TODO 163 time.sleep(sleeptime)
The description fact displays the commands x, y, z ...
1 <policy> 2 <job> 3 <fact name="description" 4 type="String" 5 value="This is a test job to exercise fact junctions." /> 6 </job> 7 </policy>
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 panel at the location:
/ZOS/YOUR_GRID/Jobs/examples
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: vmmanager.factJunction.421 > zos log factJunction > zos status vmmanager.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 ZENworkd Orchestrator (How Do I Interact with ZENworks Orchestrator?
)