Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[master] Use relenv.fetch to download tarball #67022

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions salt/client/ssh/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""

Create ssh executor system
"""

Expand Down Expand Up @@ -192,11 +193,7 @@
)


SSH_SH_SHIM_RELENV = "\n".join(
[
s.strip()
for s in """
/bin/sh << 'EOF'
SSH_SH_SHIM_RELENV = """/bin/sh << 'EOF'
set -e
set -u
DEBUG="{DEBUG}"
Expand All @@ -211,9 +208,11 @@
SUDO_USER="{SUDO_USER}"
if [ "$SUDO" ] && [ "$SUDO_USER" ]; then SUDO="$SUDO -u $SUDO_USER"; fi

RELENV_TAR="{THIN_DIR}/salt-relenv.tar.xz"
mkdir -p "{THIN_DIR}"
SALT_CALL_BIN="{THIN_DIR}/salt-call"
THIN_DIR={THIN_DIR}
mkdir -pv $THIN_DIR >&2
ls "$THIN_DIR" >&2
RELENV_TAR=$THIN_DIR/salt-relenv.tar.xz
SALT_CALL_BIN="$THIN_DIR/salt-call"

# Extract relenv tarball if not already extracted
if [ ! -x "$SALT_CALL_BIN" ]; then
Expand All @@ -223,9 +222,13 @@
exit 11
fi

file $RELENV_TAR >&2

# Create directory if not exists and extract the tarball
tar --strip-components=1 -xf "$RELENV_TAR" -C "{THIN_DIR}"
fi
tar --strip-components=1 -xf "$RELENV_TAR" -C "$THIN_DIR"
fi;

file $SALT_CALL_BIN >&2

# Check if Python binary is executable
if [ ! -x "$SALT_CALL_BIN" ]; then
Expand All @@ -236,13 +239,10 @@
echo "{RSTR}"
echo "{RSTR}" >&2

exec $SUDO "$SALT_CALL_BIN" --retcode-passthrough --local --metadata --out=json -lquiet -c "{THIN_DIR}" {ARGS}
exec $SUDO "$SALT_CALL_BIN" --retcode-passthrough --local --metadata --out=json -lquiet -c "$THIN_DIR" {ARGS}
EOF
""".split(
"\n"
)
]
)
"""


if not salt.utils.platform.is_windows() and not salt.utils.platform.is_junos():
shim_file = os.path.join(os.path.dirname(__file__), "ssh_py_shim.py")
Expand Down
47 changes: 41 additions & 6 deletions salt/utils/relenv.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@

log = logging.getLogger(__name__)

BASE_URL = "https://packages.broadcom.com/artifactory/saltproject-generic/onedir/"


def gen_relenv(
cachedir,
kernel,
os_arch,
overwrite=False,
base_url=BASE_URL,
):
"""
Deploy salt-relenv.
Expand All @@ -26,30 +29,33 @@ def gen_relenv(
:param overwrite: Whether to overwrite the existing cached tarball.
:return: The path to the recompressed .tgz file.
"""
version = get_latest_version(base_url)

# Set up directories
relenv_dir = os.path.join(cachedir, "relenv", kernel, os_arch)
relenv_dir = os.path.join(cachedir, "relenv", version, kernel, os_arch)
if not os.path.isdir(relenv_dir):
os.makedirs(relenv_dir)

relenv_url = get_tarball(kernel, os_arch)
relenv_url = get_tarball(f"{base_url}/{version}/", kernel, os_arch)
tarball_path = os.path.join(relenv_dir, "salt-relenv.tar.xz")

# Download the tarball if it doesn't exist or overwrite is True
if overwrite or not os.path.exists(tarball_path):
if not download(cachedir, relenv_url, tarball_path):
if not download(relenv_url, tarball_path):
return False

return tarball_path


def get_tarball(kernel, arch):
def get_tarball(base_url, kernel, arch):
"""
Get the latest Salt onedir tarball URL for the specified kernel and architecture.
:param base_url: The artifactory location
:param kernel: The detected OS (e.g., 'linux', 'darwin', 'windows').
:param arch: The detected architecture (e.g., 'amd64', 'x86_64', 'arm64').
:return: The URL of the latest tarball.
"""
base_url = "https://repo.saltproject.io/salt/py3/onedir/latest/"

try:
# Request the page listing
response = requests.get(base_url, timeout=60)
Expand All @@ -71,9 +77,38 @@ def get_tarball(kernel, arch):
return base_url + latest_tarball


def download(cachedir, url, destination):
def get_latest_version(base_url):
"""
Retrieve the latest version from the base artifactory directory
:param base_url: The artifactory location
:return: The version number of the latest artifact
"""
try:
response = requests.get(base_url, timeout=60)
response.raise_for_status()
except requests.RequestException as e:
log.error(f"Failed to retrieve directory listing: {e}")
raise ValueError("Unable to fetch directory list from repository")

# Extract version numbers from hrefs
pattern = re.compile(r'href="(\d+\.\d+)/"')
versions = pattern.findall(response.text)

if not versions:
log.error("No versions found in directory listing")
raise ValueError("No versions found in directory listing")

# Sort versions numerically and return the latest one
versions.sort(key=lambda s: list(map(int, s.split("."))), reverse=True)
return versions[0]


def download(url, destination):
"""
Download the salt artifact from the given destination to the cache.
:param url: The artifact location
:param destination: Path to the downloaded file
:return: True if the download was successful, else False
"""
if not os.path.exists(destination):
log.info(f"Downloading from {url} to {destination}")
Expand Down
Loading