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

Provide a way to set the working directory for the linters #885

Open
dhoogfr opened this issue May 10, 2023 · 9 comments
Open

Provide a way to set the working directory for the linters #885

dhoogfr opened this issue May 10, 2023 · 9 comments
Labels
feature New feature or request waiting on author Waiting on feedback from author

Comments

@dhoogfr
Copy link

dhoogfr commented May 10, 2023

Problem

The plugin runs ansible-lint / ansible --syntax-check from a working directory that seems to be set to the workspace root directory.
This can cause issues if for example you have the following directory structure

./project
├── code
│   ├── collections
│   ├── files
│   ├── inventories
│   ├── library
│   ├── playbooks
│   └── roles
└── keys

With the vscode workspace root directory set to "./project" and you have an ansible.cfg file under the code directory.

In such a situation, the linter will not pickup this ansible.cfg file.
In my case it causes an error with "ansible-playbook --syntax-check" as the vault-password-file variable is not picked up and it fails to decrypt the vault file:

Unexpected error code 1 from execution of: ansible-playbook --syntax-check -i localhost, code/playbooks/config_sftp_s3fs.ymlansible-lint[internal-error]

Solution

The Python plugin provides a configuration parameter to set the working directory for the linter.
A similar option for the Ansible plugin to set a (relative) path would solve the above problems

Alternatives

An alternative would be to have an explicit configuration option to specify the vault password file.
But that would not solve the issue with not reading the ansible.cfg file.

Another alternative could be to instead of using the vscode workspace root as working directory, allow the vscode buildin terminal CWD configuration parameter to override it.
But that could break existing setups

Additional context

No response

@cidrblock
Copy link
Contributor

There is a setting to set the command line paramters for ansible-lint, I'm curious if that could be used to set the target directory for linting as a workspace setting

"ansible.validation.lint.arguments": ""

It's also in the extentsion's settings:

image

Let me know if that helps?

TY, brad

@cidrblock cidrblock added waiting on author Waiting on feedback from author and removed new labels May 17, 2023
@dhoogfr
Copy link
Author

dhoogfr commented May 17, 2023

Hi,

I tried to use that setting with the --project-dir parameter, but it did not work.
From the error message it seems that this parameter is not passed to the "ansible-playbook --syntax-check" command

image

image

@robpomeroy
Copy link

robpomeroy commented Jun 6, 2023

Similarly to @dhoogfr, I've attempted to specify a project directory, including through a .ansible-lint file in the playbook's root folder. I even lobbed in an extra var in the hope that I might hit an undocumented feature 😉:

---
project_dir: .

enable_list:
  - args
  - empty-string-compare
  - no-log-password
  - no-same-owner
  - name[prefix]
  - yaml

extra_vars:
  vault_password_file: ~/vault-password

But like @dhoogfr, the only way I could get the extension to pick up the vault password file was to place an ansible.cfg file in the root of my workspace. That's not a fix if the playbooks under that root use different vault passwords.

Can we set a per-project environment variable, and override ANSIBLE_CONFIG? Could the extension offer that possibility? 🤔 (I'm not sure if the environment variable is merged with any config files...?)

For reference, my project structure is like this (simplified):

Ansible
├── project1
│      .ansible-lint
│      ansible.cfg <--- ignored by the extension
│      inventory
│      main.yml
├── project2
│      .ansible-lint
│      ansible.cfg <--- ignored by the extension
│      inventory
│      main.yml
ansible.cfg <--- used by the extension

I also tried:

  • Launching VS Code with ANSIBLE_CONFIG set (ANSIBLE_CONFIG="[default] vault_password_file = ~/vault-password" code)
  • Using a modeline in the playbook (# code: language=ansible env=ANSIBLE_CONFIG="[default] vault_password_file = ~/vault-password")

Unfortunately I don't think we'll get folder-specific settings from VS Code any time soon, so the best option is for this to be available as a setting within the extension.

PS This issue might need the "waiting on author" tag removing?

@ganeshrn
Copy link
Member

ganeshrn commented Jun 6, 2023

@robpomeroy The extension does support multi-root workspace so you can try adding project1 and project2 folder at the root of the workspace using Add folder to workspace option and try setting folder level settings.

Screenshot 2023-06-06 at 8 11 05 PM

@ganeshrn
Copy link
Member

ganeshrn commented Jun 6, 2023

@dhoogfr As mentioned in above comment extension support multi root workspace, so you can add multiple folders at the top level of the workspace.

@robpomeroy
Copy link

@robpomeroy The extension does support multi-root workspace so you can try adding project1 and project2 folder at the root of the workspace using Add folder to workspace option and try setting folder level settings.

Yes, thank you, I had spotted that. 👍 Unfortunately my workspace is large, structured and mature, and I was hoping not to have to rearrange it. It's already multi-root, with Ansible, Docker, Polyglot development, Packer, Terraform and WSL and some others all as separate roots (eight in total). Within the Ansible root, I have 37 separate projects. Ideally I'd prefer a fix that doesn't involve a complete rearrange. 🙂

@ganeshrn
Copy link
Member

ganeshrn commented Jun 6, 2023

The Python plugin provides a configuration parameter to set the working directory for the linter.
A similar option for the Ansible plugin to set a (relative) path would solve the above problems

I like the idea however in case of single Ansible root folder workspace the setting needs to be changed based on which project you are working on within the VSCode window.

I usually work with separate VSCode windows for different projects and use multi-root workspace for related sub-projects

@erichiller
Copy link

I too have found myself in need of this feature, I have a project/repo with a structure like:

/services/
 └ ansible/
  ├ ansible.cfg
  ├ .yamllint
  ├ .ansible-lint
  ├ .ansible-lint-ignore
  ├ playbooks/
  └ roles/

Currently, the VSCode Ansible extension only works when opened from /services/ansible and not / or /services/. Watching the extension debug output I see that the .ansible-lint config file is used, but it does not detect the ansible.cfg config, nor .yamllint.

I tried setting ANSIBLE_CONFIG in the workspace .vscode/settings.json:

"terminal.integrated.env.linux": {
    "ANSIBLE_CONFIG": "/xxx/services/ansible/ansible.cfg"
}

But this did not fix anything.

I found that if I set in the console export ANSIBLE_CONFIG=/xxx/services/ansible/ansible.cfg and then open vscode like code . then the ansible extension detects the ansible.cfg and works as I would expect (however the .yamllint config file still is not used).

Assuming the issue is detection of ansible.cfg then one of the following would be really helpful.

  1. Respect the vscode. internal terminal (SP?) environment setting (ANSIBLE_CONFIG)
  2. Add a config setting for the path to the ansible.cfg
  3. Add a config setting for the ansible working directory

@hatifnatt
Copy link

Just bumped into this while setting up ansible-lint, I have two Ansible projects with common inventory, with directory structure like this

/
├── .ansible-lint
├── code-helper.sh*
├── infra/
│   ├── ansible.cfg
│   ├── .ansible-lint
│   ├── requirements/
│   ├── roles/
│   ├── roles_internal/
│   ├── roles_public/
│   ├── templates/
│   └── myplaybook.yml
├── inventories/
│   ├── group_a/
│   └── group_a/
├── private/
│   ├── ansible.cfg
│   ├── .ansible-lint
│   ├── anotherplaybook.yaml
│   └── roles/
└── .vscode/
    └── settings.json

When I'm running ansible-lint from inside subproject directory (inside infra or private) - all fine it reads ansible.cfg and takes into account roles_path parameter where all roles directories are specified.
But when VSCode is running ansible-lint it always run it with project root as cwd therefor ansible-lint doesn't read ansible.cfg and .ansible-lint from sub directories and I'm getting error about 'role not found' i.e.

# rewrapped for readability
"message": "the role 'private.role' was not found in
/~snip~/ansible/infra/roles:
/home/hatifnatt/.cache/:
/home/hatifnatt/.ansible/roles:
/usr/share/ansible/roles:
/etc/ansible/roles:
/~snip~/ansible/infra"

It's easy to notice that infra/roles_internal/, infra/roles_public/ not included in the search path.

First I'm tried to add

"ansible.validation.lint.arguments": "--project-dir ${PWD}/infra",

to .vscode/settings.json, but that does not help ansible-lint still doesn't read ansible.cfg, also in a such way I can only resolve issue with one subproject.

For now I take idea from @erichiller and created helper script code-helper.sh located in the project root.

#!/usr/bin/env bash

SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
export ANSIBLE_ROLES_PATH=./infra/roles/:./infra/roles_internal/:./infra/roles_public/:./private/roles/
code "$SCRIPT_DIR"

I'm not using ANSIBLE_CONFIG because in my case I have multiple ones and they may be not exactly similar.

From VSCode side of thing it would be nice if environment variables defined for integrated terminal would be passed to command line linters, or alternatively additional configuration section in Ansible extension where environment variables can be defined.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request waiting on author Waiting on feedback from author
Projects
Status: No status
Development

No branches or pull requests

6 participants