Skip to content

Prototyping CLI based on Obsah#131

Closed
ehelms wants to merge 1 commit intotheforeman:masterfrom
ehelms:prototype-obash
Closed

Prototyping CLI based on Obsah#131
ehelms wants to merge 1 commit intotheforeman:masterfrom
ehelms:prototype-obash

Conversation

@ehelms
Copy link
Member

@ehelms ehelms commented Apr 11, 2025

Simple as I could get CLI using Obsah based on the data-types branch (theforeman/obsah#63). I'll follow up with adding some additional variables that make use of types to play around with the idea more.

@ehelms ehelms force-pushed the prototype-obash branch 4 times, most recently from f17cd09 to 98fe327 Compare April 14, 2025 18:41
@ehelms
Copy link
Member Author

ehelms commented Apr 15, 2025

I broke out the start/stop behaviour into it's own PR -- #132

@ehelms ehelms force-pushed the prototype-obash branch 2 times, most recently from f45f3f2 to b7aa809 Compare April 22, 2025 15:27
@ehelms ehelms force-pushed the prototype-obash branch 2 times, most recently from 729afc2 to 7886741 Compare April 24, 2025 01:54
Copy link
Member

@ekohl ekohl left a comment

Choose a reason for hiding this comment

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

I took a stab at making it really shippable and ekohl@55664e8 is the result. Probably still incomplete and I didn't look at the README yet.

I had an idea to also use this as an input to an RPM and then add packit, but this is what I could do before heading back into a meeting.

@ehelms ehelms force-pushed the prototype-obash branch 4 times, most recently from d625463 to 4b3ed36 Compare April 25, 2025 14:32
@ehelms ehelms marked this pull request as ready for review April 28, 2025 12:22
@ehelms ehelms force-pushed the prototype-obash branch 9 times, most recently from 3420981 to e95a933 Compare April 29, 2025 17:49
return path

@staticmethod
def inventory_path():
Copy link
Member Author

Choose a reason for hiding this comment

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

@evgeni I think this concept get's kinda weird in this use case compared to Obal's. The inventory will be dynamic for this use case, and therefore shouldn't live in the Python package. For now, here in the git repository, the inventories/ top level path works. But if I were taking it a step further and installing the Python package on a fresh machine, I would need an inventory defined and specified for using this against remote targets. For running this on the same machine (local) then having a default inventory works just fine. I was thinking of:

  1. Default to localhost so that the default mode is installation on the machine the installer exists.
  2. A user parameter that allows specifying the location of an inventory file.

I wondered about defaulting to also checking /etc/rop for an inventory file for the standard packaged case.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I think for this case, /etc/rop/inventory.yml (or whatever) is the cleanest solution.

Copy link
Member

Choose a reason for hiding this comment

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

To elaborate a bit what I wanted to say: Ansible implies localhost when the given intentory is empty or non-parse-able, so we can just point this to the "production" inventory (which the user will edit, IF they want to add the external DB) that we ship in the RPM, and the dev setup should still work?

% ansible -i /etc/lol/what -m ping localhost
[WARNING]: Unable to parse /etc/lol/what as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
localhost | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

@ehelms
Copy link
Member Author

ehelms commented Apr 29, 2025

This is now rebased on latest, and converted to a Python package along with updates to testing and Github actions. This also introduces a script to setup the virtualenv easily for local development and use in CI.

Copy link
Member

Choose a reason for hiding this comment

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

This file also installs Ansible, but we now pull that in via obsah so doesn't have to mentioned either.

@ehelms ehelms force-pushed the prototype-obash branch from 201ef97 to 377ad32 Compare May 2, 2025 15:37
@ehelms
Copy link
Member Author

ehelms commented May 2, 2025

I opted for a change in strategy to drop the setup command/playbook and move those dependencies around. Two notable things:

  1. This moves the etc_host setup useful for testing into a small playbook that is run by Vagrant at provisioning time.
  2. This moves (in an ugly-ish way) the "what do we do about these dependencies" into the deploy playbook for now.

@ehelms ehelms force-pushed the prototype-obash branch 2 times, most recently from 2ff020b to 7a4883c Compare May 2, 2025 15:46
@ehelms ehelms force-pushed the prototype-obash branch 2 times, most recently from 27b1125 to c977ee6 Compare May 2, 2025 18:40
Copy link
Member

@ekohl ekohl left a comment

Choose a reason for hiding this comment

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

Random shower thought: can we use a simple shell script wrapper instead?

My idea is to configure obsah via environment variables. Something like:

#!/usr/bin/sh

OBSAH_NAME=rop
OBSAH_DATA=data
OBSAH_INVENTORY=
export OBSAH_NAME OBSAH_DATA OBSAH_INVENTORY

exec obsah "$@"

Right now OBSAH_NAME doesn't exist but we can enhance it to. I had a thought to enhance obsah where you symlink /usr/bin/obsah and it looks at __name__ to derive it, but since you need to set OBSAH_DATA anyway I think you need a wrapper anyway.

How I started to think about this was development. Can we install production rop (or whatever), ship all data somewhere and set ROP_DATA / OBSAH_DATA to that location? Then if you take that to a more logical extreme: do we even need rop then?

If we go that route then it may be feasible to package it up as a true Ansible collection while in the RPM we only add the trivial wrapper and package dependencies.

Thinking more about that, perhaps we can still use the symlink /usr/bin/obsah idea but add a /usr/libexec/obsah-collection (or something) that will look at an ansible collection with the same name in /usr/share/ansible/collections/ansible_collections (though that may be too hard with namespaces). Or we can introduce /usr/share/obsah for that purpose.

long_description_content_type='text/markdown',
url='https://github.com/theforeman/foreman-quadlet',
author='The Foreman Project',
author_email='foreman-dev@googlegroups.com',
Copy link
Member

Choose a reason for hiding this comment

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

does that even still exist? :)

@ehelms ehelms force-pushed the prototype-obash branch from c977ee6 to 4687b5c Compare May 6, 2025 11:21
@evgeni
Copy link
Member

evgeni commented May 6, 2025

Random shower thought: can we use a simple shell script wrapper instead?

My idea is to configure obsah via environment variables. Something like:

#!/usr/bin/sh

OBSAH_NAME=rop
OBSAH_DATA=data
OBSAH_INVENTORY=
export OBSAH_NAME OBSAH_DATA OBSAH_INVENTORY

exec obsah "$@"

Most probably: yes. We originally went this route, as the current ApplicationConfig in obal contains executable code (os.getcwd() for the inventory etc), which would need more logic in this wrapper. rop probably won't have that, so it can be easier.

That said, this is an improvement we can do later. Or are you hinting at "then we don't need a python package after all"?

Right now OBSAH_NAME doesn't exist but we can enhance it to. I had a thought to enhance obsah where you symlink /usr/bin/obsah and it looks at __name__ to derive it, but since you need to set OBSAH_DATA anyway I think you need a wrapper anyway.

How I started to think about this was development. Can we install production rop (or whatever), ship all data somewhere and set ROP_DATA / OBSAH_DATA to that location? Then if you take that to a more logical extreme: do we even need rop then?

If we go that route then it may be feasible to package it up as a true Ansible collection while in the RPM we only add the trivial wrapper and package dependencies.

Thinking more about that, perhaps we can still use the symlink /usr/bin/obsah idea but add a /usr/libexec/obsah-collection (or something) that will look at an ansible collection with the same name in /usr/share/ansible/collections/ansible_collections (though that may be too hard with namespaces). Or we can introduce /usr/share/obsah for that purpose.

We should not put (or require! or even accept!) things in /usr/share/ansible/collections/ansible_collections. People will have all sorts of weird stuff there. Incompatible versions etc.

But yes, we should place things in /usr/share/something and point the vars there for prod

pip install -r requirements.txt
ansible-galaxy install -r requirements.yml

echo "\n\nSetup complete. Activate the virtualenv 'source .venv/bin/activate' and then run the cli 'rop'"
Copy link
Member

Choose a reason for hiding this comment

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

bash's echo does not interpret escape chars by default. you need to either use echo -e (non POSIX, afaik) or printf

@ehelms
Copy link
Member Author

ehelms commented May 6, 2025

Random shower thought: can we use a simple shell script wrapper instead?
My idea is to configure obsah via environment variables. Something like:

#!/usr/bin/sh

OBSAH_NAME=rop
OBSAH_DATA=data
OBSAH_INVENTORY=
export OBSAH_NAME OBSAH_DATA OBSAH_INVENTORY

exec obsah "$@"

Most probably: yes. We originally went this route, as the current ApplicationConfig in obal contains executable code (os.getcwd() for the inventory etc), which would need more logic in this wrapper. rop probably won't have that, so it can be easier.

That said, this is an improvement we can do later. Or are you hinting at "then we don't need a python package after all"?

I think it's an interesting idea, that we should capture but I'd like to see us get further and through more of the complex bits before we decide that it can be that simple.

We also have some non-collection things in our tool like the metadata. I guess we could put it in there but would the collection validators complain?

@ehelms ehelms force-pushed the prototype-obash branch from 4687b5c to 8c403c9 Compare May 6, 2025 11:40
name='cli',
version='0.0.1',
license='GPL-2.0-only',
description='packaging wrapper using ansible',
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
description='packaging wrapper using ansible',
description='foreman deployment using ansible',

@ekohl
Copy link
Member

ekohl commented May 6, 2025

That said, this is an improvement we can do later. Or are you hinting at "then we don't need a python package after all"?

I was thinking about that. At least for the prototype it would keep things simple if we don't need a Python package.

Then when we get closer to an actual installer (and perhaps tool to replace foreman-maintain) we can look at how to build it. For example, foreman-maintain configure could be the new installer entry point (with an foreman-maintain install as an alias).

@evgeni
Copy link
Member

evgeni commented May 6, 2025

theforeman/obsah#75

@evgeni
Copy link
Member

evgeni commented May 6, 2025

I like the "simple shell script" idea, as it not only reduces the amount of (boilerplate) code, but also simplifies the directory structure in the repo. OTOH the current state in the PR works fine and would allow us to continue iterating.

Read this comment as: ACK, merge it, unless you want to rewrite it again right now :)

We also have some non-collection things in our tool like the metadata. I guess we could put it in there but would the collection validators complain?

Collection validators don't care much about additional files

@evgeni
Copy link
Member

evgeni commented May 6, 2025

theforeman/obsah#75

that's merged, and the following works after a git mv cli/data .:

#!/bin/bash

OBSAH_NAME=rop
OBSAH_DATA=data
OBSAH_INVENTORY=./inventories/
export OBSAH_NAME OBSAH_DATA OBSAH_INVENTORY

exec obsah "$@"

do whatever you want with that info :)

@ehelms
Copy link
Member Author

ehelms commented May 6, 2025

Then when we get closer to an actual installer (and perhaps tool to replace foreman-maintain) we can look at how to build it. For example, foreman-maintain configure could be the new installer entry point (with an foreman-maintain install as an alias).

Are you thinking this would be recreated in Ansible and follow the same CLI model? Or that it would require some real code in python that would be handled?

@ekohl
Copy link
Member

ekohl commented May 6, 2025

Are you thinking this would be recreated in Ansible and follow the same CLI model? Or that it would require some real code in python that would be handled?

That will depend on how much of the functionality we keep. I'd love to keep it minimal but at this point I'm unclear on where we'd end up and if it's realistic.

Signed-off-by: Eric D. Helms <ericdhelms@gmail.com>
@ehelms ehelms force-pushed the prototype-obash branch from 8c403c9 to ab5caf6 Compare May 8, 2025 12:05
@ehelms
Copy link
Member Author

ehelms commented May 8, 2025

Closing in favor of #143

@ehelms ehelms closed this May 8, 2025
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.

3 participants