Skip to content

List enabled and available features#404

Open
arvind4501 wants to merge 4 commits intotheforeman:masterfrom
arvind4501:features
Open

List enabled and available features#404
arvind4501 wants to merge 4 commits intotheforeman:masterfrom
arvind4501:features

Conversation

@arvind4501
Copy link
Contributor

This implemets listing of available and enabled features, with old foreman-installer there was no good way to list all availabe features then doing foreman-installer --full-help which comes up with lot of puppet module args listed.

Here we have features.yml as source of truth for features listing. I did not like how ansible playbook outputs directly for listing features(it creates a lot of noise), i want it to be like systemctl so i have created a PR in obsah which allows bypassing ansible playbook execution and runs scripts directly(a hack to get nice output, maybe can be better).

This is how it will show the result

./foremanctl features

FEATURE                   STATE        BASE                 DESCRIPTION
katello                   enabled      foreman              Katello content management
remote_execution          enabled      foreman,proxy        Foreman Remote Execution support
azure_rm                  available    foreman              Azure Resource Manager integration
google                    available    foreman              Google Compute Engine integration

This PR lays out my initial thought of solving features listing.

It requires: PR

@arvind4501
Copy link
Contributor Author

Currently This Does not list the BASE features which are hammer, foreman-proxy, foreman

@arvind4501 arvind4501 requested a review from evgeni March 10, 2026 10:50
@ehelms
Copy link
Member

ehelms commented Mar 10, 2026

Is there any to make use of callback_result_format just for this command to format the results the way you'd want to the user? Just a curious question, I can see how this might be useful for some additional things in the future.

In the results, what does the BASE column represent?

@ehelms
Copy link
Member

ehelms commented Mar 10, 2026

Colors can sometimes be a pain, this would enforce colors even if Ansible is configured with no colors. I think we either should skip colors or be consistent with Ansible's configuration.

@arvind4501
Copy link
Contributor Author

Is there any to make use of callback_result_format just for this command to format the results the way you'd want to the user? Just a curious question, I can see how this might be useful for some additional things in the future.

I was not much aware about available callback plugins, but now that you mentioned it, i see that there are builtin plugins which i tried and they does not give our expected output format(if i did not missed anything), we might need to create a custom plugin for that but not sure if we should?

My thought here was that what if i need a custom script to run at some point from foremanctl and i did not find a way to do so, and that made me do theforeman/obsah#105,

In the results, what does the BASE column represent?

This was taken from https://github.com/theforeman/foremanctl/blob/master/src/filter_plugins/foremanctl.py#L7 , where we define BASE_FEATURES(which can have plugins on top of that). So here BASE represent that a feature is a plugin for which BASE_FEATURE. i was expecting this question while deciding what should be the column name and ended up using BASE which i think is confusing and should be better

@arvind4501
Copy link
Contributor Author

arvind4501 commented Mar 11, 2026

Colors can sometimes be a pain, this would enforce colors even if Ansible is configured with no colors. I think we either should skip colors or be consistent with Ansible's configuration.

I agree, colors should be consistent, thanks

@arvind4501 arvind4501 requested a review from stejskalleos March 11, 2026 05:28
@stejskalleos stejskalleos self-assigned this Mar 11, 2026
@ehelms
Copy link
Member

ehelms commented Mar 11, 2026

In the results, what does the BASE column represent?

This was taken from https://github.com/theforeman/foremanctl/blob/master/src/filter_plugins/foremanctl.py#L7 , where we define BASE_FEATURES(which can have plugins on top of that). So here BASE represent that a feature is a plugin for which BASE_FEATURE. i was expecting this question while deciding what should be the column name and ended up using BASE which i think is confusing and should be better

I am not sure this column of information is useful to the user, and we can omit it in the output.

Copy link
Contributor

@stejskalleos stejskalleos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🍏 LGTM
Tested together with the theforeman/obsah#105

Before installation:

./foremanctl features

FEATURE                   STATE        DESCRIPTION
katello                   enabled      Content and Subscription Management plugin for Foreman
azure_rm                  available    Azure Resource Manager plugin for Foreman
google                    available    Google Compute Engine plugin for Foreman

After installation

./foremanctl deploy  --add-feature azure_rm --add-feature google
./foremanctl features

FEATURE                   STATE        DESCRIPTION
azure_rm                  enabled      Azure Resource Manager plugin for Foreman
google                    enabled      Google Compute Engine plugin for Foreman
katello                   enabled      Content and Subscription Management plugin for Foreman

3 features listed (3 enabled, 0 available).

@stejskalleos
Copy link
Contributor

@evgeni @ehelms if you don't have any other comments, feel free to merge

@evgeni
Copy link
Member

evgeni commented Mar 12, 2026

I like the output a lot, but I totally dislike it's a standalone script 🙈

params_yaml = STATE_DIR / "parameters.yaml"
params = load_yaml(params_yaml)

flavor = params.get('flavor', 'katello')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am hesitant to have a default flavor.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, i can omit that

features_yaml = BASE_DIR / "features.yaml"
all_features = load_yaml(features_yaml)

# Load persisted parameters
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of the comments in the file I'd avoid. The code speaks for itself and the comment becomes noise.

@ehelms
Copy link
Member

ehelms commented Mar 12, 2026

I'd be interested in seeing a contrasting implementation of this that follow the paradigms of the current design. That is, using Ansible to collect and output the list of features. Perhaps just something simple that uses the debug module to output the results in the structure you've presented above. I feel like this is needed before we accept a deviation from our baseline design.

@arvind4501
Copy link
Contributor Author

arvind4501 commented Mar 12, 2026

I like the output a lot, but I totally dislike it's a standalone script 🙈

yes @evgeni, i just wanted that there is a way to run scripts via foremanctl rather than playbook, if there are some other use cases for it.
but then also i would love to know if there is some better way which i can implement. are you thinking about custom callback plugins, sure i can try that but not sure how they fit in our design

@arvind4501
Copy link
Contributor Author

arvind4501 commented Mar 12, 2026

I'd be interested in seeing a contrasting implementation of this that follow the paradigms of the current design. That is, using Ansible to collect and output the list of features. Perhaps just something simple that uses the debug module to output the results in the structure you've presented above. I feel like this is needed before we accept a deviation from our baseline design.

I can see that there is a way for callback plugins to hook into ansible's lifecycle events and change default output behavior, so maybe we are going towards callback plugins(stdout callback plugins).
Also looking at filter_plugins i see this a similar to our existing design

@arvind4501
Copy link
Contributor Author

With 0ee3f43 and theforeman/obsah#107 to set stdout callback for a playbook) , we have now moved from running direct script to run ansible stdout callback plugin to change how the output of a command/playbook is displayed.

This is more cleaner and does not by pass running playbook, it hooks into the ansible output event and customize the display.

@evgeni
Copy link
Member

evgeni commented Mar 13, 2026

An alternative can be seen in #408 where I wrote a custom callback, that strips all fancy output if the playbook is features.yaml and otherwise falls back to ansible.builtin.default

@ShimShtein
Copy link
Member

Personally I like the implementation from @evgeni as filter and callback much more than a standalone script. Feels much more native and suited for other usages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants