0
votes

I've to run a shell script at the end of my playbook on RHEL 7 target servers. I'm able to execute the script manually on target, but through ansible it errors out as below:

TASK [oracle_si_grid_install : executing the script to modify template values] **************************************************************************************************************
FAILED - RETRYING: executing the script to modify template values (3 retries left).
FAILED - RETRYING: executing the script to modify template values (2 retries left).
FAILED - RETRYING: executing the script to modify template values (1 retries left).

fatal: [10.210.224.87]: FAILED! => {"attempts": 3, "changed": true, "cmd": "/tmp/modify_db_template.sh", "delta": "0:00:00.113423", "end": "2020-11-19 12:21:18.642239", "msg": "non-zero return code", "rc": 2, "start": "2020-11-19 12:21:18.528816", "stderr": "/tmp/modify_db_template.sh: line 9: syntax error near unexpected token <'\n/tmp/modify_db_template.sh: line 9: while IFS= read -r line; do echo "processing line: $line"; sed -i "s|$line| <initParam name=\"sga_target\" value=\"${SGA_TARGET}\" unit=\"MB\"/>|g" $DBCA_TEMPLATE; done < <(grep 'name="sga_target" value=' $DBCA_TEMPLATE)'", "stderr_lines": ["/tmp/modify_db_template.sh: line 9: syntax error near unexpected token <'", "/tmp/modify_db_template.sh: line 9: while IFS= read -r line; do echo "processing line: $line"; sed -i "s|$line| <initParam name=\"sga_target\" value=\"${SGA_TARGET}\" unit=\"MB\"/>|g" $DBCA_TEMPLATE; done < <(grep 'name="sga_target" value=' $DBCA_TEMPLATE)'"], "stdout": "", "stdout_lines": []}

Ansible code for that module is as below:

- name: executing the script to modify template values
  shell: "/tmp/{{ modify_template }}"
  register: modtemp
  retries: 3
  delay: 2
  until: modtemp.rc == 0
  become: True
  become_user: "{{ db_user }}"
  become_method: su

Please note that I did use script / shell & added args: executable params too, but they fail as well. The shell script is as follows:

if [ ! -e /tmp/benv.sh ]
then
  echo "No Env file found"
  exit -1
fi

source /tmp/benv.sh

while IFS= read -r line; do echo "processing line: $line"; sed -i "s|$line|         <initParam name=\"sga_target\" value=\"${SGA_TARGET}\" unit=\"MB\"/>|g" $DBCA_TEMPLATE; done < <(grep 'name="sga_target" value=' $DBCA_TEMPLATE)
while IFS= read -r line; do echo "processing line: $line"; sed -i "s|$line|         <initParam name=\"processes\" value=\"${DB_PROCESSES}\"/>|g" $DBCA_TEMPLATE; done < <(grep 'name="processes" value=' $DBCA_TEMPLATE)
while IFS= read -r line; do echo "processing line: $line"; sed -i "s|$line|         <initParam name=\"pga_aggregate_target\" value=\"${PGA_TARGET}\" unit=\"MB\"/>|g" $DBCA_TEMPLATE; done < <(grep 'name="pga_aggregate_target" value=' $DBCA_TEMPLATE)
#while IFS= read -r line; do echo "processing line: $line"; sed -i "s|$line|         <fileSize unit=\"KB\">${REDO_SIZE}</fileSize>|g" $DBCA_TEMPLATE; done < <(grep '<fileSize unit="KB">204800</fileSize>' $DBCA_TEMPLATE)
# if there are no disks for FRA, then recovery destination and related init params will be removed from template
while IFS= read -r line; do echo "processing line: $line"; [ -n "${ORA_LOG}" ] && sed -i "s|$line|         <initParam name=\"db_recovery_file_dest_size\" value=\"${RECOVERY_SIZE}\" unit=\"MB\"/>|g" $DBCA_TEMPLATE || sed -i "\|${line}|d" $DBCA_TEMPLATE; done < <(grep 'name="db_recovery_file_dest_size" value=' $DBCA_TEMPLATE )
while IFS= read -r line; do echo "processing line: $line"; [ -z "${ORA_LOG}" ] && sed -i "\|${line}|d" $DBCA_TEMPLATE; done < <(grep 'name="archive_lag_target" value=' $DBCA_TEMPLATE)
while IFS= read -r line; do echo "processing line: $line"; [ -z "${ORA_LOG}" ] && sed -i "\|${line}|d" $DBCA_TEMPLATE; done < <(grep 'name="control_file_record_keep_time" value=' $DBCA_TEMPLATE)
# if there is no BACKUP disk, then noarchivelog will be assumed
# if Oracle Cloud Backup module is used, then ORA_BACKUP must have a fake disk specified
while IFS= read -r line; do echo "processing line: $line"; [ -z "${ORA_LOG}" ] && sed -i "s|$line|         <archiveLogMode>false</archiveLogMode>|g" $DBCA_TEMPLATE ; done < <(grep '<archiveLogMode>true</archiveLogMode>' $DBCA_TEMPLATE)

Manually, it runs as expected

[oracle@ansible-poc6 ~]$ /tmp/modify_db_template.sh
processing line:          <initParam name="sga_target" value="9536" unit="MB"/>
processing line:          <initParam name="processes" value="1339"/>
processing line:          <initParam name="pga_aggregate_target" value="1906" unit="MB"/>
processing line:          <initParam name="db_recovery_file_dest_size" value="" unit="MB"/>
processing line:          <initParam name="archive_lag_target" value="900"/>
processing line:          <initParam name="control_file_record_keep_time" value="38"/>
processing line:          <archiveLogMode>true</archiveLogMode>
[oracle@ansible-poc6 ~]$ echo $SHELL
/bin/bash

Contents of /tmp/benv.sh

export DB_SID=oratest
export COMPLIANCE_TYPE="sox"
export CRITICALITY="critical"
export ORA_CHAR=AL32UTF8
export ORA_NCHAR=AL16UTF16
# storage vars - if more than one disk, then list separate with whitespace
export ORA_OCR="/dev/sdb"
export ORA_DATA="/dev/sdd /dev/sde /dev/sdf"
export ORA_SWAP=""
export ORA_LOG="/dev/sdg"
# constants
export BASE_ORA=/u01/app/oracle
export HOME_ORA=/u01/app/oracle/product/19/dbee_1
export HOME_CRS=/u01/app/19/grid
# template file
DBCA_TEMPLATE="/u01/app/oracle/product/19/dbee_1/assistants/dbca/templates/dbca-create-seeded.dbc"

# calculations
MEMORY=$(eval "echo $((`grep 'MemTotal:' /proc/meminfo | awk '{print $2}'` / 1024))") # [MB]
[ -n "${ORA_OCR}" ] && DB_MEMORY=$(eval "(( `echo $((MEMORY - 3072))` < `echo $((MEMORY * 8/10))` )) && echo $((MEMORY - 3072)) || echo $((MEMORY * 8/10))") || DB_MEMORY=$(eval "(( `echo $((MEMORY - 2048))` < `echo $((MEMORY * 8/10))` )) && echo $((MEMORY - 2048)) || echo $((MEMORY * 8/10))") # [MB]
DB_PROCESSES=$(eval "(( `echo $(( (DB_MEMORY+512) * 1000000 / 9868951 ))` < 320 )) && echo '320' || ((( `echo $(( (DB_MEMORY+512) * 1000000 / 9868951 ))` > 20000 )) && echo '20000' || echo $(( (DB_MEMORY+512) * 1000000 / 9868951 )))")
SGA_TARGET=$(eval "(( `echo $((DB_MEMORY * 75/100))` < 768 )) && echo '768' || echo $((DB_MEMORY * 75/100))") # [MB]
SGA_TARGET=$(eval "
if     [ ${SGA_TARGET} -le 1024 ]; then (( `echo $((SGA_TARGET%4))` > 0 )) && echo $((4-SGA_TARGET%4+SGA_TARGET)) || echo $SGA_TARGET;
elif   [ ${SGA_TARGET} -le 8192 ]; then (( `echo $((SGA_TARGET%16))` > 0 )) && echo $((16-SGA_TARGET%16+SGA_TARGET)) || echo $SGA_TARGET;
elif  [ ${SGA_TARGET} -le 16384 ]; then (( `echo $((SGA_TARGET%32))` > 0 )) && echo $((32-SGA_TARGET%32+SGA_TARGET)) || echo $SGA_TARGET;
elif  [ ${SGA_TARGET} -le 32768 ]; then (( `echo $((SGA_TARGET%64))` > 0 )) && echo $((64-SGA_TARGET%64+SGA_TARGET)) || echo $SGA_TARGET;
elif  [ ${SGA_TARGET} -le 65536 ]; then (( `echo $((SGA_TARGET%128))` > 0 )) && echo $((128-SGA_TARGET%128+SGA_TARGET)) || echo $SGA_TARGET;
elif [ ${SGA_TARGET} -le 131072 ]; then (( `echo $((SGA_TARGET%256))` > 0 )) && echo $((256-SGA_TARGET%256+SGA_TARGET)) || echo $SGA_TARGET;
else
(( `echo $((SGA_TARGET%512))` > 0 )) && echo $((512-SGA_TARGET%512+SGA_TARGET)) || echo $SGA_TARGET;
fi
") # [MB]
PGA_TARGET=$(eval "(( `echo $((DB_MEMORY * 15/100))` < 384 )) && echo '384' || echo $((DB_MEMORY * 15/100))") # [MB] pga over 20% will cause ORA-700
HUGEPAGES=$(eval "echo $((SGA_TARGET/2 + 1))")
SWAP_SIZE=$(eval "((`echo $((MEMORY - (HUGEPAGES * 2) + 4))` < 16384)) && echo $((MEMORY - (HUGEPAGES * 2) + 4)) || echo '16384'") # [MB]

Appreciate your time and help. Thanks in advance

-- JK

1
Are you running the playbook as the same user as you do when you run the script manually?Raman Sailopal
Also, have you got a #! at the top of the script?Raman Sailopal
Yes, I'm running it as oracle user on target. Just added the #! but it still fails :(J K
What is the content of the sourced /tmp/benv.sh file ? Is your script relying on any vars set in your login environment on the target machine ? Ansible uses sh by default without any login initialization: did you try to set the executable param to bash ?Zeitounator
You will need to add #!/bin/bash or #!/bin/st depending on the environmentRaman Sailopal

1 Answers

0
votes

Quoting from module shell

"... runs the command through a shell (/bin/sh) on the remote node."

You say "Manually, it runs as expected" in /bin/bash. The error below is very probably caused by running the command in bin/sh.

"msg": "non-zero return code", "rc": 2
"stderr": "/tmp/modify_db_template.sh: line 9: syntax error near unexpected token <' ...

In Ansible, use parameter executable and run the command also in /bin/bash. For example

- name: executing the script to modify template values
  shell: "/tmp/{{ modify_template }}"
  args:
    executable: /bin/bash
  register: modtemp
  retries: 3
  delay: 2
  until: modtemp.rc == 0
  become: True
  become_user: "{{ db_user }}"
  become_method: su