block deployment with 1 instance left when rep contract aint running

Post Reply
wroomwroom
Posts: 50
Joined: Wed Jul 31, 2024 5:59 pm

block deployment with 1 instance left when rep contract aint running

Post by wroomwroom »

In /bin/sashimono/user-install.sh

After...

Code: Select all

max_instance_count=$(jq -r ".system.max_instance_count | select( . != null )" "$SA_CONFIG")
if [ -n "$max_instance_count" ] && [ "$max_instance_count" -gt 0 ]; then
    nofile_soft_limit=$((nofile_soft_limit / ( max_instance_count + 1 )))
    echo "setting ulimit -n to $nofile_soft_limit"
else
    echo "Error: max_instance_count is not valid or not found in $SA_CONFIG, defaulting ulimit to 55000"
    nofile_soft_limit=55000
fi
in /bin/sashimono/user-install.sh


Add following:

Code: Select all

###########################################################
# INSTANCE LIMIT / REPUTATION RESERVED SLOT CHECK
#
# IMPORTANT:
# Sashimono's sa.sqlite database is the source of truth.
# Do NOT count /home directories or Linux users.
#
# This code runs inside user-install.sh BEFORE Sashimono
# inserts the NEW instance into the database, so:
#
#   allocated instances = instances already in use
#   available slots      = max - allocated
#
###########################################################


# ---------------------------------------------------------
# Existing nofile setup
# ---------------------------------------------------------

nofile_soft_limit=$(ulimit -n -S)

if [ "$nofile_soft_limit" -lt 250000 ]; then
    ulimit -n 250000
    nofile_soft_limit=250000
fi


# ---------------------------------------------------------
# Get configured max instance count
# ---------------------------------------------------------

max_instance_count=$(jq -r '.system.max_instance_count // empty' "$SA_CONFIG")

if [[ "$max_instance_count" =~ ^[0-9]+$ ]] &&
   [ "$max_instance_count" -gt 0 ]; then

    nofile_soft_limit=$((nofile_soft_limit / (max_instance_count + 1)))

    echo "setting ulimit -n to $nofile_soft_limit"

else

    echo "Error: max_instance_count is invalid or missing from $SA_CONFIG"
    echo "INVALID_MAX_INSTANCE_COUNT,INST_ERR"
    exit 1
fi


# ---------------------------------------------------------
# Sashimono instance database
# ---------------------------------------------------------

SA_DB="/etc/sashimono/sa.sqlite"

if [ ! -f "$SA_DB" ]; then
    echo "Error: Sashimono database does not exist: $SA_DB"
    echo "SA_DATABASE_NOT_FOUND,INST_ERR"
    exit 1
fi


# ---------------------------------------------------------
# Read:
#
#   1. allocated instance count
#   2. whether a RUNNING reputation instance exists
#
# Directly from Sashimono's own database.
# ---------------------------------------------------------

if ! slot_db_result=$(
    python3 - "$SA_DB" <<'PY'
import sqlite3
import sys

db_path = sys.argv[1]

try:
    db = sqlite3.connect(
        f"file:{db_path}?mode=ro",
        uri=True,
        timeout=5
    )

    # Same concept Sashimono itself uses for allocated
    # instances: everything except destroyed instances.
    allocated = db.execute("""
        SELECT COUNT(name)
        FROM instances
        WHERE status != 'destroyed'
    """).fetchone()[0]

    # Reputation must actually be in RUNNING state and
    # have "reputation" in its image name.
    reputation = db.execute("""
        SELECT COUNT(name)
        FROM instances
        WHERE LOWER(status) = 'running'
          AND LOWER(image_name) LIKE '%reputation%'
    """).fetchone()[0]

    print(f"{int(allocated)}|{'true' if int(reputation) > 0 else 'false'}")

    db.close()

except Exception as e:
    print(f"ERROR:{e}", file=sys.stderr)
    sys.exit(1)
PY
); then

    echo "Error: failed reading Sashimono instance database."
    echo "SA_DATABASE_READ_ERROR,INST_ERR"
    exit 1
fi


# ---------------------------------------------------------
# Parse DB result
#
# Example:
#
#   2|true
# ---------------------------------------------------------

IFS='|' read -r current_instance_count reputation_running <<< "$slot_db_result"


# Validate returned instance count
if [[ ! "$current_instance_count" =~ ^[0-9]+$ ]]; then
    echo "Error: invalid allocated instance count: $current_instance_count"
    echo "SA_DATABASE_COUNT_INVALID,INST_ERR"
    exit 1
fi


# Validate reputation result
if [[ "$reputation_running" != "true" ]] &&
   [[ "$reputation_running" != "false" ]]; then

    echo "Error: invalid reputation status: $reputation_running"
    echo "SA_DATABASE_REPUTATION_INVALID,INST_ERR"
    exit 1
fi


# ---------------------------------------------------------
# Calculate remaining slots
# ---------------------------------------------------------

available_instance_count=$((max_instance_count - current_instance_count))

if [ "$available_instance_count" -lt 0 ]; then
    available_instance_count=0
fi


# ---------------------------------------------------------
# Normalize requested image and official reputation image
#
# docker_image may contain your custom:
#
#   --setting--value
#
# suffix, so strip that for comparison.
# ---------------------------------------------------------

requested_base_image="${docker_image%%--*}"
configured_reputation_image="${REPUTATION_IMAGE:-}"
configured_reputation_image="${configured_reputation_image%%--*}"


# Strip optional @sha256 digest as well
requested_base_image="${requested_base_image%%@*}"
configured_reputation_image="${configured_reputation_image%%@*}"


# ---------------------------------------------------------
# Determine if THIS deployment is the official reputation
# image.
#
# We do NOT simply trust any arbitrary image containing
# "reputation" here.
# ---------------------------------------------------------

requested_is_reputation=false

if [ -n "$configured_reputation_image" ] &&
   [ "$requested_base_image" = "$configured_reputation_image" ]; then

    requested_is_reputation=true
fi


# ---------------------------------------------------------
# Log current state
# ---------------------------------------------------------

echo
echo "##########################################################"
echo "# Instance slot check"
echo "##########################################################"
echo "Maximum instances:           $max_instance_count"
echo "Allocated instances:         $current_instance_count"
echo "Available instances:         $available_instance_count"
echo "Reputation running:          $reputation_running"
echo "Requested image:             $requested_base_image"
echo "Configured reputation image: $configured_reputation_image"
echo "Request is reputation:       $requested_is_reputation"
echo


# ---------------------------------------------------------
# Absolutely no capacity
# ---------------------------------------------------------

if [ "$available_instance_count" -le 0 ]; then

    echo "No Sashimono instance slots are available."
    echo "MAX_INSTANCES_REACHED,INST_ERR"

    # Do NOT rollback here.
    #
    # user-install.sh has not created the new $user yet.
    exit 1
fi


# ---------------------------------------------------------
# RESERVE FINAL SLOT FOR REPUTATION
#
# RULE:
#
# If only ONE slot remains AND no reputation instance
# is currently running:
#
#   normal image      -> BLOCK
#   reputation image  -> ALLOW
#
# This means the final slot cannot accidentally be taken
# by another tenant when reputation is missing.
# ---------------------------------------------------------

if [ "$available_instance_count" -eq 1 ] &&
   [ "$reputation_running" != "true" ]; then

    echo "WARNING: Only one Sashimono instance slot remains."
    echo "WARNING: No running reputation instance was found."
    echo

    if [ "$requested_is_reputation" = "true" ]; then

        echo "Requested deployment is the configured reputation image."
        echo "Allowing reputation to use the reserved final slot."
        echo

    else

        echo "Final instance slot is reserved for reputation."
        echo "Rejecting normal deployment."
        echo
        echo "LAST_SLOT_RESERVED_FOR_REPUTATION,INST_ERR"

        # IMPORTANT:
        # Do NOT call rollback here because $user has not
        # been created yet.
        exit 1
    fi

else

    # Helpful logging only
    if [ "$reputation_running" = "true" ]; then
        echo "Reputation is already running."
        echo "Reserved-slot protection is not required."
    else
        echo "More than one instance slot remains."
        echo "Reserved-slot protection is not required yet."
    fi

    echo
fi


###########################################################
# END INSTANCE LIMIT / REPUTATION RESERVED SLOT CHECK
###########################################################

Post Reply