276 lines
9.5 KiB
Bash
276 lines
9.5 KiB
Bash
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
# Log function
|
|
log() {
|
|
echo "[APT-WRAPPER] $1"
|
|
}
|
|
|
|
# Function to add repository files
|
|
add_repos() {
|
|
local repos_config="$1"
|
|
local cleanup=false
|
|
|
|
# Check if cleanup is enabled
|
|
if echo "$repos_config" | jq -e '.cleanup' >/dev/null 2>&1; then
|
|
cleanup=$(echo "$repos_config" | jq -r '.cleanup')
|
|
fi
|
|
|
|
# Add repository files
|
|
if echo "$repos_config" | jq -e '.files' >/dev/null 2>&1; then
|
|
local files=$(echo "$repos_config" | jq -r '.files[]? // empty')
|
|
for file in $files; do
|
|
if [[ $file == http* ]]; then
|
|
log "Downloading repository file: $file"
|
|
curl -fsSL "$file" -o "/etc/apt/sources.list.d/$(basename "$file")"
|
|
else
|
|
log "Copying repository file: $file"
|
|
cp "$file" "/etc/apt/sources.list.d/"
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Add PPA repositories
|
|
if echo "$repos_config" | jq -e '.ppa' >/dev/null 2>&1; then
|
|
local ppas=$(echo "$repos_config" | jq -r '.ppa[]? // empty')
|
|
for ppa in $ppas; do
|
|
log "Adding PPA: $ppa"
|
|
add-apt-repository -y "$ppa"
|
|
done
|
|
fi
|
|
|
|
# Add GPG keys
|
|
if echo "$repos_config" | jq -e '.keys' >/dev/null 2>&1; then
|
|
local keys=$(echo "$repos_config" | jq -r '.keys[]? // empty')
|
|
for key in $keys; do
|
|
if [[ $key == http* ]]; then
|
|
log "Downloading and adding GPG key: $key"
|
|
curl -fsSL "$key" | apt-key add -
|
|
else
|
|
log "Adding GPG key: $key"
|
|
apt-key add "$key"
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Enable backports if requested
|
|
if echo "$repos_config" | jq -e '.backports' >/dev/null 2>&1; then
|
|
local backports=$(echo "$repos_config" | jq -r '.backports')
|
|
if [ "$backports" = "true" ]; then
|
|
log "Enabling backports repository"
|
|
echo "deb http://deb.debian.org/debian $(lsb_release -cs)-backports main" > /etc/apt/sources.list.d/backports.list
|
|
fi
|
|
fi
|
|
|
|
# Update package lists
|
|
log "Updating package lists"
|
|
apt-get update
|
|
|
|
# Clean up repositories if requested
|
|
if [ "$cleanup" = "true" ]; then
|
|
log "Cleaning up added repositories"
|
|
rm -f /etc/apt/sources.list.d/*.list
|
|
apt-get update
|
|
fi
|
|
}
|
|
|
|
# Function to handle /opt/ symlinking
|
|
handle_optfix() {
|
|
local optfix_config="$1"
|
|
if [ -n "$optfix_config" ]; then
|
|
local optfixes=$(echo "$optfix_config" | jq -r '.[]? // empty')
|
|
for optfix in $optfixes; do
|
|
log "Setting up /opt/ symlink for: $optfix"
|
|
mkdir -p "/opt/$optfix"
|
|
ln -sf "/opt/$optfix" "/usr/local/$optfix"
|
|
done
|
|
fi
|
|
}
|
|
|
|
# Function to install packages
|
|
install_packages() {
|
|
local install_config="$1"
|
|
local skip_unavailable=false
|
|
|
|
# Check if skip-unavailable is enabled
|
|
if echo "$install_config" | jq -e '.skip-unavailable' >/dev/null 2>&1; then
|
|
skip_unavailable=$(echo "$install_config" | jq -r '.skip-unavailable')
|
|
fi
|
|
|
|
# Install packages
|
|
if echo "$install_config" | jq -e '.packages' >/dev/null 2>&1; then
|
|
local packages=$(echo "$install_config" | jq -r '.packages[]? // empty')
|
|
for package in $packages; do
|
|
if echo "$package" | jq -e '.repo' >/dev/null 2>&1; then
|
|
# Package from specific repository
|
|
local repo=$(echo "$package" | jq -r '.repo')
|
|
local repo_packages=$(echo "$package" | jq -r '.packages[]? // empty')
|
|
for repo_package in $repo_packages; do
|
|
log "Installing $repo_package from repository $repo"
|
|
apt-get install -y "$repo_package" || {
|
|
if [ "$skip_unavailable" = "true" ]; then
|
|
log "WARNING: Package $repo_package not available, skipping"
|
|
else
|
|
log "ERROR: Failed to install package $repo_package"
|
|
exit 1
|
|
fi
|
|
}
|
|
done
|
|
else
|
|
# Direct package specification
|
|
if [[ $package == http* && $package == *.deb ]]; then
|
|
log "Downloading and installing .deb package: $package"
|
|
curl -fsSL "$package" -o /tmp/package.deb
|
|
dpkg -i /tmp/package.deb || apt-get install -f -y
|
|
rm -f /tmp/package.deb
|
|
else
|
|
log "Installing package: $package"
|
|
apt-get install -y "$package" || {
|
|
if [ "$skip_unavailable" = "true" ]; then
|
|
log "WARNING: Package $package not available, skipping"
|
|
else
|
|
log "ERROR: Failed to install package $package"
|
|
exit 1
|
|
fi
|
|
}
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
}
|
|
|
|
# Function to remove packages
|
|
remove_packages() {
|
|
local remove_config="$1"
|
|
if echo "$remove_config" | jq -e '.packages' >/dev/null 2>&1; then
|
|
local packages=$(echo "$remove_config" | jq -r '.packages[]? // empty')
|
|
for package in $packages; do
|
|
log "Removing package: $package"
|
|
apt-get remove -y "$package" || {
|
|
log "WARNING: Failed to remove package $package"
|
|
}
|
|
done
|
|
fi
|
|
}
|
|
|
|
# Function to replace packages
|
|
replace_packages() {
|
|
local replace_config="$1"
|
|
if echo "$replace_config" | jq -e '.[]' >/dev/null 2>&1; then
|
|
local replacements=$(echo "$replace_config" | jq -c '.[]')
|
|
echo "$replacements" | while read -r replacement; do
|
|
local from_repo=$(echo "$replacement" | jq -r '.from-repo // empty')
|
|
local packages=$(echo "$replacement" | jq -r '.packages[]? // empty')
|
|
local skip_unavailable=$(echo "$replacement" | jq -r '.skip-unavailable // false')
|
|
|
|
log "Replacing packages from repository: $from_repo"
|
|
for package in $packages; do
|
|
log "Replacing package: $package"
|
|
apt-get install -y "$package" || {
|
|
if [ "$skip_unavailable" = "true" ]; then
|
|
log "WARNING: Package $package not available, skipping"
|
|
else
|
|
log "ERROR: Failed to replace package $package"
|
|
exit 1
|
|
fi
|
|
}
|
|
done
|
|
done
|
|
fi
|
|
}
|
|
|
|
# Function to install task packages
|
|
install_tasks() {
|
|
local task_config="$1"
|
|
if echo "$task_config" | jq -e '.packages' >/dev/null 2>&1; then
|
|
local with_optional=$(echo "$task_config" | jq -r '.with-optional // false')
|
|
local packages=$(echo "$task_config" | jq -r '.packages[]? // empty')
|
|
|
|
for task in $packages; do
|
|
log "Installing task: $task"
|
|
if [ "$with_optional" = "true" ]; then
|
|
tasksel install "$task" || {
|
|
log "WARNING: Failed to install task $task"
|
|
}
|
|
else
|
|
tasksel install "$task" || {
|
|
log "WARNING: Failed to install task $task"
|
|
}
|
|
fi
|
|
done
|
|
fi
|
|
}
|
|
|
|
# Function to remove task packages
|
|
remove_tasks() {
|
|
local task_config="$1"
|
|
if echo "$task_config" | jq -e '.packages' >/dev/null 2>&1; then
|
|
local packages=$(echo "$task_config" | jq -r '.packages[]? // empty')
|
|
|
|
for task in $packages; do
|
|
log "Removing task: $task"
|
|
tasksel remove "$task" || {
|
|
log "WARNING: Failed to remove task $task"
|
|
}
|
|
done
|
|
fi
|
|
}
|
|
|
|
# Main execution
|
|
main() {
|
|
local module_config="$1"
|
|
|
|
log "Starting apt module execution"
|
|
|
|
# Handle repositories
|
|
if echo "$module_config" | jq -e '.repos' >/dev/null 2>&1; then
|
|
log "Processing repositories configuration"
|
|
add_repos "$(echo "$module_config" | jq -c '.repos')"
|
|
fi
|
|
|
|
# Handle /opt/ symlinking
|
|
if echo "$module_config" | jq -e '.optfix' >/dev/null 2>&1; then
|
|
log "Processing optfix configuration"
|
|
handle_optfix "$(echo "$module_config" | jq -c '.optfix')"
|
|
fi
|
|
|
|
# Handle package installation
|
|
if echo "$module_config" | jq -e '.install' >/dev/null 2>&1; then
|
|
log "Processing package installation"
|
|
install_packages "$(echo "$module_config" | jq -c '.install')"
|
|
fi
|
|
|
|
# Handle package removal
|
|
if echo "$module_config" | jq -e '.remove' >/dev/null 2>&1; then
|
|
log "Processing package removal"
|
|
remove_packages "$(echo "$module_config" | jq -c '.remove')"
|
|
fi
|
|
|
|
# Handle package replacement
|
|
if echo "$module_config" | jq -e '.replace' >/dev/null 2>&1; then
|
|
log "Processing package replacement"
|
|
replace_packages "$(echo "$module_config" | jq -c '.replace')"
|
|
fi
|
|
|
|
# Handle task installation
|
|
if echo "$module_config" | jq -e '.task-install' >/dev/null 2>&1; then
|
|
log "Processing task installation"
|
|
install_tasks "$(echo "$module_config" | jq -c '.task-install')"
|
|
fi
|
|
|
|
# Handle task removal
|
|
if echo "$module_config" | jq -e '.task-remove' >/dev/null 2>&1; then
|
|
log "Processing task removal"
|
|
remove_tasks "$(echo "$module_config" | jq -c '.task-remove')"
|
|
fi
|
|
|
|
# Clean up
|
|
log "Cleaning up package cache"
|
|
apt-get clean
|
|
apt-get autoremove -y
|
|
|
|
log "apt module execution completed successfully"
|
|
}
|
|
|
|
# Execute main function with the module configuration
|
|
main "$1"
|