I'm trying to rename a jar file in a path for deployment using ansible and it is successful. I have tried multiple ways but still, it's failing,
For example, there are multiple Jar files in the path /appdata/tomcat/lib/jars/
we havemultiple jar files with version numbers like below
app_deploy-1.1.1.jar
app_deploy-1.1.2_old_1.jar
app_deploy-1.1.2.jar_before
app_deploy-1.1.2_old_2022.jar
app_deploy-1.1.2_before.jar
I have move all files with .jar extension with date using custom date variable {deploy_date} like this app_deploy-1.1.2_before.jar_{deploy_date}
I have method 1 as below :
- name: Get the name of the current jar files
shell: ls -l /appdata/tomcat/lib/jars/ | grep .*.jar
register: jar_files_list
- debug:
msg: "{{ jar_files_list }}"
- name: Get the date
shell: date +%Y%m%d%H%M%S
register: timestamp
when: jar_files_list.stdout != ''
- name: Rename the current jar file
file:
src: /appdata/tomcat/lib/jars/{{ jar_files_list }}
dest: /appdata/tomcat/lib/jars/{{ jar_files_list }}_{{ ansible_date_time.date }}_backup
when: jar_files_list.stdout != ''
I have method 2 as below :
- name: Rename the current jar files
shell: mv /appdata/tomcat/lib/jars/*.jar {{ repo_name }}-*.jar_backup_{{ ansible_date_time.date }}
- name: Move current filesto backup directory
shell: mv /appdata/tomcat/lib/jars/{{ repo_name }}-.*.jar /appdata/tomcat/lib/jars//backup_jars/`
Both of the solutions doest work, can someone help me with some solutions
The find module can be used to find and generate a list of files located on a remote host based on a pattern:
- name: Get jars in {{ jars_path }}
find:
paths: "{{ jars_path }}"
file_type: file
patterns: '*.jar'
register: jars_list
The output will be a dictionary of only the *.jar files in the specified path:
TASK [Get jars in /appdata/tomcat/lib/jars] ************************
ok: [test-001] => {
"changed": false,
"examined": 4,
"files": [
{
"atime": 1661249640.3583002,
"ctime": 1661249640.3583002,
"dev": 64768,
"gid": 0,
"gr_name": "root",
"inode": 8980720,
"isblk": false,
"ischr": false,
"isdir": false,
"isfifo": false,
"isgid": false,
"islnk": false,
"isreg": true,
"issock": false,
"isuid": false,
"mode": "0644",
"mtime": 1661249640.3583002,
"nlink": 1,
"path": "/appdata/tomcat/lib/jars/test1.jar",
"pw_name": "root",
"rgrp": true,
"roth": true,
"rusr": true,
"size": 0,
"uid": 0,
"wgrp": false,
"woth": false,
"wusr": true,
"xgrp": false,
"xoth": false,
"xusr": false
},
{
"atime": 1661249640.3583002,
"ctime": 1661249640.3583002,
"dev": 64768,
"gid": 0,
"gr_name": "root",
"inode": 8980722,
"isblk": false,
"ischr": false,
"isdir": false,
"isfifo": false,
"isgid": false,
"islnk": false,
"isreg": true,
"issock": false,
"isuid": false,
"mode": "0644",
"mtime": 1661249640.3583002,
"nlink": 1,
"path": "/appdata/tomcat/lib/jars/test2.jar",
"pw_name": "root",
"rgrp": true,
"roth": true,
"rusr": true,
"size": 0,
"uid": 0,
"wgrp": false,
"woth": false,
"wusr": true,
"xgrp": false,
"xoth": false,
"xusr": false
},
{
"atime": 1661249640.3583002,
"ctime": 1661249640.3583002,
"dev": 64768,
"gid": 0,
"gr_name": "root",
"inode": 8980726,
"isblk": false,
"ischr": false,
"isdir": false,
"isfifo": false,
"isgid": false,
"islnk": false,
"isreg": true,
"issock": false,
"isuid": false,
"mode": "0644",
"mtime": 1661249640.3583002,
"nlink": 1,
"path": "/appdata/tomcat/lib/jars/test3.jar",
"pw_name": "root",
"rgrp": true,
"roth": true,
"rusr": true,
"size": 0,
"uid": 0,
"wgrp": false,
"woth": false,
"wusr": true,
"xgrp": false,
"xoth": false,
"xusr": false
}
],
"invocation": {
"module_args": {
"age": null,
"age_stamp": "mtime",
"contains": null,
"depth": null,
"excludes": null,
"file_type": "file",
"follow": false,
"get_checksum": false,
"hidden": false,
"paths": [
"/appdata/tomcat/lib/jars"
],
"patterns": [
"*.jar"
],
"read_whole_file": false,
"recurse": false,
"size": null,
"use_regex": false
}
},
"matched": 3,
"msg": "All paths examined",
"skipped_paths": {}
}
"{{ jars_list.files }}" will list the files and .path will provide the full path of the file.
Now the copy module with the option remote_src: yes can be used to rename the files:
- name: Rename jars
copy:
src: "{{ item.path }}"
dest: "{{ item.path }}_{{ deploy_date }}"
remote_src: yes
loop: "{{ jars_list.files }}"
Delete the old files:
- name: Remove old jars
file:
path: "{{ item.path }}"
state: absent
loop: "{{ jars_list.files }}"
The complete playbook
- hosts: all
vars:
deploy_date: "{{ ansible_date_time.date }}"
jars_path: /appdata/tomcat/lib/jars
tasks:
- name: Get jars in {{ jars_path }}
find:
paths: "{{ jars_path }}"
file_type: file
patterns: '*.jar'
register: jars_list
- name: Rename jars
copy:
src: "{{ item.path }}"
dest: "{{ item.path }}_{{ deploy_date }}"
remote_src: yes
loop: "{{ jars_list.files }}"
- name: Remove old jars
file:
path: "{{ item.path }}"
state: absent
loop: "{{ jars_list.files }}"
Related
I'm gathering info on SSL certs on servers (looking for expiration date) using the find module.
- name: Find certs on server
find:
path: /etc/ssl/custom/certs
file_type: file
patterns: "*.crt"
recurse: yes
register: find_result
- debug:
var: find_result
The results are:
ok: [server00] => {
"find_result": {
"changed": false,
"examined": 5,
"failed": false,
"files": [
{
"atime": 1622749788.1552677,
"ctime": 1622744497.4393551,
"dev": 2050,
"gid": 0,
"gr_name": "root",
"inode": 19531534,
"isblk": false,
"ischr": false,
"isdir": false,
"isfifo": false,
"isgid": false,
"islnk": false,
"isreg": true,
"issock": false,
"isuid": false,
"mode": "0644",
"mtime": 1622744497.4393551,
"nlink": 1,
"path": "/etc/ssl/custom/certs/somewebsite0.com.crt",
"pw_name": "root",
"rgrp": true,
"roth": true,
"rusr": true,
"size": 1879,
"uid": 0,
"wgrp": false,
"woth": false,
"wusr": true,
"xgrp": false,
"xoth": false,
"xusr": false
},
{
"atime": 1622719627.2477663,
"ctime": 1616545902.3681087,
"dev": 2050,
"gid": 0,
"gr_name": "root",
"inode": 19531253,
"isblk": false,
"ischr": false,
"isdir": false,
"isfifo": false,
"isgid": false,
"islnk": false,
"isreg": true,
"issock": false,
"isuid": false,
"mode": "0644",
"mtime": 1613754568.0,
"nlink": 1,
"path": "/etc/ssl/custom/certs/somewebsite1.com.crt",
"pw_name": "root",
"rgrp": true,
"roth": true,
"rusr": true,
"size": 2081,
"uid": 0,
"wgrp": false,
"woth": false,
"wusr": true,
"xgrp": false,
"xoth": false,
"xusr": false
},
{
"atime": 1622719627.2197664,
"ctime": 1616545902.3721087,
"dev": 2050,
"gid": 0,
"gr_name": "root",
"inode": 19535012,
"isblk": false,
"ischr": false,
"isdir": false,
"isfifo": false,
"isgid": false,
"islnk": false,
"isreg": true,
"issock": false,
"isuid": false,
"mode": "0644",
"mtime": 1601653231.0,
"nlink": 1,
"path": "/etc/ssl/custom/certs/somewebsite2.com.crt",
"pw_name": "root",
"rgrp": true,
"roth": true,
"rusr": true,
"size": 2269,
"uid": 0,
"wgrp": false,
"woth": false,
"wusr": true,
"xgrp": false,
"xoth": false,
"xusr": false
}
],
"matched": 3,
"msg": ""
}
}
I'm needing the path portion of the output ("path": "/etc/ssl/custom/certs/somewebsite1.com.crt"), and if I use find_result.files[0].path it only gives me a single result for each host, when I need every *.crt file.
How can I access each index? I try to use the shell module to perform an action on the .crt file, but again, it's only grabbing the first one due to the [0] index, like so:
- name: Check expiration
shell: "cat {{ find_result.files[0].path }} | openssl x509 -noout -enddate"
register: date
- debug:
var: date.stdout_lines
ok: [server00] => {
"date.stdout_lines": [
"notAfter=Apr 2 19:50:38 2018 GMT"
]
}
Here would be an example playbook based on it:
- hosts: localhost
tasks:
- name: Find certs on server
find:
path: /etc/ssl/custom/certs
file_type: file
patterns: "*.crt"
recurse: yes
register: find_result
- debug:
var: find_result
- name: Play with the data just to demonstrate
set_fact:
IRGeekSauce_list: "{{ (IRGeekSauce_list|default([])) + [item.path] }}"# <-- add each list item to a custom list
with_items: '{{ find_result.files }}' # <-- here we get the files as a list.
- name: your list
debug:
msg: '{{ IRGeekSauce_list }}'
- include_tasks: anothertasklist.yml
loop: '{{ IRGeekSauce_list }}'
loop_control:
loop_var: singlepathvariable
And then you have another "playbook" with just the tasks 'anothertasklist.yml'
- name: hello
debug:
msg: 'You are now in another playbook'
- name:
debug:
msg: 'Woho: {{ singlepathvariable }}'
- name:
openssl_certificate_info:
howeverthatmoduleworks...
And you should be able to just take the entire and include find_result.files as the loop, and then instead just use the loopvar singlepathvariable(and maybe rename it) and just take out the path as {{ singlepathvariable.path }}
This is my ansible:
- name: finding files
find:
paths: /etc/nginx
patterns: '{{ my_vhost }}'
recurse: "yes"
file_type: "file"
delegate_to: '{{ my_server }}'
register: find_result
- name: output the path of the conf file
debug: msg="{{ find_result.files }}"
and the output of msg is:
"msg": [
{
"atime": 1567585207.0371234,
"ctime": 1567585219.9410768,
"dev": 64768,
"gid": 1001,
"inode": 4425684,
"isblk": false,
"ischr": false,
"isdir": false,
"isfifo": false,
"isgid": false,
"islnk": false,
"isreg": true,
"issock": false,
"isuid": false,
"mode": "0644",
"mtime": 1567585219.9410768,
"nlink": 1,
"path": "/etc/nginx/sites-enabled/specified-file",
"rgrp": true,
"roth": true,
"rusr": true,
"size": 546,
"uid": 1001,
"wgrp": false,
"woth": false,
"wusr": true,
"xgrp": false,
"xoth": false,
"xusr": false
}
]
}
and I only want this line to be outputed:
"path": "/etc/nginx/sites-enabled/specified-file",
I don't really care about the msg, specifically I want to use just this path "/etc/nginx/sites-enabled/specified-file" for later usage. There will always be only one result of the file path in my system.
#CzipO2, You can use the below tasks which also sets the file path in a variable which can be used later in the playbook,
- set_fact:
filepath: "{{ find_result.files | map(attribute='path') | list | first}}"
- name: output the path of the conf file
debug:
msg: "{{ filepath }}"
I don't really care about the msg, specifically, I want to use just this path "/etc/nginx/sites-enabled/specified-file" for later usage.
The filepath fact can be used in the playbook for later use.
Please try as below
- name: output the path of the conf file
set_fact:
path: "{{ item.path }}"
with_items: "{{ find_result.files}}"
- debug:
msg: "{{ path }}"
Hello i am trying to find a string as a part of a key in a dictionary.(file list)
In the next step i have to loop over a list of strings and search for it in a dictionary.
Any help out there?
Thanks for advice
Example dict:
[
{
"atime": 1564643897.7426093,
"ctime": 1564643891.0105128,
"dev": 64768,
"gid": 3007,
"gr_name": "group",
"inode": 2230336,
"isblk": false,
"ischr": false,
"isdir": false,
"isfifo": false,
"isgid": false,
"islnk": false,
"isreg": true,
"issock": false,
"isuid": false,
"mode": "0644",
"mtime": 1564643891.0105128,
"nlink": 1,
"path": "/home/user/branches/user/roles/manage_users/vars/users/my.user.yml",
"pw_name": "user",
"rgrp": true,
"roth": true,
"rusr": true,
"size": 776,
"uid": 1050,
"wgrp": false,
"woth": false,
"wusr": true,
"xgrp": false,
"xoth": false,
"xusr": false
}...
}
]
}
The match should be in key path: in the dict.
Tried several things but the closest seems to be;
- name: compare lists 1
debug:
msg: "item"
when: "item in users_list.files"
with_items:
- "{{ users }}"
But i cant get any result
Instead i get: Skipped
Expected Msg:
Msg: my.user
Got it by myself:
The trick is to create a list of path objects first with json query.
After that u can use it for comparing:
- name: create list of valid users
local_action:
module: find
path: "{{ role_path }}/vars/users"
register: users_list
- name: create list existing users
win_shell: |
try {
# powershell supposed way
$users=Get-LocalUser;echo $users.name
} catch {
#fall back
$users=Get-WmiObject -Class Win32_UserAccount -Filter "LocalAccount='True'" | select name;echo $users.name
}
register: users
- set_fact:
found_users: []
- name: compare lists
set_fact:
found_users: "{{ found_users + [item[1]] }}"
when: item[0].find(item[1]) != -1
with_nested:
- "{{ users_list.files|json_query(query) }}"
- "{{ users.stdout_lines}}"
vars:
query: "[*].path"
- debug: msg="{{ found_users }}"
I'd like to be able to iterate over all of the name values, but I'm not sure how to do so with Ansible. The variable domain is a list, and register is used.
- name: find *.ccfg files in domain(s)
find:
paths: "/tmp/opt/{{ item }}/ccfg"
patterns: "*.ccfg"
recurse: yes
excludes: "Admin.ccfg"
with_items: "{{ domain }}"
register: files
when: ('local' in group_names)
- debug:
msg: "{{ files.results }}"
The path value in each array could be anywhere from 1 to 20. Each index in the array has multiple values. Some arrays may not have any values
Standard Output:
ok: [127.0.0.1] => {
"msg": [
{
"_ansible_ignore_errors": null,
"_ansible_item_label": "CIE",
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": false,
"examined": 3,
"failed": false,
"files": [
{
"atime": 1541632866.4095802,
"ctime": 1541632866.4095802,
"dev": 64768,
"gid": 0,
"gr_name": "root",
"inode": 52174935,
"isblk": false,
"ischr": false,
"isdir": false,
"isfifo": false,
"isgid": false,
"islnk": false,
"isreg": true,
"issock": false,
"isuid": false,
"mode": "0644",
"mtime": 1541632866.4095802,
"nlink": 1,
"path": "/tmp/opt/CIE/ccfg/cie.ccfg",
"pw_name": "root",
"rgrp": true,
"roth": true,
"rusr": true,
"size": 0,
"uid": 0,
"wgrp": false,
"woth": false,
"wusr": true,
"xgrp": false,
"xoth": false,
"xusr": false
}
],
Take a look at the json_query filter:
- debug:
msg: "{{ item }}"
with_items: "{{ files | json_query('results[*].files[*].path') }}"
Official doco: https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#json-query-filter
Shameless plug with more examples: https://parko.id.au/2018/08/16/complex-data-structures-and-the-ansible-json_query-filter
I have a following hash/dict structure of sites:
sites:
example.com:
site: example.com
mail: info#example.com
site_alias: www.example.com
example.fi:
site: example.fi
mail: info#example.fi
site_alias: example.fi
...
I register a value for every site, if there is also a folder for it. Print the result.
name: "Check if path already exists so it is the first time."
stat: path={{ cert_files }}/{{ item.value.site }}
register: check_path
with_dict: "{{ sites }}"
debug: var=check_path.results
# No need to print the whole dictionary, all results are already there.
# with_dict: "{{ sites }}"
So I get something like:
TASK [letsencrypt : debug] *****************************************************
ok: [78.47.67.114] => (item={'key': u'example.com', 'value': {u'mail': u'mail#example.com', u'site_alias': u'www.example.com', u'site': u'example.com'}}) => {
"check_path.results": [
{
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": false,
"invocation": {
"module_args": {
"checksum_algorithm": "sha1",
"follow": false,
"get_checksum": true,
"get_md5": true,
"mime": false,
"path": "/etc/letsencrypt/live/example.com"
},
"module_name": "stat"
},
"item": {
"key": "example.com",
"value": {
"mail": "info#example.com",
"site": "example.com",
"site_alias": "www.example.com"
}
},
"stat": {
"atime": 147869032.3522692,
"ctime": 149636484.0226028,
"dev": 2049,
"executable": true,
"exists": true,
"gid": 0,
"gr_name": "root",
"inode": 15725,
"isblk": false,
"ischr": false,
"isdir": true,
"isfifo": false,
"isgid": false,
"islnk": false,
"isreg": false,
"issock": false,
"isuid": false,
"mode": "0755",
"mtime": 14632684.026028,
"nlink": 2,
"path": "/etc/letsencrypt/live/example.com",
"pw_name": "root",
"readable": true,
"rgrp": true,
"roth": true,
"rusr": true,
"size": 4096,
"uid": 0,
"wgrp": false,
"woth": false,
"writeable": true,
"wusr": true,
"xgrp": true,
"xoth": true,
"xusr": true
}
},
{
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": false,
"invocation": {
"module_args": {
"checksum_algorithm": "sha1",
"follow": false,
"get_checksum": true,
"get_md5": true,
"mime": false,
"path": "/etc/letsencrypt/live/example.com"
},
"module_name": "stat"
},
"item": {
"key": "example.fi",
"value": {
"mail": "info#example.fi",
"site": "example.fi",
"site_alias": "www.example.fi"
}
},
"stat": {
"atime": 1493734857.9738503,
"ctime": 1485960159.8090317,
"dev": 2049,
"executable": true,
"exists": true,
How can I the use or get the value "check_path.results.stats.exists" the last value in the next task if I want to iterate again through {{ sites }} ?
I have tried something like this with no success.
- name: Make a certificate the first time.
command: /bin/bash /opt/letsencrypt/letsencrypt-auto certonly -- standalone --email "{{ item.value.mail }}" --agree-tos --keep-until- expiring -d "{{ item.value.site }}" -d "{{ item.value.site_alias }}"
with_items: check_path
when: check_path.results.stat.exists == false
or
- name: Make a certificate the first time.
command: /bin/bash /opt/letsencrypt/letsencrypt-auto certonly standalone --email "{{ item.value.mail }}" --agree-tos --keep-until-expiring -d "{{ item.value.site }}" -d "{{ item.value.site_alias }}"
with_dict: "{{ sites }}"
when: check_path.results.stat.exists == false
You should iterate over result, not over original list:
- name: Make a certificate the first time.
command: /bin/bash /opt/letsencrypt/letsencrypt-auto certonly standalone --email "{{ item.item.value.mail }}" --agree-tos --keep-until-expiring -d "{{ item.item.value.site }}" -d "{{ item.item.value.site_alias }}"
with_items: "{{ check_path.results }}"
when: not item.stat.exists
here item.item is an item of the original list.