#!/bin/bash # Copyright Broadcom, Inc. All Rights Reserved. # SPDX-License-Identifier: APACHE-2.0 # # Library for managing files # shellcheck disable=SC1091 # Load Generic Libraries . /opt/bitnami/scripts/libos.sh # Functions ######################## # Replace a regex-matching string in a file # Arguments: # $1 - filename # $2 - match regex # $3 - substitute regex # $4 - use POSIX regex. Default: true # Returns: # None ######################### replace_in_file() { local filename="${1:?filename is required}" local match_regex="${2:?match regex is required}" local substitute_regex="${3:?substitute regex is required}" local posix_regex=${4:-true} local result # We should avoid using 'sed in-place' substitutions # 1) They are not compatible with files mounted from ConfigMap(s) # 2) We found incompatibility issues with Debian10 and "in-place" substitutions local -r del=$'\001' # Use a non-printable character as a 'sed' delimiter to avoid issues if [[ $posix_regex = true ]]; then result="$(sed -E "s${del}${match_regex}${del}${substitute_regex}${del}g" "$filename")" else result="$(sed "s${del}${match_regex}${del}${substitute_regex}${del}g" "$filename")" fi echo "$result" > "$filename" } ######################## # Replace a regex-matching multiline string in a file # Arguments: # $1 - filename # $2 - match regex # $3 - substitute regex # Returns: # None ######################### replace_in_file_multiline() { local filename="${1:?filename is required}" local match_regex="${2:?match regex is required}" local substitute_regex="${3:?substitute regex is required}" local result local -r del=$'\001' # Use a non-printable character as a 'sed' delimiter to avoid issues result="$(perl -pe "BEGIN{undef $/;} s${del}${match_regex}${del}${substitute_regex}${del}sg" "$filename")" echo "$result" > "$filename" } ######################## # Remove a line in a file based on a regex # Arguments: # $1 - filename # $2 - match regex # $3 - use POSIX regex. Default: true # Returns: # None ######################### remove_in_file() { local filename="${1:?filename is required}" local match_regex="${2:?match regex is required}" local posix_regex=${3:-true} local result # We should avoid using 'sed in-place' substitutions # 1) They are not compatible with files mounted from ConfigMap(s) # 2) We found incompatibility issues with Debian10 and "in-place" substitutions if [[ $posix_regex = true ]]; then result="$(sed -E "/$match_regex/d" "$filename")" else result="$(sed "/$match_regex/d" "$filename")" fi echo "$result" > "$filename" } ######################## # Appends text after the last line matching a pattern # Arguments: # $1 - file # $2 - match regex # $3 - contents to add # Returns: # None ######################### append_file_after_last_match() { local file="${1:?missing file}" local match_regex="${2:?missing pattern}" local value="${3:?missing value}" # We read the file in reverse, replace the first match (0,/pattern/s) and then reverse the results again result="$(tac "$file" | sed -E "0,/($match_regex)/s||${value}\n\1|" | tac)" echo "$result" > "$file" } ######################## # Wait until certain entry is present in a log file # Arguments: # $1 - entry to look for # $2 - log file # $3 - max retries. Default: 12 # $4 - sleep between retries (in seconds). Default: 5 # Returns: # Boolean ######################### wait_for_log_entry() { local -r entry="${1:-missing entry}" local -r log_file="${2:-missing log file}" local -r retries="${3:-12}" local -r interval_time="${4:-5}" local attempt=0 check_log_file_for_entry() { if ! grep -qE "$entry" "$log_file"; then debug "Entry \"${entry}\" still not present in ${log_file} (attempt $((++attempt))/${retries})" return 1 fi } debug "Checking that ${log_file} log file contains entry \"${entry}\"" if retry_while check_log_file_for_entry "$retries" "$interval_time"; then debug "Found entry \"${entry}\" in ${log_file}" true else error "Could not find entry \"${entry}\" in ${log_file} after ${retries} retries" debug_execute cat "$log_file" return 1 fi }