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

opkg - _package_in_desired_state does not handle properly opkg list_installed output #8706

Open
1 task done
akire0ne opened this issue Aug 2, 2024 · 6 comments
Open
1 task done
Labels
bug This issue/PR relates to a bug module module plugins plugin (any type) traceback

Comments

@akire0ne
Copy link

akire0ne commented Aug 2, 2024

Summary

Tried to integrate community.general.opkg for the first time in our ansible stack. We have some embedded devices that uses opkg for package management. My task is very trivial.

---
- name: Install vim - opkg
  community.general.opkg:
    name: "vim=9.0.1211-r0"

This results in

An exception occurred during task execution. To see the full traceback, use -vvv. The error was: ansible_collections.community.general.plugins.module_utils.mh.exceptions.ModuleHelperException
fatal: [<censored_hostname>]: FAILED! => {
    "changed": false,
    "output": {
        "diff": {}
    },
    "vars": {}
}

MSG:

failed to install vim=9.0.1211-r0

The package is installed on the remote host

root@XXXXXXXX:~# opkg list_installed vim
vim - 9.0.1211-r0

After installing the package, the modules runs the above command to confirm that it has been installed properly. This part is broken. After diging a bit, the culprit is that function:

def _package_in_desired_state(self, name, want_installed, version=None):
dummy, out, dummy = self.runner("state package").run(state="query", package=name)
has_package = out.startswith(name + " - %s" % ("" if not version else (version + " ")))
return want_installed == has_package

In my case: out="vim - 9.0.1211-r0\n" So when it executes has_package = out.startswith(name + " - %s" % ("" if not version else (version + " "))) - It will always return False, because there is no whitespace at the end of my out. I am not sure what is the rationale behind this condition but it clearly does not fit the out from my device. It seems like an unhandled scenario.

I fixed locally by removing the extra whitespace after version in the condtion:

has_package = out.startswith(name + " - %s" % ("" if not version else version))

I'm not sure if that approach is fine, I can't find history about that extra whitespace.

Issue Type

Bug Report

Component Name

community.general.opkg

Ansible Version

$ ansible --version
ansible [core 2.16.9]
python version = 3.10.9 (main, May  1 2024, 16:32:48)
jinja version = 3.1.4
libyaml = True

Community.general Version

$ ansible-galaxy collection list community.general
Collection        Version
----------------- -------
community.general 9.2.0

Configuration

Too sensitive environment. sorry. I don't think it's helpful for that issue.

OS / Environment

Controller: Ubuntu 22.04 LTS

Target:
OS: PetaLinux 2023.1
kernel: Linux k26-lunx-tx 6.1.30-xilinx-v2023.1 #1 SMP Fri Jun 30 09:49:44 UTC 2023 aarch64 GNU/Linux
opkg: version 0.6.1 (libsolv 0.7.22)

Steps to Reproduce

I think the description is self explanatory. The target device that we use is rather exotic and unfortunatelly I think it might be difficult to reproduce.

Expected Results

The package should show as "installed" and the module should not error out because of unhandled out

Actual Results

No response

Code of Conduct

  • I agree to follow the Ansible Code of Conduct
@akire0ne akire0ne changed the title community.general.opkg - _package_in_desired_state does not handle properly opkg list_installed community.general.opkg - _package_in_desired_state does not handle properly opkg list_installed output Aug 2, 2024
@ansibullbot
Copy link
Collaborator

Files identified in the description:

If these files are incorrect, please update the component name section of the description or use the !component bot command.

click here for bot help

@ansibullbot
Copy link
Collaborator

cc @skinp
click here for bot help

@ansibullbot ansibullbot added bug This issue/PR relates to a bug module module plugins plugin (any type) traceback labels Aug 2, 2024
@felixfontein
Copy link
Collaborator

The condition

has_package = out.startswith(name + " - %s" % ("" if not version else version))

is not correct either, since it thinks 1.1 is installed if 1.10 is installed, for example, since 1.10 starts with 1.1. I guess the output format of opkg list_installed changed, or depends on the concrete version or whatever...

I would probably adjust the code to split into lines, and check whether the first line starts with foo - version , or equals foo - version. That way both output formats are covered.

CC @joergho who implemented version support in #5688 and might have some insight here as well...

@joergho
Copy link
Contributor

joergho commented Aug 6, 2024

Thans for reporting the bug @akire0ne and for the analysis @felixfontein

If the Yocto version of opkg is used, the following code is executed in the end: print_pkg. This means that depending of the configuration, the output can be any of the following:

NAME - VERSION
NAME - VERSION - SIZE
NAME - VERSION - SIZE - DESCRIPTION
NAME - VERSION - DESCRIPTION

I'd therefore suggest to split the string by -:

    def _package_in_desired_state(self, name, want_installed, version=None):
        dummy, out, dummy = self.runner("state package").run(state="query", package=name)

        splitted = out.split(" - ")
        has_package = (splitted[0] == name) and (version is None or splitted[1] == version)
        return want_installed == has_package

I have done minimal testing in Python console but not yet using the whole ansible stack.

@felixfontein
Copy link
Collaborator

If you simply split by " - ", and the input is "NAME - VERSION\n", splitted[1] ends up as "VERSION\n" with the newline added.

How about using

        lines = out.splitlines()
        splitted = lines[0].split(" - ") if lines else [None, None]

instead of splitted = out.split(" - ")?

@joergho
Copy link
Contributor

joergho commented Aug 6, 2024

How about using (...)

Yes, this would work!

@russoz russoz changed the title community.general.opkg - _package_in_desired_state does not handle properly opkg list_installed output opkg - _package_in_desired_state does not handle properly opkg list_installed output Sep 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue/PR relates to a bug module module plugins plugin (any type) traceback
Projects
None yet
Development

No branches or pull requests

4 participants