<commit_before># Copyright (c) 2012, Calxeda Inc.
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Calxeda Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.

from pkg_resources import parse_version

from cxmanage import get_tftp, get_nodes, get_node_strings, run_command, \
        prompt_yes

from cxmanage_api.image import Image
from cxmanage_api.firmware_package import FirmwarePackage


def fwupdate_command(args):
    """update firmware on a cluster or host"""
    def do_update():
        """ Do a single firmware check+update. Returns True on failure. """
        if not args.force:
            if not args.quiet:
                print "Checking hosts..."

            results, errors = run_command(args, nodes, "_check_firmware",
                    package, args.partition, args.priority)

            if errors:
                print "ERROR: Firmware update aborted."
                return True

        if not args.quiet:
            print "Updating firmware..."

        results, errors = run_command(args, nodes, "update_firmware", package,
                args.partition, args.priority)

        return bool(errors)

    def do_reset():
        """ Reset and wait. Returns True on failure. """
        if not args.quiet:
            print "Checking ECME versions..."

        results, errors = run_command(args, nodes, "get_versions")

        for result in results.values():
            version = result.ecme_version.lstrip("v")
            if parse_version(version) < parse_version("1.2.0"):
                print "ERROR: MC reset is unsafe on ECME version v%s" % version
                print "Please power cycle the system and start a new fwupdate."
                return True
            
        if not args.quiet:
            print "Resetting nodes..."

        results, errors = run_command(args, nodes, "mc_reset", True)

        if errors:
            print "ERROR: MC reset failed. Backup partitions not updated."
            return True

        return False

    # Get firmware package
    if args.image_type == "PACKAGE":
        package = FirmwarePackage(args.filename)
    else:
        try:
            simg = None
            if args.force_simg:
                simg = False
            elif args.skip_simg:
                simg = True

            image = Image(args.filename, args.image_type, simg, args.daddr,
                    args.skip_crc32, args.fw_version)
            package = FirmwarePackage()
            package.images.append(image)
        except ValueError as e:
            print "ERROR: %s" % e
            return True

    # Print all_nodes warning/confirmation
    if not args.all_nodes:
        if args.force:
            print 'WARNING: Updating firmware without --all-nodes is dangerous.'
        else:
            if not prompt_yes(
                    'WARNING: Updating firmware without --all-nodes is dangerous. Continue?'):
                return 1

    tftp = get_tftp(args)
    nodes = get_nodes(args, tftp, verify_prompt=True)

    failure = do_update()

    if args.full:
        failure = do_reset()
        if failure:
            return True
        failure = do_update()

    if not args.quiet and not failure:
        print "Command completed successfully.\n"

    return failure


def fwinfo_command(args):
    """print firmware info"""
    tftp = get_tftp(args)
    nodes = get_nodes(args, tftp)

    if not args.quiet:
        print "Getting firmware info..."

    results, errors = run_command(args, nodes, "get_firmware_info")<commit_msg>CXMAN-202: Abort fwupdate --full if any step fails along the way<commit_after># Copyright (c) 2012, Calxeda Inc.
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Calxeda Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.

from pkg_resources import parse_version

from cxmanage import get_tftp, get_nodes, get_node_strings, run_command, \
        prompt_yes

from cxmanage_api.image import Image
from cxmanage_api.firmware_package import FirmwarePackage


def fwupdate_command(args):
    """update firmware on a cluster or host"""
    def do_update():
        """ Do a single firmware check+update. Returns True on failure. """
        if not args.force:
            if not args.quiet:
                print "Checking hosts..."

            results, errors = run_command(args, nodes, "_check_firmware",
                    package, args.partition, args.priority)
            if errors:
                print "ERROR: Firmware update aborted."
                return True

        if not args.quiet:
            print "Updating firmware..."

        results, errors = run_command(args, nodes, "update_firmware", package,
                args.partition, args.priority)
        if errors:
            print "ERROR: Firmware update failed."
            return True

        return False

    def do_reset():
        """ Reset and wait. Returns True on failure. """
        if not args.quiet:
            print "Checking ECME versions..."

        results, errors = run_command(args, nodes, "get_versions")
        if errors:
            print "ERROR: MC reset aborted. Backup partitions not updated."
            return True

        for result in results.values():
            version = result.ecme_version.lstrip("v")
            if parse_version(version) < parse_version("1.2.0"):
                print "ERROR: MC reset is unsafe on ECME version v%s" % version
                print "Please power cycle the system and start a new fwupdate."
                return True
            
        if not args.quiet:
            print "Resetting nodes..."

        results, errors = run_command(args, nodes, "mc_reset", True)
        if errors:
            print "ERROR: MC reset failed. Backup partitions not updated."
            return True

        return False

    if args.image_type == "PACKAGE":
        package = FirmwarePackage(args.filename)
    else:
        try:
            simg = None
            if args.force_simg:
                simg = False
            elif args.skip_simg:
                simg = True

            image = Image(args.filename, args.image_type, simg, args.daddr,
                    args.skip_crc32, args.fw_version)
            package = FirmwarePackage()
            package.images.append(image)
        except ValueError as e:
            print "ERROR: %s" % e
            return True

    if not args.all_nodes:
        if args.force:
            print 'WARNING: Updating firmware without --all-nodes is dangerous.'
        else:
            if not prompt_yes(
                    'WARNING: Updating firmware without --all-nodes is dangerous. Continue?'):
                return 1

    tftp = get_tftp(args)
    nodes = get_nodes(args, tftp, verify_prompt=True)

    errors = do_update()

    if args.full and not errors:
        errors = do_reset()
        if not errors:
            errors = do_update()

    if not args.quiet and not errors:
        print "Command completed successfully.\n"

    return errors


def fwinfo_command(args):
    """print firmware info"""
    tftp = get_tftp(args)
    nodes = get_nodes(args, tftp)

    if not args.quiet:
        print "Getting firmware info..."

    results, errors = run_command(args, nodes, "get_firmware_info")
{'fraction_non_alphanumeric': 0.07297514033680834, 'fraction_numerical': 0.002305533279871692, 'mean_word_length': 2.412106703146375, 'pattern_counts': {'":': 2, '<': 5, '<?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': '4476189', 'n_tokens_mistral': 2739, 'n_tokens_neox': 2482, 'n_words': 1039}