def red(txt):
- """Return colorized (if the terminal supports it) or plain text"""
+ """Return colorized (if the terminal supports it) or plain text."""
if sys.stdout.isatty():
return '\033[1;31m%s\033[0;0m' % txt
return txt
def green(txt):
- """Return colorized (if the terminal supports it) or plain text"""
+ """Return colorized (if the terminal supports it) or plain text."""
if sys.stdout.isatty():
return '\033[0;32m%s\033[0;0m' % txt
return txt
def blue(txt):
- """Return colorized (if the terminal supports it) or plain text"""
+ """Return colorized (if the terminal supports it) or plain text."""
if sys.stdout.isatty():
return '\033[0;34m%s\033[0;0m' % txt
return txt
pass
-def execute(cmd, timeout=60, cwd=None, env=None, raise_error=True, dry_run=False, log_file_path=None, quiet=False, check_times=False, capture=False,
- interactive=False, attempts=1, sleep_time_after_attempt=None):
+def execute(cmd, timeout=60, cwd=None, env=None, raise_error=True, dry_run=False, log_file_path=None,
+ quiet=False, check_times=False, capture=False, interactive=False, attempts=1,
+ sleep_time_after_attempt=None):
"""Execute a command in shell.
:param str cmd: a command to be executed
- :param int timeout: timeout in number of seconds, after that time the command is terminated but only if check_times is True
+ :param int timeout: timeout in number of seconds, after that time the command is terminated
+ but only if check_times is True
:param str cwd: current working directory for the command
:param dict env: dictionary with environment variables
- :param bool raise_error: if False then in case of error exception is not raised, default: True ie exception is raise
+ :param bool raise_error: if False then in case of error exception is not raised,
+ default: True ie exception is raise
:param bool dry_run: if True then the command is not executed
:param str log_file_path: if provided then all traces from the command are stored in indicated file
:param bool quiet: if True then the command's traces are not printed to stdout
:param bool check_times: if True then timeout is taken into account
:param bool capture: if True then the command's traces are captured and returned by the function
- :param bool interactive: if True then stdin and stdout are not redirected, traces handling is disabled, used for e.g. SSH
+ :param bool interactive: if True then stdin and stdout are not redirected, traces handling is disabled,
+ used for e.g. SSH
:param int attemts: number of attempts to run the command if it fails
:param int sleep_time_after_attempt: number of seconds to sleep before taking next attempt
"""
# If no exitcode yet, ie. process is still running then it means that timeout occured.
# In such case terminate the process and raise an exception.
if p.poll() is None:
- p.terminate()
+ # 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)
raise ExecutionError('Execution timeout')
exitcode = p.returncode
def install_pkgs(pkgs, timeout=60, env=None, check_times=False):
- """Installs native packages in a system.
+ """Install native packages in a system.
:param dict pkgs: specifies a list of packages to be installed
:param int timeout: timeout in number of seconds, after that time the command
for Kea build and building Kea.
"""
- def __init__(self, provider, system, sys_revision, features, image_template_variant, dry_run, quiet=False, check_times=False):
+ def __init__(self, provider, system, revision, features, image_template_variant,
+ dry_run, quiet=False, check_times=False):
+ """VagrantEnv initializer.
+
+ :param str provider: indicate backend type: virtualbox or lxc
+ :param str system: name of the system eg. ubuntu
+ :param str revision: revision of the system e.g. 18.04
+ :param list features: list of requested features
+ :param str image_template_variant: variant of images' templates: bare or kea
+ :param bool dry_run: if False then system commands are not really executed
+ :param bool quiet: if True then commands will not trace to stdout
+ :param bool check_times: if True then commands will be terminated after given timeout
+ """
self.provider = provider
self.system = system
- self.sys_revision = sys_revision
+ self.revision = revision
self.features = features
self.dry_run = dry_run
self.quiet = quiet
elif provider == "lxc":
vagrantfile_tpl = LXC_VAGRANTFILE_TPL
- image_tpl = IMAGE_TEMPLATES["%s-%s-%s" % (system, sys_revision, provider)][image_template_variant]
+ key = "%s-%s-%s" % (system, revision, provider)
+ image_tpl = IMAGE_TEMPLATES[key][image_template_variant]
self.repo_dir = os.getcwd()
- sys_dir = "%s-%s" % (system, sys_revision)
+ sys_dir = "%s-%s" % (system, revision)
if provider == "virtualbox":
self.vagrant_dir = os.path.join(self.repo_dir, 'hammer', sys_dir, 'vbox')
elif provider == "lxc":
pass
crc = binascii.crc32(self.vagrant_dir.encode())
- self.name = "hmr-%s-%s-kea-srv-%08d" % (system, sys_revision.replace('.', '-'), crc)
+ self.name = "hmr-%s-%s-kea-srv-%08d" % (system, revision.replace('.', '-'), crc)
vagrantfile = vagrantfile_tpl.format(image_tpl=image_tpl,
name=self.name)
log.info('Prepared vagrant system %s in %s', self.name, self.vagrant_dir)
def up(self):
+ """Do Vagrant up."""
execute("vagrant box update", cwd=self.vagrant_dir, timeout=20 * 60, dry_run=self.dry_run)
- execute("vagrant up --no-provision --provider %s" % self.provider, cwd=self.vagrant_dir, timeout=15 * 60, dry_run=self.dry_run)
+ execute("vagrant up --no-provision --provider %s" % self.provider,
+ cwd=self.vagrant_dir, timeout=15 * 60, dry_run=self.dry_run)
def package(self):
"""Package Vagrant system into Vagrant box."""
if self.provider == 'virtualbox':
- cmd = "vagrant package --output kea-%s-%s.box" % (self.system, self.sys_revision)
+ cmd = "vagrant package --output kea-%s-%s.box" % (self.system, self.revision)
execute(cmd, cwd=self.vagrant_dir, timeout=4 * 60, dry_run=self.dry_run)
elif self.provider == 'lxc':
execute('vagrant halt', cwd=self.vagrant_dir, dry_run=self.dry_run, raise_error=False)
- box_path = os.path.join(self.vagrant_dir, 'kea-%s-%s.box' % (self.system, self.sys_revision))
+ box_path = os.path.join(self.vagrant_dir, 'kea-%s-%s.box' % (self.system, self.revision))
if os.path.exists(box_path):
os.unlink(box_path)
execute('sudo rm -rf %s' % lxc_box_dir)
os.mkdir(lxc_box_dir)
lxc_container_path = os.path.join('/var/lib/lxc', self.name)
- execute('sudo bash -c \'echo "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+'
- 'kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo'
- '3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2M'
- 'WZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEg'
- 'E98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key" > %s/rootfs/home/vagrant/.ssh/authorized_keys\'' % lxc_container_path)
- cmd = 'sudo bash -c "cd %s && tar --numeric-owner --anchored --exclude=./rootfs/dev/log -czf %s/rootfs.tar.gz ./rootfs/*"'
+ execute('sudo bash -c \'echo "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8ia'
+ 'llvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ'
+ '6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTB'
+ 'ckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6k'
+ 'ivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmB'
+ 'YSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYC'
+ 'zRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key"'
+ '> %s/rootfs/home/vagrant/.ssh/authorized_keys\'' % lxc_container_path)
+ cmd = 'sudo bash -c "'
+ cmd += 'cd %s '
+ cmd += '&& tar --numeric-owner --anchored --exclude=./rootfs/dev/log -czf %s/rootfs.tar.gz ./rootfs/*'
+ cmd += '"'
execute(cmd % (lxc_container_path, lxc_box_dir))
execute('sudo cp %s/config %s/lxc-config' % (lxc_container_path, lxc_box_dir))
execute('sudo chown `id -un`:`id -gn` *', cwd=lxc_box_dir)
if not tarball_path:
name_ver = 'kea-1.5.0'
cmd = 'tar --transform "flags=r;s|^|%s/|" --exclude hammer ' % name_ver
- cmd += ' --exclude "*~" --exclude .git --exclude .libs --exclude .deps --exclude \'*.o\' --exclude \'*.lo\' '
+ cmd += ' --exclude "*~" --exclude .git --exclude .libs '
+ cmd += ' --exclude .deps --exclude \'*.o\' --exclude \'*.lo\' '
cmd += ' -zcf /tmp/%s.tar.gz .' % name_ver
execute(cmd)
tarball_path = '/tmp/%s.tar.gz' % name_ver
passed = 0
try:
if 'unittest' in self.features:
- execute('scp -F %s -r default:/home/vagrant/unit-test-results.json .' % ssh_cfg_path, cwd=self.vagrant_dir)
+ cmd = 'scp -F %s -r default:/home/vagrant/unit-test-results.json .' % ssh_cfg_path
+ execute(cmd, cwd=self.vagrant_dir)
results_file = os.path.join(self.vagrant_dir, 'unit-test-results.json')
if os.path.exists(results_file):
with open(results_file) as f:
return total, passed
def destroy(self):
- """Removes the VM completely."""
+ """Remove the VM completely."""
cmd = 'vagrant destroy --force'
execute(cmd, cwd=self.vagrant_dir, timeout=3 * 60, dry_run=self.dry_run) # timeout: 3 minutes
env = os.environ.copy()
env['LANGUAGE'] = env['LANG'] = env['LC_ALL'] = 'C'
- 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, quiet=quiet, check_times=self.check_times)
+ 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,
+ quiet=quiet, check_times=self.check_times)
def prepare_system(self):
"""Prepare Vagrant system for building Kea."""
self.nofeatures_arg = ''
# select proper python version for running Hammer inside Vagrant system
- if self.system == 'centos' and self.sys_revision == '7' or (self.system == 'debian' and self.sys_revision == '8' and self.provider != 'lxc'):
+ if (self.system == 'centos' and self.revision == '7' or
+ (self.system == 'debian' and self.revision == '8' and self.provider != 'lxc')):
self.python = 'python'
elif self.system == 'freebsd':
self.python = 'python3.6'
self.python = 'python3'
# to get python in RHEL 8 beta it is required first register machine in RHEL account
- if self.system == 'rhel' and self.sys_revision == '8':
- exitcode = self.execute("sudo subscription-manager repos --list-enabled | grep rhel-8-for-x86_64-baseos-beta-rpms", raise_error=False)
+ if self.system == 'rhel' and self.revision == '8':
+ cmd = "sudo subscription-manager repos --list-enabled | grep rhel-8-for-x86_64-baseos-beta-rpms"
+ exitcode = self.execute(cmd, raise_error=False)
if exitcode != 0:
env = os.environ.copy()
with open(os.path.expanduser('~/rhel-creds.txt')) as f:
"""Install gtest sources."""
# download gtest sources only if it is not present as native package
if not os.path.exists('/usr/src/googletest-release-1.8.0/googletest'):
- execute('wget --no-verbose -O /tmp/gtest.tar.gz https://github.com/google/googletest/archive/release-1.8.0.tar.gz')
+ cmd = 'wget --no-verbose -O /tmp/gtest.tar.gz '
+ cmd += 'https://github.com/google/googletest/archive/release-1.8.0.tar.gz'
+ execute(cmd)
execute('sudo tar -C /usr/src -zxf /tmp/gtest.tar.gz')
os.unlink('/tmp/gtest.tar.gz')
def _configure_mysql(system, revision, features):
- """Configures MySQL database."""
+ """Configure MySQL database."""
if system in ['fedora', 'centos']:
execute('sudo systemctl enable mariadb.service')
execute('sudo systemctl start mariadb.service')
time.sleep(5)
if system == 'freebsd':
- cmd = "echo 'SET PASSWORD = \"\";' | sudo mysql -u root --password=\"$(sudo cat /root/.mysql_secret | grep -v '#')\" --connect-expired-password"
+ cmd = "echo 'SET PASSWORD = \"\";' "
+ cmd += "| sudo mysql -u root --password=\"$(sudo cat /root/.mysql_secret | grep -v '#')\" --connect-expired-password"
execute(cmd, raise_error=False)
cmd = "echo 'DROP DATABASE IF EXISTS keatest;' | sudo mysql -u root"
def _install_cassandra_deb(env, check_times):
- """Installs Cassandra and cpp-driver using DEB package."""
+ """Install Cassandra and cpp-driver using DEB package."""
if not os.path.exists('/usr/sbin/cassandra'):
- execute('echo "deb http://www.apache.org/dist/cassandra/debian 311x main" | sudo tee /etc/apt/sources.list.d/cassandra.sources.list',
+ cmd = 'echo "deb http://www.apache.org/dist/cassandra/debian 311x main" '
+ cmd += '| sudo tee /etc/apt/sources.list.d/cassandra.sources.list'
+ execute(cmd, env=env, check_times=check_times)
+ execute('wget -qO- https://www.apache.org/dist/cassandra/KEYS | sudo apt-key add -',
env=env, check_times=check_times)
- execute('wget -qO- https://www.apache.org/dist/cassandra/KEYS | sudo apt-key add -', env=env, check_times=check_times)
execute('sudo apt update', env=env, check_times=check_times)
install_pkgs('cassandra libuv1 pkgconf', env=env, check_times=check_times)
env=env, check_times=check_times)
execute('wget http://downloads.datastax.com/cpp-driver/ubuntu/18.04/cassandra/v2.11.0/cassandra-cpp-driver_2.11.0-1_amd64.deb',
env=env, check_times=check_times)
- execute('sudo dpkg -i cassandra-cpp-driver-dev_2.11.0-1_amd64.deb cassandra-cpp-driver_2.11.0-1_amd64.deb', env=env, check_times=check_times)
- execute('rm -rf cassandra-cpp-driver-dev_2.11.0-1_amd64.deb cassandra-cpp-driver_2.11.0-1_amd64.deb', env=env, check_times=check_times)
+ execute('sudo dpkg -i cassandra-cpp-driver-dev_2.11.0-1_amd64.deb cassandra-cpp-driver_2.11.0-1_amd64.deb',
+ env=env, check_times=check_times)
+ execute('rm -rf cassandra-cpp-driver-dev_2.11.0-1_amd64.deb cassandra-cpp-driver_2.11.0-1_amd64.deb',
+ env=env, check_times=check_times)
def _install_freeradius_client(env, check_times):
execute('rm -rf freeradius-client')
-def _install_cassandra_rpm(system, env, check_times):
- """Installs Cassandra and cpp-driver using RPM package."""
+def _install_cassandra_rpm(env, check_times):
+ """Install Cassandra and cpp-driver using RPM package."""
if not os.path.exists('/usr/bin/cassandra'):
#execute('sudo dnf config-manager --add-repo https://www.apache.org/dist/cassandra/redhat/311x/')
#execute('sudo rpm --import https://www.apache.org/dist/cassandra/KEYS')
# prepare fedora
if system == 'fedora':
- packages = ['make', 'autoconf', 'automake', 'libtool', 'gcc-c++', 'openssl-devel', 'log4cplus-devel', 'boost-devel']
+ packages = ['make', 'autoconf', 'automake', 'libtool', 'gcc-c++', 'openssl-devel',
+ 'log4cplus-devel', 'boost-devel']
if 'native-pkg' in features:
packages.extend(['rpm-build', 'mariadb-connector-c-devel'])
execute('sudo dnf clean packages', env=env, check_times=check_times)
if 'cql' in features:
- _install_cassandra_rpm(system, env, check_times)
+ _install_cassandra_rpm(env, check_times)
# prepare centos
elif system == 'centos':
install_pkgs('epel-release', env=env, check_times=check_times)
- packages = ['make', 'autoconf', 'automake', 'libtool', 'gcc-c++', 'openssl-devel', 'log4cplus-devel', 'boost-devel',
- 'mariadb-devel', 'postgresql-devel']
+ packages = ['make', 'autoconf', 'automake', 'libtool', 'gcc-c++', 'openssl-devel',
+ 'log4cplus-devel', 'boost-devel', 'mariadb-devel', 'postgresql-devel']
if 'docs' in features:
packages.extend(['libxslt', 'elinks', 'docbook-style-xsl'])
_install_gtest_sources()
if 'cql' in features:
- _install_cassandra_rpm(system, env, check_times)
+ _install_cassandra_rpm(env, check_times)
# prepare rhel
elif system == 'rhel':
execute('wget --no-verbose -O srpms/log4cplus-1.1.3-0.4.rc3.el7.src.rpm '
'https://rpmfind.net/linux/epel/7/SRPMS/Packages/l/log4cplus-1.1.3-0.4.rc3.el7.src.rpm',
check_times=check_times)
- execute('rpmbuild --rebuild srpms/log4cplus-1.1.3-0.4.rc3.el7.src.rpm', env=env, timeout=120, check_times=check_times)
- execute('sudo rpm -i rpmbuild/RPMS/x86_64/log4cplus-1.1.3-0.4.rc3.el8.x86_64.rpm', env=env, check_times=check_times)
- execute('sudo rpm -i rpmbuild/RPMS/x86_64/log4cplus-devel-1.1.3-0.4.rc3.el8.x86_64.rpm', env=env, check_times=check_times)
+ execute('rpmbuild --rebuild srpms/log4cplus-1.1.3-0.4.rc3.el7.src.rpm',
+ env=env, timeout=120, check_times=check_times)
+ execute('sudo rpm -i rpmbuild/RPMS/x86_64/log4cplus-1.1.3-0.4.rc3.el8.x86_64.rpm',
+ env=env, check_times=check_times)
+ execute('sudo rpm -i rpmbuild/RPMS/x86_64/log4cplus-devel-1.1.3-0.4.rc3.el8.x86_64.rpm',
+ env=env, check_times=check_times)
if 'unittest' in features:
_install_gtest_sources()
if 'cql' in features:
- _install_cassandra_rpm(system, env, check_times)
+ _install_cassandra_rpm(env, check_times)
# prepare ubuntu
elif system == 'ubuntu':
execute('sudo apt update', env=env, check_times=check_times, attempts=3, sleep_time_after_attempt=10)
- packages = ['gcc', 'g++', 'make', 'autoconf', 'automake', 'libtool', 'libssl-dev', 'liblog4cplus-dev', 'libboost-system-dev']
+ packages = ['gcc', 'g++', 'make', 'autoconf', 'automake', 'libtool', 'libssl-dev', 'liblog4cplus-dev',
+ 'libboost-system-dev']
if 'unittest' in features:
if revision.startswith('16.'):
if 'native-pkg' in features:
packages.extend(['build-essential', 'fakeroot', 'devscripts'])
- packages.extend(['bison', 'debhelper', 'default-libmysqlclient-dev', 'libmysqlclient-dev', 'docbook', 'docbook-xsl', 'flex', 'libboost-dev',
- 'libpq-dev', 'postgresql-server-dev-all', 'python3-dev'])
+ packages.extend(['bison', 'debhelper', 'default-libmysqlclient-dev', 'libmysqlclient-dev',
+ 'docbook', 'docbook-xsl', 'flex', 'libboost-dev', 'libpq-dev',
+ 'postgresql-server-dev-all', 'python3-dev'])
if 'mysql' in features:
if revision == '16.04':
elif system == 'debian':
execute('sudo apt update', env=env, check_times=check_times, attempts=3, sleep_time_after_attempt=10)
- packages = ['gcc', 'g++', 'make', 'autoconf', 'automake', 'libtool', 'libssl-dev', 'liblog4cplus-dev', 'libboost-system-dev']
+ packages = ['gcc', 'g++', 'make', 'autoconf', 'automake', 'libtool', 'libssl-dev',
+ 'liblog4cplus-dev', 'libboost-system-dev']
if 'docs' in features:
packages.extend(['dblatex', 'xsltproc', 'elinks', 'docbook-xsl'])
elif system == 'freebsd':
packages = ['autoconf', 'automake', 'libtool', 'openssl', 'log4cplus', 'boost-libs']
- # TODO:
- #execute('sudo portsnap --interactive fetch', timeout=240, check_times=check_times)
- #execute('sudo portsnap extract /usr/ports/devel/log4cplus', timeout=240, check_times=check_times)
- #execute('sudo make -C /usr/ports/devel/log4cplus install clean BATCH=yes', timeout=240, check_times=check_times)
-
if 'docs' in features:
packages.extend(['libxslt', 'elinks', 'docbook-xsl'])
if 'mysql' in features:
execute('sudo sysrc mysql_enable="yes"', env=env, check_times=check_times)
- execute('sudo service mysql-server start', env=env, check_times=check_times, raise_error=False)
+ execute('sudo service mysql-server start', env=env, check_times=check_times,
+ raise_error=False)
else:
raise NotImplementedError
log.info('Preparing deps completed successfully.')
-def prepare_system_in_vagrant(provider, system, sys_revision, features, dry_run, check_times, clean_start):
+def prepare_system_in_vagrant(provider, system, revision, features, dry_run, check_times,
+ clean_start):
"""Prepare specified system in Vagrant according to specified features."""
- ve = VagrantEnv(provider, system, sys_revision, features, 'kea', dry_run, check_times=check_times)
+ ve = VagrantEnv(provider, system, revision, features, 'kea', dry_run, check_times=check_times)
if clean_start:
ve.destroy()
ve.up()
def _calculate_build_timeout(features):
- """Returns maximum allowed time for build (in seconds)"""
+ """Return maximum allowed time for build (in seconds)."""
timeout = 60
if 'mysql' in features:
timeout += 60
return timeout
-def _build_just_binaries(distro, revision, features, tarball_path, env, check_times, jobs, dry_run):
+def _build_binaries_and_run_ut(system, revision, features, tarball_path, env, check_times, jobs, dry_run):
if tarball_path:
# unpack tarball with sources
execute('sudo rm -rf kea-src')
cmd += ' --with-cql=/usr/bin/pkg-config'
if 'unittest' in features:
# prepare gtest switch - use downloaded gtest sources only if it is not present as native package
- if distro in ['centos', 'fedora', 'rhel', 'freebsd']:
+ if system in ['centos', 'fedora', 'rhel', 'freebsd']:
cmd += ' --with-gtest-source=/usr/src/googletest-release-1.8.0/googletest/'
- elif distro == 'debian' and revision == '8':
+ elif system == 'debian' and revision == '8':
cmd += ' --with-gtest-source=/usr/src/googletest-release-1.8.0/googletest/'
- elif distro == 'debian':
+ elif system == 'debian':
cmd += ' --with-gtest-source=/usr/src/googletest/googletest'
- elif distro == 'ubuntu':
+ elif system == 'ubuntu':
if revision.startswith('16.'):
cmd += ' --with-gtest-source=/usr/src/googletest-release-1.8.0/googletest/'
else:
cmd += ' --with-gtest-source=/usr/src/googletest/googletest'
else:
raise NotImplementedError
- if 'docs' in features and not (distro == 'rhel' and revision == '8'):
+ if 'docs' in features and not (system == 'rhel' and revision == '8'):
cmd += ' --enable-generate-docs'
if 'radius' in features:
cmd += ' --with-freeradius=/usr/local'
# estimate number of processes (jobs) to use in compilation if jobs are not provided
if jobs == 0:
cpus = multiprocessing.cpu_count() - 1
- if distro == 'centos':
+ if system == 'centos':
cpus = cpus // 2
if cpus == 0:
cpus = 1
env['GTEST_OUTPUT'] = 'xml:%s/' % results_dir
env['KEA_SOCKET_TEST_DIR'] = '/tmp/'
# run unit tests
- execute('make check -k', cwd=src_path, env=env, timeout=60 * 60, raise_error=False, check_times=check_times, dry_run=dry_run)
+ execute('make check -k',
+ cwd=src_path, env=env, timeout=60 * 60, raise_error=False,
+ check_times=check_times, dry_run=dry_run)
# parse unit tests results
results = {}
execute('kea-admin lease-init pgsql -u keauser -p keapass -n keadb', dry_run=dry_run)
-def _build_native_pkg(distro, features, tarball_path, env, check_times, dry_run):
- """Builds native (RPM or DEB) packages."""
- if distro in ['fedora', 'centos', 'rhel']:
+def _build_native_pkg(system, features, tarball_path, env, check_times, dry_run):
+ """Build native (RPM or DEB) packages."""
+ if system in ['fedora', 'centos', 'rhel']:
# prepare RPM environment
execute('rm -rf rpm-root', dry_run=dry_run)
os.mkdir('rpm-root')
if 'install' in features:
execute('sudo rpm -i rpm-root/RPMS/x86_64/*rpm', check_times=check_times, dry_run=dry_run)
- elif distro in ['ubuntu', 'debian']:
+ elif system in ['ubuntu', 'debian']:
# unpack tarball
execute('sudo rm -rf kea-src', check_times=check_times, dry_run=dry_run)
os.mkdir('kea-src')
src_path = glob.glob('kea-src/*')[0]
# do deb build
- execute('debuild -i -us -uc -b', env=env, cwd=src_path, timeout=60 * 40, check_times=check_times, dry_run=dry_run)
+ execute('debuild -i -us -uc -b', env=env, cwd=src_path,
+ timeout=60 * 40, check_times=check_times, dry_run=dry_run)
if 'install' in features:
execute('sudo dpkg -i kea-src/*deb', check_times=check_times, dry_run=dry_run)
env = os.environ.copy()
env['LANGUAGE'] = env['LANG'] = env['LC_ALL'] = 'C'
- distro, revision = get_system_revision()
+ system, revision = get_system_revision()
execute('df -h', dry_run=dry_run)
tarball_path = os.path.abspath(tarball_path)
if 'native-pkg' in features:
- # native pkg build
- _build_native_pkg(distro, features, tarball_path, env, check_times, dry_run)
+ _build_native_pkg(system, features, tarball_path, env, check_times, dry_run)
else:
- # build straight from sources
- _build_just_binaries(distro, revision, features, tarball_path, env, check_times, jobs, dry_run)
+ _build_binaries_and_run_ut(system, revision, features, tarball_path, env, check_times, jobs, dry_run)
execute('df -h', dry_run=dry_run)
-def build_in_vagrant(provider, system, sys_revision, features, leave_system, tarball_path, dry_run, quiet, clean_start, check_times, jobs):
+def build_in_vagrant(provider, system, revision, features, leave_system, tarball_path,
+ dry_run, quiet, clean_start, check_times, jobs):
"""Build Kea via Vagrant in specified system with specified features."""
log.info('')
- log.info(">>> Building %s, %s, %s", provider, system, sys_revision)
+ log.info(">>> Building %s, %s, %s", provider, system, revision)
log.info('')
t0 = time.time()
total = 0
passed = 0
try:
- ve = VagrantEnv(provider, system, sys_revision, features, 'kea', dry_run, quiet, check_times)
+ ve = VagrantEnv(provider, system, revision, features, 'kea', dry_run, quiet, check_times)
if clean_start:
ve.destroy()
ve.up()
dt = int(t1 - t0)
log.info('')
- log.info(">>> Building %s, %s, %s completed in %s:%s%s", provider, system, sys_revision, dt // 60, dt % 60, msg)
+ log.info(">>> Building %s, %s, %s completed in %s:%s%s", provider, system, revision, dt // 60, dt % 60, msg)
log.info('')
return dt, error, total, passed
-def package_box(provider, system, sys_revision, features, dry_run, check_times):
+def package_box(provider, system, revision, features, dry_run, check_times):
"""Prepare Vagrant box of specified system."""
- ve = VagrantEnv(provider, system, sys_revision, features, 'bare', dry_run, check_times=check_times)
+ ve = VagrantEnv(provider, system, revision, features, 'bare', dry_run, check_times=check_times)
ve.destroy()
ve.up()
ve.prepare_system()
ve.package()
-def ssh(provider, system, sys_revision):
- ve = VagrantEnv(provider, system, sys_revision, [], 'kea', False)
+def ssh(provider, system, revision):
+ """Invoke Vagrant ssh for given system."""
+ ve = VagrantEnv(provider, system, revision, [], 'kea', False)
ve.up()
ve.ssh()
def ensure_hammer_deps():
"""Install Hammer dependencies onto current, host system."""
- distro, _ = get_system_revision()
+ system, _ = get_system_revision()
exitcode = execute('vagrant version', raise_error=False)
if exitcode != 0:
- if distro in ['fedora', 'centos', 'rhel']:
- execute('wget --no-verbose -O /tmp/vagrant_2.2.2_x86_64.rpm https://releases.hashicorp.com/vagrant/2.2.2/vagrant_2.2.2_x86_64.rpm')
+ if system in ['fedora', 'centos', 'rhel']:
+ cmd = 'wget --no-verbose -O /tmp/vagrant_2.2.2_x86_64.rpm '
+ cmd += 'https://releases.hashicorp.com/vagrant/2.2.2/vagrant_2.2.2_x86_64.rpm'
+ execute(cmd)
execute('sudo rpm -i /tmp/vagrant_2.2.2_x86_64.rpm')
os.unlink('/tmp/vagrant_2.2.2_x86_64.rpm')
- elif distro in ['debian', 'ubuntu']:
- execute('wget --no-verbose -O /tmp/vagrant_2.2.2_x86_64.deb https://releases.hashicorp.com/vagrant/2.2.2/vagrant_2.2.2_x86_64.deb')
+ elif system in ['debian', 'ubuntu']:
+ cmd = 'wget --no-verbose -O /tmp/vagrant_2.2.2_x86_64.deb '
+ cmd += 'https://releases.hashicorp.com/vagrant/2.2.2/vagrant_2.2.2_x86_64.deb'
+ execute(cmd)
execute('sudo dpkg -i /tmp/vagrant_2.2.2_x86_64.deb')
os.unlink('/tmp/vagrant_2.2.2_x86_64.deb')
else:
for v in values2:
if v not in ALL_FEATURES:
- raise argparse.ArgumentError(self, "feature '%s' is not supported. List of supported features: %s." % (v, ", ".join(ALL_FEATURES)))
+ msg = "feature '%s' is not supported. List of supported features: %s."
+ msg = msg % (v, ", ".join(ALL_FEATURES))
+ raise argparse.ArgumentError(self, msg)
setattr(namespace, self.dest, values2)
DEFAULT_FEATURES = ['install', 'unittest', 'docs']
-ALL_FEATURES = ['install', 'distcheck', 'unittest', 'docs', 'mysql', 'pgsql', 'cql', 'native-pkg', 'radius', 'shell', 'forge']
+ALL_FEATURES = ['install', 'distcheck', 'unittest', 'docs', 'mysql', 'pgsql', 'cql', 'native-pkg',
+ 'radius', 'shell', 'forge']
def parse_args():
- fl = functools.partial(lambda w, t: textwrap.fill(t, w), 80) # used lambda to change args order and able to substitute width
+ """Parse arguments."""
+ # used lambda to change args order and able to substitute width
+ fl = functools.partial(lambda w, t: textwrap.fill(t, w), 80)
description = [
"Hammer - Kea development environment management tool.\n",
fl("At first it is required to install Hammer dependencies which is Vagrant and either "
subparsers = main_parser.add_subparsers(dest='command',
title="Hammer commands",
description=fl("The following commands are provided by Hammer. "
- "To get more information about particular command invoke: ./hammer.py <command> -h."))
+ "To get more information about particular command invoke: "
+ "./hammer.py <command> -h."))
parent_parser1 = argparse.ArgumentParser(add_help=False)
- parent_parser1.add_argument('-p', '--provider', default='virtualbox', choices=['lxc', 'virtualbox', 'local', 'all'],
- help="Backend build executor. If 'all' then build is executed several times on all providers. "
- "If 'local' then build is executed on current system. Default is 'virtualbox'.")
+ parent_parser1.add_argument('-p', '--provider', default='virtualbox',
+ choices=['lxc', 'virtualbox', 'local', 'all'],
+ help="Backend build executor. If 'all' then build is executed several times "
+ "on all providers. If 'local' then build is executed on current system. "
+ "Default is 'virtualbox'.")
parent_parser1.add_argument('-s', '--system', default='all', choices=list(SYSTEMS.keys()) + ['all'],
- help="Build is executed on selected system. If 'all' then build is executed several times on all systems. "
- "If provider is 'local' then this option is ignored. Default is 'all'.")
+ help="Build is executed on selected system. If 'all' then build is executed "
+ "several times on all systems. If provider is 'local' then this option is ignored. "
+ "Default is 'all'.")
parent_parser1.add_argument('-r', '--revision', default='all',
help="Revision of selected system. If 'all' then build is executed several times "
- "on all revisions of selected system. To list supported systems and their revisions invoke 'supported-systems'. "
- "Default is 'all'.")
+ "on all revisions of selected system. To list supported systems and their revisions "
+ "invoke 'supported-systems'. Default is 'all'.")
parent_parser2 = argparse.ArgumentParser(add_help=False)
hlp = "Enable features. Separate them by space or comma. List of available features: %s. Default is '%s'."
hlp = hlp % (", ".join(ALL_FEATURES), ' '.join(DEFAULT_FEATURES))
- parent_parser2.add_argument('-w', '--with', metavar='FEATURE', nargs='+', default=set(), action=CollectCommaSeparatedArgsAction, help=hlp)
- hlp = "Disable features. Separate them by space or comma. List of available features: %s. Default is ''." % ", ".join(ALL_FEATURES)
- parent_parser2.add_argument('-x', '--without', metavar='FEATURE', nargs='+', default=set(), action=CollectCommaSeparatedArgsAction, help=hlp)
+ parent_parser2.add_argument('-w', '--with', metavar='FEATURE', nargs='+', default=set(),
+ action=CollectCommaSeparatedArgsAction, help=hlp)
+ hlp = "Disable features. Separate them by space or comma. List of available features: %s. Default is ''."
+ hlp = hlp % ", ".join(ALL_FEATURES)
+ parent_parser2.add_argument('-x', '--without', metavar='FEATURE', nargs='+', default=set(),
+ action=CollectCommaSeparatedArgsAction, help=hlp)
parent_parser2.add_argument('-l', '--leave-system', action='store_true',
- help='At the end of the command do not destroy vagrant system. Default behavior is destroing the system.')
- parent_parser2.add_argument('-c', '--clean-start', action='store_true', help='If there is pre-existing system then it is destroyed first.')
- parent_parser2.add_argument('-i', '--check-times', action='store_true', help='Do not allow executing commands infinitelly.')
+ help='At the end of the command do not destroy vagrant system. Default behavior is '
+ 'destroing the system.')
+ parent_parser2.add_argument('-c', '--clean-start', action='store_true',
+ help='If there is pre-existing system then it is destroyed first.')
+ parent_parser2.add_argument('-i', '--check-times', action='store_true',
+ help='Do not allow executing commands infinitelly.')
parent_parser2.add_argument('-n', '--dry-run', action='store_true', help='Print only what would be done.')
- parser = subparsers.add_parser('ensure-hammer-deps', help="Install Hammer dependencies on current, host system.")
- parser = subparsers.add_parser('supported-systems', help="List system supported by Hammer for doing Kea development.")
+ parser = subparsers.add_parser('ensure-hammer-deps',
+ help="Install Hammer dependencies on current, host system.")
+ parser = subparsers.add_parser('supported-systems',
+ help="List system supported by Hammer for doing Kea development.")
parser = subparsers.add_parser('build', help="Prepare system and run Kea build in indicated system.",
parents=[parent_parser1, parent_parser2])
- parser.add_argument('-j', '--jobs', default=0, help='Number of processes used in compilation. Override make -j default value.')
+ parser.add_argument('-j', '--jobs', default=0,
+ help='Number of processes used in compilation. Override make -j default value.')
parser.add_argument('-t', '--from-tarball', metavar='TARBALL_PATH',
- help='Instead of building sources in current folder use provided tarball package (e.g. tar.gz).')
+ help='Instead of building sources in current folder use provided tarball '
+ 'package (e.g. tar.gz).')
parser = subparsers.add_parser('prepare-system',
- help="Prepare system for doing Kea development i.e. install all required dependencies "
- "and pre-configure the system. build command always first calls prepare-system internally.",
+ help="Prepare system for doing Kea development i.e. install all required "
+ "dependencies and pre-configure the system. build command always first calls "
+ "prepare-system internally.",
parents=[parent_parser1, parent_parser2])
parser = subparsers.add_parser('ssh', help="SSH to indicated system.",
formatter_class=argparse.RawDescriptionHelpFormatter,
- description="Allows getting into the system using SSH. If the system is not present then it will be created first "
- "but not prepared. The command can be run in 2 way: "
- "\n1) ./hammer.py ssh -p <provider> -s <system> -r <revision>\n2) ./hammer.py ssh -d <path-to-vagrant-dir>",
+ description="Allows getting into the system using SSH. If the system is "
+ "not present then it will be created first but not prepared. The command "
+ "can be run in 2 way: \n"
+ "1) ./hammer.py ssh -p <provider> -s <system> -r <revision>\n"
+ "2) ./hammer.py ssh -d <path-to-vagrant-dir>",
parents=[parent_parser1])
parser.add_argument('-d', '--directory', help='Path to directory with Vagrantfile.')
parser = subparsers.add_parser('created-systems', help="List ALL systems created by Hammer.")
"To get the list of created systems run: ./hammer.py created-systems.")
parser.add_argument('-d', '--directory', help='Path to directory with Vagrantfile.')
parser = subparsers.add_parser('package-box',
- help="Package currently running system into Vagrant Box. Prepared box can be later deployed to Vagrant Cloud.",
+ help="Package currently running system into Vagrant Box. Prepared box can be "
+ "later deployed to Vagrant Cloud.",
parents=[parent_parser1, parent_parser2])
args = main_parser.parse_args()
def list_supported_systems():
- """Lists systems hammer can support (with supported providers)"""
+ """List systems hammer can support (with supported providers)."""
for system, revisions in SYSTEMS.items():
print('%s:' % system)
for r in revisions:
def list_created_systems():
- """List VMs that are created on this host by hammer"""
+ """List VMs that are created on this host by Hammer."""
_, output = execute('vagrant global-status', quiet=True, capture=True)
systems = []
for line in output.splitlines():
def destroy_system(path):
+ "Destroy Vagrant system under given path."""
execute('vagrant destroy', cwd=path, interactive=True)
-def _what_features(args):
+def _get_features(args):
features = set(vars(args)['with'])
# distcheck is not compatible with defaults so do not add them
if 'distcheck' not in features:
def _print_summary(results, features):
- """Prints summart of build times and unit-test results"""
+ """Print summart of build times and unit-test results."""
print("")
print("+===== Hammer Summary ====================================================+")
print("| provider | system | revision | duration | status | unit tests |")
ut_results = padding + green(ut_results)
else:
ut_results = ' not planned'
- print('| %10s | %10s | %8s | %6d:%02d | %s | %s |' % (provider, system, revision, dt // 60, dt % 60, status, ut_results))
+ txt = '| %10s | %10s | %8s | %6d:%02d | %s | %s |' % (provider, system, revision,
+ dt // 60, dt % 60, status, ut_results)
+ print(txt)
print("+------------+------------+----------+-----------+---------+--------------+")
- print("| Total: %6d:%02d | |" % (total_dt // 60, total_dt % 60))
+ txt = "| Total: %6d:%02d | |" % (total_dt // 60,
+ total_dt % 60)
+ print(txt)
print("+=========================================================================+")
def prepare_system_cmd(args):
+ """Check command args and run the prepare-system command."""
if args.provider != 'local' and (args.system == 'all' or args.revision == 'all'):
print('Please provide required system and its version.')
print('Example: ./hammer.py prepare-system -s fedora -r 28.')
_check_system_revision(args.system, args.revision)
- features = _what_features(args)
+ features = _get_features(args)
log.info('Enabled features: %s', ' '.join(features))
if args.provider == 'local':
prepare_system_local(features, args.check_times)
return
- prepare_system_in_vagrant(args.provider, args.system, args.revision, features, args.dry_run, args.check_times, args.clean_start)
+ prepare_system_in_vagrant(args.provider, args.system, args.revision, features,
+ args.dry_run, args.check_times, args.clean_start)
def build_cmd(args):
- features = _what_features(args)
+ """Check command args and run the build command."""
+ features = _get_features(args)
log.info('Enabled features: %s', ' '.join(features))
if args.provider == 'local':
build_local(features, args.from_tarball, args.check_times, int(args.jobs), args.dry_run)
def main():
+ """Main function - parse args and invoke proper command."""
args = parse_args()
# prepare logging
elif args.command == "package-box":
_check_system_revision(args.system, args.revision)
- features = _what_features(args)
+ features = _get_features(args)
log.info('Enabled features: %s', ' '.join(features))
package_box(args.provider, args.system, args.revision, features, args.dry_run, args.check_times)