File: helper.py

package info (click to toggle)
python-ipmi 0.5.7-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 1,132 kB
  • sloc: python: 12,645; makefile: 2
file content (146 lines) | stat: -rw-r--r-- 4,673 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# Copyright (c) 2014  Kontron Europe GmbH
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA

import time

from .errors import CompletionCodeError, RetryError
from .utils import check_completion_code, ByteBuffer
from .msgs import constants


def get_sdr_chunk_helper(send_fn, req, reserve_fn, retry=5):

    while True:
        retry -= 1
        if retry == 0:
            raise RetryError()
        rsp = send_fn(req)
        if rsp.completion_code == constants.CC_OK:
            break
        elif rsp.completion_code == constants.CC_RES_CANCELED:
            time.sleep(1)
            req.reservation_id = reserve_fn()
            continue
        elif rsp.completion_code == constants.CC_TIMEOUT:
            time.sleep(0.1)
            continue
        elif rsp.completion_code == constants.CC_RESP_COULD_NOT_BE_PRV:
            time.sleep(0.1 * retry)
            continue
        else:
            check_completion_code(rsp.completion_code)

    return rsp


def get_sdr_data_helper(reserve_fn, get_fn, record_id, reservation_id=None):
    """Helper function to retrieve the sdr data.

    A specified helper function is used to retrieve the chunks.

    This can be used for SDRs from the Sensor Device or form the SDR
    repository.
    """
    if reservation_id is None:
        reservation_id = reserve_fn()

    (next_id, data) = get_fn(reservation_id, record_id, 0, 5)

    header = ByteBuffer(data)
    record_id = header.pop_unsigned_int(2)
    record_version = header.pop_unsigned_int(1)  # noqa:F841
    record_type = header.pop_unsigned_int(1)  # noqa:F841
    record_payload_length = header.pop_unsigned_int(1)
    record_length = record_payload_length + 5
    record_data = ByteBuffer(data)

    offset = len(record_data)
    max_req_len = 20
    retry = 20

    # now get the other record data
    while True:
        retry -= 1
        if retry == 0:
            raise RetryError()

        length = max_req_len
        if (offset + length) > record_length:
            length = record_length - offset

        try:
            (next_id, data) = get_fn(reservation_id, record_id, offset, length)
        except CompletionCodeError as e:
            if e.cc == constants.CC_CANT_RET_NUM_REQ_BYTES:
                # reduce max lenght
                max_req_len -= 4
                if max_req_len <= 0:
                    retry = 0
            else:
                raise CompletionCodeError(e.cc)

        record_data.extend(data[:])
        offset = len(record_data)
        if len(record_data) >= record_length:
            break

    return (next_id, record_data)


def _clear_repository(reserve_fn, clear_fn, ctrl, retry, reservation):
    while True:
        retry -= 1
        if retry <= 0:
            raise RetryError()

        try:
            in_progress = clear_fn(ctrl, reservation)
        except CompletionCodeError as e:
            if e.cc == constants.CC_RES_CANCELED:
                time.sleep(0.2)
                reservation = reserve_fn()
                continue
            else:
                check_completion_code(e.cc)

        if in_progress == constants.REPOSITORY_ERASURE_IN_PROGRESS:
            time.sleep(0.5)
            continue

        break
    return reservation


def clear_repository_helper(reserve_fn, clear_fn, retry=5, reservation=None):
    """Helper function to start repository erasure and wait until finish.

    This helper is used by clear_sel and clear_sdr_repository.
    """
    if reservation is None:
        reservation = reserve_fn()

    # start erasure
    reservation = _clear_repository(reserve_fn, clear_fn,
                                    constants.REPOSITORY_INITIATE_ERASE,
                                    retry, reservation)

    # give some time to clear
    time.sleep(0.5)

    # wait until finish
    reservation = _clear_repository(reserve_fn, clear_fn,
                                    constants.REPOSITORY_GET_ERASE_STATUS,
                                    retry, reservation)