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 2024-02-16 21:42:49
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/aws-efs-utils (Old)
 and      /work/SRC/openSUSE:Factory/.aws-efs-utils.new.1815 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "aws-efs-utils"

Fri Feb 16 21:42:49 2024 rev:16 rq:1147098 version:1.35.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/aws-efs-utils/aws-efs-utils.changes      
2023-04-01 19:32:15.377351941 +0200
+++ /work/SRC/openSUSE:Factory/.aws-efs-utils.new.1815/aws-efs-utils.changes    
2024-02-16 21:42:54.550898560 +0100
@@ -1,0 +2,14 @@
+Tue Feb 13 14:39:45 UTC 2024 - John Paul Adrian Glaubitz 
<adrian.glaub...@suse.com>
+
+- Update to version 1.35.1
+  * Revert openssl requirement change
+  * Revert "Update EFS Documentation: Clarify Current FIPS Compliance Status"
+  * Update EFS Documentation: Clarify Current FIPS Compliance Status
+  * test: Change repo urls in eol debian9 build
+  * Check private key file size to skip generation
+  * test: Fix pytest that failed since commit 3dd89ca
+  * Fix should_check_efs_utils_version scope
+  * Add warning if using old version
+  * Add 'fsap' option as EFS-only option
+
+-------------------------------------------------------------------

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

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

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

Other differences:
------------------
++++++ aws-efs-utils.spec ++++++
--- /var/tmp/diff_new_pack.6hS31e/_old  2024-02-16 21:42:55.542934354 +0100
+++ /var/tmp/diff_new_pack.6hS31e/_new  2024-02-16 21:42:55.546934499 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package aws-efs-utils
 #
-# Copyright (c) 2023 SUSE LLC
+# Copyright (c) 2024 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           aws-efs-utils
-Version:        1.35.0
+Version:        1.35.1
 Release:        0
 Summary:        Utilities for using the EFS file systems
 License:        MIT

++++++ efs-utils-1.35.0.tar.gz -> efs-utils-1.35.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/efs-utils-1.35.0/.circleci/config.yml 
new/efs-utils-1.35.1/.circleci/config.yml
--- old/efs-utils-1.35.0/.circleci/config.yml   2023-03-16 19:07:54.000000000 
+0100
+++ new/efs-utils-1.35.1/.circleci/config.yml   2024-01-18 16:57:36.000000000 
+0100
@@ -33,7 +33,6 @@
           path: build
   build-deb:
     steps:
-      - checkout
       - run:
           name: Repo update
           command: |
@@ -41,7 +40,12 @@
       - run:
           name: Install dependencies
           command: |
-            apt-get -y install binutils
+            apt-get -y install binutils git
+      - run:
+          name: Add local build repo as safe git directory
+          command: |
+            git config --global --add safe.directory 
/tmp/_circleci_local_build_repo
+      - checkout
       - run:
           name: Build DEB
           command: |
@@ -112,6 +116,14 @@
         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-*
+  build-debian-eol-repo:
+    steps:
+      - run:
+          name: change repo url to archive.debian.org and remove updates repo 
for EOL versions
+          command: |
+            sed -i 's/deb.debian.org/archive.debian.org/g' 
/etc/apt/sources.list
+            sed -i 's/security.debian.org/archive.debian.org/g' 
/etc/apt/sources.list
+            sed -i '/stretch-updates/d' /etc/apt/sources.list
 jobs:
   test:
     parameters:
@@ -159,6 +171,16 @@
     steps:
       - build-centos-repo
       - build-rpm
+  build-debian-eol-rpm-package:
+    parameters:
+      image:
+        type: string
+    executor:
+      name: linux
+      image: << parameters.image >>
+    steps:
+      - build-debian-eol-repo
+      - build-deb
 workflows:
   workflow:
     jobs:
@@ -195,7 +217,7 @@
       - build-deb-package:
           name: ubuntu22
           image: ubuntu:22.04
-      - build-deb-package:
+      - build-debian-eol-rpm-package:
           name: debian9
           image: debian:stretch
       - build-deb-package:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/efs-utils-1.35.0/README.md 
new/efs-utils-1.35.1/README.md
--- old/efs-utils-1.35.0/README.md      2023-03-16 19:07:54.000000000 +0100
+++ new/efs-utils-1.35.1/README.md      2024-01-18 16:57:36.000000000 +0100
@@ -10,6 +10,7 @@
 |----------------------| ----- | --------- |
 | Amazon Linux 2017.09 | `rpm` | `upstart` |
 | Amazon Linux 2       | `rpm` | `systemd` |
+| Amazon Linux 2023    | `rpm` | `systemd` |
 | CentOS 7             | `rpm` | `systemd` |
 | CentOS 8             | `rpm` | `systemd` |
 | RHEL 7               | `rpm`| `systemd` |
@@ -72,6 +73,7 @@
   - [The way to access instance metadata](#the-way-to-access-instance-metadata)
   - [Use the assumed profile credentials for 
IAM](#use-the-assumed-profile-credentials-for-iam)
   - [Enabling FIPS Mode](#enabling-fips-mode)
+  - [Disabling Version Check](#disabling-version-check)
   - [License Summary](#license-summary)
 
 
@@ -558,6 +560,18 @@
 
 For more information on how to configure OpenSSL with FIPS see the [OpenSSL 
FIPS README](https://github.com/openssl/openssl/blob/master/README-FIPS.md).
 
+## Disabling Version Check
+By default, once an hour, the watchdog daemon service will check to see if a 
newer version of amazon-efs-utils is available on github or yum.
+You can disable this check by setting the `enable_version_check` field in 
`/etc/amazon/efs/efs-utils.conf` to `false`. For example, 
+```bash
+sudo sed -i 's/enable_version_check = true/enable_version_check = false/' 
/etc/amazon/efs/efs-utils.conf
+```  
+Or on MacOS:  
+```bash
+VERSION=<efs-utils version, e.g. 1.34.1>
+sudo sed -i 's/enable_version_check = true/enable_version_check = false/' 
/usr/local/Cellar/amazon-efs-utils/${VERSION}/libexec/etc/amazon/efs/efs-utils.conf
+```
+
 ## License Summary
 
 This code is made available under the MIT license.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/efs-utils-1.35.0/amazon-efs-utils.spec 
new/efs-utils-1.35.1/amazon-efs-utils.spec
--- old/efs-utils-1.35.0/amazon-efs-utils.spec  2023-03-16 19:07:54.000000000 
+0100
+++ new/efs-utils-1.35.1/amazon-efs-utils.spec  2024-01-18 16:57:36.000000000 
+0100
@@ -35,7 +35,7 @@
 %endif
 
 Name      : amazon-efs-utils
-Version   : 1.35.0
+Version   : 1.35.1
 Release   : 1%{platform}
 Summary   : This package provides utilities for simplifying the use of EFS 
file systems
 
@@ -53,6 +53,7 @@
 Requires  : stunnel >= 4.56
 %endif
 Requires  : %{python_requires}
+
 Requires  : openssl >= 1.0.2
 Requires  : util-linux
 Requires  : which
@@ -137,6 +138,12 @@
 %clean
 
 %changelog
+* Wed Jan 10 2024 Sean Zatz <zat...@amazon.com> - 1.35.1
+- Add 'fsap' to ignored mount option list
+- Accept openssl 3.0 in rpm spec file
+- Watchdog now prints a log message if efs-utils is on an old version
+- Regenerate the private key if the file is empty
+
 * Wed Mar 15 2023 Soyeon Ju <mjsoy...@amazon.com> - 1.35.0
 - Support MacOS Ventura, Oracle8 distribution
 - Add debug statement for size of state file write
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/efs-utils-1.35.0/build-deb.sh 
new/efs-utils-1.35.1/build-deb.sh
--- old/efs-utils-1.35.0/build-deb.sh   2023-03-16 19:07:54.000000000 +0100
+++ new/efs-utils-1.35.1/build-deb.sh   2024-01-18 16:57:36.000000000 +0100
@@ -11,7 +11,7 @@
 
 BASE_DIR=$(pwd)
 BUILD_ROOT=${BASE_DIR}/build/debbuild
-VERSION=1.35.0
+VERSION=1.35.1
 RELEASE=1
 DEB_SYSTEM_RELEASE_PATH=/etc/os-release
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/efs-utils-1.35.0/config.ini 
new/efs-utils-1.35.1/config.ini
--- old/efs-utils-1.35.0/config.ini     2023-03-16 19:07:54.000000000 +0100
+++ new/efs-utils-1.35.1/config.ini     2024-01-18 16:57:36.000000000 +0100
@@ -7,5 +7,5 @@
 #
 
 [global]
-version=1.35.0
+version=1.35.1
 release=1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/efs-utils-1.35.0/dist/amazon-efs-utils.control 
new/efs-utils-1.35.1/dist/amazon-efs-utils.control
--- old/efs-utils-1.35.0/dist/amazon-efs-utils.control  2023-03-16 
19:07:54.000000000 +0100
+++ new/efs-utils-1.35.1/dist/amazon-efs-utils.control  2024-01-18 
16:57:36.000000000 +0100
@@ -1,6 +1,6 @@
 Package: amazon-efs-utils
 Architecture: all
-Version: 1.35.0
+Version: 1.35.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.35.0/dist/efs-utils.conf 
new/efs-utils-1.35.1/dist/efs-utils.conf
--- old/efs-utils-1.35.0/dist/efs-utils.conf    2023-03-16 19:07:54.000000000 
+0100
+++ new/efs-utils-1.35.1/dist/efs-utils.conf    2024-01-18 16:57:36.000000000 
+0100
@@ -88,6 +88,10 @@
 stunnel_health_check_interval_min = 5
 stunnel_health_check_command_timeout_sec = 30
 
+# By default, once an hour, the watchdog process will check the latest version 
of amazon-efs-utils available
+# on yum and github.  If we detect that the currently installed version is 
outdated, we'll log a warning.
+enable_version_check = true
+
 [cloudwatch-log]
 # enabled = true
 log_group_name = /aws/efs/utils
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/efs-utils-1.35.0/src/mount_efs/__init__.py 
new/efs-utils-1.35.1/src/mount_efs/__init__.py
--- old/efs-utils-1.35.0/src/mount_efs/__init__.py      2023-03-16 
19:07:54.000000000 +0100
+++ new/efs-utils-1.35.1/src/mount_efs/__init__.py      2024-01-18 
16:57:36.000000000 +0100
@@ -85,7 +85,7 @@
     BOTOCORE_PRESENT = False
 
 
-VERSION = "1.35.0"
+VERSION = "1.35.1"
 SERVICE = "elasticfilesystem"
 
 AMAZON_LINUX_2_RELEASE_ID = "Amazon Linux release 2 (Karoo)"
@@ -238,6 +238,7 @@
     "verify",
     "rolearn",
     "jwtpath",
+    "fsap",
 ]
 
 UNSUPPORTED_OPTIONS = ["capath"]
@@ -1623,11 +1624,11 @@
         cert_details["privateKey"] = get_private_key_path()
         cert_details["fsId"] = fs_id
 
-        start_watchdog(init_system)
-
         if not os.path.exists(state_file_dir):
             create_required_directory(config, state_file_dir)
 
+        start_watchdog(init_system)
+
         verify_level = int(options.get("verify", DEFAULT_STUNNEL_VERIFY_LEVEL))
         ocsp_enabled = is_ocsp_enabled(config, options)
 
@@ -1760,7 +1761,6 @@
 
 
 def mount_nfs(config, dns_name, path, mountpoint, options, 
fallback_ip_address=None):
-
     if "tls" in options:
         mount_path = "127.0.0.1:%s" % path
     elif fallback_ip_address:
@@ -1826,7 +1826,7 @@
 ):
     def backoff_function(i):
         """Backoff exponentially and add a constant 0-1 second jitter"""
-        return (1.5 ** i) + random.random()
+        return (1.5**i) + random.random()
 
     if not get_boolean_config_item_value(
         config, CONFIG_SECTION, "retry_nfs_mount_command", default_value=True
@@ -2089,12 +2089,15 @@
     not_before = get_certificate_timestamp(current_time, 
minutes=-NOT_BEFORE_MINS)
     not_after = get_certificate_timestamp(current_time, hours=NOT_AFTER_HOURS)
 
-    cmd = "openssl ca -startdate %s -enddate %s -selfsign -batch -notext 
-config %s -in %s -out %s" % (
-        not_before,
-        not_after,
-        certificate_config,
-        certificate_signing_request,
-        certificate,
+    cmd = (
+        "openssl ca -startdate %s -enddate %s -selfsign -batch -notext -config 
%s -in %s -out %s"
+        % (
+            not_before,
+            not_after,
+            certificate_config,
+            certificate_signing_request,
+            certificate,
+        )
     )
     subprocess_call(cmd, "Failed to create self-signed client-side 
certificate")
     return current_time.strftime(CERT_DATETIME_FORMAT)
@@ -2147,7 +2150,13 @@
 
     def generate_key():
         if os.path.isfile(key):
-            return
+            # If the openssl genpkey command is interrupted or isn't 
successful,
+            # it will leave behind an empty file.
+            if os.path.getsize(key) == 0:
+                logging.warning("Purging empty private key file")
+                os.remove(key)
+            else:
+                return
 
         cmd = (
             "openssl genpkey -algorithm RSA -out %s -pkeyopt 
rsa_keygen_bits:3072" % key
@@ -3664,7 +3673,6 @@
 # NFS client might see a throughput drop in kernel 5.4+, especially for 
sequential read.
 # To fix the issue, below function will modify read_ahead_kb to 15 * rsize 
(1MB by default) after mount.
 def optimize_readahead_window(mountpoint, options, config):
-
     if not should_revise_readahead(config):
         return
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/efs-utils-1.35.0/src/watchdog/__init__.py 
new/efs-utils-1.35.1/src/watchdog/__init__.py
--- old/efs-utils-1.35.0/src/watchdog/__init__.py       2023-03-16 
19:07:54.000000000 +0100
+++ new/efs-utils-1.35.1/src/watchdog/__init__.py       2024-01-18 
16:57:36.000000000 +0100
@@ -56,13 +56,14 @@
     AMAZON_LINUX_2_RELEASE_ID,
     AMAZON_LINUX_2_PRETTY_NAME,
 ]
-VERSION = "1.35.0"
+VERSION = "1.35.1"
 SERVICE = "elasticfilesystem"
 
 CONFIG_FILE = "/etc/amazon/efs/efs-utils.conf"
 CONFIG_SECTION = "mount-watchdog"
 MOUNT_CONFIG_SECTION = "mount"
 CLIENT_INFO_SECTION = "client-info"
+ENABLE_VERSION_CHECK = "enable_version_check"
 CLIENT_SOURCE_STR_LEN_LIMIT = 100
 DISABLE_FETCH_EC2_METADATA_TOKEN_ITEM = "disable_fetch_ec2_metadata_token"
 DEFAULT_UNKNOWN_VALUE = "unknown"
@@ -75,6 +76,7 @@
 
 STATE_FILE_DIR = "/var/run/efs"
 STUNNEL_PID_FILE = "stunnel.pid"
+LAST_VERSION_CHECK_FILE = "last_version_check.json"
 
 DEFAULT_NFS_PORT = "2049"
 PRIVATE_KEY_FILE = "/etc/amazon/efs/privateKey.pem"
@@ -182,6 +184,255 @@
 STUNNEL_INSTALLATION_MESSAGE = "Please install it following the instructions 
at: 
https://docs.aws.amazon.com/efs/latest/ug/using-amazon-efs-utils.html#upgrading-stunnel";
 
 
+def check_if_platform_is_mac():
+    return sys.platform in MAC_OS_PLATFORM_LIST
+
+
+def get_system_release_version():
+    # MacOS does not maintain paths /etc/os-release and /etc/sys-release
+    if check_if_platform_is_mac():
+        return platform.platform()
+
+    try:
+        with open(SYSTEM_RELEASE_PATH) as f:
+            return f.read().strip()
+    except IOError:
+        logging.debug("Unable to read %s", SYSTEM_RELEASE_PATH)
+
+    try:
+        with open(OS_RELEASE_PATH) as f:
+            for line in f:
+                if "PRETTY_NAME" in line:
+                    return line.split("=")[1].strip()
+    except IOError:
+        logging.debug("Unable to read %s", OS_RELEASE_PATH)
+
+    return DEFAULT_UNKNOWN_VALUE
+
+
+class Version:
+    """This class is used for the version check logic.  An instance of this 
class represents
+    a semantic version following the format major.minor.patch.  It is useful 
for comparing versions.
+    """
+
+    def __init__(self, version_str):
+        self.version_str = version_str
+
+        # The version list will have the format [major, minor, patch]
+        self.version = version_str.split(".")
+        if len(self.version) != 3:
+            raise ValueError(
+                "Version class must be instantiated with a version string that 
follows the format 'major.minor.patch'."
+            )
+
+    def __validate_comparison_input(self, other):
+        """Assert that other has type Version"""
+        if not isinstance(other, self.__class__):
+            raise TypeError(
+                "Version comparisons are only permitted between Version 
instances."
+            )
+
+    def __lt__(self, other):
+        """returns True if self < other"""
+        self.__validate_comparison_input(other)
+        return (not self.__eq__(other)) and (not self.__gt__(other))
+
+    def __gt__(self, other):
+        """returns True if self > other"""
+        self.__validate_comparison_input(other)
+        return self.version > other.version
+
+    def __eq__(self, other):
+        """returns True if self == other"""
+        self.__validate_comparison_input(other)
+        return self.version == other.version
+
+    def __str__(self):
+        return self.version_str
+
+
+class EFSUtilsVersionChecker:
+    GITHUB_TIMEOUT_SEC = 0.300
+    VERSION_CHECK_POLL_INTERVAL_SEC = 3600
+    VERSION_CHECK_FILE_KEY = "time"
+    GITHUB_TAG_API_URL = "https://api.github.com/repos/aws/efs-utils/tags";
+    SHOULD_CHECK_AMZN_REPOS = "Amazon Linux" in get_system_release_version()
+
+    @staticmethod
+    def get_latest_version_by_github():
+        """Queries the github api and returns a string with the latest tag 
(version) for efs-utils in the form of (e.g.) 1.34.5"""
+        logging.debug("Querying github for the latest amazon-efs-utils 
version")
+        with urlopen(
+            EFSUtilsVersionChecker.GITHUB_TAG_API_URL,
+            timeout=EFSUtilsVersionChecker.GITHUB_TIMEOUT_SEC,
+        ) as response:
+            html = response.read()
+            string = html.decode("utf-8")
+            json_obj = json.loads(string)
+            latest_version_dict = json_obj[0]
+            latest_version_str = latest_version_dict["name"]
+            logging.debug(
+                "Latest amazon-efs-utils version found on github: "
+                + latest_version_str[1:]
+            )
+            return latest_version_str[1:]
+
+    @staticmethod
+    def get_latest_version_by_yum():
+        """
+        Queries yum and returns a string with the latest tag (version) for 
efs-utils in the form of (e.g.) 1.34.5.
+        Returns an empty string if amazon-efs-utils is not available on Yum
+        """
+        logging.debug("Querying yum for the latest amazon-efs-utils version")
+        ps_yum = subprocess.Popen(
+            ["yum", "info", "amazon-efs-utils"],
+            stdout=subprocess.PIPE,
+        )
+        ps_grep = subprocess.Popen(
+            ["grep", "Available Packages", "-A", "4"],
+            stdin=ps_yum.stdout,
+            stdout=subprocess.PIPE,
+        )
+        latest_version_str = subprocess.check_output(
+            ["awk", "/Version/ {printf $3}"], stdin=ps_grep.stdout
+        ).decode("utf-8")
+
+        if not latest_version_str:
+            logging.debug("amazon-efs-utils was not found by yum")
+            return ""
+
+        logging.debug(
+            "Latest amazon-efs-utils version found on yum: " + 
latest_version_str
+        )
+        return latest_version_str
+
+    @staticmethod
+    def warn_newer_version_available_yum(current_version, newer_version):
+        message = (
+            "We recommend you upgrade to the latest version of efs-utils by 
running 'yum update amazon-efs-utils'. "
+            + "Current version: "
+            + str(current_version)
+            + ". Latest version: "
+            + str(newer_version)
+        )
+        logging.warning(message)
+
+    @staticmethod
+    def warn_newer_version_available_github(current_version, newer_version):
+        message = (
+            "We recommend you install the latest version of efs-utils from 
github. "
+            + "Current version: "
+            + str(current_version)
+            + ". Latest version: "
+            + str(newer_version)
+        )
+        logging.warning(message)
+
+    @staticmethod
+    def get_last_version_check_time():
+        """
+        Return the date that the last amazon-efs-utils version check was 
performed.
+        Returns None if the version check file does not exist (indicates check 
hasn't happened yet).
+        """
+        version_check_file = os.path.join(STATE_FILE_DIR, 
LAST_VERSION_CHECK_FILE)
+        if not os.path.exists(version_check_file):
+            return None
+
+        with open(version_check_file, "r") as f:
+            data = json.load(f)
+            if EFSUtilsVersionChecker.VERSION_CHECK_FILE_KEY not in data:
+                return None
+            last_version_check_time = datetime.strptime(
+                data[EFSUtilsVersionChecker.VERSION_CHECK_FILE_KEY],
+                CERT_DATETIME_FORMAT,
+            )
+
+        return last_version_check_time
+
+    @staticmethod
+    def version_check_ready():
+        """Inspect the last version check file and return true if the time 
since last version check
+        is greater than VERSION_CHECK_POLL_INTERVAL"""
+        last_version_check_time = 
EFSUtilsVersionChecker.get_last_version_check_time()
+        if not last_version_check_time:
+            return True
+
+        elapsed_seconds = (get_utc_now() - 
last_version_check_time).total_seconds()
+        return elapsed_seconds >= 
EFSUtilsVersionChecker.VERSION_CHECK_POLL_INTERVAL_SEC
+
+    @staticmethod
+    def update_version_check_file():
+        """Write current time into the version check file"""
+        current_time_str = get_utc_now().strftime(CERT_DATETIME_FORMAT)
+        dictionary = {
+            EFSUtilsVersionChecker.VERSION_CHECK_FILE_KEY: current_time_str,
+        }
+
+        if not os.path.exists(STATE_FILE_DIR):
+            logging.warning(
+                "update_version_check_file failed: "
+                + str(STATE_FILE_DIR)
+                + " does not exist."
+            )
+            return
+
+        with open(os.path.join(STATE_FILE_DIR, LAST_VERSION_CHECK_FILE), "w+") 
as f:
+            json.dump(dictionary, f)
+
+    @staticmethod
+    def check_if_using_old_version(current_version_string):
+        """Log a warning and print to console if newer version of 
amazon-efs-utils is available.
+        The check will first query yum, and then if that fails,
+        it will pull the latest tag from the github api.
+        """
+        current_version = Version(current_version_string)
+
+        if EFSUtilsVersionChecker.SHOULD_CHECK_AMZN_REPOS:
+            try:
+                latest_yum_version = Version(
+                    EFSUtilsVersionChecker.get_latest_version_by_yum()
+                )
+                if latest_yum_version > current_version:
+                    EFSUtilsVersionChecker.warn_newer_version_available_yum(
+                        current_version, latest_yum_version
+                    )
+                    EFSUtilsVersionChecker.update_version_check_file()
+                    return
+            except Exception as err:
+                logging.debug(
+                    "Failed to query Yum for latest version of 
amazon-efs-utils. "
+                    + str(err)
+                )
+                pass
+
+        try:
+            latest_github_version = Version(
+                EFSUtilsVersionChecker.get_latest_version_by_github()
+            )
+            if latest_github_version > current_version:
+                EFSUtilsVersionChecker.warn_newer_version_available_github(
+                    current_version, latest_github_version
+                )
+        except Exception as err:
+            logging.debug(
+                "Failed to query Github for latest version of 
amazon-efs-utils.  This is expected when Github is not reachable. "
+                + str(err)
+            )
+            pass
+
+        EFSUtilsVersionChecker.update_version_check_file()
+
+    @staticmethod
+    def should_check_efs_utils_version(config):
+        """Returns True if a customer has enabled the amazon-efs-utils version 
check,
+        and if the last version check occurred more than 
VERSION_CHECK_POLL_INTERVAL seconds ago.
+        """
+        version_check_enabled = get_boolean_config_item_value(
+            config, CONFIG_SECTION, ENABLE_VERSION_CHECK, default_value=True
+        )
+        return version_check_enabled and 
EFSUtilsVersionChecker.version_check_ready()
+
+
 def fatal_error(user_message, log_message=None):
     if log_message is None:
         log_message = user_message
@@ -714,7 +965,6 @@
 
 
 def get_nfs_mount_options_on_macos(mount_point, mount_server="127.0.0.1:/"):
-
     if not mount_point:
         logging.warning("Unable to get local mount options with empty mount 
point")
         return None
@@ -869,32 +1119,6 @@
         return False
 
 
-def check_if_platform_is_mac():
-    return sys.platform in MAC_OS_PLATFORM_LIST
-
-
-def get_system_release_version():
-    # MacOS does not maintain paths /etc/os-release and /etc/sys-release
-    if check_if_platform_is_mac():
-        return platform.platform()
-
-    try:
-        with open(SYSTEM_RELEASE_PATH) as f:
-            return f.read().strip()
-    except IOError:
-        logging.debug("Unable to read %s", SYSTEM_RELEASE_PATH)
-
-    try:
-        with open(OS_RELEASE_PATH) as f:
-            for line in f:
-                if "PRETTY_NAME" in line:
-                    return line.split("=")[1].strip()
-    except IOError:
-        logging.debug("Unable to read %s", OS_RELEASE_PATH)
-
-    return DEFAULT_UNKNOWN_VALUE
-
-
 def find_command_path(command, install_method):
     # If not running on macOS, use linux paths
     if not check_if_platform_is_mac():
@@ -1539,12 +1763,15 @@
     not_before = get_certificate_timestamp(current_time, 
minutes=-NOT_BEFORE_MINS)
     not_after = get_certificate_timestamp(current_time, hours=NOT_AFTER_HOURS)
 
-    cmd = "openssl ca -startdate %s -enddate %s -selfsign -batch -notext 
-config %s -in %s -out %s" % (
-        not_before,
-        not_after,
-        certificate_config,
-        certificate_signing_request,
-        certificate,
+    cmd = (
+        "openssl ca -startdate %s -enddate %s -selfsign -batch -notext -config 
%s -in %s -out %s"
+        % (
+            not_before,
+            not_after,
+            certificate_config,
+            certificate_signing_request,
+            certificate,
+        )
     )
     subprocess_call(cmd, "Failed to create self-signed client-side 
certificate")
     return current_time.strftime(CERT_DATETIME_FORMAT)
@@ -1599,8 +1826,10 @@
 
     def generate_key():
         if os.path.isfile(key):
+            # If the openssl genpkey command is interrupted or isn't 
successful,
+            # it will leave behind an empty file.
             if os.path.getsize(key) == 0:
-                logging.info("Purging empty private key file")
+                logging.warning("Purging empty private key file")
                 os.remove(key)
             else:
                 return
@@ -2149,6 +2378,9 @@
             )
             check_child_procs(child_procs)
 
+            if EFSUtilsVersionChecker.should_check_efs_utils_version(config):
+                EFSUtilsVersionChecker.check_if_using_old_version(VERSION)
+
             time.sleep(poll_interval_sec)
     else:
         logging.info("amazon-efs-mount-watchdog is not enabled")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/efs-utils-1.35.0/test/mount_efs_test/test_create_self_signed_cert.py 
new/efs-utils-1.35.1/test/mount_efs_test/test_create_self_signed_cert.py
--- old/efs-utils-1.35.0/test/mount_efs_test/test_create_self_signed_cert.py    
2023-03-16 19:07:54.000000000 +0100
+++ new/efs-utils-1.35.1/test/mount_efs_test/test_create_self_signed_cert.py    
2024-01-18 16:57:36.000000000 +0100
@@ -711,3 +711,25 @@
     )
 
     assert full_config_body == matching_config_body
+
+
+def test_check_and_create_private_key_key_was_empty(mocker, tmpdir):
+    pk_path = _get_mock_private_key_path(mocker, tmpdir)
+    with open(pk_path, "w") as pk_file:
+        pass
+
+    state_file_dir = str(tmpdir)
+    mount_efs.check_and_create_private_key(state_file_dir)
+    assert os.path.getsize(pk_path) > 0
+
+
+def test_check_and_create_private_key_key_already_exists(mocker, tmpdir):
+    pk_path = _get_mock_private_key_path(mocker, tmpdir)
+    with open(pk_path, "w") as pk_file:
+        pk_file.write("private key file contents")
+
+    call_mock = mocker.patch("mount_efs.subprocess_call")
+
+    state_file_dir = str(tmpdir)
+    mount_efs.check_and_create_private_key(state_file_dir)
+    assert call_mock.call_count == 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/efs-utils-1.35.0/test/mount_efs_test/test_get_nfs_mount_options.py 
new/efs-utils-1.35.1/test/mount_efs_test/test_get_nfs_mount_options.py
--- old/efs-utils-1.35.0/test/mount_efs_test/test_get_nfs_mount_options.py      
2023-03-16 19:07:54.000000000 +0100
+++ new/efs-utils-1.35.1/test/mount_efs_test/test_get_nfs_mount_options.py      
2024-01-18 16:57:36.000000000 +0100
@@ -91,6 +91,12 @@
     assert "tls" not in nfs_opts
 
 
+def test_fsap_efs_only():
+    nfs_opts = mount_efs.get_nfs_mount_options({"fsap": None})
+
+    assert "fsap" not in nfs_opts
+
+
 def test_get_default_nfs_mount_options_macos(mocker):
     mocker.patch("mount_efs.check_if_platform_is_mac", return_value=True)
     nfs_opts = mount_efs.get_nfs_mount_options({})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/efs-utils-1.35.0/test/mount_efs_test/test_write_stunnel_config_file.py 
new/efs-utils-1.35.1/test/mount_efs_test/test_write_stunnel_config_file.py
--- old/efs-utils-1.35.0/test/mount_efs_test/test_write_stunnel_config_file.py  
2023-03-16 19:07:54.000000000 +0100
+++ new/efs-utils-1.35.1/test/mount_efs_test/test_write_stunnel_config_file.py  
2024-01-18 16:57:36.000000000 +0100
@@ -41,7 +41,6 @@
     stunnel_libwrap_option_supported=True,
     fips_mode_enabled=False,
 ):
-
     options = []
     if stunnel_check_cert_hostname_supported:
         options.append(b"checkHost              = peer certificate host name 
pattern")
@@ -163,7 +162,6 @@
     disable_libwrap=True,
     fallback_ip_address=None,
 ):
-
     expected_efs_config = dict(mount_efs.STUNNEL_EFS_CONFIG)
     expected_efs_config["accept"] = expected_efs_config["accept"] % port
     if not fallback_ip_address:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/efs-utils-1.35.0/test/watchdog_test/test_check_if_using_old_version.py 
new/efs-utils-1.35.1/test/watchdog_test/test_check_if_using_old_version.py
--- old/efs-utils-1.35.0/test/watchdog_test/test_check_if_using_old_version.py  
1970-01-01 01:00:00.000000000 +0100
+++ new/efs-utils-1.35.1/test/watchdog_test/test_check_if_using_old_version.py  
2024-01-18 16:57:36.000000000 +0100
@@ -0,0 +1,200 @@
+# 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 logging
+import tempfile
+from datetime import date, datetime
+
+import pytest
+
+import watchdog
+
+try:
+    import ConfigParser
+except ImportError:
+    from configparser import ConfigParser
+
+OLD_VERSION = "1.34.3"
+GITHUB_VERSION = "1.35.9"
+YUM_VERSION = "1.35.8"
+
+CERT_DATETIME_FORMAT = "%y%m%d%H%M%SZ"
+
+
+def test_check_if_using_old_version_yum_works(mocker, caplog):
+    mocker.patch(
+        "watchdog.EFSUtilsVersionChecker.get_latest_version_by_yum",
+        return_value=YUM_VERSION,
+    )
+    mocker.patch(
+        "watchdog.EFSUtilsVersionChecker.get_latest_version_by_github",
+        return_value=GITHUB_VERSION,
+    )
+    mocker.patch("watchdog.EFSUtilsVersionChecker.update_version_check_file")
+    mocker.patch(
+        "watchdog.EFSUtilsVersionChecker.SHOULD_CHECK_AMZN_REPOS",
+        return_value=True,
+    )
+
+    with caplog.at_level(logging.INFO):
+        watchdog.EFSUtilsVersionChecker.check_if_using_old_version(OLD_VERSION)
+    assert (
+        "We recommend you upgrade to the latest version of efs-utils by 
running 'yum update amazon-efs-utils'."
+        in caplog.text
+    )
+    assert YUM_VERSION in caplog.text
+
+
+def test_check_if_using_old_version_yum_fails(mocker, caplog):
+    mocker.patch(
+        "watchdog.EFSUtilsVersionChecker.get_latest_version_by_yum",
+        side_effect=TimeoutError,
+    )
+    mocker.patch(
+        "watchdog.EFSUtilsVersionChecker.get_latest_version_by_github",
+        return_value=GITHUB_VERSION,
+    )
+    mocker.patch("watchdog.EFSUtilsVersionChecker.update_version_check_file")
+
+    with caplog.at_level(logging.INFO):
+        watchdog.EFSUtilsVersionChecker.check_if_using_old_version(OLD_VERSION)
+
+    assert (
+        "We recommend you install the latest version of efs-utils from github"
+        in caplog.text
+    )
+    assert GITHUB_VERSION in caplog.text
+
+
+def test_check_if_using_old_version_yum_github_fail(mocker, caplog):
+    mocker.patch(
+        "watchdog.EFSUtilsVersionChecker.get_latest_version_by_yum",
+        side_effect=FileNotFoundError("No such file or directory: 'yum'"),
+    )
+    mocker.patch(
+        "watchdog.EFSUtilsVersionChecker.get_latest_version_by_github",
+        side_effect=TimeoutError,
+    )
+    mocker.patch("watchdog.EFSUtilsVersionChecker.update_version_check_file")
+
+    with caplog.at_level(logging.WARNING):
+        watchdog.EFSUtilsVersionChecker.check_if_using_old_version(OLD_VERSION)
+
+    assert not caplog.text
+
+
+def test_get_last_version_check_date(mocker, tmp_path):
+    current_time_str = datetime.utcnow().strftime(CERT_DATETIME_FORMAT)
+    dictionary = {
+        "time": current_time_str,
+    }
+    version_check_file = tempfile.NamedTemporaryFile(mode="w+", 
dir=str(tmp_path))
+    json.dump(dictionary, version_check_file)
+    version_check_file.flush()
+
+    mocker.patch("os.path.join", return_value=version_check_file.name)
+    last_version_check_date = (
+        watchdog.EFSUtilsVersionChecker.get_last_version_check_time()
+    )
+    assert last_version_check_date.strftime(CERT_DATETIME_FORMAT) == 
current_time_str
+
+    version_check_file.close()
+
+
+def test_get_last_version_check_bad_format(mocker, tmp_path):
+    """Make sure that watchdog does not crash if the version check file does 
not have a format we expect"""
+    current_time_str = datetime.utcnow().strftime(CERT_DATETIME_FORMAT)
+    dictionary = {
+        "bad_key": current_time_str,
+    }
+    version_check_file = tempfile.NamedTemporaryFile(mode="w+", 
dir=str(tmp_path))
+    json.dump(dictionary, version_check_file)
+    version_check_file.flush()
+
+    mocker.patch("os.path.join", return_value=version_check_file.name)
+    last_version_check_date = (
+        watchdog.EFSUtilsVersionChecker.get_last_version_check_time()
+    )
+    assert not last_version_check_date
+
+    version_check_file.close()
+
+
+def test_version_check_ready(mocker):
+    old_datetime = datetime(2000, 2, 3, 5, 35, 2)
+    mocker.patch(
+        "watchdog.EFSUtilsVersionChecker.get_last_version_check_time",
+        return_value=old_datetime,
+    )
+    assert watchdog.EFSUtilsVersionChecker.version_check_ready()
+
+
+def test_update_version_check_file(mocker, tmp_path):
+    """Write current time into the version check file"""
+    current_time = datetime.utcnow()
+    mocker.patch("watchdog.get_utc_now", return_value=current_time)
+    version_check_file = tempfile.NamedTemporaryFile(mode="w+", 
dir=str(tmp_path))
+    mocker.patch("os.path.join", return_value=version_check_file.name)
+    mocker.patch("os.path.exists", return_value=True)
+
+    watchdog.EFSUtilsVersionChecker.update_version_check_file()
+    version_check_file.flush()
+
+    with open(version_check_file.name, "r") as f:
+        data = json.load(f)
+
+    assert current_time.strftime(CERT_DATETIME_FORMAT) == data["time"]
+
+
+def test_version_gt():
+    assert watchdog.Version("1.34.5") > watchdog.Version("0.34.5")
+    assert watchdog.Version("1.35.5") > watchdog.Version("1.34.5")
+    assert watchdog.Version("1.34.5") > watchdog.Version("1.34.4")
+
+    assert not watchdog.Version("0.34.5") > watchdog.Version("1.34.5")
+    assert not watchdog.Version("1.34.5") > watchdog.Version("1.35.5")
+    assert not watchdog.Version("1.34.4") > watchdog.Version("1.34.5")
+
+
+def test_version_lt():
+    assert watchdog.Version("0.34.5") < watchdog.Version("1.34.5")
+    assert watchdog.Version("1.34.5") < watchdog.Version("1.35.5")
+    assert watchdog.Version("1.34.4") < watchdog.Version("1.34.5")
+
+    assert not watchdog.Version("1.34.5") < watchdog.Version("0.34.5")
+    assert not watchdog.Version("1.35.5") < watchdog.Version("1.34.5")
+    assert not watchdog.Version("1.34.5") < watchdog.Version("1.34.4")
+
+
+def test_version_eq():
+    assert watchdog.Version("0.34.5") == watchdog.Version("0.34.5")
+    assert not watchdog.Version("0.34.5") > watchdog.Version("0.34.5")
+    assert not watchdog.Version("0.34.5") < watchdog.Version("0.34.5")
+
+
+def test_version_empty_version_str():
+    """Assert that an Exception is thrown when we try to construct a Version 
instance with an empty string"""
+    with pytest.raises(Exception):
+        watchdog.Version("")
+
+
+def test_should_check_efs_utils_version(mocker):
+    mocker.patch("watchdog.get_boolean_config_item_value", return_value=True)
+    mocker.patch(
+        "watchdog.EFSUtilsVersionChecker.version_check_ready", 
return_value=True
+    )
+    config = ConfigParser()
+    assert 
watchdog.EFSUtilsVersionChecker.should_check_efs_utils_version(config)
+
+    mocker.patch("watchdog.get_boolean_config_item_value", return_value=False)
+    assert not 
watchdog.EFSUtilsVersionChecker.should_check_efs_utils_version(config)
+
+    mocker.patch(
+        "watchdog.EFSUtilsVersionChecker.version_check_ready", 
return_value=False
+    )
+    mocker.patch("watchdog.get_boolean_config_item_value", return_value=True)
+    assert not 
watchdog.EFSUtilsVersionChecker.should_check_efs_utils_version(config)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/efs-utils-1.35.0/test/watchdog_test/test_refresh_self_signed_certificate.py 
new/efs-utils-1.35.1/test/watchdog_test/test_refresh_self_signed_certificate.py
--- 
old/efs-utils-1.35.0/test/watchdog_test/test_refresh_self_signed_certificate.py 
    2023-03-16 19:07:54.000000000 +0100
+++ 
new/efs-utils-1.35.1/test/watchdog_test/test_refresh_self_signed_certificate.py 
    2024-01-18 16:57:36.000000000 +0100
@@ -894,3 +894,25 @@
     )
 
     assert full_config_body == matching_config_body
+
+
+def test_check_and_create_private_key_key_was_empty(mocker, tmpdir):
+    pk_path = _get_mock_private_key_path(mocker, tmpdir)
+    with open(pk_path, "w") as pk_file:
+        pass
+
+    state_file_dir = str(tmpdir)
+    watchdog.check_and_create_private_key(state_file_dir)
+    assert os.path.getsize(pk_path) > 0
+
+
+def test_check_and_create_private_key_key_already_exists(mocker, tmpdir):
+    pk_path = _get_mock_private_key_path(mocker, tmpdir)
+    with open(pk_path, "w") as pk_file:
+        pk_file.write("private key file contents")
+
+    call_mock = mocker.patch("watchdog.subprocess_call")
+
+    state_file_dir = str(tmpdir)
+    watchdog.check_and_create_private_key(state_file_dir)
+    assert call_mock.call_count == 0

Reply via email to