Skip to content

Commit 4beba8e

Browse files
committed
feat(bash): add systemd manager lifecycle commands
1 parent 7734b14 commit 4beba8e

11 files changed

Lines changed: 310 additions & 0 deletions

File tree

scripts/bash/systemd-service-manager/build.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ MODULES=(
2424
"${SCRIPT_DIR}/commands/init.sh"
2525
"${SCRIPT_DIR}/commands/list.sh"
2626
"${SCRIPT_DIR}/commands/install.sh"
27+
"${SCRIPT_DIR}/commands/start.sh"
28+
"${SCRIPT_DIR}/commands/stop.sh"
29+
"${SCRIPT_DIR}/commands/restart.sh"
30+
"${SCRIPT_DIR}/commands/status.sh"
31+
"${SCRIPT_DIR}/commands/logs.sh"
32+
"${SCRIPT_DIR}/commands/enable.sh"
33+
"${SCRIPT_DIR}/commands/disable.sh"
2734
"${SCRIPT_DIR}/main.sh"
2835
)
2936

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# shellcheck shell=bash
2+
3+
if [[ -n "${SSM_CMD_DISABLE_LOADED:-}" ]]; then
4+
return 0
5+
fi
6+
SSM_CMD_DISABLE_LOADED=1
7+
8+
# 禁用目标 unit 的自启动。
9+
ssm_cmd_disable() {
10+
local target_kind="${1:-}"
11+
local target_name="${2:-}"
12+
ssm_load_target_context "${target_kind}" "${target_name}"
13+
ssm_systemctl "${SSM_ACTIVE_SCOPE}" disable "${SSM_ACTIVE_UNIT}"
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# shellcheck shell=bash
2+
3+
if [[ -n "${SSM_CMD_ENABLE_LOADED:-}" ]]; then
4+
return 0
5+
fi
6+
SSM_CMD_ENABLE_LOADED=1
7+
8+
# 启用目标 unit 的自启动。
9+
ssm_cmd_enable() {
10+
local target_kind="${1:-}"
11+
local target_name="${2:-}"
12+
ssm_load_target_context "${target_kind}" "${target_name}"
13+
ssm_systemctl "${SSM_ACTIVE_SCOPE}" enable "${SSM_ACTIVE_UNIT}"
14+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# shellcheck shell=bash
2+
3+
if [[ -n "${SSM_CMD_LOGS_LOADED:-}" ]]; then
4+
return 0
5+
fi
6+
SSM_CMD_LOGS_LOADED=1
7+
8+
# 查看目标 unit 的 journald 日志,并按需跟随输出。
9+
ssm_cmd_logs() {
10+
local target_kind="${1:-}"
11+
local target_name="${2:-}"
12+
ssm_load_target_context "${target_kind}" "${target_name}"
13+
14+
local -a args=(-u "${SSM_ACTIVE_UNIT}")
15+
if [[ "${SSM_CLI_FOLLOW}" == "1" ]]; then
16+
args+=(-f)
17+
fi
18+
ssm_journalctl "${SSM_ACTIVE_SCOPE}" "${args[@]}"
19+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# shellcheck shell=bash
2+
3+
if [[ -n "${SSM_CMD_RESTART_LOADED:-}" ]]; then
4+
return 0
5+
fi
6+
SSM_CMD_RESTART_LOADED=1
7+
8+
# 重启目标 unit。
9+
ssm_cmd_restart() {
10+
local target_kind="${1:-}"
11+
local target_name="${2:-}"
12+
ssm_load_target_context "${target_kind}" "${target_name}"
13+
ssm_systemctl "${SSM_ACTIVE_SCOPE}" restart "${SSM_ACTIVE_UNIT}"
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# shellcheck shell=bash
2+
3+
if [[ -n "${SSM_CMD_START_LOADED:-}" ]]; then
4+
return 0
5+
fi
6+
SSM_CMD_START_LOADED=1
7+
8+
# 启动目标 unit,scope 由目标配置决定。
9+
ssm_cmd_start() {
10+
local target_kind="${1:-}"
11+
local target_name="${2:-}"
12+
ssm_load_target_context "${target_kind}" "${target_name}"
13+
ssm_systemctl "${SSM_ACTIVE_SCOPE}" start "${SSM_ACTIVE_UNIT}"
14+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# shellcheck shell=bash
2+
3+
if [[ -n "${SSM_CMD_STATUS_LOADED:-}" ]]; then
4+
return 0
5+
fi
6+
SSM_CMD_STATUS_LOADED=1
7+
8+
# 输出统一状态摘要,便于脚本和人工共同消费。
9+
ssm_cmd_status() {
10+
local target_kind="${1:-}"
11+
local target_name="${2:-}"
12+
ssm_load_target_context "${target_kind}" "${target_name}"
13+
14+
local enabled_state=""
15+
local active_state=""
16+
enabled_state="$(ssm_systemctl "${SSM_ACTIVE_SCOPE}" is-enabled "${SSM_ACTIVE_UNIT}" 2>/dev/null || true)"
17+
active_state="$(ssm_systemctl "${SSM_ACTIVE_SCOPE}" is-active "${SSM_ACTIVE_UNIT}" 2>/dev/null || true)"
18+
19+
printf 'name=%s\n' "${target_name}"
20+
printf 'unit=%s\n' "${SSM_ACTIVE_UNIT}"
21+
printf 'scope=%s\n' "${SSM_ACTIVE_SCOPE}"
22+
printf 'installed=%s\n' "$(ssm_is_unit_installed "${SSM_ACTIVE_SCOPE}" "${SSM_ACTIVE_UNIT}")"
23+
printf 'enabled=%s\n' "${enabled_state:-unknown}"
24+
printf 'active=%s\n' "${active_state:-unknown}"
25+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# shellcheck shell=bash
2+
3+
if [[ -n "${SSM_CMD_STOP_LOADED:-}" ]]; then
4+
return 0
5+
fi
6+
SSM_CMD_STOP_LOADED=1
7+
8+
# 停止目标 unit。
9+
ssm_cmd_stop() {
10+
local target_kind="${1:-}"
11+
local target_name="${2:-}"
12+
ssm_load_target_context "${target_kind}" "${target_name}"
13+
ssm_systemctl "${SSM_ACTIVE_SCOPE}" stop "${SSM_ACTIVE_UNIT}"
14+
}

scripts/bash/systemd-service-manager/lib/systemd.sh

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,45 @@ ssm_verify_unit_file() {
4848
local unit_file="$1"
4949
systemd-analyze verify "${unit_file}" >/dev/null 2>&1
5050
}
51+
52+
# 按 scope 包装 journalctl,用于 logs 命令。
53+
ssm_journalctl() {
54+
local scope="$1"
55+
shift
56+
if [[ "${scope}" == "user" ]]; then
57+
journalctl --user "$@"
58+
else
59+
journalctl "$@"
60+
fi
61+
}
62+
63+
# 判断目标 unit 当前是否已经落盘安装。
64+
ssm_is_unit_installed() {
65+
local scope="$1"
66+
local unit_name="$2"
67+
[[ -f "$(ssm_unit_dir_for_scope "${scope}")/${unit_name}" ]] && printf 'true' || printf 'false'
68+
}
69+
70+
# 把 service/timer 目标解析成 scope 与最终 unit 名,供 lifecycle 命令复用。
71+
ssm_load_target_context() {
72+
local target_kind="$1"
73+
local target_name="$2"
74+
local project_dir
75+
project_dir="$(ssm_find_project_dir "${SSM_CLI_PROJECT_DIR:-}")"
76+
77+
case "${target_kind}" in
78+
service)
79+
ssm_parse_service_config "${project_dir}" "${target_name}"
80+
SSM_ACTIVE_SCOPE="${SSM_SERVICE_SCOPE}"
81+
SSM_ACTIVE_UNIT="$(ssm_service_unit_name "${target_name}")"
82+
;;
83+
timer)
84+
ssm_parse_timer_config "${project_dir}" "${target_name}"
85+
SSM_ACTIVE_SCOPE="${SSM_TIMER_SCOPE}"
86+
SSM_ACTIVE_UNIT="$(ssm_timer_unit_name "${target_name}")"
87+
;;
88+
*)
89+
ssm_die "Unknown target kind: ${target_kind}"
90+
;;
91+
esac
92+
}

scripts/bash/systemd-service-manager/main.sh

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,20 @@ if [[ -z "${SSM_STANDALONE:-}" ]]; then
3232
source "${SCRIPT_DIR}/commands/list.sh"
3333
# shellcheck source=scripts/bash/systemd-service-manager/commands/install.sh
3434
source "${SCRIPT_DIR}/commands/install.sh"
35+
# shellcheck source=scripts/bash/systemd-service-manager/commands/start.sh
36+
source "${SCRIPT_DIR}/commands/start.sh"
37+
# shellcheck source=scripts/bash/systemd-service-manager/commands/stop.sh
38+
source "${SCRIPT_DIR}/commands/stop.sh"
39+
# shellcheck source=scripts/bash/systemd-service-manager/commands/restart.sh
40+
source "${SCRIPT_DIR}/commands/restart.sh"
41+
# shellcheck source=scripts/bash/systemd-service-manager/commands/status.sh
42+
source "${SCRIPT_DIR}/commands/status.sh"
43+
# shellcheck source=scripts/bash/systemd-service-manager/commands/logs.sh
44+
source "${SCRIPT_DIR}/commands/logs.sh"
45+
# shellcheck source=scripts/bash/systemd-service-manager/commands/enable.sh
46+
source "${SCRIPT_DIR}/commands/enable.sh"
47+
# shellcheck source=scripts/bash/systemd-service-manager/commands/disable.sh
48+
source "${SCRIPT_DIR}/commands/disable.sh"
3549
fi
3650

3751
# 顶层分发仅保留 help 和错误分支,满足第一轮测试闭环。
@@ -57,6 +71,27 @@ ssm_main() {
5771
install)
5872
ssm_cmd_install "$@"
5973
;;
74+
start)
75+
ssm_cmd_start "$@"
76+
;;
77+
stop)
78+
ssm_cmd_stop "$@"
79+
;;
80+
restart)
81+
ssm_cmd_restart "$@"
82+
;;
83+
status)
84+
ssm_cmd_status "$@"
85+
;;
86+
logs)
87+
ssm_cmd_logs "$@"
88+
;;
89+
enable)
90+
ssm_cmd_enable "$@"
91+
;;
92+
disable)
93+
ssm_cmd_disable "$@"
94+
;;
6095
debug-schedule)
6196
[[ -n "${1:-}" ]] || ssm_die "Missing schedule expression"
6297
ssm_resolve_schedule "$1"

0 commit comments

Comments
 (0)