0
[core]: alpine‐Install.func
CanbiZ edited this page 2025-12-01 10:25:56 +01:00
This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Alpine-Install.func Wiki

A specialized module for Alpine Linux LXC container setup and configuration, providing functions for IPv6 management, network verification, OS updates, SSH configuration, timezone validation, and passwordless auto-login customization.


📋 Table of Contents


Overview

This module provides Alpine Linux-specific installation and configuration functions used inside LXC containers during the setup phase. Key capabilities include:

  • IPv6 enablement/disablement with persistent configuration
  • Network connectivity verification with retry logic
  • Alpine Linux OS updates via apk package manager
  • SSH daemon and MOTD configuration
  • Passwordless root auto-login setup
  • Timezone validation for Alpine containers
  • Comprehensive error handling with signal traps

Integration Pattern

# Alpine container scripts load this module via curl
source <(curl -fsSL https://git.community-scripts.org/.../alpine-install.func)
load_functions      # Initialize core utilities
catch_errors        # Setup error handling and signal traps

Initialization & Signal Handling

Module Dependencies

The module automatically sources two required dependencies:

source <(curl -fsSL .../core.func)           # Color codes, icons, message functions
source <(curl -fsSL .../error_handler.func)  # Error handling and exit codes
load_functions                                # Initialize color/formatting
catch_errors                                  # Setup trap handlers

Signal Trap Configuration

set -Eeuo pipefail                            # Strict error mode
trap 'error_handler $? $LINENO "$BASH_COMMAND"' ERR
trap on_exit EXIT                             # Cleanup on exit
trap on_interrupt INT                         # Handle Ctrl+C (SIGINT)
trap on_terminate TERM                        # Handle SIGTERM

Network & Connectivity Functions

verb_ip6()

Purpose: Configures IPv6 settings and sets verbose mode based on environment variables.

Signature:

verb_ip6()

Parameters: None

Returns: No explicit return value (configures system state)

Environment Effects:

  • Sets STD variable to control output verbosity (via set_std_mode())
  • If DISABLEIPV6=yes: disables IPv6 system-wide via sysctl
  • Modifies /etc/sysctl.conf for persistent IPv6 disabled state

Implementation Pattern:

verb_ip6() {
  set_std_mode  # Initialize STD="" or STD="silent"

  if [ "$DISABLEIPV6" == "yes" ]; then
    $STD sysctl -w net.ipv6.conf.all.disable_ipv6=1
    echo "net.ipv6.conf.all.disable_ipv6 = 1" >>/etc/sysctl.conf
    $STD rc-update add sysctl default
  fi
}

Usage Examples:

# Example 1: With IPv6 disabled
DISABLEIPV6="yes"
VERBOSE="no"
verb_ip6
# Result: IPv6 disabled, changes persisted to sysctl.conf

# Example 2: Keep IPv6 enabled (default)
DISABLEIPV6="no"
verb_ip6
# Result: IPv6 remains enabled, no configuration changes

setting_up_container()

Purpose: Verifies network connectivity by checking for assigned IP addresses and retrying if necessary.

Signature:

setting_up_container()

Parameters: None (uses global RETRY_NUM and RETRY_EVERY)

Returns: 0 on success; exits with code 1 if network unavailable after retries

Environment Side Effects:

  • Requires: RETRY_NUM (max attempts, default: 10), RETRY_EVERY (seconds between retries, default: 3)
  • Uses: CROSS, RD, CL, GN, BL color variables from core.func
  • Calls: msg_info(), msg_ok() message functions

Implementation Pattern:

setting_up_container() {
  msg_info "Setting up Container OS"
  i=$RETRY_NUM  # Use global counter
  while [ $i -gt 0 ]; do
    # Check for non-loopback IPv4 address
    if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | ...)" != "" ]; then
      break
    fi
    echo 1>&2 -en "${CROSS}${RD} No Network! "
    sleep $RETRY_EVERY
    i=$((i - 1))
  done

  # If still no network after retries, exit with error
  if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | ...)" = "" ]; then
    exit 1
  fi
  msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | ...)${CL}"
}

Usage Examples:

# Example 1: Network available immediately
RETRY_NUM=10
RETRY_EVERY=3
setting_up_container
# Output:
#   Setting up Container OS
# ✔️  Set up Container OS
# ✔️  Network Connected: 10.0.3.50

# Example 2: Network delayed by 6 seconds (2 retries)
# Script waits 3 seconds x 2, then succeeds
# Output shows retry messages, then success

network_check()

Purpose: Comprehensive network connectivity verification for both IPv4 and IPv6, including DNS resolution checks for Git-related domains.

Signature:

network_check()

Parameters: None

Returns: 0 on success; exits with code 1 if DNS critical failure

Environment Side Effects:

  • Temporarily disables error trap (set +e, trap - ERR)
  • Modifies error handling to allow graceful failure detection
  • Re-enables error trap at end of function
  • Calls: msg_ok(), msg_error(), fatal() message functions

Implementation Pattern:

network_check() {
  set +e
  trap - ERR

  # Test IPv4 via multiple DNS servers
  if ping -c 1 -W 1 1.1.1.1 &>/dev/null || ...; then
    ipv4_status="${GN}${CL} IPv4"
  else
    ipv4_status="${RD}${CL} IPv4"
    # Prompt user to continue without internet
  fi

  # Verify DNS resolution for GitHub domains
  RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }')
  if [[ -z "$RESOLVEDIP" ]]; then
    msg_error "Internet: ${ipv4_status}  DNS Failed"
  else
    msg_ok "Internet: ${ipv4_status}  DNS: ${BL}${RESOLVEDIP}${CL}"
  fi

  set -e
  trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
}

Usage Examples:

# Example 1: Good connectivity
network_check
# Output:
# ✔️  Network Connected: IPv4
# ✔️  Internet: ✔ IPv4  DNS: 140.82.113.3

# Example 2: No internet, user continues anyway
# Output prompts: "Internet NOT connected. Continue anyway? <y/N>"
# If user enters 'y':
# ⚠️  Expect Issues Without Internet

OS Configuration Functions

update_os()

Purpose: Updates Alpine Linux OS packages and installs Alpine-specific tools library for additional setup functions.

Signature:

update_os()

Parameters: None

Returns: No explicit return value (updates system)

Environment Side Effects:

  • Runs apk update && apk upgrade
  • Sources alpine-tools.func for Alpine-specific package installation helpers
  • Uses $STD wrapper to suppress output unless VERBOSE=yes
  • Calls: msg_info(), msg_ok() message functions

Implementation Pattern:

update_os() {
  msg_info "Updating Container OS"
  $STD apk update && $STD apk upgrade
  source <(curl -fsSL https://git.community-scripts.org/.../alpine-tools.func)
  msg_ok "Updated Container OS"
}

Usage Examples:

# Example 1: Standard update
VERBOSE="no"
update_os
# Output:
#   Updating Container OS
# ✔️  Updated Container OS
# (Output suppressed via $STD)

# Example 2: Verbose mode
VERBOSE="yes"
update_os
# Output shows all apk operations plus success message

SSH & MOTD Configuration

motd_ssh()

Purpose: Configures Message of the Day (MOTD) with container information and enables SSH root access if required.

Signature:

motd_ssh()

Parameters: None

Returns: No explicit return value (configures system)

Environment Side Effects:

  • Modifies /root/.bashrc to set TERM environment variable
  • Creates /etc/profile.d/00_lxc-details.sh with container information script
  • If SSH_ROOT=yes: modifies /etc/ssh/sshd_config and starts SSH daemon
  • Uses: APPLICATION, SSH_ROOT variables from environment
  • Requires: color variables (BOLD, YW, RD, GN, CL) from core.func

Implementation Pattern:

motd_ssh() {
  # Configure TERM for better terminal support
  echo "export TERM='xterm-256color'" >>/root/.bashrc

  # Gather OS information
  OS_NAME=$(grep ^NAME /etc/os-release | cut -d= -f2 | tr -d '"')
  OS_VERSION=$(grep ^VERSION_ID /etc/os-release | cut -d= -f2 | tr -d '"')
  IP=$(ip -4 addr show eth0 | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1)

  # Create MOTD script with container details
  PROFILE_FILE="/etc/profile.d/00_lxc-details.sh"
  cat > "$PROFILE_FILE" <<'EOF'
echo -e ""
echo -e "${BOLD}${YW}${APPLICATION} LXC Container - DEV Repository${CL}"
echo -e "${RD}WARNING: This is a DEVELOPMENT version (ProxmoxVED). Do NOT use in production!${CL}"
echo -e "${YW} OS: ${GN}${OS_NAME} - Version: ${OS_VERSION}${CL}"
echo -e "${YW} Hostname: ${GN}$(hostname)${CL}"
echo -e "${YW} IP Address: ${GN}${IP}${CL}"
echo -e "${YW} Repository: ${GN}https://github.com/community-scripts/ProxmoxVED${CL}"
echo ""
EOF

  # Enable SSH root access if configured
  if [[ "${SSH_ROOT}" == "yes" ]]; then
    sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config
    rc-update add sshd
    /etc/init.d/sshd start
  fi
}

Usage Examples:

# Example 1: MOTD configuration with SSH enabled
APPLICATION="MyApp"
SSH_ROOT="yes"
motd_ssh
# Result: SSH daemon started and set to auto-start, MOTD shows app info

# Example 2: MOTD only (SSH disabled)
APPLICATION="MyApp"
SSH_ROOT="no"
motd_ssh
# Result: MOTD configured but SSH remains disabled

Container Customization

validate_tz()

Purpose: Validates that a timezone string exists in the Alpine Linux timezone database.

Signature:

validate_tz()

Parameters:

  • $1 - Timezone string (e.g., "America/New_York", "UTC", "Europe/London")

Returns: 0 if timezone file exists, 1 if invalid

Implementation Pattern:

validate_tz() {
  [[ -f "/usr/share/zoneinfo/$1" ]]  # Bash test operator returns success/failure
}

Usage Examples:

# Example 1: Valid timezone
validate_tz "America/New_York"
echo $?  # Output: 0

# Example 2: Invalid timezone
validate_tz "Invalid/Timezone"
echo $?  # Output: 1

# Example 3: UTC (always valid)
validate_tz "UTC"
echo $?  # Output: 0

customize()

Purpose: Configures container for passwordless root auto-login and creates update script for easy application re-deployment.

Signature:

customize()

Parameters: None (uses global PASSWORD and app variables)

Returns: No explicit return value (configures system)

Environment Side Effects:

  • If PASSWORD="" (empty):
    • Removes password prompt from root login
    • Drops user into shell automatically
    • Creates autologin boot script at /etc/local.d/autologin.start
    • Creates .hushlogin to suppress login banners
    • Registers script with rc-update
  • Creates /usr/bin/update script for application updates
  • Requires: app variable (application name in lowercase)
  • Calls: msg_info(), msg_ok() message functions

Implementation Pattern:

customize() {
  if [[ "$PASSWORD" == "" ]]; then
    msg_info "Customizing Container"

    # Remove password requirement
    passwd -d root >/dev/null 2>&1

    # Install util-linux if needed
    apk add --no-cache --force-broken-world util-linux >/dev/null 2>&1

    # Create autologin startup script
    mkdir -p /etc/local.d
    cat > /etc/local.d/autologin.start <<'EOF'
#!/bin/sh
sed -i 's|^tty1::respawn:.*|tty1::respawn:/sbin/agetty --autologin root --noclear tty1 38400 linux|' /etc/inittab
kill -HUP 1
EOF
    chmod +x /etc/local.d/autologin.start
    touch /root/.hushlogin

    rc-update add local >/dev/null 2>&1
    /etc/local.d/autologin.start

    msg_ok "Customized Container"
  fi

  # Create update script
  echo "bash -c \"\$(curl -fsSL https://github.com/community-scripts/ProxmoxVED/raw/main/ct/${app}.sh)\"" >/usr/bin/update
  chmod +x /usr/bin/update
}

Usage Examples:

# Example 1: Passwordless auto-login
PASSWORD=""
app="myapp"
customize
# Result: Root login without password, auto-login configured
# User can type: /usr/bin/update to re-run application setup

# Example 2: Password-protected login
PASSWORD="MySecurePassword"
customize
# Result: Auto-login skipped, password remains active
# Update script still created for re-deployment

Best Practices

1. Initialization Order

Always follow this sequence in Alpine install scripts:

#!/bin/sh
set -Eeuo pipefail

# 1. Ensure curl is available for sourcing functions
if ! command -v curl >/dev/null 2>&1; then
  apk update && apk add curl >/dev/null 2>&1
fi

# 2. Source dependencies in correct order
source <(curl -fsSL .../core.func)
source <(curl -fsSL .../error_handler.func)

# 3. Initialize function libraries
load_functions      # Sets up colors, formatting, icons
catch_errors        # Configures error traps and signal handlers

# 4. Now safe to call alpine-install.func functions
verb_ip6
setting_up_container
network_check
update_os

2. Signal Handling

Alpine-install.func provides comprehensive signal trap setup:

# ERR trap: Catches all command failures
trap 'error_handler $? $LINENO "$BASH_COMMAND"' ERR

# EXIT trap: Cleanup on normal or abnormal termination
trap on_exit EXIT

# INT trap: Handle Ctrl+C gracefully
trap on_interrupt INT

# TERM trap: Handle SIGTERM signal
trap on_terminate TERM

3. Network Configuration

Use retry logic when network may not be immediately available:

setting_up_container  # Retries up to RETRY_NUM times
network_check         # Validates DNS and Internet

4. IPv6 Considerations

For production Alpine containers:

# Disable IPv6 if not needed (reduces attack surface)
DISABLEIPV6="yes"
verb_ip6

# Or keep enabled (default):
DISABLEIPV6="no"
# No configuration needed

5. Error Handling with Color Output

Functions use color-coded message output:

msg_info   # Informational messages (yellow)
msg_ok     # Success messages (green)
msg_error  # Error messages (red)
msg_warn   # Warning messages (orange)

Error Handling

The module implements comprehensive error handling:

Exit Codes

Code Meaning
0 Success
1 General error (network unavailable, DNS failed, etc.)
130 Interrupted by user (SIGINT)
143 Terminated by signal (SIGTERM)

Error Handler Function

The error_handler receives three parameters:

error_handler() {
  local exit_code="$1"     # Exit code from failed command
  local line_number="$2"   # Line where error occurred
  local command="$3"       # Command that failed

  # Errors are reported with line number and command details
  # Stack trace available for debugging
}

Debug Variables

Available for troubleshooting:

$VERBOSE          # Set to "yes" to show all output
$DEV_MODE_TRACE   # Set to "true" for bash -x tracing
$DEV_MODE_LOGS    # Set to "true" to persist logs

Contributing

Adding New Functions

When adding Alpine-specific functions:

  1. Follow the established naming convention: function_purpose()
  2. Include comprehensive docstring with signature, parameters, returns
  3. Use color variables from core.func for output consistency
  4. Handle errors via error_handler trap
  5. Document all environment variable dependencies

Testing New Functions

# Test function in isolation with error traps:
set -Eeuo pipefail
trap 'error_handler $? $LINENO "$BASH_COMMAND"' ERR

source <(curl -fsSL .../core.func)
source <(curl -fsSL .../error_handler.func)
load_functions
catch_errors

# Now test your function:
your_function

Compatibility

  • Alpine Linux 3.16+ (uses ash shell compatible syntax)
  • OpenRC init system (rc-update, rc-service)
  • Requires: core.func, error_handler.func
  • Optional: alpine-tools.func (for extended package management)

Notes

  • Functions are designed for execution inside LXC containers (not on Proxmox host)
  • Alpine uses apk package manager (not apt)
  • Alpine uses OpenRC (not systemd) - use rc-update and /etc/init.d/ commands
  • IPv6 can be disabled for security/performance but is enabled by default
  • Auto-login configuration persists across container reboots via rc-update