179 lines
4.8 KiB
Bash
Executable File

#!/usr/bin/env bash
set -Eeuo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
INSTALL_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
REPO_ROOT="$(cd "${INSTALL_DIR}/.." && pwd)"
# shellcheck source=install/lib/common.sh
source "${INSTALL_DIR}/lib/common.sh"
# shellcheck source=install/lib/logging.sh
source "${INSTALL_DIR}/lib/logging.sh"
# shellcheck source=install/lib/packages.sh
source "${INSTALL_DIR}/lib/packages.sh"
atlas_set_script_name "10-dotnet.sh"
atlas_install_error_trap
REQUIRED_OS_ID="ubuntu"
REQUIRED_OS_VERSION="26.04"
DOTNET_BACKPORTS_PPA="ppa:dotnet/backports"
DOTNET_REQUIRED_PACKAGES=("dotnet-sdk-8.0" "dotnet-sdk-10.0")
usage() {
cat <<'USAGE'
Usage: install/phases/10-dotnet.sh [options]
Install the Atlas .NET development SDKs from official Ubuntu package feeds.
Required SDKs:
dotnet-sdk-8.0
dotnet-sdk-10.0
Options:
--help Show this help text.
--version Show script/framework version.
--dry-run Show intended actions without making changes.
--verbose Print additional diagnostic output.
USAGE
}
while [[ "$#" -gt 0 ]]; do
case "$1" in
--help)
usage
exit "${ATLAS_EXIT_OK}"
;;
--version)
atlas_print_version
exit "${ATLAS_EXIT_OK}"
;;
--dry-run)
atlas_enable_dry_run
;;
--verbose)
atlas_enable_verbose
;;
*)
atlas_usage_error "Unknown option: $1"
exit "${ATLAS_EXIT_USAGE}"
;;
esac
shift
done
load_os_release() {
if [[ ! -r /etc/os-release ]]; then
atlas_log_error "/etc/os-release is not readable"
exit "${ATLAS_EXIT_PREREQ}"
fi
# shellcheck disable=SC1091
. /etc/os-release
if [[ "${ID:-}" != "${REQUIRED_OS_ID}" || "${VERSION_ID:-}" != "${REQUIRED_OS_VERSION}" ]]; then
atlas_log_error "Unsupported OS: ${PRETTY_NAME:-unknown}; expected Ubuntu 26.04"
exit "${ATLAS_EXIT_PREREQ}"
fi
}
package_has_candidate() {
local package_name="$1"
local candidate
candidate="$(apt-cache policy "$package_name" 2>/dev/null | awk -F: '/Candidate:/ {gsub(/^[ \t]+/, "", $2); print $2; exit}')"
[[ -n "$candidate" && "$candidate" != "(none)" ]]
}
backports_configured() {
grep -RqsE 'ppa\\.launchpadcontent\\.net/dotnet/backports|LP-PPA-dotnet-backports|dotnet-ubuntu-backports' /etc/apt/sources.list /etc/apt/sources.list.d 2>/dev/null
}
ensure_backports_if_needed() {
if package_has_candidate dotnet-sdk-8.0; then
atlas_log_info "dotnet-sdk-8.0 is available from configured package sources"
return 0
fi
if backports_configured; then
atlas_log_info "Ubuntu .NET backports repository is configured; refreshing package metadata"
atlas_sudo_run apt-get update
return 0
fi
atlas_log_info "dotnet-sdk-8.0 is not available; adding official Ubuntu .NET backports repository"
if [[ "${ATLAS_DRY_RUN}" == "1" ]]; then
atlas_log_info "Dry-run mode: would run add-apt-repository -y ${DOTNET_BACKPORTS_PPA}"
atlas_log_info "Dry-run mode: would run apt-get update"
return 0
fi
atlas_require_command add-apt-repository
atlas_sudo_run add-apt-repository -y "${DOTNET_BACKPORTS_PPA}"
atlas_sudo_run apt-get update
}
install_missing_sdks() {
local missing=()
local package_name
for package_name in "${DOTNET_REQUIRED_PACKAGES[@]}"; do
if atlas_package_installed "$package_name"; then
atlas_log_ok "${package_name} is already installed"
else
missing+=("$package_name")
fi
done
if [[ "${#missing[@]}" -eq 0 ]]; then
atlas_log_ok "All required .NET SDK packages are installed"
return 0
fi
for package_name in "${missing[@]}"; do
if [[ "${ATLAS_DRY_RUN}" == "1" ]]; then
atlas_log_info "Dry-run mode: would verify package candidate for ${package_name}"
continue
fi
if ! package_has_candidate "$package_name"; then
atlas_log_error "No official configured package candidate found for ${package_name}"
exit "${ATLAS_EXIT_PREREQ}"
fi
done
atlas_install_packages "${missing[@]}"
}
verify_dotnet() {
atlas_require_command dotnet
dotnet --list-sdks | grep -q '^8\.' || {
atlas_log_error ".NET 8 SDK was not found after installation"
exit "${ATLAS_EXIT_VALIDATION}"
}
dotnet --list-sdks | grep -q '^10\.' || {
atlas_log_error ".NET 10 SDK was not found after installation"
exit "${ATLAS_EXIT_VALIDATION}"
}
atlas_log_ok ".NET SDK verification passed"
}
main() {
load_os_release
atlas_require_sudo_noninteractive || {
atlas_log_error "Passwordless non-interactive sudo is required"
exit "${ATLAS_EXIT_PREREQ}"
}
atlas_require_command apt-cache
atlas_require_command apt-get
atlas_require_command dpkg-query
ensure_backports_if_needed
install_missing_sdks
if [[ "${ATLAS_DRY_RUN}" == "1" ]]; then
atlas_log_info "Dry-run mode: skipping post-install dotnet verification"
else
verify_dotnet
fi
}
main