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

cargo fails to find standard homedir path for cargo binary #4407

Closed
1 task done
hammerandtongs opened this issue Mar 27, 2022 · 11 comments · Fixed by #7352
Closed
1 task done

cargo fails to find standard homedir path for cargo binary #4407

hammerandtongs opened this issue Mar 27, 2022 · 11 comments · Fixed by #7352
Labels
bug This issue/PR relates to a bug language module module packaging plugins plugin (any type)

Comments

@hammerandtongs
Copy link

hammerandtongs commented Mar 27, 2022

Summary

the cargo module fails with -

TASK [Install tokei Rust package] *************************************************************************************************************************** fatal: [hostname]: FAILED! => {"changed": false, "msg": "Failed to find required executable \"cargo\" in paths: /usr/local/bin:/usr/bin:/bin:/usr/games:/sbin:/usr/sbin:/usr/local/sbin"}

cargo executable is located in default rustup install location /home/username/.cargo/bin/

Issue Type

Bug Report

Component Name

cargo

Ansible Version

$ ansible --version
ansible [core 2.12.3]
  config file = /home/username/foo/ansible.cfg
  configured module search path = ['/home/username/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /home/username/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.9.10 (main, Feb 22 2022, 13:54:07) [GCC 11.2.0]
  jinja version = 3.0.3
  libyaml = True

Community.general Version

$ ansible-galaxy collection list community.general

# /usr/lib/python3/dist-packages/ansible_collections
Collection        Version
----------------- -------
community.general 4.5.0  

Configuration

$ ansible-config dump --only-changed
DEFAULT_HOST_LIST(/home/username/foo/ansible.cfg) = ['/home/username/foo/HOSTS']

OS / Environment

Debian Bookworm targeting Bookworm

Steps to Reproduce

Run this module against home directory with the default rustup install location.

Expected Results

cargo installs the package

Actual Results

TASK [Install tokei Rust package] ***************************************************************************************************************************
fatal: [hostname]: FAILED! => {"changed": false, "msg": "Failed to find required executable \"cargo\" in paths: /usr/local/bin:/usr/bin:/bin:/usr/games:/sbin:/usr/sbin:/usr/local/sbin"}

Code of Conduct

  • I agree to follow the Ansible Code of Conduct
@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

@ansibullbot ansibullbot added bug This issue/PR relates to a bug language module module packaging plugins plugin (any type) labels Mar 27, 2022
@felixfontein
Copy link
Collaborator

Ansible looks in /sbin, /usr/sbin, /usr/local/sbin and $PATH. Your $PATH only seems to contain /usr/local/bin, /usr/bin, and /bin, but not /home/username/.cargo/bin/.

@hammerandtongs
Copy link
Author

hammerandtongs commented Mar 28, 2022

Yes ansible is ignoring the expanded path from the .bashrc and .profile (and this is how ansible normally works).

Rustup puts a . ~/.cargo/env in profile or bashrc and this is being ignored by ansible and so the cargo module can't work with this setup.

There is mention of this in the ansible cargo docs as working better with the hardcoded bin paths probably because of this issue.

edit-

This seems like a case where the module cargo should use something like -

shell: bash -ilc 'which cargo'

So that the proper environment is found.

@felixfontein
Copy link
Collaborator

Ansible does nowhere document that these files are loaded and/or interpreted. So why is this a bug? It is a mismatched expectation / missing feature (ability to specify extra paths where to look, diectly path to executable, or automatically add ~/.cargo/bin/ to search path), but I don't see how this is a bug.

@hammerandtongs
Copy link
Author

This module seems like a busy sysadmins trap.

It doesn't detect the default install location for most peoples development environment (ie rustup based) that it's failing to find.

It's also going to invoke cargo install (which does build things) without respecting the developer rust environment.

There are many potential bugs by hardcoding things like this.

Right now this module seems unsuitable for a developer workstation deploy.

The module can work for people that only want to install ripgrep via an os installed cargo (thus bypassing the os installed ripgrep).

I think I would have nacked this module until both the path and cargo respected the remote environment.

But really it needs some rustup integration as well, as a big chunk of developer tooling is in rustup. -

https://github.com/hurricanehrndz/ansible-rustup

This following yaml was robust and useful in deploying a workstation

---
- hosts: workstations
  vars:
    cargo_installs: [tokei,cargo-crev,flamegraph]
    rustup_installs: [rustfmt, rust-src, clippy]
  tasks:
  - name: check if cargo is installed
    shell: bash -lc "command -v cargo"
    register: cargo_exists
    ignore_errors: no
  - name: Download rustup
    when: cargo_exists is failed
    get_url:
      url: https://sh.rustup.rs
      dest: /tmp/sh.rustup.rs
      mode: '0750'
      force: 'yes'
    tags:
      - rust
  - name: install rust/cargo
    when: cargo_exists is failed
    shell: /tmp/sh.rustup.rs -y
    tags:
      - rust
  - name: do the cargo installs
    with_items: "{{cargo_installs}}"
    shell: "bash -lc 'cargo install -q {{item}}'"
    loop: "{{cargo_installs}}"
    register: op
  - name: do the rustup installs
    with_items: "{{rustup_installs}}"
    shell: "bash -lc 'rustup component add {{item}}'"
  - name: rustup update
    shell: bash -lc "rustup update"

original source - https://waylonwalker.com/til/install-rust/#full-install-playbook

@radek-sprta
Copy link
Contributor

I think implementing executable argument to specify path to the binary (like some of the other modules do) seems to be the best solution.

@hammerandtongs
Copy link
Author

@radek-sprta I think that would solve the immediate issue but I'm not sure it will be correct in the medium term.

When you run "~/.cargo/bin/cargo" or the found cargo directly its still going to ignore -

https://doc.rust-lang.org/cargo/reference/environment-variables.html

If you don't run cargo install within the shell environment.

I have no idea who or in what circumstances would get future confusion or bugs.

@radek-sprta
Copy link
Contributor

Whjen I get back from PTO, I'll take a look at implementing those.

@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

@autra
Copy link

autra commented Sep 25, 2023

It's old, but searches brings here. My current workaround is to directly alter the PATH:

- name: install rust stuff
  environment:
    PATH: "{{ansible_env.PATH}}:{{ ansible_env.HOME }}/.cargo/bin"
  community.general.cargo:
    name:
      - ...

It has the advantage of making it explicit which cargo I target (but for that I would prefer an executable option still).

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 language module module packaging plugins plugin (any type)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants