Imagemagick install from source - No makefile found - makefile

I'm trying to install ImageMagick from source. To do this I'm using the instructions here. It works until the make command is executed. It says that it can't find the makefile "cmd": "/usr/bin/make", "msg": "make: *** No targets specified and no makefile found. Stop." I tried different targets such as 'all' and 'install', and no target. In the directory are 2 files Makefile.am, and Makefile.in.
This is the text from the Ansible playbook I set up for this:
- name: register directory name var
shell: ls -d /path/ImageMagick-*
register: dir_path
- name: configure imagemagick make
command: "{{ dir_path.stdout }}/configure"
- name: Build default target
make:
chdir: "{{ dir_path.stdout }}"
- name: Run 'install' target
make:
chdir: "{{ dir_path.stdout }}"
target: install
The problem seems to be in the configure step but it appears to have completed successfully, or else it should have displayed an error message, I suppose? Here is the output from Ansible as a paste: https://pastebin.com/MJjnQeRB
If I run ./configure and then make on the command line, it works. So this seems to be an Ansible problem. How can I make it work?

Your other targets use chdir to switch to another directory, but you're not doing that for configure, so its output lands somewhere else. You need to run configure and make in the same directory.
Option 1: add chdir: to the configure recipe, too.
Option 2: remove chdir: from the other recipes.
Option 3: collapse configure and make to run in the same recipe, and chdir: or not as you wish.

The solution is to change the command to include chdir:
- name: configure imagemagick make
command: ./configure
args:
chdir: "{{ dir_path.stdout }}"

Related

Best way to create directory if not exists, but do not modify if exists

I would like to create a new directory with a specified mode/owner but only if it does not yet exist.
I can do it by first checking stat:
- name: Determine if exists
stat:
path: "{{ my_path }}"
register: path
- name: Create path
file:
path: "{{ my_path }}"
owner: someuser
group: somegroup
mode: 0775
state: directory
when: not path.stat.exists
Is it possible to do this without the extra step?
If not, is there a better way to accomplish this?
Ansible can be used to manage the directory in question, always ensuring that it will have the defined ownership and permissions irrespective of whether it exists or not.
If you want to avoid any chances of modifying an existing directory for some reason, the way you accomplished it using Ansible modules (requiring two tasks) is correct.
However, if you do need to accomplish this in 1 step - you can use the command module to run the install command to create directory.
Example:
- name: Create path
command:
cmd: "install -o someuser -g somegroup -m 0775 -d {{ my_path }}"
creates: "{{ my_path }}"
Here we are using the creates property to prevent the command from running when the path already exists.

File permissions unset or incorrect

I am using ansible copy module to copy a file. The linter tells me "File permissions unset or incorrect" and I don't understand the problem.
Here is the ansible task
- name: Ensure some.txt is there
copy:
src: some.txt
dest: "{{ some_path }}/some.txt"
force: false
mode: '644'
Where some.txt is a file that exists in the ansible/files directory.
I have also tried with mode: 0644 but no luck.
My ansible version:
$ ansible-lint --version
ansible-lint 5.0.7 using ansible 2.10.8
Restarting the editor fixed it, but that's not really an answer.
Any ideas?
risky-file-permissions
File permissions unset or incorrect
Missing or unsupported mode parameter can cause unexpected file permissions based on version of Ansible being used. Be explicit, like mode: 0644 to avoid hitting this rule. Special preserve value is accepted only by copy, template modules. See https://github.com/ansible/ansible/issues/71200
Reference: https://ansible-lint.readthedocs.io/en/latest/default_rules.html
If you're using some module who requires the usage of mode... Set the mode and the error will vanish.
You just need to specify mode: 0644 in your playbook and it will be all good.

Head first program - ansible

I have installed ansible using following commands.
sudo apt-add-repository ppa:ansible/ansible
sudo apt update
sudo apt install ansible
After i followed this Link. By using that i created a yml file called test.yml ( the code is shown below)
- name: test my new module
hosts: 127.0.1
tasks:
- name: run the new module
my_test:
name: 'hello'
new: true
register: testout
- name: dump test output
debug:
msg: '{{ testout }}'
Then i run ansible-playbook ./test.yml . I get following error.
I have no idea where i missed. Any idea is appreciated. Thank you so much.
sato:~/play_around_with_ansible$ ansible-playbook ./test.yml
[WARNING]: provided hosts list is empty, only localhost is available. Note
that the implicit localhost does not match 'all'
ERROR! no action detected in task. This often indicates a misspelled module name, or incorrect module path.
The error appears to be in '/home/ven/play_around_with_ansible/test.yml': line 4, column 5, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
tasks:
- name: run the new module
^ here
You are missing the inventory file. Create inventory file in current folder or in the directory of your choice and provide the inventory file path to the ansible-playbook command as below or you can mention the default location of your host file in ansible.cfg
inventory file contents (sample)
[127.0.1]
localhost ansible_connection=local
command
ansible-playbook -i inventory ./test.yml
In the above command inventory is the file name with path.
seems your 'yaml' file was not able to recognize the path for custom module. Even I am new to custom module development. As per the standards you should keep the .py file in "library" directory and create the .ymal file outside of library directory.
This will help your yaml file to look into ./library directory for modules.

Running Python script via ansible

I'm trying to run a python script from an ansible script. I would think this would be an easy thing to do, but I can't figure it out. I've got a project structure like this:
playbook-folder
roles
stagecode
files
mypythonscript.py
tasks
main.yml
release.yml
I'm trying to run mypythonscript.py within a task in main.yml (which is a role used in release.yml). Here's the task:
- name: run my script!
command: ./roles/stagecode/files/mypythonscript.py
args:
chdir: /dir/to/be/run/in
delegate_to: 127.0.0.1
run_once: true
I've also tried ../files/mypythonscript.py. I thought the path for ansible would be relative to the playbook, but I guess not?
I also tried debugging to figure out where I am in the middle of the script, but no luck there either.
- name: figure out where we are
stat: path=.
delegate_to: 127.0.0.1
run_once: true
register: righthere
- name: print where we are
debug: msg="{{righthere.stat.path}}"
delegate_to: 127.0.0.1
run_once: true
That just prints out ".". So helpful ...
try to use script directive, it works for me
my main.yml
---
- name: execute install script
script: get-pip.py
and get-pip.py file should be in files in the same role
If you want to be able to use a relative path to your script rather than an absolute path then you might be better using the role_path magic variable to find the path to the role and work from there.
With the structure you are using in the question the following should work:
- name: run my script!
command: ./mypythonscript.py
args:
chdir: "{{ role_path }}"/files
delegate_to: 127.0.0.1
run_once: true
An alternative/straight forward solution:
Let's say you have already built your virtual env under ./env1 and used pip3 install the needed python modules.
Now write playbook task like:
- name: Run a script using an executable in a system path
script: ./test.py
args:
executable: ./env1/bin/python
register: python_result
- name: Get stdout or stderr from the output
debug:
var: python_result.stdout
If you want to execute the inline script without having a separate script file (for example, as molecule test) you can write something like this:
- name: Test database connection
ansible.builtin.command: |
python3 -c
"
import psycopg2;
psycopg2.connect(
host='127.0.0.1',
dbname='db',
user='user',
password='password'
);
"
You can even insert Ansible variables in this string.

How can I check if file has been downloaded in ansible

I am downloading the file with wget from ansible.
- name: Download Solr
shell: wget http://mirror.mel.bkb.net.au/pub/apache/lucene/solr/4.7.0/solr-4.7.0.zip
args:
chdir: {{project_root}}/solr
but I only want to do that if zip file does not exist in that location. Currently the system is downloading it every time.
Note: this answer covers general question of "How can i check the file existence in ansible", not a specific case of downloading file.
The problems with the previous answers using "command" or "shell" actions is that they won't work in --check mode. Actually, first action will be skipped, and next will error out on "when: solr_exists.rc != 0" condition (due to variable not being defined).
Since Ansible 1.3, there's more direct way to check for file existance - using "stat" module. It of course also works well as "local_action" to check a local file existence:
- local_action: stat path={{secrets_dir}}/secrets.yml
register: secrets_exist
- fail: msg="Production credentials not found"
when: secrets_exist.stat.exists == False
Unless you have a reason to use wget why not use get_url module. It will check if the file needs to be downloaded.
---
- hosts : all
gather_facts : no
tasks:
- get_url:
url="http://mirror.mel.bkb.net.au/pub/apache/lucene/solr/4.7.0/solr-4.7.0.zip"
dest="{{project_root}}/solr-4.7.0.zip"
NOTE: If you put the directory and not the full path in the dest ansible will still download the file to a temporary dir but do an md5 check to decide whether to copy to the dest dir.
And if you need to save state of download you can use:
---
- hosts : all
gather_facts : no
tasks:
- get_url:
url="http://mirror.mel.bkb.net.au/pub/apache/lucene/solr/4.7.0/solr-4.7.0.zip"
dest="{{project_root}}/solr-4.7.0.zip"
register: get_solr
- debug:
msg="solr was downloaded"
when: get_solr|changed
Many modules are already aware of the result and will be skipped if its already there, like file or geturl. Others like command have a creates option, which will skip this command if that file already exists (or doesn't exist, if you use the removes option).
So you should first check the available modules, if they are smart enough already. If not: I recommend the stats module. Advantage over the other solution: No "red errors but ignored" in the output.
- name: Check MySQL data directory existence
stat: path=/var/lib/mysql-slave
register: mysql_slave_data_dir
- name: Stop MySQL master to copy data directory
service: name=mysql state=stopped
sudo: yes
when: not mysql_slave_data_dir.stat.exists
There are at least two options here.
You can register a variable if the file exists, then use a when condition to execute the command on the condition that the file doesn't already exist:
- command: /usr/bin/test -e {{project_root}}/solr/solr-4.7.0.zip
register: solr_zip
ignore_errors: True
- name: Download Solr
shell: chdir={{project_root}}/solr /usr/bin/wget http://mirror.mel.bkb.net.au/pub/apache/lucene/solr/4.7.0/solr-4.7.0.zip
when: solr_zip|failed
You could also use the commands module with the creates option:
- name: Download Solr
command: /usr/bin/wget http://mirror.mel.bkb.net.au/pub/apache/lucene/solr/4.7.0/solr-4.7.0.zip chdir={{project_root}}/solr creates={{project_root}}/solr/solr-4.7.0.zip
This article might be useful
Out of it comes this example:
tasks:
- shell: if [[ -f "/etc/monitrc" ]]; then /bin/true; else /bin/false; fi
register: result
ignore_errors: True
- command: /bin/something
when: result|failed
- command: /bin/something_else
when: result|success
- command: /bin/still/something_else
when: result|skipped
So basically you can do this checking by registering a variable from a command and checking its return code. (You can also do this by checking its stdout)
- name: playbook
hosts: all
user: <your-user>
vars:
project_root: /usr/local
tasks:
- name: Check if the solr zip exists.
command: /usr/bin/test -e {{project_root}}/solr/solr-4.7.0.zip
ignore_errors: True
register: solr_exists
- name: Download Solr
shell: chdir={{project_root}}/solr wget http://mirror.mel.bkb.net.au/pub/apache/lucene/solr/4.7.0/solr-4.7.0.zip
when: solr_exists.rc != 0
This basically says that if the /usr/bin/test -e {{project_root}}/solr/solr-4.7.0.zip command returns a code that is not 0, meaning it doesn't exist then execute the task Download Solr
Hope it helps.
my favourite is to only download the file if it is newer than the local file (which includes when the local file does not exist)
the -N option with wget does this: https://www.gnu.org/software/wget/manual/html_node/Time_002dStamping-Usage.html .
sadly, i don't think there is an equivalent feature in get_url
so a very small change:
- name: Download Solr
shell: chdir={{project_root}}/solr wget -N http://<SNIPPED>/solr-4.7.0.zip
Use the creates argument
- name: Download Solr
shell: creates={{working_directory}}/solr/solr-4.7.0.zip chdir={{working_directory}}/solr wget http://mirror.mel.bkb.net.au/pub/apache/lucene/solr/4.7.0/solr-4.7.0.zip

Resources