• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3
4# Copyright (c) 2021 Huawei Device Co., Ltd.
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16"""
17Description: create actions_list and transfer package
18"""
19
20import os
21import re
22from collections import OrderedDict
23from enum import Enum
24
25from blocks_manager import BlocksManager
26from log_exception import UPDATE_LOGGER
27from utils import FILE_MAP_ZERO_KEY
28from utils import FILE_MAP_COPY_KEY
29
30VERSION_NAME_RE = r"[0-9]+"
31REPLACE_CONTENT = "#"
32
33
34class ActionType(Enum):
35    NEW = 0
36    ZERO = 1
37    DIFFERENT = 2
38    MOVE = 3
39
40
41class ActionInfo:
42    def __init__(self, type_str, tgt_name, src_name, tgt_block_set,
43                 src_block_set):
44        self.type_str = type_str
45        self.tgt_name = tgt_name
46        self.src_name = src_name
47        self.tgt_block_set = tgt_block_set
48        if src_block_set is not None:
49            self.src_block_set = src_block_set
50        else:
51            self.src_block_set = BlocksManager()
52        self.child = OrderedDict()
53        self.parent = OrderedDict()
54        self.stash_before = []
55        self.use_stash = []
56
57    def get_max_block_number(self):
58        if self.src_block_set and self.src_block_set.size() != 0:
59            return max(self.src_block_set.range_data)
60        else:
61            return 0
62
63    def net_stash_change(self):
64        return (sum(sr.size() for (_, sr) in self.stash_before) -
65                sum(sr.size() for (_, sr) in self.use_stash))
66
67
68class TransfersManager(object):
69    def __init__(self, partition, tgt_img_obj, src_img_obj,
70                 disable_img_diff=False):
71        self.tgt_img_obj = tgt_img_obj
72        self.src_img_obj = src_img_obj
73        self.partition = partition
74        self.disable_img_diff = disable_img_diff
75
76        self.action_file_list = []
77
78    @staticmethod
79    def simplify_file_name(file_name):
80        base_name = os.path.basename(file_name)
81        no_version_name = re.sub(VERSION_NAME_RE, REPLACE_CONTENT, base_name)
82        return base_name, no_version_name
83
84    def arrange_source_file(self):
85        base_names = {}
86        version_patterns = {}
87        for file_name in self.src_img_obj.file_map.keys():
88            base_name, no_version_name = self.simplify_file_name(file_name)
89            base_names[base_name] = file_name
90            version_patterns[no_version_name] = file_name
91        return base_names, version_patterns
92
93    def find_process_needs(self):
94        """
95        generate action_list
96        """
97        src_base_names, src_version_patterns = self.arrange_source_file()
98        max_size = -1
99
100        for tgt_file_name, tgt_blocks in \
101                self.tgt_img_obj.file_map.items():
102            if FILE_MAP_ZERO_KEY == tgt_file_name:
103                UPDATE_LOGGER.print_log("Apply ZERO type!")
104                self.action_file_list.append(
105                    ActionInfo(
106                        ActionType.ZERO, tgt_file_name, FILE_MAP_ZERO_KEY,
107                        tgt_blocks, self.src_img_obj.
108                        file_map.get(FILE_MAP_ZERO_KEY, None)))
109                continue
110            if FILE_MAP_COPY_KEY == tgt_file_name:
111                UPDATE_LOGGER.print_log("Apply COPY type!")
112                self.action_file_list.append(
113                    ActionInfo(ActionType.NEW, tgt_file_name,
114                               None, tgt_blocks, None))
115                continue
116            if tgt_file_name in self.src_img_obj.file_map:
117                UPDATE_LOGGER.print_log("Apply DIFF type!")
118                action_info = ActionInfo(
119                    ActionType.DIFFERENT, tgt_file_name, tgt_file_name,
120                    tgt_blocks,
121                    self.src_img_obj.file_map[tgt_file_name])
122                max_size = action_info.get_max_block_number() \
123                    if action_info.get_max_block_number() > \
124                    max_size else max_size
125                self.action_file_list.append(action_info)
126                continue
127            src_file_name = self.get_file_name(
128                src_base_names, src_version_patterns, tgt_file_name)
129            if src_file_name:
130                action_info = ActionInfo(
131                    ActionType.DIFFERENT, tgt_file_name, src_file_name,
132                    tgt_blocks,
133                    self.src_img_obj.file_map[src_file_name])
134                max_size = action_info.get_max_block_number() if \
135                    action_info.get_max_block_number() > max_size else max_size
136                self.action_file_list.append(action_info)
137                continue
138            self.action_file_list.append(
139                ActionInfo(ActionType.NEW, tgt_file_name,
140                           None, tgt_blocks, None))
141
142        return max_size
143
144    def get_file_name(self, src_base_names, src_version_patterns,
145                      tgt_file_name):
146        tgt_base_name, tgt_version_patterns = \
147            self.simplify_file_name(tgt_file_name)
148        has_diff_name = True if tgt_base_name in src_base_names else False
149        has_diff_version = \
150            True if tgt_version_patterns in src_version_patterns else False
151        src_file_name = \
152            src_base_names[tgt_base_name] if has_diff_name else \
153            src_version_patterns[tgt_version_patterns] if \
154            has_diff_version else None
155        return src_file_name
156
157    def get_action_list(self):
158        return self.action_file_list
159