Skip to content

fix: keep the existing install until the new archive has extracted - #201

Merged
MickLesk merged 4 commits into
community-scripts:mainfrom
rcourtman:fix/clean-install-after-extract
Nov 5, 2026
Merged

MickLesk merged 4 commits into
community-scripts:mainfrom
rcourtman:fix/clean-install-after-extract

Conversation

@rcourtman

@rcourtman rcourtman commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

✍️ Description

With CLEAN_INSTALL=1, _deploy_unpacked_archive and _deploy_source_tarball emptied the target before extracting into the workdir. Any failure after that left an empty target: a truncated download, an archive that unpacks to nothing, or a disk that fills up while it unpacks. The last one is easy to hit. The Pulse linux tarball is ~287 MB in a 4 GB container, and ct/pulse.sh then has no binary left to restart.

Extraction only writes into the workdir, so the wipe now runs after the payload has extracted and is non-empty, right before the copy. CLEAN_INSTALL_KEEP, return codes and messages are unchanged.

This is community-scripts/ProxmoxVE#16312 again. It merged into misc/tools.func on 6 August, the day after tools.func was split into this repo, so the split kept the old order.

_deploy_source_tarball now also returns 251 for a tarball with no top-level directory. Before, unpack_dir came back empty and the copy ran as cp -r "/"*.

tests/forge-clean-install.sh covers both helpers: truncated archive, empty payload, unsupported format, extraction failing partway (disk full), plus clean, merge and CLEAN_INSTALL_KEEP success paths. 14/14 pass on Ubuntu 24.04 (GNU tar 1.35) and macOS (bsdtar 3.5). Against main, the five failure cases leave the target empty and every success case gives the same result.

Tested on Proxmox VE 9.2 with a real ct/pulse.sh container (Debian 13, defaults), built and updated with COMMUNITY_SCRIPTS_CORE_URL pointed at this branch:

Run /opt/pulse after Pulse
Normal update, this branch redeployed running 6.7.0
/tmp too small to extract (500 MB tmpfs over the Debian 13 tmpfs), this branch intact, 389 MB restarted, API answering
Same, main empty stuck in activating, API down

On main, ct/pulse.sh still printed "Restarted the previously installed Pulse", because systemctl start succeeds for a Restart=always unit that has nothing left to run. Not tested on Incus (no Incus host here). Locally there are no ShellCheck errors and no new warnings, and the split-file checks and every script in tests/ pass.

Written and tested with Claude Opus 5.5 (reasoning: high).

🔗 Related Issue

Related: community-scripts/ProxmoxVE#16312

✅ Prerequisites (X in brackets)

  • Self-review completed – Code follows project standards.
  • Tested thoroughly – Changes work as expected (Proxmox VE and/or Incus, as applicable).
  • No security risks – No hardcoded secrets, unnecessary privilege escalations, or permission issues.
  • API.txt regenerated – If a function signature or behavior changed, API.txt was updated to match.

🛠️ Type of Change (X in brackets)

  • 🐞 Bug fix – Resolves an issue without breaking functionality.
  • ✨ New feature – Adds new, non-breaking functionality.
  • 💥 Breaking change – Alters existing behavior in a way that may require updates in every downstream script.
  • 🔧 Refactoring / Code Cleanup – Improves readability or maintainability without changing functionality.
  • 📝 Documentation update – Changes to README, docs/, CONTRIBUTING.md, or other docs.

🤖 AI Assistance (X in brackets)

If you used an AI tool (GitHub Copilot, Claude, ChatGPT, etc.) to write or generate any code in this PR, you must confirm compliance below.
Select exactly one option.

  • No AI used – Code was written without AI assistance.
  • AI was used – The output has been reviewed and corrected, and I take responsibility for it matching this repo's conventions.

_deploy_unpacked_archive and _deploy_source_tarball wiped the target for
CLEAN_INSTALL=1 before extracting into the workdir. Any failure after the
wipe left an empty target: a truncated download, an archive that unpacks to
nothing, or a disk that fills up while it unpacks. Update scripts such as
ct/pulse.sh then have no binary left to restart.

Extraction only writes into the workdir, so the wipe now waits until the
payload has extracted and is non-empty, right before the copy.

This was fixed in ProxmoxVE's misc/tools.func by
community-scripts/ProxmoxVE#16312 the day after
tools.func was split into this repo, so the split kept the old order.

_deploy_source_tarball also refuses a tarball with no top-level directory:
unpack_dir came back empty and the copy became cp -r "/"*.
@github-actions

github-actions Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Try this branch

The engine and the scripts resolve independently, so a production script can
be run against the engine from this PR by setting one variable:

COMMUNITY_SCRIPTS_CORE_URL=https://raw.githubusercontent.com/rcourtman/core/fix/clean-install-after-extract \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/debian.sh)"

Swap ct/debian.sh for whatever exercises the change.

Run a script from a fork as well
curl -fsSL https://raw.githubusercontent.com/rcourtman/core/fix/clean-install-after-extract/tools/run.sh |
  bash -s -- https://raw.githubusercontent.com/YOU/DevScripts/your-branch ct/debian.sh \
             https://raw.githubusercontent.com/rcourtman/core/fix/clean-install-after-extract

Note that run.sh is reached through a pipe, so the script it starts inherits
an exhausted stdin. Whiptail is fine — it opens /dev/tty — but a plain read
would see EOF. The single-variable form above does not have that problem.

Useful flags while testing

dev_mode=net logs every engine fetch with status and duration, which is the
quickest way to confirm the branch is really being used. dev_mode=keep stops a
failed build from deleting the container along with the evidence.

@MickLesk

MickLesk commented Nov 4, 2026

Copy link
Copy Markdown
Member

Thanks, looks good. #16312 got lost in the split, and the guard against cp -r /* is a good catch.

Could you merge main and keep both sides of the verify-split-files.yml conflict? It is only the test list.

optional, but not blocking:

  • The comment above the wipe in _deploy_unpacked_archive could be one line; the function header already says it.
  • Two spots still wipe before the payload is there and would fit a follow-up: the git clone path (rm -rf "$target" before cloning, forge.func ~1115) and lib/alpine.func, which wipes after extracting but without the mount-point and CLEAN_INSTALL_KEEP handling.

rcourtman added 2 commits November 4, 2026 16:31
…er-extract

# Conflicts:
#	.github/workflows/verify-split-files.yml
The function header already says what CLEAN_INSTALL does and when. The
comment at the wipe only has to say why it sits after the extract.
@rcourtman

Copy link
Copy Markdown
Contributor Author

Thanks. Main is merged with both sides of the test list kept, and the comment is now one line.

On the follow-up: do you want a separate PR for the git clone path and lib/alpine.func, or would you rather leave those for now? Happy to do either.

@MickLesk

MickLesk commented Nov 4, 2026

Copy link
Copy Markdown
Member

both variants are fine for me.

@MickLesk
MickLesk merged commit 6dce64b into community-scripts:main Nov 5, 2026
5 checks passed
@rcourtman
rcourtman deleted the fix/clean-install-after-extract branch November 5, 2026 10:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants