提交 54366299 编写于 作者: O openeuler-ci-bot 提交者: Gitee

!152 atune: refactor the code to generate yaml files and update csv and yaml files

Merge pull request !152 from hanxinke/master
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Copyright (c) 2020 Huawei Technologies Co., Ltd.
# A-Tune is licensed under the Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
# http://license.coscl.org.cn/MulanPSL2
# 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 v2 for more details.
# Create: 2020-07-30
"""
The tool to translate .excel file to .yaml files
Usage: python3 translate_xlsx2yaml.py [-h] [-i] [-o] [-t] [-p]
"""
import argparse
import os
import subprocess
import string
from enum import Enum
from io import StringIO
import io
import openpyxl
import glob
import shlex
class CsvAttr(Enum):
"""Enumerate the headers"""
name = 0
desc = 1
geti = 2
seti = 3
needrestart = 4
typei = 5
options = 6
dtype = 7
scope_min = 8
scope_max = 9
step = 10
items = 11
select = 12
class TuningObject:
"""Tuning Object"""
def __init__(self, obj_list, block_dev, network_dev):
self.name = obj_list[CsvAttr.name.value].strip()
self.desc = obj_list[CsvAttr.desc.value].strip()
self.get = obj_list[CsvAttr.geti.value].strip()
self.set = obj_list[CsvAttr.seti.value].strip()
self.needrestart = obj_list[CsvAttr.needrestart.value].strip()
self.type = obj_list[CsvAttr.typei.value].strip()
self.options = obj_list[CsvAttr.options.value].strip()
self.dtype = obj_list[CsvAttr.dtype.value].strip()
self.scope_min = obj_list[CsvAttr.scope_min.value].strip()
self.scope_max = obj_list[CsvAttr.scope_max.value].strip()
self.step = obj_list[CsvAttr.step.value].strip()
self.items = obj_list[CsvAttr.items.value].strip()
self.block_device = block_dev
self.network_device = network_dev
if '@name' in self.get:
self.get = self.get.replace('@name', self.name)
if '@name' in self.set:
self.set = self.set.replace('@name', self.name)
if '@block' in self.get:
self.get = self.get.replace('@block', self.block_device)
if '@block' in self.set:
self.set = self.set.replace('@block', self.block_device)
if '@netdev' in self.get:
self.get = self.get.replace('@netdev', self.network_device)
if '@netdev' in self.set:
self.set = self.set.replace('@netdev', self.network_device)
self.needrestart = self.needrestart.lower()
def exec_cmd(self, cmd, value):
"""
Execute the input command
:param cmd: input command
:param value: the value used in the command
:return: True or False, the results of the execution
"""
if 'echo' in self.set:
cmd1, cmd2 = cmd.split('>')
try:
file = open(cmd2.strip(), "w")
except PermissionError:
return False
process = subprocess.Popen(shlex.split(cmd1), stdout=file, shell=False)
process.wait()
result = str(process.returncode)
elif 'ifconfig' in self.set:
process = subprocess.Popen(shlex.split(cmd), shell=False)
process.wait()
result = str(process.returncode)
elif 'sysctl' in self.set:
result = subprocess.check_output(shlex.split(cmd), stderr=subprocess.STDOUT, shell=False).decode().strip()
else:
process = subprocess.Popen(shlex.split(cmd), shell=False)
process.wait()
result = str(process.returncode)
cmd_fail = False
if 'sysctl' in self.set:
if 'Invalid argument' in result:
cmd_fail = True
elif 'ethtool' in self.set:
if result != '0' and result != '80':
cmd_fail = True
else:
if result != '0':
cmd_fail = True
if cmd_fail:
print('Invalid Value for ', self.name, ' :', value, '. Make sure the value is in valid range!(', cmd, ')')
return False
return True
def valid_test_command(self, value, orig_value):
"""
Test the set command in excel
:param value: the value used in the set command
:param orig_value: the result of get command
:return: True or False, the result of execution set command
"""
if value == orig_value:
return True
cmd = self.set.replace('$value', value)
result = self.exec_cmd(cmd, value)
return result
def valid_test_good(self):
"""
Main check, check the command and given values.
:return: True or False, check result
"""
if self.type == 'continuous':
return True
get_cmd = self.get
count = get_cmd.count('|')
if count > 0:
get_cmds = get_cmd.split('|')
i = 0
for cmds in get_cmds:
if i == 0:
child = subprocess.Popen(shlex.split(cmds), shell=False, stdout=subprocess.PIPE)
elif i == count:
process = subprocess.Popen(shlex.split(cmds), stdin=child.stdout,
stdout=subprocess.PIPE, shell=False)
result = process.communicate()
else:
child = subprocess.Popen(shlex.split(cmds), shell=False, stdin=child.stdout, stdout=subprocess.PIPE)
i += 1
else:
process = subprocess.Popen(shlex.split(get_cmd), shell=False, stdout=subprocess.PIPE)
result = process.communicate()
orig_value = str(result)
if self.dtype == 'int':
result_min = self.valid_test_command(self.scope_min, orig_value)
result_max = self.valid_test_command(self.scope_max, orig_value)
if not result_min or not result_max:
return False
elif self.dtype == 'string':
dis_options = self.options.split(';')
for option in dis_options:
option = '\"' + option.strip() + '\"'
result = self.valid_test_command(option, orig_value)
if not result:
return False
else:
print("Invalid dtype of ", self.name, ":", self.dtype, ". Only support int and string")
return False
return True
def __repr__(self):
fstr = StringIO()
fstr.write(' -\n')
fstr.write(' name : \"' + self.name + '\"\n')
fstr.write(' info :\n')
fstr.write(' desc : \"' + self.desc + '\"\n')
fstr.write(' get : \"' + self.get + '\"\n')
fstr.write(' set : \"' + self.set + '\"\n')
fstr.write(' needrestart : \"' + self.needrestart + '\"\n')
fstr.write(' type : \"' + self.type + '\"\n')
if self.type == 'continuous':
fstr.write(' scope :\n')
fstr.write(' - ' + self.scope_min + '\n')
fstr.write(' - ' + self.scope_max + '\n')
if self.dtype == 'string':
fstr.write(' dtype : \"string\"\n')
else:
fstr.write(' dtype : \"int\"\n')
elif self.type == 'discrete':
if self.dtype == 'string':
fstr.write(' options :\n')
dis_options = self.options.split(';')
for option in dis_options:
fstr.write(' - \"' + option.strip() + '\"\n')
fstr.write(' dtype : \"string\"\n')
elif self.dtype == 'int':
fstr.write(' scope :\n')
fstr.write(' - ' + self.scope_min + '\n')
fstr.write(' - ' + self.scope_max + '\n')
fstr.write(' step : ' + self.step + '\n')
fstr.write(' items : \n')
if self.items != '':
dis_items = self.items.split(';')
for dit in dis_items:
fstr.write(' - ' + dit + '\n')
fstr.write(' dtype : \"int\"\n')
else:
pass
else:
pass
return fstr.getvalue()
class XLSX2YAML:
"""
Get objects from excel files
"""
def __init__(self, in_file_name, out_file_name, project_name, iterations):
with open(in_file_name, 'rb') as file:
in_mem_file = io.BytesIO(file.read())
self.workbook = openpyxl.load_workbook(in_mem_file, read_only=True)
self.out_file = open(out_file_name, 'w')
self.project_name = project_name
self.iterations = iterations
def __del__(self):
self.out_file.close()
def get_head(self):
"""
Generate the header of yaml file.
:return: string, the header of yaml file.
"""
fstr = StringIO()
fstr.write('project:' + ' \"' + self.project_name + '\"' + '\n')
fstr.write('maxiterations: ' + str(self.iterations) + '\n')
fstr.write('startworkload: \"\"\n')
fstr.write('stopworkload: \"\"\n')
fstr.write('object : \n')
return fstr.getvalue()
def read_line_tuning_object(self, worksheet, line):
"""
Get a line of excel into list.
:param worksheet: excel sheet.
:param line: the number of line to get.
:return: list, the tuning object.
"""
obj_list = []
name_ = worksheet[str('B' + str(line))].value
if name_ is None or name_.strip() == "":
return obj_list
cols = string.ascii_uppercase[1:15]
for col in cols:
val = worksheet[str(col + str(line))].value
if val is None:
val = ''
obj_list.append(str(val))
return obj_list
def translate(self, block_dev, network_dev, test):
"""
Translate excel to yaml.
:param block_dev: the name of block device.
:param network_dev: the name of network device.
:param test: whether test the commands in file or not.
:return: True or False, translation result.
"""
self.out_file.write(self.get_head())
sheetnames = self.workbook.sheetnames
worksheet = self.workbook[sheetnames[0]]
line = 2
obj_list = self.read_line_tuning_object(worksheet, line)
if not obj_list:
print("Empty workbook, translation stops:", self.out_file)
return False
while obj_list:
is_select = obj_list[CsvAttr.select.value].strip()
if is_select == 'yes':
tun_obj = TuningObject(obj_list, block_dev, network_dev)
if test == 'True':
valid = tun_obj.valid_test_good()
if not valid:
return False
if tun_obj.name != '':
self.out_file.write(str(tun_obj))
line = line + 1
obj_list = self.read_line_tuning_object(worksheet, line)
return True
def main(in_dir, out_dir, iterations, project_name, block_dev, network_dev, test):
"""
Translate .xlsx files to .yaml files.
:param in_dir: the folder of input excel files.
:param out_dir: the folder of output yaml files.
:param iterations: iterations of the project (> 10).
:param project_name: the name of the configuration project.
:param block_dev: the name of block device.
:param network_dev: the name of network device.
:param test: whether test the commands in file or not.
:return: None
"""
if iterations <= 10:
print('-t iterations must be > 10, the input is ', iterations)
return False
if not os.path.exists(in_dir):
print("Failed: The input directory is not existed:", in_dir)
return False
if not os.path.exists(out_dir):
print("Warning: The output directory is not existed:", out_dir)
return False
in_file_list = glob.glob((str(in_dir) + "*.xlsx"))
if not in_file_list:
print("No .xlsx files exist in the directory")
return False
for file in in_file_list:
in_file_name = file
out_file_name = file.replace(".xlsx", ".yaml")
if os.path.exists(str(out_dir) + out_file_name):
print("Warning: The output yaml file is already exist, overwrite it!--", out_file_name)
xlsx2yaml = XLSX2YAML((in_dir + in_file_name), (out_dir + out_file_name), project_name, iterations)
result = xlsx2yaml.translate(block_dev, network_dev, test)
if result:
print('Translation of ' + str(file) + ' SUCCEEDED!\n')
else:
print('Translation of' + str(file) + ' FAILED!\n')
return result
if __name__ == '__main__':
ARG_PARSER = argparse.ArgumentParser(description="translate excel files to yaml files")
ARG_PARSER.add_argument('-i', '--in_dir', metavar='INPUT DIRECTORY',
default="./", help='The folder of input excel files')
ARG_PARSER.add_argument('-o', '--out_dir', metavar='OUTPUT DIRECTORY',
default="./", help='The folder of output yaml files')
ARG_PARSER.add_argument('-t', '--iteration', metavar='ITERATIONS', type=int,
default="100", help='Iterations of the project (> 10)')
ARG_PARSER.add_argument('-p', '--prj_name', metavar='NAME',
default="example", help='The name of the project')
ARG_PARSER.add_argument('-bd', '--block_device', metavar='BLOCK DEVICE',
default="sda", help='The name of block device')
ARG_PARSER.add_argument('-nd', '--network_device', metavar='NETWORK DEVICE',
default="enp189s0f0", help='The name of network device')
ARG_PARSER.add_argument('-f', '--test', metavar='TEST COMMAND',
default="True", help='Whether test the command or not')
ARGS = ARG_PARSER.parse_args()
main(ARGS.in_dir, ARGS.out_dir, ARGS.iteration, ARGS.prj_name, ARGS.block_device, ARGS.network_device, ARGS.test)
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Copyright (c) 2020 Huawei Technologies Co., Ltd.
# A-Tune is licensed under the Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
# http://license.coscl.org.cn/MulanPSL2
# 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 v2 for more details.
# Create: 2020-08-14
...@@ -9,31 +9,26 @@ ...@@ -9,31 +9,26 @@
# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR # IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
# PURPOSE. # PURPOSE.
# See the Mulan PSL v2 for more details. # See the Mulan PSL v2 for more details.
# Create: 2020-07-30 # Create: 2020-08-14
""" """
The tool to translate .csv file to .yaml files Configure attribute in yaml file
Usage: python3 translate_csv2yaml.py [-h] [-i] [-o] [-t] [-p]
""" """
import csv
import argparse
import os
import subprocess import subprocess
from enum import Enum from enum import Enum
from io import StringIO from io import StringIO
import glob
import shlex import shlex
class CsvAttr(Enum): class ConfigAttrName(Enum):
"""Enumerate the headers""" """Enumerate config attribute"""
name = 0 name = 0
desc = 1 desc = 1
geti = 2 get = 2
seti = 3 set = 3
needrestart = 4 need_restart = 4
typei = 5 type = 5
options = 6 options = 6
dtype = 7 dtype = 7
scope_min = 8 scope_min = 8
...@@ -43,40 +38,34 @@ class CsvAttr(Enum): ...@@ -43,40 +38,34 @@ class CsvAttr(Enum):
select = 12 select = 12
class TuningObject: class ConfigAttribute:
"""Tuning Object""" """config attribute in yaml"""
def __init__(self, obj_list, block_dev, network_dev): def __init__(self, obj_list, block_dev, network_dev):
self.name = obj_list[CsvAttr.name.value].strip() self.name = obj_list[ConfigAttrName.name.value].strip()
self.desc = obj_list[CsvAttr.desc.value].strip() self.desc = obj_list[ConfigAttrName.desc.value].strip()
self.get = obj_list[CsvAttr.geti.value].strip() self.get = obj_list[ConfigAttrName.get.value].strip()
self.set = obj_list[CsvAttr.seti.value].strip() self.set = obj_list[ConfigAttrName.set.value].strip()
self.needrestart = obj_list[CsvAttr.needrestart.value].strip() self.need_restart = obj_list[ConfigAttrName.need_restart.value].strip()
self.type = obj_list[CsvAttr.typei.value].strip() self.type = obj_list[ConfigAttrName.type.value].strip()
self.options = obj_list[CsvAttr.options.value].strip() self.options = obj_list[ConfigAttrName.options.value].strip()
self.dtype = obj_list[CsvAttr.dtype.value].strip() self.dtype = obj_list[ConfigAttrName.dtype.value].strip()
self.scope_min = obj_list[CsvAttr.scope_min.value].strip() self.scope_min = obj_list[ConfigAttrName.scope_min.value].strip()
self.scope_max = obj_list[CsvAttr.scope_max.value].strip() self.scope_max = obj_list[ConfigAttrName.scope_max.value].strip()
self.step = obj_list[CsvAttr.step.value].strip() self.step = obj_list[ConfigAttrName.step.value].strip()
self.items = obj_list[CsvAttr.items.value].strip() self.items = obj_list[ConfigAttrName.items.value].strip()
self.block_device = block_dev self.block_device = block_dev
self.network_device = network_dev self.network_device = network_dev
if '@name' in self.get: replace_map = {'@name': self.name, '@block': self.block_device,
self.get = self.get.replace('@name', self.name) '@netdev': self.network_device}
if '@name' in self.set: for key, value in replace_map.items():
self.set = self.set.replace('@name', self.name) if key in self.get:
self.get = self.get.replace(key, value)
if '@block' in self.get: if key in self.set:
self.get = self.get.replace('@block', self.block_device) self.set = self.set.replace(key, value)
if '@block' in self.set:
self.set = self.set.replace('@block', self.block_device)
if '@netdev' in self.get:
self.get = self.get.replace('@netdev', self.network_device)
if '@netdev' in self.set:
self.set = self.set.replace('@netdev', self.network_device)
self.needrestart = self.needrestart.lower() self.need_restart = self.need_restart.lower()
def exec_cmd(self, cmd, value): def exec_cmd(self, cmd, value):
""" """
...@@ -85,22 +74,19 @@ class TuningObject: ...@@ -85,22 +74,19 @@ class TuningObject:
:param value: the value used in the command :param value: the value used in the command
:return: True or False, the results of the execution :return: True or False, the results of the execution
""" """
if 'echo ' in self.set and '>' in self.set:
if 'echo' in self.set:
cmd1, cmd2 = cmd.split('>') cmd1, cmd2 = cmd.split('>')
try: with open(cmd2.strip(), 'w') as file:
file = open(cmd2.strip(), "w")
except PermissionError:
return False
process = subprocess.Popen(shlex.split(cmd1), stdout=file, shell=False) process = subprocess.Popen(shlex.split(cmd1), stdout=file, shell=False)
process.wait() process.wait()
result = str(process.returncode) result = str(process.returncode)
elif 'ifconfig' in self.set: elif 'ifconfig ' in self.set:
process = subprocess.Popen(shlex.split(cmd), shell=False) process = subprocess.Popen(shlex.split(cmd), shell=False)
process.wait() process.wait()
result = str(process.returncode) result = str(process.returncode)
elif 'sysctl' in self.set: elif 'sysctl ' in self.set:
result = subprocess.check_output(shlex.split(cmd), stderr=subprocess.STDOUT, shell=False).decode().strip() result = subprocess.check_output(shlex.split(cmd), stderr=subprocess.STDOUT,
shell=False).decode().strip()
else: else:
process = subprocess.Popen(shlex.split(cmd), shell=False) process = subprocess.Popen(shlex.split(cmd), shell=False)
process.wait() process.wait()
...@@ -110,38 +96,19 @@ class TuningObject: ...@@ -110,38 +96,19 @@ class TuningObject:
if 'sysctl' in self.set: if 'sysctl' in self.set:
if 'Invalid argument' in result: if 'Invalid argument' in result:
cmd_fail = True cmd_fail = True
elif 'ethtool' in self.set:
if result != '0' and result != '80':
cmd_fail = True
else: else:
if result != '0': if result != '0':
cmd_fail = True cmd_fail = True
if cmd_fail: if cmd_fail:
print('Invalid Value for ', self.name, ' :', value, '. Make sure the value is in valid range!(', cmd, ')') print('Warning: %s invalid Value %s, make sure the value is in valid range.'
% (self.name, value))
return False return False
return True return True
def valid_test_attr(self):
def valid_test_command(self, value, orig_value):
""" """
Test the set command in csv check the command and given attr.
:param value: the value used in the set command
:param orig_value: the result of get command
:return: True or False, the result of execution set command
"""
if value == orig_value:
return True
cmd = self.set.replace('$value', value)
result = self.exec_cmd(cmd, value)
return result
def valid_test_good(self):
"""
Main check, check the command and given values.
:return: True or False, check result :return: True or False, check result
""" """
if self.type == 'continuous': if self.type == 'continuous':
...@@ -149,42 +116,48 @@ class TuningObject: ...@@ -149,42 +116,48 @@ class TuningObject:
get_cmd = self.get get_cmd = self.get
count = get_cmd.count('|') count = get_cmd.count('|')
process = None
if count > 0: if count > 0:
get_cmds = get_cmd.split('|') for cmds in get_cmd.split('|'):
i = 0 process = subprocess.Popen(shlex.split(cmds), shell=False, stdout=subprocess.PIPE,
for cmds in get_cmds: stdin=None if process is None else process.stdout)
if i == 0:
child = subprocess.Popen(shlex.split(cmds), shell=False, stdout=subprocess.PIPE)
elif i == count:
process = subprocess.Popen(shlex.split(cmds), stdin=child.stdout, stdout=subprocess.PIPE, shell=False)
result = process.communicate()
else:
child = subprocess.Popen(shlex.split(cmds), shell=False, stdin=child.stdout, stdout=subprocess.PIPE)
i += 1
else: else:
process = subprocess.Popen(shlex.split(get_cmd), shell=False, stdout=subprocess.PIPE) process = subprocess.Popen(shlex.split(get_cmd), shell=False, stdout=subprocess.PIPE)
result = process.communicate() result = process.communicate()
orig_value = bytes.decode(result[0]).replace('\n', ' ').strip()
orig_value = str(result)
if self.dtype == 'int': if self.dtype == 'int':
result_min = self.valid_test_command(self.scope_min, orig_value) for value in [self.scope_min, self.scope_max]:
result_max = self.valid_test_command(self.scope_max, orig_value) result = self.valid_test_command(value, orig_value)
if not result_min or not result_max: if not result:
return False return False
elif self.dtype == 'string': elif self.dtype == 'string':
dis_options = self.options.split(';') dis_options = self.options.split(';')
for option in dis_options: for option in dis_options:
option = '\"' + option.strip() + '\"' option = '\"' + option.strip() + '\"'
result = self.valid_test_command(option, orig_value) result = self.valid_test_command(option, '\"' + orig_value + '\"')
if not result: if not result:
return False return False
else: else:
print("Invalid dtype of ", self.name, ":", self.dtype, ". Only support int and string") print("Warning: %s invalid dtype %s, only support int and string"
% (self.name, self.dtype))
return False return False
return True
def valid_test_command(self, value, orig_value):
"""
Test the set command
:param value: the value used in the set command
:param orig_value: the result of get command
:return: True or False, the result of execution set command
"""
if value == orig_value:
return True return True
cmd = self.set.replace('$value', value)
result = self.exec_cmd(cmd, value)
return result
def __repr__(self): def __repr__(self):
fstr = StringIO() fstr = StringIO()
fstr.write(' -\n') fstr.write(' -\n')
...@@ -193,7 +166,7 @@ class TuningObject: ...@@ -193,7 +166,7 @@ class TuningObject:
fstr.write(' desc : \"' + self.desc + '\"\n') fstr.write(' desc : \"' + self.desc + '\"\n')
fstr.write(' get : \"' + self.get + '\"\n') fstr.write(' get : \"' + self.get + '\"\n')
fstr.write(' set : \"' + self.set + '\"\n') fstr.write(' set : \"' + self.set + '\"\n')
fstr.write(' needrestart : \"' + self.needrestart + '\"\n') fstr.write(' needrestart : \"' + self.need_restart + '\"\n')
fstr.write(' type : \"' + self.type + '\"\n') fstr.write(' type : \"' + self.type + '\"\n')
if self.type == 'continuous': if self.type == 'continuous':
...@@ -219,160 +192,14 @@ class TuningObject: ...@@ -219,160 +192,14 @@ class TuningObject:
fstr.write(' items : \n') fstr.write(' items : \n')
if self.items != '': if self.items != '':
dis_items = self.items.split(';') dis_items = self.items.split(';')
for dit in dis_items: for item in dis_items:
fstr.write(' - ' + dit + '\n') fstr.write(' - ' + item + '\n')
fstr.write(' dtype : \"int\"\n') fstr.write(' dtype : \"int\"\n')
else: else:
pass print("Warning: %s invalid dtype %s, only support int and string"
% (self.name, self.dtype))
else: else:
pass print("Warning: %s invalid type %s, only support continuous and discrete"
% (self.name, self.type))
return fstr.getvalue() return fstr.getvalue()
class XLSX2YAML:
"""
Get objects from excel files
"""
def __init__(self, in_file_name, out_file_name, project_name, iterations):
with open(in_file_name) as file:
reader = csv.reader(file)
self.rows = [row for row in reader]
self.out_file = open(out_file_name, 'w')
self.project_name = project_name
self.iterations = iterations
def __del__(self):
self.out_file.close()
def get_head(self):
"""
Generate the header of yaml file.
:return: string, the header of yaml file.
"""
fstr = StringIO()
fstr.write('project:' + ' \"' + self.project_name + '\"' + '\n')
fstr.write('maxiterations: ' + str(self.iterations) + '\n')
fstr.write('startworkload: \"\"\n')
fstr.write('stopworkload: \"\"\n')
fstr.write('object : \n')
return fstr.getvalue()
def read_line_tuning_object(self, line):
"""
Get a line of csv into list.
:param line: the number of line to get.
:return: list, the tuning object.
"""
obj_list = []
if line >= len(self.rows):
return obj_list
name_ = self.rows[line][1]
if name_ is None or name_.strip() == "":
return obj_list
for col in range(1, 14):
val = self.rows[line][col]
if val is None:
val = ''
obj_list.append(str(val))
return obj_list
def translate(self, block_dev, network_dev, test):
"""
Translate csv to yaml.
:param block_dev: block device name
:param network_dev: network device name
:param test: Whether test the commands or not
:return: True or False, the result of translation
"""
self.out_file.write(self.get_head())
line = 1
obj_list = self.read_line_tuning_object(line)
if not obj_list:
print("Empty workbook, translation stops:", self.out_file)
return False
while obj_list:
is_select = obj_list[CsvAttr.select.value].strip()
if is_select == 'yes':
tun_obj = TuningObject(obj_list, block_dev, network_dev)
if test == 'True':
valid = tun_obj.valid_test_good()
if not valid:
return False
if tun_obj.name != '':
self.out_file.write(str(tun_obj))
line = line + 1
obj_list = self.read_line_tuning_object(line)
return True
def main(in_dir, out_dir, iterations, project_name, block_dev, network_dev, test):
"""
Translate .csv files to .yaml files.
:param in_dir: the folder of input csv files.
:param out_dir: the folder of output yaml files.
:param iterations: iterations of the project (> 10).
:param project_name: the name of the configuration project.
:param block_dev: the name of block device.
:param network_dev: the name of network device.
:param test: Whether test the commands or not
:return: None
"""
if iterations <= 10:
print('-t iterations must be > 10, the input is ', iterations)
return False
if not os.path.exists(in_dir):
print("Failed: The input directory is not existed:", in_dir)
return False
if not os.path.exists(out_dir):
print("Warning: The output directory is not existed:", out_dir)
return False
in_file_list = glob.glob((str(in_dir) + "*.csv"))
if not in_file_list:
print("No .csv files exist in the directory")
return False
for file in in_file_list:
in_file_name = file
out_file_name = file.replace(".csv", ".yaml")
if os.path.exists(str(out_dir) + out_file_name):
print("Warning: The output yaml file is already exist, overwrite it!--", out_file_name)
xlsx2yaml = XLSX2YAML((in_dir + in_file_name), (out_dir + out_file_name),
project_name, iterations)
result = xlsx2yaml.translate(block_dev, network_dev, test)
if result:
print('Translation of ' + str(file) + ' SUCCEEDED!\n')
else:
print('Translation of' + str(file) + ' FAILED!\n')
return result
if __name__ == '__main__':
ARG_PARSER = argparse.ArgumentParser(description="translate excel files to yaml files")
ARG_PARSER.add_argument('-i', '--in_dir', metavar='INPUT DIRECTORY',
default="./", help='The folder of input excel files')
ARG_PARSER.add_argument('-o', '--out_dir', metavar='OUTPUT DIRECTORY',
default="./", help='The folder of output yaml files')
ARG_PARSER.add_argument('-t', '--iteration', metavar='ITERATIONS', type=int,
default="100", help='Iterations of the project (> 10)')
ARG_PARSER.add_argument('-p', '--prj_name', metavar='NAME',
default="example", help='The name of the project')
ARG_PARSER.add_argument('-bd', '--block_device', metavar='BLOCK DEVICE',
default="sda", help='The name of block device')
ARG_PARSER.add_argument('-nd', '--network_device', metavar='NETWORK DEVICE',
default="enp189s0f0", help='The name of network device')
ARG_PARSER.add_argument('-f', '--test', metavar='TEST COMMAND',
default="True", help='Whether test the command or not')
ARGS = ARG_PARSER.parse_args()
main(ARGS.in_dir, ARGS.out_dir, ARGS.iteration, ARGS.prj_name, ARGS.block_device, ARGS.network_device, ARGS.test)
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Copyright (c) 2020 Huawei Technologies Co., Ltd.
# A-Tune is licensed under the Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
# http://license.coscl.org.cn/MulanPSL2
# 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 v2 for more details.
# Create: 2020-08-14
"""
The tool to translate file to .yaml files
Usage: python3 translate.py [-h] [-i] [-o] [-t] [-p] [-b] [-n] [-s] [-f]
"""
import argparse
import ast
import os
import glob
from translate_csv2yaml import TranslateCsv2Yaml
from translate_xlsx2yaml import TranslateXlsx2Yaml
def main(in_dir, out_dir, iterations, project_name, block_dev, network_dev, test, file_extension):
"""
Translate .xlsx or .csv files to .yaml files.
:param in_dir: the folder of input files.
:param out_dir: the folder of output yaml files.
:param iterations: iterations of the project (> 10).
:param project_name: the name of the configuration project.
:param block_dev: the name of block device.
:param network_dev: the name of network device.
:param test: whether test the commands in file or not.
:param file_extension: The file extension converted to yaml files.
:return: None
"""
if iterations <= 10:
print('Failed: Iterations must be > 10, the input is %s' % iterations)
return
if not os.path.exists(in_dir):
print("Failed: The input directory (%s) is not existed" % in_dir)
return
if not os.path.exists(out_dir):
print("Failed: The output directory (%s) is not existed" % out_dir)
return
if not file_extension in ("xlsx", "csv"):
print("Failed: The file extension must be be xlsx or csv")
return
in_file_list = glob.glob((str(in_dir) + "*." + file_extension))
if not in_file_list:
print("Warning: No %s files exist in the directory" % file_extension)
return
for file in in_file_list:
in_file_name = file
in_file_basename = os.path.basename(file)
out_file_name = in_file_basename.replace("." + file_extension, ".yaml")
if os.path.exists(str(out_dir) + out_file_name):
print("Warning: The output yaml file (%s) is already exist,"
" overwrite it!--" % out_file_name)
if file_extension == "xlsx":
translate_yaml = TranslateXlsx2Yaml(os.path.join(in_dir, in_file_name),
os.path.join(out_dir, out_file_name),
project_name, iterations,
block_dev, network_dev, test)
else:
translate_yaml = TranslateCsv2Yaml(os.path.join(in_dir, in_file_name),
os.path.join(out_dir, out_file_name),
project_name, iterations,
block_dev, network_dev, test)
if translate_yaml.translate():
print('Translating %s SUCCEEDED!' % str(file))
else:
print('Translating %s FAILED!' % str(file))
if __name__ == '__main__':
ARG_PARSER = argparse.ArgumentParser(description="translate excel or csv files to yaml files")
ARG_PARSER.add_argument('-i', '--in_dir', metavar='INPUT DIRECTORY',
default="./", help='The folder of input excel or csv files')
ARG_PARSER.add_argument('-o', '--out_dir', metavar='OUTPUT DIRECTORY',
default="./", help='The folder of output yaml files')
ARG_PARSER.add_argument('-t', '--iteration', metavar='ITERATIONS', type=int,
default="100", help='Iterations of the project (> 10)')
ARG_PARSER.add_argument('-p', '--prj_name', metavar='NAME',
default="example", help='The name of the project')
ARG_PARSER.add_argument('-b', '--block_device', metavar='BLOCK DEVICE',
default="sda", help='The name of block device')
ARG_PARSER.add_argument('-n', '--network_device', metavar='NETWORK DEVICE',
default="enp189s0f0", help='The name of network device')
ARG_PARSER.add_argument('-s', '--test', metavar='TEST COMMAND',
type=ast.literal_eval, default=False,
help='Whether test the command or not, True or False')
ARG_PARSER.add_argument('-f', '--file_extension', metavar='FILE EXTENSION',
default="csv", help='The file extension converted to yaml files '
'can be xlsx or csv')
ARGS = ARG_PARSER.parse_args()
main(ARGS.in_dir, ARGS.out_dir, ARGS.iteration, ARGS.prj_name,
ARGS.block_device, ARGS.network_device, ARGS.test, ARGS.file_extension)
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Copyright (c) 2020 Huawei Technologies Co., Ltd.
# A-Tune is licensed under the Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
# http://license.coscl.org.cn/MulanPSL2
# 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 v2 for more details.
# Create: 2020-07-30
"""
translate .csv file to .yaml files
"""
import csv
from translate_yaml import TranslateYaml
class TranslateCsv2Yaml(TranslateYaml):
"""
The subclass for translating csv to .yaml files
"""
def __init__(self, in_file_name, out_file_name, project_name,
iterations, block_dev, network_dev, test):
super(TranslateCsv2Yaml, self).__init__(out_file_name, project_name,
iterations, block_dev, network_dev, test)
with open(in_file_name) as file:
reader = csv.reader(file)
self.rows = list(reader)
@staticmethod
def read_line(reader, line):
"""
Get a line from csv into list.
:param reader: the content of the csv to be read.
:param line: the number of line to get.
:return: list, the yaml object.
"""
obj_list = []
if line >= len(reader):
return obj_list
name_ = reader[line][1]
if name_ is None or name_.strip() == "":
return obj_list
for col in range(1, 14):
val = reader[line][col]
if val is None:
val = ''
obj_list.append(str(val))
return obj_list
def translate(self):
"""
Translate csv to yaml.
:return: True or False, translation result.
"""
line = 1
return self.write_yaml(self.rows, line)
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Copyright (c) 2020 Huawei Technologies Co., Ltd.
# A-Tune is licensed under the Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
# http://license.coscl.org.cn/MulanPSL2
# 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 v2 for more details.
# Create: 2020-07-30
"""
translate .xlsx file to .yaml files
"""
import string
import io
import openpyxl
from translate_yaml import TranslateYaml
class TranslateXlsx2Yaml(TranslateYaml):
"""
The subclass for translating xlsx to .yaml files
"""
def __init__(self, in_file_name, out_file_name, project_name,
iterations, block_dev, network_dev, test):
super(TranslateXlsx2Yaml, self).__init__(out_file_name, project_name,
iterations, block_dev, network_dev, test)
with open(in_file_name, 'rb') as file:
in_mem_file = io.BytesIO(file.read())
self.workbook = openpyxl.load_workbook(in_mem_file, read_only=True)
@staticmethod
def read_line(reader, line):
"""
Get a line from xlsx into list.
:param reader: the content of the xlsx to be read.
:param line: the number of line to get.
:return: list, the yaml object.
"""
obj_list = []
name_ = reader[str('B' + str(line))].value
if name_ is None or name_.strip() == "":
return obj_list
cols = string.ascii_uppercase[1:15]
for col in cols:
val = reader[str(col + str(line))].value
if val is None:
val = ''
obj_list.append(str(val))
return obj_list
def translate(self):
"""
Translate xlsx to yaml.
:return: True or False, translation result.
"""
sheetnames = self.workbook.sheetnames
worksheet = self.workbook[sheetnames[0]]
line = 2
return self.write_yaml(worksheet, line)
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Copyright (c) 2020 Huawei Technologies Co., Ltd.
# A-Tune is licensed under the Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
# http://license.coscl.org.cn/MulanPSL2
# 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 v2 for more details.
# Create: 2020-08-14
"""
translating file to .yaml files
"""
from io import StringIO
from config_attribute import ConfigAttrName, ConfigAttribute
class TranslateYaml:
"""The base class for translating file to .yaml files"""
def __init__(self, out_file_name, project_name, iterations, block_dev, network_dev, test):
"""
init TranslateYaml
:param out_file_name: the folder of output yaml files.
:param project_name: the name of the configuration project.
:param iterations: iterations of the project (> 10).
:param block_dev: the name of block device.
:param network_dev: the name of network device.
:param test: whether test the commands in file or not.
"""
self.out_file = open(out_file_name, 'w')
self.project_name = project_name
self.iterations = iterations
self.block_dev = block_dev
self.network_dev = network_dev
self.test = test
def __del__(self):
self.out_file.close()
def get_head(self):
"""
Generate the header of yaml file.
:return: string, the header of yaml file.
"""
fstr = StringIO()
fstr.write('project:' + ' \"' + self.project_name + '\"' + '\n')
fstr.write('maxiterations: ' + str(self.iterations) + '\n')
fstr.write('startworkload: \"\"\n')
fstr.write('stopworkload: \"\"\n')
fstr.write('object : \n')
return fstr.getvalue()
@staticmethod
def read_line(reader, line):
"""
Get a line into list.
:param reader: the content of the file to be read.
:param line: the number of line to get.
:return: list, the yaml object.
"""
print(reader, line)
return []
def translate(self):
"""
Translate file to yaml.
:return: True or False, translation result.
"""
print(self.project_name)
def write_yaml(self, content, line):
"""
write content to yaml.
:param content: the content written to yaml.
:param line: the line of content.
:return: True or False, translation result.
"""
self.out_file.write(self.get_head())
obj_list = self.read_line(content, line)
if not obj_list:
print("Empty workbook, stop translating %s" % self.out_file)
return False
while obj_list:
self.write_config_attr(obj_list)
line = line + 1
obj_list = self.read_line(content, line)
return True
def write_config_attr(self, obj_list):
"""
Write config attribute to yaml
:param obj_list: config attribute
:return: None
"""
is_select = obj_list[ConfigAttrName.select.value].strip()
if is_select == 'yes':
config_attr = ConfigAttribute(obj_list, self.block_dev, self.network_dev)
if self.test:
valid = config_attr.valid_test_attr()
if not valid:
return
if config_attr.name != '':
self.out_file.write(str(config_attr))
此差异已折叠。
...@@ -9,16 +9,16 @@ Category,"name ...@@ -9,16 +9,16 @@ Category,"name
(Maximum Value of the parameter)","step (Maximum Value of the parameter)","step
(Step of the parameter value)","items (Step of the parameter value)","items
(Enumerated values out of parameter values. Use "";"" to split different values)",select (whether to select the parameter),Remarks (Enumerated values out of parameter values. Use "";"" to split different values)",select (whether to select the parameter),Remarks
mariadb,mariadb.key_buffer_size,Index parameters of the myisam storage engine,cat /etc/my.cnf | grep key_buffer_size | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/key_buffer_size.*/key_buffer_size = $value/g' /etc/my.cnf,false,discrete,,int,1048576?,536870912,1048576?,,yes, mariadb,mariadb.key_buffer_size,Index parameters of the myisam storage engine,cat /etc/my.cnf | grep key_buffer_size | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/key_buffer_size.*/key_buffer_size = $value/g' /etc/my.cnf,FALSE,discrete,,int,1048576,536870912,1048576,,yes,
,mariadb.max_allowed_packet,Maximum number of received packets,cat /etc/my.cnf | grep max_allowed_packet | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/max_allowed_packet.*/max_allowed_packet = $value/g' /etc/my.cnf,false,discrete,,int,1048576?,1048576?00,1048576?,,yes, ,mariadb.max_allowed_packet,Maximum number of received packets,cat /etc/my.cnf | grep max_allowed_packet | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/max_allowed_packet.*/max_allowed_packet = $value/g' /etc/my.cnf,FALSE,discrete,,int,1048576,104857600,1048576,,yes,
,mariadb.table_open_cache,Table cache for storing data,cat /etc/my.cnf | grep table_open_cache | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/table_open_cache.*/table_open_cache = $value/g' /etc/my.cnf,false,discrete,,int,16,1000000,2,,yes, ,mariadb.table_open_cache,Table cache for storing data,cat /etc/my.cnf | grep table_open_cache | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/table_open_cache.*/table_open_cache = $value/g' /etc/my.cnf,FALSE,discrete,,int,16,1000000,2,,yes,
,mariadb.back_log,The number of new requests stored in the stack,cat /etc/my.cnf | grep back_log | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/back_log.*/back_log = $value/g' /etc/my.cnf,false,continuous,,int,16,65536,,,yes, ,mariadb.back_log,The number of new requests stored in the stack,cat /etc/my.cnf | grep back_log | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/back_log.*/back_log = $value/g' /etc/my.cnf,FALSE,continuous,,int,16,65536,,,yes,
,mariadb.sort_buffer_size,Cache used for sorting,cat /etc/my.cnf | grep sort_buffer_size | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/sort_buffer_size.*/sort_buffer_size = $value/g' /etc/my.cnf,false,discrete,,int,256,1048576?00,1024,,yes, ,mariadb.sort_buffer_size,Cache used for sorting,cat /etc/my.cnf | grep sort_buffer_size | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/sort_buffer_size.*/sort_buffer_size = $value/g' /etc/my.cnf,FALSE,discrete,,int,256,104857600,1024,,yes,
,mariadb.read_buffer_size,the buffer allocated to each thread during sequential table scanning.,cat /etc/my.cnf | grep read_buffer_size | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/read_buffer_size.*/read_buffer_size = $value/g' /etc/my.cnf,false,discrete,,int,1024,1048576?00,1024,,yes, ,mariadb.read_buffer_size,the buffer allocated to each thread during sequential table scanning.,cat /etc/my.cnf | grep read_buffer_size | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/read_buffer_size.*/read_buffer_size = $value/g' /etc/my.cnf,FALSE,discrete,,int,1024,104857600,1024,,yes,
,mariadb.read_rnd_buffer_size,the buffer allocated to each thread when the table is read randomly,cat /etc/my.cnf | grep read_rnd_buffer_size | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/read_rnd_buffer_size.*/read_rnd_buffer_size = $value/g' /etc/my.cnf,false,discrete,,int,1024,1048576?00,1024,,yes, ,mariadb.read_rnd_buffer_size,the buffer allocated to each thread when the table is read randomly,cat /etc/my.cnf | grep read_rnd_buffer_size | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/read_rnd_buffer_size.*/read_rnd_buffer_size = $value/g' /etc/my.cnf,FALSE,discrete,,int,1024,104857600,1024,,yes,
,mariadb.myisam_sort_buffer_size,the buffer required for reordering when the MyISAM table changes,cat /etc/my.cnf | grep myisam_sort_buffer_size | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/myisam_sort_buffer_size.*/myisam_sort_buffer_size = $value/g' /etc/my.cnf,false,discrete,,int,1024,1048576?00,1024,,yes, ,mariadb.myisam_sort_buffer_size,the buffer required for reordering when the MyISAM table changes,cat /etc/my.cnf | grep myisam_sort_buffer_size | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/myisam_sort_buffer_size.*/myisam_sort_buffer_size = $value/g' /etc/my.cnf,FALSE,discrete,,int,1024,104857600,1024,,yes,
,mariadb.thread_cache_size,Number of threads saved in the cache that are reused,cat /etc/my.cnf | grep thread_cache_size | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/thread_cache_size.*/thread_cache_size = $value/g' /etc/my.cnf,false,continuous,,int,8,1000,,,yes, ,mariadb.thread_cache_size,Number of threads saved in the cache that are reused,cat /etc/my.cnf | grep thread_cache_size | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/thread_cache_size.*/thread_cache_size = $value/g' /etc/my.cnf,FALSE,continuous,,int,8,1000,,,yes,
,mariadb.max_connections,the max number of connections,cat /etc/my.cnf | grep max_connections | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/max_connections.*/max_connections = $value/g' /etc/my.cnf,false,continuous,,int,10,65536,,,yes, ,mariadb.max_connections,the max number of connections,cat /etc/my.cnf | grep max_connections | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/max_connections.*/max_connections = $value/g' /etc/my.cnf,FALSE,continuous,,int,10,65536,,,yes,
,mariadb.max_heap_table_size,size of a memory table that can be created,cat /etc/my.cnf | grep max_heap_table_size | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/max_heap_table_size.*/max_heap_table_size = $value/g' /etc/my.cnf,false,discrete,,int,1024,1048576?00,1024,,yes, ,mariadb.max_heap_table_size,size of a memory table that can be created,cat /etc/my.cnf | grep max_heap_table_size | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/max_heap_table_size.*/max_heap_table_size = $value/g' /etc/my.cnf,FALSE,discrete,,int,1024,104857600,1024,,yes,
,mariadb.innodb_buffer_pool_size,size of innodb buffer pool,cat /etc/my.cnf | grep innodb_buffer_pool_size | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/innodb_buffer_pool_size.*/innodb_buffer_pool_size = $value/g' /etc/my.cnf,false,discrete,,int,1024,137438953472?,1024,,yes, ,mariadb.innodb_buffer_pool_size,size of innodb buffer pool,cat /etc/my.cnf | grep innodb_buffer_pool_size | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/innodb_buffer_pool_size.*/innodb_buffer_pool_size = $value/g' /etc/my.cnf,FALSE,discrete,,int,1024,1.37E+11,1024,,yes,
,mariadb.innodb_log_buffer_size,size of innodb log buffer,cat /etc/my.cnf | grep innodb_log_buffer_size | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/innodb_log_buffer_size.*/innodb_log_buffer_size = $value/g' /etc/my.cnf,false,discrete,,int,1048576?,1048576?00,1048576?,,yes, ,mariadb.innodb_log_buffer_size,size of innodb log buffer,cat /etc/my.cnf | grep innodb_log_buffer_size | awk -F '=' '{print $2}' | awk '$1=$1',sed -i 's/innodb_log_buffer_size.*/innodb_log_buffer_size = $value/g' /etc/my.cnf,FALSE,discrete,,int,1048576,104857600,1048576,,yes,
此差异已折叠。
...@@ -12,9 +12,9 @@ object : ...@@ -12,9 +12,9 @@ object :
needrestart : "false" needrestart : "false"
type : "discrete" type : "discrete"
scope : scope :
- 1,048,576‬ - 1048576
- 536870912 - 536870912
step : 1,048,576‬ step : 1048576
items : items :
dtype : "int" dtype : "int"
- -
...@@ -26,9 +26,9 @@ object : ...@@ -26,9 +26,9 @@ object :
needrestart : "false" needrestart : "false"
type : "discrete" type : "discrete"
scope : scope :
- 1,048,576‬ - 1048576
- 1,048,576‬00 - 104857600
step : 1,048,576‬ step : 1048576
items : items :
dtype : "int" dtype : "int"
- -
...@@ -67,7 +67,7 @@ object : ...@@ -67,7 +67,7 @@ object :
type : "discrete" type : "discrete"
scope : scope :
- 256 - 256
- 1,048,576‬00 - 104857600
step : 1024 step : 1024
items : items :
dtype : "int" dtype : "int"
...@@ -81,7 +81,7 @@ object : ...@@ -81,7 +81,7 @@ object :
type : "discrete" type : "discrete"
scope : scope :
- 1024 - 1024
- 1,048,576‬00 - 104857600
step : 1024 step : 1024
items : items :
dtype : "int" dtype : "int"
...@@ -95,7 +95,7 @@ object : ...@@ -95,7 +95,7 @@ object :
type : "discrete" type : "discrete"
scope : scope :
- 1024 - 1024
- 1,048,576‬00 - 104857600
step : 1024 step : 1024
items : items :
dtype : "int" dtype : "int"
...@@ -109,7 +109,7 @@ object : ...@@ -109,7 +109,7 @@ object :
type : "discrete" type : "discrete"
scope : scope :
- 1024 - 1024
- 1,048,576‬00 - 104857600
step : 1024 step : 1024
items : items :
dtype : "int" dtype : "int"
...@@ -147,7 +147,7 @@ object : ...@@ -147,7 +147,7 @@ object :
type : "discrete" type : "discrete"
scope : scope :
- 1024 - 1024
- 1,048,576‬00 - 104857600
step : 1024 step : 1024
items : items :
dtype : "int" dtype : "int"
...@@ -161,7 +161,7 @@ object : ...@@ -161,7 +161,7 @@ object :
type : "discrete" type : "discrete"
scope : scope :
- 1024 - 1024
- 137,438,953,472‬ - 1.37E+11
step : 1024 step : 1024
items : items :
dtype : "int" dtype : "int"
...@@ -174,8 +174,8 @@ object : ...@@ -174,8 +174,8 @@ object :
needrestart : "false" needrestart : "false"
type : "discrete" type : "discrete"
scope : scope :
- 1,048,576‬ - 1048576
- 1,048,576‬00 - 104857600
step : 1,048,576‬ step : 1048576
items : items :
dtype : "int" dtype : "int"
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册