[yocto] [yocto-autobuilder][PATCHv2 3/5] autobuilder/buildsteps: Add DaftGetDevices step
Aníbal Limón
anibal.limon at linux.intel.com
Tue Jun 6 08:46:49 PDT 2017
This buildstep will copy the devices configuration from the
worker and read it, in order to get daft ip an ssh port, to
use later in RunSanityTests
[YOCTO #10604]
Signed-off-by: Aníbal Limón <anibal.limon at linux.intel.com>
Signed-off-by: Monserrat Sedeno <monserratx.sedeno.bustos.intel.com>
Signed-off-by: Edwin Plauchu <edwin.plauchu.camacho at linux.intel.com>
---
config/autobuilder.conf.example | 3 +
.../autobuilder/buildsteps/DaftGetDevices.py | 44 ++++++++
lib/python2.7/site-packages/autobuilder/config.py | 1 +
.../site-packages/autobuilder/lib/daft.py | 115 +++++++++++++++++++++
4 files changed, 163 insertions(+)
create mode 100644 lib/python2.7/site-packages/autobuilder/buildsteps/DaftGetDevices.py
create mode 100644 lib/python2.7/site-packages/autobuilder/lib/daft.py
diff --git a/config/autobuilder.conf.example b/config/autobuilder.conf.example
index 2ee11e6..e5ec16b 100644
--- a/config/autobuilder.conf.example
+++ b/config/autobuilder.conf.example
@@ -95,3 +95,6 @@ PERFORMANCE_MAIL_TO = "root at localhost otherperson at localhost"
PERFORMANCE_MAIL_CC = "buildcc at localhost"
PERFORMANCE_MAIL_BCC = "buildbcc at localhost"
PERFORMANCE_MAIL_SIG = "Multiline\nSig\nLine"
+
+[Daft]
+DAFT_WORKER_DEVICES_CFG = "/etc/daft/devices.cfg"
diff --git a/lib/python2.7/site-packages/autobuilder/buildsteps/DaftGetDevices.py b/lib/python2.7/site-packages/autobuilder/buildsteps/DaftGetDevices.py
new file mode 100644
index 0000000..133a4d6
--- /dev/null
+++ b/lib/python2.7/site-packages/autobuilder/buildsteps/DaftGetDevices.py
@@ -0,0 +1,44 @@
+import os
+from buildbot.steps.transfer import FileUpload
+from buildbot.process.buildstep import BuildStep
+
+from lib.daft import DeployScanner
+from autobuilder.config import DAFT_WORKER_DEVICES_CFG
+
+class DaftGetDevices(FileUpload):
+ haltOnFailure = True
+
+ name = "DaftGetDevices"
+
+ def __init__(self, factory, argdict=None, **kwargs):
+ self.tests = None
+ self.factory = factory
+ for k, v in argdict.iteritems():
+ setattr(self, k, v)
+ self.description = "Getting devices configuration"
+ self.timeout = 100000
+ kwargs['timeout']=self.timeout
+
+ super(DaftGetDevices, self).__init__(DAFT_WORKER_DEVICES_CFG,
+ os.path.join('/tmp', 'devices.cfg'))
+
+ def finished(self, result):
+ if self.cmd:
+ ds = DeployScanner(devsconf_file = self.masterdest)
+ devices = ds()
+
+ found = False
+ dut_label = self.getProperty('custom_dut')
+ for d in devices:
+ if d['dut_label'] == dut_label:
+ self.setProperty('dut_name', d['dut_label'], 'DaftGetDevices')
+ self.setProperty('server_ip', d['server_address'], 'DaftGetDevices')
+ target_ip = "%s:%s" % (d['ctrl_address'], d['dut_sshport'])
+ self.setProperty('target_ip', target_ip, 'DaftGetDevices')
+
+ found = True
+
+ if not found:
+ return BuildStep.finished(self, FAILURE)
+
+ return super(DaftGetDevices, self).finished(result)
diff --git a/lib/python2.7/site-packages/autobuilder/config.py b/lib/python2.7/site-packages/autobuilder/config.py
index 9d945b1..5bcf6c6 100644
--- a/lib/python2.7/site-packages/autobuilder/config.py
+++ b/lib/python2.7/site-packages/autobuilder/config.py
@@ -23,3 +23,4 @@ RPM_PUBLISH_DIR = os.environ.get("RPM_PUBLISH_DIR")
IPK_PUBLISH_DIR = os.environ.get("IPK_PUBLISH_DIR")
DEB_PUBLISH_DIR = os.environ.get("DEB_PUBLISH_DIR")
PERFORMANCE_PUBLISH_DIR = os.environ.get("PERFORMANCE_PUBLISH_DIR")
+DAFT_WORKER_DEVICES_CFG = os.environ.get("DAFT_WORKER_DEVICES_CFG")
diff --git a/lib/python2.7/site-packages/autobuilder/lib/daft.py b/lib/python2.7/site-packages/autobuilder/lib/daft.py
new file mode 100644
index 0000000..eef4bab
--- /dev/null
+++ b/lib/python2.7/site-packages/autobuilder/lib/daft.py
@@ -0,0 +1,115 @@
+import os
+import ConfigParser as configparser
+
+class DeployScanner(object):
+ '''
+ In charge of scanning deployed daft bbb devices
+ '''
+
+ __MAGIC_SERVER_ADDRESS = '192.168.30.1' # DAFT uses this address for this internal network
+ __MAGIC_SSH_PORT = 2233 # it is hardcoded as per DAFT implementation manual
+
+ def __init__(self, *args, **kwargs):
+ self.devsconf_fp = kwargs.get('devsconf_file', None)
+ if not self.devsconf_fp:
+ raise Exception('not fed devsconf file')
+ self.ign_leases = kwargs.get('ign_leases', True)
+ if not self.ign_leases:
+ self.leases_file_path = kwargs.get('leases_file', None)
+ if not self.leases_file_path:
+ raise Exception('not fed leases file')
+
+ def __call__(self):
+ '''
+ Creates relation of deployed devices
+ Returns:
+ List of dictionaries containing info about devices deployed.
+ '''
+ def create_relation(i,j):
+ r = []
+ for conf in i:
+ for active in j:
+ if conf['bb_ip'] == active['ip']:
+ r.append({
+ 'dut_label': conf['device'].lower(),
+ 'dut_family': conf['device_type'].lower(),
+ 'dut_sshport': str(self.__MAGIC_SSH_PORT),
+ 'ctrl_address': conf['bb_ip'],
+ 'server_address': self.__MAGIC_SERVER_ADDRESS
+ })
+ return r
+
+ def slack_relation(i):
+ r = []
+ for conf in i:
+ r.append({
+ 'dut_label': conf['device'],
+ 'dut_family': conf['device_type'],
+ 'dut_sshport': str(self.__MAGIC_SSH_PORT),
+ 'ctrl_address': conf['bb_ip'],
+ 'server_address': self.__MAGIC_SERVER_ADDRESS
+ })
+ return r
+
+ fc = self.__fetch_confs()
+ if not fc:
+ raise Exception('There are no configurations as per BBB devices')
+
+ if self.ign_leases:
+ # Devices that nobody knows if were deployed
+ return slack_relation(fc)
+
+ als = self.__active_leases()
+ if not als:
+ raise Exception('DHCP server has not registered any host yet')
+
+ return create_relation(fc, als)
+
+ def __fetch_confs(self):
+ '''
+ Read and parse BBB configuration file and return result as dictionary
+ '''
+ config = configparser.SafeConfigParser()
+ config.read(self.devsconf_fp)
+ configurations = []
+ for device in config.sections():
+ device_config = dict(config.items(device))
+ device_config["device"] = device
+ device_config["device_type"] = device.rstrip('1234567890_')
+ configurations.append(device_config)
+ return configurations
+
+ def __active_leases(self):
+ """
+ Read the active leases from dnsmasq leases file and return a list of
+ active leases as dictionaries.
+ Args:
+ file_name (str): Path to leases file, e.g. /path/to/file/dnsmasq.leases
+ Returns:
+ List of dictionaries containing the active leases.
+ The dictionaries have the following format:
+ {
+ "mac": "device_mac_address",
+ "ip": "device_ip_address",
+ "hostname": "device_host_name",
+ "client_id": "client_id_or_*_if_unset"
+ }
+ """
+ with open(self.leases_file_path) as lease_file:
+ leases = lease_file.readlines()
+
+ leases_list = []
+
+ # dnsmasq.leases contains rows with the following format:
+ # <lease_expiry_time_as_epoch_format> <mac> <ip> <hostname> <domain>
+ # See:
+ #http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2005q1/000143.html
+ for lease in leases:
+ lease = lease.split()
+ leases_list.append({
+ "mac": lease[1],
+ "ip": lease[2],
+ "hostname": lease[3],
+ "client_id": lease[4],
+ })
+ return leases_list
--
2.1.4
More information about the yocto
mailing list