From 6ae674ba8afd37d224ffa3cd6a23e1f81fea59b8 Mon Sep 17 00:00:00 2001 From: Mark Murnane Date: Tue, 16 Apr 2024 19:02:18 -0400 Subject: [PATCH] Cleaning up old stuff --- .travis.yml | 27 ---- Dockerfile | 93 ++----------- MANIFEST.in | 2 - development-defaults.ini | 10 -- fabfile.py | 32 ----- manifest.yaml.template | 10 -- package-support/init.d/sideboard | 181 ------------------------- package-support/postinstall.sh | 16 --- package-support/preinstall.sh | 5 - package-support/sideboard-server.cfg | 22 --- package-support/sysconfig/sideboard | 6 - pavement.py | 193 --------------------------- requirements.txt | 1 - sideboard/lib/_threads.py | 25 ++-- test-defaults.ini | 30 ----- tox.ini | 38 ------ 16 files changed, 27 insertions(+), 664 deletions(-) delete mode 100644 .travis.yml delete mode 100644 MANIFEST.in delete mode 100644 development-defaults.ini delete mode 100644 fabfile.py delete mode 100644 manifest.yaml.template delete mode 100755 package-support/init.d/sideboard delete mode 100644 package-support/postinstall.sh delete mode 100644 package-support/preinstall.sh delete mode 100644 package-support/sideboard-server.cfg delete mode 100644 package-support/sysconfig/sideboard delete mode 100644 pavement.py delete mode 100644 test-defaults.ini delete mode 100644 tox.ini diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 040cd9c..0000000 --- a/.travis.yml +++ /dev/null @@ -1,27 +0,0 @@ -language: python -matrix: - include: - - python: "2.7" - env: TOX_ENV=pep8 - - python: "2.7" - env: TOX_ENV=py27 - - python: "3.3" - env: TOX_ENV=py33 - - python: "3.4" - env: TOX_ENV=py34 - - python: "3.5" - env: TOX_ENV=py35 -before_install: - - sudo apt-get -qq update - - sudo apt-get install -y build-essential libcap-dev -install: - - pip install tox - - if [[ $TOX_ENV == py27 ]] || [[ $TOX_ENV == py35 ]]; then - pip install coveralls; - fi -script: - - tox -e $TOX_ENV -after_success: - - if [[ $TOX_ENV == py27 ]] || [[ $TOX_ENV == py35 ]]; then - coveralls; - fi diff --git a/Dockerfile b/Dockerfile index 6005872..03437fd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,91 +1,20 @@ -FROM python:3.12.3 as build +FROM python:3.12.3-slim as build MAINTAINER RAMS Project "code@magfest.org" LABEL version.sideboard ="1.0" WORKDIR /app -# This is actually the least bad way to compose two Dockerfile tech stacks right now. -# The following is copied and pasted from the Node Dockerfile at -# https://github.com/nodejs/docker-node/blob/main/12/buster/Dockerfile -# Update this comment and change the entire copypasta section to upgrade Node version - -######################################### -# START NODEJS DOCKERFILE COPYPASTA # -# https://github.com/nodejs/docker-node # -######################################### -RUN groupadd --gid 1000 node \ - && useradd --uid 1000 --gid node --shell /bin/bash --create-home node - -ENV NODE_VERSION 12.22.3 - -RUN ARCH= && dpkgArch="$(dpkg --print-architecture)" \ - && case "${dpkgArch##*-}" in \ - amd64) ARCH='x64';; \ - ppc64el) ARCH='ppc64le';; \ - s390x) ARCH='s390x';; \ - arm64) ARCH='arm64';; \ - armhf) ARCH='armv7l';; \ - i386) ARCH='x86';; \ - *) echo "unsupported architecture"; exit 1 ;; \ - esac \ - # gpg keys listed at https://github.com/nodejs/node#release-keys - && set -ex \ - && for key in \ - 4ED778F539E3634C779C87C6D7062848A1AB005C \ - 94AE36675C464D64BAFA68DD7434390BDBE9B9C5 \ - 74F12602B6F1C4E913FAA37AD3A89613643B6201 \ - 71DCFD284A79C3B38668286BC97EC7A07EDE3FC1 \ - 8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600 \ - C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \ - C82FA3AE1CBEDC6BE46B9360C43CEC45C17AB93C \ - DD8F2338BAE7501E3DD5AC78C273792F7D83545D \ - A48C2BEE680E841632CD4E44F07496B3EB3C1762 \ - 108F52B48DB57BB0CC439B2997B01419BD92F80A \ - B9E2F5981AA6E0CD28160D9FF13993A75599653C \ - ; do \ - gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys "$key" || \ - gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key" ; \ - done \ - && curl -fsSLO --compressed "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-$ARCH.tar.xz" \ - && curl -fsSLO --compressed "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \ - && gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \ - && grep " node-v$NODE_VERSION-linux-$ARCH.tar.xz\$" SHASUMS256.txt | sha256sum -c - \ - && tar -xJf "node-v$NODE_VERSION-linux-$ARCH.tar.xz" -C /usr/local --strip-components=1 --no-same-owner \ - && rm "node-v$NODE_VERSION-linux-$ARCH.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt \ - # smoke tests - && node --version \ - && npm --version - -RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \ - && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \ - && gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \ - && grep " node-v$NODE_VERSION-linux-x64.tar.xz\$" SHASUMS256.txt | sha256sum -c - \ - && tar -xJf "node-v$NODE_VERSION-linux-x64.tar.xz" -C /usr/local --strip-components=1 \ - && rm "node-v$NODE_VERSION-linux-x64.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt \ - && ln -s /usr/local/bin/node /usr/local/bin/nodejs -################################### -# END NODEJS DOCKERFILE COPYPASTA # -################################### - -# required for python-prctl -RUN apt-get update && apt-get install -y libcap-dev && rm -rf /var/lib/apt/lists/* - -RUN pip3 install virtualenv \ - && virtualenv --always-copy /app/env \ - && /app/env/bin/pip3 install paver - ADD requirements.txt requirements.txt -ADD test_requirements.txt test_requirements.txt -ADD setup.py setup.py -ADD sideboard/_version.py sideboard/_version.py -ADD pavement.py pavement.py - -RUN /app/env/bin/paver install_deps -ADD . /app/ +RUN --mount=type=cache,target=/root/.cache \ + pip install -r requirements.txt FROM build as test -RUN /app/env/bin/pip install mock pytest -CMD /app/env/bin/python3 -m pytest +ADD test_requirements.txt test_requirements.txt +RUN --mount=type=cache,target=/root/.cache \ + pip install -r test_requirements.txt +CMD python -m pytest +ADD . /app/ FROM build as release -CMD /app/env/bin/python3 /app/sideboard/run_server.py -EXPOSE 8282 \ No newline at end of file +CMD python /app/sideboard/run_server.py +EXPOSE 80 +ADD . /app/ \ No newline at end of file diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 9861bfd..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -include requirements.txt -recursive-include sideboard * \ No newline at end of file diff --git a/development-defaults.ini b/development-defaults.ini deleted file mode 100644 index eb39f37..0000000 --- a/development-defaults.ini +++ /dev/null @@ -1,10 +0,0 @@ -debug = False -ws.auth_required = False - -[cherrypy] -server.socket_host = "0.0.0.0" -engine.autoreload.on = True -tools.cpstats.on = False - -[loggers] -root = "DEBUG" diff --git a/fabfile.py b/fabfile.py deleted file mode 100644 index 04082a8..0000000 --- a/fabfile.py +++ /dev/null @@ -1,32 +0,0 @@ -from __future__ import unicode_literals -import time -import os.path - -import yaml -import ship_it - - -__here__ = os.path.abspath(os.path.dirname(__file__)) -MANIFEST_YAML = os.path.join(__here__, 'manifest.yaml') -MANIFEST_TEMPLATE = MANIFEST_YAML + '.template' - - -def _populate_manifest_and_invoke_fpm(iteration): - import sideboard - with open(MANIFEST_TEMPLATE) as f: - manifest = yaml.load(f) - manifest[b'version'] = sideboard.__version__ - manifest[b'iteration'] = iteration - - with open(MANIFEST_YAML, 'w') as f: - yaml.dump(manifest, f) - - ship_it.fpm(MANIFEST_YAML) - - -def fpm_stable(iteration): - _populate_manifest_and_invoke_fpm(iteration) - - -def fpm_testing(): - _populate_manifest_and_invoke_fpm(b'0.{}'.format(int(time.time()))) diff --git a/manifest.yaml.template b/manifest.yaml.template deleted file mode 100644 index 1a735a2..0000000 --- a/manifest.yaml.template +++ /dev/null @@ -1,10 +0,0 @@ -description: Sideboard Framework -name: sideboard -before_install: package-support/preinstall.sh -after_install: package-support/postinstall.sh -config_files: - /etc/sideboard/sideboard-server.cfg: package-support/sideboard-server.cfg - /etc/init.d/sideboard: package-support/init.d/sideboard - /etc/sysconfig/sideboard: package-support/sysconfig/sideboard -depends: - - python27 diff --git a/package-support/init.d/sideboard b/package-support/init.d/sideboard deleted file mode 100755 index 03383bd..0000000 --- a/package-support/init.d/sideboard +++ /dev/null @@ -1,181 +0,0 @@ -#!/bin/bash - -# chkconfig: - 88 14 -# description: Sideboard exit node manager -# processname: sideboard -# -### BEGIN INIT INFO -# Provides: sideboard -# Required-Start: $local_fs $remote_fs $network $named -# Required-Stop: $local_fs $remote_fs $network -# Short-Description: start and stop sideboard -# Description: Sideboard exit node manager -### END INIT INFO - -RETVAL=0 -prog="sideboard" - -DESC=sideboard -VENV=/opt/sideboard -PYTHON=$VENV/bin/python -SEP=$VENV/bin/sep -CHERRYD=$VENV/bin/cherryd -USER=sideboard -PID_FILE=/var/run/sideboard/sideboard.pid -COUNTDOWN=10 - -SIDEBOARDMODE=server -if [ -f /etc/sysconfig/sideboard ]; then - # import $SIDEBOARDMODE from defaults file -. /etc/sysconfig/sideboard -fi - -OPTIONS="mainloop_daemon --pidfile=$PID_FILE" -if [ "$SIDEBOARDMODE" == "server" ]; then - OPTIONS="-d --pidfile=$PID_FILE --import=sideboard.server" -fi - -procgrep() { - grep "python.*${DESC}" | grep -v grep -} - -filepid() { - cat $PID_FILE 2>/dev/null -} - -procpid() { - ps aux | procgrep | awk '{print $2}' -} - -allpids () { - FP=$(filepid) - PP=$(procpid) - if [ "$PP" == "$FP" ]; then - echo $PP - else - FP_IS_CORRECT_PROC=$(cat /proc/$FP/cmdline 2>/dev/null | procgrep) - if [ -n "$FP_IS_CORRECT_PROC" ]; then - echo $PP $FP - else - echo $PP - fi - fi -} - -isrunning() { - if [ -n "$(filepid)" ]; then - RETVAL=0 - elif [ -n "$(procpid)" ]; then - RETVAL=0 - else - RETVAL=1 - fi - return $RETVAL -} - -start() { - if isrunning; then - echo "Starting $prog: $prog is already running [FAIL]" - RETVAL=1 - else - echo -n $"Starting $prog: " - if [ "$SIDEBOARDMODE" == "server" ]; then - sudo -u $USER $CHERRYD $OPTIONS - else - sudo -u $USER $SEP $OPTIONS - fi - RETVAL=$? - if [ $RETVAL -eq 0 ]; then - echo '[OK]' - else - echo '[FAIL]' - fi - fi - return $RETVAL -} - -exitcountdown() { - while [ "$COUNTDOWN" -gt 0 ]; do - if [ -z "$(procpid)" ]; then - break - fi - echo -n . - sleep 1 - COUNTDOWN=`expr $COUNTDOWN - 1` - done -} - -stop() { - if isrunning; then - echo -n "Shutting down $prog" - kill $(allpids) 2>/dev/null - exitcountdown - if [ -n "$(procpid)" ]; then - echo -n " $prog failed to exit cleanly, terminating" - kill -9 $(allpids) 2>/dev/null - COUNTDOWN=3 - exitcountdown - fi - rm -f $PID_FILE - if isrunning; then - echo ' [FAIL]' - else - echo ' [OK]' - fi - RETVAL=0 - else - echo "$prog is not running" - RETVAL=1 - fi - return $RETVAL -} - -restart() { - stop - start -} - -condrestart() { - if isrunning; then - restart - fi -} - -status() { - if isrunning; then - FP=$(filepid) - PP=$(procpid) - if [ "$FP" == "$PP" ]; then - RETVAL=0 - echo "$prog is running with pid $PP" - else - RETVAL=1 - echo "$prog has a pidfile with pid ${FP:-} but a running process with pid ${PP:-}" - fi - else - RETVAL=3 - echo "$prog is not running" - fi - return $RETVAL -} - -case "$1" in - start) - start - ;; - stop) - stop - ;; - status) - status - ;; - restart) - restart - ;; - condrestart|try-restart) - condrestart - ;; - *) - echo $"Usage: $0 {start|stop|status|restart|condrestart}" - RETVAL=1 -esac diff --git a/package-support/postinstall.sh b/package-support/postinstall.sh deleted file mode 100644 index dad1b91..0000000 --- a/package-support/postinstall.sh +++ /dev/null @@ -1,16 +0,0 @@ - -for dname in /var/run/sideboard /var/tmp/sideboard /var/tmp/sideboard/sessions /opt/sideboard /opt/sideboard/db /opt/sideboard/plugins; do - mkdir -p $dname - chmod 750 $dname - chown sideboard.sideboard $dname -done - -# unlike all of the other directories in the above loop, we want this directory (and also its contents) to be sideboard.root -chown -R root.sideboard /etc/sideboard - -chown root.root /etc/init.d/sideboard -chown root.root /etc/sysconfig/sideboard - -# TODO: instead of doing this in postinstall, we should eventually do ---use-file-permissions -chmod 700 /etc/init.d/sideboard -chmod 600 /etc/sysconfig/sideboard diff --git a/package-support/preinstall.sh b/package-support/preinstall.sh deleted file mode 100644 index 36d0831..0000000 --- a/package-support/preinstall.sh +++ /dev/null @@ -1,5 +0,0 @@ - -if ! id -u sideboard &>/dev/null; then - groupadd --force -r sideboard -g 600 - useradd -r --shell /sbin/nologin -uid 600 --gid sideboard sideboard -fi diff --git a/package-support/sideboard-server.cfg b/package-support/sideboard-server.cfg deleted file mode 100644 index a1cf43f..0000000 --- a/package-support/sideboard-server.cfg +++ /dev/null @@ -1,22 +0,0 @@ -plugins_dir = "/opt/sideboard/plugins" - -[cherrypy] -server.socket_host = "127.0.0.1" -tools.sessions.storage_path = "/var/tmp/sideboard/sessions" - -[loggers] -root = "INFO" - -[handlers] -[[syslog]] -class = "logging.handlers.SysLogHandler" -address = "/dev/log" -formatter = syslog - -[formatters] -[[syslog]] -format = "$$(levelname)-5.5s $$(threadName)s [$$(name)s] $$(message)s" - -[[default]] -format = "$$(asctime)s,$$(msecs)03d $$(levelname)-5.5s $$(threadName)s [$$(name)s] $$(message)s" -datefmt = "$$m-$$d $$H:$$M:$$S" diff --git a/package-support/sysconfig/sideboard b/package-support/sysconfig/sideboard deleted file mode 100644 index 6b81aa9..0000000 --- a/package-support/sysconfig/sideboard +++ /dev/null @@ -1,6 +0,0 @@ -# defaults for sideboard package -# SIDEBOARDMODE=server -SIDEBOARDMODE=daemon - -# DESC=sideboard -DESC=sideboard-daemon diff --git a/pavement.py b/pavement.py deleted file mode 100644 index 404242b..0000000 --- a/pavement.py +++ /dev/null @@ -1,193 +0,0 @@ -from __future__ import unicode_literals, print_function -import os -import sys -import glob -from itertools import chain -from os.path import abspath, dirname, exists, join - -import paver.virtual as virtual -from paver.easy import * # paver docs pretty consistently want you to do this -from paver.path import path # primarily here to support the rmtree method of a path object - -__here__ = path(abspath(dirname(__file__))) -PLUGINS_DIR = __here__ / path('plugins') -SIDEBOARD_DIR = __here__ / path('sideboard') - - -def bootstrap_venv(intended_venv, bootstrap_name=None): - # bootstrap wants options available in options.virtualenv which is a Bunch - if exists(intended_venv): - intended_venv.rmtree() - - venv = getattr(options, 'virtualenv', Bunch()) - - with open(path(dirname(intended_venv)) / path('requirements.txt')) as reqs: - # we expect this to be reversed in setup.py - venv.packages_to_install = [line.strip() for line in reqs.readlines()[::-1] if line.strip()] - - venv.dest_dir = intended_venv - if bootstrap_name: - venv.script_name = '{}-bootstrap.py'.format(bootstrap_name) - - options.virtualenv = venv - virtual.bootstrap() - if sys.executable: - # if we can figure out the python associated with this paver, execute the bootstrap script - # and we can expect the virtual env will then exist - sh('{python_path} "{script_name}"'.format(python_path=sys.executable, - script_name=venv.script_name)) - - -def guess_plugin_module_name(containing_folder): - """ - given a containing folder, guess what the plugin name should be - - :param containing_folder: the folder that possibly contains a plugin - :type containing_folder: unicode - :return: - """ - # TODO: this only works as long as insist that the plugin dir be the module name - return os.path.split(containing_folder)[-1].replace('-', '_') - - -def collect_plugin_dirs(module=False): - """ - :param module: if True, return the module within a plugin directory, else (default) just return - the plugin directory - :return: the plugin folders in a form that can be iterated over - :rtype: collections.Iterator - """ - for potential_folder in glob.glob(PLUGINS_DIR / path('*')): - if all(exists(join(potential_folder, req_file)) for req_file in ('setup.py', 'requirements.txt')): - if module: - yield join(potential_folder, guess_plugin_module_name(potential_folder)) - else: - yield potential_folder - - -@task -def make_venv(): - """ - make a virtualenv for the sideboard project - """ - bootstrap_venv(__here__ / path('env'), 'sideboard') - develop_sideboard() - - -def install_pip_requirements_in_dir(dir_of_requirements_txt): - path_to_pip = __here__ / path('env/bin/pip') - - print("---- installing dependencies in {} ----" - .format(dir_of_requirements_txt)) - - sh('{pip} install -e {dir_of_requirements_txt}' - .format( - pip=path_to_pip, - dir_of_requirements_txt=dir_of_requirements_txt)) - - -def run_setup_py(path): - venv_python = str(__here__ / 'env' / 'bin' / 'python') - sh('cd {path} && {python_path} {setup_path} develop' - .format( - path=path, - python_path=venv_python if exists(venv_python) else sys.executable, - setup_path=join(path, 'setup.py'))) - - -def develop_sideboard(): - run_setup_py(__here__) - - -@task -def pull_plugins(): - """ - invoke git pull from each plug-in directory, your global git either needs to allow this to \ -happen auth-free, or you need to enter your credentials each time - """ - for plugin_dir in collect_plugin_dirs(): - sh('cd "{}";git pull'.format(plugin_dir)) - - -@task -def assert_all_projects_correctly_define_a_version(): - """ - error if there are plugins where we can't find a version defined - """ - all_files_with_bad_versions = [] - # FIXME: should we try to execfile? that's what setup.py is going to do anyway - cmd = (r'grep -xP "__version__\s*=\s*[\'\"][0-9]+\.[0-9]+(\.[0-9]+)?[\'\+]" {0}/_version.py') - for test_dir in chain(['sideboard'], collect_plugin_dirs(module=True)): - try: - sh(cmd.format(test_dir)) - except BuildFailure: - all_files_with_bad_versions.append(test_dir) - - if all_files_with_bad_versions: - print('the following directories do not include a _version.py file with __version__ ' - 'specified:') - print('\n'.join(all_files_with_bad_versions)) - print('Your plugin should be in agreement with this stack overflow post:') - print('http://stackoverflow.com/questions/458550/' - 'standard-way-to-embed-version-into-python-package/7071358#7071358') - - raise BuildFailure("there were projects that didn't include correctly specify __version__") - - -@task -@needs(['assert_all_files_import_unicode_literals', - 'assert_all_projects_correctly_define_a_version']) -def run_all_assertions(): - """ - run all the assertion tasks that sideboard supports - """ - - -@task -@cmdopts([ - ('name=', 'n', 'name of the plugin to create'), - ('drop', 'd', 'delete existing plugin if present'), - ('no_webapp', 'w', 'do not expose webpages in the plugin'), - ('no_sqlalchemy', 'a', 'do not use SQLAlchemy in the plugin'), - ('no_service', 'r', 'do not expose a service in the plugin'), - ('no_sphinx', 's', 'do not generate Sphinx docs'), - ('django=', 'j', 'create a Django project alongside the plugin with this name'), - ('cli', 'c', 'make this a cli application; implies -w/-r') -]) -def create_plugin(options): - """create a plugin skeleton to start a new project""" - - plugin_name = options.create_plugin.name - - if getattr(options.create_plugin, 'drop', False) and (PLUGINS_DIR / path(plugin_name.replace('_', '-'))).exists(): - # rmtree fails if the dir doesn't exist apparently - (PLUGINS_DIR / path(plugin_name.replace('_', '-'))).rmtree() - - kwargs = {} - for opt in ['webapp', 'sqlalchemy', 'service', 'sphinx']: - kwargs[opt] = not getattr(options.create_plugin, 'no_' + opt, False) - kwargs['cli'] = getattr(options.create_plugin, 'cli', False) - kwargs['django'] = getattr(options.create_plugin, 'django', None) - if kwargs['cli']: - kwargs['webapp'] = False - kwargs['service'] = False - - from data.paver import skeleton - skeleton.create_plugin(PLUGINS_DIR, plugin_name, **kwargs) - print('{} successfully created'.format(options.create_plugin.name)) - - -@task -def install_deps(): - install_pip_requirements_in_dir(__here__) - for pdir in collect_plugin_dirs(): - install_pip_requirements_in_dir(pdir) - - -@task -def clean(): - """ - clean all pyc and __pycache__ files - """ - sh("find . -name '*.pyc' | xargs rm -f") - sh("find . -name __pycache__ | xargs rm -fr") diff --git a/requirements.txt b/requirements.txt index b701108..9b6a6f4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,6 @@ Jinja2==3.1.3 paver==1.3.4 pip==24.0 psutil==5.9.8 -python-prctl==1.8.1; 'linux' in sys_platform redis==5.0.3 requests==2.31.0 rpctools==0.3.1 diff --git a/sideboard/lib/_threads.py b/sideboard/lib/_threads.py index 4d79c66..1a54d0a 100644 --- a/sideboard/lib/_threads.py +++ b/sideboard/lib/_threads.py @@ -2,7 +2,8 @@ import sys import time import heapq -import ctypes +import ctypes, ctypes.util +import psutil import platform import traceback import threading @@ -15,11 +16,15 @@ from sideboard.lib import log, config, on_startup, on_shutdown from sideboard.debugging import register_diagnostics_status_function -try: - import prctl - import psutil -except ImportError: - prctl = psutil = None # For platforms without this support. +# Replaces the prior prctl implementation with a direct call to pthread to change thread names +libpthread_path = ctypes.util.find_library("pthread") +pthread_setname_np = None +if libpthread_path: + libpthread = ctypes.CDLL(libpthread_path) + if hasattr(libpthread, "pthread_setname_np"): + pthread_setname_np = libpthread.pthread_setname_np + pthread_setname_np.argtypes = [ctypes.c_void_p, ctypes.c_char_p] + pthread_setname_np.restype = ctypes.c_int def _get_linux_thread_tid(): @@ -43,18 +48,20 @@ def _get_linux_thread_tid(): def _set_current_thread_ids_from(thread): # thread ID part 1: set externally visible thread name in /proc/[pid]/tasks/[tid]/comm to our internal name - if prctl and thread.name: + if pthread_setname_np and thread.name: # linux doesn't allow thread names > 15 chars, and we ideally want to see the end of the name. # attempt to shorten the name if we need to. shorter_name = thread.name if len(thread.name) < 15 else thread.name.replace('CP Server Thread', 'CPServ') - prctl.set_name(shorter_name) + if thread.ident is not None: + pthread_setname_np(thread.ident, shorter_name) + # thread ID part 2: capture linux-specific thread ID (TID) and store it with this thread object # if TID can't be obtained or system call fails, tid will be -1 thread.linux_tid = _get_linux_thread_tid() -# inject our own code at the start of every thread's start() method which sets the thread name via prctl(). +# inject our own code at the start of every thread's start() method which sets the thread name via pthread(). # Python thread names will now be shown in external system tools like 'top', '/proc', etc. def _thread_name_insert(self): _set_current_thread_ids_from(self) diff --git a/test-defaults.ini b/test-defaults.ini deleted file mode 100644 index 970fdb0..0000000 --- a/test-defaults.ini +++ /dev/null @@ -1,30 +0,0 @@ - -# The settings in this file (test-defaults.ini) can be overridden in test.ini. - -debug = True -ws.auth_required = False - -is_test_running = True - -[cherrypy] -engine.autoreload.on = False -profiling.on = False -server.socket_host = "127.0.0.1" - -# By default the test server runs on port 8282. If you are already using -# port 8282, you'll receive errors like: -# OSError: Port 8282 not free on '127.0.0.1' -# -# You can change this setting in test.ini to either another free port, or -# to port 0 (meaning a free port will be chosen by the OS automatically). -# Using port 0 is mostly safe, but on heavily used systems there is a -# potential race condition if another process uses the same port in the time -# between requesting an available port and actually using it. -# -# See https://eklitzke.org/binding-on-port-zero -# -server.socket_port = 8282 - - -[loggers] -root = "DEBUG" diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 1712758..0000000 --- a/tox.ini +++ /dev/null @@ -1,38 +0,0 @@ -# QUICK TIPS -# ========== -# -# Run all tests for all environments from the command line: -# $ tox -# -# -# Run all tests for a single environment from the command line: -# $ tox -e pep8 -# or: -# $ tox -e py34 -# -# -# Run only tests that match a substring expression, for a single environment: -# $ tox -e py34 -- -k expression -# -# -# In general, everything after the "--" is passed as arguments to py.test: -# $ tox -- -s -v -k expression -# -[tox] -envlist=pep8,py27,py33,py34,py35 -skipsdist=True - -[testenv] -setenv= - SIDEBOARD_CONFIG_OVERRIDES=test-defaults.ini -deps= - -rrequirements.txt - -rtest_requirements.txt -commands= - coverage run --source sideboard -m py.test {posargs} sideboard - coverage report --show-missing - -[testenv:pep8] -deps=pep8 -commands= - pep8 sideboard/