I have an OCI VM which requires > 20% CPU utilization at the 95th percentile to avoid OCI from deleting the VM.  To avoid deletion of my VM, I intend to use the script that I provide below to artificially increase the CPU utilization.  However, there is a problem with this script, because the specified base CPU load (of 25%) is not increased by a random amount up to the specified additional percentage (of 10%) to cover the total CPU load range of 25% to 35%.  I suspect that the cause of this problem is in how the fluctuation is calculated before it is added to the specified base CPU load within the function generate_random_fluctuation() because the calculation multiplies the fluctuation by the base - which is incorrect.  Please correct the error and explain how to replace the currently running service on the VM with that of the corrected script.  Here is the function:

#!/bin/bash

# --- Configuration ---
BASE_TARGET_MIN_TOTAL_CPU_UTIL=25    # Base target minimum total CPU utilization (percentage)
ADDITIONAL_FLUCTUATION_PERCENTAGE=10  # Additional percentage of fluctuation beyond the base target
MIN_CHECK_INTERVAL_SECONDS=5.0        # Minimum check interval in seconds (can be fractional)
MAX_CHECK_INTERVAL_SECONDS=15.0       # Maximum check interval in seconds (can be fractional)
NICE_LEVEL=19                         # Lowest CPU scheduling priority

# --- Logic ---

# Function to get current overall CPU utilization (100 - idle percentage)
get_current_cpu_utilization() {
  # Get idle percentage from vmstat.
  # vmstat first line is average since boot, second line is current sample.
  # We take the second sample after a 1-second interval.
  # $15 is the 'id' (idle) column in vmstat output.
  IDLE_CPU=$(vmstat 1 2 | tail -1 | awk '{print $15}')
  CURRENT_UTILIZATION=$(echo "100 - $IDLE_CPU" | bc)
  echo "$CURRENT_UTILIZATION"
}

# Function to generate a random fluctuation beyond the specified percentage
generate_random_fluctuation() {
  local additional_fluctuation_percentage=$1
  local base_target=$2
  local fluctuation=$(echo "$additional_fluctuation_percentage * 0.01" | bc)
  local random_value=$(echo "$RANDOM % 100" | bc)
  local fluctuation_amount=$(echo "$fluctuation * $base_target * ($random_value / 100)" | bc)
  local adjusted_target=$(echo "$base_target + $fluctuation_amount" | bc)
  echo "$adjusted_target"
}

# Function to generate a random check interval within the specified range
generate_random_check_interval() {
  local min_interval=$1
  local max_interval=$2
  local range=$(echo "$max_interval - $min_interval" | bc)
  local random_fraction=$(echo "scale=6; $RANDOM / 32767" | bc)
  local interval=$(echo "$min_interval + ($range * $random_fraction)" | bc)
  echo "$interval"
}

echo "Dynamic CPU Load Manager started."
echo "Base target minimum CPU: ${BASE_TARGET_MIN_TOTAL_CPU_UTIL}%"
echo "Additional fluctuation percentage: ${ADDITIONAL_FLUCTUATION_PERCENTAGE}%"
echo "Check interval range: ${MIN_CHECK_INTERVAL_SECONDS}s to ${MAX_CHECK_INTERVAL_SECONDS}s"
echo "Nice level: ${NICE_LEVEL}"

# Ensure no orphaned stress-ng processes from previous runs if script was killed abruptly
pkill -f "stress-ng --cpu 0 --cpu-load"

while true; do
  # Generate a random check interval for this iteration
  CHECK_INTERVAL_SECONDS=$(generate_random_check_interval "$MIN_CHECK_INTERVAL_SECONDS" "$MAX_CHECK_INTERVAL_SECONDS")
  
  CURRENT_CPU_UTIL=$(get_current_cpu_utilization)
  CURRENT_CPU_UTIL_INT=${CURRENT_CPU_UTIL%.*} # Convert to integer for bash comparison

  echo "$(date): Current CPU Util: ${CURRENT_CPU_UTIL}%"

  # Generate a random fluctuation beyond the base target
  TARGET_MIN_TOTAL_CPU_UTIL=$(generate_random_fluctuation "$ADDITIONAL_FLUCTUATION_PERCENTAGE" "$BASE_TARGET_MIN_TOTAL_CPU_UTIL")

  # Check if we need to add artificial load
  if (( CURRENT_CPU_UTIL_INT < TARGET_MIN_TOTAL_CPU_UTIL )); then
    # Calculate the potential load stress-ng should attempt to generate.
    LOAD_TO_GENERATE=$TARGET_MIN_TOTAL_CPU_UTIL

    echo "$(date): Below target. Current: ${CURRENT_CPU_UTIL}%. Adding load (aiming for ${LOAD_TO_GENERATE}% on workers) for ${CHECK_INTERVAL_SECONDS}s."

    # Run stress-ng at the lowest priority.
    # Note: We're using the same random check interval for the stress-ng timeout
    nice -n "$NICE_LEVEL" stress-ng --cpu 0 --cpu-load "$LOAD_TO_GENERATE" --timeout "${CHECK_INTERVAL_SECONDS}s" --quiet &

  else
    echo "$(date): At or above target. Current: ${CURRENT_CPU_UTIL}%. No artificial load needed."
  fi

  # Wait for the next check interval.
  echo "$(date): Next check in ${CHECK_INTERVAL_SECONDS}s."
  sleep "$CHECK_INTERVAL_SECONDS"
done