hftestx/67b8b004
0
1#!/bin/bash2 3set -e4 5# Restic Backup Utility Script6# Provides independent backup functionality, can be called by other scripts7 8# Logging functions9log() {10 echo "[$(date '+%Y-%m-%d %H:%M:%S')] [BACKUP] $*"11}12 13log_success() {14 echo -e "\033[32m[$(date '+%Y-%m-%d %H:%M:%S')] [SUCCESS] $*\033[0m"15}16 17log_error() {18 echo -e "\033[31m[$(date '+%Y-%m-%d %H:%M:%S')] [ERROR] $*\033[0m"19}20 21log_warn() {22 echo -e "\033[33m[$(date '+%Y-%m-%d %H:%M:%S')] [WARN] $*\033[0m"23}24 25# Display usage instructions26show_usage() {27 cat << EOF28Usage: $0 [options] [paths...]29 30Options:31 -c, --config FILE Specify configuration file path32 -r, --repository DIR Specify repository path (overrides config file)33 -p, --password PASS Specify password (overrides config file)34 -t, --tag TAG Add backup tag (can be used multiple times)35 -e, --exclude PATTERN Add exclude pattern (can be used multiple times)36 --compression MODE Compression mode: off, fastest, auto, better, max (default: auto)37 -v, --verbose Enable verbose output38 -n, --dry-run Only show operations to be executed39 -h, --help Show this help message40 41Compression mode explanation:42 off - No compression (fastest backup speed)43 fastest - Fastest compression (minimal CPU usage)44 auto - Auto compression (default, balanced speed and compression ratio)45 better - Better compression (more CPU, better compression ratio)46 max - Maximum compression (highest CPU, best compression ratio)47 48Examples:49 $0 # Backup using default configuration50 $0 /home/user/data # Backup specified path51 $0 -t "manual" -v /important # Verbose backup with tag52 $0 --compression max -v # Verbose backup with maximum compression53 $0 -c custom.conf -n # Dry run with custom configuration54 55EOF56}57 58# Load configuration file59load_config() {60 local config_file="$1"61 62 if [[ -f "$config_file" ]]; then63 log "Loading configuration file: $config_file"64 65 # Use safe configuration loading method66 local temp_config="/tmp/restic_backup_config_$$"67 sed 's/^\([^#]*\)=\(.*\)$/\1=${\1:-\2}/' "$config_file" > "$temp_config"68 source "$temp_config"69 rm -f "$temp_config"70 71 log_success "Configuration loaded (environment variables take precedence)"72 else73 log_warn "Configuration file does not exist: $config_file"74 fi75}76 77# Set environment variables78setup_environment() {79 # Check necessary configuration variables80 if [[ -z "$RESTIC_REPOSITORY_PATH" ]]; then81 log_error "RESTIC_REPOSITORY_PATH not set, please check configuration file or environment variables"82 return 183 fi84 85 # Check password setting86 if [[ -z "${RESTIC_PASSWORD:-}" ]]; then87 log_error "RESTIC_PASSWORD not set, please check configuration file or environment variables"88 return 189 fi90 91 log "Using password from environment variables"92 93 # Export environment variables94 export RESTIC_REPOSITORY="$RESTIC_REPOSITORY_PATH"95 export RESTIC_PASSWORD96 export RESTIC_CACHE_DIR97 98 # Set performance tuning environment variables (read from config file or environment variables)99 [[ -n "$RESTIC_MAX_PROCS" ]] && export GOMAXPROCS="$RESTIC_MAX_PROCS"100 [[ -n "$RESTIC_TEMP_DIR" ]] && export TMPDIR="$RESTIC_TEMP_DIR"101 [[ -n "$RESTIC_FEATURES" ]] && export RESTIC_FEATURES102 103 # Check restic command104 if ! command -v restic &> /dev/null; then105 log_error "restic command not found"106 return 1107 fi108 109 log_success "Environment setup completed"110}111 112# Validate backup paths113validate_paths() {114 local paths=("$@")115 local valid_paths=()116 117 for path in "${paths[@]}"; do118 if [[ -e "$path" ]]; then119 valid_paths+=("$path")120 log "Valid path: $path"121 else122 log_warn "Path does not exist: $path"123 fi124 done125 126 if [[ ${#valid_paths[@]} -eq 0 ]]; then127 log_error "No valid backup paths"128 return 1129 fi130 131 # Store valid paths in global variable132 VALIDATED_PATHS=("${valid_paths[@]}")133 return 0134}135 136# Perform backup137perform_backup() {138 local dry_run="$1"139 shift140 local backup_paths=("$@")141 142 log "Starting backup operation..."143 144 # If no paths specified, use paths from configuration145 if [[ ${#backup_paths[@]} -eq 0 ]]; then146 IFS=':' read -ra backup_paths <<< "$RESTIC_BACKUP_PATHS"147 fi148 149 # Validate paths150 if ! validate_paths "${backup_paths[@]}"; then151 return 1152 fi153 154 # Build backup command arguments155 local args=("backup")156 157 # Add exclude patterns158 if [[ -n "$RESTIC_EXCLUDE_PATTERNS" ]]; then159 IFS=',' read -ra patterns <<< "$RESTIC_EXCLUDE_PATTERNS"160 for pattern in "${patterns[@]}"; do161 args+=("--exclude" "$pattern")162 done163 fi164 165 # Add extra exclude patterns (from command line)166 for exclude in "${EXTRA_EXCLUDES[@]}"; do167 args+=("--exclude" "$exclude")168 done169 170 # Add tags171 if [[ -n "$RESTIC_BACKUP_TAG" ]]; then172 IFS=',' read -ra tags <<< "$RESTIC_BACKUP_TAG"173 for tag in "${tags[@]}"; do174 args+=("--tag" "$tag")175 done176 fi177 178 # Add extra tags (from command line)179 for tag in "${EXTRA_TAGS[@]}"; do180 args+=("--tag" "$tag")181 done182 183 # Add options184 [[ "$RESTIC_VERBOSE" == "true" ]] && args+=("--verbose")185 186 # Add compression option187 args+=("--compression" "$RESTIC_COMPRESSION")188 189 # New: Performance tuning options (prioritize RESTIC_READ_CONCURRENCY, otherwise use RESTIC_PARALLEL_UPLOADS)190 if [[ -n "$RESTIC_READ_CONCURRENCY" ]]; then191 args+=("--read-concurrency" "$RESTIC_READ_CONCURRENCY")192 elif [[ -n "$RESTIC_PARALLEL_UPLOADS" ]]; then193 args+=("--read-concurrency" "$RESTIC_PARALLEL_UPLOADS")194 fi195 [[ -n "$RESTIC_PACK_SIZE" ]] && args+=("--pack-size" "$RESTIC_PACK_SIZE")196 [[ "$RESTIC_NO_SCAN" == "true" ]] && args+=("--no-scan")197 [[ "$RESTIC_EXTRA_VERIFY" == "false" ]] && args+=("--no-extra-verify")198 [[ "$RESTIC_NO_CACHE" == "true" ]] && args+=("--no-cache")199 200 # New: Backend connection configuration201 if [[ -n "$RESTIC_BACKEND_CONNECTIONS" ]]; then202 # Auto-detect backend type203 if [[ "$RESTIC_REPOSITORY_PATH" =~ ^s3: ]]; then204 args+=("-o" "s3.connections=$RESTIC_BACKEND_CONNECTIONS")205 elif [[ "$RESTIC_REPOSITORY_PATH" =~ ^rest: ]]; then206 args+=("-o" "rest.connections=$RESTIC_BACKEND_CONNECTIONS")207 elif [[ "$RESTIC_REPOSITORY_PATH" =~ ^sftp: ]]; then208 args+=("-o" "sftp.connections=$RESTIC_BACKEND_CONNECTIONS")209 else210 # Local backend211 args+=("-o" "local.connections=$RESTIC_BACKEND_CONNECTIONS")212 fi213 fi214 215 # Add paths216 args+=("${VALIDATED_PATHS[@]}")217 218 log "Executing command: restic ${args[*]}"219 220 if [[ "$dry_run" == "true" ]]; then221 log_warn "Dry run mode - actual backup not executed"222 return 0223 fi224 225 # Execute backup226 if restic "${args[@]}"; then227 log_success "Backup completed successfully"228 return 0229 else230 log_error "Backup failed"231 return 1232 fi233}234 235# Main function236main() {237 # Parse command line arguments238 local config_file=""239 local dry_run="false"240 local backup_paths=()241 local EXTRA_TAGS=()242 local EXTRA_EXCLUDES=()243 244 while [[ $# -gt 0 ]]; do245 case $1 in246 -c|--config)247 config_file="$2"248 shift 2249 ;;250 -r|--repository)251 RESTIC_REPOSITORY_PATH="$2"252 shift 2253 ;;254 -p|--password)255 RESTIC_PASSWORD="$2"256 shift 2257 ;;258 -t|--tag)259 EXTRA_TAGS+=("$2")260 shift 2261 ;;262 -e|--exclude)263 EXTRA_EXCLUDES+=("$2")264 shift 2265 ;;266 --compression)267 RESTIC_COMPRESSION="$2"268 shift 2269 ;;270 -v|--verbose)271 RESTIC_VERBOSE="true"272 shift273 ;;274 -n|--dry-run)275 dry_run="true"276 shift277 ;;278 -h|--help)279 show_usage280 exit 0281 ;;282 -*)283 log_error "Unknown option: $1"284 show_usage285 exit 1286 ;;287 *)288 backup_paths+=("$1")289 shift290 ;;291 esac292 done293 294 log "======= Restic Backup Tool ======="295 296 # Load configuration file297 if [[ -n "$config_file" ]]; then298 load_config "$config_file"299 elif [[ -f "${HOME:-/home/user}/config/restic.conf" ]]; then300 load_config "${HOME:-/home/user}/config/restic.conf"301 fi302 303 # Setup environment304 if ! setup_environment; then305 exit 1306 fi307 308 # Display configuration information309 log "Backup configuration:"310 log " Repository path: $RESTIC_REPOSITORY_PATH"311 log " Cache directory: $RESTIC_CACHE_DIR"312 log " Compression mode: $RESTIC_COMPRESSION"313 log " Dry run mode: $dry_run"314 log " Performance tuning:"315 log " - Backend connections: ${RESTIC_BACKEND_CONNECTIONS:-default}"316 log " - CPU core limit: ${RESTIC_MAX_PROCS:-all available}"317 log " - Read concurrency: ${RESTIC_READ_CONCURRENCY:-default}"318 log " - Pack size: ${RESTIC_PACK_SIZE:-16}MiB"319 log " - Disable scan: ${RESTIC_NO_SCAN:-false}"320 log " - Extra verify: ${RESTIC_EXTRA_VERIFY:-true}"321 log " - Disable cache: ${RESTIC_NO_CACHE:-false}"322 [[ -n "$RESTIC_TEMP_DIR" ]] && log " - Temp directory: $RESTIC_TEMP_DIR"323 [[ -n "$RESTIC_FEATURES" ]] && log " - Feature flags: $RESTIC_FEATURES"324 [[ ${#EXTRA_TAGS[@]} -gt 0 ]] && log " Extra tags: ${EXTRA_TAGS[*]}"325 [[ ${#EXTRA_EXCLUDES[@]} -gt 0 ]] && log " Extra excludes: ${EXTRA_EXCLUDES[*]}"326 327 # Execute backup328 perform_backup "$dry_run" "${backup_paths[@]}"329}330 331# If script is executed directly (not sourced)332if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then333 main "$@"334fi 