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