mirror of
https://github.com/pgsty/minio.git
synced 2026-08-09 07:43:29 +03:00
15ab10833b
Everything a user installs is renamed, and the package finally installs enough to be startable on a clean host. Artifact names - goreleaser.yml: build id, binary, archive and checksum manifest become silo_*. release.github.name stays "minio" with a comment - the GitHub repository has not been renamed yet, and pointing at pgsty/silo before the rename would 404. Also adds per-archive SPDX SBOMs and a keyless cosign signature over the checksum manifest, so the signed manifest covers archives and SBOMs together. - nfpm.yml: package name silo, and the binary moves from /usr/local/bin/minio to /usr/bin/silo. /usr/local is not on the default PATH of a systemd unit and is not FHS-correct for a distribution package. - package-release.sh, sign-release-rpms.sh and verify-build-provenance.sh follow the new names; the RPM signing script asserts NAME=silo and the new four-file payload. nfpm is now invoked from the repository root so relative script paths in the config resolve regardless of the caller's directory. Package relationships are deliberately empty No Provides, Obsoletes, Replaces or package-level Conflicts. Obsoletes: minio cannot distinguish a pgsty package from upstream's own identically named one, so an unattended dnf upgrade could silently swap a different vendor's product for this one. With no relationships, both packages coexist, their file sets do not overlap, and migration and rollback are single explicit commands. The mutual exclusion lives in the unit instead: silo.service carries Conflicts=minio.service plus After=minio.service. Payload, from two files to four - /usr/bin/silo - /usr/lib/systemd/system/silo.service - /etc/default/silo, installed config|noreplace - /usr/lib/sysusers.d/silo.conf The old package shipped a unit referencing an account nothing created, so a clean install could not start. postinstall.sh now creates the silo system account through systemd-sysusers, useradd or BusyBox adduser in that order and runs daemon-reload. It never stops a service, never chowns data and never touches /etc/default/minio. preremove.sh disables silo.service only on a real removal - Debian "remove", RPM 0, Alpine's dotted version - so upgrades leave the running service alone. lifecycle_test.sh exercises both against a stubbed PATH, so a green run cannot create an account or touch the host. silo.service reads /etc/default/minio then /etc/default/silo, in that order, so an existing node's MINIO_* values keep working and the new file overrides them. The packaged silo.env therefore ships comments only: any active assignment would shadow the legacy file with an empty value. Makefile: build/install/install-race produce ./silo, and the docker target now assembles a context from a locally built linux binary plus Dockerfile.goreleaser instead of the deleted Dockerfile. The hotfix, hotfix-push, docker-hotfix and docker-hotfix-push targets are gone - they downloaded upstream's pkger, signed with upstream's minisign key and scp'd to dl-N.minio.io. verifiers now depends on a new rebrand-guard target. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
173 lines
4.7 KiB
Bash
Executable File
173 lines
4.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -euo pipefail
|
|
|
|
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
repo_dir="$(cd "${script_dir}/../.." && pwd)"
|
|
postinstall="${script_dir}/postinstall.sh"
|
|
preremove="${script_dir}/preremove.sh"
|
|
test_dir="$(mktemp -d)"
|
|
fakebin="${test_dir}/bin"
|
|
log_file="${test_dir}/calls.log"
|
|
useradd_shell=/usr/sbin/nologin
|
|
[ -x "${useradd_shell}" ] || useradd_shell=/sbin/nologin
|
|
busybox_shell=/sbin/nologin
|
|
[ -x "${busybox_shell}" ] || busybox_shell=/bin/false
|
|
|
|
cleanup() {
|
|
rm -rf "${test_dir}"
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
mkdir -p "${fakebin}"
|
|
touch "${log_file}"
|
|
|
|
# One dispatcher represents every external command used by the lifecycle
|
|
# scripts. The tested scripts run with no host utilities in PATH, so a green
|
|
# result cannot create a real account or touch the host service manager.
|
|
cat > "${fakebin}/fake-command" <<'EOF'
|
|
#!/bin/sh
|
|
set -eu
|
|
|
|
command_name=${0##*/}
|
|
case "${command_name}" in
|
|
id)
|
|
[ "${PACKAGE_TEST_USER_EXISTS:-0}" = 1 ]
|
|
;;
|
|
getent)
|
|
[ "${PACKAGE_TEST_GROUP_EXISTS:-0}" = 1 ]
|
|
;;
|
|
systemd-sysusers|useradd|addgroup|adduser|systemctl)
|
|
{
|
|
printf '%s' "${command_name}"
|
|
for argument in "$@"; do
|
|
printf ' %s' "${argument}"
|
|
done
|
|
printf '\n'
|
|
} >> "${PACKAGE_TEST_LOG}"
|
|
;;
|
|
*)
|
|
echo "unexpected fake command: ${command_name}" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
EOF
|
|
chmod +x "${fakebin}/fake-command"
|
|
|
|
link_command() {
|
|
ln -sf fake-command "${fakebin}/$1"
|
|
}
|
|
|
|
unlink_optional_commands() {
|
|
rm -f \
|
|
"${fakebin}/systemd-sysusers" \
|
|
"${fakebin}/useradd" \
|
|
"${fakebin}/adduser" \
|
|
"${fakebin}/addgroup"
|
|
}
|
|
|
|
reset_log() {
|
|
: > "${log_file}"
|
|
}
|
|
|
|
run_postinstall() {
|
|
PACKAGE_TEST_LOG="${log_file}" \
|
|
PACKAGE_TEST_USER_EXISTS="${1}" \
|
|
PACKAGE_TEST_GROUP_EXISTS="${2}" \
|
|
PATH="${fakebin}" \
|
|
/bin/sh "${postinstall}"
|
|
}
|
|
|
|
run_preremove() {
|
|
PACKAGE_TEST_LOG="${log_file}" PATH="${fakebin}" \
|
|
/bin/sh "${preremove}" "$@"
|
|
}
|
|
|
|
assert_log_line() {
|
|
grep -Fx -- "$1" "${log_file}" >/dev/null
|
|
}
|
|
|
|
reject_log_text() {
|
|
if grep -F -- "$1" "${log_file}" >/dev/null; then
|
|
echo "unexpected lifecycle call containing '$1':" >&2
|
|
cat "${log_file}" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
link_command id
|
|
link_command getent
|
|
link_command systemctl
|
|
|
|
# Clean install through systemd-sysusers. Side-by-side safety is represented
|
|
# by the fact that the only service-manager operation is daemon-reload: no old
|
|
# service is stopped, disabled, enabled, masked, or restarted.
|
|
unlink_optional_commands
|
|
link_command systemd-sysusers
|
|
reset_log
|
|
run_postinstall 0 0
|
|
assert_log_line "systemd-sysusers /usr/lib/sysusers.d/silo.conf"
|
|
assert_log_line "systemctl daemon-reload"
|
|
test "$(wc -l < "${log_file}" | tr -d ' ')" -eq 2
|
|
|
|
# An existing service account is preserved without modification.
|
|
reset_log
|
|
run_postinstall 1 0
|
|
test "$(cat "${log_file}")" = "systemctl daemon-reload"
|
|
|
|
# useradd creates a private group only when one does not already exist. An
|
|
# administrator may pre-create group silo with the legacy GID; that group must
|
|
# be reused rather than causing installation to fail.
|
|
unlink_optional_commands
|
|
link_command useradd
|
|
reset_log
|
|
run_postinstall 0 0
|
|
assert_log_line "useradd --system --user-group --no-create-home --shell ${useradd_shell} --comment Silo object storage service silo"
|
|
reject_log_text "--gid silo"
|
|
|
|
reset_log
|
|
run_postinstall 0 1
|
|
assert_log_line "useradd --system --gid silo --no-create-home --shell ${useradd_shell} --comment Silo object storage service silo"
|
|
reject_log_text "--user-group"
|
|
|
|
# BusyBox follows the same existing-group contract.
|
|
unlink_optional_commands
|
|
link_command adduser
|
|
link_command addgroup
|
|
reset_log
|
|
run_postinstall 0 0
|
|
assert_log_line "addgroup -S silo"
|
|
assert_log_line "adduser -S -D -H -G silo -s ${busybox_shell} silo"
|
|
|
|
reset_log
|
|
run_postinstall 0 1
|
|
reject_log_text "addgroup"
|
|
assert_log_line "adduser -S -D -H -G silo -s ${busybox_shell} silo"
|
|
|
|
# Debian remove, RPM erase, and Alpine deinstall stop the Silo unit. Upgrade
|
|
# arguments must leave the running service alone.
|
|
for removal_argument in remove 0 20260214120000.0.0-r0; do
|
|
reset_log
|
|
run_preremove "${removal_argument}"
|
|
test "$(cat "${log_file}")" = "systemctl disable --now silo.service"
|
|
done
|
|
|
|
for upgrade_argument in upgrade 1; do
|
|
reset_log
|
|
run_preremove "${upgrade_argument}"
|
|
test ! -s "${log_file}"
|
|
done
|
|
|
|
# The package deliberately leaves legacy ownership changes to an explicit
|
|
# systemd drop-in. Lifecycle scripts must never rewrite ownership or touch the
|
|
# old unit, and the base unit must expose overridable User/Group directives.
|
|
grep -Fx 'User=silo' "${repo_dir}/silo.service" >/dev/null
|
|
grep -Fx 'Group=silo' "${repo_dir}/silo.service" >/dev/null
|
|
if grep -Ein '\b(chown|chgrp|usermod|groupmod)\b|minio\.service' \
|
|
"${postinstall}" "${preremove}"; then
|
|
echo "package lifecycle scripts must not mutate data ownership or the legacy service" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "Silo package lifecycle checks passed"
|