Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

operatingsystems ambiguity #1401

Closed
gvde opened this issue May 4, 2022 · 10 comments · Fixed by #1407
Closed

operatingsystems ambiguity #1401

gvde opened this issue May 4, 2022 · 10 comments · Fixed by #1407

Comments

@gvde
Copy link
Contributor

gvde commented May 4, 2022

SUMMARY

Running against a katello 4.3 or 4.4 server my playbook complains about the operating systems to be created/updated:

[WARNING]: While constructing a mapping from /home/k/k202081/git/foreman-ansible/first.yaml, line 1834, column 9, found a duplicate dict key (foreman_operatingsystems). Using
last defined value only.

It seems the problem is that multiple operating systems can have the same name, e.g. AlmaLinux. I have AlmaLinux with major version 8 and no minor version (AlmaLinux 8) and one with minor version 5 (AlmaLinux 8.5)

When adding and syncing AlmaLinux repositories it automatically generates a distribution and operating system "AlmaLinux 8".

The a client host with AlmaLinux 8.5 is registered it automatically generates an operating system "AlmaLinux 8.5" (from puppet facts or subscription manager?)

So this scenario seems standard.

ANSIBLE VERSION
$ ansible --version
ansible 2.9.27
  config file = /home/k/k111111/git/foreman-ansible/ansible.cfg
  configured module search path = ['/home/k/k111111/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.6.8 (default, Nov 17 2021, 16:10:06) [GCC 8.5.0 20210514 (Red Hat 8.5.0-3)]
COLLECTION VERSION

Using latest version 3.3.0 from ansible-galaxy with some patches from pull requests.

KATELLO/FOREMAN VERSION
katello-4.4.0-1.el8.noarch
foreman-3.2.0-1.el8.noarch
STEPS TO REPRODUCE

Playbook

    - role: theforeman.foreman.operatingsystems
      vars:
        foreman_operatingsystems:
          - name: "AlmaLinux"
            major: "8"
            description: "AlmaLinux 8"
            os_family: "Redhat"
            architectures:
              - "x86_64"
            password_hash: "SHA256"
            media:
              - "AlmaLinux 8"
              - "Local AlmaLinux 8"
        foreman_operatingsystems:
          - name: "AlmaLinux"
            major: "8"
            minor: "5"
            description: "AlmaLinux 8.5"
            os_family: "Redhat"
            architectures:
              - "x86_64"
            password_hash: "SHA256"
            media:
              - "AlmaLinux 8"
              - "Local AlmaLinux 8"
           override: disabled
EXPECTED RESULTS

No error and correct configuration of all operating system entities.

@evgeni
Copy link
Member

evgeni commented May 4, 2022

I think your yaml is wrong.

Shouldn't it be

    - role: theforeman.foreman.operatingsystems
      vars:
        foreman_operatingsystems:
          - name: "AlmaLinux"
            major: "8"
            description: "AlmaLinux 8"
            os_family: "Redhat"
            architectures:
              - "x86_64"
            password_hash: "SHA256"
            media:
              - "AlmaLinux 8"
              - "Local AlmaLinux 8"
          - name: "AlmaLinux"
            major: "8"
            minor: "5"
            description: "AlmaLinux 8.5"
            os_family: "Redhat"
            architectures:
              - "x86_64"
            password_hash: "SHA256"
            media:
              - "AlmaLinux 8"
              - "Local AlmaLinux 8"

@gvde
Copy link
Contributor Author

gvde commented May 4, 2022

Yes. You are right. I was already wondering why I got this error. Initially it was a different one which I now get again:

TASK [theforeman.foreman.operatingsystems : Create Operatingsystems] **********************************************************************************************************************************
failed: [foreman8.example.com] (item={'name': 'AlmaLinux', 'major': '8', 'description': 'AlmaLinux 8', 'os_family': 'Redhat', 'architectures': ['x86_64'], 'password_hash': 'SHA256', 'media': ['AlmaLinux 8', 'Local AlmaLinux 8']}) => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "ansible_loop_var": "item", "changed": false, "error": {"errors": {"name": ["Operating system version already exists"], "title": ["has already been taken"]}, "full_messages": ["Name Operating system version already exists", "Title has already been taken"], "id": null}, "item": {"architectures": ["x86_64"], "description": "AlmaLinux 8", "major": "8", "media": ["AlmaLinux 8", "Local AlmaLinux 8"], "name": "AlmaLinux", "os_family": "Redhat", "password_hash": "SHA256"}, "msg": "Error while performing create on operatingsystems: 422 Client Error: Unprocessable Entity for url: https://foreman8.dkrz.de/api/operatingsystems"}
ok: [foreman8.example.com] => (item={'name': 'AlmaLinux', 'major': '8', 'minor': '5', 'description': 'AlmaLinux 8.5', 'os_family': 'Redhat', 'architectures': ['x86_64'], 'password_hash': 'SHA256', 'media': ['AlmaLinux 8', 'Local AlmaLinux 8']})

In check mode it looks as if it wants to create a new entry even though it already exists... Both operating systems already exist on the server.

@evgeni
Copy link
Member

evgeni commented May 10, 2022

can you show us the output of curl -u admin:changeme https://foreman.example.com/api/operatingsystems?

@gvde
Copy link
Contributor Author

gvde commented May 10, 2022

Here is the output from my new server:

{
    "total": 4,
    "subtotal": 4,
    "page": 1,
    "per_page": 20,
    "search": null,
    "sort": {
        "by": null,
        "order": null
    },
    "results": [
        {
            "description": null,
            "major": "8",
            "minor": "",
            "family": "Redhat",
            "release_name": null,
            "password_hash": "SHA256",
            "created_at": "2022-05-03 17:29:04 UTC",
            "updated_at": "2022-05-03 17:29:04 UTC",
            "id": 3,
            "name": "AlmaLinux",
            "title": "AlmaLinux 8"
        },
        {
            "description": "AlmaLinux 8.5",
            "major": "8",
            "minor": "5",
            "family": "Redhat",
            "release_name": null,
            "password_hash": "SHA256",
            "created_at": "2022-04-25 08:12:21 UTC",
            "updated_at": "2022-04-25 08:12:21 UTC",
            "id": 1,
            "name": "AlmaLinux",
            "title": "AlmaLinux 8.5"
        },
        {
            "description": null,
            "major": "7",
            "minor": "",
            "family": "Redhat",
            "release_name": null,
            "password_hash": "SHA256",
            "created_at": "2022-04-26 14:46:15 UTC",
            "updated_at": "2022-04-26 14:46:15 UTC",
            "id": 2,
            "name": "CentOS",
            "title": "CentOS 7"
        },
        {
            "description": null,
            "major": "8",
            "minor": "",
            "family": "Redhat",
            "release_name": null,
            "password_hash": "SHA256",
            "created_at": "2022-05-04 09:04:05 UTC",
            "updated_at": "2022-05-04 09:04:05 UTC",
            "id": 4,
            "name": "CentOS_Stream",
            "title": "CentOS_Stream 8"
        }
    ]
}

@evgeni
Copy link
Member

evgeni commented May 13, 2022

Oooh, mhh. Operating systems in Foreman are super weird, so we have some crude logic to search for them. It goes essentially like this: "try to find by description, if that fails, look up by name/major/minor".

Now your playbook sets description to "AlmaLinux 8" but the currently existing OS doesn't have that set, so it's not finding it by that (fine!). Next it should try name/major/minor (you didn't set minor, so that would be not taken into the search), so the search string should be name="AlmaLinux" major="8" and I would think it should find it like that, but it does not :(

The 8.5 search works, as there it already finds it by description.

(Did I mention I hate how OSes are implemented?)

@evgeni
Copy link
Member

evgeni commented May 13, 2022

Got it!

It searches for "name=AlmaLinux,major=8", but that returns two results, and thus it discards the result.

@evgeni
Copy link
Member

evgeni commented May 13, 2022

diff --git plugins/modules/operatingsystem.py plugins/modules/operatingsystem.py
index 69d70d3d..0be9e478 100644
--- plugins/modules/operatingsystem.py
+++ plugins/modules/operatingsystem.py
@@ -211,7 +211,7 @@ def main():
         entity = None
         # If we have a description, search for it
         if 'description' in module_params and module_params['description'] != '':
-            search_string = 'description="{0}"'.format(module_params['description'])
+            search_string = 'description="{0}" or title="{0}"'.format(module_params['description'], module_params['description'])
             entity = module.find_resource('operatingsystems', search_string, failsafe=True)
         # If we did not yet find a unique OS, search by name & version
         # In case of state == absent, those information might be missing, we assume that we did not find an operatingsytem to delete then

This should fix the issue for you.

@gvde
Copy link
Contributor Author

gvde commented May 13, 2022

Got it!

It searches for "name=AlmaLinux,major=8", but that returns two results, and thus it discards the result.

Shouldn't it possible to distinguish between searching for major=8,minor=null and major=8,minor=*?

@evgeni
Copy link
Member

evgeni commented May 13, 2022

Shouldn't it possible to distinguish between searching for major=8,minor=null and major=8,minor=*?

See my explanation in #1407 on why this is not as trivial as it sounds (TL;DR: minor can be null, minor can be an empty string)

@evgeni
Copy link
Member

evgeni commented May 13, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants