s (3602B)
1 #!/bin/zsh 2 setopt no_unset warn_create_global extended_glob 3 4 typeset -g default_bundle=ok-all 5 6 load_s6_rc_db() { 7 typeset -gA service_type 8 typeset -ga oneshots longruns bundles 9 10 local s 11 12 oneshots=( "${(@f)"$( s6-rc-db list oneshots )"}" ) || exit $? 13 longruns=( "${(@f)"$( s6-rc-db list longruns )"}" ) || exit $? 14 bundles=( "${(@f)"$( s6-rc-db list bundles )"}" ) || exit $? 15 for s in $oneshots; do service_type[$s]=oneshot; done 16 for s in $longruns; do service_type[$s]=longrun; done 17 for s in $bundles; do service_type[$s]=bundle; done 18 } 19 20 load_s6_rc() { 21 typeset -gA service_bundles bundle_services service_in_bundle service_active 22 typeset -ga active_services 23 24 local b s svc_bundles 25 26 active_services=( "${(@f)"$( s6-rc -a list )"}" ) || exit $? 27 for s in $active_services; do 28 service_active[$s]=1 29 done 30 for b in $bundles; do 31 bundle_services[$b]=$( s6-rc listall $b ) || exit $? 32 for s in "${(@f)bundle_services[$b]}"; do 33 service_in_bundle[$s//$b]=1 34 service_bundles[$s]+=$b$'\n' 35 done 36 done 37 for s svc_bundles in "${(kv@)service_bundles}"; do 38 service_bundles[$s]=${svc_bundles%$'\n'} 39 done 40 41 process_bundles 42 } 43 44 process_bundles() { 45 typeset -gA bundle_stat 46 47 local b s 48 local -a count bundle_content 49 50 for b in ${(k)bundle_services}; do 51 bundle_content=( ${(f)bundle_services[$b]} ) 52 count=( 0 0 ) # Active, inactive 53 for s in $bundle_content; do 54 [[ $s == s6rc-* ]] && continue # skip s6-rc internal services 55 : $(( count[${service_active[$s]:-2}]++ )) 56 done 57 if (($count[1] == 0)); then 58 bundle_stat[$b]=1 # inactive 59 elif (($count[2] == 0)); then 60 bundle_stat[$b]=3 # active 61 else 62 bundle_stat[$b]=2 # partial 63 fi 64 done 65 } 66 67 load_svstat() { 68 typeset -gA service_stat 69 typeset -ga s6_services 70 71 local -a svstat 72 local s svcdir 73 74 for svcdir in /run/service/*(-/); do 75 s=$svcdir:t 76 s6_services+=( $s ) 77 if svstat=( $(s6-svstat $svcdir) ); then 78 service_stat[$s]=$svstat[1] 79 [[ $service_stat[$s] == up && $svstat[3] == ? ]] && service_stat[$s]=starting 80 else 81 service_stat[$s]=err 82 fi 83 done 84 } 85 86 print_service_bundles() { 87 local b post='%f%b' s=$1 88 local -a fmt_active=( '%F{cyan}' '%F{magenta}' '%F{yellow}%B' ) 89 if ! (($+service_bundles[$s])); then 90 printf '\t-\n' 91 return 92 fi 93 for b in ${(f)service_bundles[$s]}; do 94 printf '\t%s' "${(%)fmt_active[${bundle_stat[$b]}]}$b${(%)post}" 95 done 96 print 97 } 98 99 show_oneshots() { 100 local -a fmt_active=( '%F{yellow}%BA%b%f' '%F{cyan}I%f' ) 101 local s pre post='%s' 102 for s in $oneshots; do 103 pre=' ' 104 if (($+service_active[$s] ^^ $+service_in_bundle[$s//$default_bundle])); then 105 if (($+service_active[$s])); then 106 pre=' _%S' 107 else 108 pre=' ^%S' 109 fi 110 fi 111 printf "%s" ${(%)fmt_active[${service_active[$s]:-2}]} ${(%)pre} $s ${(%)post} 112 print_service_bundles $s 113 done 114 } 115 116 show_longruns() { 117 local -a sv_stat fmt_active=( '%F{yellow}%BA%b%f' '%F{cyan}I%f' '%F{magenta}-%f' ) 118 local -A fmt_up=( up '%F{green}%BU%b%f' down '%F{red}D%f' starting '%F{magenta}%B?%b%f' err '%K{red}X%k' ) 119 local s state active pre post=%s 120 for s in $s6_services; do 121 state=$service_stat[$s] 122 if (($+service_type[$s])); then 123 active=${service_active[$s]:-2} 124 else 125 active=3 126 fi 127 pre=' ' 128 if (($+service_active[$s] ^^ $+service_in_bundle[$s//$default_bundle])); then 129 if (($+service_active[$s])); then 130 pre='_%S' 131 else 132 pre='^%S' 133 fi 134 fi 135 printf "%s" ${(%)fmt_active[$active]} ${(%)fmt_up[$state]} ${(%)pre} $s ${(%)post} 136 print_service_bundles $s 137 done 138 } 139 140 main() { 141 load_s6_rc_db 142 load_s6_rc 143 load_svstat 144 145 show_oneshots 146 show_longruns 147 148 #diff -u <(s6-rc listall ok-all) <(s6-rc -a list) 149 } 150 151 main "$@"