Service Script Block Structure

Every service script follows a standardized structure composed of distinct blocks. This document defines each block, its purpose, and requirements.

Block Overview

#Block NameRequiredDescription
0Shebang✅ YesInterpreter directive
1Manifest✅ YesScript metadata (name, schedule, etc.)
2Overview❌ NoDetailed explanation of the script
3Standard Constants✅ YesPre-defined status codes and timestamp
4Configuration❌ NoUser-customizable settings
5Dependencies❌ NoExternal tools required by the script
6Main✅ YesCore monitoring logic

Block 0: Shebang (Required)

The Shebang is the first line of every script. It tells the system which interpreter to use.

bash
1#!/bin/bash

Rules:

  • Must be the very first line of the file
  • Must be exactly #!/bin/bash
  • No other interpreters are supported

Block 1: Manifest (Required)

The Manifest contains metadata about the script. It is parsed by the SSI Agent when adding the service.

bash
1# --- Manifest --- #
2# name: API Health
3# description: Checks the health of an API that has a health check endpoint
4# version: 1.0
5# schedule: *:0/01:00
6# timeout: 10

Fields:

FieldRequiredDescription
name✅ YesHuman-readable name (3-60 characters)
description✅ YesShort description (max 255 characters)
version✅ YesVersion string (e.g., 1.0, 2.1.3)
schedule✅ Yessystemd OnCalendar format
timeout❌ NoMax execution time in seconds (default: 20)

See Manifest Reference for detailed specifications.


Block 2: Overview (Optional)

The Overview block provides a detailed explanation of what the script does. Use this to describe:

  • What the script monitors
  • What conditions trigger each status
  • Expected behavior
bash
1# --- Overview --- #
2# This script calls the health check endpoint at the configured URL
3# and checks for the expected response.
4#
5# Returns "OK" if the API responds with the expected JSON.
6# Returns "WARNING" if the response differs from expected.
7# Returns "FAILURE" if the API is unreachable.

Guidelines:

  • Explain what the script does, not how it does it
  • Describe the conditions for each possible status
  • Do not explain the code itself (code should be self-documenting)

Block 3: Standard Constants (Required)

The Standard Constants block contains pre-defined values that every service script must include. These are hardcoded by design to ensure complete transparency and independence.

bash
1# --- Standard Constants --- #
2STATUS_OK="OK"
3STATUS_UPDATE="UPDATE"
4STATUS_WARNING="WARNING"
5STATUS_FAILURE="FAILURE"
6TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")

Why are these copied to every script?

  1. Transparency: What you see is exactly what runs
  2. Independence: Scripts work without the SSI Agent installed
  3. Auditability: No hidden values or imports
  4. Reliability: No external dependencies

Additional Constants (Optional):

You may add additional constants like STATUS_ERROR if your script uses them:

bash
1STATUS_ERROR="ERROR"
2STATUS_UNKNOWN="UNKNOWN"

Block 4: Configuration (Optional)

The Configuration block contains user-specific settings that customize the script's behavior.

bash
1# --- Configurations --- #
2URL="https://api.example.com/health/"
3EXPECTED_STATUS=200
4RETRY_COUNT=3
5
6# Configuration with defaults (for dynamic configuration)
7ALERT_THRESHOLD="${ALERT_THRESHOLD:-90}"

Guidelines:

  • Place all configurable values here
  • Use meaningful variable names in UPPER_SNAKE_CASE
  • Provide sensible defaults where appropriate
  • Use ${VAR:-default} syntax for optional environment variables

Block 5: Dependencies (Optional)

The Dependencies block documents external tools required by the script. This block is purely for documentation and transparency.

bash
1# --- Dependencies --- #
2# curl      - HTTP client for API requests
3# jq        - JSON parser (optional, for complex responses)
4# zpool     - ZFS pool management utility

Guidelines:

  • List each dependency on its own line
  • Include a brief description of why it's needed
  • This helps users understand what must be installed

Block 6: Main (Required)

The Main block contains the core monitoring logic of the script. This is where the actual work happens.

bash
1# --- Main --- #
2HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$URL" 2>/dev/null)
3
4if [ "$HTTP_CODE" = "200" ]; then
5    echo "$TIMESTAMP, $STATUS_OK, API is healthy"
6    exit 0
7else
8    echo "$TIMESTAMP, $STATUS_FAILURE, API returned HTTP $HTTP_CODE"
9    exit 1
10fi

Rules:

  1. Output Format: Must print status in the format:

    <TIMESTAMP>, <STATUS>, <MESSAGE>
  2. Exit Codes:

    • exit 0 — Script completed successfully (status can be any)
    • exit 1 — Script encountered an error
  3. Single Final Status: The last line of output determines the reported status

  4. Streaming Updates: For long-running scripts, you can output multiple UPDATE lines:

    bash
    1echo "$TIMESTAMP, $STATUS_UPDATE, Scrub in progress: 25%"
    2sleep 5
    3echo "$TIMESTAMP, $STATUS_UPDATE, Scrub in progress: 50%"
    4sleep 5
    5echo "$TIMESTAMP, $STATUS_OK, Scrub completed successfully"

Complete Example

Here's a complete service script with all blocks:

bash
1#!/bin/bash
2
3# --- Manifest --- #
4# name: Disk Usage Check
5# description: Monitors disk usage and warns if above threshold
6# version: 1.0
7# schedule: *:0/15:00
8# timeout: 30
9
10# --- Overview --- #
11# This script checks the disk usage of the root partition.
12# Returns "OK" if usage is below 80%.
13# Returns "WARNING" if usage is between 80% and 95%.
14# Returns "FAILURE" if usage is above 95%.
15
16# --- Standard Constants --- #
17STATUS_OK="OK"
18STATUS_UPDATE="UPDATE"
19STATUS_WARNING="WARNING"
20STATUS_FAILURE="FAILURE"
21TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
22
23# --- Configurations --- #
24MOUNT_POINT="/"
25WARNING_THRESHOLD=80
26CRITICAL_THRESHOLD=95
27
28# --- Dependencies --- #
29# df - Disk free utility (standard on all Linux systems)
30
31# --- Main --- #
32USAGE=$(df -h "$MOUNT_POINT" | awk 'NR==2 {print $5}' | tr -d '%')
33
34if [ "$USAGE" -ge "$CRITICAL_THRESHOLD" ]; then
35    echo "$TIMESTAMP, $STATUS_FAILURE, Disk usage critical: ${USAGE}%"
36    exit 1
37elif [ "$USAGE" -ge "$WARNING_THRESHOLD" ]; then
38    echo "$TIMESTAMP, $STATUS_WARNING, Disk usage high: ${USAGE}%"
39    exit 0
40else
41    echo "$TIMESTAMP, $STATUS_OK, Disk usage normal: ${USAGE}%"
42    exit 0
43fi

Block Order

Blocks should appear in this order for consistency:

  1. Shebang
  2. Manifest
  3. Overview (if present)
  4. Standard Constants
  5. Configuration (if present)
  6. Dependencies (if present)
  7. Main

Block Markers

Use consistent comment markers to identify blocks:

bash
1# --- Block Name --- #

This makes scripts easy to scan and understand.