[yocto] [yocto-autobuilder][PATCHv2 3/5] autobuilder/buildsteps: Add DaftGetDevices step
Aníbal Limón
anibal.limon at linux.intel.com
Mon Jul 3 09:34:14 PDT 2017
On 07/03/2017 09:03 AM, Joshua Lock wrote:
> 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.
This code was original created by Edwin, i will change the code to add
better clarity.
>
>> +
>> + 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.
Agree,
>
>> + 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.
Agree,
Anibal
>
>> + 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