Merge freeze forward into master (#62403)

* Update versionadded from 3006 to 3005

* Add known issue about SSC 8.9.0 dependency

* Add explanation for the issue

* Update release candidate documentation

* Add clarification per Shane's review

* Add RHEL GPG key info

* Revise topic per Murphy's review

* Switch to the SaltStack ORG on quay.io

Signed-off-by: Pedro Algarvio <palgarvio@vmware.com>

* Update the salt pip executable to salt-pip

* Fix pre-install and post-install scripts

Make the date display in the logs properly

* Add pyinstaller hook which pulls in all of salt and the standard library

Signed-off-by: Pedro Algarvio <palgarvio@vmware.com>

* Add changelog for #62383 which fixes #62362

Signed-off-by: Pedro Algarvio <palgarvio@vmware.com>

* Windows search path is different

Signed-off-by: Pedro Algarvio <palgarvio@vmware.com>

* Salt should not do any logic to include/exclude requirements. That's pip's job.

Refs #62386
Fixes #62392

Signed-off-by: Pedro Algarvio <palgarvio@vmware.com>

Co-authored-by: Megan Wilhite <mwilhite@vmware.com>
Co-authored-by: Alyssa Rock <alyssa.rock@gmail.com>
Co-authored-by: Twangboy <leesh@vmware.com>
This commit is contained in:
Pedro Algarvio 2022-08-02 01:44:17 +01:00 committed by GitHub
parent 77be876be3
commit bf24613010
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 262 additions and 166 deletions

1
changelog/62362.fixed Normal file
View file

@ -0,0 +1 @@
Added a pyinstaller hook that traverses the python used on the tiamat package to add all possible modules as hidden imports.

1
changelog/62392.fixed Normal file
View file

@ -0,0 +1 @@
All of the requirements provided in the requirements files are now included. The job of evaluating platform markers is not Salt's it's pip's.

View file

@ -1268,7 +1268,7 @@ Returns:
``random_sample``
-----------------
.. versionadded:: 3006
.. versionadded:: 3005
Returns a given sample size from a list. The ``seed`` parameter can be used to
return a predictable outcome.
@ -1292,7 +1292,7 @@ Returns:
``random_shuffle``
------------------
.. versionadded:: 3006
.. versionadded:: 3005
Returns a shuffled copy of an input list. The ``seed`` parameter can be used to
return a predictable outcome.

View file

@ -141,6 +141,24 @@ For example:
- bin_env: /usr/bin/python3
Known issues
------------
To make use of Salt 3005 or later on a Salt master connected to SaltStack
Config, you must use SaltStack Config version 8.9.0 or later.
The root cause of the issue is a breaking change to
``AsyncClient._proc_function()``` in Salt, which is the function that the
raas-master uses to run ``salt-run`` commands. As this is a private API, there's
no expectation that the API should remain backward-compatible.
It is recommended to upgrade SaltStack Config before upgrading your Salt
masters. However, if a Salt master is upgraded to version 3005 before
upgrading SaltStack Config, the upgrade can still be completed.
After upgrading SaltStack Config, including the SSC plugin on each Salt master,
restart the Salt masters.
Removed
-------

View file

@ -19,123 +19,130 @@
###############################################################################
# Define Variables
###############################################################################
# Get Minor Version
OSX_VERSION=$(sw_vers | grep ProductVersion | cut -f 2 -d: | tr -d '[:space:]')
MINOR=$(echo ${OSX_VERSION} | cut -f 2 -d.)
PY_DOT_VERSION=3.9.12
# Path Variables
INSTALL_DIR="/opt/salt"
BIN_DIR="$INSTALL_DIR/bin"
CONFIG_DIR="/etc/salt"
TEMP_DIR="/tmp"
SBIN_DIR="/usr/local/sbin"
PY_DOT_VERSION="3.7.12"
###############################################################################
# Define Functions
###############################################################################
log () {
if [ -f "$TEMP_DIR/postinstall.txt" ]; then
echo "$1" >> "$TEMP_DIR/postinstall.txt"
else
echo "$1" > "$TEMP_DIR/postinstall.txt"
fi
}
quit_on_error() {
log "$(basename "$0") caught error: $1 on line : $2 command was: $3"
exit 1
}
###############################################################################
# Set up logging and error handling
###############################################################################
echo "Post install script started on:" > "$TEMP_DIR/postinstall.txt"
date "+%Y/%m/%d %H:%m:%S" >> "$TEMP_DIR/postinstall.txt"
trap 'quit_on_error $LINENO $BASH_COMMAND' ERR
quit_on_error() {
echo "$(basename $0) caught error on line : $1 command was: $2" >> "$TEMP_DIR/postinstall.txt"
exit 1
}
log "Post install script started on: $(date '+%Y/%m/%d %H:%M:%S')"
trap 'quit_on_error $? $LINENO $BASH_COMMAND' ERR
###############################################################################
# Check for existing minion config, copy if it doesn't exist
###############################################################################
if [ ! -f "$CONFIG_DIR/minion" ]; then
echo "Config: Copy Started..." >> "$TEMP_DIR/postinstall.txt"
log "Config: Copy Started..."
cp "$CONFIG_DIR/minion.dist" "$CONFIG_DIR/minion"
echo "Config: Copied Successfully" >> "$TEMP_DIR/postinstall.txt"
log "Config: Copied Successfully"
fi
###############################################################################
# Create symlinks to pyenv directories
###############################################################################
echo "Symlink: Creating symlinks to pyenv directories..." >> "$TEMP_DIR/postinstall.txt"
log "Symlink: Creating symlinks to pyenv directories..."
ln -s "$INSTALL_DIR/.pyenv/versions/$PY_DOT_VERSION/bin" "$INSTALL_DIR/bin"
ln -s "$INSTALL_DIR/.pyenv/versions/$PY_DOT_VERSION/include" "$INSTALL_DIR/include"
ln -s "$INSTALL_DIR/.pyenv/versions/$PY_DOT_VERSION/lib" "$INSTALL_DIR/lib"
echo "Symlink: Creating symlinks to library files..." >> "$TEMP_DIR/postinstall.txt"
log "Symlink: Creating symlinks to library files..."
find "$INSTALL_DIR/.pyenv/versions/$PY_DOT_VERSION" \
-name '*.dylib' \
-type f \
-exec ln -s {} $INSTALL_DIR/lib/ \;
echo "Symlink: Copying symlinks for openssl..." >> "$TEMP_DIR/postinstall.txt"
log "Symlink: Copying symlinks for openssl..."
find "$INSTALL_DIR/.pyenv/versions/$PY_DOT_VERSION/openssl" \
-name '*.dylib' \
-type l \
-exec cp -R {} $INSTALL_DIR/lib/ \;
echo "Symlink: Copying symlinks for readline..." >> "$TEMP_DIR/postinstall.txt"
log "Symlink: Copying symlinks for readline..."
find "$INSTALL_DIR/.pyenv/versions/$PY_DOT_VERSION/readline" \
-name '*.dylib' \
-type l \
-exec cp -R {} $INSTALL_DIR/lib/ \;
echo "Symlink: Created Successfully" >> "$TEMP_DIR/postinstall.txt"
log "Symlink: Created Successfully"
###############################################################################
# Create symlink to salt-config.sh
###############################################################################
if [ ! -d "$SBIN_DIR" ]; then
echo "Symlink: Creating $SBIN_DIR..." >> "$TEMP_DIR/postinstall.txt"
log "Symlink: Creating $SBIN_DIR..."
mkdir "$SBIN_DIR"
echo "Symlink: Created Successfully" >> "$TEMP_DIR/postinstall.txt"
log "Symlink: Created Successfully"
fi
echo "Symlink: Creating symlink for salt-config..." >> "$TEMP_DIR/postinstall.txt"
# This is a special tool to make it easier for the user to get started setting
# up salt
log "Symlink: Creating symlink for salt-config..."
ln -sf "$BIN_DIR/salt-config.sh" "$SBIN_DIR/salt-config"
echo "Symlink: Created Successfully" >> "$TEMP_DIR/postinstall.txt"
log "Symlink: Created Successfully"
###############################################################################
# Add salt to paths.d
###############################################################################
if [ ! -d "/etc/paths.d" ]; then
echo "Path: Creating paths.d directory..." >> "$TEMP_DIR/postinstall.txt"
log "Path: Creating paths.d directory..."
mkdir /etc/paths.d
echo "Path: Created Successfully" >> "$TEMP_DIR/postinstall.txt"
log "Path: Created Successfully"
fi
echo "Path: Adding salt to the path..." >> "$TEMP_DIR/postinstall.txt"
log "Path: Adding salt to the path..."
sh -c "echo \"$BIN_DIR\" > /etc/paths.d/salt"
sh -c "echo \"$SBIN_DIR\" >> /etc/paths.d/salt"
echo "Path: Added Successfully" >> "$TEMP_DIR/postinstall.txt"
log "Path: Added Successfully"
###############################################################################
# Register Salt as a service
###############################################################################
echo "Service: Configuring..." >> "$TEMP_DIR/postinstall.txt"
log "Service: Configuring..."
echo "Service: Enabling salt-minion..." >> "$TEMP_DIR/postinstall.txt"
log "Service: Enabling salt-minion..."
launchctl enable system/com.saltstack.salt.minion
echo "Service: Enabled Successfully" >> "$TEMP_DIR/postinstall.txt"
log "Service: Enabled Successfully"
echo "Service: Bootstrapping salt-minion..." >> "$TEMP_DIR/postinstall.txt"
log "Service: Bootstrapping salt-minion..."
launchctl bootstrap system /Library/LaunchDaemons/com.saltstack.salt.minion.plist
echo "Service: Bootstrapped Successfully" >> "$TEMP_DIR/postinstall.txt"
log "Service: Bootstrapped Successfully"
if /bin/launchctl list "com.saltstack.salt.minion" &> /dev/null; then
echo "Service: Service Running" >> "$TEMP_DIR/postinstall.txt"
log "Service: Service Running"
else
echo "Service: Kickstarting Service..." >> "$TEMP_DIR/postinstall.txt"
log "Service: Kickstarting Service..."
launchctl kickstart -kp system/com.saltstack.salt.minion
echo "Service: Kickstarted Successfully" >> "$TEMP_DIR/postinstall.txt"
log "Service: Kickstarted Successfully"
fi
echo "Service: Started Successfully" >> "$TEMP_DIR/postinstall.txt"
log "Service: Started Successfully"
echo "Service: Disabling Master, Syndic, and API services" >> "$TEMP_DIR/postinstall.txt"
log "Service: Disabling Master, Syndic, and API services"
launchctl disable system/com.saltstack.salt.master
launchctl disable system/com.saltstack.salt.syndic
launchctl disable system/com.saltstack.salt.api
echo "Service: Disabled Successfully" >> "$TEMP_DIR/postinstall.txt"
log "Service: Disabled Successfully"
echo "Service: Configured Successfully" >> "$TEMP_DIR/postinstall.txt"
log "Service: Configured Successfully"
echo "Post install completed successfully on:" >> "$TEMP_DIR/postinstall.txt"
date "+%Y/%m/%d %H:%m:%S" >> "$TEMP_DIR/postinstall.txt"
log "Post install completed successfully on: $(date '+%Y/%m/%d %H:%M:%S')"
exit 0

View file

@ -20,91 +20,99 @@
###############################################################################
# Define Variables
###############################################################################
# Get Minor Version
OSX_VERSION=$(sw_vers | grep ProductVersion | cut -f 2 -d: | tr -d '[:space:]')
MINOR=$(echo ${OSX_VERSION} | cut -f 2 -d.)
# Path Variables
INSTALL_DIR="/opt/salt"
BIN_DIR="$INSTALL_DIR/bin"
CONFIG_DIR="/etc/salt"
TEMP_DIR="/tmp"
SBIN_DIR="/usr/local/sbin"
###############################################################################
# Set up logging and error handling
# Define Functions
###############################################################################
echo "Preinstall started on:" > "$TEMP_DIR/preinstall.txt"
date "+%Y/%m/%d %H:%m:%S" >> "$TEMP_DIR/preinstall.txt"
trap 'quit_on_error $LINENO $BASH_COMMAND' ERR
log () {
if [ -f "$TEMP_DIR/preinstall.txt" ]; then
echo "$1" >> "$TEMP_DIR/preinstall.txt"
else
echo "$1" > "$TEMP_DIR/preinstall.txt"
fi
}
quit_on_error() {
echo "$(basename $0) caught error on line : $1 command was: $2" >> "$TEMP_DIR/preinstall.txt"
# Launchctl returns error code 36 when bootout is in progress, so just return
test "$1" == 36 && return;
log "$(basename "$0") caught error: $1 on line : $2 command was: $3"
exit 1
}
OSX_VERSION=$(sw_vers | grep ProductVersion | cut -f 2 -d: | tr -d '[:space:]')
MINOR=$(echo ${OSX_VERSION} | cut -f 2 -d.)
###############################################################################
# Set up logging and error handling
###############################################################################
log "Preinstall started on: $(date '+%Y/%m/%d %H:%M:%S')"
trap 'quit_on_error $? $LINENO $BASH_COMMAND' ERR
###############################################################################
# Stop the service
###############################################################################
echo "Service: Configuring..." >> "$TEMP_DIR/preinstall.txt"
log "Service: Configuring..."
if /bin/launchctl list "com.saltstack.salt.minion" &> /dev/null; then
echo "Service: Stopping minion..." >> "$TEMP_DIR/preinstall.txt"
while /bin/launchctl list "com.saltstack.salt.minion" &> /dev/null; do
log "Service: Stopping minion..."
launchctl disable system/com.saltstack.salt.minion
launchctl bootout system /Library/LaunchDaemons/com.saltstack.salt.minion.plist
echo "Service: Stopped Successfully" >> "$TEMP_DIR/preinstall.txt"
fi
if /bin/launchctl list "com.saltstack.salt.master" &> /dev/null; then
echo "Service: Stopping master..." >> "$TEMP_DIR/preinstall.txt"
sleep 1
log "Service: Stopped Successfully"
done
while /bin/launchctl list "com.saltstack.salt.master" &> /dev/null; do
log "Service: Stopping master..."
launchctl disable system/com.saltstack.salt.master
launchctl bootout system /Library/LaunchDaemons/com.saltstack.salt.master.plist
echo "Service: Stopped Successfully" >> "$TEMP_DIR/preinstall.txt"
fi
if /bin/launchctl list "com.saltstack.salt.syndic" &> /dev/null; then
echo "Service: Stopping syndic..." >> "$TEMP_DIR/preinstall.txt"
sleep 1
log "Service: Stopped Successfully"
done
while /bin/launchctl list "com.saltstack.salt.syndic" &> /dev/null; do
log "Service: Stopping syndic..."
launchctl disable system/com.saltstack.salt.syndic
launchctl bootout system /Library/LaunchDaemons/com.saltstack.salt.syndic.plist
echo "Service: Stopped Successfully" >> "$TEMP_DIR/preinstall.txt"
fi
if /bin/launchctl list "com.saltstack.salt.api" &> /dev/null; then
echo "Service: Stopping api..." >> "$TEMP_DIR/preinstall.txt"
sleep 1
log "Service: Stopped Successfully"
done
while /bin/launchctl list "com.saltstack.salt.api" &> /dev/null; do
log "Service: Stopping api..."
launchctl disable system/com.saltstack.salt.api
launchctl bootout system /Library/LaunchDaemons/com.saltstack.salt.api.plist
echo "Service: Stopped Successfully" >> "$TEMP_DIR/preinstall.txt"
fi
sleep 1
log "Service: Stopped Successfully"
done
echo "Service: Configured Successfully" >> "$TEMP_DIR/preinstall.txt"
log "Service: Configured Successfully"
###############################################################################
# Remove the Symlink to salt-config.sh
###############################################################################
if [ -L "$SBIN_DIR/salt-config" ]; then
echo "Cleanup: Removing Symlink $BIN_DIR/salt-config" >> "$TEMP_DIR/preinstall.txt"
log "Cleanup: Removing Symlink $BIN_DIR/salt-config"
rm "$SBIN_DIR/salt-config"
echo "Cleanup: Removed Successfully" >> "$TEMP_DIR/preinstall.txt"
log "Cleanup: Removed Successfully"
fi
###############################################################################
# Remove the $INSTALL_DIR directory
###############################################################################
if [ -d "$INSTALL_DIR" ]; then
echo "Cleanup: Removing $INSTALL_DIR" >> "$TEMP_DIR/preinstall.txt"
log "Cleanup: Removing $INSTALL_DIR"
rm -rf "$INSTALL_DIR"
echo "Cleanup: Removed Successfully" >> "$TEMP_DIR/preinstall.txt"
log "Cleanup: Removed Successfully"
fi
###############################################################################
# Remove the salt from the paths.d
###############################################################################
if [ -f "/etc/paths.d/salt" ]; then
echo "Path: Removing salt from the path..." >> "$TEMP_DIR/preinstall.txt"
log "Path: Removing salt from the path..."
rm "/etc/paths.d/salt"
echo "Path: Removed Successfully" >> "$TEMP_DIR/preinstall.txt"
log "Path: Removed Successfully"
fi
echo "Preinstall Completed Successfully on:" >> "$TEMP_DIR/preinstall.txt"
date "+%Y/%m/%d %H:%m:%S" >> "$TEMP_DIR/preinstall.txt"
log "Preinstall Completed Successfully on: $(date '+%Y/%m/%d %H:%M:%S')"
exit 0

View file

@ -0,0 +1,146 @@
# pylint: disable=3rd-party-module-not-gated
import logging
import pathlib
import sys
from PyInstaller.utils import hooks
log = logging.getLogger(__name__)
def _filter_stdlib_tests(name):
"""
Filter out non useful modules from the stdlib
"""
if ".test." in name:
return False
if ".tests." in name:
return False
if ".idle_test" in name:
return False
return True
def _python_stdlib_path():
"""
Return the path to the standard library folder
"""
base_exec_prefix = pathlib.Path(sys.base_exec_prefix)
log.info("Grabbing 'base_exec_prefix' for platform: %s", sys.platform)
if not sys.platform.lower().startswith("win"):
return base_exec_prefix / "lib" / "python{}.{}".format(*sys.version_info)
return base_exec_prefix / "Lib"
def _collect_python_stdlib_hidden_imports():
"""
Collect all of the standard library(most of it) as hidden imports.
"""
_hidden_imports = set()
stdlib = _python_stdlib_path()
if not stdlib.exists():
log.error("The path '%s' does not exist", stdlib)
return list(_hidden_imports)
log.info(
"Collecting hidden imports from the python standard library at: %s",
stdlib,
)
for path in stdlib.glob("*"):
if path.is_dir():
if path.name in (
"__pycache__",
"site-packages",
"test",
"turtledemo",
"ensurepip",
):
continue
if path.joinpath("__init__.py").is_file():
log.info("Collecting: %s", path.name)
try:
_module_hidden_imports = hooks.collect_submodules(
path.name, filter=_filter_stdlib_tests
)
log.debug("Collected(%s): %s", path.name, _module_hidden_imports)
_hidden_imports.update(set(_module_hidden_imports))
except Exception as exc: # pylint: disable=broad-except
log.error("Failed to collect %r: %s", path.name, exc)
continue
if path.suffix not in (".py", ".pyc", ".pyo"):
continue
_hidden_imports.add(path.stem)
log.info("Collected stdlib hidden imports: %s", sorted(_hidden_imports))
return sorted(_hidden_imports)
def _collect_python_stdlib_dynamic_libraries():
"""
Collect all of the standard library(most of it) dynamic libraries.
"""
_dynamic_libs = set()
stdlib = _python_stdlib_path()
if not stdlib.exists():
log.error("The path '%s' does not exist", stdlib)
return list(_dynamic_libs)
log.info(
"Collecting dynamic libraries from the python standard library at: %s",
stdlib,
)
for path in stdlib.glob("*"):
if not path.is_dir():
continue
if path.name in (
"__pycache__",
"site-packages",
"test",
"turtledemo",
"ensurepip",
):
continue
if path.joinpath("__init__.py").is_file():
log.info("Collecting: %s", path.name)
try:
_module_dynamic_libs = hooks.collect_dynamic_libs(path.name, path.name)
log.debug("Collected(%s): %s", path.name, _module_dynamic_libs)
_dynamic_libs.update(set(_module_dynamic_libs))
except Exception as exc: # pylint: disable=broad-except
log.error("Failed to collect %r: %s", path.name, exc)
log.info("Collected stdlib dynamic libs: %s", sorted(_dynamic_libs))
return sorted(_dynamic_libs)
def _filter_submodules(name):
# this should never happen, but serves as a place-holder for when/if we have to filter
if not name.startswith("salt"):
return False
return True
# Collect Salt datas, binaries(should be None) and hidden imports
SALT_DATAS, SALT_BINARIES, SALT_HIDDENIMPORTS = hooks.collect_all(
"salt",
include_py_files=True,
filter_submodules=_filter_submodules,
)
# In case there's salt-extensions installed, collect their datas and hidden imports
SALT_EXTENSIONS_DATAS, SALT_EXTENSIONS_HIDDENIMPORTS = hooks.collect_entry_point(
"salt.loader"
)
# PyInstaller attributes
datas = sorted(set(SALT_DATAS + SALT_EXTENSIONS_DATAS))
binaries = sorted(set(SALT_BINARIES + _collect_python_stdlib_dynamic_libraries()))
hiddenimports = sorted(
set(
SALT_HIDDENIMPORTS
+ SALT_EXTENSIONS_HIDDENIMPORTS
+ _collect_python_stdlib_hidden_imports()
)
)

View file

@ -7,7 +7,6 @@ The setup script for salt
import contextlib
import distutils.dist
import glob
import operator
import os
import platform
import sys
@ -175,77 +174,6 @@ exec(compile(open(SALT_VERSION).read(), SALT_VERSION, "exec"))
# ----- Helper Functions -------------------------------------------------------------------------------------------->
def _parse_op(op):
"""
>>> _parse_op('>')
'gt'
>>> _parse_op('>=')
'ge'
>>> _parse_op('=>')
'ge'
>>> _parse_op('=> ')
'ge'
>>> _parse_op('<')
'lt'
>>> _parse_op('<=')
'le'
>>> _parse_op('==')
'eq'
>>> _parse_op(' <= ')
'le'
"""
op = op.strip()
if ">" in op:
if "=" in op:
return "ge"
else:
return "gt"
elif "<" in op:
if "=" in op:
return "le"
else:
return "lt"
elif "!" in op:
return "ne"
else:
return "eq"
def _parse_ver(ver):
"""
>>> _parse_ver("'3.4' # pyzmq 17.1.0 stopped building wheels for python3.4")
'3.4'
>>> _parse_ver('"3.4"')
'3.4'
>>> _parse_ver('"2.6.17"')
'2.6.17'
"""
if "#" in ver:
ver, _ = ver.split("#", 1)
ver = ver.strip()
return ver.strip("'").strip('"')
def _check_ver(pyver, op, wanted):
"""
>>> _check_ver('2.7.15', 'gt', '2.7')
True
>>> _check_ver('2.7.15', 'gt', '2.7.15')
False
>>> _check_ver('2.7.15', 'ge', '2.7.15')
True
>>> _check_ver('2.7.15', 'eq', '2.7.15')
True
"""
pyver = distutils.version.LooseVersion(pyver)
wanted = distutils.version.LooseVersion(wanted)
if not isinstance(pyver, str):
pyver = str(pyver)
if not isinstance(wanted, str):
wanted = str(wanted)
return getattr(operator, "__{}__".format(op))(pyver, wanted)
def _parse_requirements_file(requirements_file):
parsed_requirements = []
with open(requirements_file) as rfh:
@ -256,19 +184,6 @@ def _parse_requirements_file(requirements_file):
if IS_WINDOWS_PLATFORM:
if "libcloud" in line:
continue
try:
pkg, pyverspec = line.rsplit(";", 1)
except ValueError:
pkg, pyverspec = line, ""
pyverspec = pyverspec.strip()
if pyverspec and (
not pkg.startswith("pycrypto") or pkg.startswith("pycryptodome")
):
_, op, ver = pyverspec.split(" ", 2)
if not _check_ver(
platform.python_version(), _parse_op(op), _parse_ver(ver)
):
continue
parsed_requirements.append(line)
return parsed_requirements