I am trying to run a script using the command module on a Jenkins server. The script is written in such a way that it should return 0 if not making any configuration changes and the Ansible task should not be changed.
Here is the code:
- name: Script to run
command: java -jar /var/cache/jenkins/war/WEB-INF/jenkins-cli.jar -s http://localhost:8080 groovy "{{ jenkins_home }}/userContent/script.groovy"
register: return_code
changed_when: return_code.stdout != 0
But the above code behaves is always showing as changed.
The Ansible output:
TASK [jenkins : Script to run] ********************************
changed: [test] => {"changed": true, "cmd": ["java", "-jar", "/var/cache/jenkins/war/WEB-INF/jenkins-cli.jar", "-s", "http://localhost:8080", "groovy", "/var/lib/jenkins/userContent/script.groovy"], "delta": "0:00:01.547098", "end": "2017-02-06 15:31:05.989134", "rc": 0, "start": "2017-02-06 15:31:04.442036", "stderr": "[WARN] Failed to authenticate with your SSH keys. Proceeding as anonymous", "stdout": "0", "stdout_lines": ["0"], "warnings": []}
You need to compare the stdout value with a string instead of an integer:
- name: Script to run
command: java -jar /var/cache/jenkins/war/WEB-INF/jenkins-cli.jar -s http://localhost:8080 groovy "{{ jenkins_home }}/userContent/script.groovy"
register: script_call
changed_when: script_call.stdout != "0"
Related
I'm new in Ansible and I try to do some practice playbook. I write a playbook to deploy a Docker container as follows. I write a task in the block section if an error happened, run a task in the rescue section based on Failed message content. For example, I want to run a specific task to delete an existing container if the Failed message is something like this:
failed: [192.168.1.140] (item=stderr_lines) => {"changed": true, "cmd": ["docker", "run", "-itd", "--name", "h1", "-p", "80:80", "httpd"], "delta": "0:00:00.016385", "end": "2021-01-04 03:00:55.403364", "failed_when_result": true, "item": "stderr_lines", "msg": "non-zero return code", "rc": 125, "start": "2021-01-04 03:00:55.386979", "stderr": "/usr/bin/docker-current: Error response from daemon: Conflict. The container name "/h1" is already in use by container bc5cc803a5f4321358992d06097ce271f3a63b8eba19900cfc0d23e321a4e243. You have to remove (or rename) that container to be able to reuse that name..\nSee '/usr/bin/docker-current run --help'.", "stderr_lines": ["/usr/bin/docker-current: Error response from daemon: Conflict. The container name "/h1" is already in use by container bc5cc803a5f4321358992d06097ce271f3a63b8eba19900cfc0d23e321a4e243. You have to remove (or rename) that container to be able to reuse that name..", "See '/usr/bin/docker-current run --help'."], "stdout": "", "stdout_lines": []}"
My playbook is as follows but it didn't work correctly. Sometimes an error in reading dictionary or "Unexpected templating type error occurred on". Can somebody guide me on what should I write?
- name: run a container
vars:
- run_container: docker run -itd --name h1 -p 80:80 httpd
- rm_container: docker stop h1 && docker rm h1
hosts: 192.168.x.x
tasks:
- name: check docker container
block:
- name: run a container httpd
command: "{{run_container}}"
register: rss
with_items:
- "stderr_lines"
failed_when: "'Error' in rss.stderr"
rescue:
- name: iterate over list
debug:
msg: "{{item.value}}"
loop: "{{rss | dict2items}}"
- name: remove the exited container
command: "{{rm_container}}"
register: rs
with_items:
- "{{rss | dict2items}}"
when: item.value is search("The container name .* is already in use")
To disable logins for root I would like to set its shell to the path of nologin, which is determined by a command.
The command module registers the variable properly:
- name: Get nologin path
command: which nologin
register: nologin
- debug:
var: nologin
Debug info:
ok: [192.168.178.25] => {
"nologin": {
"changed": true,
"cmd": [
"which",
"nologin"
],
"delta": "0:00:00.001612",
"end": "2019-08-26 11:23:41.764847",
"failed": false,
"rc": 0,
"start": "2019-08-26 11:23:41.763235",
"stderr": "",
"stderr_lines": [],
"stdout": "/usr/sbin/nologin",
"stdout_lines": [
"/usr/sbin/nologin"
]
}
}
But when I use the user module it takes the registered variable as a string:
- name: Disable root
user:
name: root
shell: nologin.stdout
state: present
Result in /etc/passwd:
$ cat /etc/passwd
root:x:0:0:root:/root:nologin.stdout
Thanks for any help!
It's a variable, to use it you need to put in jinja2 template {{ }} and inside " " as it is required by YAML:
shell: "{{ nologin.stdout }}"
Ref:
https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#using-variables-with-jinja2
https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#hey-wait-a-yaml-gotcha
I am trying to download a golang package from github. This is how my playbook looks like
- name: Fetch latest gogs repository
shell: "go get -u github.com/gogits/gogs"
become: true
become_user: git
It is throwing me following error:
{
"changed": true,
"cmd": "go get -u github.com/gogits/gogs",
"delta": "0:00:00.002695",
"end": "2017-08-22 10:50:02.984669",
"failed": true,
"invocation": {
"module_args": {
"_raw_params": "go get -u github.com/gogits/gogs",
"_uses_shell": true,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"warn": true
}
},
"rc": 127,
"start": "2017-08-22 10:50:02.981974",
"stderr": "/bin/sh: go: command not found",
"stderr_lines": [
"/bin/sh: go: command not found"
],
"stdout": "",
"stdout_lines": []
}
When I am trying this
- name: Fetch latest gogs repository
shell: "go get -u {{ gogs_repo }}"
environment:
- PATH: $PATH:/usr/local/go/bin:/usr/bin
- GOPATH: "{{gogs_home}}/{{ gogs_project_directory }}/src"
- GOBIN: "{{gogs_home}}/{{ gogs_project_directory }}/bin"
become: true
become_user: git
I got this error
fatal: [atul-ec2]: FAILED! => {
"changed": false,
"failed": true,
"module_stderr": "Shared connection to ec2-13-126-203-235.ap-south-1.compute.amazonaws.com closed.\r\n",
"module_stdout": "Traceback (most recent call last):\r\n File \"/tmp/ansible_gntmXa/ansible_module_command.py\", line 220, in <module>\r\n main()\r\n File \"/tmp/ansible_gntmXa/ansible_module_command.py\", line 163, in main\r\n os.chdir(chdir)\r\nOSError: [Errno 13] Permission denied: '/home/ec2-user/goprojects/src/src/github.com/gogits/gogs'\r\n",
"msg": "MODULE FAILURE",
"rc": 1
}
Here my variables are
---
go_version: go1.7.linux-amd64.tar.gz
go_url: https://storage.googleapis.com/golang/{{ go_version }}
go_hash: sha256:702ad90f705365227e902b42d91dd1a40e48ca7f67a2f4b2fd052aaa4295cd95
go_project_dir: goprojects
go_home: "{{ ansible_env.HOME }}"
gogs_home: "/home/git"
gogs_project_directory: "git.varadev.com"
gogs_repo: github.com/gogits/gogs
But when i am using following command on my server
which go
I got this
/usr/local/go/bin/go
and when I try manually go get -u github.com/gogits/gogs, it is working fine.
Hope this can help you as a start point:
---
- hosts: all
connection: local
tasks:
- name: check go version
command: go version
register: result
changed_when: no
ignore_errors: true
- set_fact:
go_path: "{{ lookup('env', 'GOPATH') | default(ansible_env.HOME+'/go', true) }}"
when: not result|failed
- name: go get gogs
shell: go get -u github.com/gogits/gogs
environment:
GOPATH: "{{ go_path }}"
register: gogs
when: not result|failed
- debug: var=gogs
Try to run this on your remote server by typing:
ansible-playbook gogs.yml -i localhost,
If that works then just later try remotely.
Normally you don't want to do this since you want to execute this remotely over ssh, but since you had tried so far and are getting some errors, probably by trying locally connection: local could help to debug more in details this issue.
I know this post is too old, but maybe this may help someone.
Ths issue /bin/sh: go: command not found it is because you are missing some configuration when Ansible runs, and probably you need to source the bash profile like this:
- name: Install gogs
shell: "source ~/.bash_profile && github.com/gogits/gogs"
args:
chdir: /home/{{ owner }}
become_user: '{{ owner }}'
That worked for me.
While provisioning via Vagrant and Ansible I keep running into this issue.
TASK [postgresql : Create extensions] ******************************************
failed: [myapp] (item=postgresql_extensions) => {"changed": true, "cmd": "psql myapp -c 'CREATE EXTENSION IF NOT EXISTS postgresql_extensions;'", "delta": "0:00:00.037786", "end": "2017-04-01 08:37:34.805325", "failed": true, "item": "postgresql_extensions", "rc": 1, "start": "2017-04-01 08:37:34.767539", "stderr": "ERROR: could not open extension control file \"/usr/share/postgresql/9.3/extension/postgresql_extensions.control\": No such file or directory", "stdout": "", "stdout_lines": [], "warnings": []}
I'm using a railsbox.io generated playbook.
Turns out that railsbox.io is still using a deprecated syntax in the task.
- name: Create extensions
sudo_user: '{{ postgresql_admin_user }}'
shell: "psql {{ postgresql_db_name }} -c 'CREATE EXTENSION IF NOT EXISTS {{ item }};'"
with_items: postgresql_extensions
when: postgresql_extensions
The last line should use full jinja2 syntax.
when: '{{postgresql_extensions}}'
I am trying to write an Ansible playbook that only compiles Nginx if it's not already present and at the current version. However it compiles every time which is undesirable.
This is what I have:
- shell: /usr/local/nginx/sbin/nginx -v 2>&1
register: nginxVersion
- debug:
var=nginxVersion
- name: install nginx
shell: /var/local/ansible/nginx/makenginx.sh
when: "not nginxVersion == 'nginx version: nginx/1.8.0'"
become: yes
The script all works apart from the fact that it runs the shell script every time to compile Nginx. The debug output for nginxVersion is:
ok: [server] => {
"var": {
"nginxVersion": {
"changed": true,
"cmd": "/usr/local/nginx/sbin/nginx -v 2>&1",
"delta": "0:00:00.003752",
"end": "2015-09-25 16:45:26.500409",
"invocation": {
"module_args": "/usr/local/nginx/sbin/nginx -v 2>&1",
"module_name": "shell"
},
"rc": 0,
"start": "2015-09-25 16:45:26.496657",
"stderr": "",
"stdout": "nginx version: nginx/1.8.0",
"stdout_lines": [
"nginx version: nginx/1.8.0"
],
"warnings": []
}
}
}
According to the documentation I am on the right lines, what simple trick am I missing?
Try:
when: nginxVersion.stdout != 'nginx version: nginx/1.8.0'
or
when: '"nginx version: nginx/1.8.0" not in nginxVersion.stdout'
Since var is a json string you can parse it to json and access it's keys.
set_fact:
var_json: "{{ var.stdout|from_json }}"
Then access the json and get the value you want.
when: var_json.nginxVersion.stdout == 'nginx version: nginx/1.8.0'
checkout this link: https://gist.github.com/justinhennessy/28e82c2ec05f9081786a