Skip to content

Commit 73f85c8

Browse files
authored
Exclude projects from node (#181)
* Exclude projects from nodes (AlmaLinux/build-system#365) * Black and isort formatting
1 parent 9829924 commit 73f85c8

File tree

5 files changed

+168
-65
lines changed

5 files changed

+168
-65
lines changed

build_node/build_node_builder.py

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,7 @@ class BuildNodeBuilder(threading.Thread):
4141
"""Build thread."""
4242

4343
def __init__(
44-
self,
45-
config,
46-
thread_num,
47-
terminated_event,
48-
graceful_terminated_event,
49-
task_queue,
44+
self, config, thread_num, terminated_event, graceful_terminated_event
5045
):
5146
"""
5247
Build thread initialization.
@@ -62,9 +57,7 @@ def __init__(
6257
graceful_terminated_event : threading.Event
6358
Shows, if process got "kill -10" signal.
6459
"""
65-
super(BuildNodeBuilder, self).__init__(
66-
name='Builder-{0}'.format(thread_num)
67-
)
60+
super(BuildNodeBuilder, self).__init__(name=f'Builder-{thread_num}')
6861
self.__config = config
6962
self.__working_dir = os.path.join(
7063
config.working_dir, 'builder-{0}'.format(thread_num)
@@ -151,12 +144,8 @@ def run(self):
151144
)
152145
capture_exception(e)
153146
finally:
154-
only_logs = not (
155-
bool(
156-
filter_files(
157-
artifacts_dir, lambda f: f.endswith('.rpm')
158-
)
159-
)
147+
only_logs = not bool(
148+
filter_files(artifacts_dir, lambda f: f.endswith('.rpm'))
160149
)
161150
if success is False:
162151
only_logs = True

build_node/build_node_config.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,16 @@
3232
DEFAULT_REQUEST_TIMEOUT = 60 # 1 minute
3333
DEFAULT_PULP_TIMEOUT = 120 # 2 minutes
3434
DEFAULT_JWT_TOKEN = 'test_jwt'
35+
DEFAULT_CACHE_UPDATE_INTERVAL = 600
36+
DEFAULT_EXCLUSIONS_URL = (
37+
'https://git.almalinux.org/almalinux/build-node-exclusions/raw/branch/main'
38+
)
39+
DEFAULT_CACHE_SIZE = 1
3540

3641
__all__ = ['BuildNodeConfig']
3742

3843

3944
class BuildNodeConfig(BaseConfig):
40-
4145
"""
4246
Build node configuration storage.
4347
@@ -125,6 +129,10 @@ def __init__(self, config_file=None, **cmd_args):
125129
'immudb_public_key_file': None,
126130
'request_timeout': DEFAULT_REQUEST_TIMEOUT,
127131
'jwt_token': DEFAULT_JWT_TOKEN,
132+
'cache_update_interval': DEFAULT_CACHE_UPDATE_INTERVAL,
133+
'exclusions_url': DEFAULT_EXCLUSIONS_URL,
134+
'build_node_name': self.get_node_name(),
135+
'cache_size': DEFAULT_CACHE_SIZE,
128136
}
129137
schema = {
130138
'development_mode': {'type': 'boolean', 'default': False},
@@ -136,7 +144,11 @@ def __init__(self, config_file=None, **cmd_args):
136144
'working_dir': {'type': 'string', 'required': True},
137145
'git_cache_locks_dir': {'type': 'string', 'required': True},
138146
'git_repos_cache_dir': {'type': 'string', 'required': True},
139-
'git_extra_options': {'type': 'list', 'required': False, 'nullable': True},
147+
'git_extra_options': {
148+
'type': 'list',
149+
'required': False,
150+
'nullable': True,
151+
},
140152
'native_support': {'type': 'boolean', 'default': True},
141153
'arm64_support': {'type': 'boolean', 'default': False},
142154
'arm32_support': {'type': 'boolean', 'default': False},
@@ -159,12 +171,20 @@ def __init__(self, config_file=None, **cmd_args):
159171
'immudb_public_key_file': {'type': 'string', 'nullable': True},
160172
'base_arch': {'type': 'string', 'nullable': False},
161173
'build_src': {'type': 'boolean', 'nullable': False},
162-
'pulp_timeout': {'type': 'integer', 'min': DEFAULT_PULP_TIMEOUT,
163-
'required': True},
174+
'pulp_timeout': {
175+
'type': 'integer',
176+
'min': DEFAULT_PULP_TIMEOUT,
177+
'required': True,
178+
},
164179
'request_timeout': {'type': 'integer', 'required': True},
180+
'cache_update_interval': {'type': 'integer', 'required': True},
181+
'exclusions_url': {'type': 'string', 'required': True},
182+
'build_node_name': {'type': 'string', 'required': True},
183+
'cache_size': {'type': 'integer', 'required': True},
165184
}
166-
super(BuildNodeConfig, self).__init__(default_config, config_file,
167-
schema, **cmd_args)
185+
super(BuildNodeConfig, self).__init__(
186+
default_config, config_file, schema, **cmd_args
187+
)
168188

169189
@property
170190
def codenotary_enabled(self) -> bool:

build_node/build_node_supervisor.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
import requests
77
import requests.adapters
88
from urllib3 import Retry
9+
from cachetools import TTLCache
910

1011
from build_node import constants
12+
from build_node.utils.file_utils import file_url_exists
1113

1214

1315
class BuilderSupervisor(threading.Thread):
@@ -24,6 +26,10 @@ def __init__(
2426
self.terminated_event = terminated_event
2527
self.__session = None
2628
self.__task_queue = task_queue
29+
self.__cached_config = TTLCache(
30+
maxsize=config.cache_size,
31+
ttl=config.cache_update_interval,
32+
)
2733
super(BuilderSupervisor, self).__init__(name='BuildersSupervisor')
2834

2935
def __generate_request_session(self):
@@ -45,6 +51,7 @@ def __generate_request_session(self):
4551
def __request_build_task(self):
4652
if not self.__task_queue.full():
4753
supported_arches = [self.config.base_arch]
54+
excluded_packages = self.get_excluded_packages()
4855
if self.config.base_arch == 'x86_64':
4956
supported_arches.append('i686')
5057
if self.config.build_src:
@@ -54,7 +61,7 @@ def __request_build_task(self):
5461
)
5562
data = {
5663
'supported_arches': supported_arches,
57-
'excluded_packages': [],
64+
'excluded_packages': excluded_packages,
5865
}
5966
try:
6067
response = self.__session.post(
@@ -90,6 +97,15 @@ def __report_active_tasks(self):
9097
traceback.format_exc(),
9198
)
9299

100+
def get_excluded_packages(self):
101+
if 'excluded_packages' not in self.__cached_config:
102+
uri = f'{self.__config.exclusions_url}/{self.__config.build_node_name}'
103+
if file_url_exists(uri):
104+
response = requests.get(uri).text
105+
self.__cached_config['excluded_packages'] = response.splitlines()
106+
107+
return self.__cached_config.get('excluded_packages', [])
108+
93109
def run(self):
94110
self.__generate_request_session()
95111
while not self.terminated_event.is_set():

build_node/utils/config.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020

2121
class ConfigValidator(cerberus.Validator):
22-
2322
"""
2423
Custom validator for CloudLinux Build System configuration objects.
2524
"""
@@ -70,20 +69,21 @@ def locate_config_file(component, config_path=None):
7069
if config_path:
7170
config_path = normalize_path(config_path)
7271
if not os.path.exists(config_path):
73-
raise ValueError('configuration file {0} is not found'.
74-
format(config_path))
72+
raise ValueError(
73+
'configuration file {0} is not found'.format(config_path)
74+
)
7575
return config_path
7676
config_path = normalize_path('~/.config/castor/{0}.yml'.format(component))
7777
if os.path.exists(config_path):
7878
return config_path
7979

8080

8181
class BaseConfig(object):
82-
8382
"""Base configuration object for Build System processes."""
8483

85-
def __init__(self, default_config, config_path=None, schema=None,
86-
**cmd_args):
84+
def __init__(
85+
self, default_config, config_path=None, schema=None, **cmd_args
86+
):
8787
"""
8888
Configuration object initialization.
8989
@@ -128,6 +128,11 @@ def generate_node_id(postfix=''):
128128
"""
129129
return '{0}.{1}{2}'.format(platform.node(), os.getpid(), postfix)
130130

131+
@staticmethod
132+
def get_node_name():
133+
host_name = platform.node()
134+
return host_name.rsplit('.', 2)[0]
135+
131136
def __dir__(self):
132137
return list(self.__config.keys())
133138

@@ -145,7 +150,9 @@ def __parse_config_file(self, config_path):
145150
def __validate_config(self, schema):
146151
validator = ConfigValidator(schema or {})
147152
if not validator.validate(self.__config):
148-
error_list = ['{0}: {1}'.format(k, ', '.join(v))
149-
for k, v in validator.errors.items()]
153+
error_list = [
154+
'{0}: {1}'.format(k, ', '.join(v))
155+
for k, v in validator.errors.items()
156+
]
150157
raise ValueError('. '.join(error_list))
151158
self.__config = validator.document

0 commit comments

Comments
 (0)