<commit_before>#Copyright 2012 Calxeda, Inc.  All rights reserved.

""" Target objects used by the cx_manage_util controller """

import socket, time

from pyipmi import make_bmc, IpmiError
from pyipmi.bmc import LanBMC

class Target:
    """ Contains info for a single target. A target consists of a hostname,
    an username, and a password. """

    def __init__(self, address, username, password):
        self.address = address
        self.username = username
        self.password = password
        self.bmc = make_bmc(LanBMC, hostname=address,
                username=username, password=password)

    def get_fabric_ipinfo(self, tftp, filename):
        """ Send an IPMI get_fabric_ipinfo command to this target

        Note that this method puts the ip_info file on the TFTP server
        but does not retrieve it locally. """
        tftp_address = self._get_tftp_address(tftp)
        self.bmc.get_fabric_ipinfo(filename, tftp_address)

    def power_command(self, command):
        """ Send an IPMI power command to this target """
        try:
            self.bmc.handle.chassis_control(mode=command)
        except IpmiError:
            raise ValueError("Failed to send power command")

    def power_status(self):
        """ Return power status reported by IPMI """
        try:
            if self.bmc.handle.chassis_status().power_on:
                return "on"
            else:
                return "off"
        except IpmiError:
            raise ValueError("Failed to retrieve power status")

    def update_firmware(self, work_dir, tftp, images, slot_arg):
        """ Update firmware on this target. """
        # Get all updates
        plan = self._get_update_plan(images, slot_arg)
        for image, slot, new_version in plan:
            self._update_image(work_dir, tftp, image, slot, new_version)

    def mc_reset(self):
        """ Send an IPMI MC reset command to the target """
        try:
            self.bmc.mc_reset("cold")
        except IpmiError:
            raise ValueError("Failed to send MC reset command")

    def _get_tftp_address(self, tftp):
        """ Get the TFTP server address
        Returns a string in ip:port format """
        # Get address
        if tftp.is_internal() and tftp.get_address() == None:
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            s.connect((self.address, 0))
            address = s.getsockname()[0]
            s.close()
        else:
            address = tftp.get_address()

        # Get port
        port = tftp.get_port()

        # Return in address:port form
        return "%s:%i" % (address, port)

    def _get_update_plan(self, images, slot_arg):
        """ Get an update plan.
        
        A plan consists of a list of tuples:
        (image, slot, version) """
        plan = []

        # Get all slots
        slots = self.bmc.get_firmware_info()[:-1]
        if not slots:
            raise ValueError("Failed to retrieve firmware info")

        soc_plan_made = False
        cdb_plan_made = False
        for image in images:        
            if image.type == "SPIF":
                # Add all slots
                for slot in slots:
                    plan.append((image, slot, 0))
            elif soc_plan_made and image.type == "CDB":
                for update in plan:
                    if update[0].type == "SOC_ELF":
                        slot = slots[int(update[1].slot) + 1]
                        plan.append((image, slot, update[2]))
            elif cdb_plan_made and image.type == "SOC_ELF":
                for update in plan:
                    if update[0].type == "CDB":
                        slot = slots[int(update[1].slot) - 1]
                        plan.append((image, slot, update[2]))
            else:
                # Filter slots for this type
                type_slots = [x for x in slots if
                        x.type.split()[1][1:-1] == image.type][:2]<commit_msg>cxmanage: Get fwinfo more carefully<commit_after>#Copyright 2012 Calxeda, Inc.  All rights reserved.

""" Target objects used by the cx_manage_util controller """

import socket, time

from pyipmi import make_bmc, IpmiError
from pyipmi.bmc import LanBMC

class Target:
    """ Contains info for a single target. A target consists of a hostname,
    an username, and a password. """

    def __init__(self, address, username, password):
        self.address = address
        self.username = username
        self.password = password
        self.bmc = make_bmc(LanBMC, hostname=address,
                username=username, password=password)

    def get_fabric_ipinfo(self, tftp, filename):
        """ Send an IPMI get_fabric_ipinfo command to this target

        Note that this method puts the ip_info file on the TFTP server
        but does not retrieve it locally. """
        tftp_address = self._get_tftp_address(tftp)
        self.bmc.get_fabric_ipinfo(filename, tftp_address)

    def power_command(self, command):
        """ Send an IPMI power command to this target """
        try:
            self.bmc.handle.chassis_control(mode=command)
        except IpmiError:
            raise ValueError("Failed to send power command")

    def power_status(self):
        """ Return power status reported by IPMI """
        try:
            if self.bmc.handle.chassis_status().power_on:
                return "on"
            else:
                return "off"
        except IpmiError:
            raise ValueError("Failed to retrieve power status")

    def update_firmware(self, work_dir, tftp, images, slot_arg):
        """ Update firmware on this target. """
        # Get all updates
        plan = self._get_update_plan(images, slot_arg)
        for image, slot, new_version in plan:
            self._update_image(work_dir, tftp, image, slot, new_version)

    def mc_reset(self):
        """ Send an IPMI MC reset command to the target """
        try:
            self.bmc.mc_reset("cold")
        except IpmiError:
            raise ValueError("Failed to send MC reset command")

    def _get_tftp_address(self, tftp):
        """ Get the TFTP server address
        Returns a string in ip:port format """
        # Get address
        if tftp.is_internal() and tftp.get_address() == None:
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            s.connect((self.address, 0))
            address = s.getsockname()[0]
            s.close()
        else:
            address = tftp.get_address()

        # Get port
        port = tftp.get_port()

        # Return in address:port form
        return "%s:%i" % (address, port)

    def _get_update_plan(self, images, slot_arg):
        """ Get an update plan.
        
        A plan consists of a list of tuples:
        (image, slot, version) """
        plan = []

        # Get all slots
        slots = [x for x in self.bmc.get_firmware_info() if hasattr(x, "slot")]
        if not slots:
            raise ValueError("Failed to retrieve firmware info")

        soc_plan_made = False
        cdb_plan_made = False
        for image in images:        
            if image.type == "SPIF":
                # Add all slots
                for slot in slots:
                    plan.append((image, slot, 0))
            elif soc_plan_made and image.type == "CDB":
                for update in plan:
                    if update[0].type == "SOC_ELF":
                        slot = slots[int(update[1].slot) + 1]
                        plan.append((image, slot, update[2]))
            elif cdb_plan_made and image.type == "SOC_ELF":
                for update in plan:
                    if update[0].type == "CDB":
                        slot = slots[int(update[1].slot) - 1]
                        plan.append((image, slot, update[2]))
            else:
                # Filter slots for this type
                type_slots = [x for x in slots if
                        x.type.split()[1][1:-1] == image.type][:2]
{'fraction_non_alphanumeric': 0.09453360080240722, 'fraction_numerical': 0.0048896690070210636, 'mean_word_length': 1.8581153708348261, 'pattern_counts': {'":': 10, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6056007', 'n_tokens_mistral': 2323, 'n_tokens_neox': 2203, 'n_words': 690}