Skip to content

Commit 345c26b

Browse files
committed
fix(build-basket): make --auto truly non-interactive
Thread an `auto` flag through build_basket_for_plugin() -> generate_basket() -> manage_uuids() so that unknown datafields and objects get a fresh uuid instead of dropping into an interactive input() prompt. Fixes the EOFError crash in CI and non-interactive shells whenever a plugin introduces a new datafield without first regenerating its basket.
1 parent c8e2867 commit 345c26b

File tree

2 files changed

+22
-9
lines changed

2 files changed

+22
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ Monitoring Plugins:
112112

113113
Tools:
114114

115+
* build-basket: `--auto` is now truly non-interactive. Previously it kept its promise only when every datafield already existed in the committed basket; the moment a plugin introduced a new datafield, the tool fell through to an `input()` prompt and crashed with `EOFError` when run from CI or a non-interactive shell. `--auto` now treats unknown datafields and objects as new and generates fresh uuids for them instead of asking
115116
* rename `tools/check2basket` to `tools/build-basket` (one basket is built per run, so the singular name matches what the tool does) and `tools/remove-uuids` to `tools/basket-remove-uuids` (prefix-group consistency with `basket-compare` / `basket-join`). Update any scripts, wrappers or documentation that invoked the old names.
116117

117118

tools/build-basket

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ import _common
4949
import yaml
5050

5151
__author__ = 'Linuxfabrik GmbH, Zurich/Switzerland'
52-
__version__ = '2026041302'
52+
__version__ = '2026041401'
5353

5454
DESCRIPTION = """Generate an Icinga Director basket JSON from a check plugin. Walks the
5555
plugin's argparse definition, turns each parameter into a Director datafield, emits a
@@ -162,7 +162,9 @@ def parse_args():
162162
mode.add_argument(
163163
'--auto',
164164
help='Automatically (re)generate baskets for every check plugin '
165-
'in the repo.',
165+
'in the repo. Never prompts: unknown datafields or objects get '
166+
'a fresh uuid instead of asking which old object they '
167+
'correspond to.',
166168
dest='AUTO',
167169
action='store_true',
168170
default=False,
@@ -447,7 +449,7 @@ def offer_selection(options):
447449
sys.exit(130)
448450

449451

450-
def manage_uuids(data, old_data=None):
452+
def manage_uuids(data, old_data=None, auto=False):
451453
if old_data:
452454
reused_uuid_objects = []
453455
for parent_key, parent_value in data.items():
@@ -471,6 +473,10 @@ def manage_uuids(data, old_data=None):
471473
# could not find the uuid in the existing basket, therefore skipping so a new one is generated further down
472474
continue
473475
old_uuid = None
476+
elif auto:
477+
# `--auto` never prompts: treat unknown varnames as new
478+
# objects so a fresh uuid is generated further down.
479+
continue
474480
else:
475481
print(
476482
f'\nCould not find the corresponding object for "[{parent_key}][{value["varname"]}]". Which uuid should I use?'
@@ -497,6 +503,10 @@ def manage_uuids(data, old_data=None):
497503
if old_uuid is not None:
498504
data[parent_key][key]['uuid'] = old_uuid
499505
reused_uuid_objects.append(f'[{parent_key}][{key}]')
506+
elif auto:
507+
# `--auto` never prompts: treat unknown keys as new
508+
# objects so a fresh uuid is generated further down.
509+
continue
500510
else:
501511
print(
502512
f'\nCould not find the corresponding object for "[{parent_key}][{key}]".'
@@ -756,7 +766,7 @@ def parse_plugin_args(
756766
return data, command_field_id
757767

758768

759-
def generate_basket(plugin_file, config=None, old_data=None):
769+
def generate_basket(plugin_file, config=None, old_data=None, auto=False):
760770
if config is None:
761771
config = {}
762772
if 'variants' not in config:
@@ -929,7 +939,7 @@ def generate_basket(plugin_file, config=None, old_data=None):
929939
if not data[key]:
930940
del data[key]
931941

932-
return manage_uuids(data, old_data)
942+
return manage_uuids(data, old_data, auto=auto)
933943

934944

935945
def _load_old_basket(path):
@@ -963,12 +973,14 @@ def _load_config(path):
963973
return None
964974

965975

966-
def build_basket_for_plugin(plugin_file):
976+
def build_basket_for_plugin(plugin_file, auto=False):
967977
"""Generate (or regenerate) the basket for one plugin file.
968978
969979
Returns True on success, False on failure. Callers decide
970980
whether a single failure stops the sweep or just gets
971-
collected for an end-of-run summary.
981+
collected for an end-of-run summary. With ``auto=True`` no
982+
interactive prompts are shown: unknown objects get fresh
983+
uuids instead of asking which old object they correspond to.
972984
"""
973985
plugin_file = Path(plugin_file)
974986
if not plugin_file.is_file():
@@ -989,7 +1001,7 @@ def build_basket_for_plugin(plugin_file):
9891001
if config is not None:
9901002
print(f'Using config at {config_file}.')
9911003

992-
plugin_data = generate_basket(str(plugin_file), config, old_data)
1004+
plugin_data = generate_basket(str(plugin_file), config, old_data, auto=auto)
9931005
if plugin_data is None:
9941006
_common.err(f'No data for {check_name}.')
9951007
return False
@@ -1015,7 +1027,7 @@ def main():
10151027
print('\n' + '- ' * 40)
10161028
print(f'Check: {plugin_dir.name}')
10171029
print('- ' * 40)
1018-
if not build_basket_for_plugin(plugin_file):
1030+
if not build_basket_for_plugin(plugin_file, auto=True):
10191031
failed.append(plugin_dir.name)
10201032

10211033
if failed:

0 commit comments

Comments
 (0)