Example #1
0
    def execute(self):
        """
        Executes the task.
        """
        from data.models import Machine, SerialConsole

        if not ServerConfig.objects.bool_by_key(
                'orthos.debug.serialconsole.write'):
            logger.warning(
                "Disabled: set 'orthos.debug.serialconsole.write' to 'true'")
            return

        try:
            cscreen_server = Machine.objects.get(fqdn=self.fqdn)
        except Machine.DoesNotExist:
            logger.warning("Serial console server does not exist: {}".format(
                self.fqdn))

        conn = None
        try:
            conn = SSH(cscreen_server.fqdn)
            conn.connect()

            stdout, stderr, exitstatus = conn.execute(
                'sudo touch /etc/cscreenrc_allow_update')

            if exitstatus != 0:
                raise Exception(
                    "Couldn't lock cscreen ('touch /etc/cscreenrc_allow_update')"
                )

            new_content = ''
            for serialconsole in SerialConsole.cscreen.get(cscreen_server):
                new_content += serialconsole.get_comment_record() + '\n'
                new_content += serialconsole.get_command_record() + '\n'

            screenrc_file = '/etc/cscreenrc'

            # create `/etc/cscreenrc` if it doesn't exist
            stdout, stderr, exitstatus = conn.execute(
                '[ -e "{}"]'.format(screenrc_file))

            orthos_inline_begin = ServerConfig.objects.by_key(
                'orthos.configuration.inline.begin')
            orthos_inline_end = ServerConfig.objects.by_key(
                'orthos.configuration.inline.end')

            if exitstatus != 0:
                stdout, stderr, exitstatus = conn.execute(
                    'echo "{}\n{}" > {}'.format(orthos_inline_begin,
                                                screenrc_file,
                                                orthos_inline_end))

            if exitstatus != 0:
                raise Exception("Couldn't create CScreen file ('{}')".format(
                    screenrc_file))

            # Save backup file which is used later by an invoked script
            # to determine the changes and update the running screen
            # session (add, remove or restart modified entries).
            stdout, stderr, exitstatus = conn.execute(
                'sudo cp {} {}.old'.format(screenrc_file, screenrc_file))

            cscreen = conn.get_file(screenrc_file, 'r')
            buffer = ''

            in_replace = False
            for line in cscreen.readlines():
                if not in_replace and line.startswith(orthos_inline_begin):
                    buffer += line + new_content
                    in_replace = True
                elif in_replace and line.startswith(orthos_inline_end):
                    buffer += line
                    in_replace = False
                elif not in_replace:
                    buffer += line

            cscreen.close()

            cscreen = conn.get_file(screenrc_file, 'w')
            buffer = buffer.strip('\n')
            print(buffer, file=cscreen)
            cscreen.close()

            stdout, stderr, exitstatus = conn.execute(
                'sudo /usr/bin/cscreen -u')
            logger.info("CScreen update exited with: {}".format(exitstatus))

            stdout, stderr, exitstatus = conn.execute(
                'sudo rm -f /etc/cscreenrc_allow_update')

            if exitstatus != 0:
                raise Exception(
                    "Couldn't unlock CScreen ('rm /etc/cscreenrc_allow_update')"
                )

        except SSH.Exception as exception:
            logger.error(exception)
        except IOError as exception:
            logger.error(exception)
        finally:
            if conn:
                conn.close()
Example #2
0
    def execute(self):
        """
        Executes the task.
        """
        if not ServerConfig.objects.bool_by_key('orthos.debug.motd.write'):
            logger.warning("Disabled: set 'orthos.debug.motd.write' to 'true'")
            return

        BEGIN = '-' * 69 + ' Orthos{ --'
        LINE = '-' * 80
        END = '-' * 69 + ' Orthos} --'

        try:
            machine = Machine.objects.get(fqdn=self.fqdn)
        except Machine.DoesNotExist:
            logger.error("Machine does not exist: fqdn={}".format(self.fqdn))
            return

        conn = None
        try:
            conn = SSH(machine.fqdn)
            conn.connect()
            motd = conn.get_file('/etc/motd.orthos', 'w')
            print(BEGIN, file=motd)
            print(
                "Machine of the ARCH team. Contact <{}> for problems.".format(
                    machine.get_support_contact()),
                file=motd)
            if machine.comment:
                print("INFO: " + machine.comment, file=motd)
            if machine.administrative:
                print(
                    "This machine is an administrative machine. DON\'T TOUCH!",
                    file=motd)
            if machine.reserved_by:
                print(LINE, file=motd)
                if machine.reserved_until != timezone.ZERO:
                    print("This machine is RESERVED by {} until {}.".format(
                        machine.reserved_by, machine.reserved_until),
                          file=motd)
                else:
                    print("This machine is RESERVED by {}.".format(
                        machine.reserved_by),
                          file=motd)
                print('', file=motd)
                print(wrap80(machine.reserved_reason), file=motd)
            print(END, file=motd)
            motd.close()
            stdout, stderr, exitstatus = conn.execute_script_remote(
                'machine_sync_motd.sh')

            if exitstatus != 0:
                logger.exception("({}) {}".format(machine.fqdn, stderr))
                raise Exception(stderr)

        except SSH.Exception as e:
            logger.error("({}) {}".format(machine.fqdn, e))
            return False
        except IOError as e:
            logger.error("({}) {}".format(machine.fqdn, e))
            return False
        finally:
            if conn:
                conn.close()
Example #3
0
def get_hardware_information(fqdn):
    """
    Retrieves information of the system.
    """
    try:
        machine = Machine.objects.get(fqdn=fqdn)
    except Machine.DoesNotExist:
        logger.warning("Machine '{}' does not exist".format(fqdn))
        return

    # set needed values for several checks from original machine
    machine_ = Machine(architecture=machine.architecture)

    conn = None
    timer = None
    try:
        conn = SSH(fqdn)
        conn.connect()
        timer = threading.Timer(5 * 60, conn.close)
        timer.start()

        # CPUs
        logger.debug("Get CPU number...")
        output, stderr, exitstatus = conn.execute_script_remote(
            'machine_get_cpu_number.sh')
        if output:
            for line in output:
                if line.startswith('SOCKETS'):
                    machine_.cpu_physical = int(line.split('=')[1])
                elif line.startswith('CORES'):
                    machine_.cpu_cores = int(line.split('=')[1])
                elif line.startswith('THREADS'):
                    machine_.cpu_threads = int(line.split('=')[1])

        logger.debug("Get CPU type...")
        output, stderr, exitstatus = conn.execute_script_remote(
            'machine_get_cpu_type.sh')
        if output and output[0]:
            machine_.cpu_model = output[0].strip()

        logger.debug("Get CPU flags...")
        output, stderr, exitstatus = conn.execute_script_remote(
            'machine_get_cpu_flags.sh')
        if output and output[0]:
            machine_.cpu_flags = output[0].strip()

        logger.debug("Get CPU speed...")
        output, stderr, exitstatus = conn.execute_script_remote(
            'machine_get_cpu_speed.sh')
        if output and output[0]:
            machine_.cpu_speed = Decimal(int(output[0].strip()) / 1000000)

        logger.debug("Get CPU ID...")
        output, stderr, exitstatus = conn.execute_script_remote(
            'machine_get_cpu_id.sh')
        if output and output[0]:
            machine_.cpu_id = output[0].strip()

        # EFI
        logger.debug("Check for EFI...")
        try:
            efi_file = conn.get_file('/sys/firmware/efi', 'r')
            efi_file.close()
            machine_.efi = True
        except IOError:
            machine_.efi = False

        # Memory
        logger.debug("Get RAM amount...")
        for line in conn.read_file('/proc/meminfo'):
            if line.startswith('MemTotal'):
                machine_.ram_amount = int(int(line.split()[1]) / 1024)

        # Virtualization capability
        VM_HOST_MIN_RAM_MB = 7000
        machine_.vm_capable = False

        # Virtualization: x86
        logger.debug("Check for VM capability...")
        if machine_.architecture_id == Architecture.Type.X86_64:
            cpu_flags = machine_.cpu_flags
            if cpu_flags:
                cpu_flags = cpu_flags.upper()
                if ((cpu_flags.find('VMX') >= 0 or cpu_flags.find('SVM') >= 0)
                        and int(machine_.ram_amount) > VM_HOST_MIN_RAM_MB):
                    machine_.vm_capable = True

        # Virtualization: ppc64le
        if machine_.architecture_id == Architecture.Type.PPC64LE:
            for line in conn.read_file('/proc/cpuinfo'):
                if line.startswith('firmware') and 'OPAL' in line:
                    machine_.vm_capable = True

        # Disk
        logger.debug("Get disk information...")
        stdout, stderr, exitstatus = conn.execute('hwinfo --disk')
        for line in stdout:
            line = line.strip()
            if line.startswith('Size:'):
                machine_.disk_primary_size = int(
                    int(line.split()[1]) / 2 / 1024**2)
            elif line.startswith('Attached to:'):
                opening_bracket = line.find('(')
                closing_bracket = line.find(')')
                if opening_bracket > 0 and closing_bracket > 0:
                    machine_.disk_type = line[opening_bracket +
                                              1:closing_bracket]
                else:
                    machine_.disk_type = 'Unknown disk type'
                break

        # lsmod
        logger.debug("Get 'lsmod'...")
        stdout, stderr, exitstatus = conn.execute('lsmod')
        machine_.lsmod = normalize_ascii("".join(stdout))

        # lspci
        logger.debug("Get 'lspci'...")
        stdout, stderr, exitstatus = conn.execute('lspci -vvv -nn')
        machine_.lspci = normalize_ascii("".join(stdout))

        # last
        logger.debug("Get 'last'...")
        output, stderr, exitstatus = conn.execute(
            'last | grep -v reboot | head -n 1')
        string = ''.join(output)
        result = string[0:8] + string[38:49]
        machine_.last = normalize_ascii("".join(result))

        # hwinfo
        logger.debug("Get 'hwinfo' (full)...")
        stdout, stderr, exitstatus = conn.execute(
            'hwinfo --bios ' +
            '--block --bridge --cdrom --cpu --disk --floppy --framebuffer ' +
            '--gfxcard --hub --ide --isapnp --isdn --keyboard --memory ' +
            '--monitor --mouse --netcard --network --partition --pci --pcmcia '
            + '--scsi --smp --sound --sys --tape --tv --usb --usb-ctrl --wlan')
        machine_.hwinfo = normalize_ascii("".join(stdout))

        # dmidecode
        logger.debug("Get 'dmidecode'...")
        stdout, stderr, exitstatus = conn.execute('dmidecode')
        machine_.dmidecode = normalize_ascii("".join(stdout))

        # dmesg
        logger.debug("Get 'dmesg'...")
        stdout, stderr, exitstatus = conn.execute(
            'if [ -e /var/log/boot.msg ]; then ' +
            'cat /var/log/boot.msg; else journalctl -xl | head -n200; ' + 'fi')
        machine_.dmesg = normalize_ascii("".join(stdout))

        # lsscsi
        logger.debug("Get 'lsscsi'...")
        stdout, stderr, exitstatus = conn.execute('lsscsi -s')
        machine_.lsscsi = normalize_ascii("".join(stdout))

        # lsusb
        logger.debug("Get 'lsusb'...")
        stdout, stderr, exitstatus = conn.execute('lsusb')
        machine_.lsusb = normalize_ascii("".join(stdout))

        # IPMI
        logger.debug("Check for IPMI...")
        machine_.ipmi = machine_.dmidecode.find('IPMI') >= 0

        # Firmware script
        logger.debug("Get BIOS version...")
        output, stderr, exitstatus = conn.execute_script_remote(
            'machine_get_firmware.sh')
        if output and output[0]:
            machine_.bios_version = output[0].strip()

        return machine_

    except Exception as e:
        logger.error("{} ({})".format(fqdn, e))
        return False
    finally:
        if conn:
            conn.close()
        if timer:
            timer.cancel()

    return None