Skip to content
Merged
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
1 change: 1 addition & 0 deletions lib/API.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ _forge_scan_older
_forge_source_url
_forge_stable_filter
_forge_strip_v
_forge_workdir
_gh_scan_older_releases
_github_release_noapi
_gl_scan_older_releases
Expand Down
24 changes: 18 additions & 6 deletions lib/forge.func
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,18 @@ _cs_clean_target_dir() {
fi
}

# ------------------------------------------------------------------------------
# _forge_workdir
#
# A private directory for a download and its extraction, on disk. /tmp is tmpfs
# on Debian 13, so a release staged there counts against the container's memory
# limit and nothing can reclaim it: without swap, a 273 MiB archive that unpacks
# to 725 MiB gets the install OOM-killed in a 1 GiB container. TMPDIR still wins.
# ------------------------------------------------------------------------------
_forge_workdir() {
mktemp -d -p "${TMPDIR:-/var/tmp}" 2>/dev/null || mktemp -d -p /tmp
}

# ------------------------------------------------------------------------------
# _deploy_source_tarball <tarball_path> <target> <workdir>
#
Expand Down Expand Up @@ -761,7 +773,7 @@ fetch_and_deploy_gh_tag() {
fi

local tmpdir
tmpdir=$(mktemp -d) || return 1
tmpdir=$(_forge_workdir) || return 1
trap 'rm -rf "$tmpdir"; trap - RETURN' RETURN
local tarball_url="https://github.com/${repo}/archive/refs/tags/${version}.tar.gz"
local filename="${app_lc}-${version}.tar.gz"
Expand Down Expand Up @@ -940,7 +952,7 @@ fetch_and_deploy_gl_tag() {
local tarball_url="${gitlab_url}/${repo}/-/archive/${resolved_tag}/${app_lc}-${version_safe}.tar.gz"

local tmpdir
tmpdir=$(mktemp -d) || return 1
tmpdir=$(_forge_workdir) || return 1
trap 'rm -rf "$tmpdir"; trap - RETURN' RETURN
local filename="${app_lc}-${version_safe}.tar.gz"

Expand Down Expand Up @@ -2149,7 +2161,7 @@ fetch_and_deploy_release() {
json="$(mktemp /tmp/tools-forge-sel-XXXXXX)" || return 73

local tmpdir unpack_tmp=""
tmpdir="$(mktemp -d)" || {
tmpdir="$(_forge_workdir)" || {
rm -f "$json"
return 1
}
Expand Down Expand Up @@ -2341,7 +2353,7 @@ fetch_and_deploy_release() {
msg_error "Download failed: $asset_url"
return 250
}
unpack_tmp="$(mktemp -d)"
unpack_tmp="$(_forge_workdir)"
_deploy_unpacked_archive "$tmpdir/$filename" "$target" "$unpack_tmp" || return
else
mkdir -p "$target"
Expand Down Expand Up @@ -2449,7 +2461,7 @@ fetch_and_deploy_from_url() {
msg_info "Downloading from $url"

local tmpdir
tmpdir=$(mktemp -d) || {
tmpdir=$(_forge_workdir) || {
msg_error "Failed to create temporary directory"
return 252
}
Expand Down Expand Up @@ -2512,7 +2524,7 @@ fetch_and_deploy_from_url() {
msg_info "Extracting archive to $directory"

local unpack_tmp
unpack_tmp=$(mktemp -d)
unpack_tmp=$(_forge_workdir)

_deploy_unpacked_archive "$tmpdir/$filename" "$directory" "$unpack_tmp" "$archive_type" || return

Expand Down
2 changes: 1 addition & 1 deletion tests/forge-appversion-scope.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
set -uo pipefail

CORE_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
eval "$(awk '/^(fetch_and_deploy_release|_forge_is_script_app|_forge_descriptor|_forge_strip_v|_forge_previous_version)[(][)] [{]/,/^}/' "$CORE_DIR/lib/forge.func")"
eval "$(awk '/^(fetch_and_deploy_release|_forge_workdir|_forge_is_script_app|_forge_descriptor|_forge_strip_v|_forge_previous_version)[(][)] [{]/,/^}/' "$CORE_DIR/lib/forge.func")"

TEST_DIR="$(mktemp -d)"
trap 'rm -rf -- "$TEST_DIR"' EXIT
Expand Down
18 changes: 17 additions & 1 deletion tests/forge-clean-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
set -euo pipefail

CORE_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
eval "$(awk '/^(_cs_clean_target_dir|_deploy_source_tarball|_deploy_unpacked_archive)\(\) \{/,/^}/' "$CORE_DIR/lib/forge.func")"
eval "$(awk '/^(_cs_clean_target_dir|_deploy_source_tarball|_deploy_unpacked_archive|_forge_workdir)\(\) \{/,/^}/' "$CORE_DIR/lib/forge.func")"

TEST_DIR="$(mktemp -d)"
trap 'rm -rf -- "$TEST_DIR"' EXIT
Expand Down Expand Up @@ -76,5 +76,21 @@ check "source: no top-level dir leaves the install" "251 $intact" "$(source_tarb
check "source: clean install replaces the target" "0 ./app " "$(source_tarball good.tar.gz)"
check "source: CLEAN_INSTALL_KEEP survives" "0 ./app ./data/db " "$(CLEAN_INSTALL_KEEP="data" source_tarball good.tar.gz)"

# Releases stage on disk, so a large one does not count against the memory limit.
workdir_under() {
local dir rc=0
dir="$(TMPDIR="$1" _forge_workdir)" || rc=$?
echo "$rc ${dir%/*}"
rm -rf -- "$dir"
}
mkdir "$TEST_DIR/staging"
check "workdir: TMPDIR wins" "0 $TEST_DIR/staging" "$(workdir_under "$TEST_DIR/staging")"
check "workdir: an unusable TMPDIR falls back to /tmp" "0 /tmp" "$(workdir_under "$TEST_DIR/missing")"
unset TMPDIR
default_workdir="$(_forge_workdir)"
check "workdir: defaults to /var/tmp, not /tmp" "/var/tmp" "${default_workdir%/*}"
rm -rf -- "$default_workdir"
check "no helper stages in the mktemp default" "0" "$(awk '/^(fetch_and_deploy_[a-z_]+|_forge_[a-z_]+)\(\) \{/,/^}/' "$CORE_DIR/lib/forge.func" | grep -c '_tmp="\{0,1\}$(mktemp -d)\|tmpdir="\{0,1\}$(mktemp -d)')"

echo "${passed} passed, ${failed} failed"
((failed == 0))
2 changes: 1 addition & 1 deletion tests/release-stamp-pending.sh
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ rm -f "$HOME/.npm"
expect "a fresh install has no previous version" "" "$(_forge_previous_version "$HOME/.npm")"

# fetch_and_deploy_release: a redo deploys again, the failed run may have patched the files
eval "$(awk '/^fetch_and_deploy_release[(][)] [{]/,/^}/' "$CORE_DIR/lib/forge.func")"
eval "$(awk '/^(fetch_and_deploy_release|_forge_workdir)[(][)] [{]/,/^}/' "$CORE_DIR/lib/forge.func")"
_forge_release_json() { printf '%s' '{"tag_name":"v2.16.0"}' >"$5"; }
_forge_source_url() { echo "https://example.invalid/src.tar.gz"; }
_download_source_tarball() { :; }
Expand Down
Loading