Parse the array status line, e.g.::

        1318680576 blocks level 5, 1024k chunk, algorithm 2 [10/10] [UUUUUUUUUU]

    This retrieves the following pieces of information:

    * ``blocks`` - (int) number of blocks in the whole MD device (always present)
    * ``level`` - (int) if found, the present RAID level
    * ``chunksize`` - (str) if found, the size of the data chunk in kilobytes
    * ``algorithm`` - (int) if found, the current algorithm in use.

    Because of the way data is stored per-component and not per-array, this
    then puts the above keys into each of the component dictionaries in the
    list we've been given.

    Sample data::

        1250241792 blocks super 1.2 level 5, 64k chunk, algorithm 2 [5/5] [UUUUUU]
        1465151808 blocks level 5, 64k chunk, algorithm 2 [4/3] [UUU_]
        136448 blocks [2/2] [UU]
        6306 blocks super external:imsm<Paste>

def parse_array_status(line, components):
    """
    Parse the array status line, e.g.::

        1318680576 blocks level 5, 1024k chunk, algorithm 2 [10/10] [UUUUUUUUUU]

    This retrieves the following pieces of information:

    * ``blocks`` - (int) number of blocks in the whole MD device (always present)
    * ``level`` - (int) if found, the present RAID level
    * ``chunksize`` - (str) if found, the size of the data chunk in kilobytes
    * ``algorithm`` - (int) if found, the current algorithm in use.

    Because of the way data is stored per-component and not per-array, this
    then puts the above keys into each of the component dictionaries in the
    list we've been given.

    Sample data::

        1250241792 blocks super 1.2 level 5, 64k chunk, algorithm 2 [5/5] [UUUUUU]
        1465151808 blocks level 5, 64k chunk, algorithm 2 [4/3] [UUU_]
        136448 blocks [2/2] [UU]
        6306 blocks super external:imsm<Paste>
    """
    status_line_re = r'(?P<blocks>\d+) blocks' + \
        r'(?: super (?P<super>\S+))?' + \
        r'(?: level (?P<level>\d+),)?' + \
        r'(?: (?P<chunk>\d+k) chunk,)?' + \
        r'(?: algorithm (?P<algorithm>\d+))?'
    # Since we're only called once per line, unless there's a good way to
    # cache this regular expression in compiled form we're going to have to
    # compile it each time.
    status_line_rex = re.compile(status_line_re)
    match = status_line_rex.search(line)
    if match:
        attributes = {'blocks': int(match.group('blocks'))}
        if match.group('level'):
            attributes['level'] = int(match.group('level'))
        if match.group('chunk'):
            attributes['chunk'] = match.group('chunk')
        if match.group('algorithm'):
            attributes['algorithm'] = int(match.group('algorithm'))
        for comp in components:
            comp.update(attributes)