[yocto] [yocto-autobuilder][PATCHv2 3/5] autobuilder/buildsteps: Add DaftGetDevices step
Joshua Lock
joshua.g.lock at linux.intel.com
Mon Jul 3 07:03:18 PDT 2017
On Tue, 2017-06-06 at 10:46 -0500, Aníbal Limón wrote:
> 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>
Typo in the email address here.
> 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 l
> ocalhost"
> 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()
I'm not at all fond of this. It would be easier to follow this code if
this were an explicit method.
> +
> + 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 = []
Please use more verbose variable names for clarity.
> + 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:
Please use more verbose variable names for clarity.
> + 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/20
> 05q1/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
More information about the yocto
mailing list