What's Task/Workflow
- Task is the declarative representation of job
- Workflow is the minimum executable unit in user level, it is the declarative composition of tasks.
- Definition vs. Instance
- RackHD supports customize Task and Workflow.
- Only one active workflow is allowed for a node.
Linkage
Graph Definition
{
"friendlyName": "Install CentOS",
"injectableName": "Graph.InstallCentOS",
"options": {
"defaults": {
"repo": "/centos//os/x86_64",
"version": null
}
},
"tasks": [
{
"ignoreFailure": true,
"label": "set-boot-pxe",
"taskName": "Task.Obm.Node.PxeBoot"
},
{
"label": "reboot",
"taskName": "Task.Obm.Node.Reboot",
"waitOn": {
"set-boot-pxe": "finished"
}
},
{
"label": "install-os",
"taskName": "Task.Os.Install.CentOS",
"waitOn": {
"reboot": "succeeded"
}
}
]
}
Task Definition
// Copyright 2016, EMC, Inc.
'use strict';
module.exports = {
friendlyName: 'Evaluate Condition',
injectableName: 'Task.Evaluate.Condition',
implementsTask: 'Task.Base.Evaluate.Condition',
options: {},
properties: {}
};
Or:
{
"friendlyName": "Catalog lsall",
"implementsTask": "Task.Base.Linux.Catalog",
"injectableName": "Task.Catalog.lsall",
"options": {
"commands": [
"sudo lspci -nn -vmm",
"sudo lshw -json",
"sudo lsblk -o KNAME,TYPE,ROTA; echo BREAK; sudo lsscsi --size"
]
},
"properties": {
"catalog": {
"type": "lsall"
}
}
}
- friendlyName
- injectableName
- implementsTask
- options
- properties
Task Template Options
RackHD designs some template options, so you don't need to hardcode it:
{
"options": {
"defaults": {
"version": "6.5",
"repo": "http:///centos/",
},
"install-os": {
"rootPassword": "123456789",
"hostname": "rackhd-machine",
"dnsServers": [ "192.168.1.3", "10.0.2.1"]
},
"pxe-reboot": {
"obmServiceName": "ipmi-obm-service"
}
}
}
Refer http://rackhd.readthedocs.io/en/latest/rackhd/index.html#task-templates for details.
BaseTask Definition
'use strict';
module.exports = {
friendlyName: 'Evaluate Condition',
injectableName: 'Task.Base.Evaluate.Condition',
runJob: 'Job.Evaluate.Condition',
optionsSchema: {
properties: {
when: {
description: 'The condition value that to be evaluated. Only string "true" means condition meets',
type: 'string'
}
},
required: ['when']
},
requiredProperties: {},
properties: {}
};
or:
{
"friendlyName": "Evaluate Condition",
"injectableName": "Task.Base.Evaluate.Condition",
"runJob": "Job.Evaluate.Condition",
"optionsSchema": {
"properties": {
"when": {
"description": "The condition value that to be evaluated. Only string \"true\" means condition meets",
"type": "string"
}
},
"required": [
"when"
]
},
"requiredProperties": {},
"properties": {}
}
Job
- Job example:
// Copyright 2016, EMC, Inc.
'use strict';
module.exports = conditionJobFactory;
var di = require('di');
di.annotate(conditionJobFactory, new di.Provide('Job.Evaluate.Condition'));
di.annotate(conditionJobFactory, new di.Inject(
'Job.Base',
'Util',
'Logger',
'Assert'
)
);
function conditionJobFactory(
BaseJob,
util,
Logger,
assert
) {
var logger = Logger.initialize(conditionJobFactory);
function ConditionJob(options, context, taskId) {
ConditionJob.super_.call(this, logger, options, context, taskId);
assert.string(options.when);
}
util.inherits(ConditionJob, BaseJob);
/**
* @memberOf ConditionJob
*/
ConditionJob.prototype._run = function run() {
var when = this.options.when.toLowerCase();
if( when === 'true' ) {
return this._done();
}
this._done(new Error('condition evaluated to false'));
};
return ConditionJob;
}
- Base Job
- Job utils
- Pub/Sub API to talk with node
Task example:
// Copyright 2016, EMC, Inc.
'use strict';
module.exports = {
friendlyName: 'Evaluate Condition',
injectableName: 'Task.Evaluate.Condition',
implementsTask: 'Task.Base.Evaluate.Condition',
options: {},
properties: {}
};
Options Schema
- A schema to describe the
options
fromat for the task or job - Job Schema / Task-Specific Schema / Common Schema
- Upfront input validation
- Generate document for task
- Refer to http://rackhd.readthedocs.io/en/latest/rackhd/tasks.html#options-schema
Task Documentation
Exercise
(1) In mathematics, the Fibonacci numbers are the numbers in the following integer sequence, called the Fibonacci sequence, and characterized by the fact that every number after the first two is the sum of the two preceding ones:
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...
Please write a RackHD job to calculate the Fibonacci number for given seqIndex
and store the result into context.fibonacciResult
:
- If
seqIndex=1
,context.fibonacciResult=1;
IfseqIndex=2
,context.fibonacciResult=1;
IfseqIndex=3
,context.fibonacciResult=2; ...
- If
seqIndex<=0
orseqIndex > 50
, The job should fail withRangeError.
- If
seqIndex
is not a number or not specified, The job should fail withTypeError
. - If
seqIndex
is folat number, then use its integer parts. For example,seqIndex=5.2
will get same result withseqIndex=5
- The unit-test file has been provided, you should ensure your job pass the unit-test.
- You should create the BaseTask and Task defintion for the fibonacci job.
- Please construct a graph definition using the new fibonacci job, and make sure you job is executed after trigger the new workflow.