Zhipeng Xie 4335408875 atune: init code
upload code to gitee

Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
2019-11-13 17:14:15 +08:00

146 lines
4.6 KiB
Python
Executable File

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Copyright (c) 2019 Huawei Technologies Co., Ltd.
# A-Tune is licensed under the Mulan PSL v1.
# You can use this software according to the terms and conditions of the Mulan PSL v1.
# You may obtain a copy of Mulan PSL v1 at:
# http://license.coscl.org.cn/MulanPSL
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
# PURPOSE.
# See the Mulan PSL v1 for more details.
# Create: 2019-10-29
"""
The sub class of the Configurator, used to change the grub2 config.
"""
import sys
import logging
import os
import subprocess
import random
import shutil
import re
from bootutils import Utils
if __name__ == "__main__":
sys.path.insert(0, "./../../")
from configurator.common import *
logger = logging.getLogger(__name__)
class Grub2(Configurator):
"""To change the grub2 config"""
_module = "BOOTLOADER"
_submod = "GRUB2"
def __init__(self, user=None):
Configurator.__init__(self, user)
__cfg_files = ["/etc/grub2.cfg", "/etc/grub2-efi.cfg"]
for f in __cfg_files:
if os.path.isfile(f):
self.__cfg_file = f
break
self.__kernel_ver = subprocess.check_output("uname -r".split()).decode(
).replace("\n", "")
def __get_cfg_entry(self, version):
with open(self.__cfg_file, 'r') as f:
ctx = f.read()
pattern = re.compile(
"\n(menuentry)[^\{\}]*?\{[^\{\}]*?\n\s+(linux)[^\{\}]*?" +
version.replace(
".",
"\.") +
"[^\{\}]*?(\})",
re.ASCII | re.DOTALL)
searchObj = pattern.search(ctx)
start = searchObj.span(1)
cmd = searchObj.span(2)
end = searchObj.span(3)
return {"START": start[0], "CMD": cmd[0], "END": end[1]}
def _get(self, key):
entry = self.__get_cfg_entry(self.__kernel_ver)
with open(self.__cfg_file, 'r') as f:
f.seek(entry["CMD"])
cmd = f.readline()
keypos = Utils.get_keypos(cmd, key)
if keypos == -1:
err = GetConfigError("Fail to find {} config".format(key))
logger.error(
"{}.{}: {}".format(
self.__class__.__name__,
sys._getframe().f_code.co_name,
str(err)))
raise err
config = cmd[keypos:].split()[0]
if config.find("=") != -1:
return config.split("=")[1]
else:
return None
@pre_check(
Configurator._precheck,
os.path.split(
os.path.realpath(__file__))[0] +
"/grub2.json")
def _set(self, key, value):
entry = self.__get_cfg_entry(self.__kernel_ver)
if value is None:
new = key
else:
new = "{key}={val}".format(key=key, val=value)
with open(self.__cfg_file, 'r+') as f:
f.seek(entry["CMD"])
cmd = f.readline()
keypos = Utils.get_keypos(cmd, key)
if keypos != -1:
old = cmd[keypos:].split("\n")[0].split()[0]
file_modify(f, entry["CMD"] + keypos,
entry["CMD"] + keypos + len(old) - 1, new)
else:
file_modify(f, entry["CMD"] + len(cmd) - 1, -1, " " + new)
active = Utils.get_value(key)
if value == active:
return 0
raise NeedRebootWarning(
"Need reboot to make the config change of grub2 effect.")
def _backup(self, key, rollback_info):
name = os.path.basename(self.__cfg_file)
bak_file = "{path}/{file}{ver}".format(path=rollback_info, file=name,
ver=random.random())
shutil.copy(self.__cfg_file, bak_file)
return "CPI_ROLLBACK_INFO = {}".format(bak_file)
def _resume(self, key, value):
if key != "CPI_ROLLBACK_INFO":
err = ValueError("unsupported resume type: {}".format(key))
logger.error(
"{}.{}: {}".format(
self.__class__.__name__,
sys._getframe().f_code.co_name,
str(err)))
raise err
shutil.copy(value, self.__cfg_file)
return None
if __name__ == "__main__":
if len(sys.argv) != 2:
print('usage: ' + sys.argv[0] + ' key[=value]')
sys.exit(-1)
ct = Grub2("UT1")
save = ct.backup(sys.argv[1], "./1/")
print(save)
print(ct.set(sys.argv[1]))
print(ct.get(ct._getcfg(sys.argv[1])[0]))
print(ct.resume(save))