Ansible does not expand newline and linefeed characters in verbose SSH output - ssh

When debugging an Ansible playbook, I occasionally need to use verbose mode to debug the connection itself, like in this call:
ansible-playbook -vvvv -i inventories/whatever playbook_under_test.yml
This will, among the debug info from Ansible itself, also output everything that SSH -vvvv would print. However, on the terminal, all newlines and linefeeds from this SSH debug output are represented by escape sequences, which makes the output a huge and rather unreadable unstructured block of text:
<192.168.1.2> (255, b'', b'OpenSSH_8.7p1, OpenSSL 1.1.1q FIPS 5 Jul 2022\r\nd
ebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug3: /etc/ssh/ssh
_config line 55: Including file /etc/ssh/ssh_config.d/50-redhat.conf depth 0\
r\ndebug1: Reading configuration data /etc/ssh/ssh_config.d/50-redhat.conf\r\
ndebug2: checking match for \'final all\' host 192.168.1.2 originally 192.168
.1.2\r\ndebug3: /etc/ssh/ssh_config.d/50-redhat.conf line 3: not matched \'fi
nal\'\r\ndebug2: match not found\r\ndebug3: /etc/ssh/ssh_config.d/50-redhat.c
onf line 5: Including file /etc/crypto-policies/back-ends/openssh.config dept
h 1 (parse only)\r\ndebug1: Reading configuration data /etc/crypto-policies/b
ack-ends/openssh.config\r\ndebug3: gss kex names ok: [gss-curve25519-sha256-,
gss-nistp256-sha256-,gss-group14-sha256-,gss-group16-sha512-,gss-gex-sha1-,gs
s-group14-sha1-,gss-group1-sha1-]\r\ndebug3: kex names ok: [curve25519-sha256
,curve25519-sha256#libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2
(wrapped at 78 columns for readability here, output is abbreviated and anonymized).
How can I configure my Ansible setup so that those \r\n escape sequences are actually printed out as proper linebreaks on my terminal?

How can I configure my Ansible setup so that those \r\n escape sequences are actually printed out as proper linebreaks on my terminal?
Create an ansible.cfg file from the location you run Ansible.
> cat ansible.cfg
[defaults]
stdout_callback = yaml

Related

SED command to delete last line in a remote host

I have the following running one liner to delete last injected ED key from last line of authorized keys folder of a remote host.
sed -i '${/^\(ssh-ed25519\) \(.*\) \([A-Za-z][A-Za-z]*\.[A-Za-z][A-Za-z]*#hpe\.com\)$/d;}' .ssh/authorized_keys
I do a couple of operations after creating ED key and injecting it into remote host. Then I want to clear up as tear down step. However when I tried to run it by connecting to remote host it failed. I tried the following things:
ssh -T 'sh -c "sed command here"' # too many single and double quotes, so I gave up
Then I tried removing T terminal and as well as "sh -c" command running part
ssh root#my_remote_host "sed -i '${/^\(ssh-ed25519\) \(.*\) \([A-Za-z][A-Za-z]*\.[A-Za-z][A-Za-z]*#hpe\.com\)$/d;}' .ssh/authorized_keys"
had this error:
sed: couldn't open temporary file .ssh/sedWC1YAQ: Read-only file system
I referred to this link but it also didn't help : Using SED in a ssh command on a remote node
I appreciate any help, and let me know if what I'm trying is a good way to apply.

Replace string containing _ and double quotes inside a file

Might be a repeat question, but I am kind of stuck:
I have a file test.txt with the following contents:
# To push each commit to a remote, put the name of the remote here.
# (eg, "origin" for git). Space-separated lists of multiple remotes
# also work (eg, "origin gitlab github" for git).
PUSH_REMOTE=""
I simply want to replace the line in the file that contains PUSH_REMOTE="" with PUSH_REMOTE="origin". Was looking for a sed or awk syntax to achieve the same. I tried escaping the double quotes using sed -i 's#PUSH_REMOTE=""#"PUSH_REMOTE="origin"#g' test.txt, But I keep getting the error sed: 1: "test.txt": undefined label 'est.txt'.
The desired output (file contents of test.txt) is as follows:
# To push each commit to a remote, put the name of the remote here.
# (eg, "origin" for git). Space-separated lists of multiple remotes
# also work (eg, "origin gitlab github" for git).
PUSH_REMOTE="origin"
Thanks again in advance for your time to address this somewhat basic issue of mine!
Here are my os-release details, in case it helps:
NAME="Red Hat Enterprise Linux"
VERSION="8.3 (Ootpa)"
ID="rhel"
ID_LIKE="fedora"
VERSION_ID="8.3"
PLATFORM_ID="platform:el8"
PRETTY_NAME="Red Hat Enterprise Linux 8.3 (Ootpa)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:redhat:enterprise_linux:8.3:GA"
HOME_URL="https://www.redhat.com/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 8"
REDHAT_BUGZILLA_PRODUCT_VERSION=8.3
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="8.3"
The error message sed: 1: "test.txt": undefined label 'est.txt' probably means you're using a sed that doesn't have a -i option or, more likely, whose -i option requires a temp file name after it and so it's treating your script as that temp file name and then treating your file name as the script. Either that or you just have a plain old syntax error in your sed script.
This will do what you want using any sed in any shell on every Unix box:
$ sed 's/\(PUSH_REMOTE=\)""/\1"origin"/' file
# To push each commit to a remote, put the name of the remote here.
# (eg, "origin" for git). Space-separated lists of multiple remotes
# also work (eg, "origin gitlab github" for git).
PUSH_REMOTE="origin"
Do whatever you like to update the input file with that output, e.g. either of these:
sed -i '...' file, or
sed -i '' '...' file, or
sed '...' file > tmp && mv tmp file
or whatever.
Could you check whether this awk-command works:
awk '$0~/^PUSH_REMOTE=""$/{$0="PUSH_REMOTE=\"origin\""}1' test.txt

Docs for redis-server command line options

I've looked "everywhere." I cannot find documentation for all the supported command line options for redis-server I'm using version 5.0.3
I tried redis-server --help It is no help.
The usage given doesn't even mention --port, --slaveof, --replicaof, --loglevel ... yet these options are shown in the help's examples.
Does someone know where I can find full and complete documentation for the server's command line?
Thanks.
Right at the top of the redis configuration documents it says the following:
"... it is possible to ... pass Redis configuration parameters using
the command line directly."
Therefore, every configuration file option is passable on the command line. I'm an idiot.
Edit: Note that config file parameters which have spaces in them will not work as a command line parameter. For example, --save "600 1 30 10 6 100" will not be used. Running redis-cli followed by config get save will show "". Doesn't matter if the parameter is placed at the end of the command line. Doesn't matter if it is enclosed with single quotes, double quotes, or no quotes.
redis-server command line does not parse params with spaces correctly. The issue is known and closed without being resolved:
https://github.com/redis/redis/issues/2366
The most useful information about configuring redis-server is at https://redis.io/docs/manual/config/
Passing arguments via the command line
You can also pass Redis configuration parameters using the command line directly. This is very useful for testing purposes. The following is an example that starts a new Redis instance using port 6380 as a replica of the instance running at 127.0.0.1 port 6379.
./redis-server --port 6380 --replicaof 127.0.0.1 6379
The format of the arguments passed via the command line is exactly the same as the one used in the redis.conf file, with the exception that the keyword is prefixed with --.
Note that internally this generates an in-memory temporary config file (possibly concatenating the config file passed by the user, if any) where arguments are translated into the format of redis.conf.
The .conf file with all the params has reasonably useful inline docs.
man redis-server and redis-server -h are basically useless.
man redis-server:
REDIS-SERVER(1) General Commands Manual REDIS-SERVER(1)
NAME
redis-server - Persistent key-value database
SYNOPSIS
redis-server configfile
DESCRIPTION
Redis is a key-value database. It is similar to memcached but the dataset is not volatile and other
datatypes (such as lists and sets) are natively supported.
OPTIONS
configfile
Read options from specified configuration file.
NOTES
On Debian GNU/Linux systems, redis-server is typically started via the /etc/init.d/redis-server initscript,
not manually. This defaults to using /etc/redis/redis.conf as a configuration file.
AUTHOR
redis-server was written by Salvatore Sanfilippo.
This manual page was written by Chris Lamb <lamby#debian.org> for the Debian project (but may be used by
others).
March 20, 2009 REDIS-SERVER(1)
`redis-server -h`:
Usage: ./redis-server [/path/to/redis.conf] [options] [-]
./redis-server - (read config from stdin)
./redis-server -v or --version
./redis-server -h or --help
./redis-server --test-memory <megabytes>
./redis-server --check-system
Examples:
./redis-server (run the server with default conf)
echo 'maxmemory 128mb' | ./redis-server -
./redis-server /etc/redis/6379.conf
./redis-server --port 7777
./redis-server --port 7777 --replicaof 127.0.0.1 8888
./redis-server /etc/myredis.conf --loglevel verbose -
./redis-server /etc/myredis.conf --loglevel verbose
Sentinel mode:
./redis-server /etc/sentinel.conf --sentinel
Also, if someone knows how to tuck the man and -h snippets of this answer into <details> with SO markup, please edit this response, thanks.

Ansible :Unable to parse /etc/ansible/hosts as an inventory source

I am new to ansible, got the below issue.
I was able to ssh into my client machine .but unable to run playbook.
Getting the error below:
[WARNING]: Unable to parse /etc/ansible/hosts as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit
localhost does not match 'all'
[WARNING]: Could not match supplied host pattern, ignoring: a
here a is my group name. my hosts given below :
---------
[a]
172.31.26.93
[all:vars]
ansible_user=vagrant
ansible_ssh_pass=vagrant
ansible_ssh_host=172.31.26.93
ansible_ssh_port=22
ansible_ssh_user='ansibleuser'
ansible_ssh_private_key_file=/home/ansibleuser/.ssh
------- my playbook file given below ----
- hosts: a
tasks:
- name: create a directory
file: path=/home/ansiblesuser/www state=directory
This is the first time I am getting this issue.
Before running the playbook just run the following command
ansible all --list-hosts
If the above error persists then go to /etc/ansible/ansible.cfg and edit the inventory path which points to your specific host file.
i had the same issue, the plugins ini and yaml were not enable in the ansible.cfg :
[inventory]
enable_plugins = yaml, ini
I suddenly experienced the same issue with an inventory that was many years in use and hadn't changed recently.
It turned out I enabled a plugin which caused this issue.
I enabled the plugin vmware_vm_inventory which was the source of the message. This showed up by running ansible-playbook -vvvv <host>
I'd figured I should define the plugin in an ansible.cfg file that is present in the folder where I run playbooks that use this plugin and leave it out of the /etc/ansible/ansible.cfg
The following solved the problem for me:
Go to the root directory /
cd etc or mkdir etc and cd etc
mkdir ansible then cd ansible
vi hosts (then add the hosts)
chmod 777 hosts.
Check ansible all -m ping
If you are still having this issue when you run
ansible-playbook -i path/to/inventory/file playbook.yml
Simply create an empty ansible.cfg file in the directory where you have your playbook.
Centos 7
this was causing above error:
ansible-playbook -i host_test -v tasks.yml
this fixed it:
ansible-playbook -i hosttest -v tasks.yml
Host file with no read permissions caused the following error message:
[WARNING]: Unable to parse /etc/ansible/hosts as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that
the implicit localhost does not match 'all'
Solution: change permissions
sudo chmod 744 /etc/ansible/hosts
In another occasion I got an error message due to an incorrect formatting of the hosts file:
[WARNING]: * Failed to parse /etc/ansible/hosts with yaml plugin: YAML
inventory has invalid structure, it should be a dictionary, got: <class
'ansible.parsing.yaml.objects.AnsibleUnicode'>
[WARNING]: * Failed to parse /etc/ansible/hosts with ini plugin:
/etc/ansible/hosts:3: Expected key=value host variable assignment, got: ;
[WARNING]: Unable to parse /etc/ansible/hosts as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
and I fixed the issue by correcting the format error.
As suggested in another answer check if hosts are available with
ansible all --list-hosts
Also check the actual location of the inventory file in the Ansible configuration file ansible.cfg.
You'll see this error if the file doesn't exist on disk as well.
This will be in the -vvvv log:
Skipping due to inventory source not existing or not being readable by the current user
Removing the spaces around the = worked for me, Ansible managed to parse my host.ini file.
Using ansible version ansible 2.9.27
able to resolve by giving complete (absolute path) for me error is like below
[WARNING]: Unable to parse /root/hosts as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is
available [WARNING]: provided hosts list is empty, only localhost is
available. Note that the implicit localhost does not match 'all'
[WARNING]: Could not match supplied host pattern, ignoring: all
Use following command
ansible-playbook -i /etc/ansible/hosts showfiles.yml
I have the same problem:
The solution was Space issues in Token
`$ ansible-playbook -i inventory/forem/setup.yml playbooks/providers/aws.yml
[WARNING]: * Failed to parse /var/home/core/selfhost/inventory/forem/setup.yml with ini plugin: Invalid host pattern '---' supplied, '---' is normally a sign this is
a YAML file.
[WARNING]: * Failed to parse /var/home/core/selfhost/inventory/forem/setup.yml with yaml plugin: We were unable to read either as JSON nor YAML, these are the errors
we got from each: JSON: Expecting value: line 1 column 1 (char 0) Syntax Error while loading YAML. could not find expected ':' The error appears to be in
'/var/home/core/selfhost/inventory/forem/setup.yml': line 85, column 11, but may be elsewhere in the file depending on the exact syntax problem. The offending line
appears to be: $ANSIBLE_VAULT;1.1;AES256 62376137383864393461613561353234643230666431643935303533346631393537363564366334 ^ here
[WARNING]: Unable to parse /var/home/core/selfhost/inventory/forem/setup.yml as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [Deploy Forem to AWS]

Transfer files over SSH, then appended to another file

I'm trying to automate a script that copies a file from my local server to a remote server on the command line. I've done the research on scp and know how to copy the file to the remote server, but then I want to append that file to another.
This is my code:
scp ~/file.txt user#host:
ssh user#host cat file.txt >> other_file.txt
When I enter everything into the command line manually as such, everything works fine:
scp ~/file.txt user#host:
ssh user#host
cat file.txt >> other_file.txt
But when I run the script, only the file is copied, not appended to the end of other_file.txt. Help?
The second line of your code should be
ssh user#host "cat file.txt >> other_file.txt"
Three important points:
You don't want your local shell to interpret >> in any way (which it does if it's unquoted)
There is a remote shell which will interpret >> in the command correctly.
Final arguments to ssh are "joined" to form a command, not carried into an argv array as they are. It may be convenient but it also may lead to confusion or bugs: ssh cat "$MYFILE" and ssh "cat '$MYFILE'" both work in a common use case, but they both break for different values of $MYFILE.
You need to enclose the command to be run on the remote host in quotes. Otherwise, the redirection is being done locally rather than remotely. Try this instead:
scp ~/file.txt user#host:
ssh user#host 'cat file.txt >> other_file.txt'
Try this:
$ cat file.txt| ssh hostname 'cat >> other_file.txt'