Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package aws-efs-utils for openSUSE:Factory 
checked in at 2022-05-02 16:25:39
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/aws-efs-utils (Old)
 and      /work/SRC/openSUSE:Factory/.aws-efs-utils.new.1538 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "aws-efs-utils"

Mon May  2 16:25:39 2022 rev:8 rq:974305 version:1.32.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/aws-efs-utils/aws-efs-utils.changes      
2022-03-11 11:40:23.642548932 +0100
+++ /work/SRC/openSUSE:Factory/.aws-efs-utils.new.1538/aws-efs-utils.changes    
2022-05-02 16:25:45.668850989 +0200
@@ -1,0 +2,9 @@
+Wed Apr 27 06:39:41 UTC 2022 - pgaj...@suse.com
+
+- version update to 1.32.1
+  * Enable watchdog to check stunnel health periodically and restart
+    hanging stunnel process when necessary.
+- do not require python-mock for build
+  https://trello.com/c/S6eADbii/64-remove-python-mock
+
+-------------------------------------------------------------------

Old:
----
  efs-utils-1.31.3.tar.gz

New:
----
  efs-utils-1.32.1.tar.gz

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

Other differences:
------------------
++++++ aws-efs-utils.spec ++++++
--- /var/tmp/diff_new_pack.tfgdZv/_old  2022-05-02 16:25:46.544851963 +0200
+++ /var/tmp/diff_new_pack.tfgdZv/_new  2022-05-02 16:25:46.560851981 +0200
@@ -17,13 +17,13 @@
 
 
 Name:           aws-efs-utils
-Version:        1.31.3
+Version:        1.32.1
 Release:        0
 Summary:        Utilities for using the EFS file systems
 License:        MIT
 Group:          System/Management
 URL:            https://github.com/aws/efs-utils
-Source0:        efs-utils-%{version}.tar.gz
+Source0:        
https://github.com/aws/efs-utils/archive/refs/tags/v%{version}.tar.gz#/efs-utils-%{version}.tar.gz
 Patch0:         disable_mount_efs_test.patch
 Patch1:         harden_amazon-efs-mount-watchdog.service.patch
 Patch2:         skip-styletest.patch
@@ -34,7 +34,6 @@
 #BuildRequires:  python3-flake8 >= 3.7.9
 BuildRequires:  python3-flake8
 BuildRequires:  python3-mccabe >= 0.6.1
-BuildRequires:  python3-mock >= 2.0.0
 BuildRequires:  python3-pbr >= 3.1.1
 BuildRequires:  python3-pluggy >= 0.13.0
 BuildRequires:  python3-py >= 1.10.0
@@ -66,6 +65,8 @@
 # No build required
 
 %check
+# https://github.com/aws/efs-utils/issues/131
+sed -i 's:from mock:from unittest.mock:' test/*/test_*.py
 make test
 
 %install

++++++ efs-utils-1.31.3.tar.gz -> efs-utils-1.32.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/efs-utils-1.31.3/.circleci/config.yml 
new/efs-utils-1.32.1/.circleci/config.yml
--- old/efs-utils-1.31.3/.circleci/config.yml   2021-12-09 04:39:51.000000000 
+0100
+++ new/efs-utils-1.32.1/.circleci/config.yml   2022-04-01 22:34:12.000000000 
+0200
@@ -49,7 +49,7 @@
       - run:
           name: Install package
           command: |
-            apt-get -y install ./build/amazon-efs-utils*deb
+            DEBIAN_FRONTEND=noninteractive apt-get -y install 
./build/amazon-efs-utils*deb
       - run:
           name: Check installed successfully
           command: |
@@ -105,6 +105,13 @@
           name: Check changelog
           command: |
             rpm -q --changelog amazon-efs-utils
+  build-centos-repo:
+    steps:
+    - run:
+        name: change the mirrors to vault.centos.org
+        command: |
+          sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
+          sed -i 
's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' 
/etc/yum.repos.d/CentOS-*
 jobs:
   test:
     parameters:
@@ -142,6 +149,16 @@
       image: << parameters.image >>
     steps:
       - build-suse-rpm
+  build-centos-rpm-package:
+    parameters:
+      image:
+        type: string
+    executor:
+      name: linux
+      image: << parameters.image >>
+    steps:
+      - build-centos-repo
+      - build-rpm
 workflows:
   workflow:
     jobs:
@@ -164,12 +181,24 @@
           name: python34
           image: circleci/python:3.4.9
       - build-deb-package:
+          name: ubuntu-latest
+          image: ubuntu:latest
+      - build-deb-package:
           name: ubuntu16
           image: ubuntu:16.04
       - build-deb-package:
           name: ubuntu18
           image: ubuntu:18.04
       - build-deb-package:
+          name: ubuntu20
+          image: ubuntu:20.04
+      - build-deb-package:
+          name: ubuntu21
+          image: ubuntu:21.04
+      - build-deb-package:
+          name: ubuntu22
+          image: ubuntu:22.04
+      - build-deb-package:
           name: debian9
           image: debian:stretch
       - build-deb-package:
@@ -178,19 +207,31 @@
       - build-deb-package:
           name: debian11
           image: debian:bullseye
+      - build-centos-rpm-package:
+          name: centos-latest
+          image: centos:latest
       - build-rpm-package:
           name: centos7
           image: centos:centos7
-      - build-rpm-package:
+      - build-centos-rpm-package:
           name: centos8
           image: centos:centos8
       - build-rpm-package:
+          name: rocky8
+          image: rockylinux/rockylinux:8
+      - build-rpm-package:
+          name: amazon-linux-latest
+          image: amazonlinux:latest
+      - build-rpm-package:
           name: amazon-linux-2
           image: amazonlinux:2
       - build-rpm-package:
           name: amazon-linux
           image: amazonlinux:1
       - build-rpm-package:
+          name: fedora-latest
+          image: fedora:latest
+      - build-rpm-package:
           name: fedora28
           image: fedora:28
       - build-rpm-package:
@@ -208,6 +249,15 @@
       - build-rpm-package:
           name: fedora33
           image: fedora:33
+      - build-rpm-package:
+          name: fedora34
+          image: fedora:34
+      - build-rpm-package:
+          name: fedora35
+          image: fedora:35
+      - build-rpm-package:
+          name: fedora36
+          image: fedora:36
       - build-suse-rpm-package:
           name: opensuse-leap15.1
           image: opensuse/leap:15.1
@@ -215,5 +265,11 @@
           name: opensuse-leap15.2
           image: opensuse/leap:15.2
       - build-suse-rpm-package:
+          name: opensuse-leap15.3
+          image: opensuse/leap:15.3
+      - build-suse-rpm-package:
+          name: opensuse-leap15.4
+          image: opensuse/leap:15.4
+      - build-suse-rpm-package:
           name: opensuse-leap-latest
           image: opensuse/leap:latest
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/efs-utils-1.31.3/README.md 
new/efs-utils-1.32.1/README.md
--- old/efs-utils-1.31.3/README.md      2021-12-09 04:39:51.000000000 +0100
+++ new/efs-utils-1.32.1/README.md      2022-04-01 22:34:12.000000000 +0200
@@ -31,9 +31,10 @@
 
 The `efs-utils` package has been verified against the following MacOS 
distributions:
 
-| Distribution | `init` System |
-| ------------ | ------------- |
-| MacOS Big Sur | `launchd` |
+| Distribution   | `init` System |
+| -------------- | ------------- |
+| MacOS Big Sur  | `launchd` |
+| MacOS Monterey | `launchd` |
 
 ## Prerequisites
 
@@ -116,14 +117,16 @@
 $ sudo apt-get -y install ./build/amazon-efs-utils*deb
 ```
 
-### On MacOS Big Sur distribution
+### On MacOS Big Sur and macOS Monterey distribution
 
-For EC2 Mac instances running macOS Big Sur, you can install amazon-efs-utils 
from the [homebrew-aws](https://github.com/aws/homebrew-aws) respository.
+For EC2 Mac instances running macOS Big Sur and macOS Monterey, you can 
install amazon-efs-utils from the 
+[homebrew-aws](https://github.com/aws/homebrew-aws) respository. **Note that 
this will ONLY work on EC2 instances
+running macOS Big Sur and macOS Monterey, not local Mac computers.**
 ```
 brew install amazon-efs-utils
 ```
 
-This will install amazon-efs-utils on your EC2 Mac Instance running macOS Big 
Sur in the directory `/usr/local/Cellar/amazon-efs-utils`. At the end of the 
installation, it will print a set of commands that must be executed in order to 
start using efs-utils. The instructions that are printed after amazon-efs-utils 
and must be executed are:
+This will install amazon-efs-utils on your EC2 Mac Instance running macOS Big 
Sur and macOS Monterey in the directory `/usr/local/Cellar/amazon-efs-utils`. 
At the end of the installation, it will print a set of commands that must be 
executed in order to start using efs-utils. The instructions that are printed 
after amazon-efs-utils and must be executed are:
 
 ```
 Perform below actions to start using efs:
@@ -278,7 +281,9 @@
 sudo yum -y install wget
 ```
 ```bash
-if [[ "$(python3 -V 2>&1)" =~ ^(Python 3.5.*) ]]; then
+if [[ "$(python3 -V 2>&1)" =~ ^(Python 3.6.*) ]]; then
+    sudo wget https://bootstrap.pypa.io/3.6/get-pip.py -O /tmp/get-pip.py
+elif [[ "$(python3 -V 2>&1)" =~ ^(Python 3.5.*) ]]; then
     sudo wget https://bootstrap.pypa.io/3.5/get-pip.py -O /tmp/get-pip.py
 elif [[ "$(python3 -V 2>&1)" =~ ^(Python 3.4.*) ]]; then
     sudo wget https://bootstrap.pypa.io/3.4/get-pip.py -O /tmp/get-pip.py
@@ -292,7 +297,9 @@
 sudo apt-get -y install wget
 ```
 ```bash
-if echo $(python3 -V 2>&1) | grep -e "Python 3.5"; then
+if echo $(python3 -V 2>&1) | grep -e "Python 3.6"; then
+    sudo wget https://bootstrap.pypa.io/3.6/get-pip.py -O /tmp/get-pip.py
+elif echo $(python3 -V 2>&1) | grep -e "Python 3.5"; then
     sudo wget https://bootstrap.pypa.io/3.5/get-pip.py -O /tmp/get-pip.py
 elif echo $(python3 -V 2>&1) | grep -e "Python 3.4"; then
     sudo wget https://bootstrap.pypa.io/3.4/get-pip.py -O /tmp/get-pip.py
@@ -346,7 +353,7 @@
 
 - For MacOS:
 ```bash
-sudo sed -i -e '/\[cloudwatch-log\]/{N;s/# enabled = true/enabled = true/;}' 
/usr/local/Cellar/amazon-efs-utils/<version>/etc/amazon/efs/efs-utils.conf
+sudo sed -i -e '/\[cloudwatch-log\]/{N;s/# enabled = true/enabled = true/;}' 
/usr/local/Cellar/amazon-efs-utils/<version>/libexec/etc/amazon/efs/efs-utils.conf
 ```
 You can also configure CloudWatch log group name and log retention days in the 
config file.
 If you want to have separate log groups in Cloudwatch for every mounted file 
system, add `/{fs_id}` to the end of the `log_group_name` field in 
`efs-utils.conf` file. For example, the `log_group_name` in `efs-utils.conf` 
file would look something like:
@@ -427,7 +434,7 @@
 `awsprofile` option. These options require the `tls` option.
 
 ```
-$ sudo mount -t efs -o tls,iam,aws-profile=test-profile file-system-id 
efs-mount-point/
+$ sudo mount -t efs -o tls,iam,awsprofile=test-profile file-system-id 
efs-mount-point/
 ```
 
 To configure the named profile, see the [Named Profiles 
doc](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/efs-utils-1.31.3/amazon-efs-utils.spec 
new/efs-utils-1.32.1/amazon-efs-utils.spec
--- old/efs-utils-1.31.3/amazon-efs-utils.spec  2021-12-09 04:39:51.000000000 
+0100
+++ new/efs-utils-1.32.1/amazon-efs-utils.spec  2022-04-01 22:34:12.000000000 
+0200
@@ -18,20 +18,24 @@
 %global with_systemd 1
 %endif
 
-%if 0%{?is_opensuse}
-%global platform .opensuse
+%if 0%{?dist:1}
+%global platform %{dist}
 %else
-
-%if 0%{?sle_version}
+%if 0%{?suse_version}
 %global platform .suse
 %else
-%global platform %{dist}
+%global platform .unknown
+%endif
 %endif
 
+%if 0%{?amzn} > 2
+%global efs_bindir %{_sbindir}
+%else
+%global efs_bindir /sbin
 %endif
 
 Name      : amazon-efs-utils
-Version   : 1.31.3
+Version   : 1.32.1
 Release   : 1%{platform}
 Summary   : This package provides utilities for simplifying the use of EFS 
file systems
 
@@ -78,14 +82,14 @@
 install -p -m 644 %{_builddir}/%{name}/dist/amazon-efs-mount-watchdog.conf 
%{buildroot}%{_sysconfdir}/init
 %endif
 
-mkdir -p %{buildroot}/sbin
+mkdir -p %{buildroot}%{efs_bindir}
 mkdir -p %{buildroot}%{_bindir}
 mkdir -p %{buildroot}%{_localstatedir}/log/amazon/efs
 mkdir -p  %{buildroot}%{_mandir}/man8
 
 install -p -m 644 %{_builddir}/%{name}/dist/efs-utils.conf 
%{buildroot}%{_sysconfdir}/amazon/efs
 install -p -m 444 %{_builddir}/%{name}/dist/efs-utils.crt 
%{buildroot}%{_sysconfdir}/amazon/efs
-install -p -m 755 %{_builddir}/%{name}/src/mount_efs/__init__.py 
%{buildroot}/sbin/mount.efs
+install -p -m 755 %{_builddir}/%{name}/src/mount_efs/__init__.py 
%{buildroot}%{efs_bindir}/mount.efs
 install -p -m 755 %{_builddir}/%{name}/src/watchdog/__init__.py 
%{buildroot}%{_bindir}/amazon-efs-mount-watchdog
 install -p -m 644 %{_builddir}/%{name}/man/mount.efs.8 
%{buildroot}%{_mandir}/man8
 
@@ -97,7 +101,7 @@
 %config(noreplace) %{_sysconfdir}/init/amazon-efs-mount-watchdog.conf
 %endif
 %{_sysconfdir}/amazon/efs/efs-utils.crt
-/sbin/mount.efs
+%{efs_bindir}/mount.efs
 %{_bindir}/amazon-efs-mount-watchdog
 /var/log/amazon
 %{_mandir}/man8/mount.efs.8.gz
@@ -131,7 +135,12 @@
 %clean
 
 %changelog
-* Thu Nov 23 2021 Jigar Dedhia <dedhi...@amazon.com> - 1.31.3
+* Thu Mar 31 2022 Shivam Gupta <lshig...@amazon.com> - 1.32.1
+- Enable watchdog to check stunnel health periodically and restart hanging 
stunnel process when necessary.
+- Fix potential race condition issue when removing lock files.
+- Add efs-utils Support for MacOS Monterey EC2 instances.
+
+* Tue Nov 23 2021 Jigar Dedhia <dedhi...@amazon.com> - 1.31.3
 - Add unmount_time and unmount_count to handle inconsistent mount reads
 - Allow specifying fs_id in cloudwatch log group name
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/efs-utils-1.31.3/build-deb.sh 
new/efs-utils-1.32.1/build-deb.sh
--- old/efs-utils-1.31.3/build-deb.sh   2021-12-09 04:39:51.000000000 +0100
+++ new/efs-utils-1.32.1/build-deb.sh   2022-04-01 22:34:12.000000000 +0200
@@ -11,7 +11,7 @@
 
 BASE_DIR=$(pwd)
 BUILD_ROOT=${BASE_DIR}/build/debbuild
-VERSION=1.31.3
+VERSION=1.32.1
 RELEASE=1
 DEB_SYSTEM_RELEASE_PATH=/etc/os-release
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/efs-utils-1.31.3/config.ini 
new/efs-utils-1.32.1/config.ini
--- old/efs-utils-1.31.3/config.ini     2021-12-09 04:39:51.000000000 +0100
+++ new/efs-utils-1.32.1/config.ini     2022-04-01 22:34:12.000000000 +0200
@@ -7,5 +7,5 @@
 #
 
 [global]
-version=1.31.3
+version=1.32.1
 release=1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/efs-utils-1.31.3/dist/amazon-efs-utils.control 
new/efs-utils-1.32.1/dist/amazon-efs-utils.control
--- old/efs-utils-1.31.3/dist/amazon-efs-utils.control  2021-12-09 
04:39:51.000000000 +0100
+++ new/efs-utils-1.32.1/dist/amazon-efs-utils.control  2022-04-01 
22:34:12.000000000 +0200
@@ -1,6 +1,6 @@
 Package: amazon-efs-utils
 Architecture: all
-Version: 1.31.3
+Version: 1.32.1
 Section: utils
 Depends: python3, nfs-common, stunnel4 (>= 4.56), openssl (>= 1.0.2), 
util-linux
 Priority: optional
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/efs-utils-1.31.3/dist/efs-utils.conf 
new/efs-utils-1.32.1/dist/efs-utils.conf
--- old/efs-utils-1.31.3/dist/efs-utils.conf    2021-12-09 04:39:51.000000000 
+0100
+++ new/efs-utils-1.32.1/dist/efs-utils.conf    2022-04-01 22:34:12.000000000 
+0200
@@ -55,10 +55,6 @@
 dns_name_suffix = c2s.ic.gov
 stunnel_cafile = /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
 
-[mount.us-isob-east-1]
-dns_name_suffix = sc2s.sgov.gov
-stunnel_cafile = /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
-
 [mount-watchdog]
 enabled = true
 poll_interval_sec = 1
@@ -68,6 +64,11 @@
 # Set client auth/access point certificate renewal rate. Minimum value is 1 
minute.
 tls_cert_renewal_interval_min = 60
 
+# Periodically check the health of stunnel to make sure the connection is 
fully established
+stunnel_health_check_enabled = true
+stunnel_health_check_interval_min = 5
+stunnel_health_check_command_timeout_sec = 30
+
 [cloudwatch-log]
 # enabled = true
 log_group_name = /aws/efs/utils
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/efs-utils-1.31.3/src/mount_efs/__init__.py 
new/efs-utils-1.32.1/src/mount_efs/__init__.py
--- old/efs-utils-1.31.3/src/mount_efs/__init__.py      2021-12-09 
04:39:51.000000000 +0100
+++ new/efs-utils-1.32.1/src/mount_efs/__init__.py      2022-04-01 
22:34:12.000000000 +0200
@@ -84,7 +84,7 @@
     BOTOCORE_PRESENT = False
 
 
-VERSION = "1.31.3"
+VERSION = "1.32.1"
 SERVICE = "elasticfilesystem"
 
 CLONE_NEWNET = 0x40000000
@@ -258,23 +258,8 @@
 WATCHDOG_SERVICE_PLIST_PATH = 
"/Library/LaunchAgents/amazon-efs-mount-watchdog.plist"
 SYSTEM_RELEASE_PATH = "/etc/system-release"
 OS_RELEASE_PATH = "/etc/os-release"
-RHEL8_RELEASE_NAME = "Red Hat Enterprise Linux release 8"
-CENTOS8_RELEASE_NAME = "CentOS Linux release 8"
-ORACLE_RELEASE_NAME = "Oracle Linux Server release 8"
-FEDORA_RELEASE_NAME = "Fedora release"
-OPEN_SUSE_LEAP_RELEASE_NAME = "openSUSE Leap"
-SUSE_RELEASE_NAME = "SUSE Linux Enterprise Server"
 MACOS_BIG_SUR_RELEASE = "macOS-11"
-
-SKIP_NO_LIBWRAP_RELEASES = [
-    RHEL8_RELEASE_NAME,
-    CENTOS8_RELEASE_NAME,
-    FEDORA_RELEASE_NAME,
-    OPEN_SUSE_LEAP_RELEASE_NAME,
-    SUSE_RELEASE_NAME,
-    MACOS_BIG_SUR_RELEASE,
-    ORACLE_RELEASE_NAME,
-]
+MACOS_MONTEREY_RELEASE = "macOS-12"
 
 # Multiplier for max read ahead buffer size
 # Set default as 15 aligning with prior linux kernel 5.4
@@ -283,11 +268,11 @@
 NFS_READAHEAD_OPTIMIZE_LINUX_KERNEL_MIN_VERSION = [5, 4]
 
 # MacOS does not support the property of Socket SO_BINDTODEVICE in stunnel 
configuration
-SKIP_NO_SO_BINDTODEVICE_RELEASES = [MACOS_BIG_SUR_RELEASE]
+SKIP_NO_SO_BINDTODEVICE_RELEASES = [MACOS_BIG_SUR_RELEASE, 
MACOS_MONTEREY_RELEASE]
 
 MAC_OS_PLATFORM_LIST = ["darwin"]
-# MacOS Versions : Big Sur - 20.*, Catalina - 19.*, Mojave - 18.*. Catalina 
and Mojave are not supported for now
-MAC_OS_SUPPORTED_VERSION_LIST = ["20"]
+# MacOS Versions : Monterey - 21.*, Big Sur - 20.*, Catalina - 19.*, Mojave - 
18.*. Catalina and Mojave are not supported for now
+MAC_OS_SUPPORTED_VERSION_LIST = ["20", "21"]
 
 
 def errcheck(ret, func, args):
@@ -1073,7 +1058,7 @@
     return supported
 
 
-def get_version_specific_stunnel_options():
+def get_stunnel_options():
     stunnel_command = [_stunnel_bin(), "-help"]
     proc = subprocess.Popen(
         stunnel_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, 
close_fds=True
@@ -1081,12 +1066,7 @@
     proc.wait()
     _, err = proc.communicate()
 
-    stunnel_output = err.splitlines()
-
-    check_host_supported = is_stunnel_option_supported(stunnel_output, 
b"checkHost")
-    ocsp_aia_supported = is_stunnel_option_supported(stunnel_output, 
b"OCSPaia")
-
-    return check_host_supported, ocsp_aia_supported
+    return err.splitlines()
 
 
 def _stunnel_bin():
@@ -1193,7 +1173,7 @@
         efs_config["cert"] = cert_details["certificate"]
         efs_config["key"] = cert_details["privateKey"]
 
-    check_host_supported, ocsp_aia_supported = 
get_version_specific_stunnel_options()
+    stunnel_options = get_stunnel_options()
 
     tls_controls_message = (
         "WARNING: Your client lacks sufficient controls to properly enforce 
TLS. Please upgrade stunnel, "
@@ -1204,7 +1184,7 @@
     if get_boolean_config_item_value(
         config, CONFIG_SECTION, "stunnel_check_cert_hostname", 
default_value=True
     ):
-        if check_host_supported:
+        if is_stunnel_option_supported(stunnel_options, b"checkHost"):
             # Stunnel checkHost option checks if the specified DNS host name 
or wildcard matches any of the provider in peer
             # certificate's CN fields, after introducing the AZ field in dns 
name, the host name in the stunnel config file
             # is not valid, remove the az info there
@@ -1214,14 +1194,14 @@
 
     # Only use the config setting if the override is not set
     if ocsp_enabled:
-        if ocsp_aia_supported:
+        if is_stunnel_option_supported(stunnel_options, b"OCSPaia"):
             efs_config["OCSPaia"] = "yes"
         else:
             fatal_error(tls_controls_message % "stunnel_check_cert_validity")
 
-    if not any(
-        release in system_release_version for release in 
SKIP_NO_LIBWRAP_RELEASES
-    ):
+    # If the stunnel libwrap option is supported, we disable the usage of 
/etc/hosts.allow and /etc/hosts.deny by
+    # setting the option to no
+    if is_stunnel_option_supported(stunnel_options, b"libwrap"):
         efs_config["libwrap"] = "no"
 
     stunnel_config = "\n".join(
@@ -1261,6 +1241,7 @@
         "cmd": command,
         "files": files,
         "mount_time": time.time(),
+        "mountpoint": mountpoint,
     }
 
     if cert_details:
@@ -1562,8 +1543,8 @@
     while not verify_tlsport_can_be_connected(tlsport) and retry_times > 0:
         logging.debug(
             "The tlsport %s cannot be connected yet, sleep %s(s), %s retry 
time(s) left",
-            DEFAULT_TIMEOUT,
             tlsport,
+            DEFAULT_TIMEOUT,
             retry_times,
         )
         time.sleep(DEFAULT_TIMEOUT)
@@ -1831,8 +1812,7 @@
             os.write(f, lock_file_contents.encode("utf-8"))
             yield f
         finally:
-            os.close(f)
-            os.remove(lock_file)
+            check_and_remove_lock_file(lock_file, f)
 
     def do_with_lock(function):
         while True:
@@ -1847,7 +1827,15 @@
                     )
                     time.sleep(DEFAULT_TIMEOUT)
                 else:
-                    raise
+                    # errno.ENOENT: No such file or directory, errno.EBADF: 
Bad file descriptor
+                    if e.errno == errno.ENOENT or e.errno == errno.EBADF:
+                        logging.debug(
+                            "lock file does not exist or Bad file descriptor, 
The file is already removed nothing to do."
+                        )
+                    else:
+                        raise Exception(
+                            "Could not remove lock file unexpected exception: 
%s", e
+                        )
 
     def generate_key():
         if os.path.isfile(key):
@@ -2074,7 +2062,10 @@
         os.path.join(log_dir, LOG_FILE), maxBytes=max_bytes, 
backupCount=file_count
     )
     handler.setFormatter(
-        logging.Formatter(fmt="%(asctime)s - %(levelname)s - %(message)s")
+        logging.Formatter(
+            fmt="%(asctime)s - %(levelname)s - %(message)s",
+            datefmt="%Y-%m-%d %H:%M:%S %Z",
+        )
     )
 
     logger = logging.getLogger()
@@ -2221,6 +2212,24 @@
     )
 
 
+def check_and_remove_lock_file(path, file):
+    """
+    There is a possibility of having a race condition as the lock file is 
getting deleted in both mount_efs and watchdog,
+    so creating a function in order to check whether the path exist or not 
before removing the lock file.
+    """
+    try:
+        os.close(file)
+        os.remove(path)
+        logging.debug("Removed %s successfully", path)
+    except OSError as e:
+        if not (e.errno == errno.ENOENT or e.errno == errno.EBADF):
+            raise Exception("Could not remove %s. Unexpected exception: %s", 
path, e)
+        else:
+            logging.debug(
+                "%s does not exist, The file is already removed nothing to 
do", path
+            )
+
+
 def dns_name_can_be_resolved(dns_name):
     try:
         socket.gethostbyname(dns_name)
@@ -3399,7 +3408,9 @@
     bootstrap_logging(config)
 
     if check_if_platform_is_mac() and not check_if_mac_version_is_supported():
-        fatal_error("We do not support EFS on MacOS " + platform.release())
+        fatal_error(
+            "We do not support EFS on MacOS Kernel version " + 
platform.release()
+        )
 
     fs_id, path, mountpoint, options = parse_arguments(config)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/efs-utils-1.31.3/src/watchdog/__init__.py 
new/efs-utils-1.32.1/src/watchdog/__init__.py
--- old/efs-utils-1.31.3/src/watchdog/__init__.py       2021-12-09 
04:39:51.000000000 +0100
+++ new/efs-utils-1.32.1/src/watchdog/__init__.py       2022-04-01 
22:34:12.000000000 +0200
@@ -27,7 +27,7 @@
 from contextlib import contextmanager
 from datetime import datetime, timedelta
 from logging.handlers import RotatingFileHandler
-from signal import SIGTERM, SIGHUP
+from signal import SIGHUP, SIGKILL, SIGTERM
 
 try:
     from configparser import ConfigParser, NoOptionError, NoSectionError
@@ -49,7 +49,7 @@
     from urllib import urlencode
 
 
-VERSION = "1.31.3"
+VERSION = "1.32.1"
 SERVICE = "elasticfilesystem"
 
 CONFIG_FILE = "/etc/amazon/efs/efs-utils.conf"
@@ -71,6 +71,8 @@
 DEFAULT_NFS_PORT = "2049"
 PRIVATE_KEY_FILE = "/etc/amazon/efs/privateKey.pem"
 DEFAULT_REFRESH_SELF_SIGNED_CERT_INTERVAL_MIN = 60
+DEFAULT_STUNNEL_HEALTH_CHECK_INTERVAL_MIN = 5
+DEFAULT_STUNNEL_HEALTH_CHECK_TIMEOUT_SEC = 30
 NOT_BEFORE_MINS = 15
 NOT_AFTER_HOURS = 3
 DATE_ONLY_FORMAT = "%Y%m%d"
@@ -585,7 +587,10 @@
         os.path.join(log_dir, LOG_FILE), maxBytes=max_bytes, 
backupCount=file_count
     )
     handler.setFormatter(
-        logging.Formatter(fmt="%(asctime)s - %(levelname)s - %(message)s")
+        logging.Formatter(
+            fmt="%(asctime)s - %(levelname)s - %(message)s",
+            datefmt="%Y-%m-%d %H:%M:%S %Z",
+        )
     )
 
     logger = logging.getLogger()
@@ -937,11 +942,165 @@
 
             if is_running:
                 logging.debug("TLS tunnel for %s is running", state_file)
+                # 
https://github.com/kubernetes-sigs/aws-efs-csi-driver/issues/616 We have seen 
EFS hanging issue caused
+                # by stuck stunnel (version: 4.56) process. Apart from 
checking whether stunnel is running or not, we
+                # need to check whether the stunnel connection established is 
healthy periodically.
+                #
+                # The way to check the stunnel health is by `df` the 
mountpoint, i.e. check the file system information,
+                # which will trigger a remote GETATTR on the root of the file 
system. Normally the command will finish
+                # in 10 milliseconds, thus if the command hang for certain 
period (defined as 30 sec as of now), the
+                # stunnel connection is likely to be unhealthy. Watchdog will 
kill the old stunnel process and restart
+                # a new one for the unhealthy mount. The health check will run 
every 5 min since mount.
+                #
+                # Both the command hang timeout and health check interval are 
configurable in efs-utils config file.
+                #
+                check_stunnel_health(
+                    config, state, state_file_dir, state_file, child_procs, 
nfs_mounts
+                )
             else:
                 logging.warning("TLS tunnel for %s is not running", state_file)
                 restart_tls_tunnel(child_procs, state, state_file_dir, 
state_file)
 
 
+def check_stunnel_health(
+    config, state, state_file_dir, state_file, child_procs, nfs_mounts
+):
+    if not get_boolean_config_item_value(
+        config, CONFIG_SECTION, "stunnel_health_check_enabled", 
default_value=True
+    ):
+        return
+
+    check_interval_min = get_int_value_from_config_file(
+        config,
+        "stunnel_health_check_interval_min",
+        DEFAULT_STUNNEL_HEALTH_CHECK_INTERVAL_MIN,
+    )
+
+    current_time = time.time()
+
+    # The mount_time info in the state file is added in version 1.31.3. It is 
possible for existing mounts, there are
+    # no mount_time in state file, which will cause watchdog to crash. If the 
information does not exist, we just take
+    # current time as the initial mount time of the mount.
+    #
+    if "mount_time" not in state:
+        state["mount_time"] = current_time
+        rewrite_state_file(state, state_file_dir, state_file)
+        return
+
+    # Only start to perform the stunnel health check after the check interval 
passed.
+    if current_time - state["mount_time"] < check_interval_min * 60:
+        return
+
+    last_stunnel_check_time = (
+        state["last_stunnel_check_time"] if "last_stunnel_check_time" in state 
else 0
+    )
+    if (
+        last_stunnel_check_time != 0
+        and current_time - last_stunnel_check_time < check_interval_min * 60
+    ):
+        return
+
+    # We add this mountpoint info in the state file along with this change. It 
is possible for existing mounts, there
+    # are no mountpoint in state file, which will cause watchdog to crash. To 
handle that case, we need to extract the
+    # mountpoint from the state file name, and write that information to state 
file.
+    #
+    if "mountpoint" in state:
+        mountpoint = state["mountpoint"]
+    else:
+        mountpoint = get_mountpoint_from_nfs_mounts(state_file, nfs_mounts)
+        state["mountpoint"] = mountpoint
+        rewrite_state_file(state, state_file_dir, state_file)
+
+    stunnel_pid = state["pid"]
+    process = subprocess.Popen(
+        ["df", mountpoint],
+        stdout=subprocess.DEVNULL,
+        stderr=subprocess.DEVNULL,
+        close_fds=True,
+    )
+
+    command_timeout_sec = get_int_value_from_config_file(
+        config,
+        "stunnel_health_check_command_timeout_sec",
+        DEFAULT_STUNNEL_HEALTH_CHECK_TIMEOUT_SEC,
+    )
+    try:
+        state["last_stunnel_check_time"] = current_time
+        process.communicate(timeout=command_timeout_sec)
+        logging.debug(
+            "Stunnel [PID: %d] running for tls mount on %s passed health 
check.",
+            stunnel_pid,
+            mountpoint,
+        )
+        rewrite_state_file(state, state_file_dir, state_file)
+    except subprocess.TimeoutExpired:
+        if is_pid_running(stunnel_pid):
+            process_group = os.getpgid(stunnel_pid)
+            logging.warning(
+                "Connection timeout for %s after %d, the stunnel could be 
unhealthy. Sending SIGKILL to kill the "
+                "stunnel(PID: %d, group ID: %s) and starting a new stunnel 
process.",
+                mountpoint,
+                command_timeout_sec,
+                stunnel_pid,
+                process_group,
+            )
+            os.killpg(process_group, SIGKILL)
+            restart_tls_tunnel(child_procs, state, state_file_dir, state_file)
+        else:
+            logging.warning(
+                "Stunnel health check timed out for %s, stunnel [PID: %d] is 
not running anymore.",
+                mountpoint,
+                stunnel_pid,
+            )
+        # The child process is not killed if the timeout expires, so in order 
to cleanup properly, kill the child
+        # process after the timeout.
+        #
+        process.kill()
+
+
+# Retrieve the nfs mountpoint with the port information in the mount option
+def get_mountpoint_from_nfs_mounts(state_file, nfs_mounts):
+    search_pattern = "port={port}".format(
+        port=os.path.basename(state_file).split(".")[-1]
+    )
+    for mount in nfs_mounts.values():
+        if search_pattern in mount[3]:
+            return mount[1]
+
+
+def get_int_value_from_config_file(config, config_name, default_config_value):
+    val = default_config_value
+    try:
+        value_from_config = config.get(CONFIG_SECTION, config_name)
+        try:
+            if int(value_from_config) > 0:
+                val = int(value_from_config)
+            else:
+                logging.warning(
+                    '%s value in config file "%s" is lower than 1. Defaulting 
to %d.',
+                    config_name,
+                    CONFIG_FILE,
+                    default_config_value,
+                )
+        except ValueError:
+            logging.warning(
+                'Bad %s, "%s", in config file "%s". Defaulting to %d.',
+                config_name,
+                value_from_config,
+                CONFIG_FILE,
+                default_config_value,
+            )
+    except NoOptionError:
+        logging.warning(
+            'No %s value in config file "%s". Defaulting to %d.',
+            config_name,
+            CONFIG_FILE,
+            default_config_value,
+        )
+
+    return val
+
+
 def check_child_procs(child_procs):
     for proc in child_procs:
         proc.poll()
@@ -1177,8 +1336,7 @@
             os.write(f, lock_file_contents.encode("utf-8"))
             yield f
         finally:
-            os.close(f)
-            os.remove(lock_file)
+            check_and_remove_lock_file(lock_file, f)
 
     def do_with_lock(function):
         while True:
@@ -1193,7 +1351,15 @@
                     )
                     time.sleep(DEFAULT_TIMEOUT)
                 else:
-                    raise
+                    # errno.ENOENT: No such file or directory, errno.EBADF: 
Bad file descriptor
+                    if e.errno == errno.ENOENT or e.errno == errno.EBADF:
+                        logging.debug(
+                            "lock file does not exist or Bad file descriptor, 
The file is already removed nothing to do."
+                        )
+                    else:
+                        raise Exception(
+                            "Could not remove lock file unexpected exception: 
%s", e
+                        )
 
     def generate_key():
         if os.path.isfile(key):
@@ -1630,6 +1796,24 @@
             logging.debug("%s does not exist, nothing to do", path)
 
 
+def check_and_remove_lock_file(path, file):
+    """
+    There is a possibility of having a race condition as the lock file is 
getting deleted in both mount_efs and watchdog,
+    so creating a function in order to check whether the path exist or not 
before removing the lock file.
+    """
+    try:
+        os.close(file)
+        os.remove(path)
+        logging.debug("Removed %s successfully", path)
+    except OSError as e:
+        if not (e.errno == errno.ENOENT or e.errno == errno.EBADF):
+            raise Exception("Could not remove %s. Unexpected exception: %s", 
path, e)
+        else:
+            logging.debug(
+                "%s does not exist, The file is already removed nothing to 
do", path
+            )
+
+
 def clean_up_certificate_lock_file(state_file_dir=STATE_FILE_DIR):
     """
     Cleans up private key lock file 'efs-utils-lock' left behind by a previous 
process attempting to create private key
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/efs-utils-1.31.3/test/mount_efs_test/test_add_stunnel_ca_options.py 
new/efs-utils-1.32.1/test/mount_efs_test/test_add_stunnel_ca_options.py
--- old/efs-utils-1.31.3/test/mount_efs_test/test_add_stunnel_ca_options.py     
2021-12-09 04:39:51.000000000 +0100
+++ new/efs-utils-1.32.1/test/mount_efs_test/test_add_stunnel_ca_options.py     
2022-04-01 22:34:12.000000000 +0200
@@ -31,7 +31,7 @@
 
 
 def _create_temp_file(tmpdir, content=""):
-    temp_file = tmpdir.join(tempfile.mktemp())
+    temp_file = tmpdir.join(tempfile.mkstemp()[1])
     temp_file.write(content, ensure=True)
     return temp_file
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/efs-utils-1.31.3/test/mount_efs_test/test_bootstrap_tls.py 
new/efs-utils-1.32.1/test/mount_efs_test/test_bootstrap_tls.py
--- old/efs-utils-1.31.3/test/mount_efs_test/test_bootstrap_tls.py      
2021-12-09 04:39:51.000000000 +0100
+++ new/efs-utils-1.32.1/test/mount_efs_test/test_bootstrap_tls.py      
2022-04-01 22:34:12.000000000 +0200
@@ -97,7 +97,7 @@
 
 def test_bootstrap_tls_state_file_nonexistent_dir(mocker, tmpdir):
     popen_mock, _ = setup_mocks(mocker)
-    state_file_dir = str(tmpdir.join(tempfile.mktemp()))
+    state_file_dir = str(tmpdir.join(tempfile.mkdtemp()[1]))
 
     def config_get_side_effect(section, field):
         if section == mount_efs.CONFIG_SECTION and field == 
"state_file_dir_mode":
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/efs-utils-1.31.3/test/mount_efs_test/test_get_init_system.py 
new/efs-utils-1.32.1/test/mount_efs_test/test_get_init_system.py
--- old/efs-utils-1.31.3/test/mount_efs_test/test_get_init_system.py    
2021-12-09 04:39:51.000000000 +0100
+++ new/efs-utils-1.32.1/test/mount_efs_test/test_get_init_system.py    
2022-04-01 22:34:12.000000000 +0200
@@ -12,7 +12,7 @@
 
 
 def test_get_init_system_from_file(tmpdir):
-    temp_file = tmpdir.join(tempfile.mktemp())
+    temp_file = tmpdir.join(tempfile.mkstemp()[1])
     temp_file.write("systemd\n", ensure=True)
 
     init_system = mount_efs.get_init_system(str(temp_file))
@@ -21,7 +21,7 @@
 
 
 def test_get_init_system_nonexistent_file(tmpdir):
-    temp_file = tmpdir.join(tempfile.mktemp())
+    temp_file = tmpdir.join(tempfile.mkstemp()[1])
 
     init_system = mount_efs.get_init_system(str(temp_file))
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/efs-utils-1.31.3/test/mount_efs_test/test_write_stunnel_config_file.py 
new/efs-utils-1.32.1/test/mount_efs_test/test_write_stunnel_config_file.py
--- old/efs-utils-1.31.3/test/mount_efs_test/test_write_stunnel_config_file.py  
2021-12-09 04:39:51.000000000 +0100
+++ new/efs-utils-1.32.1/test/mount_efs_test/test_write_stunnel_config_file.py  
2022-04-01 22:34:12.000000000 +0200
@@ -36,14 +36,24 @@
     stunnel_check_cert_hostname=None,
     stunnel_check_cert_validity=False,
     stunnel_logs_file=None,
+    stunnel_libwrap_option_supported=True,
 ):
 
+    options = []
+    if stunnel_check_cert_hostname_supported:
+        options.append(b"checkHost              = peer certificate host name 
pattern")
+    if stunnel_check_cert_validity_supported:
+        options.append(
+            b"OCSPaia                = yes|no check the AIA responders from 
certificates"
+        )
+    if stunnel_libwrap_option_supported:
+        options.append(
+            b"libwrap                = yes|no use /etc/hosts.allow and 
/etc/hosts.deny"
+        )
+
     mocker.patch(
-        "mount_efs.get_version_specific_stunnel_options",
-        return_value=(
-            stunnel_check_cert_hostname_supported,
-            stunnel_check_cert_validity_supported,
-        ),
+        "mount_efs.get_stunnel_options",
+        return_value=options,
     )
 
     if stunnel_check_cert_hostname is None:
@@ -274,8 +284,11 @@
     )
 
 
-def _test_disable_libwrap(
-    mocker, tmpdir, system_release="unknown", disable_libwrap=True
+def _test_enable_disable_libwrap(
+    mocker,
+    tmpdir,
+    system_release="unknown",
+    libwrap_supported=True,
 ):
     mocker.patch("mount_efs.add_stunnel_ca_options")
     ver_mocker = mocker.patch(
@@ -283,7 +296,7 @@
     )
 
     config_file = mount_efs.write_stunnel_config_file(
-        _get_config(mocker),
+        _get_config(mocker, 
stunnel_libwrap_option_supported=libwrap_supported),
         str(tmpdir),
         FS_ID,
         MOUNT_POINT,
@@ -299,7 +312,7 @@
     _validate_config(
         config_file,
         mount_efs.STUNNEL_GLOBAL_CONFIG,
-        _get_expected_efs_config(disable_libwrap=disable_libwrap),
+        _get_expected_efs_config(disable_libwrap=libwrap_supported),
     )
 
 
@@ -539,28 +552,12 @@
     )
 
 
-def test_write_stunnel_config_for_rhel8_disable_libwrap(mocker, tmpdir):
-    _test_disable_libwrap(
-        mocker,
-        tmpdir,
-        system_release="Red Hat Enterprise Linux release 8.0 (Ootpa)",
-        disable_libwrap=False,
-    )
-
-
-def test_write_stunnel_config_for_unknown_system_enable_libwrap(mocker, 
tmpdir):
-    _test_disable_libwrap(
-        mocker, tmpdir, system_release="unknown", disable_libwrap=True
-    )
+def test_write_stunnel_config_libwrap_not_supported(mocker, tmpdir):
+    _test_enable_disable_libwrap(mocker, tmpdir, libwrap_supported=False)
 
 
-def test_write_stunnel_config_for_non_rhel8_enable_libwrap(mocker, tmpdir):
-    _test_disable_libwrap(
-        mocker,
-        tmpdir,
-        system_release="Amazon Linux release 2 (Karoo)",
-        disable_libwrap=True,
-    )
+def test_write_stunnel_config_libwrap_supported(mocker, tmpdir):
+    _test_enable_disable_libwrap(mocker, tmpdir, libwrap_supported=True)
 
 
 def test_write_stunnel_config_with_fall_back_ip_address(mocker, tmpdir):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/efs-utils-1.31.3/test/watchdog_test/test_check_efs_mounts.py 
new/efs-utils-1.32.1/test/watchdog_test/test_check_efs_mounts.py
--- old/efs-utils-1.31.3/test/watchdog_test/test_check_efs_mounts.py    
2021-12-09 04:39:51.000000000 +0100
+++ new/efs-utils-1.32.1/test/watchdog_test/test_check_efs_mounts.py    
2022-04-01 22:34:12.000000000 +0200
@@ -45,6 +45,8 @@
         config = ConfigParser()
     config.add_section(mount_efs.CONFIG_SECTION)
     config.set(mount_efs.CONFIG_SECTION, "state_file_dir_mode", "750")
+    config.add_section(watchdog.CONFIG_SECTION)
+    config.set(watchdog.CONFIG_SECTION, "stunnel_health_check_enabled", 
"false")
     return config
 
 
@@ -75,7 +77,7 @@
 
 
 def create_state_file(tmpdir, content=json.dumps(STATE)):
-    state_file = tmpdir.join(tempfile.mktemp())
+    state_file = tmpdir.join(tempfile.mkstemp()[1])
     state_file.write(content, ensure=True)
 
     return state_file.dirname, state_file.basename
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/efs-utils-1.31.3/test/watchdog_test/test_check_stunnel_health.py 
new/efs-utils-1.32.1/test/watchdog_test/test_check_stunnel_health.py
--- old/efs-utils-1.31.3/test/watchdog_test/test_check_stunnel_health.py        
1970-01-01 01:00:00.000000000 +0100
+++ new/efs-utils-1.32.1/test/watchdog_test/test_check_stunnel_health.py        
2022-04-01 22:34:12.000000000 +0200
@@ -0,0 +1,286 @@
+#
+# Copyright 2017-2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
+#
+# Licensed under the MIT License. See the LICENSE accompanying this file
+# for the specific language governing permissions and limitations under
+# the License.
+#
+
+import json
+import subprocess
+import tempfile
+
+import watchdog
+from mock import MagicMock
+
+from .. import utils
+
+try:
+    import ConfigParser
+except ImportError:
+    from configparser import ConfigParser
+
+
+DEFAULT_MOUNT_POINT = "/mnt"
+FIXED_TIME = 1648627041.66836
+DEFAULT_MOUNT_TIME = (
+    FIXED_TIME - watchdog.DEFAULT_STUNNEL_HEALTH_CHECK_INTERVAL_MIN * 60 * 2 - 
1
+)
+DEFAULT_LAST_STUNNEL_CHECK_TIME = (
+    FIXED_TIME - watchdog.DEFAULT_STUNNEL_HEALTH_CHECK_INTERVAL_MIN * 60 - 1
+)
+DEFAULT_MOUNTS = {
+    "mnt": watchdog.Mount(
+        "127.0.0.1", DEFAULT_MOUNT_POINT, "nfs4", "port=12345", "0", "0"
+    ),
+}
+
+
+def setup_mocks(
+    mocker, mock_subprocess_success=False, mock_subprocess_timeout_sec=None
+):
+    check_time_mock = mocker.patch("time.time", return_value=FIXED_TIME)
+    popen_mock = None
+    if mock_subprocess_success:
+        process_mock = MagicMock()
+        process_mock.communicate.return_value = (
+            "stdout",
+            "stderr",
+        )
+        process_mock.returncode = 0
+        popen_mock = mocker.patch("subprocess.Popen", 
return_value=process_mock)
+    elif mock_subprocess_timeout_sec:
+        process_mock = MagicMock()
+        process_mock.communicate.side_effect = subprocess.TimeoutExpired(
+            "cmd", timeout=mock_subprocess_timeout_sec
+        )
+        popen_mock = mocker.patch("subprocess.Popen", 
return_value=process_mock)
+    return check_time_mock, popen_mock
+
+
+def _get_config(
+    stunnel_health_check_enabled=True,
+    stunnel_health_check_interval_min=5,
+    stunnel_health_check_command_timeout_sec=30,
+):
+    try:
+        config = ConfigParser.SafeConfigParser()
+    except AttributeError:
+        config = ConfigParser()
+
+    config.add_section(watchdog.CONFIG_SECTION)
+    config.set(
+        watchdog.CONFIG_SECTION,
+        "stunnel_health_check_enabled",
+        "true" if stunnel_health_check_enabled else "false",
+    )
+    config.set(
+        watchdog.CONFIG_SECTION,
+        "stunnel_health_check_interval_min",
+        str(stunnel_health_check_interval_min),
+    )
+    config.set(
+        watchdog.CONFIG_SECTION,
+        "stunnel_health_check_command_timeout_sec",
+        str(stunnel_health_check_command_timeout_sec),
+    )
+    return config
+
+
+def test_stunnel_health_not_checked_when_feature_disabled(mocker, tmpdir):
+    check_time_mock, _ = setup_mocks(mocker)
+    config = _get_config(stunnel_health_check_enabled=False)
+
+    state = {}
+    state_file = tmpdir.join(tempfile.mkstemp()[1])
+    state_file.write(json.dumps(state), ensure=True)
+    watchdog.check_stunnel_health(
+        config, state, state_file.dirname, state_file.basename, [], 
DEFAULT_MOUNTS
+    )
+    utils.assert_not_called(check_time_mock)
+
+
+def test_stunnel_health_not_checked_mount_time_not_exist(mocker, tmpdir):
+    check_time_mock, subprocess_mock = setup_mocks(mocker, 
mock_subprocess_success=True)
+    config = _get_config(stunnel_health_check_enabled=True)
+
+    state = {}
+    state_file = tmpdir.join(tempfile.mkstemp()[1])
+    state_file.write(json.dumps(state), ensure=True)
+    watchdog.check_stunnel_health(
+        config, state, state_file.dirname, state_file.basename, [], 
DEFAULT_MOUNTS
+    )
+    utils.assert_called_once(check_time_mock)
+    utils.assert_not_called(subprocess_mock)
+    with state_file.open() as f:
+        new_state = json.load(f)
+    assert FIXED_TIME == new_state["mount_time"]
+
+
+def test_stunnel_health_not_checked_when_mount_passed_short_time(mocker, 
tmpdir):
+    check_time_mock, subprocess_mock = setup_mocks(mocker, 
mock_subprocess_success=True)
+    config = _get_config(stunnel_health_check_enabled=True)
+
+    state = {"mount_time": FIXED_TIME - 1}
+    state_file = tmpdir.join(tempfile.mkstemp()[1])
+    state_file.write(json.dumps(state), ensure=True)
+    watchdog.check_stunnel_health(
+        config, state, state_file.dirname, state_file.basename, [], 
DEFAULT_MOUNTS
+    )
+    utils.assert_called_once(check_time_mock)
+    utils.assert_not_called(subprocess_mock)
+
+
+def test_stunnel_health_not_checked_when_last_stunnel_check_passed_short_time(
+    mocker, tmpdir
+):
+    check_time_mock, subprocess_mock = setup_mocks(mocker, 
mock_subprocess_success=True)
+    config = _get_config(stunnel_health_check_enabled=True)
+
+    state = {
+        "mount_time": DEFAULT_MOUNT_TIME,
+        "last_stunnel_check_time": FIXED_TIME
+        - watchdog.DEFAULT_STUNNEL_HEALTH_CHECK_INTERVAL_MIN * 60
+        + 1,
+    }
+    state_file = tmpdir.join(tempfile.mkstemp()[1])
+    state_file.write(json.dumps(state), ensure=True)
+    watchdog.check_stunnel_health(
+        config, state, state_file.dirname, state_file.basename, [], 
DEFAULT_MOUNTS
+    )
+    utils.assert_called_once(check_time_mock)
+    utils.assert_not_called(subprocess_mock)
+
+
+def test_stunnel_health_checked_passed_for_first_check(mocker, tmpdir):
+    check_time_mock, subprocess_mock = setup_mocks(mocker, 
mock_subprocess_success=True)
+    config = _get_config(stunnel_health_check_enabled=True)
+
+    state = {
+        "mount_time": DEFAULT_MOUNT_TIME,
+        "mountpoint": "/mnt",
+        "pid": 9999,
+    }
+    state_file = tmpdir.join(tempfile.mkstemp()[1])
+    state_file.write(json.dumps(state), ensure=True)
+    watchdog.check_stunnel_health(
+        config, state, state_file.dirname, state_file.basename, [], 
DEFAULT_MOUNTS
+    )
+
+    utils.assert_called_once(check_time_mock)
+    utils.assert_called_once(subprocess_mock)
+    with state_file.open() as f:
+        new_state = json.load(f)
+    assert FIXED_TIME == new_state["last_stunnel_check_time"]
+
+
+def test_stunnel_health_checked_passed_for_non_first_check_default_interval(
+    mocker, tmpdir
+):
+    config = _get_config(stunnel_health_check_enabled=True)
+    _test_stunnel_health_checked_passed_for_non_first_check_helper(
+        mocker, tmpdir, config
+    )
+
+
+def test_stunnel_health_checked_passed_for_non_first_check_short_interval(
+    mocker, tmpdir
+):
+    config = _get_config(
+        stunnel_health_check_enabled=True, stunnel_health_check_interval_min=1
+    )
+    _test_stunnel_health_checked_passed_for_non_first_check_helper(
+        mocker, tmpdir, config, last_stunnel_check_time=FIXED_TIME - 61
+    )
+
+
+def test_stunnel_health_failed_due_to_timeout_not_kill_stunnel(mocker, tmpdir):
+    _, subprocess_mock = setup_mocks(
+        mocker,
+        
mock_subprocess_timeout_sec=watchdog.DEFAULT_STUNNEL_HEALTH_CHECK_TIMEOUT_SEC,
+    )
+    config = _get_config(stunnel_health_check_enabled=True)
+
+    state = {
+        "mount_time": DEFAULT_MOUNT_TIME,
+        "mountpoint": "/mnt",
+        "pid": 9999,
+        "last_stunnel_check_time": DEFAULT_LAST_STUNNEL_CHECK_TIME,
+    }
+    state_file = tmpdir.join(tempfile.mkstemp()[1])
+    state_file.write(json.dumps(state), ensure=True)
+
+    mocker.patch("watchdog.is_pid_running", return_value=False)
+    watchdog.check_stunnel_health(
+        config, state, state_file.dirname, state_file.basename, [], 
DEFAULT_MOUNTS
+    )
+    utils.assert_called_once(subprocess_mock)
+
+
+def test_stunnel_health_failed_due_to_timeout_kill_stunnel(mocker, tmpdir):
+    _, subprocess_mock = setup_mocks(
+        mocker,
+        
mock_subprocess_timeout_sec=watchdog.DEFAULT_STUNNEL_HEALTH_CHECK_TIMEOUT_SEC,
+    )
+    config = _get_config(stunnel_health_check_enabled=True)
+
+    state = {
+        "mount_time": DEFAULT_MOUNT_TIME,
+        "mountpoint": "/mnt",
+        "pid": 9999,
+        "last_stunnel_check_time": DEFAULT_LAST_STUNNEL_CHECK_TIME,
+    }
+    state_file = tmpdir.join(tempfile.mkstemp()[1])
+    state_file.write(json.dumps(state), ensure=True)
+
+    mocker.patch("watchdog.is_pid_running", return_value=True)
+    mocker.patch("os.getpgid", return_value="fakepg")
+    kill_mock = mocker.patch("os.killpg")
+    restart_tls_tunnel_mock = mocker.patch("watchdog.restart_tls_tunnel")
+    watchdog.check_stunnel_health(
+        config, state, state_file.dirname, state_file.basename, [], 
DEFAULT_MOUNTS
+    )
+    utils.assert_called_once(subprocess_mock)
+    utils.assert_called_once(kill_mock)
+    utils.assert_called_once(restart_tls_tunnel_mock)
+
+
+def test_stunnel_health_checked_passed_for_non_first_check_no_mountpoint_info(
+    mocker, tmpdir
+):
+    config = _get_config(stunnel_health_check_enabled=True)
+    _test_stunnel_health_checked_passed_for_non_first_check_helper(
+        mocker, tmpdir, config, mountpoint=None
+    )
+
+
+def _test_stunnel_health_checked_passed_for_non_first_check_helper(
+    mocker,
+    tmpdir,
+    config,
+    mount_time=DEFAULT_MOUNT_TIME,
+    last_stunnel_check_time=DEFAULT_LAST_STUNNEL_CHECK_TIME,
+    mountpoint=DEFAULT_MOUNT_POINT,
+):
+    _, subprocess_mock = setup_mocks(mocker, mock_subprocess_success=True)
+    state = {
+        "mount_time": mount_time,
+        "pid": 9999,
+        "last_stunnel_check_time": last_stunnel_check_time,
+    }
+
+    if mountpoint:
+        state["mountpoint"] = mountpoint
+
+    state_file = tmpdir.join(tempfile.mkstemp()[1])
+    state_file.write(json.dumps(state), ensure=True)
+    watchdog.check_stunnel_health(
+        config, state, state_file.dirname, state_file.basename, [], 
DEFAULT_MOUNTS
+    )
+
+    utils.assert_called_once(subprocess_mock)
+    with state_file.open() as f:
+        new_state = json.load(f)
+    assert FIXED_TIME == new_state["last_stunnel_check_time"]
+    if not mountpoint:
+        assert mountpoint == new_state["mountpoint"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/efs-utils-1.31.3/test/watchdog_test/test_clean_up_mount_state.py 
new/efs-utils-1.32.1/test/watchdog_test/test_clean_up_mount_state.py
--- old/efs-utils-1.31.3/test/watchdog_test/test_clean_up_mount_state.py        
2021-12-09 04:39:51.000000000 +0100
+++ new/efs-utils-1.32.1/test/watchdog_test/test_clean_up_mount_state.py        
2022-04-01 22:34:12.000000000 +0200
@@ -18,7 +18,7 @@
 
 
 def create_temp_file(tmpdir, content=""):
-    temp_file = tmpdir.join(tempfile.mktemp())
+    temp_file = tmpdir.join(tempfile.mkstemp()[1])
     temp_file.write(content, ensure=True)
     return temp_file
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/efs-utils-1.31.3/test/watchdog_test/test_clean_up_previous_stunnel_pids.py 
new/efs-utils-1.32.1/test/watchdog_test/test_clean_up_previous_stunnel_pids.py
--- 
old/efs-utils-1.31.3/test/watchdog_test/test_clean_up_previous_stunnel_pids.py  
    2021-12-09 04:39:51.000000000 +0100
+++ 
new/efs-utils-1.32.1/test/watchdog_test/test_clean_up_previous_stunnel_pids.py  
    2022-04-01 22:34:12.000000000 +0200
@@ -40,7 +40,8 @@
 
 
 def create_state_file(tmpdir, content=json.dumps(STATE)):
-    state_file = tmpdir.join(tempfile.mktemp())
+    state_file = tmpdir.join(tempfile.mkstemp()[1])
+
     state_file.write(content, ensure=True)
 
     return state_file.dirname, state_file.basename
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/efs-utils-1.31.3/test/watchdog_test/test_helper_function.py 
new/efs-utils-1.32.1/test/watchdog_test/test_helper_function.py
--- old/efs-utils-1.31.3/test/watchdog_test/test_helper_function.py     
2021-12-09 04:39:51.000000000 +0100
+++ new/efs-utils-1.32.1/test/watchdog_test/test_helper_function.py     
2022-04-01 22:34:12.000000000 +0200
@@ -42,7 +42,7 @@
     if config_section:
         config.add_section(config_section)
         if config_item and config_item_value is not None:
-            config.set(config_section, config_item, config_item_value)
+            config.set(config_section, config_item, str(config_item_value))
     return config
 
 
@@ -297,3 +297,87 @@
 
     boto_session_mock.set_config_variable.assert_called_once()
     boto_session_mock.get_credentials.assert_called_once()
+
+
+def test_get_int_value_from_config_file():
+    config_section = watchdog.CONFIG_SECTION
+    config_item = "stunnel_health_check_interval_min"
+    config_value = watchdog.DEFAULT_STUNNEL_HEALTH_CHECK_INTERVAL_MIN + 1
+    config = get_config(config_section, config_item, config_value)
+    assert config_value == watchdog.get_int_value_from_config_file(
+        config, config_item, watchdog.DEFAULT_STUNNEL_HEALTH_CHECK_INTERVAL_MIN
+    )
+
+
+def test_get_int_value_from_config_file_not_positive_value():
+    config_section = watchdog.CONFIG_SECTION
+    config_item = "stunnel_health_check_interval_min"
+    config_value = 0
+    config = get_config(config_section, config_item, config_value)
+    assert (
+        watchdog.DEFAULT_STUNNEL_HEALTH_CHECK_INTERVAL_MIN
+        == watchdog.get_int_value_from_config_file(
+            config, config_item, 
watchdog.DEFAULT_STUNNEL_HEALTH_CHECK_INTERVAL_MIN
+        )
+    )
+
+
+def test_get_int_value_from_config_file_no_config_value():
+    config_item = "stunnel_health_check_interval_min"
+    config = get_config()
+    assert (
+        watchdog.DEFAULT_STUNNEL_HEALTH_CHECK_INTERVAL_MIN
+        == watchdog.get_int_value_from_config_file(
+            config, config_item, 
watchdog.DEFAULT_STUNNEL_HEALTH_CHECK_INTERVAL_MIN
+        )
+    )
+
+
+def test_get_int_value_from_config_file_wrong_type_value():
+    config_section = watchdog.CONFIG_SECTION
+    config_item = "stunnel_health_check_interval_min"
+    config_value = "false"
+    config = get_config(config_section, config_item, config_value)
+    assert (
+        watchdog.DEFAULT_STUNNEL_HEALTH_CHECK_INTERVAL_MIN
+        == watchdog.get_int_value_from_config_file(
+            config, config_item, 
watchdog.DEFAULT_STUNNEL_HEALTH_CHECK_INTERVAL_MIN
+        )
+    )
+
+
+def test_get_mountpoint_from_state_file_name():
+    state_file_name = "/var/run/efs/fs-deadbeef.home.efs.12345"
+    nfs_mounts = {
+        "mnt": watchdog.Mount("127.0.0.1", "/mnt", "nfs4", "port=12343", "0", 
"0"),
+        "mnt1": watchdog.Mount("127.0.0.1", "/mnt1", "nfs4", "port=12342", 
"0", "0"),
+        "home.efs": watchdog.Mount(
+            "127.0.0.1", "/home/efs", "nfs4", "port=12345", "0", "0"
+        ),
+    }
+    assert "/home/efs" == watchdog.get_mountpoint_from_nfs_mounts(
+        state_file_name, nfs_mounts
+    )
+
+    state_file_name = (
+        
"/var/run/efs/fs-deadbeef.var.lib.kubelet.pods.2cbe4183-2c36-4a37-9f72-7e3c1a67538c.volumes"
+        
".kubernetes.io~csi.pvc-008bf5dc-5859-482e-b8b9-0e5e6887e411.mount.12345"
+    )
+    nfs_mounts = {
+        "mnt": watchdog.Mount("127.0.0.1", "/mnt", "nfs4", "port=12343", "0", 
"0"),
+        "mnt1": watchdog.Mount("127.0.0.1", "/mnt1", "nfs4", "port=12342", 
"0", "0"),
+        "test": watchdog.Mount(
+            "127.0.0.1:/deadbeef/test-008bf5dc-5859-482e-b8b9-0e5e6887e411",
+            
"/var/lib/kubelet/pods/1234583-2c36-4a37-9f72-7e3c1a67538c/volumes/"
+            "kubernetes.io~csi/pvc-008bf5dc-5859-482e-b8b9-0e5e6887e411/mount",
+            "nfs4",
+            "port=12345",
+            "0",
+            "0",
+        ),
+    }
+    assert (
+        
"/var/lib/kubelet/pods/1234583-2c36-4a37-9f72-7e3c1a67538c/volumes/kubernetes.io~csi/pvc-008bf5dc-5859"
+        "-482e-b8b9-0e5e6887e411/mount"
+        == watchdog.get_mountpoint_from_nfs_mounts(state_file_name, nfs_mounts)
+    )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/efs-utils-1.31.3/test/watchdog_test/test_restart_tls_tunnel.py 
new/efs-utils-1.32.1/test/watchdog_test/test_restart_tls_tunnel.py
--- old/efs-utils-1.31.3/test/watchdog_test/test_restart_tls_tunnel.py  
2021-12-09 04:39:51.000000000 +0100
+++ new/efs-utils-1.32.1/test/watchdog_test/test_restart_tls_tunnel.py  
2022-04-01 22:34:12.000000000 +0200
@@ -21,7 +21,7 @@
 
     state = {"pid": 9999, "cmd": ""}
 
-    state_file = tmpdir.join(tempfile.mktemp())
+    state_file = tmpdir.join(tempfile.mkstemp()[1])
     state_file.write(json.dumps(state), ensure=True)
 
     watchdog.restart_tls_tunnel([], state, state_file.dirname, 
state_file.basename)
@@ -39,7 +39,7 @@
 
     state = {"pid": 9999, "cmd": "", "certificate": "foo/bar/certificate.pem"}
 
-    state_file = tmpdir.join(tempfile.mktemp())
+    state_file = tmpdir.join(tempfile.mkstemp()[1])
     state_file.write(json.dumps(state), ensure=True)
 
     watchdog.restart_tls_tunnel([], state, state_file.dirname, 
state_file.basename)

Reply via email to