I am configuring a mesos-marathon cluster.
I have the next role to install java and mesos.
---
- name: importar key Mesosphere
shell: gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys E56151BF
- name: ppa java8
apt_repository: repo='ppa:webupd8team/java' state=present
- name: seleccionar licencia Oracle
shell: echo debconf shared/accepted-oracle-license-v1-1 select true | sudo debconf-set-selections
- name: actualizar
apt: update_cache=yes
- name: instalar java8
apt: name=oracle-java8-installer state=latest update-cache=yes force=yes
- name: actualizar sources list
shell: DISTRO=$(lsb_release -is | tr '[:upper:]' '[:lower:]') && CODENAME=$(lsb_release -cs) && echo "deb http://repos.mesosphere.io/${DISTRO} ${CODENAME} main" | sudo tee /etc/apt/sources.list.d/mesosphere.list
- name: actualizar paquetes
apt: update_cache=yes cache_valid_time=3600
- name: instalar mesos
apt: name=mesos state=present install_recommends=yes force=yes
- name: instalar mesosphere
apt: name=mesosphere state=present install_recommends=yes force=yes
My problem is that when I execute the playbook, it gives me the next error:
TASK [common : actualizar sources list] ****************************************
changed: [172.16.8.191]
TASK [common : actualizar paquetes] ********************************************
ok: [172.16.8.191]
TASK [common : instalar mesos] *************************************************
fatal: [172.16.8.191]: FAILED! => {"changed": false, "failed": true, "msg": "No package matching 'mesos' is available"}
PLAY RECAP *********************************************************************
172.16.8.191 : ok=8 changed=5 unreachable=0 failed=1
But if I execute ansible for a second time it works perfectly you can see executing a second time:
TASK [common : actualizar paquetes] ********************************************
ok: [172.16.8.191]
TASK [common : instalar mesos] *************************************************
changed: [172.16.8.191]
TASK [common : instalar mesosphere] ********************************************
changed: [172.16.8.191]
What could be the problem?
Thanks.
SOLUTION BY #ydaetskcoR
Change the task 'instalar mesos':
- name: instalar mesos
apt: name=mesos state=present install_recommends=yes update_cache=yes force=yes
The issue you have is that the actualizar paquetes task is only doing an apt-get update to refresh your repo lists if the last update was more than an hour ago.
Considering you've only just added the Mesos repo in the previous task you won't then be able to find the package. Re-running the playbook triggers the actualizar task before that which doesn't have a cache_valid_time setting and so will force an apt-get update which will then allow you to use the Mesos repo that you added in the last playbook run.
To fix it you could just remove the cache_valid_time from the actualizar paquetes task.
As mentioned in the comments, you can also move the update_cache only apt tasks into the main apt task that actually installs packages and Ansible will run the apt-get update before the apt-get install.
Related
I am new to Ansible and try, as an example, a task to install Vivaldi. My only task in a role Vivaldi update starts with
- name: Run apt upgrade
apt:
upgrade: "yes"
update_cache: yes
cache_valid_time: 432000
- name: Add Vivaldi Repository
apt_repository:
repo: "deb https://repo.vivaldi.com/stable/deb/ stable main"
state: present
filename: vivaldi.list
update_cache: true
tags:
- vivaldi
And with this, I fail on localhost on a DebianĀ 10 (Buster) installation:
Linux london 4.19.0-12-amd64 #1 SMP Debian 4.19.152-1 (2020-10-18) x86_64 GNU/Linux).
All commands succeed on the command line.
Ansible is 2.9.15.
The first task runs OK (if run alone), but the second fails with:
FAILED! => {"changed": false, "msg": "apt cache update failed"}.
A task to add a repository key fails with:
FAILED! => {"changed": false, "id": "6D3789EDC3401E12", "msg": "key does not seem to have been added"}
However, if I add the repository manually to /etc/apt/sources.list the last task,
- name: Install Vivaldi
apt:
name: vivaldi-stable
update_cache: yes
state: latest
tags:
- vivaldi
it succeeds.
What am I doing wrong?
According to official documentation you need to add the key and later the repository:
Manual setup of the Vivaldi Linux repositories
Edit your playbook with the task Add key:
- name: Run apt upgrade
apt:
upgrade: "yes"
update_cache: yes
cache_valid_time: 432000
- name: Add key
apt_key:
url: https://repo.vivaldi.com/archive/linux_signing_key.pub
state: present
tags:
- vivaldi
- name: Add Vivaldi Repository
apt_repository:
repo: "deb https://repo.vivaldi.com/stable/deb/ stable main"
state: present
filename: vivaldi.list
update_cache: true
tags:
- vivaldi
- name: Install Vivaldi
apt:
name: vivaldi-stable
update_cache: yes
state: latest
tags:
- vivaldi
I have the following ansible playbook:
- hosts: node1
sudo: yes
gather_facts: no
tasks:
- name: update apt
apt: update_cache=yes
- name: install python-setuptools
apt: name=python-setuptools update_cache=yes
- name: easy_install pexpect module
easy_install: name=pexpect state=latest
- name: add geonode repo
apt_repository: repo='ppa:geonode/stable' state=present
- name: update apt
apt: update_cache=yes
- name: install geonode
apt: name=geonode update_cache=yes
- expect:
command: geonode createsuperuser
responses:
(?i)username: 'test'
(?i)email: 'test#test.com'
When I run it I get:
PLAY [node1] *******************************************************************
TASK [update apt] **************************************************************
ok: [node1]
TASK [install python-setuptools] ***********************************************
changed: [node1]
TASK [easy_install pexpect module] *********************************************
changed: [node1]
TASK [add geonode repo] ********************************************************
changed: [node1]
TASK [update apt] **************************************************************
ok: [node1]
TASK [install geonode] *********************************************************
Then it hangs indefinitely.
In the remote node (node1), I checked the dir
/home/vagrant/.ansible/tmp/ansible-tmp-1470059145.13-122191240803512/
run the file inside to see why my task is hanging
vagrant#node1:~/.ansible/tmp/ansible-tmp-1470059145.13-122191240803512$ python apt
and get:
{"msg": "Failed to lock apt for exclusive operation", "failed": true, "invocation": {"module_args": {"dpkg_options": "force-confdef,force-confold", "autoremove": false, "force": false, "name": "geonode", "install_recommends": null, "package": ["geonode"], "purge": false, "allow_unauthenticated": false, "state": "present", "upgrade": null, "update_cache": true, "default_release": null, "only_upgrade": false, "deb": null, "cache_valid_time": null}}}
Do you have any insights?
EDIT 1:
It is all day I'm launching this script and never got it working. As I posted this question, obviously, the script successfully executed till the end in 15 minutes. I launched it before lunch today and after 1 hour it was still hanging. Why do I get such a different behaviour? Is there a way in which I can control it?
This issue might be caused by an empty /var/lib/apt folder.
Vagrant might take a while to populate these folders which could cause the apt lock.
Also the playbook is inefficient as update_cache is used multiple times. I would recommend to use something like this:
- hosts: node1
sudo: yes
gather_facts: no
tasks:
# Pause for 5 minutes to make sure vagrant does not hold apt lock.
- pause:
minutes: 5
- name: add geonode repo
apt_repository:
repo: 'ppa:geonode/stable'
state: present
- name: Install apt packages.
apt:
name: "{{ item }}"
state: present
update_cache: true
with_items:
- python-setuptools
- geonode
- name: Create geonode superuser.
expect:
command: geonode createsuperuser
responses:
(?i)username: 'test'
(?i)email: 'test#test.com'
This way Ansible won't update the repositories multiple times during the play.
Since the last thing you see is TASK [install geonode], that's where it's getting stuck.
You are asking it to run geonode createsuperuser which you expect to cause a prompt for username and password.
But what is likely happening is that there is an error being produced from that command, and the expect task is not handling the error, instead just hanging.
You can login to the server you are running this against and run the geonode createsuperuser command manually to see what error is being produced.
In my case, this was happening as a result of the username already being taken since I successfully ran the command on this machine already.
Error: That username is already taken.
Even with the echo: yes argument, ansible doesn't seem to pass on the responses to make it obvious what's happening. And it doesn't accept ignore_errors, so there seems to be no way to handle errors with the expect module.
To work around this, I added another task after the createsuperuser task which places a file in the project indicating the user was created once, and then added creates: {{ path }}/superuser_exists.txt to the createsuperuser task so that it won't run if that file is already there.
It's a hack, but an easy one, and until the module gets better error handling, it will work well enough.
- name: Create the django superuser
expect:
command: "{{ virtualenv_path }}/bin/python3 {{ project_path }}/{{ api_app_name }}/manage.py createsuperuser"
creates: "{{ project_path }}/{{ api_app_name }}/superuser_exists.txt"
responses:
(?i)username: "{{ superuser_username }}"
(?i)email: "{{ superuser_email }}"
(?i)password: "{{ superuser_password }}"
(?i)again: "{{ superuser_password }}"
- name: Create a file to indicate that the superuser was already created
file: path="{{ project_path }}/{{ api_app_name }}/superuser_exists.txt" state=touch
I am testing with ansible, what I'm trying to do is install apache2 on another ubuntu server, I already have the group "test" defined with 1 ip. but what happens is that ansible throws me some errors when executing it, I've searched a lot of sites and a lot of people have had this issue, but on different situations and I amd starting to get frustrated with it. Can somebody help me?
Ansible Playbook:
---
- hosts: test
sudo: yes
tasks:
- name: Check if Im sudo
command: echo $USER
- name: install packages
apt: name:apache2 update_cache=yes state=latest
notify: start apache2
handlers:
- name: start apache2
service: name=apache2 state=started
STDOUT
root#ip-172-31-35-33:/etc/ansible/example# ansible-playbook example.yml
PLAY [test] *******************************************************************
GATHERING FACTS ***************************************************************
ok: [172.31.36.176]
TASK: [Check if Im sudo] ******************************************************
changed: [172.31.36.176]
TASK: [install packages] ******************************************************
failed: [172.31.36.176] => {"failed": true}
msg: this module requires key=value arguments (['name:apache2', 'update_cache=yes', 'state=latest'])
FATAL: all hosts have already failed -- aborting
PLAY RECAP ********************************************************************
to retry, use: --limit #/root/example.retry
172.31.36.176 : ok=2 changed=1 unreachable=0 failed=1
BTW, the host is reachable, I can ssh into it, even with ansible, this is the proof
root#ip-172-31-35-33:/etc/ansible/example# ansible -m shell -a "ifconfig | grep 'inet addr'" test
172.31.36.176 | success | rc=0 >>
inet addr:172.31.36.176 Bcast:172.31.47.255 Mask:255.255.240.0
inet addr:127.0.0.1 Mask:255.0.0.0
another thing is that I'm able to install apache2 by hand on the other server, BUT IT IS NOT INSTALLED BECAUSE I WANT TO INSTALL IT USING ANSIBLE
Thanks
Within an individual task, Ansible requires you to make the choice between standard YAML syntax and their own parsed version with equals signs. In this task, you are mixing the two:
- name: install packages
apt: name:apache2 update_cache=yes state=latest
notify: start apache2
This could be either written:
- name: install packages
apt:
name: apache2
update_cache: yes
state: latest
notify: start apache2
Or:
- name: install packages
apt: name=apache2 update_cache=yes state=latest
notify: start apache2
YAML also allows for using bracket and comma syntax to allow you to specify your key-value information on the same line:
- name: install packages
apt: {name: apache2, update_cache: yes, state: latest}
notify: start apache2
Any of these are valid.
You're using a colon where an equal is needed. You need to change the name:apache2 to name=apache2.
I need to set-up my server. I've the following ansible playbook.
---
- hosts: webservers
user: root
sudo: yes
tasks:
- name: add nginx ppa
action: apt_repository repo=ppa:nginx/stable state=present
- name: install common packages needed for python application development
action: apt pkg=$item state=installed
with_items:
- libpq-dev
- libmysqlclient-dev
- libxml2-dev
- libxslt1-dev
- mysql-client
- python-dev
- python-setuptools
- python-mysqldb
- build-essential
- git
- nginx
- name: install pip
action: easy_install name=pip
- name: install various libraries with pip
action: pip name=$item state=present
with_items:
- uwsgi
handlers:
- name: restart nginx
service: name=nginx state=restarted
When I run this script, following is the output
PLAY [webservers] *************************************************************
GATHERING FACTS ***************************************************************
ok: [IP]
TASK: [add nginx ppa] *********************************************************
ok: [IP]
TASK: [install common packages needed for python application development] *****
failed: [IP] => (item=libpq-dev,libmysqlclient-dev,libxml2-dev,libxslt1-dev,mysql-client,python-dev,python-setuptools,python-mysqldb,build-essential,git,nginx) => {"failed": true, "item": "libpq-dev,libmysqlclient-dev,libxml2-dev,libxslt1-dev,mysql-client,python-dev,python-setuptools,python-mysqldb,build-essential,git,nginx"}
msg: No package matching '$item' is available
FATAL: all hosts have already failed -- aborting
PLAY RECAP ********************************************************************
to retry, use: --limit #/home/praful/setup_server.yaml.retry
IP : ok=2 changed=0 unreachable=0 failed=1
I've referred this link for the same.
I'm new to ansible and dont understand the error, since there is no typo in the package name provided in with_items. What exactly is the error??
You need the jinja variable syntax {{item}} where you have $item.
Ok, It is my task:
---
- name: copy source list
copy: src=sources.list dest=/etc/apt/sources.list
notify: update apt
# - name: Update apt
# shell: apt-get update
- name: Install postgres
shell: apt-get install -q -y postgresql-9.1
#apt: name=postgresql-9.1 state=present
- others tasks...
Here is my handler:
- name: update apt
action: apt-get update
When I run it doesn't notify.
...
TASK: [postgresql | copy source list] *****************************************
changed: [host_slave2]
changed: [host_slave1]
changed: [host_pgpool]
changed: [host_master]
TASK: [postgresql | Install postgres] *****************************************
changed: [host_slave1]
changed: [host_master]
changed: [host_slave2]
changed: [host_pgpool]
...
After the copy I should have to see the notification, what is wrong?
---
- name: copy source list
copy: src=sources.list dest=/etc/apt/sources.list
#http://docs.ansible.com/apt_repository_module.html
register: update_apt
- name: Update apt
apt: update_cache=yes cache_valid_time=86400
#http://docs.ansible.com/apt_module.html
when: update_apt is defined and update_apt.changed == True
- name: Install postgres
shell: apt-get install -q -y postgresql-9.1
#apt: name=postgresql-9.1 state=present
- others tasks...
http://wherenow.org/ansible-handlers/
In fact the issue is necessary to force the implementation of
---
- name: copy source list
copy: src=sources.list dest=/etc/apt/sources.list
notify: update apt
- meta: flush_handlers
- name: Install postgres
shell: apt-get install -q -y postgresql-9.1
#apt: name=postgresql-9.1 state=present
- others tasks...
handler:
- name: update apt
action: apt-get update