mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-29 04:57:52 +00:00
[#3287] fix pylint warnings
- C0115: Missing class docstring (missing-class-docstring) - C0123: Use isinstance() rather than type() for a typecheck. (unidiomatic-typecheck) - C0201: Consider iterating the dictionary directly instead of calling .keys() (consider-iterating-dictionary) - C0206: Consider iterating with .items() (consider-using-dict-items) - C0411: standard import "..." should be placed before "..." (wrong-import-order) - C0415: Import outside toplevel (...) (import-outside-toplevel) - C1802: Do not use `len(SEQUENCE)` without comparison to determine if a sequence is empty (use-implicit-booleaness-not-len) - E0001: Parsing failed: 'invalid syntax (<unknown>, line 2313)' (syntax-error) - E0401: Unable to import '...' (import-error) - E0602: Undefined variable 'l' (undefined-variable) - R0205: Class 'VagrantEnv' inherits from object, can be safely removed from bases in python3 (useless-object-inheritance) - E1101: Instance of 'NSECBASE' has no 'dump_fixedpart' member (no-member) - E1123: Unexpected keyword argument 'capture' in method call (unexpected-keyword-arg) - R0902: Too many instance attributes (too-many-instance-attributes) - R0913: Too many arguments (too-many-arguments) - R0916: Too many boolean expressions in if statement (6/5) (too-many-boolean-expressions) - R1717: Consider using a dictionary comprehension (consider-using-dict-comprehension) - R1722: Consider using 'sys.exit' instead (consider-using-sys-exit) - R1732: Consider using 'with' for resource-allocating operations (consider-using-with) - R1735: Consider using '{}' instead of a call to 'dict'. (use-dict-literal) - W0102: Dangerous default value sys.argv[1:] (builtins.list) as argument (dangerous-default-value) - W0102: Dangerous default value {} as argument (dangerous-default-value) - W0106: Expression "[f.write('%02x' % x) for x in bin_address]" is assigned to nothing (expression-not-assigned) - W0107: Unnecessary pass statement (unnecessary-pass) - W0201: Attribute 'config' defined outside __init__ (attribute-defined-outside-init) - W0404: Reimport '...' (imported line ...) (reimported) - W0611: Unused import ... (unused-import) - W0612: Unused variable '...' (unused-variable) - W0613: Unused argument '...' (unused-argument) - W0621: Redefining name '...' from outer scope (line 1471) (redefined-outer-name) - W0622: Redefining built-in '...' (redefined-builtin) - W0707: Consider explicitly re-raising using 'raise ... from ...' (raise-missing-from) - W0718: Catching too general exception Exception (broad-exception-caught) - W1202: Use lazy % formatting in logging functions (logging-format-interpolation) - W1203: Use lazy % formatting in logging functions (logging-fstring-interpolation) - W1308: Duplicate string formatting argument 'connection_type', consider passing as named argument (duplicate-string-formatting-argument) - W1401: Anomalous backslash in string: '\/'. String constant might be missing an r prefix. (anomalous-backslash-in-string) - W1406: The u prefix for strings is no longer necessary in Python >=3.0 (redundant-u-string-prefix) - W1514: Using open without explicitly specifying an encoding (unspecified-encoding) - W4901: Deprecated module 'optparse' (deprecated-module) - W4904: Using deprecated class SafeConfigParser of module configparser (deprecated-class)
This commit is contained in:
parent
8e37580e59
commit
9c35a4db68
@ -33,7 +33,7 @@ def read_input_files(files):
|
|||||||
if name.startswith('_'):
|
if name.startswith('_'):
|
||||||
print("Skipping %s (starts with underscore)" % f)
|
print("Skipping %s (starts with underscore)" % f)
|
||||||
continue
|
continue
|
||||||
with open(f) as fp:
|
with open(f, encoding='utf-8') as fp:
|
||||||
print("Processing %s" % f)
|
print("Processing %s" % f)
|
||||||
# use OrderedDict to preserve order of fields in cmd-syntax
|
# use OrderedDict to preserve order of fields in cmd-syntax
|
||||||
try:
|
try:
|
||||||
@ -42,7 +42,7 @@ def read_input_files(files):
|
|||||||
print(f'\nError while processing {f}: {e}\n\n')
|
print(f'\nError while processing {f}: {e}\n\n')
|
||||||
raise
|
raise
|
||||||
if name != descr['name']:
|
if name != descr['name']:
|
||||||
exit("Expected name == descr['name'], but name is {name} and descr['name'] is {descr['name']}")
|
raise ValueError("Expected name == descr['name']. Name is {name} and descr['name'] is {descr['name']}.")
|
||||||
|
|
||||||
apis[name] = descr
|
apis[name] = descr
|
||||||
|
|
||||||
@ -196,7 +196,7 @@ def generate(in_files, out_file):
|
|||||||
rst = generate_rst(apis)
|
rst = generate_rst(apis)
|
||||||
|
|
||||||
if out_file:
|
if out_file:
|
||||||
with open(out_file, 'w') as f:
|
with open(out_file, 'w', encoding='utf-8') as f:
|
||||||
f.write(rst)
|
f.write(rst)
|
||||||
print('Wrote generated RST content to: %s' % out_file)
|
print('Wrote generated RST content to: %s' % out_file)
|
||||||
else:
|
else:
|
||||||
|
@ -6,31 +6,35 @@
|
|||||||
# full list see the documentation:
|
# full list see the documentation:
|
||||||
# http://www.sphinx-doc.org/en/master/config
|
# http://www.sphinx-doc.org/en/master/config
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from shutil import copyfile
|
||||||
|
|
||||||
# -- Path setup --------------------------------------------------------------
|
# -- Path setup --------------------------------------------------------------
|
||||||
|
|
||||||
|
# to avoid sphinx.errors.SphinxParallelError: RecursionError: maximum recursion depth exceeded while pickling an object
|
||||||
|
sys.setrecursionlimit(5000)
|
||||||
|
|
||||||
# If extensions (or modules to document with autodoc) are in another directory,
|
# If extensions (or modules to document with autodoc) are in another directory,
|
||||||
# add these directories to sys.path here. If the directory is relative to the
|
# add these directories to sys.path here. If the directory is relative to the
|
||||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||||
#
|
SRC_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||||
import os
|
sys.path.append(SRC_DIR)
|
||||||
# import sys
|
|
||||||
# sys.path.insert(0, os.path.abspath('.'))
|
|
||||||
|
|
||||||
# to avoid sphinx.errors.SphinxParallelError: RecursionError: maximum recursion depth exceeded while pickling an object
|
import api2doc # noqa # pylint: disable=wrong-import-position
|
||||||
import sys
|
import mes2doc # noqa # pylint: disable=wrong-import-position
|
||||||
sys.setrecursionlimit(5000)
|
|
||||||
|
|
||||||
# -- Project information -----------------------------------------------------
|
# -- Project information -----------------------------------------------------
|
||||||
|
|
||||||
project = 'Kea'
|
project = 'Kea'
|
||||||
copyright = '2019-2024, Internet Systems Consortium'
|
copyright = '2019-2024, Internet Systems Consortium' # pylint: disable=redefined-builtin
|
||||||
author = 'Internet Systems Consortium'
|
author = 'Internet Systems Consortium'
|
||||||
|
|
||||||
# get current kea version
|
# get current kea version
|
||||||
config_ac_path = '../../configure.ac'
|
config_ac_path = '../../configure.ac'
|
||||||
changelog_path = '../../ChangeLog'
|
changelog_path = '../../ChangeLog'
|
||||||
release = 'UNRELEASED'
|
release = 'UNRELEASED'
|
||||||
with open(config_ac_path) as f:
|
with open(config_ac_path, encoding='utf-8') as f:
|
||||||
for line in f.readlines():
|
for line in f.readlines():
|
||||||
if line.startswith('AC_INIT(kea'):
|
if line.startswith('AC_INIT(kea'):
|
||||||
parts = line.split(',')
|
parts = line.split(',')
|
||||||
@ -39,7 +43,7 @@ with open(config_ac_path) as f:
|
|||||||
# that this is the final release.
|
# that this is the final release.
|
||||||
dash_parts = release.split('-')
|
dash_parts = release.split('-')
|
||||||
candidate_release = dash_parts[0]
|
candidate_release = dash_parts[0]
|
||||||
with open(changelog_path) as changelog_file:
|
with open(changelog_path, encoding='utf-8') as changelog_file:
|
||||||
first_line = changelog_file.readline()
|
first_line = changelog_file.readline()
|
||||||
if candidate_release in first_line and "released" in first_line:
|
if candidate_release in first_line and "released" in first_line:
|
||||||
release = candidate_release
|
release = candidate_release
|
||||||
@ -251,23 +255,15 @@ rst_prolog = """
|
|||||||
# Do generation of api.rst and kea-messages.rst here in conf.py instead of Makefile.am
|
# Do generation of api.rst and kea-messages.rst here in conf.py instead of Makefile.am
|
||||||
# so they are available on ReadTheDocs as there makefiles are not used for building docs.
|
# so they are available on ReadTheDocs as there makefiles are not used for building docs.
|
||||||
def run_generate_docs(_):
|
def run_generate_docs(_):
|
||||||
import os
|
with open(os.path.join(SRC_DIR, 'api-files.txt'), encoding='utf-8') as af:
|
||||||
import sys
|
|
||||||
src_dir = os.path.abspath(os.path.dirname(__file__))
|
|
||||||
print(src_dir)
|
|
||||||
sys.path.append(src_dir)
|
|
||||||
|
|
||||||
import api2doc
|
|
||||||
with open(os.path.join(src_dir, 'api-files.txt')) as af:
|
|
||||||
api_files = af.read().split()
|
api_files = af.read().split()
|
||||||
api_files = [os.path.abspath(os.path.join(src_dir, '../..', af)) for af in api_files]
|
api_files = [os.path.abspath(os.path.join(SRC_DIR, '../..', af)) for af in api_files]
|
||||||
api2doc.generate(api_files, os.path.join(src_dir, 'api.rst'))
|
api2doc.generate(api_files, os.path.join(SRC_DIR, 'api.rst'))
|
||||||
|
|
||||||
import mes2doc
|
with open(os.path.join(SRC_DIR, 'mes-files.txt'), encoding='utf-8') as mf:
|
||||||
with open(os.path.join(src_dir, 'mes-files.txt')) as mf:
|
|
||||||
mes_files = mf.read().split()
|
mes_files = mf.read().split()
|
||||||
mes_files = [os.path.abspath(os.path.join(src_dir, '../..', mf)) for mf in mes_files]
|
mes_files = [os.path.abspath(os.path.join(SRC_DIR, '../..', mf)) for mf in mes_files]
|
||||||
mes2doc.generate(mes_files, os.path.join(src_dir, 'kea-messages.rst'))
|
mes2doc.generate(mes_files, os.path.join(SRC_DIR, 'kea-messages.rst'))
|
||||||
|
|
||||||
# Sphinx has some limitations. It can't import files from outside its directory, which
|
# Sphinx has some limitations. It can't import files from outside its directory, which
|
||||||
# in our case is src/sphinx. On the other hand, we need to have platforms.rst file
|
# in our case is src/sphinx. On the other hand, we need to have platforms.rst file
|
||||||
@ -292,10 +288,9 @@ def run_generate_docs(_):
|
|||||||
['../examples/template-ha-mt-tls/kea-dhcp4-2.conf', 'template-ha-mt-tls-dhcp4-2.conf']
|
['../examples/template-ha-mt-tls/kea-dhcp4-2.conf', 'template-ha-mt-tls-dhcp4-2.conf']
|
||||||
]
|
]
|
||||||
|
|
||||||
from shutil import copyfile
|
|
||||||
for [a, b] in FILES_TO_COPY:
|
for [a, b] in FILES_TO_COPY:
|
||||||
src = os.path.join(src_dir, a)
|
src = os.path.join(SRC_DIR, a)
|
||||||
dst = os.path.join(src_dir, 'arm', b)
|
dst = os.path.join(SRC_DIR, 'arm', b)
|
||||||
print("Copying %s to %s" % (src, dst))
|
print("Copying %s to %s" % (src, dst))
|
||||||
copyfile(src, dst)
|
copyfile(src, dst)
|
||||||
|
|
||||||
|
@ -36,9 +36,8 @@ def parse_args():
|
|||||||
def read_input_files(files):
|
def read_input_files(files):
|
||||||
messages = {}
|
messages = {}
|
||||||
for f in files:
|
for f in files:
|
||||||
with open(f) as fp:
|
with open(f, encoding='utf-8') as fp:
|
||||||
print("Processing %s" % f)
|
print("Processing %s" % f)
|
||||||
namespace = None
|
|
||||||
msg_descr = None
|
msg_descr = None
|
||||||
msg_id = None
|
msg_id = None
|
||||||
msg_text = None
|
msg_text = None
|
||||||
@ -119,7 +118,7 @@ def generate(in_files, out_file):
|
|||||||
rst = generate_rst(messages)
|
rst = generate_rst(messages)
|
||||||
|
|
||||||
if out_file:
|
if out_file:
|
||||||
with open(out_file, 'w') as f:
|
with open(out_file, 'w', encoding='utf-8') as f:
|
||||||
f.write(rst)
|
f.write(rst)
|
||||||
print('Wrote generated RST content to: %s' % out_file)
|
print('Wrote generated RST content to: %s' % out_file)
|
||||||
else:
|
else:
|
||||||
|
315
hammer.py
315
hammer.py
@ -6,6 +6,8 @@
|
|||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
# pylint: disable=broad-exception-caught
|
||||||
|
|
||||||
"""Hammer - Kea development environment management tool."""
|
"""Hammer - Kea development environment management tool."""
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
@ -117,10 +119,9 @@ SYSTEMS = {
|
|||||||
'3.19': True,
|
'3.19': True,
|
||||||
'3.20': True,
|
'3.20': True,
|
||||||
},
|
},
|
||||||
'arch': {}
|
'arch': {},
|
||||||
}
|
}
|
||||||
|
|
||||||
# pylint: disable=C0326
|
|
||||||
IMAGE_TEMPLATES = {
|
IMAGE_TEMPLATES = {
|
||||||
# fedora
|
# fedora
|
||||||
'fedora-27-lxc': {'bare': 'lxc-fedora-27', 'kea': 'godfryd/kea-fedora-27'},
|
'fedora-27-lxc': {'bare': 'lxc-fedora-27', 'kea': 'godfryd/kea-fedora-27'},
|
||||||
@ -276,52 +277,37 @@ def get_system_revision():
|
|||||||
system = platform.system()
|
system = platform.system()
|
||||||
if system == 'Linux':
|
if system == 'Linux':
|
||||||
system, revision = None, None
|
system, revision = None, None
|
||||||
try:
|
if not os.path.exists('/etc/os-release'):
|
||||||
system, revision, _ = platform.dist() # pylint: disable=deprecated-method
|
raise UnexpectedError('/etc/os-release does not exist. Cannot determine system or its revision.')
|
||||||
if system == 'debian':
|
vals = {}
|
||||||
revision = revision.split('.')[0]
|
with open('/etc/os-release', encoding='utf-8') as f:
|
||||||
elif system == 'redhat':
|
for line in f.readlines():
|
||||||
system = 'rhel'
|
if '=' in line:
|
||||||
revision = revision[0]
|
key, val = line.split('=', 1)
|
||||||
elif system == 'rocky':
|
vals[key.strip()] = val.strip().replace('"', '')
|
||||||
revision = revision[0]
|
|
||||||
elif system == 'centos':
|
|
||||||
revision = revision[0]
|
|
||||||
if not system or not revision:
|
|
||||||
raise Exception('fallback to /etc/os-release')
|
|
||||||
except Exception:
|
|
||||||
if os.path.exists('/etc/os-release'):
|
|
||||||
vals = {}
|
|
||||||
with open('/etc/os-release') as f:
|
|
||||||
for line in f.readlines():
|
|
||||||
if '=' in line:
|
|
||||||
key, val = line.split('=', 1)
|
|
||||||
vals[key.strip()] = val.strip().replace('"', '')
|
|
||||||
|
|
||||||
for i in ['ID', 'ID_LIKE']:
|
for i in ['ID', 'ID_LIKE']:
|
||||||
if i in vals:
|
if i in vals:
|
||||||
system_candidates = vals[i].strip('"').split()
|
system_candidates = vals[i].strip('"').split()
|
||||||
for system_candidate in system_candidates:
|
for system_candidate in system_candidates:
|
||||||
if system_candidate in SYSTEMS:
|
if system_candidate in SYSTEMS:
|
||||||
system = system_candidate
|
system = system_candidate
|
||||||
break
|
|
||||||
else:
|
|
||||||
continue
|
|
||||||
break
|
break
|
||||||
if system is None:
|
else:
|
||||||
raise Exception('cannot determine system')
|
continue
|
||||||
|
break
|
||||||
|
if system is None:
|
||||||
|
raise UnexpectedError('cannot determine system')
|
||||||
|
|
||||||
for i in ['VERSION_ID', 'BUILD_ID']:
|
for i in ['VERSION_ID', 'BUILD_ID']:
|
||||||
if i in vals:
|
if i in vals:
|
||||||
revision = vals[i]
|
revision = vals[i]
|
||||||
break
|
break
|
||||||
if revision is None:
|
if revision is None:
|
||||||
raise Exception('cannot determine revision')
|
raise UnexpectedError('cannot determine revision')
|
||||||
|
|
||||||
if system in ['alpine', 'rhel', 'rocky']:
|
if system in ['alpine', 'rhel', 'rocky']:
|
||||||
revision = revision.rsplit('.', 1)[0]
|
revision = revision.rsplit('.', 1)[0]
|
||||||
else:
|
|
||||||
raise Exception('cannot determine system or its revision')
|
|
||||||
elif system == 'FreeBSD':
|
elif system == 'FreeBSD':
|
||||||
system = system.lower()
|
system = system.lower()
|
||||||
revision = platform.release()
|
revision = platform.release()
|
||||||
@ -336,7 +322,10 @@ def get_system_revision():
|
|||||||
|
|
||||||
class ExecutionError(Exception):
|
class ExecutionError(Exception):
|
||||||
"""Exception thrown when execution encountered an error."""
|
"""Exception thrown when execution encountered an error."""
|
||||||
pass
|
|
||||||
|
|
||||||
|
class UnexpectedError(Exception):
|
||||||
|
"""Exception thrown when an unexpected error occurred that hammer does not know how to recover from."""
|
||||||
|
|
||||||
|
|
||||||
def execute(cmd, timeout=60, cwd=None, env=None, raise_error=True, dry_run=False, log_file_path=None,
|
def execute(cmd, timeout=60, cwd=None, env=None, raise_error=True, dry_run=False, log_file_path=None,
|
||||||
@ -379,57 +368,43 @@ def execute(cmd, timeout=60, cwd=None, env=None, raise_error=True, dry_run=False
|
|||||||
cmd = cmd.replace('sudo', 'sudo -E')
|
cmd = cmd.replace('sudo', 'sudo -E')
|
||||||
|
|
||||||
if log_file_path:
|
if log_file_path:
|
||||||
log_file = open(log_file_path, "wb")
|
with open(log_file_path, "wb", encoding='utf-8') as file:
|
||||||
|
log_file = file.read()
|
||||||
|
|
||||||
for attempt in range(attempts):
|
for attempt in range(attempts):
|
||||||
if interactive:
|
if interactive:
|
||||||
# Issue: [B602:subprocess_popen_with_shell_equals_true] subprocess call with shell=True identified,
|
# Issue: [B602:subprocess_popen_with_shell_equals_true] subprocess call with shell=True identified,
|
||||||
# security issue.
|
# security issue.
|
||||||
p = subprocess.Popen(cmd, cwd=cwd, env=env, shell=True) # nosec B602
|
with subprocess.Popen(cmd, cwd=cwd, env=env, shell=True) as pipe: # nosec: B602
|
||||||
exitcode = p.wait()
|
pipe.communicate()
|
||||||
|
exitcode = pipe.returncode
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Issue: [B602:subprocess_popen_with_shell_equals_true] subprocess call with shell=True identified,
|
# Issue: [B602:subprocess_popen_with_shell_equals_true] subprocess call with shell=True identified,
|
||||||
# security issue.
|
# security issue.
|
||||||
p = subprocess.Popen(cmd, cwd=cwd, env=env, shell=True, # nosec B602
|
with subprocess.Popen(cmd, cwd=cwd, env=env, shell=True, # nosec: B602
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as pipe:
|
||||||
|
if timeout is not None:
|
||||||
if capture:
|
pipe.wait(timeout)
|
||||||
output = ''
|
try:
|
||||||
t0 = time.time()
|
stdout, _ = pipe.communicate()
|
||||||
# Repeat until the process has stopped and there are no more lines
|
except subprocess.TimeoutExpired as e:
|
||||||
# to read, or until the timeout is up.
|
pipe.kill()
|
||||||
while True:
|
stdout2, _ = pipe.communicate()
|
||||||
line = p.stdout.readline()
|
stdout += stdout2
|
||||||
if line:
|
raise ExecutionError(f'Execution timeout: {e}, cmd: {cmd}') from e
|
||||||
line_decoded = line.decode(encoding='ascii', errors='ignore').rstrip() + '\r'
|
exitcode = pipe.returncode
|
||||||
if not quiet:
|
if capture:
|
||||||
log.info(line_decoded)
|
output = stdout.decode('utf-8')
|
||||||
if capture:
|
if not quiet:
|
||||||
output += line_decoded
|
print(stdout.decode('utf-8'))
|
||||||
if log_file_path:
|
if log_file_path is not None:
|
||||||
log_file.write(line)
|
log_file.write(stdout)
|
||||||
t1 = time.time()
|
|
||||||
if p.poll() is not None and not line or (timeout is not None and timeout < t1 - t0):
|
|
||||||
break
|
|
||||||
|
|
||||||
# If no exitcode yet, ie. process is still running then it means that timeout occurred.
|
|
||||||
# In such case terminate the process and raise an exception.
|
|
||||||
if p.poll() is None:
|
|
||||||
# kill using sudo to be able to kill other sudo commands
|
|
||||||
execute('sudo kill -s TERM %s' % p.pid)
|
|
||||||
time.sleep(5)
|
|
||||||
# if still running, kill harder
|
|
||||||
if p.poll() is None:
|
|
||||||
execute('sudo kill -s KILL %s' % p.pid)
|
|
||||||
msg = "Execution timeout, %d > %d seconds elapsed (start: %d, stop %d), cmd: '%s'"
|
|
||||||
msg = msg % (t1 - t0, timeout, t0, t1, cmd)
|
|
||||||
raise ExecutionError(msg)
|
|
||||||
exitcode = p.returncode
|
|
||||||
|
|
||||||
if exitcode == 0:
|
if exitcode == 0:
|
||||||
break
|
break
|
||||||
elif attempt < attempts - 1:
|
|
||||||
|
if attempt < attempts - 1:
|
||||||
txt = 'command failed, retry, attempt %d/%d' % (attempt, attempts)
|
txt = 'command failed, retry, attempt %d/%d' % (attempt, attempts)
|
||||||
if log_file_path:
|
if log_file_path:
|
||||||
txt_to_file = '\n\n[HAMMER] %s\n\n\n' % txt
|
txt_to_file = '\n\n[HAMMER] %s\n\n\n' % txt
|
||||||
@ -468,7 +443,12 @@ def _prepare_installed_packages_cache_for_debs():
|
|||||||
continue
|
continue
|
||||||
status, name, version, arch, descr = m.groups()
|
status, name, version, arch, descr = m.groups()
|
||||||
name = name.split(':')[0]
|
name = name.split(':')[0]
|
||||||
pkg_cache[name] = dict(status=status, version=version, arch=arch, descr=descr)
|
pkg_cache[name] = {
|
||||||
|
'status': status,
|
||||||
|
'version': version,
|
||||||
|
'arch': arch,
|
||||||
|
'descr': descr,
|
||||||
|
}
|
||||||
|
|
||||||
return pkg_cache
|
return pkg_cache
|
||||||
|
|
||||||
@ -480,7 +460,7 @@ def _prepare_installed_packages_cache_for_rpms():
|
|||||||
|
|
||||||
for line in out.splitlines():
|
for line in out.splitlines():
|
||||||
name = line.strip()
|
name = line.strip()
|
||||||
pkg_cache[name] = dict(status='ii')
|
pkg_cache[name] = {'status': 'ii'}
|
||||||
|
|
||||||
return pkg_cache
|
return pkg_cache
|
||||||
|
|
||||||
@ -492,7 +472,7 @@ def _prepare_installed_packages_cache_for_alpine():
|
|||||||
|
|
||||||
for line in out.splitlines():
|
for line in out.splitlines():
|
||||||
name = line.strip()
|
name = line.strip()
|
||||||
pkg_cache[name] = dict(status='ii')
|
pkg_cache[name] = {'status': 'ii'}
|
||||||
|
|
||||||
return pkg_cache
|
return pkg_cache
|
||||||
|
|
||||||
@ -575,7 +555,7 @@ def get_image_template(key, variant):
|
|||||||
return IMAGE_TEMPLATES[key][variant]
|
return IMAGE_TEMPLATES[key][variant]
|
||||||
|
|
||||||
|
|
||||||
def _get_full_repo_url(repository_url, system, revision, pkg_version):
|
def _get_full_repo_url(repository_url, system, revision):
|
||||||
if not repository_url:
|
if not repository_url:
|
||||||
return None
|
return None
|
||||||
repo_name = 'kea-%s-%s' % (system, revision)
|
repo_name = 'kea-%s-%s' % (system, revision)
|
||||||
@ -584,7 +564,7 @@ def _get_full_repo_url(repository_url, system, revision, pkg_version):
|
|||||||
return repo_url
|
return repo_url
|
||||||
|
|
||||||
|
|
||||||
class VagrantEnv(object):
|
class VagrantEnv():
|
||||||
"""Helper class that makes interacting with Vagrant easier.
|
"""Helper class that makes interacting with Vagrant easier.
|
||||||
|
|
||||||
It creates Vagrantfile according to specified system. It exposes basic Vagrant functions
|
It creates Vagrantfile according to specified system. It exposes basic Vagrant functions
|
||||||
@ -619,7 +599,7 @@ class VagrantEnv(object):
|
|||||||
self.python = None
|
self.python = None
|
||||||
|
|
||||||
self.key = key = "%s-%s-%s" % (system, revision, provider)
|
self.key = key = "%s-%s-%s" % (system, revision, provider)
|
||||||
self.image_tpl = image_tpl = get_image_template(key, image_template_variant)
|
self.image_tpl = get_image_template(key, image_template_variant)
|
||||||
self.repo_dir = os.getcwd()
|
self.repo_dir = os.getcwd()
|
||||||
|
|
||||||
sys_dir = "%s-%s" % (system, revision)
|
sys_dir = "%s-%s" % (system, revision)
|
||||||
@ -670,7 +650,7 @@ class VagrantEnv(object):
|
|||||||
box_version=box_version,
|
box_version=box_version,
|
||||||
hostname=hostname)
|
hostname=hostname)
|
||||||
|
|
||||||
with open(vagrantfile_path, "w") as f:
|
with open(vagrantfile_path, "w", encoding='utf-8') as f:
|
||||||
f.write(vagrantfile)
|
f.write(vagrantfile)
|
||||||
|
|
||||||
log.info('Prepared vagrant system %s in %s', self.name, self.vagrant_dir)
|
log.info('Prepared vagrant system %s in %s', self.name, self.vagrant_dir)
|
||||||
@ -706,7 +686,7 @@ class VagrantEnv(object):
|
|||||||
with urllib.request.urlopen(url) as response: # nosec B310
|
with urllib.request.urlopen(url) as response: # nosec B310
|
||||||
data = response.read()
|
data = response.read()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.exception(f'ignored exception: {e}')
|
log.exception('ignored exception: %s', e)
|
||||||
return {}
|
return {}
|
||||||
data = json.loads(data)
|
data = json.loads(data)
|
||||||
return data
|
return data
|
||||||
@ -715,7 +695,7 @@ class VagrantEnv(object):
|
|||||||
meta_file = os.path.join(self.vagrant_dir, '.vagrant/machines/default', self.provider, 'box_meta')
|
meta_file = os.path.join(self.vagrant_dir, '.vagrant/machines/default', self.provider, 'box_meta')
|
||||||
if not os.path.exists(meta_file):
|
if not os.path.exists(meta_file):
|
||||||
return {}
|
return {}
|
||||||
with open(meta_file) as f:
|
with open(meta_file, encoding='utf-8') as f:
|
||||||
data = f.read()
|
data = f.read()
|
||||||
data = json.loads(data)
|
data = json.loads(data)
|
||||||
return data
|
return data
|
||||||
@ -751,7 +731,7 @@ class VagrantEnv(object):
|
|||||||
_, out = execute("vagrant status", cwd=self.vagrant_dir, timeout=15, capture=True, quiet=True)
|
_, out = execute("vagrant status", cwd=self.vagrant_dir, timeout=15, capture=True, quiet=True)
|
||||||
m = re.search(r'default\s+(.+)\(', out)
|
m = re.search(r'default\s+(.+)\(', out)
|
||||||
if not m:
|
if not m:
|
||||||
raise Exception('cannot get status in:\n%s' % out)
|
raise UnexpectedError('cannot get status in:\n%s' % out)
|
||||||
return m.group(1).strip()
|
return m.group(1).strip()
|
||||||
|
|
||||||
def bring_up_latest_box(self):
|
def bring_up_latest_box(self):
|
||||||
@ -813,7 +793,7 @@ class VagrantEnv(object):
|
|||||||
# correct files ownership
|
# correct files ownership
|
||||||
execute('sudo chown `id -un`:`id -gn` *', cwd=lxc_box_dir)
|
execute('sudo chown `id -un`:`id -gn` *', cwd=lxc_box_dir)
|
||||||
# and other metadata
|
# and other metadata
|
||||||
with open(os.path.join(lxc_box_dir, 'metadata.json'), 'w') as f:
|
with open(os.path.join(lxc_box_dir, 'metadata.json'), 'w', encoding='utf-8') as f:
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
f.write('{\n')
|
f.write('{\n')
|
||||||
f.write(' "provider": "lxc",\n')
|
f.write(' "provider": "lxc",\n')
|
||||||
@ -906,7 +886,7 @@ class VagrantEnv(object):
|
|||||||
execute('scp -F %s -r default:~/kea-pkg/* .' % ssh_cfg_path, cwd=pkgs_dir)
|
execute('scp -F %s -r default:~/kea-pkg/* .' % ssh_cfg_path, cwd=pkgs_dir)
|
||||||
|
|
||||||
if upload:
|
if upload:
|
||||||
repo_url = _get_full_repo_url(repository_url, self.system, self.revision, pkg_version)
|
repo_url = _get_full_repo_url(repository_url, self.system, self.revision)
|
||||||
if repo_url is None:
|
if repo_url is None:
|
||||||
raise ValueError('repo_url is None')
|
raise ValueError('repo_url is None')
|
||||||
upload_cmd = 'curl -v --netrc -f'
|
upload_cmd = 'curl -v --netrc -f'
|
||||||
@ -957,7 +937,7 @@ class VagrantEnv(object):
|
|||||||
execute(cmd, cwd=self.vagrant_dir)
|
execute(cmd, cwd=self.vagrant_dir)
|
||||||
results_file = os.path.join(self.vagrant_dir, 'unit-test-results.json')
|
results_file = os.path.join(self.vagrant_dir, 'unit-test-results.json')
|
||||||
if os.path.exists(results_file):
|
if os.path.exists(results_file):
|
||||||
with open(results_file) as f:
|
with open(results_file, encoding='utf-8') as f:
|
||||||
txt = f.read()
|
txt = f.read()
|
||||||
results = json.loads(txt)
|
results = json.loads(txt)
|
||||||
total = results['grand_total']
|
total = results['grand_total']
|
||||||
@ -966,7 +946,7 @@ class VagrantEnv(object):
|
|||||||
cmd = 'scp -F %s -r default:/home/vagrant/aggregated_tests.xml .' % ssh_cfg_path
|
cmd = 'scp -F %s -r default:/home/vagrant/aggregated_tests.xml .' % ssh_cfg_path
|
||||||
execute(cmd, cwd=self.vagrant_dir)
|
execute(cmd, cwd=self.vagrant_dir)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.exception(f'ignored issue with parsing unit test results: {e}')
|
log.exception('ignored issue with parsing unit test results: %s', e)
|
||||||
|
|
||||||
return total, passed
|
return total, passed
|
||||||
|
|
||||||
@ -987,7 +967,7 @@ class VagrantEnv(object):
|
|||||||
execute('vagrant ssh-config > %s' % ssh_cfg_path, cwd=self.vagrant_dir)
|
execute('vagrant ssh-config > %s' % ssh_cfg_path, cwd=self.vagrant_dir)
|
||||||
return ssh_cfg_path
|
return ssh_cfg_path
|
||||||
|
|
||||||
def execute(self, cmd, timeout=None, raise_error=True, log_file_path=None, quiet=False, env=None,
|
def execute(self, cmd, timeout=None, raise_error=True, log_file_path=None, quiet=False, env=None, capture=False,
|
||||||
attempts=1, sleep_time_after_attempt=None):
|
attempts=1, sleep_time_after_attempt=None):
|
||||||
"""Execute provided command inside Vagrant system."""
|
"""Execute provided command inside Vagrant system."""
|
||||||
if not env:
|
if not env:
|
||||||
@ -996,7 +976,7 @@ class VagrantEnv(object):
|
|||||||
|
|
||||||
return execute('vagrant ssh -c "%s"' % cmd, env=env, cwd=self.vagrant_dir, timeout=timeout,
|
return execute('vagrant ssh -c "%s"' % cmd, env=env, cwd=self.vagrant_dir, timeout=timeout,
|
||||||
raise_error=raise_error, dry_run=self.dry_run, log_file_path=log_file_path,
|
raise_error=raise_error, dry_run=self.dry_run, log_file_path=log_file_path,
|
||||||
quiet=quiet, check_times=self.check_times,
|
quiet=quiet, check_times=self.check_times, capture=capture,
|
||||||
attempts=attempts, sleep_time_after_attempt=sleep_time_after_attempt)
|
attempts=attempts, sleep_time_after_attempt=sleep_time_after_attempt)
|
||||||
|
|
||||||
def prepare_system(self):
|
def prepare_system(self):
|
||||||
@ -1038,7 +1018,7 @@ class VagrantEnv(object):
|
|||||||
exitcode = self.execute(cmd, raise_error=False)
|
exitcode = self.execute(cmd, raise_error=False)
|
||||||
if exitcode != 0:
|
if exitcode != 0:
|
||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
with open(os.path.expanduser('~/rhel-creds.txt')) as f:
|
with open(os.path.expanduser('~/rhel-creds.txt'), encoding='utf-8') as f:
|
||||||
env['RHEL_USER'] = f.readline().strip()
|
env['RHEL_USER'] = f.readline().strip()
|
||||||
env['RHEL_PASSWD'] = f.readline().strip()
|
env['RHEL_PASSWD'] = f.readline().strip()
|
||||||
self.execute('sudo subscription-manager register --user $RHEL_USER --password "$RHEL_PASSWD"', env=env)
|
self.execute('sudo subscription-manager register --user $RHEL_USER --password "$RHEL_PASSWD"', env=env)
|
||||||
@ -1114,7 +1094,7 @@ def _install_gtest_sources():
|
|||||||
gtest_version = '1.14.0'
|
gtest_version = '1.14.0'
|
||||||
gtest_path = f'/usr/src/googletest-release-{gtest_version}/googletest'
|
gtest_path = f'/usr/src/googletest-release-{gtest_version}/googletest'
|
||||||
if os.path.exists(gtest_path):
|
if os.path.exists(gtest_path):
|
||||||
log.info(f'gtest is already installed in {gtest_path}.')
|
log.info('gtest is already installed in %s.', gtest_path)
|
||||||
return
|
return
|
||||||
|
|
||||||
execute('mkdir -p ~/.hammer-tmp')
|
execute('mkdir -p ~/.hammer-tmp')
|
||||||
@ -1134,7 +1114,7 @@ def _install_libyang_from_sources(ignore_errors=False):
|
|||||||
libyang_header = f'{prefix}/include/libyang/version.h'
|
libyang_header = f'{prefix}/include/libyang/version.h'
|
||||||
if (any(os.path.exists(i) for i in libyang_so_candidates) and os.path.exists(libyang_header) and
|
if (any(os.path.exists(i) for i in libyang_so_candidates) and os.path.exists(libyang_header) and
|
||||||
execute(f"grep -F '#define LY_VERSION_MAJOR 2' '{libyang_header}'", raise_error=False) == 0):
|
execute(f"grep -F '#define LY_VERSION_MAJOR 2' '{libyang_header}'", raise_error=False) == 0):
|
||||||
log.info(f'libyang is already installed at {libyang_header}.')
|
log.info('libyang is already installed at %s.', libyang_header)
|
||||||
return
|
return
|
||||||
|
|
||||||
version = 'v2.1.4'
|
version = 'v2.1.4'
|
||||||
@ -1149,7 +1129,7 @@ def _install_libyang_from_sources(ignore_errors=False):
|
|||||||
cwd='~/.hammer-tmp/libyang/build')
|
cwd='~/.hammer-tmp/libyang/build')
|
||||||
execute('make -j $(nproc || gnproc || echo 1)', cwd='~/.hammer-tmp/libyang/build')
|
execute('make -j $(nproc || gnproc || echo 1)', cwd='~/.hammer-tmp/libyang/build')
|
||||||
execute('sudo make install', cwd='~/.hammer-tmp/libyang/build')
|
execute('sudo make install', cwd='~/.hammer-tmp/libyang/build')
|
||||||
system, revision = get_system_revision()
|
system, _ = get_system_revision()
|
||||||
if system != 'alpine':
|
if system != 'alpine':
|
||||||
execute('sudo ldconfig')
|
execute('sudo ldconfig')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -1167,7 +1147,7 @@ def _install_sysrepo_from_sources(ignore_errors=False):
|
|||||||
sysrepo_header = f'{prefix}/include/sysrepo/version.h'
|
sysrepo_header = f'{prefix}/include/sysrepo/version.h'
|
||||||
if (any(os.path.exists(i) for i in sysrepo_so_candidates) and os.path.exists(sysrepo_header) and
|
if (any(os.path.exists(i) for i in sysrepo_so_candidates) and os.path.exists(sysrepo_header) and
|
||||||
execute(f"grep -F '#define SR_VERSION_MAJOR 7' '{sysrepo_header}'", raise_error=False) == 0):
|
execute(f"grep -F '#define SR_VERSION_MAJOR 7' '{sysrepo_header}'", raise_error=False) == 0):
|
||||||
log.info(f'sysrepo is already installed at {sysrepo_header}.')
|
log.info('sysrepo is already installed at %s.', sysrepo_header)
|
||||||
return
|
return
|
||||||
|
|
||||||
version = 'v2.2.12'
|
version = 'v2.2.12'
|
||||||
@ -1185,7 +1165,7 @@ def _install_sysrepo_from_sources(ignore_errors=False):
|
|||||||
execute('cmake -DBUILD_TESTING=OFF -DREPO_PATH=/etc/sysrepo ..', cwd='~/.hammer-tmp/sysrepo/build')
|
execute('cmake -DBUILD_TESTING=OFF -DREPO_PATH=/etc/sysrepo ..', cwd='~/.hammer-tmp/sysrepo/build')
|
||||||
execute('make -j $(nproc || gnproc || echo 1)', cwd='~/.hammer-tmp/sysrepo/build')
|
execute('make -j $(nproc || gnproc || echo 1)', cwd='~/.hammer-tmp/sysrepo/build')
|
||||||
execute('sudo make install', cwd='~/.hammer-tmp/sysrepo/build')
|
execute('sudo make install', cwd='~/.hammer-tmp/sysrepo/build')
|
||||||
system, revision = get_system_revision()
|
system, _ = get_system_revision()
|
||||||
if system != 'alpine':
|
if system != 'alpine':
|
||||||
execute('sudo ldconfig')
|
execute('sudo ldconfig')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -1203,7 +1183,7 @@ def _install_libyang_cpp_from_sources(ignore_errors=False):
|
|||||||
libyang_cpp_pc = f'{prefix_lib}/pkgconfig/libyang-cpp.pc'
|
libyang_cpp_pc = f'{prefix_lib}/pkgconfig/libyang-cpp.pc'
|
||||||
if (os.path.exists(libyang_cpp_so) and os.path.exists(libyang_cpp_pc) and
|
if (os.path.exists(libyang_cpp_so) and os.path.exists(libyang_cpp_pc) and
|
||||||
execute(f"grep -F 'Version: 1.1.0' '{libyang_cpp_pc}'", raise_error=False) == 0):
|
execute(f"grep -F 'Version: 1.1.0' '{libyang_cpp_pc}'", raise_error=False) == 0):
|
||||||
log.info(f'libyang-cpp is already installed at {libyang_cpp_so}.')
|
log.info('libyang-cpp is already installed at %s.', libyang_cpp_so)
|
||||||
return
|
return
|
||||||
|
|
||||||
version = 'ae7d649ea75da081725c119dd553b2ef3121a6f8'
|
version = 'ae7d649ea75da081725c119dd553b2ef3121a6f8'
|
||||||
@ -1214,16 +1194,22 @@ def _install_libyang_cpp_from_sources(ignore_errors=False):
|
|||||||
execute('git clone https://github.com/CESNET/libyang-cpp.git ~/.hammer-tmp/libyang-cpp')
|
execute('git clone https://github.com/CESNET/libyang-cpp.git ~/.hammer-tmp/libyang-cpp')
|
||||||
execute(f'git checkout {version}', cwd='~/.hammer-tmp/libyang-cpp')
|
execute(f'git checkout {version}', cwd='~/.hammer-tmp/libyang-cpp')
|
||||||
# New cpp compiler is more picky about missing headers. (ex. Fedora 40)
|
# New cpp compiler is more picky about missing headers. (ex. Fedora 40)
|
||||||
return_code = execute('sudo grep "#include <algorithm>" ~/.hammer-tmp/libyang-cpp/src/Context.cpp',
|
execute("""git apply <<EOF
|
||||||
raise_error=False)
|
diff --git a/src/Context.cpp b/src/Context.cpp
|
||||||
if return_code == 1:
|
index b2fe887..add11cc 100644
|
||||||
execute(r'sed -i "/#include <libyang\/libyang.h>/a #include <algorithm>" '
|
--- a/src/Context.cpp
|
||||||
'~/.hammer-tmp/libyang-cpp/src/Context.cpp')
|
+++ b/src/Context.cpp
|
||||||
|
@@ -13,2 +13,3 @@
|
||||||
|
#include <libyang/libyang.h>
|
||||||
|
+#include <algorithm>
|
||||||
|
#include <span>
|
||||||
|
EOF
|
||||||
|
""", cwd='~/.hammer-tmp/libyang-cpp')
|
||||||
execute('mkdir ~/.hammer-tmp/libyang-cpp/build')
|
execute('mkdir ~/.hammer-tmp/libyang-cpp/build')
|
||||||
execute('cmake -DBUILD_TESTING=OFF .. ', cwd='~/.hammer-tmp/libyang-cpp/build')
|
execute('cmake -DBUILD_TESTING=OFF .. ', cwd='~/.hammer-tmp/libyang-cpp/build')
|
||||||
execute('make -j $(nproc || gnproc || echo 1)', cwd='~/.hammer-tmp/libyang-cpp/build')
|
execute('make -j $(nproc || gnproc || echo 1)', cwd='~/.hammer-tmp/libyang-cpp/build')
|
||||||
execute('sudo make install', cwd='~/.hammer-tmp/libyang-cpp/build')
|
execute('sudo make install', cwd='~/.hammer-tmp/libyang-cpp/build')
|
||||||
system, revision = get_system_revision()
|
system, _ = get_system_revision()
|
||||||
if system != 'alpine':
|
if system != 'alpine':
|
||||||
execute('sudo ldconfig')
|
execute('sudo ldconfig')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -1241,7 +1227,7 @@ def _install_sysrepo_cpp_from_sources(ignore_errors=False):
|
|||||||
sysrepo_cpp_pc = f'{prefix_lib}/pkgconfig/sysrepo-cpp.pc'
|
sysrepo_cpp_pc = f'{prefix_lib}/pkgconfig/sysrepo-cpp.pc'
|
||||||
if (os.path.exists(sysrepo_cpp_so) and os.path.exists(sysrepo_cpp_pc) and
|
if (os.path.exists(sysrepo_cpp_so) and os.path.exists(sysrepo_cpp_pc) and
|
||||||
execute(f"grep -F 'Version: 1.1.0' '{sysrepo_cpp_pc}'", raise_error=False) == 0):
|
execute(f"grep -F 'Version: 1.1.0' '{sysrepo_cpp_pc}'", raise_error=False) == 0):
|
||||||
log.info(f'sysrepo-cpp is already installed at {sysrepo_cpp_so}.')
|
log.info('sysrepo-cpp is already installed at %s.', sysrepo_cpp_so)
|
||||||
return
|
return
|
||||||
|
|
||||||
version = '02634174ffc60568301c3d9b9b7cf710cff6a586'
|
version = '02634174ffc60568301c3d9b9b7cf710cff6a586'
|
||||||
@ -1255,7 +1241,7 @@ def _install_sysrepo_cpp_from_sources(ignore_errors=False):
|
|||||||
execute('cmake -DBUILD_TESTING=OFF .. ', cwd='~/.hammer-tmp/sysrepo-cpp/build')
|
execute('cmake -DBUILD_TESTING=OFF .. ', cwd='~/.hammer-tmp/sysrepo-cpp/build')
|
||||||
execute('make -j $(nproc || gnproc || echo 1)', cwd='~/.hammer-tmp/sysrepo-cpp/build')
|
execute('make -j $(nproc || gnproc || echo 1)', cwd='~/.hammer-tmp/sysrepo-cpp/build')
|
||||||
execute('sudo make install', cwd='~/.hammer-tmp/sysrepo-cpp/build')
|
execute('sudo make install', cwd='~/.hammer-tmp/sysrepo-cpp/build')
|
||||||
system, revision = get_system_revision()
|
system, _ = get_system_revision()
|
||||||
if system != 'alpine':
|
if system != 'alpine':
|
||||||
execute('sudo ldconfig')
|
execute('sudo ldconfig')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -1332,7 +1318,7 @@ def _configure_mysql(system, revision, features):
|
|||||||
exit_code = execute('openssl rsa -in src/lib/asiolink/testutils/ca/kea-server.key '
|
exit_code = execute('openssl rsa -in src/lib/asiolink/testutils/ca/kea-server.key '
|
||||||
'-out src/lib/asiolink/testutils/ca/kea-server.key', raise_error=False)
|
'-out src/lib/asiolink/testutils/ca/kea-server.key', raise_error=False)
|
||||||
if exit_code != 0:
|
if exit_code != 0:
|
||||||
log.warning(f'openssl command failed with exit code {exit_code}, but continuing...')
|
log.warning('openssl command failed with exit code %d, but continuing...', exit_code)
|
||||||
for file in [
|
for file in [
|
||||||
'./src/lib/asiolink/testutils/ca/kea-ca.crt',
|
'./src/lib/asiolink/testutils/ca/kea-ca.crt',
|
||||||
'./src/lib/asiolink/testutils/ca/kea-client.crt',
|
'./src/lib/asiolink/testutils/ca/kea-client.crt',
|
||||||
@ -1436,7 +1422,7 @@ ssl_key = {cert_dir}/kea-client.key
|
|||||||
execute(cmd)
|
execute(cmd)
|
||||||
|
|
||||||
if system == 'debian' and revision == '9':
|
if system == 'debian' and revision == '9':
|
||||||
log.info('FIX FOR ISSUE kea#389: {} {}'.format(system, revision))
|
log.info('FIX FOR ISSUE kea#389: %s %s', system, revision)
|
||||||
cmd = "sh -c \"cat <<EOF | sudo mysql -u root\n"
|
cmd = "sh -c \"cat <<EOF | sudo mysql -u root\n"
|
||||||
cmd += "use keatest;\n"
|
cmd += "use keatest;\n"
|
||||||
cmd += "set global innodb_large_prefix=on;\n"
|
cmd += "set global innodb_large_prefix=on;\n"
|
||||||
@ -1447,7 +1433,7 @@ ssl_key = {cert_dir}/kea-client.key
|
|||||||
execute(cmd)
|
execute(cmd)
|
||||||
|
|
||||||
|
|
||||||
def _enable_postgresql(system, revision):
|
def _enable_postgresql(system):
|
||||||
if system == 'alpine':
|
if system == 'alpine':
|
||||||
execute('sudo rc-update add postgresql')
|
execute('sudo rc-update add postgresql')
|
||||||
elif system == 'freebsd':
|
elif system == 'freebsd':
|
||||||
@ -1463,7 +1449,7 @@ def _enable_postgresql(system, revision):
|
|||||||
execute('sudo systemctl enable postgresql.service')
|
execute('sudo systemctl enable postgresql.service')
|
||||||
|
|
||||||
|
|
||||||
def _restart_postgresql(system, revision):
|
def _restart_postgresql(system):
|
||||||
if system == 'freebsd':
|
if system == 'freebsd':
|
||||||
# redirecting output from start script to /dev/null otherwise the postgresql rc.d script will hang
|
# redirecting output from start script to /dev/null otherwise the postgresql rc.d script will hang
|
||||||
# calling restart instead of start allow hammer.py to pass even if postgresql is already installed
|
# calling restart instead of start allow hammer.py to pass even if postgresql is already installed
|
||||||
@ -1481,12 +1467,12 @@ def _restart_postgresql(system, revision):
|
|||||||
exit_code = execute('sudo systemctl restart postgresql.service', raise_error=False)
|
exit_code = execute('sudo systemctl restart postgresql.service', raise_error=False)
|
||||||
if exit_code != 0:
|
if exit_code != 0:
|
||||||
log.error('Command "sudo systemctl restart postgresql.service" failed. Here is the journal:')
|
log.error('Command "sudo systemctl restart postgresql.service" failed. Here is the journal:')
|
||||||
_, output = execute('sudo journalctl -xu postgresql.service', raise_error=False)
|
execute('sudo journalctl -xu postgresql.service', raise_error=False)
|
||||||
log.error('And here are the logs:')
|
log.error('And here are the logs:')
|
||||||
_, output = execute("sudo -u postgres psql -A -t -c 'SELECT pg_current_logfile()'",
|
_, output = execute("sudo -u postgres psql -A -t -c 'SELECT pg_current_logfile()'",
|
||||||
capture=True, quiet=True)
|
capture=True, quiet=True)
|
||||||
logfile = os.path.basename(output.strip())
|
logfile = os.path.basename(output.strip())
|
||||||
_, output = execute(fr'sudo find /var -type f -name "{logfile}" -exec cat {{}} \;', raise_error=False)
|
execute(fr'sudo find /var -type f -name "{logfile}" -exec cat {{}} \;', raise_error=False)
|
||||||
sys.exit(exit_code)
|
sys.exit(exit_code)
|
||||||
|
|
||||||
|
|
||||||
@ -1495,11 +1481,12 @@ def _restart_postgresql(system, revision):
|
|||||||
# and user both set to 'all'. This is to not affect authentication of
|
# and user both set to 'all'. This is to not affect authentication of
|
||||||
# `postgres` user which should have a separate entry.
|
# `postgres` user which should have a separate entry.
|
||||||
def _change_postgresql_auth_method(connection_type, auth_method, hba_file):
|
def _change_postgresql_auth_method(connection_type, auth_method, hba_file):
|
||||||
execute(r"sudo sed -i.bak 's/^{}\(.*\)all\(.*\)all\(.*\) [a-z0-9]*$/{}\1all\2all\3 {}/g' '{}'".format(
|
execute(fr"sudo sed -i.bak 's/^{connection_type}\(.*\)all\(.*\)all\(.*\) [a-z0-9]*$"
|
||||||
connection_type, connection_type, auth_method, hba_file), cwd='/tmp')
|
fr"/{connection_type}\1all\2all\3 {auth_method}/g' '{hba_file}'",
|
||||||
|
cwd='/tmp')
|
||||||
|
|
||||||
|
|
||||||
def _configure_pgsql(system, revision, features):
|
def _configure_pgsql(system, features):
|
||||||
""" Configure PostgreSQL DB """
|
""" Configure PostgreSQL DB """
|
||||||
|
|
||||||
if system == 'freebsd':
|
if system == 'freebsd':
|
||||||
@ -1539,8 +1526,8 @@ def _configure_pgsql(system, revision, features):
|
|||||||
# the initial start of the postgresql will create the 'postmaster.opts' file
|
# the initial start of the postgresql will create the 'postmaster.opts' file
|
||||||
execute(f'sudo test ! -f {var_db_postgres_data}/postmaster.opts && sudo service postgresql onestart || true')
|
execute(f'sudo test ! -f {var_db_postgres_data}/postmaster.opts && sudo service postgresql onestart || true')
|
||||||
|
|
||||||
_enable_postgresql(system, revision)
|
_enable_postgresql(system)
|
||||||
_restart_postgresql(system, revision)
|
_restart_postgresql(system)
|
||||||
|
|
||||||
# Change auth-method to 'md5' on all connections.
|
# Change auth-method to 'md5' on all connections.
|
||||||
cmd = "sudo -u postgres psql -t -c 'SHOW hba_file' | xargs"
|
cmd = "sudo -u postgres psql -t -c 'SHOW hba_file' | xargs"
|
||||||
@ -1560,7 +1547,7 @@ def _configure_pgsql(system, revision, features):
|
|||||||
{}
|
{}
|
||||||
' '{}'""".format(auth_header, postgres_auth_line, hba_file))
|
' '{}'""".format(auth_header, postgres_auth_line, hba_file))
|
||||||
|
|
||||||
_restart_postgresql(system, revision)
|
_restart_postgresql(system)
|
||||||
|
|
||||||
cmd = """sh -c \"cat <<EOF | sudo -u postgres psql postgres
|
cmd = """sh -c \"cat <<EOF | sudo -u postgres psql postgres
|
||||||
DROP DATABASE IF EXISTS keatest;
|
DROP DATABASE IF EXISTS keatest;
|
||||||
@ -1614,7 +1601,7 @@ def _get_package_version(package: str):
|
|||||||
Returns the version available in the package manager's repository for the requested package.
|
Returns the version available in the package manager's repository for the requested package.
|
||||||
:param package: the name of the package whose version is retrieved
|
:param package: the name of the package whose version is retrieved
|
||||||
"""
|
"""
|
||||||
system, revision = get_system_revision()
|
system, _ = get_system_revision()
|
||||||
if system == 'alpine':
|
if system == 'alpine':
|
||||||
cmd = "apk search --exact {0} | sed 's/{0}-//g'"
|
cmd = "apk search --exact {0} | sed 's/{0}-//g'"
|
||||||
elif system in ['debian', 'ubuntu']:
|
elif system in ['debian', 'ubuntu']:
|
||||||
@ -1644,13 +1631,13 @@ def require_minimum_package_version(package: str, minimum: str):
|
|||||||
if version < minimum:
|
if version < minimum:
|
||||||
message = f"ERROR: {package} has version {version}, but must be >= {minimum}"
|
message = f"ERROR: {package} has version {version}, but must be >= {minimum}"
|
||||||
log.error(message)
|
log.error(message)
|
||||||
raise Exception(message)
|
raise UnexpectedError(message)
|
||||||
|
|
||||||
|
|
||||||
def prepare_system_local(features, check_times, ignore_errors_for, just_configure):
|
def prepare_system_local(features, check_times, ignore_errors_for, just_configure):
|
||||||
"""Prepare local system for Kea development based on requested features."""
|
"""Prepare local system for Kea development based on requested features."""
|
||||||
system, revision = get_system_revision()
|
system, revision = get_system_revision()
|
||||||
log.info(f'Preparing deps for {system} {revision}...')
|
log.info('Preparing deps for %s %s...', system, revision)
|
||||||
|
|
||||||
if not just_configure:
|
if not just_configure:
|
||||||
install_packages_local(system, revision, features, check_times, ignore_errors_for)
|
install_packages_local(system, revision, features, check_times, ignore_errors_for)
|
||||||
@ -1659,7 +1646,7 @@ def prepare_system_local(features, check_times, ignore_errors_for, just_configur
|
|||||||
_configure_mysql(system, revision, features)
|
_configure_mysql(system, revision, features)
|
||||||
|
|
||||||
if 'pgsql' in features:
|
if 'pgsql' in features:
|
||||||
_configure_pgsql(system, revision, features)
|
_configure_pgsql(system, features)
|
||||||
|
|
||||||
log.info('Preparing deps completed successfully.')
|
log.info('Preparing deps completed successfully.')
|
||||||
|
|
||||||
@ -2199,7 +2186,12 @@ def _build_binaries_and_run_ut(system, revision, features, tarball_path, env, ch
|
|||||||
failures = int(root.get('failures'))
|
failures = int(root.get('failures'))
|
||||||
disabled = int(root.get('disabled'))
|
disabled = int(root.get('disabled'))
|
||||||
errors = int(root.get('errors'))
|
errors = int(root.get('errors'))
|
||||||
results[fn] = dict(total=total, failures=failures, disabled=disabled, errors=errors)
|
results[fn] = {
|
||||||
|
'total': total,
|
||||||
|
'failures': failures,
|
||||||
|
'disabled': disabled,
|
||||||
|
'errors': errors,
|
||||||
|
}
|
||||||
grand_total += total
|
grand_total += total
|
||||||
grand_not_passed += failures + errors
|
grand_not_passed += failures + errors
|
||||||
|
|
||||||
@ -2221,7 +2213,7 @@ def _build_binaries_and_run_ut(system, revision, features, tarball_path, env, ch
|
|||||||
result = green(result)
|
result = green(result)
|
||||||
log.info('Unit test results: %s', result)
|
log.info('Unit test results: %s', result)
|
||||||
|
|
||||||
with open('unit-test-results.json', 'w') as f:
|
with open('unit-test-results.json', 'w', encoding='utf-8') as f:
|
||||||
f.write(json.dumps(results))
|
f.write(json.dumps(results))
|
||||||
|
|
||||||
# store aggregated results in XML
|
# store aggregated results in XML
|
||||||
@ -2255,7 +2247,7 @@ def _check_installed_rpm_or_debs(services_list):
|
|||||||
|
|
||||||
|
|
||||||
def _build_rpm(system, revision, features, tarball_path, env, check_times, dry_run,
|
def _build_rpm(system, revision, features, tarball_path, env, check_times, dry_run,
|
||||||
pkg_version, pkg_isc_version, repo_url):
|
pkg_version, pkg_isc_version):
|
||||||
|
|
||||||
# unpack kea sources tarball
|
# unpack kea sources tarball
|
||||||
_, arch = execute('arch', capture=True)
|
_, arch = execute('arch', capture=True)
|
||||||
@ -2318,7 +2310,7 @@ def _build_rpm(system, revision, features, tarball_path, env, check_times, dry_r
|
|||||||
|
|
||||||
|
|
||||||
def _build_deb(system, revision, features, tarball_path, env, check_times, dry_run,
|
def _build_deb(system, revision, features, tarball_path, env, check_times, dry_run,
|
||||||
pkg_version, pkg_isc_version, repository_url, repo_url):
|
pkg_version, pkg_isc_version, repo_url):
|
||||||
|
|
||||||
_, arch = execute('arch', capture=True)
|
_, arch = execute('arch', capture=True)
|
||||||
if system == 'debian' and revision == '9':
|
if system == 'debian' and revision == '9':
|
||||||
@ -2329,15 +2321,15 @@ def _build_deb(system, revision, features, tarball_path, env, check_times, dry_r
|
|||||||
_, output = execute("curl -o /dev/null -s -w '%{{http_code}}' {}/dists/kea/Release 2>/dev/null".format(repo_url),
|
_, output = execute("curl -o /dev/null -s -w '%{{http_code}}' {}/dists/kea/Release 2>/dev/null".format(repo_url),
|
||||||
capture=True)
|
capture=True)
|
||||||
http_code = output.rstrip()
|
http_code = output.rstrip()
|
||||||
release_file_exists = (http_code == '200')
|
release_file_exists = http_code == '200'
|
||||||
if release_file_exists:
|
if release_file_exists:
|
||||||
log.info(f'{repo_url}/dists/kea/Release exists.')
|
log.info('%s/dists/kea/Release exists.', repo_url)
|
||||||
else:
|
else:
|
||||||
repo_name = 'kea-%s-%s-%s' % (pkg_version.rsplit('.', 1)[0], system, revision)
|
repo_name = 'kea-%s-%s-%s' % (pkg_version.rsplit('.', 1)[0], system, revision)
|
||||||
log.error(f'{repo_url}/dists/kea/Release does not exist. '
|
log.error('%s/dists/kea/Release does not exist. '
|
||||||
f'This is usually caused by no package existing in {repo_name}. '
|
'This is usually caused by no package existing in %s. '
|
||||||
'You can solve this by uploading any package.'
|
'You can solve this by uploading any package.'
|
||||||
'Continuing, but the build will likely fail.')
|
'Continuing, but the build will likely fail.', repo_url, repo_name)
|
||||||
|
|
||||||
# try apt update for up to 10 times if there is an error
|
# try apt update for up to 10 times if there is an error
|
||||||
for _ in range(10):
|
for _ in range(10):
|
||||||
@ -2387,8 +2379,8 @@ def _build_deb(system, revision, features, tarball_path, env, check_times, dry_r
|
|||||||
_check_installed_rpm_or_debs(services_list)
|
_check_installed_rpm_or_debs(services_list)
|
||||||
|
|
||||||
|
|
||||||
def _build_alpine_apk(system, revision, features, tarball_path, env, check_times, dry_run,
|
def _build_alpine_apk(revision, features, tarball_path, check_times, dry_run,
|
||||||
pkg_version, pkg_isc_version, repo_url):
|
pkg_version, pkg_isc_version):
|
||||||
_, arch = execute('arch', capture=True)
|
_, arch = execute('arch', capture=True)
|
||||||
# unpack tarball
|
# unpack tarball
|
||||||
execute('sudo rm -rf kea-src packages', check_times=check_times, dry_run=dry_run)
|
execute('sudo rm -rf kea-src packages', check_times=check_times, dry_run=dry_run)
|
||||||
@ -2444,21 +2436,21 @@ def _build_native_pkg(system, revision, features, tarball_path, env, check_times
|
|||||||
# enable ccache if requested
|
# enable ccache if requested
|
||||||
env = _prepare_ccache_if_needed(system, ccache_dir, env)
|
env = _prepare_ccache_if_needed(system, ccache_dir, env)
|
||||||
|
|
||||||
repo_url = _get_full_repo_url(repository_url, system, revision, pkg_version)
|
repo_url = _get_full_repo_url(repository_url, system, revision)
|
||||||
if repo_url is None:
|
if repo_url is None:
|
||||||
raise ValueError('repo_url is None')
|
raise ValueError('repo_url is None')
|
||||||
|
|
||||||
if system in ['fedora', 'centos', 'rhel', 'rocky']:
|
if system in ['fedora', 'centos', 'rhel', 'rocky']:
|
||||||
_build_rpm(system, revision, features, tarball_path, env, check_times, dry_run,
|
_build_rpm(system, revision, features, tarball_path, env, check_times, dry_run,
|
||||||
pkg_version, pkg_isc_version, repo_url)
|
pkg_version, pkg_isc_version)
|
||||||
|
|
||||||
elif system in ['ubuntu', 'debian']:
|
elif system in ['ubuntu', 'debian']:
|
||||||
_build_deb(system, revision, features, tarball_path, env, check_times, dry_run,
|
_build_deb(system, revision, features, tarball_path, env, check_times, dry_run,
|
||||||
pkg_version, pkg_isc_version, repository_url, repo_url)
|
pkg_version, pkg_isc_version, repo_url)
|
||||||
|
|
||||||
elif system in ['alpine']:
|
elif system in ['alpine']:
|
||||||
_build_alpine_apk(system, revision, features, tarball_path, env, check_times, dry_run,
|
_build_alpine_apk(revision, features, tarball_path, check_times, dry_run,
|
||||||
pkg_version, pkg_isc_version, repo_url)
|
pkg_version, pkg_isc_version)
|
||||||
|
|
||||||
elif system in ['arch']:
|
elif system in ['arch']:
|
||||||
pass
|
pass
|
||||||
@ -2546,7 +2538,7 @@ def build_in_vagrant(provider, system, revision, features, leave_system, tarball
|
|||||||
except ExecutionError as e:
|
except ExecutionError as e:
|
||||||
error = e
|
error = e
|
||||||
msg = ' - ' + red(str(e))
|
msg = ' - ' + red(str(e))
|
||||||
except Exception as e: # pylint: disable=broad-except
|
except Exception as e:
|
||||||
log.exception('Building erred')
|
log.exception('Building erred')
|
||||||
error = e
|
error = e
|
||||||
msg = ' - ' + red(str(e))
|
msg = ' - ' + red(str(e))
|
||||||
@ -2817,9 +2809,9 @@ def parse_args():
|
|||||||
|
|
||||||
def list_supported_systems():
|
def list_supported_systems():
|
||||||
"""List systems hammer can support (with supported providers)."""
|
"""List systems hammer can support (with supported providers)."""
|
||||||
for system in SYSTEMS:
|
for system, revision in SYSTEMS.items():
|
||||||
print('%s:' % system)
|
print(f'{system}:')
|
||||||
for release, supported in SYSTEMS[system].items():
|
for release, supported in revision.items():
|
||||||
if not supported:
|
if not supported:
|
||||||
continue
|
continue
|
||||||
providers = []
|
providers = []
|
||||||
@ -2828,7 +2820,7 @@ def list_supported_systems():
|
|||||||
if k in IMAGE_TEMPLATES:
|
if k in IMAGE_TEMPLATES:
|
||||||
providers.append(p)
|
providers.append(p)
|
||||||
providers = ', '.join(providers)
|
providers = ', '.join(providers)
|
||||||
print(' - %s: %s' % (release, providers))
|
print(f' - {release}: {providers}')
|
||||||
|
|
||||||
|
|
||||||
def list_created_systems():
|
def list_created_systems():
|
||||||
@ -2903,10 +2895,10 @@ def _get_features(args):
|
|||||||
for i in args.with_randomly:
|
for i in args.with_randomly:
|
||||||
if _coin_toss():
|
if _coin_toss():
|
||||||
features.add(i)
|
features.add(i)
|
||||||
log.info(f'Feature enabled through coin toss: {i}')
|
log.info('Feature enabled through coin toss: %s', i)
|
||||||
else:
|
else:
|
||||||
features.discard(i)
|
features.discard(i)
|
||||||
log.info(f'Feature disabled through coin toss: {i}')
|
log.info('Feature disabled through coin toss: %s', i)
|
||||||
|
|
||||||
if hasattr(args, 'ccache_dir') and args.ccache_dir:
|
if hasattr(args, 'ccache_dir') and args.ccache_dir:
|
||||||
features.add('ccache')
|
features.add('ccache')
|
||||||
@ -2955,20 +2947,19 @@ def _print_summary(results, features):
|
|||||||
def _check_system_revision(system, revision):
|
def _check_system_revision(system, revision):
|
||||||
if revision == 'all':
|
if revision == 'all':
|
||||||
return
|
return
|
||||||
if system not in SYSTEMS.keys():
|
if system not in SYSTEMS:
|
||||||
msg = "hammer.py error: argument -s/--system: invalid choice: '%s' (choose from '%s')"
|
msg = "hammer.py error: argument -s/--system: invalid choice: '%s' (choose from '%s')"
|
||||||
msg = msg % (revision, "', '".join(SYSTEMS.keys()))
|
msg = msg % (revision, "', '".join(SYSTEMS.keys()))
|
||||||
log.error(msg)
|
log.error(msg)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
revs = SYSTEMS[system].keys()
|
if revision not in SYSTEMS[system]:
|
||||||
if revision not in revs:
|
|
||||||
msg = "hammer.py error: argument -r/--revision: invalid choice: '%s' (choose from '%s')"
|
msg = "hammer.py error: argument -r/--revision: invalid choice: '%s' (choose from '%s')"
|
||||||
msg = msg % (revision, "', '".join(revs))
|
msg = msg % (revision, "', '".join(SYSTEMS[system].keys()))
|
||||||
log.error(msg)
|
log.error(msg)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
if not SYSTEMS[system][revision]:
|
if not SYSTEMS[system][revision]:
|
||||||
log.warning(f'{system} ${revision} is no longer officially supported. '
|
log.warning('%s %s is no longer officially supported. '
|
||||||
'The script will continue in a best-effort manner.')
|
'The script will continue in a best-effort manner.', system, revision)
|
||||||
|
|
||||||
|
|
||||||
def _prepare_ccache_dir(ccache_dir, system, revision):
|
def _prepare_ccache_dir(ccache_dir, system, revision):
|
||||||
@ -3010,7 +3001,7 @@ def prepare_system_cmd(args):
|
|||||||
def upload_to_repo(args, pkgs_dir):
|
def upload_to_repo(args, pkgs_dir):
|
||||||
# NOTE: note the differences (if any) in system/revision vs args.system/revision
|
# NOTE: note the differences (if any) in system/revision vs args.system/revision
|
||||||
system, revision = get_system_revision()
|
system, revision = get_system_revision()
|
||||||
repo_url = _get_full_repo_url(args.repository_url, system, revision, args.pkg_version)
|
repo_url = _get_full_repo_url(args.repository_url, system, revision)
|
||||||
if repo_url is None:
|
if repo_url is None:
|
||||||
raise ValueError('repo_url is None')
|
raise ValueError('repo_url is None')
|
||||||
upload_cmd = 'curl -v --netrc -f'
|
upload_cmd = 'curl -v --netrc -f'
|
||||||
@ -3055,7 +3046,7 @@ def upload_to_repo(args, pkgs_dir):
|
|||||||
log.info("Asset already exists in the repository. Skipping upload.")
|
log.info("Asset already exists in the repository. Skipping upload.")
|
||||||
break
|
break
|
||||||
elif exitcode != 0:
|
elif exitcode != 0:
|
||||||
raise Exception('Upload failed: %s' % output)
|
raise UnexpectedError('Upload failed: %s' % output)
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -47,10 +47,10 @@ def send_to_control_agent(params):
|
|||||||
# Issue: [B310:blacklist] Audit url open for permitted schemes.
|
# Issue: [B310:blacklist] Audit url open for permitted schemes.
|
||||||
# Allowing use of file:/ or custom schemes is often unexpected.
|
# Allowing use of file:/ or custom schemes is often unexpected.
|
||||||
# Reason for nosec: url is checked to be http further above.
|
# Reason for nosec: url is checked to be http further above.
|
||||||
resp = urllib.request.urlopen(req, context=ssl_ctx) # nosec B310
|
with urllib.request.urlopen(req, context=ssl_ctx) as resp: # nosec B310
|
||||||
|
# Now get the response details, put it in CAResponse and return it
|
||||||
|
result = CAResponse(resp.getcode(), resp.reason,
|
||||||
|
resp.read().decode("utf-8"))
|
||||||
|
|
||||||
# Now get the response details, put it in CAResponse and return it
|
return result
|
||||||
result = CAResponse(resp.getcode(), resp.reason,
|
return None
|
||||||
resp.read().decode("utf-8"))
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
@ -166,8 +166,8 @@ class CARequestUnitTest(unittest.TestCase):
|
|||||||
user = 'libert\xe9'
|
user = 'libert\xe9'
|
||||||
password = '\xe9galit\xe9'
|
password = '\xe9galit\xe9'
|
||||||
else:
|
else:
|
||||||
user = u'libert\xe9'
|
user = 'libert\xe9'
|
||||||
password = u'\xe9galit\xe9'
|
password = '\xe9galit\xe9'
|
||||||
buser = user.encode('utf-8')
|
buser = user.encode('utf-8')
|
||||||
bpassword = password.encode('utf-8')
|
bpassword = password.encode('utf-8')
|
||||||
secret = b':'.join((buser, bpassword))
|
secret = b':'.join((buser, bpassword))
|
||||||
|
@ -28,7 +28,7 @@ if len(sys.argv) != 3:
|
|||||||
preproc = re.compile('^#')
|
preproc = re.compile('^#')
|
||||||
constant = re.compile('^([a-zA-Z].*?[a-zA-Z_0-9]+)\\s*=.*;')
|
constant = re.compile('^([a-zA-Z].*?[a-zA-Z_0-9]+)\\s*=.*;')
|
||||||
|
|
||||||
with open(filename_in) as file_in, open(filename_out, "w") as file_out:
|
with open(filename_in, encoding='utf-8') as file_in, open(filename_out, "w", encoding='utf-8') as file_out:
|
||||||
file_out.write("// This file is generated from " + filename_in + "\n" +
|
file_out.write("// This file is generated from " + filename_in + "\n" +
|
||||||
"// by the const2hdr.py script.\n" +
|
"// by the const2hdr.py script.\n" +
|
||||||
"// Do not edit, all changes will be lost.\n\n")
|
"// Do not edit, all changes will be lost.\n\n")
|
||||||
|
@ -316,14 +316,14 @@ What you are expected to do is as follows:
|
|||||||
examples.
|
examples.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import base64
|
||||||
import configparser
|
import configparser
|
||||||
import re
|
import re
|
||||||
import time
|
|
||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
import base64
|
import time
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from optparse import OptionParser
|
|
||||||
|
|
||||||
re_hex = re.compile(r'^0x[0-9a-fA-F]+')
|
re_hex = re.compile(r'^0x[0-9a-fA-F]+')
|
||||||
re_decimal = re.compile(r'^\d+$')
|
re_decimal = re.compile(r'^\d+$')
|
||||||
@ -334,11 +334,9 @@ dnssec_timefmt = '%Y%m%d%H%M%S'
|
|||||||
dict_qr = {'query': 0, 'response': 1}
|
dict_qr = {'query': 0, 'response': 1}
|
||||||
dict_opcode = {'query': 0, 'iquery': 1, 'status': 2, 'notify': 4,
|
dict_opcode = {'query': 0, 'iquery': 1, 'status': 2, 'notify': 4,
|
||||||
'update': 5}
|
'update': 5}
|
||||||
rdict_opcode = dict([(dict_opcode[k], k.upper()) for k in dict_opcode.keys()])
|
|
||||||
dict_rcode = {'noerror': 0, 'formerr': 1, 'servfail': 2, 'nxdomain': 3,
|
dict_rcode = {'noerror': 0, 'formerr': 1, 'servfail': 2, 'nxdomain': 3,
|
||||||
'notimp': 4, 'refused': 5, 'yxdomain': 6, 'yxrrset': 7,
|
'notimp': 4, 'refused': 5, 'yxdomain': 6, 'yxrrset': 7,
|
||||||
'nxrrset': 8, 'notauth': 9, 'notzone': 10}
|
'nxrrset': 8, 'notauth': 9, 'notzone': 10}
|
||||||
rdict_rcode = dict([(dict_rcode[k], k.upper()) for k in dict_rcode.keys()])
|
|
||||||
dict_rrtype = {'none': 0, 'a': 1, 'ns': 2, 'md': 3, 'mf': 4, 'cname': 5,
|
dict_rrtype = {'none': 0, 'a': 1, 'ns': 2, 'md': 3, 'mf': 4, 'cname': 5,
|
||||||
'soa': 6, 'mb': 7, 'mg': 8, 'mr': 9, 'null': 10,
|
'soa': 6, 'mb': 7, 'mg': 8, 'mr': 9, 'null': 10,
|
||||||
'wks': 11, 'ptr': 12, 'hinfo': 13, 'minfo': 14, 'mx': 15,
|
'wks': 11, 'ptr': 12, 'hinfo': 13, 'minfo': 14, 'mx': 15,
|
||||||
@ -352,21 +350,25 @@ dict_rrtype = {'none': 0, 'a': 1, 'ns': 2, 'md': 3, 'mf': 4, 'cname': 5,
|
|||||||
'spf': 99, 'unspec': 103, 'tkey': 249, 'tsig': 250,
|
'spf': 99, 'unspec': 103, 'tkey': 249, 'tsig': 250,
|
||||||
'dlv': 32769, 'ixfr': 251, 'axfr': 252, 'mailb': 253,
|
'dlv': 32769, 'ixfr': 251, 'axfr': 252, 'mailb': 253,
|
||||||
'maila': 254, 'any': 255, 'caa': 257}
|
'maila': 254, 'any': 255, 'caa': 257}
|
||||||
rdict_rrtype = dict([(dict_rrtype[k], k.upper()) for k in dict_rrtype.keys()])
|
|
||||||
dict_rrclass = {'in': 1, 'ch': 3, 'hs': 4, 'any': 255}
|
dict_rrclass = {'in': 1, 'ch': 3, 'hs': 4, 'any': 255}
|
||||||
rdict_rrclass = dict([(dict_rrclass[k], k.upper()) for k in dict_rrclass.keys()])
|
dict_algorithm = {'rsamd5': 1, 'dh': 2, 'dsa': 3, 'ecc': 4, 'rsasha1': 5}
|
||||||
dict_algorithm = {'rsamd5': 1, 'dh': 2, 'dsa': 3, 'ecc': 4,
|
|
||||||
'rsasha1': 5}
|
|
||||||
dict_nsec3_algorithm = {'reserved': 0, 'sha1': 1}
|
dict_nsec3_algorithm = {'reserved': 0, 'sha1': 1}
|
||||||
rdict_algorithm = dict([(dict_algorithm[k], k.upper()) for k in dict_algorithm.keys()])
|
|
||||||
rdict_nsec3_algorithm = dict([(dict_nsec3_algorithm[k], k.upper()) for k in dict_nsec3_algorithm.keys()])
|
rdict_opcode = {k.upper(): v for k, v in dict_opcode.items()}
|
||||||
|
rdict_rcode = {k.upper(): v for k, v in dict_rcode.items()}
|
||||||
|
rdict_rrtype = {k.upper(): v for k, v in dict_rrtype.items()}
|
||||||
|
rdict_rrclass = {k.upper(): v for k, v in dict_rrclass.items()}
|
||||||
|
rdict_algorithm = {k.upper(): v for k, v in dict_algorithm.items()}
|
||||||
|
rdict_nsec3_algorithm = {k.upper(): v for k, v in dict_nsec3_algorithm.items()}
|
||||||
|
|
||||||
header_xtables = {'qr': dict_qr, 'opcode': dict_opcode,
|
header_xtables = {'qr': dict_qr, 'opcode': dict_opcode,
|
||||||
'rcode': dict_rcode}
|
'rcode': dict_rcode}
|
||||||
question_xtables = {'rrtype': dict_rrtype, 'rrclass': dict_rrclass}
|
question_xtables = {'rrtype': dict_rrtype, 'rrclass': dict_rrclass}
|
||||||
|
|
||||||
|
|
||||||
def parse_value(value, xtable={}):
|
def parse_value(value, xtable=None):
|
||||||
|
if xtable is None:
|
||||||
|
xtable = {}
|
||||||
if re.search(re_hex, value):
|
if re.search(re_hex, value):
|
||||||
return int(value, 16)
|
return int(value, 16)
|
||||||
if re.search(re_decimal, value):
|
if re.search(re_decimal, value):
|
||||||
@ -380,9 +382,9 @@ def parse_value(value, xtable={}):
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def code_totext(code, dict):
|
def code_totext(code, dictionary):
|
||||||
if code in dict.keys():
|
if code in dictionary:
|
||||||
return dict[code] + '(' + str(code) + ')'
|
return dictionary[code] + '(' + str(code) + ')'
|
||||||
return str(code)
|
return str(code)
|
||||||
|
|
||||||
|
|
||||||
@ -395,7 +397,7 @@ def encode_name(name, absolute=True):
|
|||||||
for label in labels:
|
for label in labels:
|
||||||
if len(label) > 4 and label[0:4] == 'ptr=':
|
if len(label) > 4 and label[0:4] == 'ptr=':
|
||||||
# special meta-syntax for compression pointer
|
# special meta-syntax for compression pointer
|
||||||
wire += '%04x' % (0xc000 | int(l[4:]))
|
wire += '%04x' % (0xc000 | int(label[4:]))
|
||||||
break
|
break
|
||||||
if absolute or len(label) > 0:
|
if absolute or len(label) > 0:
|
||||||
wire += '%02x' % len(label)
|
wire += '%02x' % len(label)
|
||||||
@ -405,15 +407,15 @@ def encode_name(name, absolute=True):
|
|||||||
return wire
|
return wire
|
||||||
|
|
||||||
|
|
||||||
def encode_string(name, len=None):
|
def encode_string(name, length=None):
|
||||||
if type(name) is int and len is not None:
|
if isinstance(name, int) and length is not None:
|
||||||
return '%0.*x' % (len * 2, name)
|
return '%0.*x' % (length * 2, name)
|
||||||
return ''.join(['%02x' % ord(ch) for ch in name])
|
return ''.join(['%02x' % ord(ch) for ch in name])
|
||||||
|
|
||||||
|
|
||||||
def encode_bytes(name, len=None):
|
def encode_bytes(name, length=None):
|
||||||
if type(name) is int and len is not None:
|
if isinstance(name, int) and length is not None:
|
||||||
return '%0.*x' % (len * 2, name)
|
return '%0.*x' % (length * 2, name)
|
||||||
return ''.join(['%02x' % ch for ch in name])
|
return ''.join(['%02x' % ch for ch in name])
|
||||||
|
|
||||||
|
|
||||||
@ -426,11 +428,13 @@ def count_namelabels(name):
|
|||||||
return len(name.split('.'))
|
return len(name.split('.'))
|
||||||
|
|
||||||
|
|
||||||
def get_config(config, section, configobj, xtables={}):
|
def get_config(config, section, configobj, xtables=None):
|
||||||
|
if xtables is None:
|
||||||
|
xtables = {}
|
||||||
try:
|
try:
|
||||||
for field in config.options(section):
|
for field in config.options(section):
|
||||||
value = config.get(section, field)
|
value = config.get(section, field)
|
||||||
if field in xtables.keys():
|
if field in xtables:
|
||||||
xtable = xtables[field]
|
xtable = xtables[field]
|
||||||
else:
|
else:
|
||||||
xtable = {}
|
xtable = {}
|
||||||
@ -704,7 +708,8 @@ class AAAA(RR):
|
|||||||
self.dump_header(f, self.rdlen)
|
self.dump_header(f, self.rdlen)
|
||||||
f.write('# Address=%s\n' % (self.address))
|
f.write('# Address=%s\n' % (self.address))
|
||||||
bin_address = socket.inet_pton(socket.AF_INET6, self.address)
|
bin_address = socket.inet_pton(socket.AF_INET6, self.address)
|
||||||
[f.write('%02x' % x) for x in bin_address]
|
for x in bin_address:
|
||||||
|
f.write('%02x' % x)
|
||||||
f.write('\n')
|
f.write('\n')
|
||||||
|
|
||||||
|
|
||||||
@ -959,6 +964,7 @@ class NSECBASE(RR):
|
|||||||
block = 0
|
block = 0
|
||||||
maplen = None # default bitmap length, auto-calculate
|
maplen = None # default bitmap length, auto-calculate
|
||||||
bitmap = '040000000003' # an arbitrarily chosen bitmap sample
|
bitmap = '040000000003' # an arbitrarily chosen bitmap sample
|
||||||
|
nextname = None
|
||||||
|
|
||||||
def dump(self, f):
|
def dump(self, f):
|
||||||
# first, construct the bitmap data
|
# first, construct the bitmap data
|
||||||
@ -994,6 +1000,17 @@ class NSECBASE(RR):
|
|||||||
f.write('%02x %02x %s\n' %
|
f.write('%02x %02x %s\n' %
|
||||||
(block_list[i], maplen_list[i], bitmap_list[i]))
|
(block_list[i], maplen_list[i], bitmap_list[i]))
|
||||||
|
|
||||||
|
def dump_fixedpart(self, f, bitmap_totallen):
|
||||||
|
name_wire = encode_name(self.nextname)
|
||||||
|
if self.rdlen is None:
|
||||||
|
# if rdlen needs to be calculated, it must be based on the bitmap
|
||||||
|
# length, because the configured maplen can be fake.
|
||||||
|
self.rdlen = int(len(name_wire) / 2) + bitmap_totallen
|
||||||
|
self.dump_header(f, self.rdlen)
|
||||||
|
f.write('# Next Name=%s (%d bytes)\n' % (self.nextname,
|
||||||
|
int(len(name_wire) / 2)))
|
||||||
|
f.write('%s\n' % name_wire)
|
||||||
|
|
||||||
|
|
||||||
class NSEC(NSECBASE):
|
class NSEC(NSECBASE):
|
||||||
'''Implements rendering NSEC RDATA in the test data format.
|
'''Implements rendering NSEC RDATA in the test data format.
|
||||||
@ -1007,17 +1024,6 @@ class NSEC(NSECBASE):
|
|||||||
|
|
||||||
nextname = 'next.example.com'
|
nextname = 'next.example.com'
|
||||||
|
|
||||||
def dump_fixedpart(self, f, bitmap_totallen):
|
|
||||||
name_wire = encode_name(self.nextname)
|
|
||||||
if self.rdlen is None:
|
|
||||||
# if rdlen needs to be calculated, it must be based on the bitmap
|
|
||||||
# length, because the configured maplen can be fake.
|
|
||||||
self.rdlen = int(len(name_wire) / 2) + bitmap_totallen
|
|
||||||
self.dump_header(f, self.rdlen)
|
|
||||||
f.write('# Next Name=%s (%d bytes)\n' % (self.nextname,
|
|
||||||
int(len(name_wire) / 2)))
|
|
||||||
f.write('%s\n' % name_wire)
|
|
||||||
|
|
||||||
|
|
||||||
class NSEC3PARAM(RR):
|
class NSEC3PARAM(RR):
|
||||||
'''Implements rendering NSEC3PARAM RDATA in the test data format.
|
'''Implements rendering NSEC3PARAM RDATA in the test data format.
|
||||||
@ -1146,9 +1152,9 @@ class RRSIG(RR):
|
|||||||
self.rdlen = int(18 + len(name_wire) / 2 + len(str(sig_wire)) / 2)
|
self.rdlen = int(18 + len(name_wire) / 2 + len(str(sig_wire)) / 2)
|
||||||
self.dump_header(f, self.rdlen)
|
self.dump_header(f, self.rdlen)
|
||||||
|
|
||||||
if type(self.covered) is str:
|
if isinstance(self.covered, str):
|
||||||
self.covered = dict_rrtype[self.covered.lower()]
|
self.covered = dict_rrtype[self.covered.lower()]
|
||||||
if type(self.algorithm) is str:
|
if isinstance(self.algorithm, str):
|
||||||
self.algorithm = dict_algorithm[self.algorithm.lower()]
|
self.algorithm = dict_algorithm[self.algorithm.lower()]
|
||||||
if self.labels is None:
|
if self.labels is None:
|
||||||
self.labels = count_namelabels(self.signer)
|
self.labels = count_namelabels(self.signer)
|
||||||
@ -1345,7 +1351,7 @@ class TSIG(RR):
|
|||||||
name_wire = encode_name(self.algorithm)
|
name_wire = encode_name(self.algorithm)
|
||||||
mac_size = self.mac_size
|
mac_size = self.mac_size
|
||||||
if mac_size is None:
|
if mac_size is None:
|
||||||
if self.algorithm in self.dict_macsize.keys():
|
if self.algorithm in self.dict_macsize:
|
||||||
mac_size = self.dict_macsize[self.algorithm]
|
mac_size = self.dict_macsize[self.algorithm]
|
||||||
else:
|
else:
|
||||||
raise RuntimeError('TSIG Mac Size cannot be determined')
|
raise RuntimeError('TSIG Mac Size cannot be determined')
|
||||||
@ -1426,7 +1432,7 @@ config_param = {'name': (Name, {}),
|
|||||||
'header': (DNSHeader, header_xtables),
|
'header': (DNSHeader, header_xtables),
|
||||||
'question': (DNSQuestion, question_xtables),
|
'question': (DNSQuestion, question_xtables),
|
||||||
'edns': (EDNS, {})}
|
'edns': (EDNS, {})}
|
||||||
for rrtype in dict_rrtype.keys():
|
for rrtype in dict_rrtype:
|
||||||
# For any supported RR types add the tuple of (RR_CLASS, {}).
|
# For any supported RR types add the tuple of (RR_CLASS, {}).
|
||||||
# We expect KeyError as not all the types are supported, and simply
|
# We expect KeyError as not all the types are supported, and simply
|
||||||
# ignore them.
|
# ignore them.
|
||||||
@ -1448,18 +1454,18 @@ def get_config_param(section):
|
|||||||
usage = 'usage: %prog [options] input_file'
|
usage = 'usage: %prog [options] input_file'
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
def main():
|
||||||
parser = OptionParser(usage=usage)
|
parser = argparse.ArgumentParser(usage=usage)
|
||||||
parser.add_option('-o', '--output', action='store', dest='output',
|
parser.add_argument('-o', '--output', action='store', dest='output',
|
||||||
default=None, metavar='FILE',
|
default=None, metavar='FILE',
|
||||||
help='output file name [default: prefix of input_file]')
|
help='output file name [default: prefix of input_file]')
|
||||||
(options, args) = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if len(args) == 0:
|
if len(args) == 0:
|
||||||
parser.error('input file is missing')
|
parser.error('input file is missing')
|
||||||
configfile = args[0]
|
configfile = args[0]
|
||||||
|
|
||||||
outputfile = options.output
|
outputfile = args.output
|
||||||
if not outputfile:
|
if not outputfile:
|
||||||
m = re.match(r'(.*)\.[^.]+$', configfile)
|
m = re.match(r'(.*)\.[^.]+$', configfile)
|
||||||
if m:
|
if m:
|
||||||
@ -1468,12 +1474,12 @@ if __name__ == "__main__":
|
|||||||
raise ValueError('output file is not specified and input file is not in the form of "output_file.suffix"')
|
raise ValueError('output file is not specified and input file is not in the form of "output_file.suffix"')
|
||||||
|
|
||||||
# DeprecationWarning: use ConfigParser directly
|
# DeprecationWarning: use ConfigParser directly
|
||||||
config = configparser.SafeConfigParser()
|
config = configparser.SafeConfigParser() # pylint: disable=deprecated-class
|
||||||
config.read(configfile)
|
config.read(configfile)
|
||||||
|
|
||||||
output = open(outputfile, 'w')
|
output = open(outputfile, 'w', encoding='utf-8') # pylint: disable=consider-using-with
|
||||||
|
|
||||||
print_header(output, configfile)
|
print_header(outputfile, configfile)
|
||||||
|
|
||||||
# First try the 'custom' mode; if it fails assume the query mode.
|
# First try the 'custom' mode; if it fails assume the query mode.
|
||||||
try:
|
try:
|
||||||
@ -1488,3 +1494,7 @@ if __name__ == "__main__":
|
|||||||
obj.dump(output)
|
obj.dump(output)
|
||||||
|
|
||||||
output.close()
|
output.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
@ -305,9 +305,9 @@ def main(parameters):
|
|||||||
# Only print if we have something to print to avoid a newline.
|
# Only print if we have something to print to avoid a newline.
|
||||||
# Also don't clutter output with lines that doesn't cause CI failure if
|
# Also don't clutter output with lines that doesn't cause CI failure if
|
||||||
# there are lines that cause CI failure.
|
# there are lines that cause CI failure.
|
||||||
if len(output_for_latest):
|
if len(output_for_latest) > 0:
|
||||||
print(output_for_latest)
|
print(output_for_latest)
|
||||||
elif len(output_for_other_than_latest):
|
elif len(output_for_other_than_latest) > 0:
|
||||||
print(output_for_other_than_latest)
|
print(output_for_other_than_latest)
|
||||||
|
|
||||||
# Only report errors on the latest upgrade script. For all other upgrade
|
# Only report errors on the latest upgrade script. For all other upgrade
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
# git pull
|
# git pull
|
||||||
# git remote prune origin
|
# git remote prune origin
|
||||||
#
|
#
|
||||||
# This script requires python 2.7 or 3.
|
# This script requires python 3.
|
||||||
#
|
#
|
||||||
# I have limited experience in Python. If things are done in a strange or
|
# I have limited experience in Python. If things are done in a strange or
|
||||||
# uncommon way, there are no obscure reasons to do it that way, just plain
|
# uncommon way, there are no obscure reasons to do it that way, just plain
|
||||||
@ -23,9 +23,7 @@
|
|||||||
#
|
#
|
||||||
# tomek
|
# tomek
|
||||||
|
|
||||||
import string
|
import argparse
|
||||||
import sys
|
|
||||||
from optparse import OptionParser
|
|
||||||
|
|
||||||
# [B404:blacklist] Consider possible security implications associated with subprocess module.
|
# [B404:blacklist] Consider possible security implications associated with subprocess module.
|
||||||
import subprocess # nosec B404
|
import subprocess # nosec B404
|
||||||
@ -157,39 +155,31 @@ def check_output(cmd):
|
|||||||
return subprocess.check_output(cmd) # nosec B603
|
return subprocess.check_output(cmd) # nosec B603
|
||||||
|
|
||||||
|
|
||||||
def parse_args(args=sys.argv[1:], Parser=OptionParser):
|
def parse_args():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="This script prints out merged and/or unmerged branches of a GIT tree.",
|
||||||
|
usage="""%prog
|
||||||
|
Lists all obsolete (fully merged into master) branches.
|
||||||
|
""")
|
||||||
|
|
||||||
parser = Parser(description="This script prints out merged and/or unmerged"
|
parser.add_argument("-c", "--csv", action="store_true",
|
||||||
" branches of a GIT tree.")
|
default=False, help="generates CSV output")
|
||||||
|
parser.add_argument("-u", "--unmerged", action="store_true",
|
||||||
|
default=False, help="lists unmerged branches")
|
||||||
|
parser.add_argument("-m", "--skip-merged", action="store_true",
|
||||||
|
default=False, help="omits listing merged branches")
|
||||||
|
parser.add_argument("-s", "--stats", action="store_true",
|
||||||
|
default=False, help="prints also statistics")
|
||||||
|
|
||||||
parser.add_option("-c", "--csv", action="store_true",
|
return parser.parse_args()
|
||||||
default=False, help="generates CSV output")
|
|
||||||
parser.add_option("-u", "--unmerged", action="store_true",
|
|
||||||
default=False, help="lists unmerged branches")
|
|
||||||
parser.add_option("-m", "--skip-merged", action="store_true",
|
|
||||||
default=False, help="omits listing merged branches")
|
|
||||||
parser.add_option("-s", "--stats", action="store_true",
|
|
||||||
default=False, help="prints also statistics")
|
|
||||||
|
|
||||||
(options, args) = parser.parse_args(args)
|
|
||||||
|
|
||||||
if args:
|
|
||||||
parser.print_help()
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
return options
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
usage = """%prog
|
args = parse_args()
|
||||||
Lists all obsolete (fully merged into master) branches.
|
csv = args.csv
|
||||||
"""
|
merged = not args.skip_merged
|
||||||
|
unmerged = args.unmerged
|
||||||
options = parse_args()
|
stats = args.stats
|
||||||
csv = options.csv
|
|
||||||
merged = not options.skip_merged
|
|
||||||
unmerged = options.unmerged
|
|
||||||
stats = options.stats
|
|
||||||
|
|
||||||
if csv:
|
if csv:
|
||||||
print("branch name,status,date,last commit(mail),last commit(name)")
|
print("branch name,status,date,last commit(mail),last commit(name)")
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
from termcolor import colored, cprint
|
|
||||||
from io import StringIO
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import sqlalchemy as db
|
|
||||||
from sqlalchemy.sql import select
|
|
||||||
import sys
|
import sys
|
||||||
|
from io import StringIO
|
||||||
|
|
||||||
|
import sqlalchemy as db # pylint: disable=import-error
|
||||||
|
from termcolor import cprint # pylint: disable=import-error
|
||||||
|
|
||||||
|
|
||||||
def convert_to_db(entity_name, make_singular=True):
|
def convert_to_db(entity_name, make_singular=True):
|
||||||
@ -86,6 +86,7 @@ class State:
|
|||||||
|
|
||||||
class ConfigFile:
|
class ConfigFile:
|
||||||
def __init__(self, filename):
|
def __init__(self, filename):
|
||||||
|
self.config = {}
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
@ -93,7 +94,7 @@ class ConfigFile:
|
|||||||
print('The all keys file %s does not exist.' % self.filename)
|
print('The all keys file %s does not exist.' % self.filename)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
with open(self.filename) as f:
|
with open(self.filename, encoding='utf-8') as f:
|
||||||
self.config = json.load(f)
|
self.config = json.load(f)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
@ -232,17 +233,17 @@ def main():
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
sanitized_contents = ''
|
sanitized_contents = ''
|
||||||
f = open(args.all_keys_file)
|
with open(args.all_keys_file, encoding='utf-8') as f:
|
||||||
for line in f:
|
for line in f:
|
||||||
sanitized_line = line.strip()
|
sanitized_line = line.strip()
|
||||||
if not sanitized_line:
|
if not sanitized_line:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if sanitized_line.find('//') != -1 or sanitized_line.find('#') != -1:
|
if sanitized_line.find('//') != -1 or sanitized_line.find('#') != -1:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
sanitized_line = sanitized_line.replace(': .', ': 0.')
|
sanitized_line = sanitized_line.replace(': .', ': 0.')
|
||||||
sanitized_contents = sanitized_contents + sanitized_line
|
sanitized_contents = sanitized_contents + sanitized_line
|
||||||
|
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
@ -160,7 +160,8 @@ def process_file(filename):
|
|||||||
Parameters:
|
Parameters:
|
||||||
filename Name of the message file to process
|
filename Name of the message file to process
|
||||||
"""
|
"""
|
||||||
lines = open(filename).read().splitlines()
|
with open(filename, encoding='utf-8') as f:
|
||||||
|
lines = f.read().splitlines()
|
||||||
|
|
||||||
# Search for the first line starting with the percent character. Everything
|
# Search for the first line starting with the percent character. Everything
|
||||||
# before it is considered the file header and is copied to the output with
|
# before it is considered the file header and is copied to the output with
|
||||||
|
Loading…
x
Reference in New Issue
Block a user