📦 Service Wrappers Recipes
Service wrappers provide a standardized way to manage applications as system services, handling startup, shutdown, logging, and monitoring. This recipe offers patterns for creating robust service wrappers across different init systems.
🎯 Core Principles
Universal Service Wrapper Framework
Create portable service wrappers that work across different systems.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282 | #!/bin/bash
# service-wrapper.sh - Universal service wrapper framework
# Service configuration
SERVICE_NAME=""
SERVICE_DESCRIPTION=""
SERVICE_USER=""
SERVICE_GROUP=""
SERVICE_PIDFILE=""
SERVICE_LOGFILE=""
SERVICE_ERRFILE=""
SERVICE_WORKDIR=""
SERVICE_EXECUTABLE=""
SERVICE_ARGS=""
# Runtime configuration
SERVICE_DAEMONIZE=true
SERVICE_RESTART_ON_FAILURE=true
SERVICE_RESTART_DELAY=5
SERVICE_MAX_RESTARTS=10
SERVICE_TIMEOUT=30
# Internal state
SERVICE_PID=0
SERVICE_RESTART_COUNT=0
# Logging functions
log_info() {
local message="$1"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [INFO] [$SERVICE_NAME] $message" | tee -a "${SERVICE_LOGFILE:-/dev/null}"
}
log_error() {
local message="$1"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [ERROR] [$SERVICE_NAME] $message" | tee -a "${SERVICE_ERRFILE:-/dev/null}" >&2
}
log_debug() {
if [ "${SERVICE_DEBUG:-false}" = "true" ]; then
local message="$1"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [DEBUG] [$SERVICE_NAME] $message" | tee -a "${SERVICE_LOGFILE:-/dev/null}"
fi
}
# Configuration loading
load_service_config() {
local config_file="$1"
if [ -f "$config_file" ]; then
log_debug "Loading configuration from $config_file"
source "$config_file"
else
log_debug "Configuration file not found: $config_file"
fi
# Validate required configuration
if [ -z "$SERVICE_NAME" ] || [ -z "$SERVICE_EXECUTABLE" ]; then
log_error "SERVICE_NAME and SERVICE_EXECUTABLE are required"
return 1
fi
# Set default values
SERVICE_PIDFILE="${SERVICE_PIDFILE:-/var/run/$SERVICE_NAME.pid}"
SERVICE_LOGFILE="${SERVICE_LOGFILE:-/var/log/$SERVICE_NAME.log}"
SERVICE_ERRFILE="${SERVICE_ERRFILE:-/var/log/$SERVICE_NAME.err}"
SERVICE_WORKDIR="${SERVICE_WORKDIR:-/}"
# Create log directories
mkdir -p "$(dirname "$SERVICE_PIDFILE")"
mkdir -p "$(dirname "$SERVICE_LOGFILE")"
mkdir -p "$(dirname "$SERVICE_ERRFILE")"
return 0
}
# Process management
get_service_pid() {
if [ -f "$SERVICE_PIDFILE" ]; then
cat "$SERVICE_PIDFILE"
else
echo ""
fi
}
is_service_running() {
local pid
pid=$(get_service_pid)
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
return 0
else
return 1
fi
}
# Signal handling
setup_signal_handlers() {
trap 'handle_shutdown' INT TERM
trap 'handle_reload' HUP
}
handle_shutdown() {
log_info "Received shutdown signal"
stop_service
exit 0
}
handle_reload() {
log_info "Received reload signal"
reload_service
}
# Service operations
start_service() {
if is_service_running; then
log_info "Service is already running"
return 0
fi
log_info "Starting service"
# Change to working directory
cd "$SERVICE_WORKDIR" || {
log_error "Failed to change to working directory: $SERVICE_WORKDIR"
return 1
}
# Prepare command
local cmd="$SERVICE_EXECUTABLE"
if [ -n "$SERVICE_ARGS" ]; then
cmd="$cmd $SERVICE_ARGS"
fi
# Add PID file argument if supported
if [ -n "$SERVICE_PIDFILE" ]; then
cmd="$cmd --pidfile=$SERVICE_PIDFILE"
fi
log_debug "Executing: $cmd"
# Execute service
if [ "$SERVICE_DAEMONIZE" = true ]; then
# Daemonize the process
nohup $cmd >"$SERVICE_LOGFILE" 2>"$SERVICE_ERRFILE" &
local pid=$!
# Wait briefly for PID file creation
sleep 2
# Verify the process is still running
if kill -0 "$pid" 2>/dev/null; then
echo "$pid" > "$SERVICE_PIDFILE"
log_info "Service started with PID: $pid"
return 0
else
log_error "Service failed to start"
return 1
fi
else
# Run in foreground
exec $cmd
fi
}
stop_service() {
log_info "Stopping service"
local pid
pid=$(get_service_pid)
if [ -z "$pid" ]; then
log_info "Service is not running"
return 0
fi
# Send graceful shutdown signal
if kill -TERM "$pid" 2>/dev/null; then
log_debug "Sent TERM signal to PID $pid"
# Wait for graceful shutdown
local count=0
while [ $count -lt $SERVICE_TIMEOUT ] && kill -0 "$pid" 2>/dev/null; do
sleep 1
count=$((count + 1))
done
# Force kill if still running
if kill -0 "$pid" 2>/dev/null; then
log_debug "Sending KILL signal to PID $pid"
kill -KILL "$pid" 2>/dev/null
sleep 1
fi
fi
# Clean up PID file
rm -f "$SERVICE_PIDFILE"
log_info "Service stopped"
return 0
}
restart_service() {
log_info "Restarting service"
stop_service
sleep 2
start_service
}
reload_service() {
log_info "Reloading service"
local pid
pid=$(get_service_pid)
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
kill -HUP "$pid" 2>/dev/null
log_info "Reload signal sent to service"
return 0
else
log_error "Service is not running"
return 1
fi
}
status_service() {
if is_service_running; then
local pid
pid=$(get_service_pid)
log_info "Service is running with PID: $pid"
return 0
else
log_info "Service is not running"
return 1
fi
}
# Health checking
check_service_health() {
if ! is_service_running; then
log_error "Service is not running"
return 1
fi
# Service-specific health checks can be implemented here
# This is a generic placeholder
log_info "Service health check passed"
return 0
}
# Supervised execution with restart logic
supervised_execution() {
setup_signal_handlers
while true; do
if ! is_service_running; then
if [ "$SERVICE_RESTART_ON_FAILURE" = true ] && [ $SERVICE_RESTART_COUNT -lt $SERVICE_MAX_RESTARTS ]; then
SERVICE_RESTART_COUNT=$((SERVICE_RESTART_COUNT + 1))
log_info "Restarting service (attempt $SERVICE_RESTART_COUNT/$SERVICE_MAX_RESTARTS)"
start_service
if [ $? -ne 0 ]; then
log_error "Service failed to start"
sleep $SERVICE_RESTART_DELAY
continue
fi
log_info "Service restarted successfully"
elif [ $SERVICE_RESTART_COUNT -ge $SERVICE_MAX_RESTARTS ]; then
log_error "Maximum restart attempts reached ($SERVICE_MAX_RESTARTS)"
exit 1
else
log_info "Service stopped normally"
exit 0
fi
fi
# Check health periodically
sleep 30
check_service_health
done
}
|
🔧 Systemd Service Integration
Creating Systemd Service Units
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85 | # systemd-wrapper.sh - Systemd integration for service wrappers
# Generate systemd service unit file
generate_systemd_unit() {
local service_name="$1"
local wrapper_script="$2"
local unit_file="/etc/systemd/system/$service_name.service"
cat > "$unit_file" << EOF
[Unit]
Description=$SERVICE_DESCRIPTION
After=network.target
[Service]
Type=forking
User=$SERVICE_USER
Group=$SERVICE_GROUP
WorkingDirectory=$SERVICE_WORKDIR
ExecStart=$wrapper_script start
ExecStop=$wrapper_script stop
ExecReload=$wrapper_script reload
PIDFile=$SERVICE_PIDFILE
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=$SERVICE_NAME
Environment=SERVICE_CONFIG=/etc/$SERVICE_NAME/config
[Install]
WantedBy=multi-user.target
EOF
log_info "Generated systemd unit file: $unit_file"
# Reload systemd daemon
systemctl daemon-reload
return 0
}
# Systemd-aware service wrapper
systemd_service_wrapper() {
local action="$1"
case "$action" in
start)
if [ -n "$NOTIFY_SOCKET" ]; then
log_debug "Running under systemd"
# Notify systemd when ready
start_service
local result=$?
if [ $result -eq 0 ]; then
systemd-notify --ready
fi
return $result
else
start_service
fi
;;
stop)
stop_service
;;
restart)
restart_service
;;
reload)
reload_service
;;
status)
status_service
;;
supervise)
supervised_execution
;;
*)
echo "Usage: $0 {start|stop|restart|reload|status|supervise}" >&2
return 1
;;
esac
}
|
📦 Init Script Integration
SysV Init Script Wrapper
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128 | # init-wrapper.sh - SysV init script integration
# Generate init script
generate_init_script() {
local service_name="$1"
local wrapper_script="$2"
local init_script="/etc/init.d/$service_name"
cat > "$init_script" << 'EOF'
#!/bin/bash
### BEGIN INIT INFO
# Provides: SERVICE_NAME
# Required-Start: $local_fs $network $named $time $syslog
# Required-Stop: $local_fs $network $named $time $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Description: SERVICE_DESCRIPTION
### END INIT INFO
WRAPPER_SCRIPT="WRAPPER_SCRIPT_PATH"
LOCK_FILE="/var/lock/subsys/SERVICE_NAME"
# Source function library
if [ -f /etc/rc.d/init.d/functions ]; then
. /etc/rc.d/init.d/functions
fi
start() {
echo -n "Starting SERVICE_NAME: "
if [ -f "$LOCK_FILE" ]; then
echo "already running"
return 0
fi
$WRAPPER_SCRIPT start
if [ $? -eq 0 ]; then
touch "$LOCK_FILE"
echo "OK"
return 0
else
echo "FAILED"
return 1
fi
}
stop() {
echo -n "Stopping SERVICE_NAME: "
if [ ! -f "$LOCK_FILE" ]; then
echo "not running"
return 0
fi
$WRAPPER_SCRIPT stop
if [ $? -eq 0 ]; then
rm -f "$LOCK_FILE"
echo "OK"
return 0
else
echo "FAILED"
return 1
fi
}
restart() {
stop
start
}
reload() {
echo -n "Reloading SERVICE_NAME: "
$WRAPPER_SCRIPT reload
if [ $? -eq 0 ]; then
echo "OK"
return 0
else
echo "FAILED"
return 1
fi
}
status() {
$WRAPPER_SCRIPT status
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
reload)
reload
;;
status)
status
;;
*)
echo "Usage: $0 {start|stop|restart|reload|status}"
exit 1
;;
esac
exit $?
EOF
# Customize the script
sed -i "s/SERVICE_NAME/$service_name/g" "$init_script"
sed -i "s|WRAPPER_SCRIPT_PATH|$wrapper_script|g" "$init_script"
sed -i "s/SERVICE_DESCRIPTION/$SERVICE_DESCRIPTION/g" "$init_script"
# Make executable
chmod +x "$init_script"
# Add to default runlevels
if command -v chkconfig >/dev/null 2>&1; then
chkconfig --add "$service_name"
chkconfig "$service_name" on
elif command -v update-rc.d >/dev/null 2>&1; then
update-rc.d "$service_name" defaults
fi
log_info "Generated init script: $init_script"
return 0
}
|
🔄 Service Monitoring and Management
Advanced Service Management Features
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154 | # service-monitor.sh - Advanced service monitoring and management
# Resource monitoring
monitor_service_resources() {
local pid
pid=$(get_service_pid)
if [ -z "$pid" ] || ! kill -0 "$pid" 2>/dev/null; then
return 1
fi
# Get resource usage
local cpu_usage
cpu_usage=$(ps -p "$pid" -o %cpu= 2>/dev/null | tr -d ' ')
local memory_usage
memory_usage=$(ps -p "$pid" -o %mem= 2>/dev/null | tr -d ' ')
local memory_rss
memory_rss=$(ps -p "$pid" -o rss= 2>/dev/null | tr -d ' ')
log_debug "Resource usage - CPU: ${cpu_usage}%, Memory: ${memory_usage}%, RSS: ${memory_rss}KB"
# Check thresholds
local cpu_threshold="${SERVICE_CPU_THRESHOLD:-90}"
local memory_threshold="${SERVICE_MEMORY_THRESHOLD:-90}"
if [ -n "$cpu_usage" ] && [ "$(echo "$cpu_usage > $cpu_threshold" | bc 2>/dev/null)" = "1" ]; then
log_error "CPU usage (${cpu_usage}%) exceeds threshold (${cpu_threshold}%)"
return 1
fi
if [ -n "$memory_usage" ] && [ "$(echo "$memory_usage > $memory_threshold" | bc 2>/dev/null)" = "1" ]; then
log_error "Memory usage (${memory_usage}%) exceeds threshold (${memory_threshold}%)"
return 1
fi
return 0
}
# Log monitoring
monitor_service_logs() {
local log_file="$SERVICE_LOGFILE"
local error_patterns="$SERVICE_ERROR_PATTERNS"
if [ ! -f "$log_file" ]; then
return 0
fi
# Check for error patterns
if [ -n "$error_patterns" ]; then
IFS=',' read -ra patterns <<< "$error_patterns"
for pattern in "${patterns[@]}"; do
if tail -100 "$log_file" | grep -q "$pattern"; then
log_error "Error pattern detected in logs: $pattern"
return 1
fi
done
fi
return 0
}
# Health check with custom validation
custom_health_check() {
local health_check_script="$SERVICE_HEALTH_CHECK"
if [ -n "$health_check_script" ] && [ -x "$health_check_script" ]; then
log_debug "Running custom health check: $health_check_script"
if ! timeout 30 "$health_check_script"; then
log_error "Custom health check failed: $health_check_script"
return 1
fi
log_debug "Custom health check passed"
fi
return 0
}
# Automatic service restart based on conditions
conditional_restart() {
local restart_conditions="$SERVICE_RESTART_CONDITIONS"
if [ -z "$restart_conditions" ]; then
return 0
fi
IFS=',' read -ra conditions <<< "$restart_conditions"
for condition in "${conditions[@]}"; do
case "$condition" in
resource_exceeded)
if ! monitor_service_resources; then
log_info "Restarting due to resource threshold exceeded"
restart_service
return 0
fi
;;
log_errors)
if ! monitor_service_logs; then
log_info "Restarting due to log errors detected"
restart_service
return 0
fi
;;
custom_check)
if ! custom_health_check; then
log_info "Restarting due to custom health check failure"
restart_service
return 0
fi
;;
esac
done
return 0
}
# Service supervisor with monitoring
enhanced_supervisor() {
setup_signal_handlers
log_info "Starting enhanced supervisor"
while true; do
# Check if service should be running
if ! is_service_running; then
if [ "$SERVICE_RESTART_ON_FAILURE" = true ] && [ $SERVICE_RESTART_COUNT -lt $SERVICE_MAX_RESTARTS ]; then
SERVICE_RESTART_COUNT=$((SERVICE_RESTART_COUNT + 1))
log_info "Automatic restart (attempt $SERVICE_RESTART_COUNT/$SERVICE_MAX_RESTARTS)"
start_service
if [ $? -ne 0 ]; then
log_error "Service failed to start"
sleep $SERVICE_RESTART_DELAY
continue
fi
log_info "Service restarted successfully"
SERVICE_RESTART_COUNT=0 # Reset on successful start
elif [ $SERVICE_RESTART_COUNT -ge $SERVICE_MAX_RESTARTS ]; then
log_error "Maximum restart attempts reached ($SERVICE_MAX_RESTARTS)"
exit 1
fi
fi
# Perform conditional checks
conditional_restart
# Sleep before next check
sleep "${SERVICE_MONITOR_INTERVAL:-60}"
done
}
|
🎨 Advanced Service Wrapper Features
Configuration Management and Templates
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106 | # config-management.sh - Service configuration management
# Generate configuration from template
generate_service_config() {
local template_file="$1"
local output_file="$2"
if [ ! -f "$template_file" ]; then
log_error "Template file not found: $template_file"
return 1
fi
# Process template with environment variables
envsubst < "$template_file" > "$output_file"
# Set appropriate permissions
chmod 644 "$output_file"
log_info "Generated configuration file: $output_file"
return 0
}
# Validate configuration
validate_service_config() {
local config_file="$1"
local validator_script="$2"
if [ -n "$validator_script" ] && [ -x "$validator_script" ]; then
log_debug "Validating configuration: $config_file"
if ! "$validator_script" "$config_file"; then
log_error "Configuration validation failed: $config_file"
return 1
fi
log_debug "Configuration validation passed"
fi
return 0
}
# Backup configuration
backup_service_config() {
local config_file="$1"
local backup_dir="${2:-/var/backups}"
if [ ! -f "$config_file" ]; then
return 0
fi
mkdir -p "$backup_dir"
local timestamp
timestamp=$(date +%Y%m%d_%H%M%S)
local backup_file="$backup_dir/$(basename "$config_file").$timestamp"
cp "$config_file" "$backup_file"
log_debug "Configuration backed up to: $backup_file"
return 0
}
# Rotate configuration backups
rotate_config_backups() {
local backup_dir="${1:-/var/backups}"
local max_backups="${2:-10}"
if [ ! -d "$backup_dir" ]; then
return 0
fi
# Remove old backups
find "$backup_dir" -name "*.conf.*" -type f | sort | head -n -$max_backups | xargs rm -f
return 0
}
# Configuration hot reload
hot_reload_config() {
local config_file="$1"
# Backup current configuration
backup_service_config "$config_file"
# Validate new configuration
if ! validate_service_config "$config_file"; then
log_error "New configuration is invalid, restoring backup"
# Restore from most recent backup
local latest_backup
latest_backup=$(find /var/backups -name "$(basename "$config_file").*" -type f | sort | tail -1)
if [ -n "$latest_backup" ]; then
cp "$latest_backup" "$config_file"
log_info "Restored configuration from backup: $latest_backup"
fi
return 1
fi
# Trigger service reload
reload_service
# Rotate old backups
rotate_config_backups
log_info "Configuration hot reload completed"
return 0
}
|
🧾 Summary Best Practices
Service Wrapper Guidelines
- Portability: Design wrappers to work across different init systems
- Process Management: Properly handle PID files and process lifecycle
- Signal Handling: Implement proper signal handling for graceful shutdown
- Logging: Centralize and structure service logs appropriately
- Monitoring: Include resource and health monitoring capabilities
- Configuration: Support flexible configuration management
- Security: Run services with appropriate user privileges
- Error Handling: Implement robust error handling and restart logic
- Documentation: Provide clear documentation for service operations
- Testing: Thoroughly test service wrapper functionality
Sample Service Configuration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 | # service-config-example.sh - Service configuration template
# Basic service information
export SERVICE_NAME="my-application"
export SERVICE_DESCRIPTION="My Application Service"
export SERVICE_USER="appuser"
export SERVICE_GROUP="appgroup"
# Executable and arguments
export SERVICE_EXECUTABLE="/opt/myapp/bin/myapp"
export SERVICE_ARGS="--config=/etc/myapp/config.conf --log-level=info"
# Paths and files
export SERVICE_WORKDIR="/opt/myapp"
export SERVICE_PIDFILE="/var/run/myapp.pid"
export SERVICE_LOGFILE="/var/log/myapp.log"
export SERVICE_ERRFILE="/var/log/myapp.err"
# Runtime behavior
export SERVICE_DAEMONIZE=true
export SERVICE_RESTART_ON_FAILURE=true
export SERVICE_RESTART_DELAY=10
export SERVICE_MAX_RESTARTS=5
export SERVICE_TIMEOUT=30
# Monitoring thresholds
export SERVICE_CPU_THRESHOLD=80
export SERVICE_MEMORY_THRESHOLD=80
export SERVICE_MONITOR_INTERVAL=60
# Health checking
export SERVICE_HEALTH_CHECK="/opt/myapp/bin/health-check.sh"
export SERVICE_ERROR_PATTERNS="ERROR,FATAL,Exception"
# Configuration management
export SERVICE_CONFIG_TEMPLATE="/etc/myapp/config.conf.template"
export SERVICE_CONFIG_VALIDATOR="/opt/myapp/bin/validate-config.sh"
|
🧠 Complete Service Wrapper Script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 | #!/bin/bash
# complete-service-wrapper.sh - Production-ready service wrapper
set -euo pipefail
# Source all modules
source service-wrapper.sh
source systemd-wrapper.sh
source init-wrapper.sh
source service-monitor.sh
source config-management.sh
# Main service wrapper function
main() {
local action="${1:-}"
# Load configuration
local config_file="${SERVICE_CONFIG:-/etc/$SERVICE_NAME/config}"
if ! load_service_config "$config_file"; then
exit 1
fi
# Execute requested action
case "$action" in
start)
start_service
;;
stop)
stop_service
;;
restart)
restart_service
;;
reload)
reload_service
;;
status)
status_service
;;
supervise)
supervised_execution
;;
enhanced-supervise)
enhanced_supervisor
;;
generate-systemd)
generate_systemd_unit "$SERVICE_NAME" "$0"
;;
generate-init)
generate_init_script "$SERVICE_NAME" "$0"
;;
check-health)
check_service_health
;;
monitor-resources)
monitor_service_resources
;;
hot-reload)
local config_file="${2:-}"
if [ -n "$config_file" ]; then
hot_reload_config "$config_file"
else
echo "Usage: $0 hot-reload <config-file>" >&2
exit 1
fi
;;
"")
echo "Usage: $0 {start|stop|restart|reload|status|supervise|enhanced-supervise|generate-systemd|generate-init|check-health|monitor-resources|hot-reload}" >&2
exit 1
;;
*)
# Pass to systemd-aware wrapper
systemd_service_wrapper "$action"
;;
esac
}
# Run main function
main "$@"
|
🧾 See Also