Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions Client/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,18 @@ def bash_completion_dir():
(bash_completion_dir(), ['bash-completion/bkr']),
],

python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*, !=3.7.*, !=3.8.*',
classifiers=[
'Development Status :: 5 - Production/Stable',
'Operating System :: POSIX :: Linux',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
'Programming Language :: Python :: 3.13',
'Programming Language :: Python :: 3.14',
'Programming Language :: Python :: 3.15',
'License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)',
],

Expand Down
11 changes: 8 additions & 3 deletions Client/src/bkr/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
try:
__import__('pkg_resources').declare_namespace(__name__)
except ImportError:
import sys
if sys.version_info[0] >= 3:
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
else:
try:
__import__('pkg_resources').declare_namespace(__name__)
except ImportError:
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
15 changes: 11 additions & 4 deletions Client/src/bkr/client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
import xml.dom.minidom
from optparse import OptionGroup

import pkg_resources
from six.moves.urllib_parse import urljoin

from bkr.common.resources import resource_listdir, resource_string

from bkr.client.command import Command
from bkr.common.pyconfig import PyConfigParser

Expand Down Expand Up @@ -52,9 +53,15 @@ def host_filter_presets():
return _host_filter_presets

_host_filter_presets = {}
config_files = (
sorted(glob.glob(pkg_resources.resource_filename('bkr.client', 'host-filters/*.conf')))
+ sorted(glob.glob('/etc/beaker/host-filters/*.conf')))
for name in sorted(resource_listdir('bkr.client', 'host-filters')):
if name.endswith('.conf'):
content = resource_string('bkr.client', 'host-filters/' + name).decode('utf-8', errors='replace')
for line in content.splitlines():
matched = re.match(r'^(\w+)\s+(\S+.*)$', line)
if matched:
preset, xml = matched.groups()
_host_filter_presets[preset] = xml
config_files = sorted(glob.glob('/etc/beaker/host-filters/*.conf'))
user_config_file = os.path.expanduser('~/.beaker_client/host-filter')
if os.path.exists(user_config_file):
config_files.append(user_config_file)
Expand Down
5 changes: 3 additions & 2 deletions Client/src/bkr/client/commands/cmd_job_submit.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,10 @@
import xml.dom.minidom

import lxml.etree
import pkg_resources
import six

from bkr.common.resources import resource_stream

from bkr.client import BeakerCommand
from bkr.client.convert import Convert
from bkr.client.task_watcher import *
Expand Down Expand Up @@ -211,7 +212,7 @@ def run(self, *args, **kwargs):
if not jobs:
jobs = ['-'] # read one job from stdin by default
job_schema = lxml.etree.RelaxNG(lxml.etree.parse(
pkg_resources.resource_stream('bkr.common', 'schema/beaker-job.rng')))
resource_stream('bkr.common', 'schema/beaker-job.rng')))

self.set_hub(**kwargs)
submitted_jobs = []
Expand Down
5 changes: 3 additions & 2 deletions Client/src/bkr/client/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
from optparse import SUPPRESS_HELP

import gssapi
import pkg_resources
from six.moves.xmlrpc_client import Fault

from bkr.common.resources import iter_entry_points

from bkr.client.command import BeakerClientConfigurationError
from bkr.client.command import ClientCommandContainer
from bkr.client.command import CommandOptionParser
Expand All @@ -41,7 +42,7 @@ def register_all(cls):
# Load subcommands from setuptools entry points in the bkr.client.commands
# group. This is the new, preferred way for other packages to provide their
# own bkr subcommands.
for entrypoint in pkg_resources.iter_entry_points('bkr.client.commands'):
for entrypoint in iter_entry_points('bkr.client.commands'):
cls.register_plugin(entrypoint.load(), name=entrypoint.name)


Expand Down
11 changes: 8 additions & 3 deletions Common/bkr/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
try:
__import__('pkg_resources').declare_namespace(__name__)
except ImportError:
import sys
if sys.version_info[0] >= 3:
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
else:
try:
__import__('pkg_resources').declare_namespace(__name__)
except ImportError:
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
42 changes: 42 additions & 0 deletions Common/bkr/common/resources.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Copyright Contributors to the Beaker project.
# SPDX-License-Identifier: GPL-2.0-or-later

import sys

if sys.version_info >= (3, 9):
import importlib.resources
import importlib.metadata

def resource_stream(package, resource_name):
return importlib.resources.files(package).joinpath(resource_name).open("rb")

def resource_string(package, resource_name):
return importlib.resources.files(package).joinpath(resource_name).read_bytes()

def resource_listdir(package, resource_name):
return [
item.name
for item in importlib.resources.files(package)
.joinpath(resource_name)
.iterdir()
]

def resource_exists(package, resource_name):
traversable = importlib.resources.files(package).joinpath(resource_name)
return traversable.is_file() or traversable.is_dir()

if sys.version_info >= (3, 10):
def iter_entry_points(group):
return importlib.metadata.entry_points(group=group)
else:
def iter_entry_points(group):
return importlib.metadata.entry_points().get(group, [])

else:
from pkg_resources import (
resource_stream,
resource_string,
resource_listdir,
resource_exists,
iter_entry_points,
)
63 changes: 63 additions & 0 deletions Common/bkr/common/test_resources.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Copyright Contributors to the Beaker project.
# SPDX-License-Identifier: GPL-2.0-or-later

import unittest

from bkr.common.resources import (
resource_stream,
resource_string,
resource_listdir,
resource_exists,
iter_entry_points,
)


class ResourceStreamTest(unittest.TestCase):
def test_resource_stream_returns_readable_file_object(self):
f = resource_stream("bkr.common", "schema/beaker-job.rng")
try:
data = f.read()
self.assertIsInstance(data, bytes)
self.assertGreater(len(data), 0)
self.assertIn(b"<grammar", data)
finally:
f.close()


class ResourceStringTest(unittest.TestCase):
def test_resource_string_returns_bytes(self):
data = resource_string("bkr.common", "schema/beaker-job.rng")
self.assertIsInstance(data, bytes)
self.assertGreater(len(data), 0)
self.assertIn(b"<grammar", data)


class ResourceListdirTest(unittest.TestCase):
def test_resource_listdir_returns_list(self):
entries = resource_listdir("bkr.common", "schema")
self.assertIsInstance(entries, list)
self.assertIn("beaker-job.rng", entries)
self.assertIn("beaker-task.rng", entries)


class ResourceExistsTest(unittest.TestCase):
def test_resource_exists_true_for_file(self):
self.assertTrue(resource_exists("bkr.common", "schema/beaker-job.rng"))

def test_resource_exists_true_for_directory(self):
self.assertTrue(resource_exists("bkr.common", "schema"))

def test_resource_exists_false(self):
self.assertFalse(resource_exists("bkr.common", "schema/nonexistent.xyz"))


class IterEntryPointsTest(unittest.TestCase):
def test_iter_entry_points_returns_iterable(self):
eps = iter_entry_points("console_scripts")
result = list(eps)
self.assertIsInstance(result, list)

def test_iter_entry_points_empty_group(self):
eps = iter_entry_points("nonexistent.group.12345")
result = list(eps)
self.assertEqual(result, [])
7 changes: 4 additions & 3 deletions Common/bkr/common/test_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
# (at your option) any later version.

import unittest
import pkg_resources
import lxml.etree

from bkr.common.resources import resource_stream

class SchemaTestBase(unittest.TestCase):

schema_doc = None # filled by setUpClass
Expand All @@ -26,7 +27,7 @@ class TaskSchemaTest(SchemaTestBase):

@classmethod
def setUpClass(cls):
cls.schema_doc = lxml.etree.parse(pkg_resources.resource_stream(
cls.schema_doc = lxml.etree.parse(resource_stream(
'bkr.common', 'schema/beaker-task.rng'))

def test_minimal_task(self):
Expand Down Expand Up @@ -86,7 +87,7 @@ class JobSchemaTest(SchemaTestBase):

@classmethod
def setUpClass(cls):
cls.schema_doc = lxml.etree.parse(pkg_resources.resource_stream(
cls.schema_doc = lxml.etree.parse(resource_stream(
'bkr.common', 'schema/beaker-job.rng'))

def test_minimal_job(self):
Expand Down
10 changes: 8 additions & 2 deletions Common/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,18 @@
'schema/*.ttl',
'default.conf']},

python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*, !=3.7.*, !=3.8.*',
classifiers=[
'Development Status :: 5 - Production/Stable',
'Operating System :: POSIX :: Linux',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
'Programming Language :: Python :: 3.13',
'Programming Language :: Python :: 3.14',
'Programming Language :: Python :: 3.15',
'License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)',
],
)