Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package resource-agents for openSUSE:Factory 
checked in at 2026-02-27 17:03:21
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/resource-agents (Old)
 and      /work/SRC/openSUSE:Factory/.resource-agents.new.29461 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "resource-agents"

Fri Feb 27 17:03:21 2026 rev:147 rq:1335169 version:4.17.0+git42.a607c299

Changes:
--------
--- /work/SRC/openSUSE:Factory/resource-agents/resource-agents.changes  
2026-01-28 15:08:50.434223749 +0100
+++ 
/work/SRC/openSUSE:Factory/.resource-agents.new.29461/resource-agents.changes   
    2026-02-27 17:07:49.342923240 +0100
@@ -1,0 +2,12 @@
+Wed Feb 25 10:46:27 UTC 2026 - Peter Varkoly <[email protected]>
+
+- Update to version 4.17.0+git42.a607c299:
+  * IPaddr2: fix find_interface output
+  * IPsrcaddr: fix grep expression, so it doesnt log "stray \ before white 
space" with newer versions of grep
+  * podman-etcd: fix learner node attribute not set after etcdctl failure
+  * docker: improve image existence check (#2121)
+  * portblock: check correct binary during validate-all
+  * send_arp.linux/tickle_tcp: better alpine compatibility (#2119)
+  * podman-etcd: enhance etcd data backup with snapshots and retention
+
+-------------------------------------------------------------------

Old:
----
  resource-agents-4.17.0+git30.b33c378d.tar.xz

New:
----
  resource-agents-4.17.0+git42.a607c299.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ resource-agents.spec ++++++
--- /var/tmp/diff_new_pack.i2lgEv/_old  2026-02-27 17:07:50.166957391 +0100
+++ /var/tmp/diff_new_pack.i2lgEv/_new  2026-02-27 17:07:50.170957557 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           resource-agents
-Version:        4.17.0+git30.b33c378d
+Version:        4.17.0+git42.a607c299
 Release:        0
 Summary:        HA Reusable Cluster Resource Scripts
 License:        GPL-2.0-only AND LGPL-2.1-or-later AND GPL-3.0-or-later

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.i2lgEv/_old  2026-02-27 17:07:50.266961536 +0100
+++ /var/tmp/diff_new_pack.i2lgEv/_new  2026-02-27 17:07:50.270961701 +0100
@@ -1,7 +1,7 @@
 <servicedata>
 <service name="tar_scm">
 <param name="url">https://github.com/ClusterLabs/resource-agents.git</param>
-<param name="changesrevision">b33c378db3a04709a276a436606105e52a946116</param>
+<param name="changesrevision">a607c299ba7784ab30511da0b0445a99396a2e3e</param>
 </service>
 </servicedata>
 (No newline at EOF)

++++++ resource-agents-4.17.0+git30.b33c378d.tar.xz -> 
resource-agents-4.17.0+git42.a607c299.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/resource-agents-4.17.0+git30.b33c378d/heartbeat/IPaddr2 
new/resource-agents-4.17.0+git42.a607c299/heartbeat/IPaddr2
--- old/resource-agents-4.17.0+git30.b33c378d/heartbeat/IPaddr2 2026-01-22 
08:54:44.000000000 +0100
+++ new/resource-agents-4.17.0+git42.a607c299/heartbeat/IPaddr2 2026-02-24 
09:59:15.000000000 +0100
@@ -660,9 +660,10 @@
                | grep " $ipaddr/$netmask" \
                | cut -d ' ' -f2 \
                | grep -v '^ipsec[0-9][0-9]*$'`"
-       local iface_altname="`$IP2UTIL -f inet link show dev $iface | grep 
"altname" | sed 's/^[[:space:]]*//; s/altname //g' | tr '\n' ' '`"
-
-       echo "$iface $iface_altname"
+       if [ -n "$iface" ]; then
+               local iface_altname="`$IP2UTIL -f inet link show dev $iface | 
grep "altname" | sed 's/^[[:space:]]*//; s/altname //g' | tr '\n' ' '`"
+               echo "$iface $iface_altname"
+       fi
        return 0
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/resource-agents-4.17.0+git30.b33c378d/heartbeat/IPsrcaddr 
new/resource-agents-4.17.0+git42.a607c299/heartbeat/IPsrcaddr
--- old/resource-agents-4.17.0+git30.b33c378d/heartbeat/IPsrcaddr       
2026-01-22 08:54:44.000000000 +0100
+++ new/resource-agents-4.17.0+git42.a607c299/heartbeat/IPsrcaddr       
2026-02-24 09:59:15.000000000 +0100
@@ -434,7 +434,7 @@
 #       is an (aliased) interface name (e.g., "eth0" and "eth0:0").
 #
 find_interface_generic() {
-       local iface=`$IP2UTIL -o -f $FAMILY addr show | grep "\ $BASEIP" \
+       local iface=`$IP2UTIL -o -f $FAMILY addr show | grep " $BASEIP" \
             | cut -d ' ' -f2 | grep -v '^ipsec[0-9][0-9]*$'`
         if [ -z "$iface" ]; then
             return $OCF_ERR_GENERIC
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/resource-agents-4.17.0+git30.b33c378d/heartbeat/docker 
new/resource-agents-4.17.0+git42.a607c299/heartbeat/docker
--- old/resource-agents-4.17.0+git30.b33c378d/heartbeat/docker  2026-01-22 
08:54:44.000000000 +0100
+++ new/resource-agents-4.17.0+git42.a607c299/heartbeat/docker  2026-02-24 
09:59:15.000000000 +0100
@@ -495,36 +495,38 @@
        local IMAGE_NAME="${OCF_RESKEY_image}"
        local IMAGE_TAG="latest"
 
+       # try to extract server name before tag, as it might also contain a 
colon (server:port/image:tag)
        SLASH_FOUND="$(echo "${OCF_RESKEY_image}" | grep -o '/' | grep -c .)"
-
        if [ ${SLASH_FOUND} -ge 1 ]; then
                SERVER_NAME="$(echo ${IMAGE_NAME} | cut -d / -f 
1-${SLASH_FOUND})"
                IMAGE_NAME="$(echo ${IMAGE_NAME} | awk -F'/' '{print $NF}')"
        fi
 
+       # extract image tag if specified
        COLON_FOUND="$(echo "${IMAGE_NAME}" | grep -o ':' | grep -c .)"
        if [ ${COLON_FOUND} -ge 1 ]; then
                IMAGE_TAG="$(echo ${IMAGE_NAME} | awk -F':' '{print $NF}')"
                IMAGE_NAME="$(echo ${IMAGE_NAME} | cut -d : -f 
1-${COLON_FOUND})"
        fi
 
-       # IMAGE_NAME might be following formats:
+       # Check for existence of image, which might be in following formats:
        # - image
-       # - repository:port/image
+       # - server_name/image (as extracted above)
        # - docker.io/image (some distro will display "docker.io/" as prefix)
-       docker images | awk '{print $1 ":" $2}' | $EGREP -q -s 
"^(docker.io\/|${SERVER_NAME}\/)?${IMAGE_NAME}:${IMAGE_TAG}\$"
+       docker image ls --all --format '{{.Repository}}:{{.Tag}}' | $EGREP -q 
-s "^(docker.io\/|${SERVER_NAME}\/)?${IMAGE_NAME}:${IMAGE_TAG}\$"
        if [ $? -eq 0 ]; then
                # image found
-               return 0
+               return $OCF_SUCCESS
        fi
 
        if ocf_is_true "$OCF_RESKEY_allow_pull"; then
                REQUIRE_IMAGE_PULL=1
                ocf_log notice "Image (${OCF_RESKEY_image}) does not exist 
locally but will be pulled during start"
-               return 0
+               return $OCF_SUCCESS
        fi
+
        # image not found.
-       return 1
+       return $OCF_ERR_ARGS
 }
 
 docker_validate()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/resource-agents-4.17.0+git30.b33c378d/heartbeat/podman-etcd 
new/resource-agents-4.17.0+git42.a607c299/heartbeat/podman-etcd
--- old/resource-agents-4.17.0+git30.b33c378d/heartbeat/podman-etcd     
2026-01-22 08:54:44.000000000 +0100
+++ new/resource-agents-4.17.0+git42.a607c299/heartbeat/podman-etcd     
2026-02-24 09:59:15.000000000 +0100
@@ -49,6 +49,7 @@
 OCF_RESKEY_oom_default="-997"
 OCF_RESKEY_config_location_default="/var/lib/etcd"
 OCF_RESKEY_backup_location_default="/var/lib/etcd"
+OCF_RESKEY_max_backup_snapshots_default="3"
 
 : ${OCF_RESKEY_image=${OCF_RESKEY_image_default}}
 : ${OCF_RESKEY_pod_manifest=${OCF_RESKEY_pod_manifest_default}}
@@ -61,6 +62,7 @@
 : ${OCF_RESKEY_oom=${OCF_RESKEY_oom_default}}
 : ${OCF_RESKEY_config_location=${OCF_RESKEY_config_location_default}}
 : ${OCF_RESKEY_backup_location=${OCF_RESKEY_backup_location_default}}
+: ${OCF_RESKEY_max_backup_snapshots=${OCF_RESKEY_max_backup_snapshots_default}}
 
 
 #######################################################################
@@ -275,6 +277,17 @@
 <content type="string" default="${OCF_RESKEY_backup_location_default}"/>
 </parameter>
 
+<parameter name="max_backup_snapshots" required="0" unique="0">
+<longdesc lang="en">
+Maximum number of etcd database snapshots to retain. When a new snapshot is 
created,
+older snapshots will be automatically removed to maintain this limit. This 
helps
+control storage usage while ensuring recent backups are available for recovery.
+Set max_backup_snapshots=0 to disable backups.
+</longdesc>
+<shortdesc lang="en">Maximum number of backup snapshots to retain</shortdesc>
+<content type="integer" default="${OCF_RESKEY_max_backup_snapshots_default}"/>
+</parameter>
+
 </parameters>
 
 <actions>
@@ -720,20 +733,190 @@
        return $OCF_SUCCESS
 }
 
+# Remove etcd member directory to allow the node to rejoin the cluster as a 
learner.
+#
+# When a node rejoins an etcd cluster, it must start fresh as a learner to 
prevent
+# data inconsistencies. This function removes the member directory and syncs 
to disk.
+#
+# Returns:
+#   OCF_SUCCESS     - Member directory successfully removed
+#   OCF_ERR_GENERIC - Failed to remove member directory (critical error)
+wipe_data_folder_for_learner()
+{
+       ocf_log info "deleting etcd member directory ($ETCD_MEMBER_DIR) to 
enable learner rejoin"
+       if ! rm -rf "$ETCD_MEMBER_DIR"; then
+               ocf_log err "could not delete etcd member directory 
($ETCD_MEMBER_DIR), error code: $?"
+               return $OCF_ERR_GENERIC
+       fi
+       sync
+       return $OCF_SUCCESS
+}
+
+
+# Calculate available disk space in bytes for a given directory.
+#
+# This function queries the filesystem and returns available space in bytes.
+# It converts df output (KB) to bytes for consistent size comparisons.
+#
+# Arguments:
+#   $1 - Target directory path to check
+#
+# Returns:
+#   OCF_SUCCESS     - Available space in bytes (via stdout)
+#   OCF_ERR_GENERIC - Failed to determine available space (error message via 
stdout)
+get_available_space_in_directory()
+{
+       local target_dir=$1
+       local available_space_kb
+       local available_space_bytes
+
+       available_space_kb=$(df -P "$target_dir" | awk 'NR==2 {print $4}' 2>&1)
+
+       # Validate output is numeric
+       if ! echo "$available_space_kb" | grep -q '^[0-9]\+$'; then
+               echo "df command failed or returned invalid value: 
$available_space_kb"
+               return $OCF_ERR_GENERIC
+       fi
+
+       available_space_bytes=$((available_space_kb*1024))
+       echo "$available_space_bytes"
+       return $OCF_SUCCESS
+}
+
+# Archive etcd database with backup and cleanup
+#
+# This function creates a backup copy of the etcd database, validates it, and
+# removes old backups according to the retention policy. Backups are optional
+# and can be disabled by setting max_backup_snapshots=0.
+#
+# Error handling strategy:
+#   All backup failures return OCF_SUCCESS to prevent blocking cluster 
recovery.
+#   Backups are beneficial but not critical for recovery operations.
+#
+# NOTE: This function cannot use etcdctl/etcdutl utilities because the etcd
+#       server is not running when this backup is performed.
 archive_data_folder()
 {
-       # TODO: use etcd snapshots
-       local dest_dir_name
-       local data_dir="/var/lib/etcd/member"
-
-       dest_dir_name="members-snapshot-$(date +%Y%M%d%H%M%S)"
-       if [ ! -d $data_dir ]; then
-               ocf_log info "no data dir to backup"
+       local backup_dir="$OCF_RESKEY_backup_location"
+       local etcd_db_path="$ETCD_MEMBER_DIR/snap/db"
+
+       if [ "$OCF_RESKEY_max_backup_snapshots" -eq 0 ]; then
+               ocf_log debug "etcd backup disabled (max_backup_snapshots=0)"
                return $OCF_SUCCESS
        fi
-       ocf_log info "backing up $data_dir under $HA_RSCTMP/$dest_dir_name"
-       mv "$data_dir" "$HA_RSCTMP/$dest_dir_name"
-       sync
+
+       # Check if the etcd database file exists
+       if [ ! -f "$etcd_db_path" ]; then
+               ocf_log warn "backup skipped: etcd database file not found at 
'$etcd_db_path'"
+               return $OCF_SUCCESS
+       fi
+
+       # Ensure backup directory exists
+       if [ ! -d "$backup_dir" ]; then
+               ocf_log debug "creating backup directory: '$backup_dir'"
+               if ! mkdir -p "$backup_dir"; then
+                       ocf_log warn "backup skipped: failed to create backup 
directory '$backup_dir'"
+                       return $OCF_SUCCESS
+               fi
+       fi
+
+       ocf_log debug "checking disk space: backup_dir=$backup_dir"
+       local available_space_bytes
+       if ! available_space_bytes=$(get_available_space_in_directory 
"$backup_dir"); then
+               ocf_log warn "backup skipped: could not compute available disk 
space in '$backup_dir', error msg: $available_space_bytes"
+               return $OCF_SUCCESS
+       fi
+
+       local required_space_bytes
+       required_space_bytes=$(stat -c %s "$etcd_db_path" 2>&1)
+       if ! echo "$required_space_bytes" | grep -q '^[0-9]\+$'; then
+               ocf_log warn "backup skipped: could not compute etcd database 
size at '$etcd_db_path', error msg: $required_space_bytes"
+               return $OCF_SUCCESS
+       fi
+
+       if [ "$required_space_bytes" -gt "$available_space_bytes" ]; then
+               ocf_log warn "backup skipped: insufficient disk space 
(required: ${required_space_bytes}B, available: ${available_space_bytes}B)"
+               return $OCF_SUCCESS
+       fi
+
+       # Generate timestamp and backup filename
+       local timestamp
+       timestamp=$(date +%Y%m%d-%H%M%S)
+
+       local backup_file
+       backup_file="$backup_dir/snapshot-$timestamp.db"
+
+       ocf_log info "creating etcd database backup: '$backup_file'"
+
+       # Create the backup by copying the database file (enable Copy-on-Write 
copy)
+       if ! cp --reflink=auto "$etcd_db_path" "$backup_file"; then
+               ocf_log warn "backup creation failed: could not copy 
'$etcd_db_path' to '$backup_file', error code: $?"
+               return $OCF_SUCCESS
+       fi
+
+       # Validate the backup file exists and has the expected size
+       if [ ! -f "$backup_file" ]; then
+               ocf_log warn "backup validation failed: snapshot file 
'$backup_file' does not exist"
+               return $OCF_SUCCESS
+       fi
+
+       local backup_size_bytes
+       backup_size_bytes=$(stat -c %s "$backup_file" 2>/dev/null || echo "0")
+       if [ "$backup_size_bytes" -ne "$required_space_bytes" ]; then
+               ocf_log warn "backup validation failed: size mismatch 
(expected: ${required_space_bytes}B, got: ${backup_size_bytes}B)"
+               rm -f "$backup_file"
+               return $OCF_SUCCESS
+       fi
+
+       ocf_log info "backup created successfully: $backup_file 
(${backup_size_bytes}B)"
+
+       # Cleanup old backups based on retention policy
+       cleanup_old_backups "$backup_dir"
+
+       return $OCF_SUCCESS
+}
+
+cleanup_old_backups()
+{
+       local backup_dir="$1"
+       local max_snapshots="$OCF_RESKEY_max_backup_snapshots"
+       local backup_count
+       local backups_to_remove
+       local old_backups
+
+       # Validate max_snapshots is a positive integer
+       if ! echo "$max_snapshots" | grep -q '^[1-9][0-9]*$'; then
+               ocf_log warn "invalid max_backup_snapshots value. Positive 
integer expected, got '$max_snapshots' instead, skipping cleanup"
+               return $OCF_SUCCESS
+       fi
+
+       # Count existing backup files
+       backup_count=$(find "$backup_dir" -maxdepth 1 -name "snapshot-*.db" 
-type f 2>/dev/null | wc -l)
+
+       if [ "$backup_count" -le "$max_snapshots" ]; then
+               ocf_log info "backup count ($backup_count) is within retention 
limit ($max_snapshots), no cleanup needed"
+               return $OCF_SUCCESS
+       fi
+
+       # Calculate how many backups to remove
+       backups_to_remove=$((backup_count - max_snapshots))
+       ocf_log info "removing $backups_to_remove old backup(s) to maintain 
retention limit of $max_snapshots"
+
+       # Find oldest backups sorted by modification time
+       # -t sorts by modification time, -r reverses (oldest first)
+       # -print0 and -0 handle filenames with spaces/special characters
+       old_backups=$(find "$backup_dir" -maxdepth 1 -name "snapshot-*.db" 
-type f -print0 2>/dev/null | \
+               xargs -0 -r ls -tr | \
+               head -n "$backups_to_remove")
+
+       if [ -n "$old_backups" ]; then
+               ocf_log info "removing old backups: $old_backups"
+               if ! echo "$old_backups" | xargs -r rm -f; then
+                       ocf_log warn "failed to remove some old backups, error 
code: $?"
+               fi
+       fi
+
+       return $OCF_SUCCESS
 }
 
 etcd_pod_container_exists() {
@@ -899,7 +1082,7 @@
        local peer_url=$(ip_url $member_ip)
 
        ocf_log info "add $member_name ($member_ip) to the member list as 
learner"
-       out=$(podman exec "${CONTAINER}" etcdctl 
--endpoints="$endpoint_url:2379" member add "$member_name" 
--peer-urls="$peer_url:2380" --learner)
+       out=$(podman exec "${CONTAINER}" etcdctl 
--endpoints="$endpoint_url:2379" member add "$member_name" 
--peer-urls="$peer_url:2380" --learner 2>&1)
        rc=$?
        if [ $rc -ne 0 ]; then
                ocf_log err "could not add $member_name as learner, error code 
$rc, etcdctl output: $out"
@@ -1246,10 +1429,22 @@
 manage_peer_membership()
 {
        local member_list_json="$1"
+       local peer_ip_map_entry
+       local peer_member_name
+       local peer_member_ip
+       local peer_member_id
+
+       # Get peer node name and IP
+       peer_ip_map_entry=$(echo "$OCF_RESKEY_node_ip_map" | tr ';' '\n' | grep 
-vF "$NODENAME")
+       if [ -z "$peer_ip_map_entry" ]; then
+               ocf_exit_reason "manage_peer_membership: could not parse 
node_ip_map: '$OCF_RESKEY_node_ip_map'"
+               exit $OCF_ERR_CONFIGURED
+       fi
+       peer_member_name=$(echo "$peer_ip_map_entry" | cut -d: -f1)
+       peer_member_ip=$(echo "$peer_ip_map_entry" | cut -d: -f2-)
 
-       # Example of .members[] instance fields in member list json format:
-       # NOTE that "name" is present in voting members only, while "isLearner" 
in learner members only
-       # and the value is always true (not a string) in that case.
+       # Parsing the member list's json output to find a "learner" member.
+       # Example of .members[] instance fields in member list json format:     
        # {
        #   "ID": <member ID>,
        #   "name": "<node hostname>",
@@ -1260,26 +1455,28 @@
        #       "https://<node IP>:2379"
        #   ]
        # }
-       for node in $(echo "$OCF_RESKEY_node_ip_map" | sed "s/\s//g;s/;/ /g"); 
do
-               name=$(echo "$node" | cut -d: -f1)
-               # do not check itself
-               if [ "$name" = "$NODENAME" ]; then
-                       continue
-               fi
+       # NOTE that the "name" field is present in voting members only, while 
"isLearner"
+       # field in learner members only and the value is always true (not a 
string) in that case.
+       peer_member_id=$(printf "%s" "$member_list_json" | jq -r ".members[] | 
select( .peerURLs | map(test(\"$peer_member_ip\")) | any).ID")
+       if [ -z "$peer_member_id" ]; then
+               ocf_log info "$peer_member_name is not in the members list"
+               add_member_as_learner "$peer_member_name" "$peer_member_ip"
+               set_standalone_node
+               return
+       fi
 
-               # Check by IP instead of Name since "learner" members appear 
only in peerURLs, not by Name.
-               ip=$(echo "$node" | cut -d: -f2-) # Grab everything after the 
first : this covers ipv4/ipv6
-               peer_member_id=$(printf "%s" "$member_list_json" | jq -r 
".members[] | select( .peerURLs | map(test(\"$ip\")) | any).ID")
-               if [ -z "$peer_member_id" ]; then
-                       ocf_log info "$name is not in the members list"
-                       add_member_as_learner "$name" "$ip"
-                       set_standalone_node
-               else
-                       ocf_log debug "$name is in the members list by IP: $ip"
-                       # Errors from reconcile_member_state are logged 
internally. Ignoring them here prevents stopping a healthy voter agent; 
critical local failures are caught by detect_cluster_leadership_loss.
-                       reconcile_member_state "$member_list_json"
-               fi
-       done
+       # Ensure learner_node attribute is always set when we have a learner 
member
+       local learner_member_id=$(printf "%s" "$member_list_json" | jq -r 
".members[] | select( .isLearner==true ).ID")
+       local current_learner_node=$(attribute_learner_node get)
+       if [ -n "$learner_member_id" ] && [ -z "$current_learner_node" ]; then
+               ocf_log debug "$peer_member_name found as learner in member 
list, but learner_node attribute was not set. Updating"
+               attribute_learner_node update "$peer_member_name"
+               return
+       fi
+
+       ocf_log debug "$peer_member_name is in the members list by IP: 
$peer_member_ip"
+       # Errors from reconcile_member_state are logged internally. Ignoring 
them here prevents stopping a healthy voter agent; critical local failures are 
caught by detect_cluster_leadership_loss.
+       reconcile_member_state "$member_list_json"
 }
 
 check_peer()
@@ -1902,6 +2099,9 @@
                fi
 
                archive_data_folder
+               if ! wipe_data_folder_for_learner; then
+                       return "$OCF_ERR_GENERIC"
+               fi
        fi
 
        ocf_log info "check for changes in pod manifest to decide if the 
container should be reused or replaced"
@@ -2023,6 +2223,7 @@
                                peer_node_ip="$(attribute_node_ip_peer)"
                                if [ -n "$peer_node_name" ] && [ -n 
"$peer_node_ip" ]; then
                                        add_member_as_learner "$peer_node_name" 
"$peer_node_ip"
+                                       set_standalone_node
                                else
                                        ocf_log err "could not add peer as 
learner (peer node name: ${peer_node_name:-unknown}, peer ip: 
${peer_node_ip:-unknown})"
                                fi
@@ -2251,6 +2452,7 @@
 POD_MANIFEST_COPY="${OCF_RESKEY_config_location}/pod.yaml"
 ETCD_CONFIGURATION_FILE="${OCF_RESKEY_config_location}/config.yaml"
 ETCD_BACKUP_FILE="${OCF_RESKEY_backup_location}/config-previous.tar.gz"
+ETCD_MEMBER_DIR="/var/lib/etcd/member"
 ETCD_REVISION_JSON="/var/lib/etcd/revision.json"
 ETCD_REVISION_BUMP_PERCENTAGE=0.2
 ETCD_BUMP_REV_DEFAULT=1000000000
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/resource-agents-4.17.0+git30.b33c378d/heartbeat/portblock 
new/resource-agents-4.17.0+git42.a607c299/heartbeat/portblock
--- old/resource-agents-4.17.0+git30.b33c378d/heartbeat/portblock       
2026-01-22 08:54:44.000000000 +0100
+++ new/resource-agents-4.17.0+git42.a607c299/heartbeat/portblock       
2026-02-24 09:59:15.000000000 +0100
@@ -761,9 +761,9 @@
 {
   case $FIREWALL in
     nft)
-      check_binary $IPTABLES ;;
-    iptables)
       check_binary $NFTABLES ;;
+    iptables)
+      check_binary $IPTABLES ;;
   esac
 
   case $protocol in
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/resource-agents-4.17.0+git30.b33c378d/tools/send_arp.linux.c 
new/resource-agents-4.17.0+git42.a607c299/tools/send_arp.linux.c
--- old/resource-agents-4.17.0+git30.b33c378d/tools/send_arp.linux.c    
2026-01-22 08:54:44.000000000 +0100
+++ new/resource-agents-4.17.0+git42.a607c299/tools/send_arp.linux.c    
2026-02-24 09:59:15.000000000 +0100
@@ -32,7 +32,6 @@
 #include <linux/sockios.h>
 #include <sys/file.h>
 #include <sys/time.h>
-#include <sys/signal.h>
 #include <signal.h>
 #include <sys/ioctl.h>
 #include <net/if.h>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/resource-agents-4.17.0+git30.b33c378d/tools/tickle_tcp.c 
new/resource-agents-4.17.0+git42.a607c299/tools/tickle_tcp.c
--- old/resource-agents-4.17.0+git30.b33c378d/tools/tickle_tcp.c        
2026-01-22 08:54:44.000000000 +0100
+++ new/resource-agents-4.17.0+git42.a607c299/tools/tickle_tcp.c        
2026-02-24 09:59:15.000000000 +0100
@@ -235,16 +235,21 @@
                ip4pkt.ip.daddr    = dst->ip.sin_addr.s_addr;
                ip4pkt.ip.check    = 0;
 
-               ip4pkt.tcp.source  = src->ip.sin_port;
-               ip4pkt.tcp.dest    = dst->ip.sin_port;
-               ip4pkt.tcp.seq     = seq;
-               ip4pkt.tcp.ack_seq = ack;
-               ip4pkt.tcp.ack     = 1;
-               if (rst)
-                       ip4pkt.tcp.rst = 1;
-               ip4pkt.tcp.doff    = sizeof(ip4pkt.tcp)/4;
-               ip4pkt.tcp.window   = htons(1234);
-               ip4pkt.tcp.check    = tcp_checksum((uint16_t *)&ip4pkt.tcp, 
sizeof(ip4pkt.tcp), &ip4pkt.ip);
+               // musl define only one of the two struct for tcphdr in
+               // /usr/include/netinet/tcp.h so we must use it to ensure 
compatibility
+               ip4pkt.tcp.th_sport = src->ip.sin_port;
+               ip4pkt.tcp.th_dport = dst->ip.sin_port;
+               ip4pkt.tcp.th_seq   = seq;
+               ip4pkt.tcp.th_ack   = ack;
+
+               ip4pkt.tcp.th_flags      = 0;
+               ip4pkt.tcp.th_flags     |= TH_ACK;
+               if (rst) {
+                       ip4pkt.tcp.th_flags |= TH_RST;
+               }
+               ip4pkt.tcp.th_off   = sizeof(ip4pkt.tcp)/4;
+               ip4pkt.tcp.th_win   = htons(1234);
+               ip4pkt.tcp.th_sum   = tcp_checksum((uint16_t *)&ip4pkt.tcp, 
sizeof(ip4pkt.tcp), &ip4pkt.ip);
 
                s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
                if (s == -1) {
@@ -280,16 +285,20 @@
                ip6pkt.ip6.ip6_src  = src->ip6.sin6_addr;
                ip6pkt.ip6.ip6_dst  = dst->ip6.sin6_addr;
 
-               ip6pkt.tcp.source   = src->ip6.sin6_port;
-               ip6pkt.tcp.dest     = dst->ip6.sin6_port;
-               ip6pkt.tcp.seq      = seq;
-               ip6pkt.tcp.ack_seq  = ack;
-               ip6pkt.tcp.ack      = 1;
-               if (rst)
-                       ip6pkt.tcp.rst      = 1;
-               ip6pkt.tcp.doff     = sizeof(ip6pkt.tcp)/4;
-               ip6pkt.tcp.window   = htons(1234);
-               ip6pkt.tcp.check    = tcp_checksum6((uint16_t *)&ip6pkt.tcp, 
sizeof(ip6pkt.tcp), &ip6pkt.ip6);
+               // musl define only one of the two struct for tcphdr in
+               // /usr/include/netinet/tcp.h so we must use it to ensure 
compatibility
+               ip6pkt.tcp.th_sport = src->ip6.sin6_port;
+               ip6pkt.tcp.th_dport = dst->ip6.sin6_port;
+               ip6pkt.tcp.th_seq   = seq;
+               ip6pkt.tcp.th_ack   = ack;
+               ip6pkt.tcp.th_flags      = 0;
+               ip6pkt.tcp.th_flags     |= TH_ACK;
+               if (rst) {
+                       ip6pkt.tcp.th_flags |= TH_RST;
+               }
+               ip6pkt.tcp.th_off   = sizeof(ip6pkt.tcp)/4;
+               ip6pkt.tcp.th_win   = htons(1234);
+               ip6pkt.tcp.th_sum   = tcp_checksum6((uint16_t *)&ip6pkt.tcp, 
sizeof(ip6pkt.tcp), &ip6pkt.ip6);
 
                s = socket(PF_INET6, SOCK_RAW, IPPROTO_RAW);
                if (s == -1) {

Reply via email to